Bitcoin ABC 0.26.3
P2P Digital Currency
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
10#include "include/secp256k1.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"). */
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"). */
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. */
48static const unsigned char bip340_algo16[16] = "BIP0340/nonce\0\0\0";
49
50static 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) {
52 unsigned char masked_key[32];
53 int i;
54
55 if (algo16 == NULL) {
56 return 0;
57 }
58
59 if (data != NULL) {
61 secp256k1_sha256_write(&sha, data, 32);
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. */
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 }
80 }
81
82 /* Hash (masked-)key||pk||msg using the tagged hash as per the spec */
83 if (data != NULL) {
85 } else {
87 }
91 return 1;
92}
93
95
96/* Initializes SHA256 with fixed midstate. This midstate was computed by applying
97 * SHA256 to SHA256("BIP0340/challenge")||SHA256("BIP0340/challenge"). */
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
111static 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];
115
116 /* tagged hash(r.x, pk.x, msg32) */
118 secp256k1_sha256_write(&sha, r32, 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. */
125}
126
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
141 ARG_CHECK(sig64 != NULL);
142 ARG_CHECK(msg32 != NULL);
144
145 if (noncefp == NULL) {
147 }
148
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)) {
155 }
156
163
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));
171 if (secp256k1_fe_is_odd(&r.y)) {
173 }
176
179 secp256k1_scalar_add(&e, &e, &k);
181
185 memset(seckey, 0, sizeof(seckey));
186
187 return ret;
188}
189
190int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const unsigned char *sig64, const unsigned char *msg32, const secp256k1_xonly_pubkey *pubkey) {
194 secp256k1_ge pk;
197 secp256k1_ge r;
198 unsigned char buf[32];
199 int overflow;
200
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
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);
223
224 /* Compute rj = s*G + (-e)*pkj */
227 secp256k1_ecmult(&ctx->ecmult_ctx, &rj, &pkj, &e, &s);
228
230 if (secp256k1_ge_is_infinity(&r)) {
231 return 0;
232 }
233
235 return !secp256k1_fe_is_odd(&r.y) &&
237}
238
239#endif
secp256k1_context * ctx
static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context *ctx)
static void secp256k1_ecmult(const secp256k1_ecmult_context *ctx, 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:151
static SECP256K1_INLINE int secp256k1_xonly_pubkey_load(const secp256k1_context *ctx, secp256k1_ge *ge, const secp256k1_xonly_pubkey *pubkey)
Definition main_impl.h:13
static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b)
Same as secp256k1_fe_equal, but may be variable time.
static void secp256k1_fe_normalize_var(secp256k1_fe *r)
Normalize a field element, without constant-time guarantee.
static int secp256k1_fe_is_odd(const secp256k1_fe *a)
Check the "oddness" of a field element.
static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a)
Set a field element equal to 32-byte big endian value.
static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a)
Convert a field element to a 32-byte big endian value.
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(secp256k1_sha256 *hash, const unsigned char *tag, size_t taglen)
Definition hash_impl.h:169
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
Definition random.h:85
static void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag)
If flag is true, set *r equal to *a; otherwise 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:31
int secp256k1_schnorrsig_verify(const secp256k1_context *ctx, const unsigned char *sig64, const unsigned char *msg32, const secp256k1_xonly_pubkey *pubkey)
Verify a Schnorr signature.
Definition main_impl.h:190
static void secp256k1_nonce_function_bip340_sha256_tagged_aux(secp256k1_sha256 *sha)
Definition main_impl.h:32
static void secp256k1_nonce_function_bip340_sha256_tagged(secp256k1_sha256 *sha)
Definition main_impl.h:16
static void secp256k1_schnorrsig_sha256_tagged(secp256k1_sha256 *sha)
Definition main_impl.h:98
const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340
An implementation of the nonce generation function as defined in Bitcoin Improvement Proposal 340 "Sc...
Definition main_impl.h:94
static void secp256k1_schnorrsig_challenge(secp256k1_scalar *e, const unsigned char *r32, const unsigned char *msg32, const unsigned char *pubkey32)
Definition main_impl.h:111
static const unsigned char bip340_algo16[16]
Definition main_impl.h:48
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)
Create a Schnorr signature.
Definition main_impl.h:127
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)
Definition main_impl.h:50
static void secp256k1_sha256_initialize(secp256k1_sha256 *hash)
static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32)
static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t size)
static SECP256K1_INLINE int secp256k1_memcmp_var(const void *s1, const void *s2, size_t n)
Semantics like memcmp.
Definition util.h:224
#define VERIFY_CHECK(cond)
Definition util.h:68
static SECP256K1_INLINE void secp256k1_memczero(void *s, size_t len, int flag)
Definition util.h:205
#define ARG_CHECK(cond)
Definition secp256k1.c:28
static SECP256K1_INLINE void secp256k1_declassify(const secp256k1_context *ctx, const void *p, size_t len)
Definition secp256k1.c:235
int(* secp256k1_nonce_function_hardened)(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *xonly_pk32, const unsigned char *algo16, 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:71
secp256k1_ecmult_context ecmult_ctx
Definition secp256k1.c:70
A group element of the secp256k1 curve, in affine coordinates.
Definition group.h:13
secp256k1_fe x
Definition group.h:14
secp256k1_fe y
Definition group.h:15
A group element of the secp256k1 curve, in jacobian coordinates.
Definition group.h:23
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
size_t bytes
Definition hash.h:16
uint32_t s[8]
Definition hash.h:14
Opaque data structure that holds a parsed and valid "x-only" public key.