Merge BlockstreamResearch/secp256k1-zkp#361: ecdsa_adaptor: make DLEQ nonce generation pluggable

b36c4ab717 ecdsa_adaptor: use context hash functions in nonce generation (DarkWindman)

Pull request description:

  Addresses #359.

ACKs for top commit:
  real-or-random:
    utACK b36c4ab717

Tree-SHA512: 0262dfcc2ec2e3d91e37c85bcf1243099aa11d9f4bff115400ce81d36a223818e09c02c41c0602fcbeeaa1f129c4f936ef643afb7149d1230cec2ea57f5b3894
This commit is contained in:
merge-script
2026-06-03 13:40:27 +02:00
2 changed files with 17 additions and 10 deletions

View File

@@ -24,6 +24,8 @@ static void secp256k1_nonce_function_dleq_sha256_tagged(secp256k1_sha256 *sha) {
/* algo argument for nonce_function_ecdsa_adaptor to derive the nonce using a tagged hash function. */
static const unsigned char dleq_algo[] = {'D','L','E','Q'};
static int nonce_function_ecdsa_adaptor_impl(const secp256k1_hash_ctx *hash_ctx, unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *pk33, const unsigned char *algo, size_t algolen, void *data);
static void secp256k1_dleq_hash_point(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *sha, secp256k1_ge *p) {
unsigned char buf[33];
@@ -36,20 +38,21 @@ static int secp256k1_dleq_nonce(const secp256k1_hash_ctx *hash_ctx, secp256k1_sc
unsigned char buf[32];
unsigned char nonce[32];
if (noncefp == NULL) {
noncefp = secp256k1_nonce_function_ecdsa_adaptor;
}
secp256k1_sha256_initialize(&sha);
secp256k1_sha256_write(hash_ctx, &sha, p1_33, 33);
secp256k1_sha256_write(hash_ctx, &sha, p2_33, 33);
secp256k1_sha256_finalize(hash_ctx, &sha, buf);
secp256k1_sha256_clear(&sha);
if (!noncefp(nonce, buf, sk32, gen2_33, dleq_algo, sizeof(dleq_algo), ndata)) {
if (noncefp == NULL || noncefp == secp256k1_nonce_function_ecdsa_adaptor) {
if (!nonce_function_ecdsa_adaptor_impl(hash_ctx, nonce, buf, sk32, gen2_33, dleq_algo, sizeof(dleq_algo), ndata)) {
return 0;
}
} else if (!noncefp(nonce, buf, sk32, gen2_33, dleq_algo, sizeof(dleq_algo), ndata)) {
return 0;
}
secp256k1_scalar_set_b32(k, nonce, NULL);
secp256k1_memclear_explicit(nonce, sizeof(nonce));
if (secp256k1_scalar_is_zero(k)) {
return 0;
}

View File

@@ -150,6 +150,7 @@ static int nonce_function_ecdsa_adaptor(
const secp256k1_nonce_function_hardened_ecdsa_adaptor secp256k1_nonce_function_ecdsa_adaptor = nonce_function_ecdsa_adaptor;
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) {
const secp256k1_hash_ctx *hash_ctx;
secp256k1_scalar k;
secp256k1_ge r[2]; /* R, R' */
secp256k1_gej rj[2]; /* R, R' */
@@ -175,16 +176,19 @@ int secp256k1_ecdsa_adaptor_encrypt(const secp256k1_context* ctx, unsigned char
secp256k1_scalar_clear(&dleq_proof_e);
secp256k1_scalar_clear(&dleq_proof_s);
if (noncefp == NULL) {
noncefp = secp256k1_nonce_function_ecdsa_adaptor;
}
if (!secp256k1_pubkey_load(ctx, &enckey_ge, enckey)) {
return 0;
}
hash_ctx = secp256k1_get_hash_context(ctx);
secp256k1_eckey_pubkey_serialize33(&enckey_ge, buf33);
ret &= !!noncefp(nonce32, msg32, seckey32, buf33, ecdsa_adaptor_algo, sizeof(ecdsa_adaptor_algo), ndata);
if (noncefp == NULL || noncefp == secp256k1_nonce_function_ecdsa_adaptor) {
ret &= nonce_function_ecdsa_adaptor_impl(hash_ctx, nonce32, msg32, seckey32, buf33, ecdsa_adaptor_algo, sizeof(ecdsa_adaptor_algo), ndata);
} else {
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);