Fix the MuSig module after integrating bip-schnorr updates
1. using xonly_pubkeys in MuSig for input public keys and the combined
pk. For that to work we need to store whether the MuSig aggregated point
has an even y in the session, may need to negate each signers secret
key and may need to negate each signers public key in
musig_partial_sig_verify.
2. using a tagged hash for the message hash.
3. use !fe_is_odd in place of fe_is_quad_var
This commit is contained in:
committed by
Andrew Poelstra
parent
005fe79262
commit
23900a0d86
@@ -1,6 +1,8 @@
|
||||
#ifndef SECP256K1_MUSIG_H
|
||||
#define SECP256K1_MUSIG_H
|
||||
|
||||
#include "secp256k1_extrakeys.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -8,15 +10,30 @@ extern "C" {
|
||||
#include <stdint.h>
|
||||
|
||||
/** This module implements a Schnorr-based multi-signature scheme called MuSig
|
||||
* (https://eprint.iacr.org/2018/068.pdf). There's an example C source file in the
|
||||
* module's directory (src/modules/musig/example.c) that demonstrates how it can be
|
||||
* used.
|
||||
* (https://eprint.iacr.org/2018/068.pdf). It is compatible with bip-schnorr.
|
||||
* There's an example C source file in the module's directory
|
||||
* (src/modules/musig/example.c) that demonstrates how it can be used.
|
||||
*
|
||||
* The documentation in this include file is for reference and may not be sufficient
|
||||
* for users to begin using the library. A full description of API usage can be found
|
||||
* in src/modules/musig/musig.md
|
||||
*/
|
||||
|
||||
/** Data structure containing auxiliary data generated in `pubkey_combine` and
|
||||
* required for `session_*_initialize`.
|
||||
* Fields:
|
||||
* magic: Set during initialization in `pubkey_combine` in order to allow
|
||||
* detecting an uninitialized object.
|
||||
* pk_hash: The 32-byte hash of the original public keys
|
||||
* is_negated: Whether the MuSig-aggregated point was negated when
|
||||
* converting it to the combined xonly pubkey.
|
||||
*/
|
||||
typedef struct {
|
||||
uint64_t magic;
|
||||
unsigned char pk_hash[32];
|
||||
int is_negated;
|
||||
} secp256k1_musig_pre_session;
|
||||
|
||||
/** Data structure containing data related to a signing session resulting in a single
|
||||
* signature.
|
||||
*
|
||||
@@ -28,14 +45,14 @@ extern "C" {
|
||||
* structure.
|
||||
*
|
||||
* Fields:
|
||||
* combined_pk: MuSig-computed combined public key
|
||||
* combined_pk: MuSig-computed combined xonly public key
|
||||
* pre_session: Auxiliary data created in `pubkey_combine`
|
||||
* n_signers: Number of signers
|
||||
* pk_hash: The 32-byte hash of the original public keys
|
||||
* combined_nonce: Summed combined public nonce (undefined if `nonce_is_set` is false)
|
||||
* nonce_is_set: Whether the above nonce has been set
|
||||
* nonce_is_negated: If `nonce_is_set`, whether the above nonce was negated after
|
||||
* summing the participants' nonces. Needed to ensure the nonce's y
|
||||
* coordinate has a quadratic-residue y coordinate
|
||||
* coordinate is even.
|
||||
* msg: The 32-byte message (hash) to be signed
|
||||
* msg_is_set: Whether the above message has been set
|
||||
* has_secret_data: Whether this session object has a signers' secret data; if this
|
||||
@@ -49,9 +66,9 @@ extern "C" {
|
||||
* nonce_commitments_hash has been set
|
||||
*/
|
||||
typedef struct {
|
||||
secp256k1_pubkey combined_pk;
|
||||
secp256k1_xonly_pubkey combined_pk;
|
||||
secp256k1_musig_pre_session pre_session;
|
||||
uint32_t n_signers;
|
||||
unsigned char pk_hash[32];
|
||||
secp256k1_pubkey combined_nonce;
|
||||
int nonce_is_set;
|
||||
int nonce_is_negated;
|
||||
@@ -119,9 +136,9 @@ typedef struct {
|
||||
* (cannot be NULL)
|
||||
* scratch: scratch space used to compute the combined pubkey by
|
||||
* multiexponentiation. If NULL, an inefficient algorithm is used.
|
||||
* Out: combined_pk: the MuSig-combined public key (cannot be NULL)
|
||||
* pk_hash32: if non-NULL, filled with the 32-byte hash of all input public
|
||||
* keys in order to be used in `musig_session_initialize`.
|
||||
* Out: combined_pk: the MuSig-combined xonly public key (cannot be NULL)
|
||||
* pre_session: if non-NULL, pointer to a musig_pre_session struct to be used in
|
||||
* `musig_session_initialize`.
|
||||
* In: pubkeys: input array of public keys to combine. The order is important;
|
||||
* a different order will result in a different combined public
|
||||
* key (cannot be NULL)
|
||||
@@ -130,9 +147,9 @@ typedef struct {
|
||||
SECP256K1_API int secp256k1_musig_pubkey_combine(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_scratch_space *scratch,
|
||||
secp256k1_pubkey *combined_pk,
|
||||
unsigned char *pk_hash32,
|
||||
const secp256k1_pubkey *pubkeys,
|
||||
secp256k1_xonly_pubkey *combined_pk,
|
||||
secp256k1_musig_pre_session *pre_session,
|
||||
const secp256k1_xonly_pubkey *pubkeys,
|
||||
size_t n_pubkeys
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
@@ -154,9 +171,9 @@ SECP256K1_API int secp256k1_musig_pubkey_combine(
|
||||
* require sharing nonce commitments before the message is known
|
||||
* because it reduces nonce misuse resistance. If NULL, must be
|
||||
* set with `musig_session_get_public_nonce`.
|
||||
* combined_pk: the combined public key of all signers (cannot be NULL)
|
||||
* pk_hash32: the 32-byte hash of the signers' individual keys (cannot be
|
||||
* NULL)
|
||||
* combined_pk: the combined xonly public key of all signers (cannot be NULL)
|
||||
* pre_session: pointer to a musig_pre_session struct from
|
||||
* `musig_pubkey_combine` (cannot be NULL)
|
||||
* n_signers: length of signers array. Number of signers participating in
|
||||
* the MuSig. Must be greater than 0 and at most 2^32 - 1.
|
||||
* my_index: index of this signer in the signers array
|
||||
@@ -169,8 +186,8 @@ SECP256K1_API int secp256k1_musig_session_initialize(
|
||||
unsigned char *nonce_commitment32,
|
||||
const unsigned char *session_id32,
|
||||
const unsigned char *msg32,
|
||||
const secp256k1_pubkey *combined_pk,
|
||||
const unsigned char *pk_hash32,
|
||||
const secp256k1_xonly_pubkey *combined_pk,
|
||||
const secp256k1_musig_pre_session *pre_session,
|
||||
size_t n_signers,
|
||||
size_t my_index,
|
||||
const unsigned char *seckey
|
||||
@@ -213,7 +230,9 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_session_get_publi
|
||||
* signers: an array of signers' data to be initialized. Array length must
|
||||
* equal to `n_signers`(cannot be NULL)
|
||||
* In: msg32: the 32-byte message to be signed (cannot be NULL)
|
||||
* combined_pk: the combined public key of all signers (cannot be NULL)
|
||||
* combined_pk: the combined xonly public key of all signers (cannot be NULL)
|
||||
* pre_session: pointer to a musig_pre_session struct from
|
||||
* `musig_pubkey_combine` (cannot be NULL)
|
||||
* pk_hash32: the 32-byte hash of the signers' individual keys (cannot be NULL)
|
||||
* commitments: array of 32-byte nonce commitments. Array length must equal to
|
||||
* `n_signers` (cannot be NULL)
|
||||
@@ -226,8 +245,8 @@ SECP256K1_API int secp256k1_musig_session_initialize_verifier(
|
||||
secp256k1_musig_session *session,
|
||||
secp256k1_musig_session_signer_data *signers,
|
||||
const unsigned char *msg32,
|
||||
const secp256k1_pubkey *combined_pk,
|
||||
const unsigned char *pk_hash32,
|
||||
const secp256k1_xonly_pubkey *combined_pk,
|
||||
const secp256k1_musig_pre_session *pre_session,
|
||||
const unsigned char *const *commitments,
|
||||
size_t n_signers
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7);
|
||||
@@ -343,7 +362,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_verif
|
||||
const secp256k1_musig_session *session,
|
||||
const secp256k1_musig_session_signer_data *signer,
|
||||
const secp256k1_musig_partial_signature *partial_sig,
|
||||
const secp256k1_pubkey *pubkey
|
||||
const secp256k1_xonly_pubkey *pubkey
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
/** Combines partial signatures
|
||||
@@ -354,23 +373,16 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_verif
|
||||
* Args: ctx: pointer to a context object (cannot be NULL)
|
||||
* session: initialized session for which the combined nonce has been
|
||||
* computed (cannot be NULL)
|
||||
* Out: sig: complete signature (cannot be NULL)
|
||||
* Out: sig64: complete signature (cannot be NULL)
|
||||
* In: partial_sigs: array of partial signatures to combine (cannot be NULL)
|
||||
* n_sigs: number of signatures in the partial_sigs array
|
||||
* tweak32: if `combined_pk` was tweaked with `ec_pubkey_tweak_add` after
|
||||
* `musig_pubkey_combine` and before `musig_session_initialize` then
|
||||
* the same tweak must be provided here in order to get a valid
|
||||
* signature for the tweaked key. Otherwise `tweak` should be NULL.
|
||||
* If the tweak is larger than the group order or 0 this function will
|
||||
* return 0. (can be NULL)
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_partial_sig_combine(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_musig_session *session,
|
||||
secp256k1_schnorrsig *sig,
|
||||
unsigned char *sig64,
|
||||
const secp256k1_musig_partial_signature *partial_sigs,
|
||||
size_t n_sigs,
|
||||
const unsigned char *tweak32
|
||||
size_t n_sigs
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Converts a partial signature to an adaptor signature by adding a given secret
|
||||
@@ -403,7 +415,7 @@ SECP256K1_API int secp256k1_musig_partial_sig_adapt(
|
||||
* 0: otherwise
|
||||
* Args: ctx: pointer to a context object (cannot be NULL)
|
||||
* Out:sec_adaptor32: 32-byte secret adaptor (cannot be NULL)
|
||||
* In: sig: complete 2-of-2 signature (cannot be NULL)
|
||||
* In: sig64: complete 2-of-2 signature (cannot be NULL)
|
||||
* partial_sigs: array of partial signatures (cannot be NULL)
|
||||
* n_partial_sigs: number of elements in partial_sigs array
|
||||
* nonce_is_negated: the `nonce_is_negated` output of `musig_session_combine_nonces`
|
||||
@@ -411,7 +423,7 @@ SECP256K1_API int secp256k1_musig_partial_sig_adapt(
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_extract_secret_adaptor(
|
||||
const secp256k1_context* ctx,
|
||||
unsigned char *sec_adaptor32,
|
||||
const secp256k1_schnorrsig *sig,
|
||||
const unsigned char *sig64,
|
||||
const secp256k1_musig_partial_signature *partial_sigs,
|
||||
size_t n_partial_sigs,
|
||||
int nonce_is_negated
|
||||
|
||||
Reference in New Issue
Block a user