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