ecdsa_adaptor: batch affine conversion in dleq_pair and dleq_prove
This commit is contained in:
@@ -77,29 +77,27 @@ static void secp256k1_dleq_challenge(secp256k1_scalar *e, secp256k1_ge *gen2, se
|
||||
secp256k1_scalar_set_b32(e, buf, NULL);
|
||||
}
|
||||
|
||||
/* P1 = x*G, P2 = x*Y */
|
||||
static void secp256k1_dleq_pair(const secp256k1_ecmult_gen_context *ecmult_gen_ctx, secp256k1_ge *p1, secp256k1_ge *p2, const secp256k1_scalar *sk, const secp256k1_ge *gen2) {
|
||||
secp256k1_gej p1j, p2j;
|
||||
/* p[0] = x*G, p[1] = x*Y */
|
||||
static void secp256k1_dleq_pair(const secp256k1_ecmult_gen_context *ecmult_gen_ctx, secp256k1_ge *p, const secp256k1_scalar *sk, const secp256k1_ge *gen2) {
|
||||
secp256k1_gej pj[2];
|
||||
|
||||
secp256k1_ecmult_gen(ecmult_gen_ctx, &p1j, sk);
|
||||
secp256k1_ge_set_gej(p1, &p1j);
|
||||
secp256k1_ecmult_const(&p2j, gen2, sk);
|
||||
secp256k1_ge_set_gej(p2, &p2j);
|
||||
secp256k1_ecmult_gen(ecmult_gen_ctx, &pj[0], sk);
|
||||
secp256k1_ecmult_const(&pj[1], gen2, sk);
|
||||
secp256k1_ge_set_all_gej(p, pj, 2);
|
||||
}
|
||||
|
||||
/* Generates a proof that the discrete logarithm of P1 to the secp256k1 base G is the
|
||||
* same as the discrete logarithm of P2 to the base Y */
|
||||
static int secp256k1_dleq_prove(const secp256k1_context* ctx, secp256k1_scalar *s, secp256k1_scalar *e, const secp256k1_scalar *sk, secp256k1_ge *gen2, secp256k1_ge *p1, secp256k1_ge *p2, secp256k1_nonce_function_hardened_ecdsa_adaptor noncefp, void *ndata) {
|
||||
secp256k1_ge r1, r2;
|
||||
secp256k1_ge r[2];
|
||||
secp256k1_scalar k = { 0 };
|
||||
unsigned char sk32[32];
|
||||
unsigned char gen2_33[33];
|
||||
unsigned char p1_33[33];
|
||||
unsigned char p2_33[33];
|
||||
int ret = 1;
|
||||
size_t pubkey_size = 33;
|
||||
int ret;
|
||||
|
||||
secp256k1_scalar_get_b32(sk32, sk);
|
||||
if (!secp256k1_eckey_pubkey_serialize(gen2, gen2_33, &pubkey_size, 1)) {
|
||||
return 0;
|
||||
}
|
||||
@@ -110,22 +108,30 @@ static int secp256k1_dleq_prove(const secp256k1_context* ctx, secp256k1_scalar *
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret &= secp256k1_dleq_nonce(&k, sk32, gen2_33, p1_33, p2_33, noncefp, ndata);
|
||||
/* R1 = k*G, R2 = k*Y */
|
||||
secp256k1_dleq_pair(&ctx->ecmult_gen_ctx, &r1, &r2, &k, gen2);
|
||||
/* We declassify the non-secret values r1 and r2 to allow using them as
|
||||
* branch points. */
|
||||
secp256k1_declassify(ctx, &r1, sizeof(r1));
|
||||
secp256k1_declassify(ctx, &r2, sizeof(r2));
|
||||
secp256k1_scalar_get_b32(sk32, sk);
|
||||
|
||||
/* e = tagged hash(p1, gen2, p2, r1, r2) */
|
||||
ret = secp256k1_dleq_nonce(&k, sk32, gen2_33, p1_33, p2_33, noncefp, ndata);
|
||||
secp256k1_declassify(ctx, &ret, sizeof(ret));
|
||||
if (!ret) {
|
||||
secp256k1_memclear_explicit(sk32, sizeof(sk32));
|
||||
return 0;
|
||||
}
|
||||
/* R1 = k*G, R2 = k*Y */
|
||||
secp256k1_dleq_pair(&ctx->ecmult_gen_ctx, r, &k, gen2);
|
||||
/* We declassify the non-secret values r[0] and r[1] to allow using them as
|
||||
* branch points. */
|
||||
secp256k1_declassify(ctx, &r[0], sizeof(r[0]));
|
||||
secp256k1_declassify(ctx, &r[1], sizeof(r[1]));
|
||||
|
||||
/* e = tagged hash(p1, gen2, p2, r[0], r[1]) */
|
||||
/* s = k + e * sk */
|
||||
secp256k1_dleq_challenge(e, gen2, &r1, &r2, p1, p2);
|
||||
secp256k1_dleq_challenge(e, gen2, &r[0], &r[1], p1, p2);
|
||||
secp256k1_scalar_mul(s, e, sk);
|
||||
secp256k1_scalar_add(s, s, &k);
|
||||
|
||||
secp256k1_scalar_clear(&k);
|
||||
return ret;
|
||||
secp256k1_memclear_explicit(sk32, sizeof(sk32));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int secp256k1_dleq_verify(const secp256k1_scalar *s, const secp256k1_scalar *e, secp256k1_ge *p1, secp256k1_ge *gen2, secp256k1_ge *p2) {
|
||||
@@ -133,8 +139,8 @@ static int secp256k1_dleq_verify(const secp256k1_scalar *s, const secp256k1_scal
|
||||
secp256k1_scalar e_expected;
|
||||
secp256k1_gej gen2j;
|
||||
secp256k1_gej p1j, p2j;
|
||||
secp256k1_gej r1j, r2j;
|
||||
secp256k1_ge r1, r2;
|
||||
secp256k1_gej rj[2];
|
||||
secp256k1_ge r[2];
|
||||
secp256k1_gej tmpj;
|
||||
|
||||
secp256k1_gej_set_ge(&p1j, p1);
|
||||
@@ -142,16 +148,16 @@ static int secp256k1_dleq_verify(const secp256k1_scalar *s, const secp256k1_scal
|
||||
|
||||
secp256k1_scalar_negate(&e_neg, e);
|
||||
/* R1 = s*G - e*P1 */
|
||||
secp256k1_ecmult(&r1j, &p1j, &e_neg, s);
|
||||
secp256k1_ecmult(&rj[0], &p1j, &e_neg, s);
|
||||
/* R2 = s*gen2 - e*P2 */
|
||||
secp256k1_ecmult(&tmpj, &p2j, &e_neg, &secp256k1_scalar_zero);
|
||||
secp256k1_gej_set_ge(&gen2j, gen2);
|
||||
secp256k1_ecmult(&r2j, &gen2j, s, &secp256k1_scalar_zero);
|
||||
secp256k1_gej_add_var(&r2j, &r2j, &tmpj, NULL);
|
||||
secp256k1_ecmult(&rj[1], &gen2j, s, &secp256k1_scalar_zero);
|
||||
secp256k1_gej_add_var(&rj[1], &rj[1], &tmpj, NULL);
|
||||
|
||||
secp256k1_ge_set_gej(&r1, &r1j);
|
||||
secp256k1_ge_set_gej(&r2, &r2j);
|
||||
secp256k1_dleq_challenge(&e_expected, gen2, &r1, &r2, p1, p2);
|
||||
secp256k1_ge_set_all_gej_var(r, rj, 2);
|
||||
|
||||
secp256k1_dleq_challenge(&e_expected, gen2, &r[0], &r[1], p1, p2);
|
||||
|
||||
secp256k1_scalar_add(&e_expected, &e_expected, &e_neg);
|
||||
return secp256k1_scalar_is_zero(&e_expected);
|
||||
|
||||
@@ -201,8 +201,12 @@ int secp256k1_ecdsa_adaptor_encrypt(const secp256k1_context* ctx, unsigned char
|
||||
secp256k1_declassify(ctx, &nonce_pts[1], sizeof(nonce_pts[1]));
|
||||
|
||||
/* dleq_proof = DLEQ_prove(k, (R', Y, R)) */
|
||||
ret &= secp256k1_dleq_prove(ctx, &dleq_proof_s, &dleq_proof_e, &k, &enckey_ge, &nonce_pts[0], &nonce_pts[1], noncefp, ndata);
|
||||
|
||||
if (!secp256k1_dleq_prove(ctx, &dleq_proof_s, &dleq_proof_e, &k, &enckey_ge, &nonce_pts[0], &nonce_pts[1], noncefp, ndata)) {
|
||||
memset(adaptor_sig162, 0, 162);
|
||||
secp256k1_memclear_explicit(nonce32, sizeof(nonce32));
|
||||
secp256k1_scalar_clear(&k);
|
||||
return 0;
|
||||
}
|
||||
ret &= secp256k1_scalar_set_b32_seckey(&sk, seckey32);
|
||||
secp256k1_scalar_cmov(&sk, &secp256k1_scalar_one, !ret);
|
||||
secp256k1_scalar_set_b32(&msg, msg32, NULL);
|
||||
@@ -221,6 +225,7 @@ int secp256k1_ecdsa_adaptor_encrypt(const secp256k1_context* ctx, unsigned char
|
||||
ret &= secp256k1_ecdsa_adaptor_sig_serialize(adaptor_sig162, &nonce_pts[1], &nonce_pts[0], &sp, &dleq_proof_e, &dleq_proof_s);
|
||||
|
||||
secp256k1_memczero(adaptor_sig162, 162, !ret);
|
||||
secp256k1_memclear_explicit(nonce32, sizeof(nonce32));
|
||||
secp256k1_scalar_clear(&n);
|
||||
secp256k1_scalar_clear(&k);
|
||||
secp256k1_scalar_clear(&sk);
|
||||
|
||||
@@ -31,6 +31,7 @@ static void dleq_nonce_bitflip(unsigned char **args, size_t n_flip, size_t n_byt
|
||||
static void dleq_tests_internal(void) {
|
||||
secp256k1_scalar s, e, sk, k;
|
||||
secp256k1_ge gen2, p1, p2;
|
||||
secp256k1_ge p[2];
|
||||
unsigned char *args[5];
|
||||
unsigned char sk32[32];
|
||||
unsigned char gen2_33[33];
|
||||
@@ -42,7 +43,9 @@ static void dleq_tests_internal(void) {
|
||||
|
||||
rand_point(&gen2);
|
||||
rand_scalar(&sk);
|
||||
secp256k1_dleq_pair(&CTX->ecmult_gen_ctx, &p1, &p2, &sk, &gen2);
|
||||
secp256k1_dleq_pair(&CTX->ecmult_gen_ctx, p, &sk, &gen2);
|
||||
p1 = p[0];
|
||||
p2 = p[1];
|
||||
CHECK(secp256k1_dleq_prove(CTX, &s, &e, &sk, &gen2, &p1, &p2, NULL, NULL) == 1);
|
||||
CHECK(secp256k1_dleq_verify(&s, &e, &p1, &gen2, &p2) == 1);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user