Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
main_impl.h
Go to the documentation of this file.
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
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"). */
16static 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"). */
32static 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/* algo argument for nonce_function_bip340 to derive the nonce exactly as stated in BIP-340
47 * by using the correct tagged hash function. */
48static const unsigned char bip340_algo[13] = "BIP0340/nonce";
49
50static const unsigned char schnorrsig_extraparams_magic[4] = SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC;
51
52static int nonce_function_bip340(unsigned char *nonce32, const unsigned char *msg, size_t msglen, const unsigned char *key32, const unsigned char *xonly_pk32, const unsigned char *algo, size_t algolen, void *data) {
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_bip340_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("BIP0340/aux", 0x0000...00); */
70 static const unsigned char ZERO_MASK[32] = {
71 84, 241, 105, 207, 201, 226, 229, 114,
72 116, 128, 68, 31, 144, 186, 37, 196,
73 136, 244, 97, 199, 11, 94, 165, 220,
74 170, 247, 175, 105, 39, 10, 165, 20
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. If this nonce function is used in BIP-340 signing as defined
83 * in the spec, an optimized tagging implementation is used. */
84 if (algolen == sizeof(bip340_algo)
85 && secp256k1_memcmp_var(algo, bip340_algo, algolen) == 0) {
86 secp256k1_nonce_function_bip340_sha256_tagged(&sha);
87 } else {
88 secp256k1_sha256_initialize_tagged(&sha, algo, algolen);
89 }
90
91 /* Hash masked-key||pk||msg using the tagged hash as per the spec */
92 secp256k1_sha256_write(&sha, masked_key, 32);
93 secp256k1_sha256_write(&sha, xonly_pk32, 32);
94 secp256k1_sha256_write(&sha, msg, msglen);
95 secp256k1_sha256_finalize(&sha, nonce32);
96 return 1;
97}
98
100
101/* Initializes SHA256 with fixed midstate. This midstate was computed by applying
102 * SHA256 to SHA256("BIP0340/challenge")||SHA256("BIP0340/challenge"). */
103static void secp256k1_schnorrsig_sha256_tagged(secp256k1_sha256 *sha) {
104 secp256k1_sha256_initialize(sha);
105 sha->s[0] = 0x9cecba11ul;
106 sha->s[1] = 0x23925381ul;
107 sha->s[2] = 0x11679112ul;
108 sha->s[3] = 0xd1627e0ful;
109 sha->s[4] = 0x97c87550ul;
110 sha->s[5] = 0x003cc765ul;
111 sha->s[6] = 0x90f61164ul;
112 sha->s[7] = 0x33e9b66aul;
113 sha->bytes = 64;
114}
115
116static void secp256k1_schnorrsig_challenge(secp256k1_scalar* e, const unsigned char *r32, const unsigned char *msg, size_t msglen, const unsigned char *pubkey32)
117{
118 unsigned char buf[32];
120
121 /* tagged hash(r.x, pk.x, msg) */
122 secp256k1_schnorrsig_sha256_tagged(&sha);
123 secp256k1_sha256_write(&sha, r32, 32);
124 secp256k1_sha256_write(&sha, pubkey32, 32);
125 secp256k1_sha256_write(&sha, msg, msglen);
126 secp256k1_sha256_finalize(&sha, buf);
127 /* Set scalar e to the challenge hash modulo the curve order as per
128 * BIP340. */
129 secp256k1_scalar_set_b32(e, buf, NULL);
130}
131
132static int secp256k1_schnorrsig_sign_internal(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_keypair *keypair, secp256k1_nonce_function_hardened noncefp, void *ndata) {
136 secp256k1_gej rj;
137 secp256k1_ge pk;
139 unsigned char buf[32] = { 0 };
140 unsigned char pk_buf[32];
141 unsigned char seckey[32];
142 int ret = 1;
143
144 VERIFY_CHECK(ctx != NULL);
145 ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
146 ARG_CHECK(sig64 != NULL);
147 ARG_CHECK(msg != NULL || msglen == 0);
148 ARG_CHECK(keypair != NULL);
149
150 if (noncefp == NULL) {
152 }
153
154 ret &= secp256k1_keypair_load(ctx, &sk, &pk, keypair);
155 /* Because we are signing for a x-only pubkey, the secret key is negated
156 * before signing if the point corresponding to the secret key does not
157 * have an even Y. */
158 if (secp256k1_fe_is_odd(&pk.y)) {
159 secp256k1_scalar_negate(&sk, &sk);
160 }
161
162 secp256k1_scalar_get_b32(seckey, &sk);
163 secp256k1_fe_get_b32(pk_buf, &pk.x);
164 ret &= !!noncefp(buf, msg, msglen, seckey, pk_buf, bip340_algo, sizeof(bip340_algo), ndata);
165 secp256k1_scalar_set_b32(&k, buf, NULL);
166 ret &= !secp256k1_scalar_is_zero(&k);
167 secp256k1_scalar_cmov(&k, &secp256k1_scalar_one, !ret);
168
169 secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &rj, &k);
170 secp256k1_ge_set_gej(&r, &rj);
171
172 /* We declassify r to allow using it as a branch point. This is fine
173 * because r is not a secret. */
174 secp256k1_declassify(ctx, &r, sizeof(r));
175 secp256k1_fe_normalize_var(&r.y);
176 if (secp256k1_fe_is_odd(&r.y)) {
177 secp256k1_scalar_negate(&k, &k);
178 }
179 secp256k1_fe_normalize_var(&r.x);
180 secp256k1_fe_get_b32(&sig64[0], &r.x);
181
182 secp256k1_schnorrsig_challenge(&e, &sig64[0], msg, msglen, pk_buf);
183 secp256k1_scalar_mul(&e, &e, &sk);
184 secp256k1_scalar_add(&e, &e, &k);
185 secp256k1_scalar_get_b32(&sig64[32], &e);
186
187 secp256k1_memczero(sig64, 64, !ret);
188 secp256k1_scalar_clear(&k);
189 secp256k1_scalar_clear(&sk);
190 memset(seckey, 0, sizeof(seckey));
191
192 return ret;
193}
194
195int secp256k1_schnorrsig_sign32(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, const unsigned char *aux_rand32) {
196 /* We cast away const from the passed aux_rand32 argument since we know the default nonce function does not modify it. */
197 return secp256k1_schnorrsig_sign_internal(ctx, sig64, msg32, 32, keypair, secp256k1_nonce_function_bip340, (unsigned char*)aux_rand32);
198}
199
200int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, const unsigned char *aux_rand32) {
201 return secp256k1_schnorrsig_sign32(ctx, sig64, msg32, keypair, aux_rand32);
202}
203
204int secp256k1_schnorrsig_sign_custom(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_keypair *keypair, secp256k1_schnorrsig_extraparams *extraparams) {
206 void *ndata = NULL;
207 VERIFY_CHECK(ctx != NULL);
208
209 if (extraparams != NULL) {
210 ARG_CHECK(secp256k1_memcmp_var(extraparams->magic,
211 schnorrsig_extraparams_magic,
212 sizeof(extraparams->magic)) == 0);
213 noncefp = extraparams->noncefp;
214 ndata = extraparams->ndata;
215 }
216 return secp256k1_schnorrsig_sign_internal(ctx, sig64, msg, msglen, keypair, noncefp, ndata);
217}
218
219int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_xonly_pubkey *pubkey) {
222 secp256k1_gej rj;
223 secp256k1_ge pk;
224 secp256k1_gej pkj;
225 secp256k1_fe rx;
227 unsigned char buf[32];
228 int overflow;
229
230 VERIFY_CHECK(ctx != NULL);
231 ARG_CHECK(sig64 != NULL);
232 ARG_CHECK(msg != NULL || msglen == 0);
233 ARG_CHECK(pubkey != NULL);
234
235 if (!secp256k1_fe_set_b32(&rx, &sig64[0])) {
236 return 0;
237 }
238
239 secp256k1_scalar_set_b32(&s, &sig64[32], &overflow);
240 if (overflow) {
241 return 0;
242 }
243
244 if (!secp256k1_xonly_pubkey_load(ctx, &pk, pubkey)) {
245 return 0;
246 }
247
248 /* Compute e. */
249 secp256k1_fe_get_b32(buf, &pk.x);
250 secp256k1_schnorrsig_challenge(&e, &sig64[0], msg, msglen, buf);
251
252 /* Compute rj = s*G + (-e)*pkj */
253 secp256k1_scalar_negate(&e, &e);
254 secp256k1_gej_set_ge(&pkj, &pk);
255 secp256k1_ecmult(&rj, &pkj, &e, &s);
256
257 secp256k1_ge_set_gej_var(&r, &rj);
258 if (secp256k1_ge_is_infinity(&r)) {
259 return 0;
260 }
261
262 secp256k1_fe_normalize_var(&r.y);
263 return !secp256k1_fe_is_odd(&r.y) &&
264 secp256k1_fe_equal_var(&rx, &r.x);
265}
266
267#endif
const mie::Vuint & r
Definition bn.cpp:28
#define VERIFY_CHECK(cond)
Definition util.h:95
int secp256k1_schnorrsig_sign(const secp256k1_context *ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, const unsigned char *aux_rand32)
Definition main_impl.h:200
int secp256k1_schnorrsig_sign_custom(const secp256k1_context *ctx, unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_keypair *keypair, secp256k1_schnorrsig_extraparams *extraparams)
Definition main_impl.h:204
int secp256k1_schnorrsig_sign32(const secp256k1_context *ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, const unsigned char *aux_rand32)
Definition main_impl.h:195
const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340
Definition main_impl.h:99
int secp256k1_schnorrsig_verify(const secp256k1_context *ctx, const unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_xonly_pubkey *pubkey)
Definition main_impl.h:219
#define ARG_CHECK(cond)
Definition secp256k1.c:34
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC
int(* secp256k1_nonce_function_hardened)(unsigned char *nonce32, const unsigned char *msg, size_t msglen, const unsigned char *key32, const unsigned char *xonly_pk32, const unsigned char *algo, size_t algolen, void *data)
secp256k1_ecmult_gen_context ecmult_gen_ctx
Definition secp256k1.c:48
secp256k1_fe x
Definition group.h:17
secp256k1_fe y
Definition group.h:18
secp256k1_nonce_function_hardened noncefp
uint64_t bytes
Definition hash.h:16
uint32_t s[8]
Definition hash.h:14
CK_RV ret
bool overflow
char * s
uint8_t buf[2048]
CK_BYTE_PTR pubkey
memset(pInfo->slotDescription, ' ', 64)