From d35cc953aba5ef4129a0a4aa3cd1b446070d888d Mon Sep 17 00:00:00 2001 From: yeastplume Date: Sun, 7 Jan 2018 00:01:51 +0000 Subject: [PATCH] partial+combined sig validation working --- include/secp256k1_aggsig.h | 15 ++-- src/modules/aggsig/main_impl.h | 129 ++++++++++---------------------- src/modules/aggsig/tests_impl.h | 51 +++++++------ 3 files changed, 75 insertions(+), 120 deletions(-) diff --git a/include/secp256k1_aggsig.h b/include/secp256k1_aggsig.h index e232fc5..f61ccbc 100644 --- a/include/secp256k1_aggsig.h +++ b/include/secp256k1_aggsig.h @@ -116,10 +116,10 @@ SECP256K1_API int secp256k1_aggsig_sign_single( const unsigned char *msg32, const unsigned char *seckey32, const unsigned char* secnonce32, - const secp256k1_pubkey *pubnonce, - const unsigned int negate, + const secp256k1_pubkey *pubnonce_for_e, + const secp256k1_pubkey* pubnonce_total, const unsigned char* seed) -SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(8) SECP256K1_WARN_UNUSED_RESULT; +SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(8) SECP256K1_WARN_UNUSED_RESULT; /** Generate a single signature part in an aggregated signature * @@ -174,9 +174,8 @@ SECP256K1_API int secp256k1_aggsig_add_signatures_single( unsigned char *sig64, const unsigned char* sig1_64, const unsigned char* sig2_64, - secp256k1_pubkey* pubnonce1, - secp256k1_pubkey* pubnonce2 -) 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_WARN_UNUSED_RESULT; + const secp256k1_pubkey* pubnonce_total +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_WARN_UNUSED_RESULT; /** Verify a single-signer signature, without a stored context @@ -193,7 +192,8 @@ int secp256k1_aggsig_verify_single( const unsigned char *sig64, const unsigned char *msg32, const secp256k1_pubkey *pubnonce, - const secp256k1_pubkey *pubkey) + const secp256k1_pubkey *pubkey, + int is_partial) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5) SECP256K1_WARN_UNUSED_RESULT; /** Verify an aggregate signature @@ -233,7 +233,6 @@ SECP256K1_API int secp256k1_aggsig_build_scratch_and_verify( size_t n_pubkeys ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_WARN_UNUSED_RESULT; -SECP256K1_API int secp256k1_aggsig_add_pubnonces_single(const secp256k1_context* ctx, secp256k1_pubkey* pubnonce, unsigned int* negate, const secp256k1_pubkey* pubnonce1, const secp256k1_pubkey* pubnonce2); # ifdef __cplusplus } # endif diff --git a/src/modules/aggsig/main_impl.h b/src/modules/aggsig/main_impl.h index e67ab28..e9c552d 100644 --- a/src/modules/aggsig/main_impl.h +++ b/src/modules/aggsig/main_impl.h @@ -183,15 +183,17 @@ int secp256k1_aggsig_sign_single(const secp256k1_context* ctx, const unsigned char *msg32, const unsigned char *seckey32, const unsigned char* secnonce32, - const secp256k1_pubkey* pubnonce, - const unsigned int negate, + const secp256k1_pubkey* pubnonce_for_e, + const secp256k1_pubkey* pubnonce_total, const unsigned char* seed){ secp256k1_scalar sighash; secp256k1_rfc6979_hmac_sha256 rng; secp256k1_scalar sec; secp256k1_ge tmp_ge; + secp256k1_ge total_tmp_ge; secp256k1_gej pubnonce_j; + secp256k1_gej pubnonce_total_j; secp256k1_pubkey pub_tmp; secp256k1_scalar secnonce; @@ -213,54 +215,32 @@ int secp256k1_aggsig_sign_single(const secp256k1_context* ctx, } secp256k1_rfc6979_hmac_sha256_finalize(&rng); secp256k1_ge_set_gej(&tmp_ge, &pubnonce_j); - if (!secp256k1_gej_has_quad_y_var(&pubnonce_j)) { - secp256k1_scalar_negate(&secnonce, &secnonce); - secp256k1_gej_neg(&pubnonce_j, &pubnonce_j); - } - secp256k1_fe_normalize(&tmp_ge.x); } else { - /* Use existing nonce */ - /* Calculate what this + pub nonce would be normally */ secp256k1_scalar_set_b32(&secnonce, secnonce32, &retry); - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pubnonce_j, &secnonce); - /* Negate nonce if needed to get y to be a quadratic residue */ - if (!secp256k1_gej_has_quad_y_var(&pubnonce_j)) { - printf("NO QUAD Y VAR\n"); - /* Comment out: partial validation doesn't work, - * leave in: summed validation doesn't work */ - /*secp256k1_scalar_negate(&secnonce, &secnonce);*/ - } - + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pubnonce_j, &secnonce); secp256k1_ge_set_gej(&tmp_ge, &pubnonce_j); - /* And negate if it should be negated */ - if (negate) { - printf("NEGATE\n"); - secp256k1_scalar_negate(&secnonce, &secnonce); - secp256k1_gej_neg(&pubnonce_j, &pubnonce_j); - secp256k1_ge_set_gej(&tmp_ge, &pubnonce_j); + if (pubnonce_total!=NULL) { + secp256k1_gej_set_infinity(&pubnonce_total_j); + secp256k1_pubkey_load(ctx, &total_tmp_ge, pubnonce_total); + secp256k1_gej_add_ge(&pubnonce_total_j, &pubnonce_total_j, &total_tmp_ge); + if (!secp256k1_gej_has_quad_y_var(&pubnonce_total_j)) { + secp256k1_scalar_negate(&secnonce, &secnonce); + } + } else { + if (!secp256k1_gej_has_quad_y_var(&pubnonce_j)) { + secp256k1_scalar_negate(&secnonce, &secnonce); + secp256k1_gej_neg(&pubnonce_j, &pubnonce_j); + secp256k1_ge_neg(&tmp_ge, &tmp_ge); + } } - - /*if ((no_quad_y && !negate) || (!no_quad_y && negate)){ - printf("WAT DOO TO ALLOW PARTIAL CHECK TO WORK?\n"); - }*/ - secp256k1_fe_normalize(&tmp_ge.x); } -#if 0 - if (!secp256k1_gej_has_quad_y_var(&pubnonce_j)) { - printf("Should negate....\n"); - /*secp256k1_gej_neg(&pubnonce_j, &pubnonce_j);*/ - secp256k1_scalar_negate(&secnonce, &secnonce); - /*secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pubnonce_j, &secnonce);*/ - secp256k1_ge_neg(&tmp_ge, &tmp_ge); - } -#endif - /*secp256k1_fe_normalize(&tmp_ge.x);*/ + secp256k1_fe_normalize(&tmp_ge.x); /* compute signature hash (in the simple case just message+pubnonce) */ - if (pubnonce != NULL) { - secp256k1_compute_sighash_single(ctx, &sighash, pubnonce, msg32); + if (pubnonce_for_e != NULL) { + secp256k1_compute_sighash_single(ctx, &sighash, pubnonce_for_e, msg32); } else { secp256k1_pubkey_save(&pub_tmp, &tmp_ge); secp256k1_compute_sighash_single(ctx, &sighash, &pub_tmp, msg32); @@ -380,50 +360,19 @@ int secp256k1_aggsig_combine_signatures(const secp256k1_context* ctx, secp256k1_ return 1; } - -int secp256k1_aggsig_add_pubnonces_single(const secp256k1_context* ctx, secp256k1_pubkey* pubnonce, unsigned int* negate, const secp256k1_pubkey* pubnonce1, const secp256k1_pubkey* pubnonce2) { - secp256k1_gej pubnonce_sum; - secp256k1_ge noncesum_pt; - secp256k1_ge tmp_ge; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(pubnonce != NULL); - ARG_CHECK(pubnonce1 != NULL); - ARG_CHECK(pubnonce2 != NULL); - - *negate = 0; - - /* Add nonces together */ - secp256k1_gej_set_infinity(&pubnonce_sum); - secp256k1_pubkey_load(ctx, &noncesum_pt, pubnonce1); - secp256k1_gej_add_ge(&pubnonce_sum, &pubnonce_sum, &noncesum_pt); - secp256k1_pubkey_load(ctx, &noncesum_pt, pubnonce2); - secp256k1_gej_add_ge(&pubnonce_sum, &pubnonce_sum, &noncesum_pt); - - if (!secp256k1_gej_has_quad_y_var(&pubnonce_sum)) { - secp256k1_gej_neg(&pubnonce_sum, &pubnonce_sum); - *negate = 1; - } - - secp256k1_ge_set_gej(&tmp_ge, &pubnonce_sum); - secp256k1_pubkey_save(pubnonce, &tmp_ge); - return 1; -} - -int secp256k1_aggsig_add_signatures_single(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char* sig1_64, const unsigned char* sig2_64, secp256k1_pubkey* pubnonce1, secp256k1_pubkey* pubnonce2) { +int secp256k1_aggsig_add_signatures_single(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char* sig1_64, const unsigned char* sig2_64, const secp256k1_pubkey* pubnonce_total) { secp256k1_scalar s; secp256k1_ge final; secp256k1_scalar tmp; - secp256k1_gej pubnonce_sum; secp256k1_ge noncesum_pt; + secp256k1_gej pubnonce_total_j; int overflow; VERIFY_CHECK(ctx != NULL); ARG_CHECK(sig64 != NULL); ARG_CHECK(sig1_64 != NULL); ARG_CHECK(sig2_64 != NULL); - ARG_CHECK(pubnonce1 != NULL); - ARG_CHECK(pubnonce2 != NULL); + ARG_CHECK(pubnonce_total != NULL); (void) ctx; /* Add signature portions together */ @@ -439,19 +388,16 @@ int secp256k1_aggsig_add_signatures_single(const secp256k1_context* ctx, unsigne } secp256k1_scalar_add(&s, &s, &tmp); - /* Add nonces together */ - secp256k1_gej_set_infinity(&pubnonce_sum); - secp256k1_pubkey_load(ctx, &noncesum_pt, pubnonce1); - secp256k1_gej_add_ge(&pubnonce_sum, &pubnonce_sum, &noncesum_pt); - secp256k1_pubkey_load(ctx, &noncesum_pt, pubnonce2); - secp256k1_gej_add_ge(&pubnonce_sum, &pubnonce_sum, &noncesum_pt); - - if (!secp256k1_gej_has_quad_y_var(&pubnonce_sum)) { - secp256k1_gej_neg(&pubnonce_sum, &pubnonce_sum); + /* nonces should already be totalled */ + secp256k1_gej_set_infinity(&pubnonce_total_j); + secp256k1_pubkey_load(ctx, &noncesum_pt, pubnonce_total); + secp256k1_gej_add_ge(&pubnonce_total_j, &pubnonce_total_j, &noncesum_pt); + if (!secp256k1_gej_has_quad_y_var(&pubnonce_total_j)) { + secp256k1_gej_neg(&pubnonce_total_j, &pubnonce_total_j); } secp256k1_scalar_get_b32(sig64, &s); - secp256k1_ge_set_gej(&final, &pubnonce_sum); + secp256k1_ge_set_gej(&final, &pubnonce_total_j); secp256k1_fe_normalize_var(&final.x); secp256k1_fe_get_b32(sig64 + 32, &final.x); return 1; @@ -546,7 +492,8 @@ int secp256k1_aggsig_verify_single( const unsigned char *sig64, const unsigned char *msg32, const secp256k1_pubkey *pubnonce, - const secp256k1_pubkey *pubkey){ + const secp256k1_pubkey *pubkey, + const int is_partial){ secp256k1_scalar g_sc; secp256k1_fe r_x; @@ -559,6 +506,7 @@ int secp256k1_aggsig_verify_single( secp256k1_pubkey tmp_pk; int overflow; + int return_check=0; VERIFY_CHECK(ctx != NULL); ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); @@ -600,8 +548,13 @@ int secp256k1_aggsig_verify_single( secp256k1_scratch_space_destroy(scratch); secp256k1_ge_set_gej(&pk_sum_ge, &pk_sum); - return secp256k1_fe_equal_var(&r_x, &pk_sum_ge.x) && - secp256k1_gej_has_quad_y_var(&pk_sum); + + return_check = secp256k1_fe_equal_var(&r_x, &pk_sum_ge.x); + if (!is_partial){ + return return_check && secp256k1_gej_has_quad_y_var(&pk_sum); + } else { + return return_check; + } } diff --git a/src/modules/aggsig/tests_impl.h b/src/modules/aggsig/tests_impl.h index 7c67d99..15f7400 100644 --- a/src/modules/aggsig/tests_impl.h +++ b/src/modules/aggsig/tests_impl.h @@ -16,6 +16,7 @@ void test_aggsig_api(void) { secp256k1_context *vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); secp256k1_context *both = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); secp256k1_scratch_space *scratch = secp256k1_scratch_space_create(none, 1024, 4096); + secp256k1_scalar tmp_s; unsigned char seckeys[5][32]; secp256k1_pubkey pubkeys[5]; secp256k1_aggsig_partial_signature partials[5]; @@ -25,12 +26,12 @@ void test_aggsig_api(void) { unsigned char sig2[64]; unsigned char combined_sig[64]; unsigned char sec_nonces[5][32]; - unsigned int negate; secp256k1_pubkey pub_nonces[5]; unsigned char orig_sig; unsigned char *msg = seed; /* shh ;) */ const secp256k1_pubkey* pubkey_combiner[2]; secp256k1_pubkey combiner_sum; + secp256k1_pubkey combiner_sum_2; int32_t ecount = 0; size_t i; @@ -45,7 +46,6 @@ void test_aggsig_api(void) { secp256k1_context_set_illegal_callback(both, counting_illegal_callback_fn, &ecount); for (i = 0; i < 5; i++) { - secp256k1_scalar tmp_s; random_scalar_order_test(&tmp_s); secp256k1_scalar_get_b32(seckeys[i], &tmp_s); CHECK(secp256k1_ec_pubkey_create(ctx, &pubkeys[i], seckeys[i]) == 1); @@ -145,76 +145,79 @@ void test_aggsig_api(void) { /* Test single api */ memset(sig, 0, sizeof(sig)); - CHECK(secp256k1_aggsig_sign_single(sign, sig, msg, seckeys[0], NULL, NULL, 0, seed)); + CHECK(secp256k1_aggsig_sign_single(sign, sig, msg, seckeys[0], NULL, NULL, NULL, seed)); CHECK(ecount == 20); - CHECK(secp256k1_aggsig_verify_single(vrfy, sig, msg, NULL, &pubkeys[0])); - CHECK(!secp256k1_aggsig_verify_single(vrfy, sig, msg, NULL, &pubkeys[1])); + CHECK(secp256k1_aggsig_verify_single(vrfy, sig, msg, NULL, &pubkeys[0], 0)); + CHECK(!secp256k1_aggsig_verify_single(vrfy, sig, msg, NULL, &pubkeys[1], 0)); orig_sig=sig[0]; sig[0]=99; - CHECK(!secp256k1_aggsig_verify_single(vrfy, sig, msg, NULL, &pubkeys[0])); + CHECK(!secp256k1_aggsig_verify_single(vrfy, sig, msg, NULL, &pubkeys[0], 0)); sig[0]=orig_sig; - CHECK(secp256k1_aggsig_verify_single(vrfy, sig, msg, NULL, &pubkeys[0])); + CHECK(secp256k1_aggsig_verify_single(vrfy, sig, msg, NULL, &pubkeys[0], 0)); msg[0]=99; - CHECK(!secp256k1_aggsig_verify_single(vrfy, sig, msg, NULL, &pubkeys[0])); + CHECK(!secp256k1_aggsig_verify_single(vrfy, sig, msg, NULL, &pubkeys[0],0)); /* Overriding sec nonce */ memset(sig, 0, sizeof(sig)); - CHECK(secp256k1_aggsig_sign_single(sign, sig, msg, seckeys[0], seckeys[1], NULL, 0, seed)); - /*CHECK(secp256k1_aggsig_verify_single(vrfy, sig, msg, NULL, &pubkeys[0]));*/ + CHECK(secp256k1_aggsig_sign_single(sign, sig, msg, seckeys[0], seckeys[1], NULL, NULL, seed)); + CHECK(secp256k1_aggsig_verify_single(vrfy, sig, msg, NULL, &pubkeys[0],0)); /* Overriding sec nonce and pub nonce encoded in e */ memset(sig, 0, sizeof(sig)); - CHECK(secp256k1_aggsig_sign_single(sign, sig, msg, seckeys[0], seckeys[1], &pubkeys[3], 0, seed)); + CHECK(secp256k1_aggsig_sign_single(sign, sig, msg, seckeys[0], seckeys[1], &pubkeys[3], NULL, seed)); /*CHECK(secp256k1_aggsig_verify_single(vrfy, sig, msg, &pubkeys[3], &pubkeys[0]));*/ /* Testing aggsig exchange algorithm for Grin */ /* ****************************************** */ + memset(sig, 0, sizeof(sig)); memset(sig, 0, sizeof(sig2)); memset(sig, 0, sizeof(combined_sig)); /* Create a couple of nonces */ + printf("STARTING GRIN EXCHANGE\n"); + /* Randomise seed to make it more interesting */ + random_scalar_order_test(&tmp_s); + secp256k1_scalar_get_b32(seed, &tmp_s); CHECK(secp256k1_aggsig_export_secnonce_single(sign, sec_nonces[0], seed)); + random_scalar_order_test(&tmp_s); + secp256k1_scalar_get_b32(seed, &tmp_s); CHECK(secp256k1_aggsig_export_secnonce_single(sign, sec_nonces[1], seed)); for (i = 0; i < 2; i++) { - secp256k1_scalar tmp_s; - random_scalar_order_test(&tmp_s); - secp256k1_scalar_get_b32(sec_nonces[i], &tmp_s); CHECK(secp256k1_ec_pubkey_create(ctx, &pub_nonces[i], sec_nonces[i]) == 1); } /* Combine pubnonces */ - /* pubkey_combiner[0]=&pub_nonces[0]; + pubkey_combiner[0]=&pub_nonces[0]; pubkey_combiner[1]=&pub_nonces[1]; - CHECK(secp256k1_ec_pubkey_combine(ctx, &combiner_sum, pubkey_combiner, 2) == 1);*/ - CHECK(secp256k1_aggsig_add_pubnonces_single(ctx, &combiner_sum, &negate, &pub_nonces[0], &pub_nonces[1]) == 1); + CHECK(secp256k1_ec_pubkey_combine(ctx, &combiner_sum, pubkey_combiner, 2) == 1); /* Create 2 partial signatures (Sender, Receiver)*/ printf("\nSIGN FIRST\n"); - CHECK(secp256k1_aggsig_sign_single(sign, sig, msg, seckeys[0], sec_nonces[0], &combiner_sum, negate, seed)); + CHECK(secp256k1_aggsig_sign_single(sign, sig, msg, seckeys[0], sec_nonces[0], &combiner_sum, &combiner_sum, seed)); /* Receiver verifies sender's Sig and signs */ - /*CHECK(secp256k1_aggsig_verify_single(vrfy, sig, msg, &combiner_sum, &pubkeys[0]));*/ + CHECK(secp256k1_aggsig_verify_single(vrfy, sig, msg, &combiner_sum, &pubkeys[0], 1)); printf("POST_VERIFY FIRST\n\n"); printf("\nSIGN SECOND\n"); - CHECK(secp256k1_aggsig_sign_single(sign, sig2, msg, seckeys[1], sec_nonces[1], &combiner_sum, negate, seed)); + CHECK(secp256k1_aggsig_sign_single(sign, sig2, msg, seckeys[1], sec_nonces[1], &combiner_sum, &combiner_sum, seed)); /* sender verifies receiver's Sig then creates final combined sig */ - /*CHECK(secp256k1_aggsig_verify_single(vrfy, sig2, msg, &combiner_sum, &pubkeys[1]));*/ + CHECK(secp256k1_aggsig_verify_single(vrfy, sig2, msg, &combiner_sum, &pubkeys[1], 1)); printf("POST_VERIFY SECOND\n\n"); /* Add 2 sigs and nonces */ - CHECK(secp256k1_aggsig_add_signatures_single(sign, combined_sig, sig, sig2, &pub_nonces[0], &pub_nonces[1])); + CHECK(secp256k1_aggsig_add_signatures_single(sign, combined_sig, sig, sig2, &combiner_sum)); /* Combine pubkeys */ pubkey_combiner[0]=&pubkeys[0]; pubkey_combiner[1]=&pubkeys[1]; - CHECK(secp256k1_ec_pubkey_combine(ctx, &combiner_sum, pubkey_combiner, 2) == 1); + CHECK(secp256k1_ec_pubkey_combine(ctx, &combiner_sum_2, pubkey_combiner, 2) == 1); /* Ensure added sigs verify properly */ - CHECK(secp256k1_aggsig_verify_single(vrfy, combined_sig, msg, NULL, &combiner_sum)); + CHECK(secp256k1_aggsig_verify_single(vrfy, combined_sig, msg, &combiner_sum, &combiner_sum_2, 0)); /*** End aggsig for Grin exchange test ***/