Skip to content

Commit e85b0bb

Browse files
committed
Add BIP-340 nonce function
1 parent a2a1b2c commit e85b0bb

File tree

5 files changed

+207
-0
lines changed

5 files changed

+207
-0
lines changed

include/secp256k1.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,23 @@ typedef int (*secp256k1_nonce_function)(
106106
unsigned int attempt
107107
);
108108

109+
/** Same as secp256k1_nonce function with the exception of accepting an
110+
* additional pubkey argument. This can protect signature schemes with
111+
* key-prefixed challenge hash inputs against reusing the nonce when signing
112+
* with the wrong precomputed pubkey.
113+
*
114+
* In: xonly_pk32: the 32-byte serialized xonly pubkey corresponding to key32 (will not be NULL)
115+
*/
116+
typedef int (*secp256k1_nonce_function_extended)(
117+
unsigned char *nonce32,
118+
const unsigned char *msg32,
119+
const unsigned char *key32,
120+
const unsigned char *xonly_pk32,
121+
const unsigned char *algo16,
122+
void *data,
123+
unsigned int attempt
124+
);
125+
109126
# if !defined(SECP256K1_GNUC_PREREQ)
110127
# if defined(__GNUC__)&&defined(__GNUC_MINOR__)
111128
# define SECP256K1_GNUC_PREREQ(_maj,_min) \
@@ -525,6 +542,22 @@ SECP256K1_API int secp256k1_ecdsa_signature_normalize(
525542
*/
526543
SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979;
527544

545+
546+
/** An implementation of the nonce generation function as defined in Bitcoin
547+
* Improvement Proposal 340 "Schnorr Signatures for secp256k1"
548+
* (https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki).
549+
*
550+
* If a data pointer is passed, it is assumed to be a pointer to 32 bytes of
551+
* auxiliary random data as defined in BIP-340. If the data pointer is NULL,
552+
* schnorrsig_sign does not produce BIP-340 compliant signatures. The algo16
553+
* argument must be non-NULL and the attempt argument must be 0, otherwise the
554+
* function will fail and return 0. The hash will be tagged with the algo16
555+
* argument, except if it is "BIP340/nonce0000" in which case the tag is
556+
* "BIP340/nonce" (and the midstate is precomputed). This is used to create BIP
557+
* 340 compliant signatures.
558+
*/
559+
SECP256K1_API extern const secp256k1_nonce_function_extended secp256k1_nonce_function_bip340;
560+
528561
/** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */
529562
SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_default;
530563

src/secp256k1.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,80 @@ static SECP256K1_INLINE void buffer_append(unsigned char *buf, unsigned int *off
434434
*offset += len;
435435
}
436436

437+
/* Initializes SHA256 with fixed midstate. This midstate was computed by applying
438+
* SHA256 to SHA256("BIP340/nonce")||SHA256("BIP340/nonce"). */
439+
static void secp256k1_nonce_function_bip340_sha256_tagged(secp256k1_sha256 *sha) {
440+
secp256k1_sha256_initialize(sha);
441+
sha->s[0] = 0xa96e75cbul;
442+
sha->s[1] = 0x74f9f0acul;
443+
sha->s[2] = 0xc49e3c98ul;
444+
sha->s[3] = 0x202f99baul;
445+
sha->s[4] = 0x8946a616ul;
446+
sha->s[5] = 0x4accf415ul;
447+
sha->s[6] = 0x86e335c3ul;
448+
sha->s[7] = 0x48d0a072ul;
449+
450+
sha->bytes = 64;
451+
}
452+
453+
/* Initializes SHA256 with fixed midstate. This midstate was computed by applying
454+
* SHA256 to SHA256("BIP340/aux")||SHA256("BIP340/aux"). */
455+
static void secp256k1_nonce_function_bip340_sha256_tagged_aux(secp256k1_sha256 *sha) {
456+
secp256k1_sha256_initialize(sha);
457+
sha->s[0] = 0x5d74a872ul;
458+
sha->s[1] = 0xd57064d4ul;
459+
sha->s[2] = 0x89495becul;
460+
sha->s[3] = 0x910f46f5ul;
461+
sha->s[4] = 0xcbc6fd3eul;
462+
sha->s[5] = 0xaf05d9d0ul;
463+
sha->s[6] = 0xcb781ce6ul;
464+
sha->s[7] = 0x062930acul;
465+
466+
sha->bytes = 64;
467+
}
468+
469+
static int nonce_function_bip340(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *xonly_pk32, const unsigned char *algo16, void *data, unsigned int counter) {
470+
secp256k1_sha256 sha;
471+
unsigned char masked_key[32];
472+
int i;
473+
474+
if (counter != 0) {
475+
return 0;
476+
}
477+
if (algo16 == NULL) {
478+
return 0;
479+
}
480+
481+
if (data != NULL) {
482+
secp256k1_nonce_function_bip340_sha256_tagged_aux(&sha);
483+
secp256k1_sha256_write(&sha, data, 32);
484+
secp256k1_sha256_finalize(&sha, masked_key);
485+
for (i = 0; i < 32; i++) {
486+
masked_key[i] ^= key32[i];
487+
}
488+
}
489+
490+
/* Tag the hash with algo16 which is important to avoid nonce reuse across
491+
* algorithms. If this nonce function is used in BIP-340 signing as defined
492+
* in the spec, an optimized tagging implementation is used. */
493+
if (memcmp(algo16, "BIP340/nonce0000", 16) == 0) {
494+
secp256k1_nonce_function_bip340_sha256_tagged(&sha);
495+
} else {
496+
secp256k1_sha256_initialize_tagged(&sha, algo16, 16);
497+
}
498+
499+
/* Hash (masked-)key||pk||msg using the tagged hash as per the spec */
500+
if (data != NULL) {
501+
secp256k1_sha256_write(&sha, masked_key, 32);
502+
} else {
503+
secp256k1_sha256_write(&sha, key32, 32);
504+
}
505+
secp256k1_sha256_write(&sha, xonly_pk32, 32);
506+
secp256k1_sha256_write(&sha, msg32, 32);
507+
secp256k1_sha256_finalize(&sha, nonce32);
508+
return 1;
509+
}
510+
437511
static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) {
438512
unsigned char keydata[112];
439513
unsigned int offset = 0;
@@ -464,6 +538,7 @@ static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *m
464538
return 1;
465539
}
466540

541+
const secp256k1_nonce_function_extended secp256k1_nonce_function_bip340 = nonce_function_bip340;
467542
const secp256k1_nonce_function secp256k1_nonce_function_rfc6979 = nonce_function_rfc6979;
468543
const secp256k1_nonce_function secp256k1_nonce_function_default = nonce_function_rfc6979;
469544

src/testrand.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ static void secp256k1_rand256(unsigned char *b32);
3232
/** Generate a pseudorandom 32-byte array with long sequences of zero and one bits. */
3333
static void secp256k1_rand256_test(unsigned char *b32);
3434

35+
/** Flip a single random bit in a byte array */
36+
static void secp256k1_rand_flip(unsigned char *b, size_t len);
37+
3538
/** Generate pseudorandom bytes with long sequences of zero and one bits. */
3639
static void secp256k1_rand_bytes_test(unsigned char *bytes, size_t len);
3740

src/testrand_impl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,8 @@ static void secp256k1_rand256_test(unsigned char *b32) {
107107
secp256k1_rand_bytes_test(b32, 32);
108108
}
109109

110+
static void secp256k1_rand_flip(unsigned char *b, size_t len) {
111+
b[secp256k1_rand_int(len)] ^= (1 << secp256k1_rand_int(8));
112+
}
113+
110114
#endif /* SECP256K1_TESTRAND_IMPL_H */

src/tests.c

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,98 @@ void run_sha256_tests(void) {
443443
}
444444
}
445445

446+
/* Tests for the equality of two sha256 structs. This function only produces a
447+
* correct result if an integer multiple of 64 many bytes have been written
448+
* into the hash functions. */
449+
void test_sha256_eq(secp256k1_sha256 *sha1, secp256k1_sha256 *sha2) {
450+
unsigned char buf[32] = { 0 };
451+
unsigned char buf2[32];
452+
453+
/* Is buffer fully consumed? */
454+
CHECK((sha1->bytes & 0x3F) == 0);
455+
456+
/* Compare the struct excluding the buffer, because it may be
457+
* uninitialized or already included in the state. */
458+
CHECK(sha1->bytes == sha2->bytes);
459+
CHECK(memcmp(sha1->s, sha2->s, sizeof(sha1->s)) == 0);
460+
461+
/* Compare the output */
462+
secp256k1_sha256_write(sha1, buf, 32);
463+
secp256k1_sha256_write(sha2, buf, 32);
464+
secp256k1_sha256_finalize(sha1, buf);
465+
secp256k1_sha256_finalize(sha2, buf2);
466+
CHECK(memcmp(buf, buf2, 32) == 0);
467+
}
468+
469+
/* Checks that a bit flip in the n_flip-th argument (that has n_bytes many
470+
* bytes) changes the hash function
471+
*/
472+
void nonce_function_bip340_bitflip(unsigned char **args, size_t n_flip, size_t n_bytes) {
473+
unsigned char nonces[2][32];
474+
CHECK(nonce_function_bip340(nonces[0], args[0], args[1], args[2], args[3], args[4], 0) == 1);
475+
secp256k1_rand_flip(args[n_flip], n_bytes);
476+
CHECK(nonce_function_bip340(nonces[1], args[0], args[1], args[2], args[3], args[4], 0) == 1);
477+
CHECK(memcmp(nonces[0], nonces[1], 32) != 0);
478+
}
479+
480+
void run_nonce_function_bip340_tests(void) {
481+
unsigned char tag[12] = "BIP340/nonce";
482+
unsigned char aux_tag[10] = "BIP340/aux";
483+
unsigned char algo16[16] = "BIP340/nonce0000";
484+
secp256k1_sha256 sha;
485+
secp256k1_sha256 sha_optimized;
486+
unsigned char nonce[32];
487+
unsigned char msg[32];
488+
unsigned char key[32];
489+
unsigned char pk[32];
490+
unsigned char aux_rand[32];
491+
unsigned char *args[5];
492+
493+
/* Check that hash initialized by
494+
* secp256k1_nonce_function_bip340_sha256_tagged has the expected
495+
* state. */
496+
secp256k1_sha256_initialize_tagged(&sha, tag, sizeof(tag));
497+
secp256k1_nonce_function_bip340_sha256_tagged(&sha_optimized);
498+
test_sha256_eq(&sha, &sha_optimized);
499+
500+
/* Check that hash initialized by
501+
* secp256k1_nonce_function_bip340_sha256_tagged_aux has the expected
502+
* state. */
503+
secp256k1_sha256_initialize_tagged(&sha, aux_tag, sizeof(aux_tag));
504+
secp256k1_nonce_function_bip340_sha256_tagged_aux(&sha_optimized);
505+
test_sha256_eq(&sha, &sha_optimized);
506+
507+
secp256k1_rand256(msg);
508+
secp256k1_rand256(key);
509+
secp256k1_rand256(pk);
510+
secp256k1_rand256(aux_rand);
511+
512+
/* Check that a bitflip in an argument results in different nonces. */
513+
args[0] = msg;
514+
args[1] = key;
515+
args[2] = pk;
516+
args[3] = algo16;
517+
args[4] = aux_rand;
518+
nonce_function_bip340_bitflip(args, 0, 32);
519+
nonce_function_bip340_bitflip(args, 1, 32);
520+
nonce_function_bip340_bitflip(args, 2, 32);
521+
/* Flip algo16 special case "BIP340/nonce0000" */
522+
nonce_function_bip340_bitflip(args, 3, 16);
523+
/* Flip algo16 again */
524+
nonce_function_bip340_bitflip(args, 3, 16);
525+
nonce_function_bip340_bitflip(args, 4, 32);
526+
527+
/* NULL algo16 is disallowed */
528+
CHECK(nonce_function_bip340(nonce, msg, key, pk, NULL, NULL, 0) == 0);
529+
530+
/* NULL aux_rand argument is allowed. */
531+
CHECK(nonce_function_bip340(nonce, msg, key, pk, algo16, NULL, 0) == 1);
532+
533+
/* Check that counter != 0 makes nonce function fail. */
534+
CHECK(nonce_function_bip340(nonce, msg, key, pk, algo16, NULL, 0) == 1);
535+
CHECK(nonce_function_bip340(nonce, msg, key, pk, algo16, NULL, 1) == 0);
536+
}
537+
446538
void run_hmac_sha256_tests(void) {
447539
static const char *keys[6] = {
448540
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",

0 commit comments

Comments
 (0)