Make aux_rnd32==NULL behave identical to 0x0000..00.

BIP340's default signing algorithm always requires an aux_rnd argument,
but permits using an all-zero one when no randomness is available.

Make secp256k1_schnorrsig_sign follow this even when aux_rnd32==NULL,
by treating the same as if an all-zero byte array was provided as
input.
This commit is contained in:
Pieter Wuille 2021-10-30 13:03:55 -04:00
parent 21c188b3c5
commit 5324f8942d
3 changed files with 20 additions and 9 deletions

View File

@ -111,7 +111,8 @@ typedef struct {
* In: msg32: the 32-byte message being signed. * In: msg32: the 32-byte message being signed.
* keypair: pointer to an initialized keypair. * keypair: pointer to an initialized keypair.
* aux_rand32: 32 bytes of fresh randomness. While recommended to provide * aux_rand32: 32 bytes of fresh randomness. While recommended to provide
* this, it is only supplemental to security and can be NULL. See * this, it is only supplemental to security and can be NULL. A
* NULL argument is treated the same as an all-zero one. See
* BIP-340 "Default Signing" for a full explanation of this * BIP-340 "Default Signing" for a full explanation of this
* argument and for guidance if randomness is expensive. * argument and for guidance if randomness is expensive.
*/ */

View File

@ -65,6 +65,17 @@ static int nonce_function_bip340(unsigned char *nonce32, const unsigned char *ms
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
masked_key[i] ^= key32[i]; masked_key[i] ^= key32[i];
} }
} else {
/* Precomputed TaggedHash("BIP0340/aux", 0x0000...00); */
static const unsigned char ZERO_MASK[32] = {
84, 241, 105, 207, 201, 226, 229, 114,
116, 128, 68, 31, 144, 186, 37, 196,
136, 244, 97, 199, 11, 94, 165, 220,
170, 247, 175, 105, 39, 10, 165, 20
};
for (i = 0; i < 32; i++) {
masked_key[i] = key32[i] ^ ZERO_MASK[i];
}
} }
/* Tag the hash with algo which is important to avoid nonce reuse across /* Tag the hash with algo which is important to avoid nonce reuse across
@ -77,12 +88,8 @@ static int nonce_function_bip340(unsigned char *nonce32, const unsigned char *ms
secp256k1_sha256_initialize_tagged(&sha, algo, algolen); secp256k1_sha256_initialize_tagged(&sha, algo, algolen);
} }
/* Hash (masked-)key||pk||msg using the tagged hash as per the spec */ /* Hash masked-key||pk||msg using the tagged hash as per the spec */
if (data != NULL) {
secp256k1_sha256_write(&sha, masked_key, 32); secp256k1_sha256_write(&sha, masked_key, 32);
} else {
secp256k1_sha256_write(&sha, key32, 32);
}
secp256k1_sha256_write(&sha, xonly_pk32, 32); secp256k1_sha256_write(&sha, xonly_pk32, 32);
secp256k1_sha256_write(&sha, msg, msglen); secp256k1_sha256_write(&sha, msg, msglen);
secp256k1_sha256_finalize(&sha, nonce32); secp256k1_sha256_finalize(&sha, nonce32);

View File

@ -38,7 +38,7 @@ void run_nonce_function_bip340_tests(void) {
size_t algolen = sizeof(algo); size_t algolen = sizeof(algo);
secp256k1_sha256 sha; secp256k1_sha256 sha;
secp256k1_sha256 sha_optimized; secp256k1_sha256 sha_optimized;
unsigned char nonce[32]; unsigned char nonce[32], nonce_z[32];
unsigned char msg[32]; unsigned char msg[32];
size_t msglen = sizeof(msg); size_t msglen = sizeof(msg);
unsigned char key[32]; unsigned char key[32];
@ -107,8 +107,11 @@ void run_nonce_function_bip340_tests(void) {
CHECK(secp256k1_memcmp_var(nonce, nonce2, 32) != 0); CHECK(secp256k1_memcmp_var(nonce, nonce2, 32) != 0);
} }
/* NULL aux_rand argument is allowed. */ /* NULL aux_rand argument is allowed, and identical to passing all zero aux_rand. */
memset(aux_rand, 0, 32);
CHECK(nonce_function_bip340(nonce_z, msg, msglen, key, pk, algo, algolen, &aux_rand) == 1);
CHECK(nonce_function_bip340(nonce, msg, msglen, key, pk, algo, algolen, NULL) == 1); CHECK(nonce_function_bip340(nonce, msg, msglen, key, pk, algo, algolen, NULL) == 1);
CHECK(secp256k1_memcmp_var(nonce_z, nonce, 32) == 0);
} }
void test_schnorrsig_api(void) { void test_schnorrsig_api(void) {