Skip to content

Commit

Permalink
partial+combined sig validation working
Browse files Browse the repository at this point in the history
  • Loading branch information
yeastplume committed Jan 7, 2018
1 parent 97fe54e commit d35cc95
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 120 deletions.
15 changes: 7 additions & 8 deletions include/secp256k1_aggsig.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
129 changes: 41 additions & 88 deletions src/modules/aggsig/main_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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 */
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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));
Expand Down Expand Up @@ -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;
}

}

Expand Down
51 changes: 27 additions & 24 deletions src/modules/aggsig/tests_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand All @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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 ***/

Expand Down

0 comments on commit d35cc95

Please sign in to comment.