From 56014e8ca01e88e0fbf2f125363c4e7cc48039df Mon Sep 17 00:00:00 2001 From: Jonas Nick Date: Fri, 7 May 2021 15:26:33 +0000 Subject: [PATCH] musig: change pubkey_combine arg to array of pointers to pks ... instead of taking an array of pubkeys directly --- include/secp256k1_musig.h | 8 ++--- src/modules/musig/example.c | 10 +++--- src/modules/musig/main_impl.h | 14 ++++---- src/modules/musig/tests_impl.h | 62 +++++++++++++++++++++++----------- 4 files changed, 60 insertions(+), 34 deletions(-) diff --git a/include/secp256k1_musig.h b/include/secp256k1_musig.h index 4ff51905..b85eacbb 100644 --- a/include/secp256k1_musig.h +++ b/include/secp256k1_musig.h @@ -154,9 +154,9 @@ typedef struct { * 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_init` or `musig_pubkey_tweak_add`. - * 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) + * In: pubkeys: input array of pointers to public keys to combine. The order + * is important; a different order will result in a different + * combined public key (cannot be NULL) * n_pubkeys: length of pubkeys array. Must be greater than 0. */ SECP256K1_API int secp256k1_musig_pubkey_combine( @@ -164,7 +164,7 @@ SECP256K1_API int secp256k1_musig_pubkey_combine( secp256k1_scratch_space *scratch, secp256k1_xonly_pubkey *combined_pk, secp256k1_musig_pre_session *pre_session, - const secp256k1_xonly_pubkey *pubkeys, + const secp256k1_xonly_pubkey * const* pubkeys, size_t n_pubkeys ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5); diff --git a/src/modules/musig/example.c b/src/modules/musig/example.c index 2cdc5565..dffec850 100644 --- a/src/modules/musig/example.c +++ b/src/modules/musig/example.c @@ -40,7 +40,7 @@ int create_keypair(const secp256k1_context* ctx, unsigned char *seckey, secp256k } /* Sign a message hash with the given key pairs and store the result in sig */ -int sign(const secp256k1_context* ctx, unsigned char seckeys[][32], const secp256k1_xonly_pubkey* pubkeys, const unsigned char* msg32, unsigned char *sig64) { +int sign(const secp256k1_context* ctx, unsigned char seckeys[][32], const secp256k1_xonly_pubkey** pubkeys, const unsigned char* msg32, unsigned char *sig64) { secp256k1_musig_session musig_session[N_SIGNERS]; unsigned char nonce_commitment[N_SIGNERS][32]; const unsigned char *nonce_commitment_ptr[N_SIGNERS]; @@ -117,7 +117,7 @@ int sign(const secp256k1_context* ctx, unsigned char seckeys[][32], const secp25 * fine to first verify the combined sig, and only verify the individual * sigs if it does not work. */ - if (!secp256k1_musig_partial_sig_verify(ctx, &musig_session[i], &signer_data[i][j], &partial_sig[j], &pubkeys[j])) { + if (!secp256k1_musig_partial_sig_verify(ctx, &musig_session[i], &signer_data[i][j], &partial_sig[j], pubkeys[j])) { return 0; } } @@ -130,6 +130,7 @@ int sign(const secp256k1_context* ctx, unsigned char seckeys[][32], const secp25 int i; unsigned char seckeys[N_SIGNERS][32]; secp256k1_xonly_pubkey pubkeys[N_SIGNERS]; + const secp256k1_xonly_pubkey *pubkeys_ptr[N_SIGNERS]; secp256k1_xonly_pubkey combined_pk; unsigned char msg[32] = "this_could_be_the_hash_of_a_msg!"; unsigned char sig[64]; @@ -142,16 +143,17 @@ int sign(const secp256k1_context* ctx, unsigned char seckeys[][32], const secp25 printf("FAILED\n"); return 1; } + pubkeys_ptr[i] = &pubkeys[i]; } printf("ok\n"); printf("Combining public keys..."); - if (!secp256k1_musig_pubkey_combine(ctx, NULL, &combined_pk, NULL, pubkeys, N_SIGNERS)) { + if (!secp256k1_musig_pubkey_combine(ctx, NULL, &combined_pk, NULL, pubkeys_ptr, N_SIGNERS)) { printf("FAILED\n"); return 1; } printf("ok\n"); printf("Signing message........."); - if (!sign(ctx, seckeys, pubkeys, msg, sig)) { + if (!sign(ctx, seckeys, pubkeys_ptr, msg, sig)) { printf("FAILED\n"); return 1; } diff --git a/src/modules/musig/main_impl.h b/src/modules/musig/main_impl.h index 6cb2b14b..57d9da16 100644 --- a/src/modules/musig/main_impl.h +++ b/src/modules/musig/main_impl.h @@ -13,14 +13,14 @@ #include "hash.h" /* Computes ell = SHA256(pk[0], ..., pk[np-1]) */ -static int secp256k1_musig_compute_ell(const secp256k1_context *ctx, unsigned char *ell, const secp256k1_xonly_pubkey *pk, size_t np) { +static int secp256k1_musig_compute_ell(const secp256k1_context *ctx, unsigned char *ell, const secp256k1_xonly_pubkey * const* pk, size_t np) { secp256k1_sha256 sha; size_t i; secp256k1_sha256_initialize(&sha); for (i = 0; i < np; i++) { unsigned char ser[32]; - if (!secp256k1_xonly_pubkey_serialize(ctx, ser, &pk[i])) { + if (!secp256k1_xonly_pubkey_serialize(ctx, ser, pk[i])) { return 0; } secp256k1_sha256_write(&sha, ser, 32); @@ -74,14 +74,14 @@ static void secp256k1_musig_keyaggcoef(secp256k1_scalar *r, const secp256k1_musi typedef struct { const secp256k1_context *ctx; unsigned char ell[32]; - const secp256k1_xonly_pubkey *pks; + const secp256k1_xonly_pubkey * const* pks; secp256k1_fe second_pk_x; } secp256k1_musig_pubkey_combine_ecmult_data; /* Callback for batch EC multiplication to compute ell_0*P0 + ell_1*P1 + ... */ static int secp256k1_musig_pubkey_combine_callback(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *data) { secp256k1_musig_pubkey_combine_ecmult_data *ctx = (secp256k1_musig_pubkey_combine_ecmult_data *) data; - if (!secp256k1_xonly_pubkey_load(ctx->ctx, pt, &ctx->pks[idx])) { + if (!secp256k1_xonly_pubkey_load(ctx->ctx, pt, ctx->pks[idx])) { return 0; } secp256k1_musig_keyaggcoef_internal(sc, ctx->ell, &pt->x, &ctx->second_pk_x); @@ -98,7 +98,7 @@ static void secp256k1_musig_signers_init(secp256k1_musig_session_signer_data *si static const uint64_t pre_session_magic = 0xf4adbbdf7c7dd304UL; -int secp256k1_musig_pubkey_combine(const secp256k1_context* ctx, secp256k1_scratch_space *scratch, secp256k1_xonly_pubkey *combined_pk, secp256k1_musig_pre_session *pre_session, const secp256k1_xonly_pubkey *pubkeys, size_t n_pubkeys) { +int secp256k1_musig_pubkey_combine(const secp256k1_context* ctx, secp256k1_scratch_space *scratch, secp256k1_xonly_pubkey *combined_pk, secp256k1_musig_pre_session *pre_session, const secp256k1_xonly_pubkey * const* pubkeys, size_t n_pubkeys) { secp256k1_musig_pubkey_combine_ecmult_data ecmult_data; secp256k1_gej pkj; secp256k1_ge pkp; @@ -117,10 +117,10 @@ int secp256k1_musig_pubkey_combine(const secp256k1_context* ctx, secp256k1_scrat secp256k1_fe_set_int(&ecmult_data.second_pk_x, 0); for (i = 1; i < n_pubkeys; i++) { secp256k1_ge pt; - if (!secp256k1_xonly_pubkey_load(ctx, &pt, &pubkeys[i])) { + if (!secp256k1_xonly_pubkey_load(ctx, &pt, pubkeys[i])) { return 0; } - if (secp256k1_memcmp_var(&pubkeys[0], &pubkeys[i], sizeof(pubkeys[0])) != 0) { + if (secp256k1_memcmp_var(pubkeys[0], pubkeys[i], sizeof(*pubkeys[0])) != 0) { ecmult_data.second_pk_x = pt.x; break; } diff --git a/src/modules/musig/tests_impl.h b/src/modules/musig/tests_impl.h index f529a158..ff20d15b 100644 --- a/src/modules/musig/tests_impl.h +++ b/src/modules/musig/tests_impl.h @@ -30,6 +30,7 @@ void musig_simple_test(secp256k1_scratch_space *scratch) { secp256k1_musig_pre_session pre_session; unsigned char session_id[2][32]; secp256k1_xonly_pubkey pk[2]; + const secp256k1_xonly_pubkey *pk_ptr[2]; const unsigned char *ncs[2]; unsigned char public_nonce[3][32]; secp256k1_musig_partial_signature partial_sig[2]; @@ -41,10 +42,12 @@ void musig_simple_test(secp256k1_scratch_space *scratch) { secp256k1_testrand256(sk[1]); secp256k1_testrand256(msg); + pk_ptr[0] = &pk[0]; + pk_ptr[1] = &pk[1]; CHECK(secp256k1_xonly_pubkey_create(&pk[0], sk[0]) == 1); CHECK(secp256k1_xonly_pubkey_create(&pk[1], sk[1]) == 1); - CHECK(secp256k1_musig_pubkey_combine(ctx, scratch, &combined_pk, &pre_session, pk, 2) == 1); + CHECK(secp256k1_musig_pubkey_combine(ctx, scratch, &combined_pk, &pre_session, pk_ptr, 2) == 1); CHECK(secp256k1_musig_session_init(ctx, &session[1], signer1, nonce_commitment[1], session_id[1], msg, &combined_pk, &pre_session, 2, sk[1]) == 1); CHECK(secp256k1_musig_session_init(ctx, &session[0], signer0, nonce_commitment[0], session_id[0], msg, &combined_pk, &pre_session, 2, sk[0]) == 1); @@ -98,6 +101,7 @@ void musig_api_tests(secp256k1_scratch_space *scratch) { secp256k1_musig_pre_session pre_session; secp256k1_musig_pre_session pre_session_uninitialized; secp256k1_xonly_pubkey pk[2]; + const secp256k1_xonly_pubkey *pk_ptr[2]; unsigned char tweak[32]; unsigned char sec_adaptor[32]; @@ -132,6 +136,8 @@ void musig_api_tests(secp256k1_scratch_space *scratch) { secp256k1_testrand256(sec_adaptor); secp256k1_testrand256(tweak); + pk_ptr[0] = &pk[0]; + pk_ptr[1] = &pk[1]; CHECK(secp256k1_xonly_pubkey_create(&pk[0], sk[0]) == 1); CHECK(secp256k1_xonly_pubkey_create(&pk[1], sk[1]) == 1); CHECK(secp256k1_ec_pubkey_create(ctx, &adaptor, sec_adaptor) == 1); @@ -141,34 +147,34 @@ void musig_api_tests(secp256k1_scratch_space *scratch) { /* Key combination */ ecount = 0; - CHECK(secp256k1_musig_pubkey_combine(none, scratch, &combined_pk, &pre_session, pk, 2) == 0); + CHECK(secp256k1_musig_pubkey_combine(none, scratch, &combined_pk, &pre_session, pk_ptr, 2) == 0); CHECK(ecount == 1); - CHECK(secp256k1_musig_pubkey_combine(sign, scratch, &combined_pk, &pre_session, pk, 2) == 0); + CHECK(secp256k1_musig_pubkey_combine(sign, scratch, &combined_pk, &pre_session, pk_ptr, 2) == 0); CHECK(ecount == 2); - CHECK(secp256k1_musig_pubkey_combine(vrfy, scratch, &combined_pk, &pre_session, pk, 2) == 1); + CHECK(secp256k1_musig_pubkey_combine(vrfy, scratch, &combined_pk, &pre_session, pk_ptr, 2) == 1); CHECK(ecount == 2); /* pubkey_combine does not require a scratch space */ - CHECK(secp256k1_musig_pubkey_combine(vrfy, NULL, &combined_pk, &pre_session, pk, 2) == 1); + CHECK(secp256k1_musig_pubkey_combine(vrfy, NULL, &combined_pk, &pre_session, pk_ptr, 2) == 1); CHECK(ecount == 2); /* A small scratch space works too, but will result in using an ineffecient algorithm */ scratch_small = secp256k1_scratch_space_create(ctx, 1); - CHECK(secp256k1_musig_pubkey_combine(vrfy, scratch_small, &combined_pk, &pre_session, pk, 2) == 1); + CHECK(secp256k1_musig_pubkey_combine(vrfy, scratch_small, &combined_pk, &pre_session, pk_ptr, 2) == 1); secp256k1_scratch_space_destroy(ctx, scratch_small); CHECK(ecount == 2); - CHECK(secp256k1_musig_pubkey_combine(vrfy, scratch, NULL, &pre_session, pk, 2) == 0); + CHECK(secp256k1_musig_pubkey_combine(vrfy, scratch, NULL, &pre_session, pk_ptr, 2) == 0); CHECK(ecount == 3); - CHECK(secp256k1_musig_pubkey_combine(vrfy, scratch, &combined_pk, NULL, pk, 2) == 1); + CHECK(secp256k1_musig_pubkey_combine(vrfy, scratch, &combined_pk, NULL, pk_ptr, 2) == 1); CHECK(ecount == 3); CHECK(secp256k1_musig_pubkey_combine(vrfy, scratch, &combined_pk, &pre_session, NULL, 2) == 0); CHECK(ecount == 4); - CHECK(secp256k1_musig_pubkey_combine(vrfy, scratch, &combined_pk, &pre_session, pk, 0) == 0); + CHECK(secp256k1_musig_pubkey_combine(vrfy, scratch, &combined_pk, &pre_session, pk_ptr, 0) == 0); CHECK(ecount == 5); CHECK(secp256k1_musig_pubkey_combine(vrfy, scratch, &combined_pk, &pre_session, NULL, 0) == 0); CHECK(ecount == 6); - CHECK(secp256k1_musig_pubkey_combine(vrfy, scratch, &combined_pk, &pre_session, pk, 2) == 1); - CHECK(secp256k1_musig_pubkey_combine(vrfy, scratch, &combined_pk, &pre_session, pk, 2) == 1); - CHECK(secp256k1_musig_pubkey_combine(vrfy, scratch, &combined_pk, &pre_session, pk, 2) == 1); + CHECK(secp256k1_musig_pubkey_combine(vrfy, scratch, &combined_pk, &pre_session, pk_ptr, 2) == 1); + CHECK(secp256k1_musig_pubkey_combine(vrfy, scratch, &combined_pk, &pre_session, pk_ptr, 2) == 1); + CHECK(secp256k1_musig_pubkey_combine(vrfy, scratch, &combined_pk, &pre_session, pk_ptr, 2) == 1); /** Tweaking */ ecount = 0; @@ -517,6 +523,7 @@ void musig_state_machine_diff_signer_msghash_test(unsigned char *msghash, secp25 secp256k1_musig_session_signer_data signers_tmp[2]; unsigned char sk_dummy[32]; secp256k1_xonly_pubkey pks_tmp[2]; + const secp256k1_xonly_pubkey *pks_tmp_ptr[2]; secp256k1_xonly_pubkey combined_pk_tmp; secp256k1_musig_pre_session pre_session_tmp; unsigned char nonce[32]; @@ -525,7 +532,9 @@ void musig_state_machine_diff_signer_msghash_test(unsigned char *msghash, secp25 secp256k1_testrand256(sk_dummy); pks_tmp[0] = pks[0]; CHECK(secp256k1_xonly_pubkey_create(&pks_tmp[1], sk_dummy) == 1); - CHECK(secp256k1_musig_pubkey_combine(ctx, NULL, &combined_pk_tmp, &pre_session_tmp, pks_tmp, 2) == 1); + pks_tmp_ptr[0] = &pks_tmp[0]; + pks_tmp_ptr[1] = &pks_tmp[1]; + CHECK(secp256k1_musig_pubkey_combine(ctx, NULL, &combined_pk_tmp, &pre_session_tmp, pks_tmp_ptr, 2) == 1); CHECK(secp256k1_musig_session_init(ctx, &session_tmp, signers_tmp, nonce_commitment, session_id, msg, &combined_pk_tmp, &pre_session_tmp, 2, sk_dummy) == 1); CHECK(secp256k1_musig_session_init(ctx, &session, signers, nonce_commitment, session_id, msg, combined_pk, pre_session, 2, sk) == 1); @@ -625,6 +634,7 @@ void musig_state_machine_tests(secp256k1_scratch_space *scratch) { unsigned char msg[32]; unsigned char sk[2][32]; secp256k1_xonly_pubkey pk[2]; + const secp256k1_xonly_pubkey *pk_ptr[2]; secp256k1_xonly_pubkey combined_pk; secp256k1_musig_pre_session pre_session; unsigned char nonce[2][32]; @@ -647,9 +657,11 @@ void musig_state_machine_tests(secp256k1_scratch_space *scratch) { secp256k1_testrand256(sk[0]); secp256k1_testrand256(sk[1]); secp256k1_testrand256(msg); + pk_ptr[0] = &pk[0]; + pk_ptr[1] = &pk[1]; CHECK(secp256k1_xonly_pubkey_create(&pk[0], sk[0]) == 1); CHECK(secp256k1_xonly_pubkey_create(&pk[1], sk[1]) == 1); - CHECK(secp256k1_musig_pubkey_combine(ctx, scratch, &combined_pk, &pre_session, pk, 2) == 1); + CHECK(secp256k1_musig_pubkey_combine(ctx, scratch, &combined_pk, &pre_session, pk_ptr, 2) == 1); CHECK(secp256k1_musig_session_init(ctx, &session[0], signers0, nonce_commitment[0], session_id[0], msg, &combined_pk, &pre_session, 2, sk[0]) == 1); CHECK(secp256k1_musig_session_init(ctx, &session[1], signers1, nonce_commitment[1], session_id[1], msg, &combined_pk, &pre_session, 2, sk[1]) == 1); /* Can't combine nonces unless we're through round 1 already */ @@ -736,7 +748,9 @@ void scriptless_atomic_swap(secp256k1_scratch_space *scratch) { unsigned char seckey_a[2][32]; unsigned char seckey_b[2][32]; secp256k1_xonly_pubkey pk_a[2]; + const secp256k1_xonly_pubkey *pk_a_ptr[2]; secp256k1_xonly_pubkey pk_b[2]; + const secp256k1_xonly_pubkey *pk_b_ptr[2]; secp256k1_musig_pre_session pre_session_a; secp256k1_musig_pre_session pre_session_b; secp256k1_xonly_pubkey combined_pk_a; @@ -765,14 +779,18 @@ void scriptless_atomic_swap(secp256k1_scratch_space *scratch) { secp256k1_testrand256(seckey_b[1]); secp256k1_testrand256(sec_adaptor); + pk_a_ptr[0] = &pk_a[0]; + pk_a_ptr[1] = &pk_a[1]; + pk_b_ptr[0] = &pk_b[0]; + pk_b_ptr[1] = &pk_b[1]; CHECK(secp256k1_xonly_pubkey_create(&pk_a[0], seckey_a[0])); CHECK(secp256k1_xonly_pubkey_create(&pk_a[1], seckey_a[1])); CHECK(secp256k1_xonly_pubkey_create(&pk_b[0], seckey_b[0])); CHECK(secp256k1_xonly_pubkey_create(&pk_b[1], seckey_b[1])); CHECK(secp256k1_ec_pubkey_create(ctx, &pub_adaptor, sec_adaptor)); - CHECK(secp256k1_musig_pubkey_combine(ctx, scratch, &combined_pk_a, &pre_session_a, pk_a, 2)); - CHECK(secp256k1_musig_pubkey_combine(ctx, scratch, &combined_pk_b, &pre_session_b, pk_b, 2)); + CHECK(secp256k1_musig_pubkey_combine(ctx, scratch, &combined_pk_a, &pre_session_a, pk_a_ptr, 2)); + CHECK(secp256k1_musig_pubkey_combine(ctx, scratch, &combined_pk_b, &pre_session_b, pk_b_ptr, 2)); CHECK(secp256k1_musig_session_init(ctx, &musig_session_a[0], data_a, noncommit_a[0], seed, msg32_a, &combined_pk_a, &pre_session_a, 2, seckey_a[0])); CHECK(secp256k1_musig_session_init(ctx, &musig_session_a[1], data_a, noncommit_a[1], seed, msg32_a, &combined_pk_a, &pre_session_a, 2, seckey_a[1])); @@ -909,6 +927,7 @@ void musig_tweak_test_helper(const secp256k1_xonly_pubkey* combined_pubkey, cons void musig_tweak_test(secp256k1_scratch_space *scratch) { unsigned char sk[2][32]; secp256k1_xonly_pubkey pk[2]; + const secp256k1_xonly_pubkey *pk_ptr[2]; secp256k1_musig_pre_session pre_session_P; secp256k1_musig_pre_session pre_session_Q; secp256k1_xonly_pubkey P; @@ -927,9 +946,11 @@ void musig_tweak_test(secp256k1_scratch_space *scratch) { secp256k1_testrand256(sk[1]); secp256k1_testrand256(contract); + pk_ptr[0] = &pk[0]; + pk_ptr[1] = &pk[1]; CHECK(secp256k1_xonly_pubkey_create(&pk[0], sk[0]) == 1); CHECK(secp256k1_xonly_pubkey_create(&pk[1], sk[1]) == 1); - CHECK(secp256k1_musig_pubkey_combine(ctx, scratch, &P, &pre_session_P, pk, 2) == 1); + CHECK(secp256k1_musig_pubkey_combine(ctx, scratch, &P, &pre_session_P, pk_ptr, 2) == 1); CHECK(secp256k1_xonly_pubkey_serialize(ctx, P_serialized, &P) == 1); secp256k1_sha256_initialize(&sha); @@ -951,7 +972,8 @@ void musig_tweak_test(secp256k1_scratch_space *scratch) { } void musig_test_vectors_helper(unsigned char pk_ser[][32], int n_pks, const unsigned char *combined_pk_expected, int has_second_pk, int second_pk_idx) { - secp256k1_xonly_pubkey *pk = malloc(n_pks * sizeof(secp256k1_xonly_pubkey)); + secp256k1_xonly_pubkey *pk = malloc(n_pks * sizeof(*pk)); + const secp256k1_xonly_pubkey **pk_ptr = malloc(n_pks * sizeof(*pk_ptr)); secp256k1_xonly_pubkey combined_pk; unsigned char combined_pk_ser[32]; secp256k1_musig_pre_session pre_session; @@ -960,9 +982,10 @@ void musig_test_vectors_helper(unsigned char pk_ser[][32], int n_pks, const unsi for (i = 0; i < n_pks; i++) { CHECK(secp256k1_xonly_pubkey_parse(ctx, &pk[i], pk_ser[i])); + pk_ptr[i] = &pk[i]; } - CHECK(secp256k1_musig_pubkey_combine(ctx, NULL, &combined_pk, &pre_session, pk, n_pks) == 1); + CHECK(secp256k1_musig_pubkey_combine(ctx, NULL, &combined_pk, &pre_session, pk_ptr, n_pks) == 1); CHECK(secp256k1_fe_set_b32(&second_pk_x, pre_session.second_pk)); CHECK(secp256k1_fe_is_zero(&second_pk_x) == !has_second_pk); if (!secp256k1_fe_is_zero(&second_pk_x)) { @@ -982,6 +1005,7 @@ void musig_test_vectors_helper(unsigned char pk_ser[][32], int n_pks, const unsi /* printf("};\n"); */ CHECK(secp256k1_memcmp_var(combined_pk_ser, combined_pk_expected, sizeof(combined_pk_ser)) == 0); free(pk); + free(pk_ptr); } void musig_test_vectors(void) {