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