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