]>
Commit | Line | Data |
---|---|---|
71712b27 | 1 | /********************************************************************** |
a9b6595e | 2 | * Copyright (c) 2013-2015 Pieter Wuille * |
71712b27 GM |
3 | * Distributed under the MIT software license, see the accompanying * |
4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* | |
5 | **********************************************************************/ | |
0a433ea2 | 6 | |
04e34d18 PW |
7 | #include "include/secp256k1.h" |
8 | ||
1c7fa133 | 9 | #include "util.h" |
11ab5622 PW |
10 | #include "num_impl.h" |
11 | #include "field_impl.h" | |
a9f5c8b8 | 12 | #include "scalar_impl.h" |
11ab5622 PW |
13 | #include "group_impl.h" |
14 | #include "ecmult_impl.h" | |
44015000 | 15 | #include "ecmult_const_impl.h" |
949c1ebb | 16 | #include "ecmult_gen_impl.h" |
11ab5622 | 17 | #include "ecdsa_impl.h" |
e2f71f1e | 18 | #include "eckey_impl.h" |
b37fbc28 | 19 | #include "hash_impl.h" |
548de42e | 20 | #include "scratch_impl.h" |
254327e4 | 21 | |
995c5487 PW |
22 | #define ARG_CHECK(cond) do { \ |
23 | if (EXPECT(!(cond), 0)) { \ | |
dd891e0e | 24 | secp256k1_callback_call(&ctx->illegal_callback, #cond); \ |
995c5487 PW |
25 | return 0; \ |
26 | } \ | |
27 | } while(0) | |
28 | ||
29 | static void default_illegal_callback_fn(const char* str, void* data) { | |
30 | (void)data; | |
31 | fprintf(stderr, "[libsecp256k1] illegal argument: %s\n", str); | |
32 | abort(); | |
33 | } | |
34 | ||
dd891e0e | 35 | static const secp256k1_callback default_illegal_callback = { |
995c5487 PW |
36 | default_illegal_callback_fn, |
37 | NULL | |
38 | }; | |
39 | ||
40 | static void default_error_callback_fn(const char* str, void* data) { | |
41 | (void)data; | |
42 | fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str); | |
43 | abort(); | |
44 | } | |
45 | ||
dd891e0e | 46 | static const secp256k1_callback default_error_callback = { |
995c5487 PW |
47 | default_error_callback_fn, |
48 | NULL | |
49 | }; | |
50 | ||
51 | ||
a9b6595e | 52 | struct secp256k1_context_struct { |
dd891e0e PW |
53 | secp256k1_ecmult_context ecmult_ctx; |
54 | secp256k1_ecmult_gen_context ecmult_gen_ctx; | |
55 | secp256k1_callback illegal_callback; | |
56 | secp256k1_callback error_callback; | |
a9b6595e PW |
57 | }; |
58 | ||
ed7c0841 AP |
59 | static const secp256k1_context secp256k1_context_no_precomp_ = { |
60 | { 0 }, | |
61 | { 0 }, | |
62 | { default_illegal_callback_fn, 0 }, | |
63 | { default_error_callback_fn, 0 } | |
64 | }; | |
65 | const secp256k1_context *secp256k1_context_no_precomp = &secp256k1_context_no_precomp_; | |
66 | ||
ef020de1 TR |
67 | size_t secp256k1_context_preallocated_size(unsigned int flags) { |
68 | size_t ret = ROUND_TO_ALIGN(sizeof(secp256k1_context)); | |
69 | ||
70 | if (EXPECT((flags & SECP256K1_FLAGS_TYPE_MASK) != SECP256K1_FLAGS_TYPE_CONTEXT, 0)) { | |
71 | secp256k1_callback_call(&default_illegal_callback, | |
72 | "Invalid flags"); | |
73 | return 0; | |
74 | } | |
75 | ||
76 | if (flags & SECP256K1_FLAGS_BIT_CONTEXT_SIGN) { | |
77 | ret += SECP256K1_ECMULT_GEN_CONTEXT_PREALLOCATED_SIZE; | |
78 | } | |
79 | if (flags & SECP256K1_FLAGS_BIT_CONTEXT_VERIFY) { | |
80 | ret += SECP256K1_ECMULT_CONTEXT_PREALLOCATED_SIZE; | |
81 | } | |
82 | return ret; | |
83 | } | |
84 | ||
c4fd5dab TR |
85 | secp256k1_context* secp256k1_context_preallocated_create(void* prealloc, unsigned int flags) { |
86 | void* const base = prealloc; | |
87 | size_t prealloc_size = secp256k1_context_preallocated_size(flags); | |
88 | secp256k1_context* ret = (secp256k1_context*)manual_alloc(&prealloc, sizeof(secp256k1_context), base, prealloc_size); | |
89 | ||
995c5487 PW |
90 | ret->illegal_callback = default_illegal_callback; |
91 | ret->error_callback = default_error_callback; | |
a9b6595e | 92 | |
9234391e | 93 | if (EXPECT((flags & SECP256K1_FLAGS_TYPE_MASK) != SECP256K1_FLAGS_TYPE_CONTEXT, 0)) { |
1a368980 RR |
94 | secp256k1_callback_call(&ret->illegal_callback, |
95 | "Invalid flags"); | |
1a368980 RR |
96 | return NULL; |
97 | } | |
98 | ||
a9b6595e PW |
99 | secp256k1_ecmult_context_init(&ret->ecmult_ctx); |
100 | secp256k1_ecmult_gen_context_init(&ret->ecmult_gen_ctx); | |
101 | ||
9234391e | 102 | if (flags & SECP256K1_FLAGS_BIT_CONTEXT_SIGN) { |
c4fd5dab | 103 | secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx, &prealloc); |
04e34d18 | 104 | } |
9234391e | 105 | if (flags & SECP256K1_FLAGS_BIT_CONTEXT_VERIFY) { |
c4fd5dab | 106 | secp256k1_ecmult_context_build(&ret->ecmult_ctx, &prealloc); |
04e34d18 | 107 | } |
a9b6595e | 108 | |
c4fd5dab TR |
109 | return (secp256k1_context*) ret; |
110 | } | |
111 | ||
112 | secp256k1_context* secp256k1_context_create(unsigned int flags) { | |
113 | size_t const prealloc_size = secp256k1_context_preallocated_size(flags); | |
114 | secp256k1_context* ctx = (secp256k1_context*)checked_malloc(&default_error_callback, prealloc_size); | |
115 | if (EXPECT(secp256k1_context_preallocated_create(ctx, flags) == NULL, 0)) { | |
116 | free(ctx); | |
117 | return NULL; | |
118 | } | |
119 | ||
120 | return ctx; | |
254327e4 PW |
121 | } |
122 | ||
dd891e0e | 123 | secp256k1_context* secp256k1_context_clone(const secp256k1_context* ctx) { |
c4fd5dab TR |
124 | secp256k1_context* ret; |
125 | size_t prealloc_size = ROUND_TO_ALIGN(sizeof(secp256k1_context)); | |
126 | if (secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)) { | |
127 | prealloc_size += SECP256K1_ECMULT_GEN_CONTEXT_PREALLOCATED_SIZE; | |
128 | } | |
129 | if (secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)) { | |
130 | prealloc_size += SECP256K1_ECMULT_CONTEXT_PREALLOCATED_SIZE; | |
131 | } | |
132 | ret = checked_malloc(&ctx->error_callback, prealloc_size); | |
133 | memcpy(ret, ctx, prealloc_size); | |
134 | secp256k1_ecmult_gen_context_finalize_memcpy(&ret->ecmult_gen_ctx, &ctx->ecmult_gen_ctx); | |
135 | secp256k1_ecmult_context_finalize_memcpy(&ret->ecmult_ctx, &ctx->ecmult_ctx); | |
d899b5b6 AP |
136 | return ret; |
137 | } | |
138 | ||
c4fd5dab | 139 | void secp256k1_context_preallocated_destroy(secp256k1_context* ctx) { |
40fde611 | 140 | CHECK(ctx != secp256k1_context_no_precomp); |
2b199de8 | 141 | if (ctx != NULL) { |
912f203f GM |
142 | secp256k1_ecmult_context_clear(&ctx->ecmult_ctx); |
143 | secp256k1_ecmult_gen_context_clear(&ctx->ecmult_gen_ctx); | |
c4fd5dab TR |
144 | } |
145 | } | |
9aac0080 | 146 | |
c4fd5dab TR |
147 | void secp256k1_context_destroy(secp256k1_context* ctx) { |
148 | if (ctx != NULL) { | |
149 | secp256k1_context_preallocated_destroy(ctx); | |
912f203f GM |
150 | free(ctx); |
151 | } | |
254327e4 PW |
152 | } |
153 | ||
dd891e0e | 154 | void secp256k1_context_set_illegal_callback(secp256k1_context* ctx, void (*fun)(const char* message, void* data), const void* data) { |
40fde611 | 155 | CHECK(ctx != secp256k1_context_no_precomp); |
2b199de8 | 156 | if (fun == NULL) { |
c9d7c2a4 | 157 | fun = default_illegal_callback_fn; |
912f203f | 158 | } |
995c5487 PW |
159 | ctx->illegal_callback.fn = fun; |
160 | ctx->illegal_callback.data = data; | |
161 | } | |
162 | ||
dd891e0e | 163 | void secp256k1_context_set_error_callback(secp256k1_context* ctx, void (*fun)(const char* message, void* data), const void* data) { |
40fde611 | 164 | CHECK(ctx != secp256k1_context_no_precomp); |
2b199de8 | 165 | if (fun == NULL) { |
c9d7c2a4 | 166 | fun = default_error_callback_fn; |
912f203f | 167 | } |
995c5487 PW |
168 | ctx->error_callback.fn = fun; |
169 | ctx->error_callback.data = data; | |
170 | } | |
171 | ||
6fe50439 | 172 | secp256k1_scratch_space* secp256k1_scratch_space_create(const secp256k1_context* ctx, size_t max_size) { |
548de42e | 173 | VERIFY_CHECK(ctx != NULL); |
6fe50439 | 174 | return secp256k1_scratch_create(&ctx->error_callback, max_size); |
548de42e AP |
175 | } |
176 | ||
177 | void secp256k1_scratch_space_destroy(secp256k1_scratch_space* scratch) { | |
178 | secp256k1_scratch_destroy(scratch); | |
179 | } | |
180 | ||
dd891e0e PW |
181 | static int secp256k1_pubkey_load(const secp256k1_context* ctx, secp256k1_ge* ge, const secp256k1_pubkey* pubkey) { |
182 | if (sizeof(secp256k1_ge_storage) == 64) { | |
183 | /* When the secp256k1_ge_storage type is exactly 64 byte, use its | |
184 | * representation inside secp256k1_pubkey, as conversion is very fast. | |
23cfa914 | 185 | * Note that secp256k1_pubkey_save must use the same representation. */ |
dd891e0e | 186 | secp256k1_ge_storage s; |
c7680e57 | 187 | memcpy(&s, &pubkey->data[0], sizeof(s)); |
23cfa914 | 188 | secp256k1_ge_from_storage(ge, &s); |
23cfa914 PW |
189 | } else { |
190 | /* Otherwise, fall back to 32-byte big endian for X and Y. */ | |
dd891e0e | 191 | secp256k1_fe x, y; |
23cfa914 | 192 | secp256k1_fe_set_b32(&x, pubkey->data); |
23cfa914 PW |
193 | secp256k1_fe_set_b32(&y, pubkey->data + 32); |
194 | secp256k1_ge_set_xy(ge, &x, &y); | |
195 | } | |
995c5487 PW |
196 | ARG_CHECK(!secp256k1_fe_is_zero(&ge->x)); |
197 | return 1; | |
23cfa914 PW |
198 | } |
199 | ||
dd891e0e PW |
200 | static void secp256k1_pubkey_save(secp256k1_pubkey* pubkey, secp256k1_ge* ge) { |
201 | if (sizeof(secp256k1_ge_storage) == 64) { | |
202 | secp256k1_ge_storage s; | |
23cfa914 | 203 | secp256k1_ge_to_storage(&s, ge); |
c7680e57 | 204 | memcpy(&pubkey->data[0], &s, sizeof(s)); |
23cfa914 PW |
205 | } else { |
206 | VERIFY_CHECK(!secp256k1_ge_is_infinity(ge)); | |
207 | secp256k1_fe_normalize_var(&ge->x); | |
208 | secp256k1_fe_normalize_var(&ge->y); | |
209 | secp256k1_fe_get_b32(pubkey->data, &ge->x); | |
210 | secp256k1_fe_get_b32(pubkey->data + 32, &ge->y); | |
211 | } | |
212 | } | |
213 | ||
dd891e0e PW |
214 | int secp256k1_ec_pubkey_parse(const secp256k1_context* ctx, secp256k1_pubkey* pubkey, const unsigned char *input, size_t inputlen) { |
215 | secp256k1_ge Q; | |
23cfa914 | 216 | |
ee2cb400 GM |
217 | VERIFY_CHECK(ctx != NULL); |
218 | ARG_CHECK(pubkey != NULL); | |
219 | memset(pubkey, 0, sizeof(*pubkey)); | |
220 | ARG_CHECK(input != NULL); | |
23cfa914 | 221 | if (!secp256k1_eckey_pubkey_parse(&Q, input, inputlen)) { |
23cfa914 PW |
222 | return 0; |
223 | } | |
224 | secp256k1_pubkey_save(pubkey, &Q); | |
225 | secp256k1_ge_clear(&Q); | |
226 | return 1; | |
227 | } | |
228 | ||
dd891e0e PW |
229 | int secp256k1_ec_pubkey_serialize(const secp256k1_context* ctx, unsigned char *output, size_t *outputlen, const secp256k1_pubkey* pubkey, unsigned int flags) { |
230 | secp256k1_ge Q; | |
5b71a3f4 GM |
231 | size_t len; |
232 | int ret = 0; | |
23cfa914 | 233 | |
ee2cb400 | 234 | VERIFY_CHECK(ctx != NULL); |
ee2cb400 | 235 | ARG_CHECK(outputlen != NULL); |
06aeea55 | 236 | ARG_CHECK(*outputlen >= ((flags & SECP256K1_FLAGS_BIT_COMPRESSION) ? 33 : 65)); |
5b71a3f4 GM |
237 | len = *outputlen; |
238 | *outputlen = 0; | |
239 | ARG_CHECK(output != NULL); | |
240 | memset(output, 0, len); | |
ee2cb400 | 241 | ARG_CHECK(pubkey != NULL); |
9234391e | 242 | ARG_CHECK((flags & SECP256K1_FLAGS_TYPE_MASK) == SECP256K1_FLAGS_TYPE_COMPRESSION); |
5b71a3f4 GM |
243 | if (secp256k1_pubkey_load(ctx, &Q, pubkey)) { |
244 | ret = secp256k1_eckey_pubkey_serialize(&Q, output, &len, flags & SECP256K1_FLAGS_BIT_COMPRESSION); | |
245 | if (ret) { | |
246 | *outputlen = len; | |
247 | } | |
248 | } | |
249 | return ret; | |
23cfa914 PW |
250 | } |
251 | ||
dd891e0e | 252 | static void secp256k1_ecdsa_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_ecdsa_signature* sig) { |
439d34ad | 253 | (void)ctx; |
dd891e0e PW |
254 | if (sizeof(secp256k1_scalar) == 32) { |
255 | /* When the secp256k1_scalar type is exactly 32 byte, use its | |
256 | * representation inside secp256k1_ecdsa_signature, as conversion is very fast. | |
439d34ad PW |
257 | * Note that secp256k1_ecdsa_signature_save must use the same representation. */ |
258 | memcpy(r, &sig->data[0], 32); | |
259 | memcpy(s, &sig->data[32], 32); | |
260 | } else { | |
261 | secp256k1_scalar_set_b32(r, &sig->data[0], NULL); | |
262 | secp256k1_scalar_set_b32(s, &sig->data[32], NULL); | |
263 | } | |
264 | } | |
265 | ||
dd891e0e PW |
266 | static void secp256k1_ecdsa_signature_save(secp256k1_ecdsa_signature* sig, const secp256k1_scalar* r, const secp256k1_scalar* s) { |
267 | if (sizeof(secp256k1_scalar) == 32) { | |
439d34ad PW |
268 | memcpy(&sig->data[0], r, 32); |
269 | memcpy(&sig->data[32], s, 32); | |
270 | } else { | |
271 | secp256k1_scalar_get_b32(&sig->data[0], r); | |
272 | secp256k1_scalar_get_b32(&sig->data[32], s); | |
273 | } | |
274 | } | |
275 | ||
dd891e0e PW |
276 | int secp256k1_ecdsa_signature_parse_der(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) { |
277 | secp256k1_scalar r, s; | |
74a2acdb | 278 | |
bcc4881d | 279 | VERIFY_CHECK(ctx != NULL); |
995c5487 PW |
280 | ARG_CHECK(sig != NULL); |
281 | ARG_CHECK(input != NULL); | |
74a2acdb | 282 | |
18c329c5 | 283 | if (secp256k1_ecdsa_sig_parse(&r, &s, input, inputlen)) { |
439d34ad | 284 | secp256k1_ecdsa_signature_save(sig, &r, &s); |
74a2acdb PW |
285 | return 1; |
286 | } else { | |
287 | memset(sig, 0, sizeof(*sig)); | |
288 | return 0; | |
289 | } | |
290 | } | |
291 | ||
3bb9c447 PW |
292 | int secp256k1_ecdsa_signature_parse_compact(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input64) { |
293 | secp256k1_scalar r, s; | |
294 | int ret = 1; | |
295 | int overflow = 0; | |
296 | ||
bcc4881d | 297 | VERIFY_CHECK(ctx != NULL); |
3bb9c447 PW |
298 | ARG_CHECK(sig != NULL); |
299 | ARG_CHECK(input64 != NULL); | |
300 | ||
301 | secp256k1_scalar_set_b32(&r, &input64[0], &overflow); | |
302 | ret &= !overflow; | |
303 | secp256k1_scalar_set_b32(&s, &input64[32], &overflow); | |
304 | ret &= !overflow; | |
305 | if (ret) { | |
306 | secp256k1_ecdsa_signature_save(sig, &r, &s); | |
307 | } else { | |
308 | memset(sig, 0, sizeof(*sig)); | |
309 | } | |
310 | return ret; | |
311 | } | |
312 | ||
dd891e0e PW |
313 | int secp256k1_ecdsa_signature_serialize_der(const secp256k1_context* ctx, unsigned char *output, size_t *outputlen, const secp256k1_ecdsa_signature* sig) { |
314 | secp256k1_scalar r, s; | |
74a2acdb | 315 | |
bcc4881d | 316 | VERIFY_CHECK(ctx != NULL); |
995c5487 PW |
317 | ARG_CHECK(output != NULL); |
318 | ARG_CHECK(outputlen != NULL); | |
319 | ARG_CHECK(sig != NULL); | |
74a2acdb | 320 | |
439d34ad | 321 | secp256k1_ecdsa_signature_load(ctx, &r, &s, sig); |
18c329c5 | 322 | return secp256k1_ecdsa_sig_serialize(output, outputlen, &r, &s); |
74a2acdb PW |
323 | } |
324 | ||
3bb9c447 PW |
325 | int secp256k1_ecdsa_signature_serialize_compact(const secp256k1_context* ctx, unsigned char *output64, const secp256k1_ecdsa_signature* sig) { |
326 | secp256k1_scalar r, s; | |
327 | ||
bcc4881d | 328 | VERIFY_CHECK(ctx != NULL); |
3bb9c447 PW |
329 | ARG_CHECK(output64 != NULL); |
330 | ARG_CHECK(sig != NULL); | |
331 | ||
332 | secp256k1_ecdsa_signature_load(ctx, &r, &s, sig); | |
333 | secp256k1_scalar_get_b32(&output64[0], &r); | |
334 | secp256k1_scalar_get_b32(&output64[32], &s); | |
335 | return 1; | |
336 | } | |
337 | ||
0c6ab2ff PW |
338 | int secp256k1_ecdsa_signature_normalize(const secp256k1_context* ctx, secp256k1_ecdsa_signature *sigout, const secp256k1_ecdsa_signature *sigin) { |
339 | secp256k1_scalar r, s; | |
340 | int ret = 0; | |
341 | ||
342 | VERIFY_CHECK(ctx != NULL); | |
343 | ARG_CHECK(sigin != NULL); | |
344 | ||
345 | secp256k1_ecdsa_signature_load(ctx, &r, &s, sigin); | |
346 | ret = secp256k1_scalar_is_high(&s); | |
347 | if (sigout != NULL) { | |
348 | if (ret) { | |
349 | secp256k1_scalar_negate(&s, &s); | |
350 | } | |
351 | secp256k1_ecdsa_signature_save(sigout, &r, &s); | |
352 | } | |
353 | ||
354 | return ret; | |
355 | } | |
356 | ||
dd891e0e PW |
357 | int secp256k1_ecdsa_verify(const secp256k1_context* ctx, const secp256k1_ecdsa_signature *sig, const unsigned char *msg32, const secp256k1_pubkey *pubkey) { |
358 | secp256k1_ge q; | |
359 | secp256k1_scalar r, s; | |
360 | secp256k1_scalar m; | |
b183b411 | 361 | VERIFY_CHECK(ctx != NULL); |
995c5487 PW |
362 | ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); |
363 | ARG_CHECK(msg32 != NULL); | |
364 | ARG_CHECK(sig != NULL); | |
365 | ARG_CHECK(pubkey != NULL); | |
1c7fa133 | 366 | |
f24041d6 | 367 | secp256k1_scalar_set_b32(&m, msg32, NULL); |
439d34ad | 368 | secp256k1_ecdsa_signature_load(ctx, &r, &s, sig); |
0c6ab2ff PW |
369 | return (!secp256k1_scalar_is_high(&s) && |
370 | secp256k1_pubkey_load(ctx, &q, pubkey) && | |
995c5487 | 371 | secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &r, &s, &q, &m)); |
607884fc PW |
372 | } |
373 | ||
c7680e57 TS |
374 | static SECP256K1_INLINE void buffer_append(unsigned char *buf, unsigned int *offset, const void *data, unsigned int len) { |
375 | memcpy(buf + *offset, data, len); | |
376 | *offset += len; | |
377 | } | |
378 | ||
05732c5a | 379 | static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { |
a5a66c70 | 380 | unsigned char keydata[112]; |
c7680e57 | 381 | unsigned int offset = 0; |
d1dc9dfc | 382 | secp256k1_rfc6979_hmac_sha256 rng; |
f735446c | 383 | unsigned int i; |
3e6f1e20 PW |
384 | /* We feed a byte array to the PRNG as input, consisting of: |
385 | * - the private key (32 bytes) and message (32 bytes), see RFC 6979 3.2d. | |
386 | * - optionally 32 extra bytes of data, see RFC 6979 3.6 Additional Data. | |
b30fc85c GM |
387 | * - optionally 16 extra bytes with the algorithm name. |
388 | * Because the arguments have distinct fixed lengths it is not possible for | |
389 | * different argument mixtures to emulate each other and result in the same | |
390 | * nonces. | |
3e6f1e20 | 391 | */ |
c7680e57 TS |
392 | buffer_append(keydata, &offset, key32, 32); |
393 | buffer_append(keydata, &offset, msg32, 32); | |
3e6f1e20 | 394 | if (data != NULL) { |
c7680e57 | 395 | buffer_append(keydata, &offset, data, 32); |
3e6f1e20 | 396 | } |
a5a66c70 | 397 | if (algo16 != NULL) { |
c7680e57 | 398 | buffer_append(keydata, &offset, algo16, 16); |
a5a66c70 | 399 | } |
c7680e57 | 400 | secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, offset); |
3e6f1e20 | 401 | memset(keydata, 0, sizeof(keydata)); |
f735446c | 402 | for (i = 0; i <= counter; i++) { |
bbd5ba7c PW |
403 | secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); |
404 | } | |
405 | secp256k1_rfc6979_hmac_sha256_finalize(&rng); | |
406 | return 1; | |
407 | } | |
408 | ||
dd891e0e PW |
409 | const secp256k1_nonce_function secp256k1_nonce_function_rfc6979 = nonce_function_rfc6979; |
410 | const secp256k1_nonce_function secp256k1_nonce_function_default = nonce_function_rfc6979; | |
bbd5ba7c | 411 | |
dd891e0e PW |
412 | int secp256k1_ecdsa_sign(const secp256k1_context* ctx, secp256k1_ecdsa_signature *signature, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { |
413 | secp256k1_scalar r, s; | |
414 | secp256k1_scalar sec, non, msg; | |
439d34ad PW |
415 | int ret = 0; |
416 | int overflow = 0; | |
b183b411 | 417 | VERIFY_CHECK(ctx != NULL); |
439d34ad PW |
418 | ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); |
419 | ARG_CHECK(msg32 != NULL); | |
420 | ARG_CHECK(signature != NULL); | |
421 | ARG_CHECK(seckey != NULL); | |
422 | if (noncefp == NULL) { | |
423 | noncefp = secp256k1_nonce_function_default; | |
424 | } | |
425 | ||
426 | secp256k1_scalar_set_b32(&sec, seckey, &overflow); | |
427 | /* Fail if the secret key is invalid. */ | |
428 | if (!overflow && !secp256k1_scalar_is_zero(&sec)) { | |
0f9e69db | 429 | unsigned char nonce32[32]; |
cfe0ed91 | 430 | unsigned int count = 0; |
439d34ad PW |
431 | secp256k1_scalar_set_b32(&msg, msg32, NULL); |
432 | while (1) { | |
05732c5a | 433 | ret = noncefp(nonce32, msg32, seckey, NULL, (void*)noncedata, count); |
439d34ad PW |
434 | if (!ret) { |
435 | break; | |
436 | } | |
437 | secp256k1_scalar_set_b32(&non, nonce32, &overflow); | |
cfe0ed91 | 438 | if (!overflow && !secp256k1_scalar_is_zero(&non)) { |
439d34ad PW |
439 | if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &r, &s, &sec, &msg, &non, NULL)) { |
440 | break; | |
441 | } | |
442 | } | |
443 | count++; | |
444 | } | |
0f9e69db | 445 | memset(nonce32, 0, 32); |
439d34ad PW |
446 | secp256k1_scalar_clear(&msg); |
447 | secp256k1_scalar_clear(&non); | |
448 | secp256k1_scalar_clear(&sec); | |
449 | } | |
450 | if (ret) { | |
451 | secp256k1_ecdsa_signature_save(signature, &r, &s); | |
452 | } else { | |
453 | memset(signature, 0, sizeof(*signature)); | |
454 | } | |
455 | return ret; | |
456 | } | |
457 | ||
dd891e0e PW |
458 | int secp256k1_ec_seckey_verify(const secp256k1_context* ctx, const unsigned char *seckey) { |
459 | secp256k1_scalar sec; | |
f735446c | 460 | int ret; |
a9f5c8b8 | 461 | int overflow; |
b183b411 | 462 | VERIFY_CHECK(ctx != NULL); |
995c5487 | 463 | ARG_CHECK(seckey != NULL); |
f735446c | 464 | |
eca6cdb1 | 465 | secp256k1_scalar_set_b32(&sec, seckey, &overflow); |
cfe0ed91 | 466 | ret = !overflow && !secp256k1_scalar_is_zero(&sec); |
a9f5c8b8 | 467 | secp256k1_scalar_clear(&sec); |
42cccdaf PW |
468 | return ret; |
469 | } | |
470 | ||
dd891e0e PW |
471 | int secp256k1_ec_pubkey_create(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *seckey) { |
472 | secp256k1_gej pj; | |
473 | secp256k1_ge p; | |
474 | secp256k1_scalar sec; | |
354ffa33 | 475 | int overflow; |
0065a8fb | 476 | int ret = 0; |
b183b411 | 477 | VERIFY_CHECK(ctx != NULL); |
995c5487 | 478 | ARG_CHECK(pubkey != NULL); |
5b71a3f4 GM |
479 | memset(pubkey, 0, sizeof(*pubkey)); |
480 | ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); | |
995c5487 | 481 | ARG_CHECK(seckey != NULL); |
1c7fa133 | 482 | |
354ffa33 | 483 | secp256k1_scalar_set_b32(&sec, seckey, &overflow); |
cfe0ed91 | 484 | ret = (!overflow) & (!secp256k1_scalar_is_zero(&sec)); |
70d46401 GM |
485 | if (ret) { |
486 | secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pj, &sec); | |
487 | secp256k1_ge_set_gej(&p, &pj); | |
488 | secp256k1_pubkey_save(pubkey, &p); | |
99fd963b | 489 | } |
70d46401 | 490 | secp256k1_scalar_clear(&sec); |
99fd963b TK |
491 | return ret; |
492 | } | |
493 | ||
8e48aa60 AP |
494 | int secp256k1_ec_privkey_negate(const secp256k1_context* ctx, unsigned char *seckey) { |
495 | secp256k1_scalar sec; | |
496 | VERIFY_CHECK(ctx != NULL); | |
497 | ARG_CHECK(seckey != NULL); | |
498 | ||
499 | secp256k1_scalar_set_b32(&sec, seckey, NULL); | |
500 | secp256k1_scalar_negate(&sec, &sec); | |
501 | secp256k1_scalar_get_b32(seckey, &sec); | |
502 | ||
069870d9 | 503 | secp256k1_scalar_clear(&sec); |
8e48aa60 AP |
504 | return 1; |
505 | } | |
506 | ||
507 | int secp256k1_ec_pubkey_negate(const secp256k1_context* ctx, secp256k1_pubkey *pubkey) { | |
508 | int ret = 0; | |
509 | secp256k1_ge p; | |
510 | VERIFY_CHECK(ctx != NULL); | |
511 | ARG_CHECK(pubkey != NULL); | |
512 | ||
513 | ret = secp256k1_pubkey_load(ctx, &p, pubkey); | |
514 | memset(pubkey, 0, sizeof(*pubkey)); | |
515 | if (ret) { | |
516 | secp256k1_ge_neg(&p, &p); | |
517 | secp256k1_pubkey_save(pubkey, &p); | |
518 | } | |
519 | return ret; | |
520 | } | |
521 | ||
dd891e0e PW |
522 | int secp256k1_ec_privkey_tweak_add(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak) { |
523 | secp256k1_scalar term; | |
524 | secp256k1_scalar sec; | |
0065a8fb | 525 | int ret = 0; |
f735446c | 526 | int overflow = 0; |
b183b411 | 527 | VERIFY_CHECK(ctx != NULL); |
995c5487 PW |
528 | ARG_CHECK(seckey != NULL); |
529 | ARG_CHECK(tweak != NULL); | |
1c7fa133 | 530 | |
eca6cdb1 | 531 | secp256k1_scalar_set_b32(&term, tweak, &overflow); |
eca6cdb1 | 532 | secp256k1_scalar_set_b32(&sec, seckey, NULL); |
eb74c36b | 533 | |
cfe0ed91 | 534 | ret = !overflow && secp256k1_eckey_privkey_tweak_add(&sec, &term); |
bb5aa4df | 535 | memset(seckey, 0, 32); |
561b0e10 | 536 | if (ret) { |
eca6cdb1 | 537 | secp256k1_scalar_get_b32(seckey, &sec); |
eb74c36b PW |
538 | } |
539 | ||
a9f5c8b8 PW |
540 | secp256k1_scalar_clear(&sec); |
541 | secp256k1_scalar_clear(&term); | |
561b0e10 PW |
542 | return ret; |
543 | } | |
544 | ||
dd891e0e PW |
545 | int secp256k1_ec_pubkey_tweak_add(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *tweak) { |
546 | secp256k1_ge p; | |
547 | secp256k1_scalar term; | |
0065a8fb | 548 | int ret = 0; |
f735446c | 549 | int overflow = 0; |
b183b411 | 550 | VERIFY_CHECK(ctx != NULL); |
995c5487 PW |
551 | ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); |
552 | ARG_CHECK(pubkey != NULL); | |
553 | ARG_CHECK(tweak != NULL); | |
1c7fa133 | 554 | |
f24041d6 | 555 | secp256k1_scalar_set_b32(&term, tweak, &overflow); |
bb5aa4df GM |
556 | ret = !overflow && secp256k1_pubkey_load(ctx, &p, pubkey); |
557 | memset(pubkey, 0, sizeof(*pubkey)); | |
558 | if (ret) { | |
559 | if (secp256k1_eckey_pubkey_tweak_add(&ctx->ecmult_ctx, &p, &term)) { | |
23cfa914 PW |
560 | secp256k1_pubkey_save(pubkey, &p); |
561 | } else { | |
bb5aa4df | 562 | ret = 0; |
0065a8fb | 563 | } |
86d3cce2 | 564 | } |
eb74c36b | 565 | |
86d3cce2 PW |
566 | return ret; |
567 | } | |
568 | ||
dd891e0e PW |
569 | int secp256k1_ec_privkey_tweak_mul(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak) { |
570 | secp256k1_scalar factor; | |
571 | secp256k1_scalar sec; | |
0065a8fb | 572 | int ret = 0; |
f735446c | 573 | int overflow = 0; |
b183b411 | 574 | VERIFY_CHECK(ctx != NULL); |
995c5487 PW |
575 | ARG_CHECK(seckey != NULL); |
576 | ARG_CHECK(tweak != NULL); | |
1c7fa133 | 577 | |
eca6cdb1 | 578 | secp256k1_scalar_set_b32(&factor, tweak, &overflow); |
eca6cdb1 | 579 | secp256k1_scalar_set_b32(&sec, seckey, NULL); |
cfe0ed91 | 580 | ret = !overflow && secp256k1_eckey_privkey_tweak_mul(&sec, &factor); |
bb5aa4df | 581 | memset(seckey, 0, 32); |
86d3cce2 | 582 | if (ret) { |
eca6cdb1 | 583 | secp256k1_scalar_get_b32(seckey, &sec); |
eb74c36b PW |
584 | } |
585 | ||
a9f5c8b8 PW |
586 | secp256k1_scalar_clear(&sec); |
587 | secp256k1_scalar_clear(&factor); | |
86d3cce2 PW |
588 | return ret; |
589 | } | |
590 | ||
dd891e0e PW |
591 | int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *tweak) { |
592 | secp256k1_ge p; | |
593 | secp256k1_scalar factor; | |
0065a8fb | 594 | int ret = 0; |
f735446c | 595 | int overflow = 0; |
b183b411 | 596 | VERIFY_CHECK(ctx != NULL); |
995c5487 PW |
597 | ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); |
598 | ARG_CHECK(pubkey != NULL); | |
599 | ARG_CHECK(tweak != NULL); | |
1c7fa133 | 600 | |
f24041d6 | 601 | secp256k1_scalar_set_b32(&factor, tweak, &overflow); |
bb5aa4df GM |
602 | ret = !overflow && secp256k1_pubkey_load(ctx, &p, pubkey); |
603 | memset(pubkey, 0, sizeof(*pubkey)); | |
604 | if (ret) { | |
605 | if (secp256k1_eckey_pubkey_tweak_mul(&ctx->ecmult_ctx, &p, &factor)) { | |
23cfa914 PW |
606 | secp256k1_pubkey_save(pubkey, &p); |
607 | } else { | |
bb5aa4df | 608 | ret = 0; |
0065a8fb | 609 | } |
561b0e10 | 610 | } |
eb74c36b | 611 | |
561b0e10 PW |
612 | return ret; |
613 | } | |
614 | ||
dd891e0e | 615 | int secp256k1_context_randomize(secp256k1_context* ctx, const unsigned char *seed32) { |
b183b411 | 616 | VERIFY_CHECK(ctx != NULL); |
61983752 TR |
617 | if (secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)) { |
618 | secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, seed32); | |
619 | } | |
d2275795 GM |
620 | return 1; |
621 | } | |
0739bbb6 | 622 | |
8e48787d GM |
623 | int secp256k1_ec_pubkey_combine(const secp256k1_context* ctx, secp256k1_pubkey *pubnonce, const secp256k1_pubkey * const *pubnonces, size_t n) { |
624 | size_t i; | |
dd891e0e PW |
625 | secp256k1_gej Qj; |
626 | secp256k1_ge Q; | |
a5a66c70 PW |
627 | |
628 | ARG_CHECK(pubnonce != NULL); | |
c69dea02 | 629 | memset(pubnonce, 0, sizeof(*pubnonce)); |
a5a66c70 PW |
630 | ARG_CHECK(n >= 1); |
631 | ARG_CHECK(pubnonces != NULL); | |
632 | ||
633 | secp256k1_gej_set_infinity(&Qj); | |
634 | ||
635 | for (i = 0; i < n; i++) { | |
636 | secp256k1_pubkey_load(ctx, &Q, pubnonces[i]); | |
637 | secp256k1_gej_add_ge(&Qj, &Qj, &Q); | |
638 | } | |
639 | if (secp256k1_gej_is_infinity(&Qj)) { | |
a5a66c70 PW |
640 | return 0; |
641 | } | |
642 | secp256k1_ge_set_gej(&Q, &Qj); | |
643 | secp256k1_pubkey_save(pubnonce, &Q); | |
644 | return 1; | |
645 | } | |
646 | ||
0739bbb6 AP |
647 | #ifdef ENABLE_MODULE_ECDH |
648 | # include "modules/ecdh/main_impl.h" | |
649 | #endif | |
a5a66c70 | 650 | |
9f443be0 PW |
651 | #ifdef ENABLE_MODULE_RECOVERY |
652 | # include "modules/recovery/main_impl.h" | |
653 | #endif |