musig: simplify state machine by adding explicit round to session struct

This commit is contained in:
Jonas Nick 2019-11-21 12:05:27 +00:00
parent 6370bdd537
commit 29b4bd85d7
3 changed files with 84 additions and 120 deletions

View File

@ -45,14 +45,10 @@ typedef struct {
* structure.
*
* Fields:
* combined_pk: MuSig-computed combined xonly public key
* round: Current round of the session
* pre_session: Auxiliary data created in `pubkey_combine`
* combined_pk: MuSig-computed combined xonly public key
* n_signers: Number of signers
* 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 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
@ -60,18 +56,18 @@ typedef struct {
* seckey: If `has_secret_data`, the signer's secret key
* secnonce: If `has_secret_data`, the signer's secret nonce
* nonce: If `has_secret_data`, the signer's public nonce
* nonce_commitments_hash: If `has_secret_data` and `nonce_commitments_hash_is_set`,
* the hash of all signers' commitments
* nonce_commitments_hash_is_set: If `has_secret_data`, whether the
* nonce_commitments_hash has been set
* nonce_commitments_hash: If `has_secret_data` and round >= 1, the hash of all
* signers' commitments
* combined_nonce: If round >= 2, the summed combined public nonce
* nonce_is_negated: If round >= 2, whether the above nonce was negated after
* summing the participants' nonces. Needed to ensure the nonce's y
* coordinate is even.
*/
typedef struct {
secp256k1_xonly_pubkey combined_pk;
int round;
secp256k1_musig_pre_session pre_session;
secp256k1_xonly_pubkey combined_pk;
uint32_t n_signers;
secp256k1_pubkey combined_nonce;
int nonce_is_set;
int nonce_is_negated;
unsigned char msg[32];
int msg_is_set;
int has_secret_data;
@ -79,7 +75,8 @@ typedef struct {
unsigned char secnonce[32];
secp256k1_pubkey nonce;
unsigned char nonce_commitments_hash[32];
int nonce_commitments_hash_is_set;
secp256k1_pubkey combined_nonce;
int nonce_is_negated;
} secp256k1_musig_session;
/** Data structure containing data on all signers in a single session.

View File

@ -140,6 +140,8 @@ int secp256k1_musig_session_initialize(const secp256k1_context* ctx, secp256k1_m
secp256k1_sha256 sha;
secp256k1_gej pj;
secp256k1_ge p;
unsigned char nonce_ser[33];
size_t nonce_ser_size = sizeof(nonce_ser);
VERIFY_CHECK(ctx != NULL);
ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
@ -162,7 +164,6 @@ int secp256k1_musig_session_initialize(const secp256k1_context* ctx, secp256k1_m
}
memcpy(&session->combined_pk, combined_pk, sizeof(*combined_pk));
session->pre_session = *pre_session;
session->nonce_is_set = 0;
session->has_secret_data = 1;
if (n_signers == 0 || my_index >= n_signers) {
return 0;
@ -172,7 +173,6 @@ int secp256k1_musig_session_initialize(const secp256k1_context* ctx, secp256k1_m
}
session->n_signers = (uint32_t) n_signers;
secp256k1_musig_signers_init(signers, session->n_signers);
session->nonce_commitments_hash_is_set = 0;
/* Compute secret key */
secp256k1_scalar_set_b32(&secret, seckey, &overflow);
@ -223,15 +223,12 @@ int secp256k1_musig_session_initialize(const secp256k1_context* ctx, secp256k1_m
secp256k1_ge_set_gej(&p, &pj);
secp256k1_pubkey_save(&session->nonce, &p);
if (nonce_commitment32 != NULL) {
unsigned char commit[33];
size_t commit_size = sizeof(commit);
secp256k1_sha256_initialize(&sha);
secp256k1_ec_pubkey_serialize(ctx, commit, &commit_size, &session->nonce, SECP256K1_EC_COMPRESSED);
secp256k1_sha256_write(&sha, commit, commit_size);
secp256k1_sha256_finalize(&sha, nonce_commitment32);
}
secp256k1_sha256_initialize(&sha);
secp256k1_ec_pubkey_serialize(ctx, nonce_ser, &nonce_ser_size, &session->nonce, SECP256K1_EC_COMPRESSED);
secp256k1_sha256_write(&sha, nonce_ser, nonce_ser_size);
secp256k1_sha256_finalize(&sha, nonce_commitment32);
session->round = 0;
secp256k1_scalar_clear(&secret);
return 1;
}
@ -247,6 +244,7 @@ int secp256k1_musig_session_get_public_nonce(const secp256k1_context* ctx, secp2
ARG_CHECK(signers != NULL);
ARG_CHECK(nonce != NULL);
ARG_CHECK(commitments != NULL);
ARG_CHECK(session->round == 0);
/* If the message was not set during initialization it must be set now. */
ARG_CHECK(!(!session->msg_is_set && msg32 == NULL));
/* The message can only be set once. */
@ -269,15 +267,9 @@ int secp256k1_musig_session_get_public_nonce(const secp256k1_context* ctx, secp2
secp256k1_sha256_write(&sha, commitments[i], 32);
}
secp256k1_sha256_finalize(&sha, nonce_commitments_hash);
if (session->nonce_commitments_hash_is_set
&& memcmp(session->nonce_commitments_hash, nonce_commitments_hash, 32) != 0) {
/* Abort if get_public_nonce has been called before with a different array of
* commitments. */
return 0;
}
memcpy(session->nonce_commitments_hash, nonce_commitments_hash, 32);
session->nonce_commitments_hash_is_set = 1;
memcpy(nonce, &session->nonce, sizeof(*nonce));
session->round = 1;
return 1;
}
@ -313,15 +305,14 @@ int secp256k1_musig_session_initialize_verifier(const secp256k1_context* ctx, se
secp256k1_musig_signers_init(signers, session->n_signers);
session->pre_session = *pre_session;
session->nonce_is_set = 0;
session->msg_is_set = 1;
memcpy(session->msg, msg32, 32);
session->has_secret_data = 0;
session->nonce_commitments_hash_is_set = 0;
for (i = 0; i < n_signers; i++) {
memcpy(signers[i].nonce_commitment, commitments[i], 32);
}
session->round = 1;
return 1;
}
@ -358,6 +349,7 @@ int secp256k1_musig_session_combine_nonces(const secp256k1_context* ctx, secp256
VERIFY_CHECK(ctx != NULL);
ARG_CHECK(session != NULL);
ARG_CHECK(signers != NULL);
ARG_CHECK(session->round == 1);
if (n_signers != session->n_signers) {
return 0;
@ -373,16 +365,13 @@ int secp256k1_musig_session_combine_nonces(const secp256k1_context* ctx, secp256
secp256k1_gej_add_ge_var(&combined_noncej, &combined_noncej, &noncep, NULL);
}
secp256k1_sha256_finalize(&sha, nonce_commitments_hash);
/* Either the session is a verifier session or or the nonce_commitments_hash has
* been set in `musig_session_get_public_nonce`. */
VERIFY_CHECK(!session->has_secret_data || session->nonce_commitments_hash_is_set);
/* If the signers' commitments changed between get_public_nonce and now we
* have to abort because in that case they may have seen our nonce before
* creating their commitment. That can happen if the signer_data given to
* this function is different to the signer_data given to get_public_nonce.
* */
if (session->has_secret_data
&& memcmp(session->nonce_commitments_hash, nonce_commitments_hash, 32) != 0) {
/* If the signers' commitments changed between get_public_nonce and now we
* have to abort because in that case they may have seen our nonce before
* creating their commitment. That can happen if the signer_data given to
* this function is different to the signer_data given to get_public_nonce.
* */
return 0;
}
@ -403,7 +392,7 @@ int secp256k1_musig_session_combine_nonces(const secp256k1_context* ctx, secp256
*nonce_is_negated = session->nonce_is_negated;
}
secp256k1_pubkey_save(&session->combined_nonce, &combined_noncep);
session->nonce_is_set = 1;
session->round = 2;
return 1;
}
@ -429,19 +418,15 @@ static int secp256k1_musig_compute_messagehash(const secp256k1_context *ctx, uns
secp256k1_ge rp;
secp256k1_sha256 sha;
VERIFY_CHECK(session->round >= 2);
secp256k1_schnorrsig_sha256_tagged(&sha);
if (!session->nonce_is_set) {
return 0;
}
secp256k1_pubkey_load(ctx, &rp, &session->combined_nonce);
secp256k1_fe_get_b32(buf, &rp.x);
secp256k1_sha256_write(&sha, buf, 32);
secp256k1_xonly_pubkey_serialize(ctx, buf, &session->combined_pk);
secp256k1_sha256_write(&sha, buf, 32);
if (!session->msg_is_set) {
return 0;
}
secp256k1_sha256_write(&sha, session->msg, 32);
secp256k1_sha256_finalize(&sha, msghash);
return 1;
@ -456,8 +441,9 @@ int secp256k1_musig_partial_sign(const secp256k1_context* ctx, const secp256k1_m
VERIFY_CHECK(ctx != NULL);
ARG_CHECK(partial_sig != NULL);
ARG_CHECK(session != NULL);
ARG_CHECK(session->round == 2);
if (!session->nonce_is_set || !session->has_secret_data) {
if (!session->has_secret_data) {
return 0;
}
@ -503,10 +489,8 @@ int secp256k1_musig_partial_sig_combine(const secp256k1_context* ctx, const secp
ARG_CHECK(sig64 != NULL);
ARG_CHECK(partial_sigs != NULL);
ARG_CHECK(session != NULL);
ARG_CHECK(session->round == 2);
if (!session->nonce_is_set) {
return 0;
}
if (n_sigs != session->n_signers) {
return 0;
}
@ -548,8 +532,9 @@ int secp256k1_musig_partial_sig_verify(const secp256k1_context* ctx, const secp2
ARG_CHECK(signer != NULL);
ARG_CHECK(partial_sig != NULL);
ARG_CHECK(pubkey != NULL);
ARG_CHECK(session->round == 2);
if (!session->nonce_is_set || !signer->present) {
if (!signer->present) {
return 0;
}
secp256k1_scalar_set_b32(&s, partial_sig->data, &overflow);

View File

@ -93,7 +93,6 @@ void musig_api_tests(secp256k1_scratch_space *scratch) {
int nonce_is_negated;
const unsigned char *ncs[2];
unsigned char msg[32];
unsigned char msghash[32];
secp256k1_xonly_pubkey combined_pk;
secp256k1_musig_pre_session pre_session;
secp256k1_musig_pre_session pre_session_uninitialized;
@ -234,37 +233,41 @@ void musig_api_tests(secp256k1_scratch_space *scratch) {
CHECK(ecount == 5);
CHECK(secp256k1_musig_session_initialize_verifier(none, &verifier_session, verifier_signer_data, msg, &combined_pk, &pre_session, ncs, 2) == 1);
CHECK(secp256k1_musig_compute_messagehash(none, msghash, &verifier_session) == 0);
CHECK(secp256k1_musig_compute_messagehash(none, msghash, &session[0]) == 0);
/** Signing step 0 -- exchange nonce commitments */
ecount = 0;
{
secp256k1_pubkey nonce;
secp256k1_musig_session session_0_tmp;
memcpy(&session_0_tmp, &session[0], sizeof(session_0_tmp));
/* Can obtain public nonce after commitments have been exchanged; still can't sign */
CHECK(secp256k1_musig_session_get_public_nonce(none, &session[0], signer0, &nonce, ncs, 2, NULL) == 1);
CHECK(secp256k1_musig_partial_sign(none, &session[0], &partial_sig[0]) == 0);
CHECK(ecount == 0);
CHECK(secp256k1_musig_session_get_public_nonce(none, &session_0_tmp, signer0, &nonce, ncs, 2, NULL) == 1);
CHECK(secp256k1_musig_partial_sign(none, &session_0_tmp, &partial_sig[0]) == 0);
CHECK(ecount == 1);
}
/** Signing step 1 -- exchange nonces */
ecount = 0;
{
secp256k1_pubkey public_nonce[3];
secp256k1_musig_session session_0_tmp;
CHECK(secp256k1_musig_session_get_public_nonce(none, &session[0], signer0, &public_nonce[0], ncs, 2, NULL) == 1);
memcpy(&session_0_tmp, &session[0], sizeof(session_0_tmp));
CHECK(secp256k1_musig_session_get_public_nonce(none, &session_0_tmp, signer0, &public_nonce[0], ncs, 2, NULL) == 1);
CHECK(ecount == 0);
/* Reset session */
memcpy(&session_0_tmp, &session[0], sizeof(session_0_tmp));
CHECK(secp256k1_musig_session_get_public_nonce(none, NULL, signer0, &public_nonce[0], ncs, 2, NULL) == 0);
CHECK(ecount == 1);
CHECK(secp256k1_musig_session_get_public_nonce(none, &session[0], NULL, &public_nonce[0], ncs, 2, NULL) == 0);
CHECK(secp256k1_musig_session_get_public_nonce(none, &session_0_tmp, NULL, &public_nonce[0], ncs, 2, NULL) == 0);
CHECK(ecount == 2);
CHECK(secp256k1_musig_session_get_public_nonce(none, &session[0], signer0, NULL, ncs, 2, NULL) == 0);
CHECK(secp256k1_musig_session_get_public_nonce(none, &session_0_tmp, signer0, NULL, ncs, 2, NULL) == 0);
CHECK(ecount == 3);
CHECK(secp256k1_musig_session_get_public_nonce(none, &session[0], signer0, &public_nonce[0], NULL, 2, NULL) == 0);
CHECK(secp256k1_musig_session_get_public_nonce(none, &session_0_tmp, signer0, &public_nonce[0], NULL, 2, NULL) == 0);
CHECK(ecount == 4);
/* Number of commitments and number of signers are different */
CHECK(secp256k1_musig_session_get_public_nonce(none, &session[0], signer0, &public_nonce[0], ncs, 1, NULL) == 0);
CHECK(secp256k1_musig_session_get_public_nonce(none, &session_0_tmp, signer0, &public_nonce[0], ncs, 1, NULL) == 0);
CHECK(ecount == 4);
CHECK(secp256k1_musig_session_get_public_nonce(none, &session[0], signer0, &public_nonce[0], ncs, 2, NULL) == 1);
@ -287,17 +290,20 @@ void musig_api_tests(secp256k1_scratch_space *scratch) {
CHECK(secp256k1_musig_set_nonce(none, &verifier_signer_data[1], &public_nonce[1]) == 1);
ecount = 0;
CHECK(secp256k1_musig_session_combine_nonces(none, &session[0], signer0, 2, &nonce_is_negated, &adaptor) == 1);
memcpy(&session_0_tmp, &session[0], sizeof(session_0_tmp));
CHECK(secp256k1_musig_session_combine_nonces(none, &session_0_tmp, signer0, 2, &nonce_is_negated, &adaptor) == 1);
memcpy(&session_0_tmp, &session[0], sizeof(session_0_tmp));
CHECK(secp256k1_musig_session_combine_nonces(none, NULL, signer0, 2, &nonce_is_negated, &adaptor) == 0);
CHECK(ecount == 1);
CHECK(secp256k1_musig_session_combine_nonces(none, &session[0], NULL, 2, &nonce_is_negated, &adaptor) == 0);
CHECK(secp256k1_musig_session_combine_nonces(none, &session_0_tmp, NULL, 2, &nonce_is_negated, &adaptor) == 0);
CHECK(ecount == 2);
/* Number of signers differs from number during intialization */
CHECK(secp256k1_musig_session_combine_nonces(none, &session[0], signer0, 1, &nonce_is_negated, &adaptor) == 0);
CHECK(secp256k1_musig_session_combine_nonces(none, &session_0_tmp, signer0, 1, &nonce_is_negated, &adaptor) == 0);
CHECK(ecount == 2);
CHECK(secp256k1_musig_session_combine_nonces(none, &session[0], signer0, 2, NULL, &adaptor) == 1);
CHECK(secp256k1_musig_session_combine_nonces(none, &session_0_tmp, signer0, 2, NULL, &adaptor) == 1);
CHECK(ecount == 2);
CHECK(secp256k1_musig_session_combine_nonces(none, &session[0], signer0, 2, &nonce_is_negated, NULL) == 1);
memcpy(&session_0_tmp, &session[0], sizeof(session_0_tmp));
CHECK(secp256k1_musig_session_combine_nonces(none, &session_0_tmp, signer0, 2, &nonce_is_negated, NULL) == 1);
CHECK(secp256k1_musig_session_combine_nonces(none, &session[0], signer0, 2, &nonce_is_negated, &adaptor) == 1);
CHECK(secp256k1_musig_session_combine_nonces(none, &session[1], signer0, 2, &nonce_is_negated, &adaptor) == 1);
@ -550,43 +556,8 @@ void musig_state_machine_late_msg_test(secp256k1_xonly_pubkey *pks, secp256k1_xo
CHECK(secp256k1_musig_partial_sig_verify(ctx, &session, &signers[1], &partial_sig, &pks[1]));
}
/* Recreates a session with the given session_id, signers, pk, msg etc. parameters
* and tries to verify and combine partial sigs. If do_combine is 0, the
* combine_nonces step is left out. In that case verify and combine should fail and
* this function should return 0. */
int musig_state_machine_missing_combine_test(secp256k1_xonly_pubkey *pks, secp256k1_xonly_pubkey *combined_pk, secp256k1_musig_pre_session *pre_session, unsigned char *nonce_commitment_other, secp256k1_pubkey *nonce_other, secp256k1_musig_partial_signature *partial_sig_other, unsigned char *msg, unsigned char *sk, unsigned char *session_id, secp256k1_musig_partial_signature *partial_sig, int do_combine) {
secp256k1_musig_session session;
secp256k1_musig_session_signer_data signers[2];
unsigned char nonce_commitment[32];
const unsigned char *ncs[2];
secp256k1_pubkey nonce;
secp256k1_musig_partial_signature partial_sigs[2];
unsigned char sig[64];
int partial_verify, sig_combine;
CHECK(secp256k1_musig_session_initialize(ctx, &session, signers, nonce_commitment, session_id, msg, combined_pk, pre_session, 2, 1, sk) == 1);
ncs[0] = nonce_commitment_other;
ncs[1] = nonce_commitment;
CHECK(secp256k1_musig_session_get_public_nonce(ctx, &session, signers, &nonce, ncs, 2, NULL) == 1);
CHECK(secp256k1_musig_set_nonce(ctx, &signers[0], nonce_other) == 1);
CHECK(secp256k1_musig_set_nonce(ctx, &signers[1], &nonce) == 1);
partial_sigs[0] = *partial_sig_other;
partial_sigs[1] = *partial_sig;
if (do_combine != 0) {
CHECK(secp256k1_musig_session_combine_nonces(ctx, &session, signers, 2, NULL, NULL) == 1);
}
partial_verify = secp256k1_musig_partial_sig_verify(ctx, &session, signers, partial_sig_other, &pks[0]);
sig_combine = secp256k1_musig_partial_sig_combine(ctx, &session, sig, partial_sigs, 2);
if (do_combine != 0) {
/* Return 1 if both succeeded */
return partial_verify && sig_combine;
}
/* Return 0 if both failed */
return partial_verify || sig_combine;
}
void musig_state_machine_tests(secp256k1_scratch_space *scratch) {
secp256k1_context *ctx_tmp = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_VERIFY);
size_t i;
secp256k1_musig_session session[2];
secp256k1_musig_session_signer_data signers0[2];
@ -601,8 +572,13 @@ void musig_state_machine_tests(secp256k1_scratch_space *scratch) {
secp256k1_pubkey nonce[2];
const unsigned char *ncs[2];
secp256k1_musig_partial_signature partial_sig[2];
unsigned char sig[64];
unsigned char msghash1[32];
unsigned char msghash2[32];
int ecount;
secp256k1_context_set_illegal_callback(ctx_tmp, counting_illegal_callback_fn, &ecount);
ecount = 0;
/* Run state machine with the same objects twice to test that it's allowed to
* reinitialize session and session_signer_data. */
@ -618,17 +594,19 @@ void musig_state_machine_tests(secp256k1_scratch_space *scratch) {
CHECK(secp256k1_musig_pubkey_combine(ctx, scratch, &combined_pk, &pre_session, pk, 2) == 1);
CHECK(secp256k1_musig_session_initialize(ctx, &session[0], signers0, nonce_commitment[0], session_id[0], msg, &combined_pk, &pre_session, 2, 0, sk[0]) == 1);
CHECK(secp256k1_musig_session_initialize(ctx, &session[1], signers1, nonce_commitment[1], session_id[1], msg, &combined_pk, &pre_session, 2, 1, sk[1]) == 1);
/* Can't combine nonces unless we're through round 1 already */
ecount = 0;
CHECK(secp256k1_musig_session_combine_nonces(ctx_tmp, &session[0], signers0, 2, NULL, NULL) == 0);
CHECK(ecount == 1);
/* Set nonce commitments */
ncs[0] = nonce_commitment[0];
ncs[1] = nonce_commitment[1];
CHECK(secp256k1_musig_session_get_public_nonce(ctx, &session[0], signers0, &nonce[0], ncs, 2, NULL) == 1);
/* Changing a nonce commitment is not okay */
ncs[1] = (unsigned char*) "this isn't a nonce commitment...";
CHECK(secp256k1_musig_session_get_public_nonce(ctx, &session[0], signers0, &nonce[0], ncs, 2, NULL) == 0);
/* Repeating with the same nonce commitments is okay */
ncs[1] = nonce_commitment[1];
CHECK(secp256k1_musig_session_get_public_nonce(ctx, &session[0], signers0, &nonce[0], ncs, 2, NULL) == 1);
/* Calling the function again is not okay */
ecount = 0;
CHECK(secp256k1_musig_session_get_public_nonce(ctx_tmp, &session[0], signers0, &nonce[0], ncs, 2, NULL) == 0);
CHECK(ecount == 1);
/* Get nonce for signer 1 */
CHECK(secp256k1_musig_session_get_public_nonce(ctx, &session[1], signers1, &nonce[1], ncs, 2, NULL) == 1);
@ -654,9 +632,16 @@ void musig_state_machine_tests(secp256k1_scratch_space *scratch) {
/* Partially sign */
CHECK(secp256k1_musig_partial_sign(ctx, &session[0], &partial_sig[0]) == 1);
/* Can't verify or sign until nonce is combined */
CHECK(secp256k1_musig_partial_sig_verify(ctx, &session[1], &signers1[0], &partial_sig[0], &pk[0]) == 0);
CHECK(secp256k1_musig_partial_sign(ctx, &session[1], &partial_sig[1]) == 0);
/* Can't verify, sign or combine signatures until nonce is combined */
ecount = 0;
CHECK(secp256k1_musig_partial_sig_verify(ctx_tmp, &session[1], &signers1[0], &partial_sig[0], &pk[0]) == 0);
CHECK(ecount == 1);
CHECK(secp256k1_musig_partial_sign(ctx_tmp, &session[1], &partial_sig[1]) == 0);
CHECK(ecount == 2);
memset(&partial_sig[1], 0, sizeof(partial_sig[1]));
CHECK(secp256k1_musig_partial_sig_combine(ctx_tmp, &session[1], sig, partial_sig, 2) == 0);
CHECK(ecount == 3);
CHECK(secp256k1_musig_session_combine_nonces(ctx, &session[1], signers1, 2, NULL, NULL) == 1);
CHECK(secp256k1_musig_partial_sig_verify(ctx, &session[1], &signers1[0], &partial_sig[0], &pk[0]) == 1);
/* messagehash should be the same as a session whose get_public_nonce was called
@ -672,11 +657,8 @@ void musig_state_machine_tests(secp256k1_scratch_space *scratch) {
CHECK(secp256k1_musig_partial_sig_verify(ctx, &session[1], &signers1[1], &partial_sig[0], &pk[1]) == 0);
/* Can't get the public nonce until msg is set */
musig_state_machine_late_msg_test(pk, &combined_pk, &pre_session, nonce_commitment[0], &nonce[0], sk[1], session_id[1], msg);
/* Can't verify and combine partial sigs until nonces are combined */
CHECK(musig_state_machine_missing_combine_test(pk, &combined_pk, &pre_session, nonce_commitment[0], &nonce[0], &partial_sig[0], msg, sk[1], session_id[1], &partial_sig[1], 0) == 0);
CHECK(musig_state_machine_missing_combine_test(pk, &combined_pk, &pre_session, nonce_commitment[0], &nonce[0], &partial_sig[0], msg, sk[1], session_id[1], &partial_sig[1], 1) == 1);
}
secp256k1_context_destroy(ctx_tmp);
}
void scriptless_atomic_swap(secp256k1_scratch_space *scratch) {