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) { 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_scalar k;
secp256k1_gej rj, rpj; secp256k1_ge nonce_pts[2];
secp256k1_ge r, rp; secp256k1_gej nonce_ptj[2];
secp256k1_ge enckey_ge; secp256k1_ge enckey_ge;
secp256k1_scalar dleq_proof_s; secp256k1_scalar dleq_proof_s;
secp256k1_scalar dleq_proof_e; 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; noncefp = secp256k1_nonce_function_ecdsa_adaptor;
} }
ret &= secp256k1_pubkey_load(ctx, &enckey_ge, enckey); if (!secp256k1_pubkey_load(ctx, &enckey_ge, enckey)) {
ret &= secp256k1_eckey_pubkey_serialize(&enckey_ge, buf33, &size, 1); 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); ret &= !!noncefp(nonce32, msg32, seckey32, buf33, ecdsa_adaptor_algo, sizeof(ecdsa_adaptor_algo), ndata);
secp256k1_scalar_set_b32(&k, nonce32, NULL); secp256k1_scalar_set_b32(&k, nonce32, NULL);
ret &= !secp256k1_scalar_is_zero(&k); ret &= !secp256k1_scalar_is_zero(&k);
secp256k1_scalar_cmov(&k, &secp256k1_scalar_one, !ret); secp256k1_scalar_cmov(&k, &secp256k1_scalar_one, !ret);
/* R' := k*G */ /* R' := k*G */
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &rpj, &k); secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &nonce_ptj[0], &k);
secp256k1_ge_set_gej(&rp, &rpj); /* R := k*Y */
/* R = k*Y; */ secp256k1_ecmult_const(&nonce_ptj[1], &enckey_ge, &k);
secp256k1_ecmult_const(&rj, &enckey_ge, &k);
secp256k1_ge_set_gej(&r, &rj); secp256k1_ge_set_all_gej(nonce_pts, nonce_ptj, 2);
/* We declassify the non-secret values rp and r to allow using them
* as branch points. */ /* We declassify the non-secret nonce values to allow using them as branch points. */
secp256k1_declassify(ctx, &rp, sizeof(rp)); secp256k1_declassify(ctx, &nonce_pts[0], sizeof(nonce_pts[0]));
secp256k1_declassify(ctx, &r, sizeof(r)); secp256k1_declassify(ctx, &nonce_pts[1], sizeof(nonce_pts[1]));
/* dleq_proof = DLEQ_prove(k, (R', Y, R)) */ /* 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); ret &= secp256k1_scalar_set_b32_seckey(&sk, seckey32);
secp256k1_scalar_cmov(&sk, &secp256k1_scalar_one, !ret); secp256k1_scalar_cmov(&sk, &secp256k1_scalar_one, !ret);
secp256k1_scalar_set_b32(&msg, msg32, NULL); secp256k1_scalar_set_b32(&msg, msg32, NULL);
secp256k1_fe_normalize(&r.x); secp256k1_fe_normalize(&nonce_pts[1].x);
secp256k1_fe_get_b32(buf33, &r.x); secp256k1_fe_get_b32(buf33, &nonce_pts[1].x);
secp256k1_scalar_set_b32(&sigr, buf33, NULL); secp256k1_scalar_set_b32(&sigr, buf33, NULL);
ret &= !secp256k1_scalar_is_zero(&sigr); ret &= !secp256k1_scalar_is_zero(&sigr);
/* s' = k⁻¹(m + R.x * x) */ /* 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); ret &= !secp256k1_scalar_is_zero(&sp);
/* return (R, R', s', dleq_proof) */ /* 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_memczero(adaptor_sig162, 162, !ret);
secp256k1_scalar_clear(&n); secp256k1_scalar_clear(&n);