Skip to content

Commit 6d51696

Browse files
committed
schnorr_adaptor: add nonce function and tags
This commit adds a nonce function that will be used by default for Schnorr adaptor signatures. This nonce function is similar to secp256k1_nonce_function_hardened with an extra argument for a compressed 33-byte adaptor point.
1 parent ce849f9 commit 6d51696

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-0
lines changed

include/secp256k1_schnorr_adaptor.h

+41
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,47 @@ extern "C" {
6464
* [1] https://eprint.iacr.org/2020/476.pdf
6565
*/
6666

67+
/** A pointer to a function to deterministically generate a nonce.
68+
*
69+
* In addition to the features of secp256k1_nonce_function_hardened,
70+
* this function introduces an extra argument for a compressed 33-byte
71+
* adaptor point.
72+
*
73+
* Returns: 1 if a nonce was successfully generated. 0 will cause signing to
74+
* return an error.
75+
* Out: nonce32: pointer to a 32-byte array to be filled by the function
76+
* In: msg32: the 32-byte message being verified (will not be NULL)
77+
* key32: pointer to a 32-byte secret key (will not be NULL)
78+
* adaptor33: the 33-byte serialized adaptor point (will not be NULL)
79+
* xonly_pk32: the 32-byte serialized xonly pubkey corresponding to key32
80+
* (will not be NULL)
81+
* algo: pointer to an array describing the signature
82+
* algorithm (will not be NULL)
83+
* algolen: the length of the algo array
84+
* data: arbitrary data pointer that is passed through
85+
*
86+
* Except for test cases, this function should compute some cryptographic hash of
87+
* the message, the key, the adaptor point, the pubkey, the algorithm description, and data.
88+
*/
89+
typedef int (*secp256k1_nonce_function_hardened_schnorr_adaptor)(
90+
unsigned char *nonce32,
91+
const unsigned char *msg32,
92+
const unsigned char *key32,
93+
const unsigned char *adaptor33,
94+
const unsigned char *xonly_pk32,
95+
const unsigned char *algo,
96+
size_t algolen,
97+
void *data
98+
);
99+
100+
/** A modified BIP-340 nonce generation function. If a data pointer is passed, it is
101+
* assumed to be a pointer to 32 bytes of auxiliary random data as defined in BIP-340.
102+
* If the data pointer is NULL, the nonce derivation procedure uses a zeroed 32-byte
103+
* auxiliary random data. The hash will be tagged with algo after removing all
104+
* terminating null bytes.
105+
*/
106+
SECP256K1_API const secp256k1_nonce_function_hardened_schnorr_adaptor secp256k1_nonce_function_schnorr_adaptor;
107+
67108
#ifdef __cplusplus
68109
}
69110
#endif

src/modules/schnorr_adaptor/main_impl.h

+89
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,93 @@
1010
#include "../../../include/secp256k1.h"
1111
#include "../../../include/secp256k1_schnorr_adaptor.h"
1212

13+
#include "../../hash.h"
14+
#include "../../scalar.h"
15+
16+
/* Initializes SHA256 with fixed midstate. This midstate was computed by applying
17+
* SHA256 to SHA256("SchnorrAdaptor/nonce")||SHA256("SchnorrAdaptor/nonce"). */
18+
static void secp256k1_nonce_function_schnorr_adaptor_sha256_tagged(secp256k1_sha256 *sha) {
19+
secp256k1_sha256_initialize(sha);
20+
sha->s[0] = 0xe268ac2aul;
21+
sha->s[1] = 0x3a221b84ul;
22+
sha->s[2] = 0x69612afdul;
23+
sha->s[3] = 0x92ce3040ul;
24+
sha->s[4] = 0xc83ca35ful;
25+
sha->s[5] = 0xec2ee152ul;
26+
sha->s[6] = 0xba136ab7ul;
27+
sha->s[7] = 0x3bf6ec7ful;
28+
29+
sha->bytes = 64;
30+
}
31+
32+
/* Initializes SHA256 with fixed midstate. This midstate was computed by applying
33+
* SHA256 to SHA256("SchnorrAdaptor/aux")||SHA256("SchnorrAdaptor/aux"). */
34+
static void secp256k1_nonce_function_schnorr_adaptor_sha256_tagged_aux(secp256k1_sha256 *sha) {
35+
secp256k1_sha256_initialize(sha);
36+
sha->s[0] = 0x50685e98ul;
37+
sha->s[1] = 0x6313905eul;
38+
sha->s[2] = 0x6db24fa0ul;
39+
sha->s[3] = 0xc8b15c48ul;
40+
sha->s[4] = 0x6b318921ul;
41+
sha->s[5] = 0x441d8ff3ul;
42+
sha->s[6] = 0xa7033a66ul;
43+
sha->s[7] = 0xc3545cddul;
44+
45+
sha->bytes = 64;
46+
}
47+
48+
/* algo argument for `nonce_function_schnorr_adaptor` to derive the nonce using a tagged hash function. */
49+
static const unsigned char schnorr_adaptor_algo[20] = "SchnorrAdaptor/nonce";
50+
51+
/* Modified BIP-340 nonce function */
52+
static int nonce_function_schnorr_adaptor(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *adaptor33, const unsigned char *xonly_pk32, const unsigned char *algo, size_t algolen, void *data) {
53+
secp256k1_sha256 sha;
54+
unsigned char masked_key[32];
55+
int i;
56+
57+
if (algo == NULL) {
58+
return 0;
59+
}
60+
61+
if (data != NULL) {
62+
secp256k1_nonce_function_schnorr_adaptor_sha256_tagged_aux(&sha);
63+
secp256k1_sha256_write(&sha, data, 32);
64+
secp256k1_sha256_finalize(&sha, masked_key);
65+
for (i = 0; i < 32; i++) {
66+
masked_key[i] ^= key32[i];
67+
}
68+
} else {
69+
/* Precomputed TaggedHash("SchnorrAdaptor/aux", 0x0000...00); */
70+
static const unsigned char ZERO_MASK[32] = {
71+
65, 206, 231, 5, 44, 99, 30, 162,
72+
119, 101, 143, 108, 176, 134, 217, 23,
73+
54, 150, 157, 221, 198, 161, 164, 85,
74+
235, 82, 28, 56, 164, 220, 113, 53
75+
};
76+
for (i = 0; i < 32; i++) {
77+
masked_key[i] = key32[i] ^ ZERO_MASK[i];
78+
}
79+
}
80+
81+
/* Tag the hash with algo which is important to avoid nonce reuse across
82+
* algorithms. An optimized tagging implementation is used if the default
83+
* tag is provided. */
84+
if (algolen == sizeof(schnorr_adaptor_algo)
85+
&& secp256k1_memcmp_var(algo, schnorr_adaptor_algo, algolen) == 0) {
86+
secp256k1_nonce_function_schnorr_adaptor_sha256_tagged(&sha);
87+
} else {
88+
secp256k1_sha256_initialize_tagged(&sha, algo, algolen);
89+
}
90+
91+
/* Hash masked-key||adaptor33||pk||msg using the tagged hash */
92+
secp256k1_sha256_write(&sha, masked_key, 32);
93+
secp256k1_sha256_write(&sha, adaptor33, 33);
94+
secp256k1_sha256_write(&sha, xonly_pk32, 32);
95+
secp256k1_sha256_write(&sha, msg32, 32);
96+
secp256k1_sha256_finalize(&sha, nonce32);
97+
return 1;
98+
}
99+
100+
const secp256k1_nonce_function_hardened_schnorr_adaptor secp256k1_nonce_function_schnorr_adaptor = nonce_function_schnorr_adaptor;
101+
13102
#endif

0 commit comments

Comments
 (0)