1 /***********************************************************************
2  * Copyright (c) 2018-2020 Andrew Poelstra, Jonas Nick                 *
3  * Distributed under the MIT software license, see the accompanying    *
4  * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
5  ***********************************************************************/
6 
7 #ifndef SECP256K1_MODULE_SCHNORRSIG_MAIN_H
8 #define SECP256K1_MODULE_SCHNORRSIG_MAIN_H
9 
10 #include "include/secp256k1.h"
11 #include "include/secp256k1_schnorrsig.h"
12 #include "hash.h"
13 
14 /* Initializes SHA256 with fixed midstate. This midstate was computed by applying
15  * SHA256 to SHA256("BIP0340/nonce")||SHA256("BIP0340/nonce"). */
secp256k1_nonce_function_bip340_sha256_tagged(secp256k1_sha256 * sha)16 static void secp256k1_nonce_function_bip340_sha256_tagged(secp256k1_sha256 *sha) {
17     secp256k1_sha256_initialize(sha);
18     sha->s[0] = 0x46615b35ul;
19     sha->s[1] = 0xf4bfbff7ul;
20     sha->s[2] = 0x9f8dc671ul;
21     sha->s[3] = 0x83627ab3ul;
22     sha->s[4] = 0x60217180ul;
23     sha->s[5] = 0x57358661ul;
24     sha->s[6] = 0x21a29e54ul;
25     sha->s[7] = 0x68b07b4cul;
26 
27     sha->bytes = 64;
28 }
29 
30 /* Initializes SHA256 with fixed midstate. This midstate was computed by applying
31  * SHA256 to SHA256("BIP0340/aux")||SHA256("BIP0340/aux"). */
secp256k1_nonce_function_bip340_sha256_tagged_aux(secp256k1_sha256 * sha)32 static void secp256k1_nonce_function_bip340_sha256_tagged_aux(secp256k1_sha256 *sha) {
33     secp256k1_sha256_initialize(sha);
34     sha->s[0] = 0x24dd3219ul;
35     sha->s[1] = 0x4eba7e70ul;
36     sha->s[2] = 0xca0fabb9ul;
37     sha->s[3] = 0x0fa3166dul;
38     sha->s[4] = 0x3afbe4b1ul;
39     sha->s[5] = 0x4c44df97ul;
40     sha->s[6] = 0x4aac2739ul;
41     sha->s[7] = 0x249e850aul;
42 
43     sha->bytes = 64;
44 }
45 
46 /* algo16 argument for nonce_function_bip340 to derive the nonce exactly as stated in BIP-340
47  * by using the correct tagged hash function. */
48 static const unsigned char bip340_algo16[16] = "BIP0340/nonce\0\0\0";
49 
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)50 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) {
51     secp256k1_sha256 sha;
52     unsigned char masked_key[32];
53     int i;
54 
55     if (algo16 == NULL) {
56         return 0;
57     }
58 
59     if (data != NULL) {
60         secp256k1_nonce_function_bip340_sha256_tagged_aux(&sha);
61         secp256k1_sha256_write(&sha, data, 32);
62         secp256k1_sha256_finalize(&sha, masked_key);
63         for (i = 0; i < 32; i++) {
64             masked_key[i] ^= key32[i];
65         }
66     }
67 
68     /* Tag the hash with algo16 which is important to avoid nonce reuse across
69      * algorithms. If this nonce function is used in BIP-340 signing as defined
70      * in the spec, an optimized tagging implementation is used. */
71     if (secp256k1_memcmp_var(algo16, bip340_algo16, 16) == 0) {
72         secp256k1_nonce_function_bip340_sha256_tagged(&sha);
73     } else {
74         int algo16_len = 16;
75         /* Remove terminating null bytes */
76         while (algo16_len > 0 && !algo16[algo16_len - 1]) {
77             algo16_len--;
78         }
79         secp256k1_sha256_initialize_tagged(&sha, algo16, algo16_len);
80     }
81 
82     /* Hash (masked-)key||pk||msg using the tagged hash as per the spec */
83     if (data != NULL) {
84         secp256k1_sha256_write(&sha, masked_key, 32);
85     } else {
86         secp256k1_sha256_write(&sha, key32, 32);
87     }
88     secp256k1_sha256_write(&sha, xonly_pk32, 32);
89     secp256k1_sha256_write(&sha, msg32, 32);
90     secp256k1_sha256_finalize(&sha, nonce32);
91     return 1;
92 }
93 
94 const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340 = nonce_function_bip340;
95 
96 /* Initializes SHA256 with fixed midstate. This midstate was computed by applying
97  * SHA256 to SHA256("BIP0340/challenge")||SHA256("BIP0340/challenge"). */
secp256k1_schnorrsig_sha256_tagged(secp256k1_sha256 * sha)98 static void secp256k1_schnorrsig_sha256_tagged(secp256k1_sha256 *sha) {
99     secp256k1_sha256_initialize(sha);
100     sha->s[0] = 0x9cecba11ul;
101     sha->s[1] = 0x23925381ul;
102     sha->s[2] = 0x11679112ul;
103     sha->s[3] = 0xd1627e0ful;
104     sha->s[4] = 0x97c87550ul;
105     sha->s[5] = 0x003cc765ul;
106     sha->s[6] = 0x90f61164ul;
107     sha->s[7] = 0x33e9b66aul;
108     sha->bytes = 64;
109 }
110 
secp256k1_schnorrsig_challenge(secp256k1_scalar * e,const unsigned char * r32,const unsigned char * msg32,const unsigned char * pubkey32)111 static void secp256k1_schnorrsig_challenge(secp256k1_scalar* e, const unsigned char *r32, const unsigned char *msg32, const unsigned char *pubkey32)
112 {
113     unsigned char buf[32];
114     secp256k1_sha256 sha;
115 
116     /* tagged hash(r.x, pk.x, msg32) */
117     secp256k1_schnorrsig_sha256_tagged(&sha);
118     secp256k1_sha256_write(&sha, r32, 32);
119     secp256k1_sha256_write(&sha, pubkey32, 32);
120     secp256k1_sha256_write(&sha, msg32, 32);
121     secp256k1_sha256_finalize(&sha, buf);
122     /* Set scalar e to the challenge hash modulo the curve order as per
123      * BIP340. */
124     secp256k1_scalar_set_b32(e, buf, NULL);
125 }
126 
secp256k1_schnorrsig_sign(const secp256k1_context * ctx,unsigned char * sig64,const unsigned char * msg32,const secp256k1_keypair * keypair,secp256k1_nonce_function_hardened noncefp,void * ndata)127 int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, secp256k1_nonce_function_hardened noncefp, void *ndata) {
128     secp256k1_scalar sk;
129     secp256k1_scalar e;
130     secp256k1_scalar k;
131     secp256k1_gej rj;
132     secp256k1_ge pk;
133     secp256k1_ge r;
134     unsigned char buf[32] = { 0 };
135     unsigned char pk_buf[32];
136     unsigned char seckey[32];
137     int ret = 1;
138 
139     VERIFY_CHECK(ctx != NULL);
140     ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
141     ARG_CHECK(sig64 != NULL);
142     ARG_CHECK(msg32 != NULL);
143     ARG_CHECK(keypair != NULL);
144 
145     if (noncefp == NULL) {
146         noncefp = secp256k1_nonce_function_bip340;
147     }
148 
149     ret &= secp256k1_keypair_load(ctx, &sk, &pk, keypair);
150     /* Because we are signing for a x-only pubkey, the secret key is negated
151      * before signing if the point corresponding to the secret key does not
152      * have an even Y. */
153     if (secp256k1_fe_is_odd(&pk.y)) {
154         secp256k1_scalar_negate(&sk, &sk);
155     }
156 
157     secp256k1_scalar_get_b32(seckey, &sk);
158     secp256k1_fe_get_b32(pk_buf, &pk.x);
159     ret &= !!noncefp(buf, msg32, seckey, pk_buf, bip340_algo16, ndata);
160     secp256k1_scalar_set_b32(&k, buf, NULL);
161     ret &= !secp256k1_scalar_is_zero(&k);
162     secp256k1_scalar_cmov(&k, &secp256k1_scalar_one, !ret);
163 
164     secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &rj, &k);
165     secp256k1_ge_set_gej(&r, &rj);
166 
167     /* We declassify r to allow using it as a branch point. This is fine
168      * because r is not a secret. */
169     secp256k1_declassify(ctx, &r, sizeof(r));
170     secp256k1_fe_normalize_var(&r.y);
171     if (secp256k1_fe_is_odd(&r.y)) {
172         secp256k1_scalar_negate(&k, &k);
173     }
174     secp256k1_fe_normalize_var(&r.x);
175     secp256k1_fe_get_b32(&sig64[0], &r.x);
176 
177     secp256k1_schnorrsig_challenge(&e, &sig64[0], msg32, pk_buf);
178     secp256k1_scalar_mul(&e, &e, &sk);
179     secp256k1_scalar_add(&e, &e, &k);
180     secp256k1_scalar_get_b32(&sig64[32], &e);
181 
182     secp256k1_memczero(sig64, 64, !ret);
183     secp256k1_scalar_clear(&k);
184     secp256k1_scalar_clear(&sk);
185     memset(seckey, 0, sizeof(seckey));
186 
187     return ret;
188 }
189 
secp256k1_schnorrsig_verify(const secp256k1_context * ctx,const unsigned char * sig64,const unsigned char * msg32,const secp256k1_xonly_pubkey * pubkey)190 int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const unsigned char *sig64, const unsigned char *msg32, const secp256k1_xonly_pubkey *pubkey) {
191     secp256k1_scalar s;
192     secp256k1_scalar e;
193     secp256k1_gej rj;
194     secp256k1_ge pk;
195     secp256k1_gej pkj;
196     secp256k1_fe rx;
197     secp256k1_ge r;
198     unsigned char buf[32];
199     int overflow;
200 
201     VERIFY_CHECK(ctx != NULL);
202     ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
203     ARG_CHECK(sig64 != NULL);
204     ARG_CHECK(msg32 != NULL);
205     ARG_CHECK(pubkey != NULL);
206 
207     if (!secp256k1_fe_set_b32(&rx, &sig64[0])) {
208         return 0;
209     }
210 
211     secp256k1_scalar_set_b32(&s, &sig64[32], &overflow);
212     if (overflow) {
213         return 0;
214     }
215 
216     if (!secp256k1_xonly_pubkey_load(ctx, &pk, pubkey)) {
217         return 0;
218     }
219 
220     /* Compute e. */
221     secp256k1_fe_get_b32(buf, &pk.x);
222     secp256k1_schnorrsig_challenge(&e, &sig64[0], msg32, buf);
223 
224     /* Compute rj =  s*G + (-e)*pkj */
225     secp256k1_scalar_negate(&e, &e);
226     secp256k1_gej_set_ge(&pkj, &pk);
227     secp256k1_ecmult(&ctx->ecmult_ctx, &rj, &pkj, &e, &s);
228 
229     secp256k1_ge_set_gej_var(&r, &rj);
230     if (secp256k1_ge_is_infinity(&r)) {
231         return 0;
232     }
233 
234     secp256k1_fe_normalize_var(&r.y);
235     return !secp256k1_fe_is_odd(&r.y) &&
236            secp256k1_fe_equal_var(&rx, &r.x);
237 }
238 
239 #endif
240