ecdsa_adaptor: optimize encrypt with batch affine conversion

This commit is contained in:
mllwchrry
2026-02-25 15:08:56 +02:00
parent 56751a4cf0
commit d380549e38

View File

@@ -150,8 +150,8 @@ const secp256k1_nonce_function_hardened_ecdsa_adaptor secp256k1_nonce_function_e
int secp256k1_ecdsa_adaptor_encrypt(const secp256k1_context* ctx, unsigned char *adaptor_sig162, unsigned char *seckey32, const secp256k1_pubkey *enckey, const unsigned char *msg32, secp256k1_nonce_function_hardened_ecdsa_adaptor noncefp, void *ndata) {
secp256k1_scalar k;
secp256k1_gej rj, rpj;
secp256k1_ge r, rp;
secp256k1_ge nonce_pts[2];
secp256k1_gej nonce_ptj[2];
secp256k1_ge enckey_ge;
secp256k1_scalar dleq_proof_s;
secp256k1_scalar dleq_proof_e;
@@ -179,32 +179,35 @@ int secp256k1_ecdsa_adaptor_encrypt(const secp256k1_context* ctx, unsigned char
noncefp = secp256k1_nonce_function_ecdsa_adaptor;
}
ret &= secp256k1_pubkey_load(ctx, &enckey_ge, enckey);
ret &= secp256k1_eckey_pubkey_serialize(&enckey_ge, buf33, &size, 1);
if (!secp256k1_pubkey_load(ctx, &enckey_ge, enckey)) {
return 0;
}
secp256k1_eckey_pubkey_serialize(&enckey_ge, buf33, &size, 1);
ret &= !!noncefp(nonce32, msg32, seckey32, buf33, ecdsa_adaptor_algo, sizeof(ecdsa_adaptor_algo), ndata);
secp256k1_scalar_set_b32(&k, nonce32, NULL);
ret &= !secp256k1_scalar_is_zero(&k);
secp256k1_scalar_cmov(&k, &secp256k1_scalar_one, !ret);
/* R' := k*G */
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &rpj, &k);
secp256k1_ge_set_gej(&rp, &rpj);
/* R = k*Y; */
secp256k1_ecmult_const(&rj, &enckey_ge, &k);
secp256k1_ge_set_gej(&r, &rj);
/* We declassify the non-secret values rp and r to allow using them
* as branch points. */
secp256k1_declassify(ctx, &rp, sizeof(rp));
secp256k1_declassify(ctx, &r, sizeof(r));
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &nonce_ptj[0], &k);
/* R := k*Y */
secp256k1_ecmult_const(&nonce_ptj[1], &enckey_ge, &k);
secp256k1_ge_set_all_gej(nonce_pts, nonce_ptj, 2);
/* We declassify the non-secret nonce values to allow using them as branch points. */
secp256k1_declassify(ctx, &nonce_pts[0], sizeof(nonce_pts[0]));
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, &rp, &r, noncefp, ndata);
ret &= secp256k1_dleq_prove(ctx, &dleq_proof_s, &dleq_proof_e, &k, &enckey_ge, &nonce_pts[0], &nonce_pts[1], noncefp, ndata);
ret &= secp256k1_scalar_set_b32_seckey(&sk, seckey32);
secp256k1_scalar_cmov(&sk, &secp256k1_scalar_one, !ret);
secp256k1_scalar_set_b32(&msg, msg32, NULL);
secp256k1_fe_normalize(&r.x);
secp256k1_fe_get_b32(buf33, &r.x);
secp256k1_fe_normalize(&nonce_pts[1].x);
secp256k1_fe_get_b32(buf33, &nonce_pts[1].x);
secp256k1_scalar_set_b32(&sigr, buf33, NULL);
ret &= !secp256k1_scalar_is_zero(&sigr);
/* s' = k⁻¹(m + R.x * x) */
@@ -215,7 +218,7 @@ int secp256k1_ecdsa_adaptor_encrypt(const secp256k1_context* ctx, unsigned char
ret &= !secp256k1_scalar_is_zero(&sp);
/* return (R, R', s', dleq_proof) */
ret &= secp256k1_ecdsa_adaptor_sig_serialize(adaptor_sig162, &r, &rp, &sp, &dleq_proof_e, &dleq_proof_s);
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_scalar_clear(&n);