Skip to content

Commit

Permalink
Make aux_rnd32==NULL behave identical to 0x0000..00.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
sipa committed Oct 30, 2021
1 parent 21c188b commit 5324f89
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 9 deletions.
3 changes: 2 additions & 1 deletion include/secp256k1_schnorrsig.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ typedef struct {
* In: msg32: the 32-byte message being signed.
* keypair: pointer to an initialized keypair.
* 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
* argument and for guidance if randomness is expensive.
*/
Expand Down
19 changes: 13 additions & 6 deletions src/modules/schnorrsig/main_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@ static int nonce_function_bip340(unsigned char *nonce32, const unsigned char *ms
for (i = 0; i < 32; 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
Expand All @@ -77,12 +88,8 @@ static int nonce_function_bip340(unsigned char *nonce32, const unsigned char *ms
secp256k1_sha256_initialize_tagged(&sha, algo, algolen);
}

/* Hash (masked-)key||pk||msg using the tagged hash as per the spec */
if (data != NULL) {
secp256k1_sha256_write(&sha, masked_key, 32);
} else {
secp256k1_sha256_write(&sha, key32, 32);
}
/* Hash masked-key||pk||msg using the tagged hash as per the spec */
secp256k1_sha256_write(&sha, masked_key, 32);
secp256k1_sha256_write(&sha, xonly_pk32, 32);
secp256k1_sha256_write(&sha, msg, msglen);
secp256k1_sha256_finalize(&sha, nonce32);
Expand Down
7 changes: 5 additions & 2 deletions src/modules/schnorrsig/tests_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ void run_nonce_function_bip340_tests(void) {
size_t algolen = sizeof(algo);
secp256k1_sha256 sha;
secp256k1_sha256 sha_optimized;
unsigned char nonce[32];
unsigned char nonce[32], nonce_z[32];
unsigned char msg[32];
size_t msglen = sizeof(msg);
unsigned char key[32];
Expand Down Expand Up @@ -107,8 +107,11 @@ void run_nonce_function_bip340_tests(void) {
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(secp256k1_memcmp_var(nonce_z, nonce, 32) == 0);
}

void test_schnorrsig_api(void) {
Expand Down

0 comments on commit 5324f89

Please sign in to comment.