diff --git a/src/secp256k1/src/modules/schnorr/main_impl.h b/src/secp256k1/src/modules/schnorr/main_impl.h --- a/src/secp256k1/src/modules/schnorr/main_impl.h +++ b/src/secp256k1/src/modules/schnorr/main_impl.h @@ -35,7 +35,7 @@ secp256k1_nonce_function noncefp, const void *ndata ) { - secp256k1_scalar sec, non; + secp256k1_scalar sec; secp256k1_pubkey pubkey; secp256k1_ge p; int ret = 0; @@ -49,19 +49,13 @@ return 0; } - if (!secp256k1_schnorr_sig_generate_k(&non, msg32, seckey, noncefp, ndata)) { - secp256k1_scalar_clear(&non); - return 0; - } - secp256k1_pubkey_load(ctx, &p, &pubkey); secp256k1_scalar_set_b32(&sec, seckey, NULL); - ret = secp256k1_schnorr_sig_sign(&ctx->ecmult_gen_ctx, sig64, &sec, &p, &non, msg32); + ret = secp256k1_schnorr_sig_sign(&ctx->ecmult_gen_ctx, sig64, msg32, &sec, &p, noncefp, ndata); if (!ret) { memset(sig64, 0, 64); } - secp256k1_scalar_clear(&non); secp256k1_scalar_clear(&sec); return ret; } diff --git a/src/secp256k1/src/modules/schnorr/schnorr.h b/src/secp256k1/src/modules/schnorr/schnorr.h --- a/src/secp256k1/src/modules/schnorr/schnorr.h +++ b/src/secp256k1/src/modules/schnorr/schnorr.h @@ -27,16 +27,36 @@ static int secp256k1_schnorr_sig_sign( const secp256k1_ecmult_gen_context* ctx, unsigned char *sig64, + const unsigned char *msg32, const secp256k1_scalar *privkey, secp256k1_ge *pubkey, - const secp256k1_scalar *nonce, - const unsigned char *msg32 + secp256k1_nonce_function noncefp, + const void *ndata +); + +static int secp256k1_schnorr_compute_k_R( + const secp256k1_ecmult_gen_context* ctx, + secp256k1_scalar *k, + secp256k1_ge *R, + const unsigned char *msg32, + const secp256k1_scalar *privkey, + secp256k1_nonce_function noncefp, + const void *ndata +); + +static int secp256k1_schnorr_compute_sig( + unsigned char *sig64, + const unsigned char *msg32, + secp256k1_scalar *k, + secp256k1_ge *R, + const secp256k1_scalar *privkey, + secp256k1_ge *pubkey ); static int secp256k1_schnorr_sig_generate_k( secp256k1_scalar *k, const unsigned char *msg32, - const unsigned char *seckey, + const secp256k1_scalar *privkey, secp256k1_nonce_function noncefp, const void *ndata ); diff --git a/src/secp256k1/src/modules/schnorr/schnorr_impl.h b/src/secp256k1/src/modules/schnorr/schnorr_impl.h --- a/src/secp256k1/src/modules/schnorr/schnorr_impl.h +++ b/src/secp256k1/src/modules/schnorr/schnorr_impl.h @@ -132,36 +132,80 @@ static int secp256k1_schnorr_sig_sign( const secp256k1_ecmult_gen_context* ctx, unsigned char *sig64, + const unsigned char *msg32, const secp256k1_scalar *privkey, secp256k1_ge *pubkey, - const secp256k1_scalar *nonce, - const unsigned char *msg32 + secp256k1_nonce_function noncefp, + const void *ndata +) { + secp256k1_ge R; + secp256k1_scalar k; + int ret; + + if (secp256k1_scalar_is_zero(privkey)) { + return 0; + } + + if (!secp256k1_schnorr_compute_k_R(ctx, &k, &R, msg32, privkey, noncefp, ndata)) { + return 0; + } + + ret = secp256k1_schnorr_compute_sig(sig64, msg32, &k, &R, privkey, pubkey); + secp256k1_scalar_clear(&k); + return ret; +} + +static int secp256k1_schnorr_compute_k_R( + const secp256k1_ecmult_gen_context* ctx, + secp256k1_scalar *k, + secp256k1_ge *R, + const unsigned char *msg32, + const secp256k1_scalar *privkey, + secp256k1_nonce_function noncefp, + const void *ndata ) { secp256k1_gej Rj; - secp256k1_ge Ra; - secp256k1_scalar e, s, k; - if (secp256k1_scalar_is_zero(privkey) || secp256k1_scalar_is_zero(nonce)) { + if (!secp256k1_schnorr_sig_generate_k(k, msg32, privkey, noncefp, ndata)) { return 0; } - k = *nonce; - secp256k1_ecmult_gen(ctx, &Rj, &k); - secp256k1_ge_set_gej(&Ra, &Rj); - if (!secp256k1_fe_is_quad_var(&Ra.y)) { + secp256k1_ecmult_gen(ctx, &Rj, k); + secp256k1_ge_set_gej(R, &Rj); + return 1; +} + +static int secp256k1_schnorr_compute_sig( + unsigned char *sig64, + const unsigned char *msg32, + secp256k1_scalar *k, + secp256k1_ge *R, + const secp256k1_scalar *privkey, + secp256k1_ge *pubkey +) { + secp256k1_scalar e, s; + + if (secp256k1_scalar_is_zero(privkey) || secp256k1_scalar_is_zero(k)) { + return 0; + } + + if (secp256k1_ge_is_infinity(pubkey)) { + return 0; + } + + if (!secp256k1_fe_is_quad_var(&R->y)) { /** * R's y coordinate is not a quadratic residue, which is not allowed. * Negate the nonce to ensure it is. */ - secp256k1_scalar_negate(&k, &k); + secp256k1_scalar_negate(k, k); } - secp256k1_fe_normalize(&Ra.x); - secp256k1_fe_get_b32(sig64, &Ra.x); + secp256k1_fe_normalize(&R->x); + secp256k1_fe_get_b32(sig64, &R->x); secp256k1_schnorr_compute_e(&e, sig64, pubkey, msg32); secp256k1_scalar_mul(&s, &e, privkey); - secp256k1_scalar_add(&s, &s, &k); - secp256k1_scalar_clear(&k); + secp256k1_scalar_add(&s, &s, k); secp256k1_scalar_get_b32(sig64 + 32, &s); return 1; } @@ -169,14 +213,14 @@ static int secp256k1_schnorr_sig_generate_k( secp256k1_scalar *k, const unsigned char *msg32, - const unsigned char *seckey, + const secp256k1_scalar *privkey, secp256k1_nonce_function noncefp, const void *ndata ) { int overflow = 0; int ret = 0; unsigned int count = 0; - unsigned char nonce32[32]; + unsigned char nonce32[32], seckey[32]; /* Seed used to make sure we generate different values of k for schnorr */ const unsigned char secp256k1_schnorr_algo16[17] = "Schnorr+SHA256 "; @@ -185,6 +229,7 @@ noncefp = secp256k1_nonce_function_default; } + secp256k1_scalar_get_b32(seckey, privkey); while (1) { ret = noncefp(nonce32, msg32, seckey, secp256k1_schnorr_algo16, (void*)ndata, count++); if (!ret) { @@ -195,8 +240,11 @@ if (!overflow && !secp256k1_scalar_is_zero(k)) { break; } + + secp256k1_scalar_clear(k); } + memset(seckey, 0, 32); memset(nonce32, 0, 32); return ret; } diff --git a/src/secp256k1/src/modules/schnorr/tests_impl.h b/src/secp256k1/src/modules/schnorr/tests_impl.h --- a/src/secp256k1/src/modules/schnorr/tests_impl.h +++ b/src/secp256k1/src/modules/schnorr/tests_impl.h @@ -40,9 +40,10 @@ void test_schnorr_sign_verify(void) { unsigned char msg32[32]; unsigned char sig64[SIG_COUNT][64]; + unsigned char ndata[SIG_COUNT][32]; secp256k1_gej pubkeyj[SIG_COUNT]; secp256k1_ge pubkey[SIG_COUNT]; - secp256k1_scalar nonce[SIG_COUNT], key[SIG_COUNT]; + secp256k1_scalar key[SIG_COUNT]; int i, j; secp256k1_rand256_test(msg32); @@ -55,8 +56,8 @@ secp256k1_fe_normalize(&pubkey[i].y); do { - random_scalar_order_test(&nonce[i]); - if (secp256k1_schnorr_sig_sign(&ctx->ecmult_gen_ctx, sig64[i], &key[i], &pubkey[i], &nonce[i], msg32)) { + secp256k1_rand256_test(ndata[i]); + if (secp256k1_schnorr_sig_sign(&ctx->ecmult_gen_ctx, sig64[i], msg32, &key[i], &pubkey[i], NULL, &ndata[i])) { break; } } while(1);