Bitcoin Core 31.99.0
P2P Digital Currency
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
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"). */
17 static const uint32_t midstate[8] = {
18 0x46615b35ul, 0xf4bfbff7ul, 0x9f8dc671ul, 0x83627ab3ul,
19 0x60217180ul, 0x57358661ul, 0x21a29e54ul, 0x68b07b4cul
20 };
21 secp256k1_sha256_initialize_midstate(sha, 64, midstate);
22}
23
24/* Initializes SHA256 with fixed midstate. This midstate was computed by applying
25 * SHA256 to SHA256("BIP0340/aux")||SHA256("BIP0340/aux"). */
27 static const uint32_t midstate[8] = {
28 0x24dd3219ul, 0x4eba7e70ul, 0xca0fabb9ul, 0x0fa3166dul,
29 0x3afbe4b1ul, 0x4c44df97ul, 0x4aac2739ul, 0x249e850aul
30 };
31 secp256k1_sha256_initialize_midstate(sha, 64, midstate);
32}
33
34/* algo argument for nonce_function_bip340 to derive the nonce exactly as stated in BIP-340
35 * by using the correct tagged hash function. */
36static const unsigned char bip340_algo[] = {'B', 'I', 'P', '0', '3', '4', '0', '/', 'n', 'o', 'n', 'c', 'e'};
37
39
40static int nonce_function_bip340_impl(const secp256k1_hash_ctx *hash_ctx, 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) {
42 unsigned char masked_key[32];
43 int i;
44
45 if (algo == NULL) {
46 return 0;
47 }
48
49 if (data != NULL) {
51 secp256k1_sha256_write(hash_ctx, &sha, data, 32);
52 secp256k1_sha256_finalize(hash_ctx, &sha, masked_key);
53 for (i = 0; i < 32; i++) {
54 masked_key[i] ^= key32[i];
55 }
56 } else {
57 /* Precomputed TaggedHash("BIP0340/aux", 0x0000...00); */
58 static const unsigned char ZERO_MASK[32] = {
59 84, 241, 105, 207, 201, 226, 229, 114,
60 116, 128, 68, 31, 144, 186, 37, 196,
61 136, 244, 97, 199, 11, 94, 165, 220,
62 170, 247, 175, 105, 39, 10, 165, 20
63 };
64 for (i = 0; i < 32; i++) {
65 masked_key[i] = key32[i] ^ ZERO_MASK[i];
66 }
67 }
68
69 /* Tag the hash with algo which is important to avoid nonce reuse across
70 * algorithms. If this nonce function is used in BIP-340 signing as defined
71 * in the spec, an optimized tagging implementation is used. */
72 if (algolen == sizeof(bip340_algo)
73 && secp256k1_memcmp_var(algo, bip340_algo, algolen) == 0) {
75 } else {
76 secp256k1_sha256_initialize_tagged(hash_ctx, &sha, algo, algolen);
77 }
78
79 /* Hash masked-key||pk||msg using the tagged hash as per the spec */
80 secp256k1_sha256_write(hash_ctx, &sha, masked_key, 32);
81 secp256k1_sha256_write(hash_ctx, &sha, xonly_pk32, 32);
82 secp256k1_sha256_write(hash_ctx, &sha, msg, msglen);
83 secp256k1_sha256_finalize(hash_ctx, &sha, nonce32);
85 secp256k1_memclear_explicit(masked_key, sizeof(masked_key));
86
87 return 1;
88}
89
90static 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) {
91 return nonce_function_bip340_impl(secp256k1_get_hash_context(secp256k1_context_static), nonce32, msg, msglen, key32, xonly_pk32, algo, algolen, data);
92}
93
95
96/* Initializes SHA256 with fixed midstate. This midstate was computed by applying
97 * SHA256 to SHA256("BIP0340/challenge")||SHA256("BIP0340/challenge"). */
99 static const uint32_t midstate[8] = {
100 0x9cecba11ul, 0x23925381ul, 0x11679112ul, 0xd1627e0ful,
101 0x97c87550ul, 0x003cc765ul, 0x90f61164ul, 0x33e9b66aul
102 };
103 secp256k1_sha256_initialize_midstate(sha, 64, midstate);
104}
105
106static void secp256k1_schnorrsig_challenge(const secp256k1_hash_ctx *hash_ctx, secp256k1_scalar* e, const unsigned char *r32, const unsigned char *msg, size_t msglen, const unsigned char *pubkey32)
107{
108 unsigned char buf[32];
110
111 /* tagged hash(r.x, pk.x, msg) */
113 secp256k1_sha256_write(hash_ctx, &sha, r32, 32);
114 secp256k1_sha256_write(hash_ctx, &sha, pubkey32, 32);
115 secp256k1_sha256_write(hash_ctx, &sha, msg, msglen);
116 secp256k1_sha256_finalize(hash_ctx, &sha, buf);
117 /* Set scalar e to the challenge hash modulo the curve order as per
118 * BIP340. */
119 secp256k1_scalar_set_b32(e, buf, NULL);
120}
121
122static 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) {
126 secp256k1_gej rj;
128 secp256k1_ge r;
129 unsigned char nonce32[32] = { 0 };
130 unsigned char pk_buf[32];
131 unsigned char seckey[32];
132 int ret = 1;
133
134 VERIFY_CHECK(ctx != NULL);
136 ARG_CHECK(sig64 != NULL);
137 ARG_CHECK(msg != NULL || msglen == 0);
138 ARG_CHECK(keypair != NULL);
139
140 ret &= secp256k1_keypair_load(ctx, &sk, &pk, keypair);
141 /* Because we are signing for a x-only pubkey, the secret key is negated
142 * before signing if the point corresponding to the secret key does not
143 * have an even Y. */
144 if (secp256k1_fe_is_odd(&pk.y)) {
146 }
147
149 secp256k1_fe_get_b32(pk_buf, &pk.x);
150
151 /* Compute nonce */
152 if (noncefp == NULL || noncefp == secp256k1_nonce_function_bip340) {
153 /* Use context-aware nonce function by default */
154 ret &= nonce_function_bip340_impl(secp256k1_get_hash_context(ctx), nonce32, msg, msglen, seckey, pk_buf, bip340_algo, sizeof(bip340_algo), ndata);
155 } else {
156 ret &= !!noncefp(nonce32, msg, msglen, seckey, pk_buf, bip340_algo, sizeof(bip340_algo), ndata);
157 }
158
159 secp256k1_scalar_set_b32(&k, nonce32, NULL);
162
164 secp256k1_ge_set_gej(&r, &rj);
165
166 /* We declassify r to allow using it as a branch point. This is fine
167 * because r is not a secret. */
168 secp256k1_declassify(ctx, &r, sizeof(r));
170 if (secp256k1_fe_is_odd(&r.y)) {
172 }
174 secp256k1_fe_get_b32(&sig64[0], &r.x);
175
176 secp256k1_schnorrsig_challenge(secp256k1_get_hash_context(ctx), &e, &sig64[0], msg, msglen, pk_buf);
177 secp256k1_scalar_mul(&e, &e, &sk);
178 secp256k1_scalar_add(&e, &e, &k);
179 secp256k1_scalar_get_b32(&sig64[32], &e);
180
181 secp256k1_memczero(sig64, 64, !ret);
184 secp256k1_memclear_explicit(seckey, sizeof(seckey));
185 secp256k1_memclear_explicit(nonce32, sizeof(nonce32));
187
188 return ret;
189}
190
191int secp256k1_schnorrsig_sign32(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, const unsigned char *aux_rand32) {
192 /* We cast away const from the passed aux_rand32 argument since we know the default nonce function does not modify it. */
193 return secp256k1_schnorrsig_sign_internal(ctx, sig64, msg32, 32, keypair, secp256k1_nonce_function_bip340, (unsigned char*)aux_rand32);
194}
195
196int secp256k1_schnorrsig_sign(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, const unsigned char *aux_rand32) {
197 return secp256k1_schnorrsig_sign32(ctx, sig64, msg32, keypair, aux_rand32);
198}
199
200int 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) {
202 void *ndata = NULL;
203 VERIFY_CHECK(ctx != NULL);
204
205 if (extraparams != NULL) {
208 sizeof(extraparams->magic)) == 0);
209 noncefp = extraparams->noncefp;
210 ndata = extraparams->ndata;
211 }
212 return secp256k1_schnorrsig_sign_internal(ctx, sig64, msg, msglen, keypair, noncefp, ndata);
213}
214
215int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_xonly_pubkey *pubkey) {
218 secp256k1_gej rj;
220 secp256k1_gej pkj;
221 secp256k1_fe rx;
222 secp256k1_ge r;
223 unsigned char buf[32];
224 int overflow;
225
226 VERIFY_CHECK(ctx != NULL);
227 ARG_CHECK(sig64 != NULL);
228 ARG_CHECK(msg != NULL || msglen == 0);
229 ARG_CHECK(pubkey != NULL);
230
231 if (!secp256k1_fe_set_b32_limit(&rx, &sig64[0])) {
232 return 0;
233 }
234
235 secp256k1_scalar_set_b32(&s, &sig64[32], &overflow);
236 if (overflow) {
237 return 0;
238 }
239
240 if (!secp256k1_xonly_pubkey_load(ctx, &pk, pubkey)) {
241 return 0;
242 }
243
244 /* Compute e. */
245 secp256k1_fe_get_b32(buf, &pk.x);
246 secp256k1_schnorrsig_challenge(secp256k1_get_hash_context(ctx), &e, &sig64[0], msg, msglen, buf);
247
248 /* Compute rj = s*G + (-e)*pkj */
250 secp256k1_gej_set_ge(&pkj, &pk);
251 secp256k1_ecmult(&rj, &pkj, &e, &s);
252
254 if (secp256k1_ge_is_infinity(&r)) {
255 return 0;
256 }
257
259 return !secp256k1_fe_is_odd(&r.y) &&
260 secp256k1_fe_equal(&rx, &r.x);
261}
262
263#endif
int ret
static void secp256k1_ecmult(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng)
Double multiply: R = na*A + ng*G.
static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp256k1_gej *r, const secp256k1_scalar *a)
Multiply with the generator: R = a*G.
static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context *ctx)
static int secp256k1_keypair_load(const secp256k1_context *ctx, secp256k1_scalar *sk, secp256k1_ge *pk, const secp256k1_keypair *keypair)
Definition: main_impl.h:176
static SECP256K1_INLINE int secp256k1_xonly_pubkey_load(const secp256k1_context *ctx, secp256k1_ge *ge, const secp256k1_xonly_pubkey *pubkey)
Definition: main_impl.h:14
#define secp256k1_fe_is_odd
Definition: field.h:85
#define secp256k1_fe_normalize_var
Definition: field.h:80
#define secp256k1_fe_set_b32_limit
Definition: field.h:88
#define secp256k1_fe_get_b32
Definition: field.h:89
static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b)
Determine whether two field elements are equal.
static void secp256k1_gej_clear(secp256k1_gej *r)
Clear a secp256k1_gej to prevent leaking sensitive information.
static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a)
Set a group element equal to another which is given in jacobian coordinates.
static int secp256k1_ge_is_infinity(const secp256k1_ge *a)
Check whether a group element is the point at infinity.
static void secp256k1_gej_set_ge(secp256k1_gej *r, const secp256k1_ge *a)
Set a group element (jacobian) equal to another which is given in affine coordinates.
static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a)
Set a group element equal to another which is given in jacobian coordinates.
static void secp256k1_sha256_initialize_tagged(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *hash, const unsigned char *tag, size_t taglen)
Definition: hash_impl.h:196
static void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag)
If flag is 1, set *r equal to *a; if flag is 0, leave it.
static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *bin, int *overflow)
Set a scalar from a big endian byte array.
static int secp256k1_scalar_is_zero(const secp256k1_scalar *a)
Check whether a scalar equals zero.
static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar *a)
Convert a scalar to a byte array.
static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b)
Add two scalars together (modulo the group order).
static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b)
Multiply two scalars (modulo the group order).
static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a)
Compute the complement of a scalar (modulo the group order).
static void secp256k1_scalar_clear(secp256k1_scalar *r)
Clear a scalar to prevent the leak of sensitive data.
static const secp256k1_scalar secp256k1_scalar_one
Definition: scalar_impl.h:27
static 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)
Definition: main_impl.h:90
static const unsigned char schnorrsig_extraparams_magic[4]
Definition: main_impl.h:38
static void secp256k1_nonce_function_bip340_sha256_tagged_aux(secp256k1_sha256 *sha)
Definition: main_impl.h:26
int secp256k1_schnorrsig_sign(const secp256k1_context *ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, const unsigned char *aux_rand32)
Same as secp256k1_schnorrsig_sign32, but DEPRECATED.
Definition: main_impl.h:196
static void secp256k1_nonce_function_bip340_sha256_tagged(secp256k1_sha256 *sha)
Definition: main_impl.h:16
static void secp256k1_schnorrsig_challenge(const secp256k1_hash_ctx *hash_ctx, secp256k1_scalar *e, const unsigned char *r32, const unsigned char *msg, size_t msglen, const unsigned char *pubkey32)
Definition: main_impl.h:106
static void secp256k1_schnorrsig_sha256_tagged(secp256k1_sha256 *sha)
Definition: main_impl.h:98
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)
Create a Schnorr signature with a more flexible API.
Definition: main_impl.h:200
int secp256k1_schnorrsig_sign32(const secp256k1_context *ctx, unsigned char *sig64, const unsigned char *msg32, const secp256k1_keypair *keypair, const unsigned char *aux_rand32)
Create a Schnorr signature.
Definition: main_impl.h:191
static const unsigned char bip340_algo[]
Definition: main_impl.h:36
static 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)
Definition: main_impl.h:122
const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340
Definition: main_impl.h:94
int secp256k1_schnorrsig_verify(const secp256k1_context *ctx, const unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_xonly_pubkey *pubkey)
Verify a Schnorr signature.
Definition: main_impl.h:215
static int nonce_function_bip340_impl(const secp256k1_hash_ctx *hash_ctx, 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)
Definition: main_impl.h:40
static void secp256k1_sha256_finalize(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *hash, unsigned char *out32)
static void secp256k1_sha256_initialize_midstate(secp256k1_sha256 *hash, uint64_t bytes, const uint32_t state[8])
static void secp256k1_sha256_write(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *hash, const unsigned char *data, size_t size)
static void secp256k1_sha256_clear(secp256k1_sha256 *hash)
static SECP256K1_INLINE void secp256k1_memclear_explicit(void *ptr, size_t len)
Definition: util.h:258
static SECP256K1_INLINE int secp256k1_memcmp_var(const void *s1, const void *s2, size_t n)
Semantics like memcmp.
Definition: util.h:271
#define VERIFY_CHECK(cond)
Definition: util.h:159
static SECP256K1_INLINE void secp256k1_memczero(void *s, size_t len, int flag)
Definition: util.h:210
#define ARG_CHECK(cond)
Definition: secp256k1.c:45
static SECP256K1_INLINE void secp256k1_declassify(const secp256k1_context *ctx, const void *p, size_t len)
Definition: secp256k1.c:255
static SECP256K1_INLINE const secp256k1_hash_ctx * secp256k1_get_hash_context(const secp256k1_context *ctx)
Definition: secp256k1.c:238
SECP256K1_API const secp256k1_context *const secp256k1_context_static
A built-in constant secp256k1 context object with static storage duration, to be used in conjunction ...
Definition: secp256k1.h:246
#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)
This module implements a variant of Schnorr signatures compliant with Bitcoin Improvement Proposal 34...
secp256k1_ecmult_gen_context ecmult_gen_ctx
Definition: secp256k1.c:62
This field implementation represents the value as 10 uint32_t limbs in base 2^26.
Definition: field_10x26.h:14
A group element in affine coordinates on the secp256k1 curve, or occasionally on an isomorphic curve ...
Definition: group.h:16
secp256k1_fe x
Definition: group.h:17
secp256k1_fe y
Definition: group.h:18
A group element of the secp256k1 curve, in jacobian coordinates.
Definition: group.h:28
Opaque data structure that holds a keypair consisting of a secret and a public key.
A scalar modulo the group order of the secp256k1 curve.
Definition: scalar_4x64.h:13
Data structure that contains additional arguments for schnorrsig_sign_custom.
secp256k1_nonce_function_hardened noncefp
Opaque data structure that holds a parsed and valid "x-only" public key.