|
|
|
|
@@ -34,7 +34,7 @@ static int create_keypair_and_pk(secp256k1_keypair *keypair, secp256k1_pubkey *p
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Just a simple (non-tweaked) 2-of-2 MuSig aggregate, sign, verify
|
|
|
|
|
/* Just a simple (non-adaptor, non-tweaked) 2-of-2 MuSig aggregate, sign, verify
|
|
|
|
|
* test. */
|
|
|
|
|
static void musig_simple_test(void) {
|
|
|
|
|
unsigned char sk[2][32];
|
|
|
|
|
@@ -74,7 +74,7 @@ static void musig_simple_test(void) {
|
|
|
|
|
|
|
|
|
|
CHECK(secp256k1_musig_pubkey_agg(CTX, &agg_pk, &keyagg_cache, pk_ptr, 2) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_nonce_agg(CTX, &aggnonce, pubnonce_ptr, 2) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, &keyagg_cache) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, &keyagg_cache, NULL) == 1);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
|
CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig[i], &secnonce[i], &keypair[i], &keyagg_cache, &session) == 1);
|
|
|
|
|
@@ -123,6 +123,7 @@ static void musig_api_tests(void) {
|
|
|
|
|
const secp256k1_musig_partial_sig *partial_sig_ptr[2];
|
|
|
|
|
secp256k1_musig_partial_sig invalid_partial_sig;
|
|
|
|
|
const secp256k1_musig_partial_sig *invalid_partial_sig_ptr[2];
|
|
|
|
|
unsigned char final_sig[64];
|
|
|
|
|
unsigned char pre_sig[64];
|
|
|
|
|
unsigned char buf[32];
|
|
|
|
|
unsigned char sk[2][32];
|
|
|
|
|
@@ -157,6 +158,10 @@ static void musig_api_tests(void) {
|
|
|
|
|
const secp256k1_pubkey *invalid_pk_ptr2[2];
|
|
|
|
|
const secp256k1_pubkey *invalid_pk_ptr3[3];
|
|
|
|
|
unsigned char tweak[32];
|
|
|
|
|
int nonce_parity;
|
|
|
|
|
unsigned char sec_adaptor[32];
|
|
|
|
|
unsigned char sec_adaptor1[32];
|
|
|
|
|
secp256k1_pubkey adaptor;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
/** setup **/
|
|
|
|
|
@@ -174,8 +179,10 @@ static void musig_api_tests(void) {
|
|
|
|
|
memset(&invalid_pubnonce, 0, sizeof(invalid_pubnonce));
|
|
|
|
|
memset(&invalid_session, 0, sizeof(invalid_session));
|
|
|
|
|
|
|
|
|
|
testrand256(sec_adaptor);
|
|
|
|
|
testrand256(msg);
|
|
|
|
|
testrand256(tweak);
|
|
|
|
|
CHECK(secp256k1_ec_pubkey_create(CTX, &adaptor, sec_adaptor) == 1);
|
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
|
pk_ptr[i] = &pk[i];
|
|
|
|
|
invalid_pk_ptr2[i] = &invalid_pk;
|
|
|
|
|
@@ -388,15 +395,17 @@ static void musig_api_tests(void) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Process nonces **/
|
|
|
|
|
CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, &keyagg_cache) == 1);
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, NULL, &aggnonce, msg, &keyagg_cache));
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, &session, NULL, msg, &keyagg_cache));
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, &session, (secp256k1_musig_aggnonce*) &invalid_pubnonce, msg, &keyagg_cache));
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, &session, &aggnonce, NULL, &keyagg_cache));
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, NULL));
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, &invalid_keyagg_cache));
|
|
|
|
|
CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, &keyagg_cache, &adaptor) == 1);
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, NULL, &aggnonce, msg, &keyagg_cache, &adaptor));
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, &session, NULL, msg, &keyagg_cache, &adaptor));
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, &session, (secp256k1_musig_aggnonce*) &invalid_pubnonce, msg, &keyagg_cache, &adaptor));
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, &session, &aggnonce, NULL, &keyagg_cache, &adaptor));
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, NULL, &adaptor));
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, &invalid_keyagg_cache, &adaptor));
|
|
|
|
|
CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, &keyagg_cache, NULL) == 1);
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, &keyagg_cache, (secp256k1_pubkey *)&invalid_pk));
|
|
|
|
|
|
|
|
|
|
CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, &keyagg_cache) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, &keyagg_cache, &adaptor) == 1);
|
|
|
|
|
|
|
|
|
|
memcpy(&secnonce_tmp, &secnonce[0], sizeof(secnonce_tmp));
|
|
|
|
|
CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce_tmp, &keypair[0], &keyagg_cache, &session) == 1);
|
|
|
|
|
@@ -481,6 +490,40 @@ static void musig_api_tests(void) {
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_partial_sig_agg(CTX, pre_sig, &session, partial_sig_ptr, 0));
|
|
|
|
|
CHECK(secp256k1_musig_partial_sig_agg(CTX, pre_sig, &session, partial_sig_ptr, 1) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_partial_sig_agg(CTX, pre_sig, &session, partial_sig_ptr, 2) == 1);
|
|
|
|
|
|
|
|
|
|
/** Adaptor signature verification */
|
|
|
|
|
CHECK(secp256k1_musig_nonce_parity(CTX, &nonce_parity, &session) == 1);
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_parity(CTX, NULL, &session));
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_parity(CTX, &nonce_parity, NULL));
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_nonce_parity(CTX, &nonce_parity, &invalid_session));
|
|
|
|
|
|
|
|
|
|
CHECK(secp256k1_musig_adapt(CTX, final_sig, pre_sig, sec_adaptor, nonce_parity) == 1);
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_adapt(CTX, NULL, pre_sig, sec_adaptor, 0));
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_adapt(CTX, final_sig, NULL, sec_adaptor, 0));
|
|
|
|
|
CHECK(secp256k1_musig_adapt(CTX, final_sig, max64, sec_adaptor, 0) == 0);
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_adapt(CTX, final_sig, pre_sig, NULL, 0));
|
|
|
|
|
CHECK(secp256k1_musig_adapt(CTX, final_sig, pre_sig, max64, 0) == 0);
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_adapt(CTX, final_sig, pre_sig, sec_adaptor, 2));
|
|
|
|
|
/* sig and pre_sig argument point to the same location */
|
|
|
|
|
memcpy(final_sig, pre_sig, sizeof(final_sig));
|
|
|
|
|
CHECK(secp256k1_musig_adapt(CTX, final_sig, final_sig, sec_adaptor, nonce_parity) == 1);
|
|
|
|
|
CHECK(secp256k1_schnorrsig_verify(CTX, final_sig, msg, sizeof(msg), &agg_pk) == 1);
|
|
|
|
|
|
|
|
|
|
CHECK(secp256k1_musig_adapt(CTX, final_sig, pre_sig, sec_adaptor, nonce_parity) == 1);
|
|
|
|
|
CHECK(secp256k1_schnorrsig_verify(CTX, final_sig, msg, sizeof(msg), &agg_pk) == 1);
|
|
|
|
|
|
|
|
|
|
/** Secret adaptor can be extracted from signature */
|
|
|
|
|
CHECK(secp256k1_musig_extract_adaptor(CTX, sec_adaptor1, final_sig, pre_sig, nonce_parity) == 1);
|
|
|
|
|
CHECK(secp256k1_memcmp_var(sec_adaptor, sec_adaptor1, 32) == 0);
|
|
|
|
|
/* wrong nonce parity */
|
|
|
|
|
CHECK(secp256k1_musig_extract_adaptor(CTX, sec_adaptor1, final_sig, pre_sig, !nonce_parity) == 1);
|
|
|
|
|
CHECK(secp256k1_memcmp_var(sec_adaptor, sec_adaptor1, 32) != 0);
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_extract_adaptor(CTX, NULL, final_sig, pre_sig, 0));
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_extract_adaptor(CTX, sec_adaptor1, NULL, pre_sig, 0));
|
|
|
|
|
CHECK(secp256k1_musig_extract_adaptor(CTX, sec_adaptor1, max64, pre_sig, 0) == 0);
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_extract_adaptor(CTX, sec_adaptor1, final_sig, NULL, 0));
|
|
|
|
|
CHECK(secp256k1_musig_extract_adaptor(CTX, sec_adaptor1, final_sig, max64, 0) == 0);
|
|
|
|
|
CHECK_ILLEGAL(CTX, secp256k1_musig_extract_adaptor(CTX, sec_adaptor1, final_sig, pre_sig, 2));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void musig_nonce_bitflip(unsigned char **args, size_t n_flip, size_t n_bytes) {
|
|
|
|
|
@@ -548,6 +591,111 @@ static void musig_nonce_test(void) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void scriptless_atomic_swap(void) {
|
|
|
|
|
/* Throughout this test "a" and "b" refer to two hypothetical blockchains,
|
|
|
|
|
* while the indices 0 and 1 refer to the two signers. Here signer 0 is
|
|
|
|
|
* sending a-coins to signer 1, while signer 1 is sending b-coins to signer
|
|
|
|
|
* 0. Signer 0 produces the adaptor signatures. */
|
|
|
|
|
unsigned char pre_sig_a[64];
|
|
|
|
|
unsigned char final_sig_a[64];
|
|
|
|
|
unsigned char pre_sig_b[64];
|
|
|
|
|
unsigned char final_sig_b[64];
|
|
|
|
|
secp256k1_musig_partial_sig partial_sig_a[2];
|
|
|
|
|
const secp256k1_musig_partial_sig *partial_sig_a_ptr[2];
|
|
|
|
|
secp256k1_musig_partial_sig partial_sig_b[2];
|
|
|
|
|
const secp256k1_musig_partial_sig *partial_sig_b_ptr[2];
|
|
|
|
|
unsigned char sec_adaptor[32];
|
|
|
|
|
unsigned char sec_adaptor_extracted[32];
|
|
|
|
|
secp256k1_pubkey pub_adaptor;
|
|
|
|
|
unsigned char sk_a[2][32];
|
|
|
|
|
unsigned char sk_b[2][32];
|
|
|
|
|
secp256k1_keypair keypair_a[2];
|
|
|
|
|
secp256k1_keypair keypair_b[2];
|
|
|
|
|
secp256k1_pubkey pk_a[2];
|
|
|
|
|
const secp256k1_pubkey *pk_a_ptr[2];
|
|
|
|
|
secp256k1_pubkey pk_b[2];
|
|
|
|
|
const secp256k1_pubkey *pk_b_ptr[2];
|
|
|
|
|
secp256k1_musig_keyagg_cache keyagg_cache_a;
|
|
|
|
|
secp256k1_musig_keyagg_cache keyagg_cache_b;
|
|
|
|
|
secp256k1_xonly_pubkey agg_pk_a;
|
|
|
|
|
secp256k1_xonly_pubkey agg_pk_b;
|
|
|
|
|
secp256k1_musig_secnonce secnonce_a[2];
|
|
|
|
|
secp256k1_musig_secnonce secnonce_b[2];
|
|
|
|
|
secp256k1_musig_pubnonce pubnonce_a[2];
|
|
|
|
|
secp256k1_musig_pubnonce pubnonce_b[2];
|
|
|
|
|
const secp256k1_musig_pubnonce *pubnonce_ptr_a[2];
|
|
|
|
|
const secp256k1_musig_pubnonce *pubnonce_ptr_b[2];
|
|
|
|
|
secp256k1_musig_aggnonce aggnonce_a;
|
|
|
|
|
secp256k1_musig_aggnonce aggnonce_b;
|
|
|
|
|
secp256k1_musig_session session_a, session_b;
|
|
|
|
|
int nonce_parity_a;
|
|
|
|
|
int nonce_parity_b;
|
|
|
|
|
unsigned char seed_a[2][32] = { "a0", "a1" };
|
|
|
|
|
unsigned char seed_b[2][32] = { "b0", "b1" };
|
|
|
|
|
const unsigned char msg32_a[32] = {'t', 'h', 'i', 's', ' ', 'i', 's', ' ', 't', 'h', 'e', ' ', 'm', 'e', 's', 's', 'a', 'g', 'e', ' ', 'b', 'l', 'o', 'c', 'k', 'c', 'h', 'a', 'i', 'n', ' ', 'a'};
|
|
|
|
|
const unsigned char msg32_b[32] = {'t', 'h', 'i', 's', ' ', 'i', 's', ' ', 't', 'h', 'e', ' ', 'm', 'e', 's', 's', 'a', 'g', 'e', ' ', 'b', 'l', 'o', 'c', 'k', 'c', 'h', 'a', 'i', 'n', ' ', 'b'};
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
/* Step 1: key setup */
|
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
|
pk_a_ptr[i] = &pk_a[i];
|
|
|
|
|
pk_b_ptr[i] = &pk_b[i];
|
|
|
|
|
pubnonce_ptr_a[i] = &pubnonce_a[i];
|
|
|
|
|
pubnonce_ptr_b[i] = &pubnonce_b[i];
|
|
|
|
|
partial_sig_a_ptr[i] = &partial_sig_a[i];
|
|
|
|
|
partial_sig_b_ptr[i] = &partial_sig_b[i];
|
|
|
|
|
|
|
|
|
|
testrand256(sk_a[i]);
|
|
|
|
|
testrand256(sk_b[i]);
|
|
|
|
|
CHECK(create_keypair_and_pk(&keypair_a[i], &pk_a[i], sk_a[i]) == 1);
|
|
|
|
|
CHECK(create_keypair_and_pk(&keypair_b[i], &pk_b[i], sk_b[i]) == 1);
|
|
|
|
|
}
|
|
|
|
|
testrand256(sec_adaptor);
|
|
|
|
|
CHECK(secp256k1_ec_pubkey_create(CTX, &pub_adaptor, sec_adaptor) == 1);
|
|
|
|
|
|
|
|
|
|
CHECK(secp256k1_musig_pubkey_agg(CTX, &agg_pk_a, &keyagg_cache_a, pk_a_ptr, 2) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_pubkey_agg(CTX, &agg_pk_b, &keyagg_cache_b, pk_b_ptr, 2) == 1);
|
|
|
|
|
|
|
|
|
|
CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce_a[0], &pubnonce_a[0], seed_a[0], sk_a[0], &pk_a[0], NULL, NULL, NULL) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce_a[1], &pubnonce_a[1], seed_a[1], sk_a[1], &pk_a[1], NULL, NULL, NULL) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce_b[0], &pubnonce_b[0], seed_b[0], sk_b[0], &pk_b[0], NULL, NULL, NULL) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce_b[1], &pubnonce_b[1], seed_b[1], sk_b[1], &pk_b[1], NULL, NULL, NULL) == 1);
|
|
|
|
|
|
|
|
|
|
/* Step 2: Exchange nonces */
|
|
|
|
|
CHECK(secp256k1_musig_nonce_agg(CTX, &aggnonce_a, pubnonce_ptr_a, 2) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_nonce_process(CTX, &session_a, &aggnonce_a, msg32_a, &keyagg_cache_a, &pub_adaptor) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_nonce_parity(CTX, &nonce_parity_a, &session_a) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_nonce_agg(CTX, &aggnonce_b, pubnonce_ptr_b, 2) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_nonce_process(CTX, &session_b, &aggnonce_b, msg32_b, &keyagg_cache_b, &pub_adaptor) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_nonce_parity(CTX, &nonce_parity_b, &session_b) == 1);
|
|
|
|
|
|
|
|
|
|
/* Step 3: Signer 0 produces partial signatures for both chains. */
|
|
|
|
|
CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig_a[0], &secnonce_a[0], &keypair_a[0], &keyagg_cache_a, &session_a) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig_b[0], &secnonce_b[0], &keypair_b[0], &keyagg_cache_b, &session_b) == 1);
|
|
|
|
|
|
|
|
|
|
/* Step 4: Signer 1 receives partial signatures, verifies them and creates a
|
|
|
|
|
* partial signature to send B-coins to signer 0. */
|
|
|
|
|
CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig_a[0], &pubnonce_a[0], &pk_a[0], &keyagg_cache_a, &session_a) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_partial_sig_verify(CTX, &partial_sig_b[0], &pubnonce_b[0], &pk_b[0], &keyagg_cache_b, &session_b) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig_b[1], &secnonce_b[1], &keypair_b[1], &keyagg_cache_b, &session_b) == 1);
|
|
|
|
|
|
|
|
|
|
/* Step 5: Signer 0 aggregates its own partial signature with the partial
|
|
|
|
|
* signature from signer 1 and adapts it. This results in a complete
|
|
|
|
|
* signature which is broadcasted by signer 0 to take B-coins. */
|
|
|
|
|
CHECK(secp256k1_musig_partial_sig_agg(CTX, pre_sig_b, &session_b, partial_sig_b_ptr, 2) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_adapt(CTX, final_sig_b, pre_sig_b, sec_adaptor, nonce_parity_b) == 1);
|
|
|
|
|
CHECK(secp256k1_schnorrsig_verify(CTX, final_sig_b, msg32_b, sizeof(msg32_b), &agg_pk_b) == 1);
|
|
|
|
|
|
|
|
|
|
/* Step 6: Signer 1 signs, extracts adaptor from the published signature,
|
|
|
|
|
* and adapts the signature to take A-coins. */
|
|
|
|
|
CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig_a[1], &secnonce_a[1], &keypair_a[1], &keyagg_cache_a, &session_a) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_partial_sig_agg(CTX, pre_sig_a, &session_a, partial_sig_a_ptr, 2) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_extract_adaptor(CTX, sec_adaptor_extracted, final_sig_b, pre_sig_b, nonce_parity_b) == 1);
|
|
|
|
|
CHECK(secp256k1_memcmp_var(sec_adaptor_extracted, sec_adaptor, sizeof(sec_adaptor)) == 0); /* in real life we couldn't check this, of course */
|
|
|
|
|
CHECK(secp256k1_musig_adapt(CTX, final_sig_a, pre_sig_a, sec_adaptor_extracted, nonce_parity_a) == 1);
|
|
|
|
|
CHECK(secp256k1_schnorrsig_verify(CTX, final_sig_a, msg32_a, sizeof(msg32_a), &agg_pk_a) == 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void sha256_tag_test_internal(secp256k1_sha256 *sha_tagged, unsigned char *tag, size_t taglen) {
|
|
|
|
|
secp256k1_sha256 sha;
|
|
|
|
|
secp256k1_sha256_initialize_tagged(&sha, tag, taglen);
|
|
|
|
|
@@ -616,7 +764,7 @@ static void musig_tweak_test_helper(const secp256k1_xonly_pubkey* agg_pk, const
|
|
|
|
|
CHECK(secp256k1_musig_nonce_gen(CTX, &secnonce[1], &pubnonce[1], session_secrand[1], sk1, &pk[1], NULL, NULL, NULL) == 1);
|
|
|
|
|
|
|
|
|
|
CHECK(secp256k1_musig_nonce_agg(CTX, &aggnonce, pubnonce_ptr, 2) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, keyagg_cache) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, msg, keyagg_cache, NULL) == 1);
|
|
|
|
|
|
|
|
|
|
CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig[0], &secnonce[0], &keypair[0], keyagg_cache, &session) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig[1], &secnonce[1], &keypair[1], keyagg_cache, &session) == 1);
|
|
|
|
|
@@ -882,7 +1030,7 @@ static void musig_test_vectors_signverify(void) {
|
|
|
|
|
CHECK(musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, NULL, vector->pubkeys, NULL, c->key_indices_len, c->key_indices, 0, NULL, NULL));
|
|
|
|
|
|
|
|
|
|
CHECK(secp256k1_musig_aggnonce_parse(CTX, &aggnonce, vector->aggnonces[c->aggnonce_index]));
|
|
|
|
|
CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, vector->msgs[c->msg_index], &keyagg_cache));
|
|
|
|
|
CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, vector->msgs[c->msg_index], &keyagg_cache, NULL));
|
|
|
|
|
|
|
|
|
|
CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, vector->pubkeys[0], sizeof(vector->pubkeys[0])));
|
|
|
|
|
musig_test_set_secnonce(&secnonce, vector->secnonces[0], &pubkey);
|
|
|
|
|
@@ -922,8 +1070,9 @@ static void musig_test_vectors_signverify(void) {
|
|
|
|
|
if (!expected) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, vector->msgs[c->msg_index], &keyagg_cache));
|
|
|
|
|
CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, vector->msgs[c->msg_index], &keyagg_cache, NULL));
|
|
|
|
|
|
|
|
|
|
CHECK(secp256k1_keypair_create(CTX, &keypair, vector->sk));
|
|
|
|
|
CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, vector->pubkeys[0], sizeof(vector->pubkeys[0])));
|
|
|
|
|
musig_test_set_secnonce(&secnonce, vector->secnonces[c->secnonce_index], &pubkey);
|
|
|
|
|
expected = c->error != MUSIG_SECNONCE;
|
|
|
|
|
@@ -955,7 +1104,7 @@ static void musig_test_vectors_signverify(void) {
|
|
|
|
|
|
|
|
|
|
CHECK(musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, NULL, vector->pubkeys, NULL, c->key_indices_len, c->key_indices, 0, NULL, NULL));
|
|
|
|
|
CHECK(secp256k1_musig_nonce_agg(CTX, &aggnonce, pubnonce_ptr, c->nonce_indices_len) == 1);
|
|
|
|
|
CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, vector->msgs[c->msg_index], &keyagg_cache));
|
|
|
|
|
CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, vector->msgs[c->msg_index], &keyagg_cache, NULL));
|
|
|
|
|
|
|
|
|
|
CHECK(secp256k1_ec_pubkey_parse(CTX, &pubkey, vector->pubkeys[c->signer_index], sizeof(vector->pubkeys[0])));
|
|
|
|
|
|
|
|
|
|
@@ -1010,7 +1159,7 @@ static void musig_test_vectors_tweak(void) {
|
|
|
|
|
CHECK(secp256k1_keypair_create(CTX, &keypair, vector->sk));
|
|
|
|
|
CHECK(musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, NULL, vector->pubkeys, vector->tweaks, c->key_indices_len, c->key_indices, c->tweak_indices_len, c->tweak_indices, c->is_xonly));
|
|
|
|
|
|
|
|
|
|
CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, vector->msg, &keyagg_cache));
|
|
|
|
|
CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, vector->msg, &keyagg_cache, NULL));
|
|
|
|
|
|
|
|
|
|
CHECK(secp256k1_musig_partial_sign(CTX, &partial_sig, &secnonce, &keypair, &keyagg_cache, &session));
|
|
|
|
|
CHECK(secp256k1_musig_partial_sig_serialize(CTX, partial_sig32, &partial_sig));
|
|
|
|
|
@@ -1046,7 +1195,7 @@ static void musig_test_vectors_sigagg(void) {
|
|
|
|
|
|
|
|
|
|
CHECK(musig_vectors_keyagg_and_tweak(&error, &keyagg_cache, agg_pk32, vector->pubkeys, vector->tweaks, c->key_indices_len, c->key_indices, c->tweak_indices_len, c->tweak_indices, c->is_xonly));
|
|
|
|
|
CHECK(secp256k1_musig_aggnonce_parse(CTX, &aggnonce, c->aggnonce));
|
|
|
|
|
CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, vector->msg, &keyagg_cache));
|
|
|
|
|
CHECK(secp256k1_musig_nonce_process(CTX, &session, &aggnonce, vector->msg, &keyagg_cache, NULL));
|
|
|
|
|
for (j = 0; j < c->psig_indices_len; j++) {
|
|
|
|
|
CHECK(secp256k1_musig_partial_sig_parse(CTX, &partial_sig[j], vector->psigs[c->psig_indices[j]]));
|
|
|
|
|
partial_sig_ptr[j] = &partial_sig[j];
|
|
|
|
|
@@ -1127,6 +1276,7 @@ static void run_musig_tests(void) {
|
|
|
|
|
for (i = 0; i < COUNT; i++) {
|
|
|
|
|
/* Run multiple times to ensure that pk and nonce have different y
|
|
|
|
|
* parities */
|
|
|
|
|
scriptless_atomic_swap();
|
|
|
|
|
musig_tweak_test();
|
|
|
|
|
}
|
|
|
|
|
sha256_tag_test();
|
|
|
|
|
|