]> Git Repo - secp256k1.git/blame - src/tests.c
Add scalar splitting functions
[secp256k1.git] / src / tests.c
CommitLineData
71712b27
GM
1/**********************************************************************
2 * Copyright (c) 2013, 2014 Pieter Wuille *
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
78cd96b1
CF
7#if defined HAVE_CONFIG_H
8#include "libsecp256k1-config.h"
9#endif
10
5a9989c5 11#include <stdio.h>
0592d117 12#include <stdlib.h>
a41f32e6 13
25f4aec0 14#include "secp256k1.c"
f0709ac5 15#include "testrand_impl.h"
a41f32e6 16
dd08f037
PW
17#ifdef ENABLE_OPENSSL_TESTS
18#include "openssl/bn.h"
19#include "openssl/ec.h"
20#include "openssl/ecdsa.h"
21#include "openssl/obj_mac.h"
22#endif
23
79f599d3 24static int count = 64;
4adf6b2a 25
404c30a8
PW
26/***** NUM TESTS *****/
27
3f44e1ad
PW
28void random_num_negate(secp256k1_num_t *num) {
29 if (secp256k1_rand32() & 1)
30 secp256k1_num_negate(num);
31}
32
9338dbf7
PW
33void random_field_element_test(secp256k1_fe_t *fe) {
34 do {
35 unsigned char b32[32];
36 secp256k1_rand256_test(b32);
37 secp256k1_num_t num;
38 secp256k1_num_set_bin(&num, b32, 32);
39 if (secp256k1_num_cmp(&num, &secp256k1_fe_consts->p) >= 0)
40 continue;
d907ebc0 41 VERIFY_CHECK(secp256k1_fe_set_b32(fe, b32));
9338dbf7
PW
42 break;
43 } while(1);
44}
45
46void random_field_element_magnitude(secp256k1_fe_t *fe) {
47 secp256k1_fe_normalize(fe);
48 int n = secp256k1_rand32() % 4;
49 for (int i = 0; i < n; i++) {
50 secp256k1_fe_negate(fe, fe, 1 + 2*i);
51 secp256k1_fe_negate(fe, fe, 2 + 2*i);
52 }
53}
54
55void random_group_element_test(secp256k1_ge_t *ge) {
56 secp256k1_fe_t fe;
57 do {
58 random_field_element_test(&fe);
59 if (secp256k1_ge_set_xo(ge, &fe, secp256k1_rand32() & 1))
60 break;
61 } while(1);
62}
63
64void random_group_element_jacobian_test(secp256k1_gej_t *gej, const secp256k1_ge_t *ge) {
65 do {
66 random_field_element_test(&gej->z);
67 if (!secp256k1_fe_is_zero(&gej->z)) {
68 break;
69 }
70 } while(1);
71 secp256k1_fe_t z2; secp256k1_fe_sqr(&z2, &gej->z);
72 secp256k1_fe_t z3; secp256k1_fe_mul(&z3, &z2, &gej->z);
73 secp256k1_fe_mul(&gej->x, &ge->x, &z2);
74 secp256k1_fe_mul(&gej->y, &ge->y, &z3);
75 gej->infinity = ge->infinity;
76}
77
404c30a8 78void random_num_order_test(secp256k1_num_t *num) {
d06e61cb
PW
79 do {
80 unsigned char b32[32];
81 secp256k1_rand256_test(b32);
82 secp256k1_num_set_bin(num, b32, 32);
83 if (secp256k1_num_is_zero(num))
84 continue;
85 if (secp256k1_num_cmp(num, &secp256k1_ge_consts->order) >= 0)
86 continue;
87 break;
88 } while(1);
89}
90
a9f5c8b8
PW
91void random_scalar_order_test(secp256k1_scalar_t *num) {
92 do {
93 unsigned char b32[32];
94 secp256k1_rand256_test(b32);
95 int overflow = 0;
eca6cdb1 96 secp256k1_scalar_set_b32(num, b32, &overflow);
a9f5c8b8
PW
97 if (overflow || secp256k1_scalar_is_zero(num))
98 continue;
99 break;
100 } while(1);
101}
102
404c30a8
PW
103void random_num_order(secp256k1_num_t *num) {
104 do {
105 unsigned char b32[32];
106 secp256k1_rand256(b32);
107 secp256k1_num_set_bin(num, b32, 32);
108 if (secp256k1_num_is_zero(num))
109 continue;
110 if (secp256k1_num_cmp(num, &secp256k1_ge_consts->order) >= 0)
111 continue;
112 break;
113 } while(1);
114}
115
2cad067a 116void test_num_copy_inc_cmp(void) {
404c30a8 117 secp256k1_num_t n1,n2;
404c30a8
PW
118 random_num_order(&n1);
119 secp256k1_num_copy(&n2, &n1);
1a749b4a
PW
120 CHECK(secp256k1_num_eq(&n1, &n2));
121 CHECK(secp256k1_num_eq(&n2, &n1));
404c30a8 122 secp256k1_num_inc(&n2);
1a749b4a
PW
123 CHECK(!secp256k1_num_eq(&n1, &n2));
124 CHECK(!secp256k1_num_eq(&n2, &n1));
404c30a8
PW
125}
126
404c30a8 127
2cad067a 128void test_num_get_set_hex(void) {
404c30a8 129 secp256k1_num_t n1,n2;
404c30a8
PW
130 random_num_order_test(&n1);
131 char c[64];
132 secp256k1_num_get_hex(c, 64, &n1);
133 secp256k1_num_set_hex(&n2, c, 64);
1a749b4a 134 CHECK(secp256k1_num_eq(&n1, &n2));
404c30a8 135 for (int i=0; i<64; i++) {
71712b27 136 /* check whether the lower 4 bits correspond to the last hex character */
404c30a8
PW
137 int low1 = secp256k1_num_shift(&n1, 4);
138 int lowh = c[63];
f0709ac5 139 int low2 = ((lowh>>6)*9+(lowh-'0'))&15;
0592d117 140 CHECK(low1 == low2);
71712b27 141 /* shift bits off the hex representation, and compare */
404c30a8
PW
142 memmove(c+1, c, 63);
143 c[0] = '0';
144 secp256k1_num_set_hex(&n2, c, 64);
1a749b4a 145 CHECK(secp256k1_num_eq(&n1, &n2));
404c30a8 146 }
404c30a8
PW
147}
148
2cad067a 149void test_num_get_set_bin(void) {
404c30a8 150 secp256k1_num_t n1,n2;
404c30a8
PW
151 random_num_order_test(&n1);
152 unsigned char c[32];
153 secp256k1_num_get_bin(c, 32, &n1);
154 secp256k1_num_set_bin(&n2, c, 32);
1a749b4a 155 CHECK(secp256k1_num_eq(&n1, &n2));
404c30a8 156 for (int i=0; i<32; i++) {
71712b27 157 /* check whether the lower 8 bits correspond to the last byte */
404c30a8
PW
158 int low1 = secp256k1_num_shift(&n1, 8);
159 int low2 = c[31];
0592d117 160 CHECK(low1 == low2);
71712b27 161 /* shift bits off the byte representation, and compare */
404c30a8
PW
162 memmove(c+1, c, 31);
163 c[0] = 0;
164 secp256k1_num_set_bin(&n2, c, 32);
1a749b4a 165 CHECK(secp256k1_num_eq(&n1, &n2));
404c30a8 166 }
404c30a8
PW
167}
168
2cad067a 169void run_num_int(void) {
404c30a8 170 secp256k1_num_t n1;
404c30a8
PW
171 for (int i=-255; i<256; i++) {
172 unsigned char c1[3] = {};
173 c1[2] = abs(i);
174 unsigned char c2[3] = {0x11,0x22,0x33};
175 secp256k1_num_set_int(&n1, i);
176 secp256k1_num_get_bin(c2, 3, &n1);
0592d117 177 CHECK(memcmp(c1, c2, 3) == 0);
404c30a8 178 }
404c30a8
PW
179}
180
2cad067a 181void test_num_negate(void) {
3f44e1ad
PW
182 secp256k1_num_t n1;
183 secp256k1_num_t n2;
71712b27 184 random_num_order_test(&n1); /* n1 = R */
3f44e1ad 185 random_num_negate(&n1);
71712b27
GM
186 secp256k1_num_copy(&n2, &n1); /* n2 = R */
187 secp256k1_num_sub(&n1, &n2, &n1); /* n1 = n2-n1 = 0 */
0592d117 188 CHECK(secp256k1_num_is_zero(&n1));
71712b27
GM
189 secp256k1_num_copy(&n1, &n2); /* n1 = R */
190 secp256k1_num_negate(&n1); /* n1 = -R */
0592d117 191 CHECK(!secp256k1_num_is_zero(&n1));
71712b27 192 secp256k1_num_add(&n1, &n2, &n1); /* n1 = n2+n1 = 0 */
0592d117 193 CHECK(secp256k1_num_is_zero(&n1));
71712b27
GM
194 secp256k1_num_copy(&n1, &n2); /* n1 = R */
195 secp256k1_num_negate(&n1); /* n1 = -R */
0592d117 196 CHECK(secp256k1_num_is_neg(&n1) != secp256k1_num_is_neg(&n2));
71712b27 197 secp256k1_num_negate(&n1); /* n1 = R */
1a749b4a 198 CHECK(secp256k1_num_eq(&n1, &n2));
3f44e1ad
PW
199}
200
2cad067a 201void test_num_add_sub(void) {
1a749b4a 202 int r = secp256k1_rand32();
3f44e1ad
PW
203 secp256k1_num_t n1;
204 secp256k1_num_t n2;
71712b27 205 random_num_order_test(&n1); /* n1 = R1 */
1a749b4a
PW
206 if (r & 1) {
207 random_num_negate(&n1);
208 }
71712b27 209 random_num_order_test(&n2); /* n2 = R2 */
1a749b4a
PW
210 if (r & 2) {
211 random_num_negate(&n2);
212 }
3f44e1ad 213 secp256k1_num_t n1p2, n2p1, n1m2, n2m1;
71712b27
GM
214 secp256k1_num_add(&n1p2, &n1, &n2); /* n1p2 = R1 + R2 */
215 secp256k1_num_add(&n2p1, &n2, &n1); /* n2p1 = R2 + R1 */
216 secp256k1_num_sub(&n1m2, &n1, &n2); /* n1m2 = R1 - R2 */
217 secp256k1_num_sub(&n2m1, &n2, &n1); /* n2m1 = R2 - R1 */
1a749b4a
PW
218 CHECK(secp256k1_num_eq(&n1p2, &n2p1));
219 CHECK(!secp256k1_num_eq(&n1p2, &n1m2));
71712b27 220 secp256k1_num_negate(&n2m1); /* n2m1 = -R2 + R1 */
1a749b4a
PW
221 CHECK(secp256k1_num_eq(&n2m1, &n1m2));
222 CHECK(!secp256k1_num_eq(&n2m1, &n1));
71712b27 223 secp256k1_num_add(&n2m1, &n2m1, &n2); /* n2m1 = -R2 + R1 + R2 = R1 */
1a749b4a
PW
224 CHECK(secp256k1_num_eq(&n2m1, &n1));
225 CHECK(!secp256k1_num_eq(&n2p1, &n1));
71712b27 226 secp256k1_num_sub(&n2p1, &n2p1, &n2); /* n2p1 = R2 + R1 - R2 = R1 */
1a749b4a 227 CHECK(secp256k1_num_eq(&n2p1, &n1));
3f44e1ad
PW
228}
229
2cad067a 230void run_num_smalltests(void) {
3f44e1ad
PW
231 for (int i=0; i<100*count; i++) {
232 test_num_copy_inc_cmp();
233 test_num_get_set_hex();
234 test_num_get_set_bin();
235 test_num_negate();
236 test_num_add_sub();
237 }
238 run_num_int();
239}
240
79359302
PW
241/***** SCALAR TESTS *****/
242
243int secp256k1_scalar_eq(const secp256k1_scalar_t *s1, const secp256k1_scalar_t *s2) {
244 secp256k1_scalar_t t;
79359302
PW
245 secp256k1_scalar_negate(&t, s2);
246 secp256k1_scalar_add(&t, &t, s1);
247 int ret = secp256k1_scalar_is_zero(&t);
79359302
PW
248 return ret;
249}
250
251void scalar_test(void) {
252 unsigned char c[32];
253
71712b27 254 /* Set 's' to a random scalar, with value 'snum'. */
79359302
PW
255 secp256k1_rand256_test(c);
256 secp256k1_scalar_t s;
79359302
PW
257 secp256k1_scalar_set_b32(&s, c, NULL);
258 secp256k1_num_t snum;
79359302
PW
259 secp256k1_num_set_bin(&snum, c, 32);
260 secp256k1_num_mod(&snum, &secp256k1_ge_consts->order);
261
71712b27 262 /* Set 's1' to a random scalar, with value 's1num'. */
79359302
PW
263 secp256k1_rand256_test(c);
264 secp256k1_scalar_t s1;
79359302
PW
265 secp256k1_scalar_set_b32(&s1, c, NULL);
266 secp256k1_num_t s1num;
79359302
PW
267 secp256k1_num_set_bin(&s1num, c, 32);
268 secp256k1_num_mod(&s1num, &secp256k1_ge_consts->order);
269
71712b27 270 /* Set 's2' to a random scalar, with value 'snum2', and byte array representation 'c'. */
79359302
PW
271 secp256k1_rand256_test(c);
272 secp256k1_scalar_t s2;
79359302
PW
273 int overflow = 0;
274 secp256k1_scalar_set_b32(&s2, c, &overflow);
275 secp256k1_num_t s2num;
79359302
PW
276 secp256k1_num_set_bin(&s2num, c, 32);
277 secp256k1_num_mod(&s2num, &secp256k1_ge_consts->order);
278
279 {
71712b27 280 /* Test that fetching groups of 4 bits from a scalar and recursing n(i)=16*n(i-1)+p(i) reconstructs it. */
1e6c77c3
PW
281 secp256k1_scalar_t n;
282 secp256k1_scalar_set_int(&n, 0);
79359302 283 for (int i = 0; i < 256; i += 4) {
1e6c77c3
PW
284 secp256k1_scalar_t t;
285 secp256k1_scalar_set_int(&t, secp256k1_scalar_get_bits(&s, 256 - 4 - i, 4));
286 for (int j = 0; j < 4; j++) {
287 secp256k1_scalar_add(&n, &n, &n);
288 }
289 secp256k1_scalar_add(&n, &n, &t);
79359302 290 }
1e6c77c3
PW
291 CHECK(secp256k1_scalar_eq(&n, &s));
292 }
293
294 {
295 /* Test that fetching groups of randomly-sized bits from a scalar and recursing n(i)=b*n(i-1)+p(i) reconstructs it. */
296 secp256k1_scalar_t n;
297 secp256k1_scalar_set_int(&n, 0);
298 int i = 0;
299 while (i < 256) {
300 int now = (secp256k1_rand32() % 15) + 1;
301 if (now + i > 256) {
302 now = 256 - i;
303 }
304 secp256k1_scalar_t t;
305 secp256k1_scalar_set_int(&t, secp256k1_scalar_get_bits_var(&s, 256 - now - i, now));
306 for (int j = 0; j < now; j++) {
307 secp256k1_scalar_add(&n, &n, &n);
308 }
309 secp256k1_scalar_add(&n, &n, &t);
310 i += now;
311 }
312 CHECK(secp256k1_scalar_eq(&n, &s));
79359302
PW
313 }
314
315 {
71712b27 316 /* Test that get_b32 returns the same as get_bin on the number. */
79359302
PW
317 unsigned char r1[32];
318 secp256k1_scalar_get_b32(r1, &s2);
319 unsigned char r2[32];
320 secp256k1_num_get_bin(r2, 32, &s2num);
321 CHECK(memcmp(r1, r2, 32) == 0);
71712b27 322 /* If no overflow occurred when assigning, it should also be equal to the original byte array. */
79359302
PW
323 CHECK((memcmp(r1, c, 32) == 0) == (overflow == 0));
324 }
325
326 {
71712b27 327 /* Test that adding the scalars together is equal to adding their numbers together modulo the order. */
79359302 328 secp256k1_num_t rnum;
79359302
PW
329 secp256k1_num_add(&rnum, &snum, &s2num);
330 secp256k1_num_mod(&rnum, &secp256k1_ge_consts->order);
331 secp256k1_scalar_t r;
79359302
PW
332 secp256k1_scalar_add(&r, &s, &s2);
333 secp256k1_num_t r2num;
79359302
PW
334 secp256k1_scalar_get_num(&r2num, &r);
335 CHECK(secp256k1_num_eq(&rnum, &r2num));
79359302
PW
336 }
337
338 {
71712b27 339 /* Test that multipying the scalars is equal to multiplying their numbers modulo the order. */
79359302 340 secp256k1_num_t rnum;
79359302
PW
341 secp256k1_num_mul(&rnum, &snum, &s2num);
342 secp256k1_num_mod(&rnum, &secp256k1_ge_consts->order);
343 secp256k1_scalar_t r;
79359302
PW
344 secp256k1_scalar_mul(&r, &s, &s2);
345 secp256k1_num_t r2num;
79359302
PW
346 secp256k1_scalar_get_num(&r2num, &r);
347 CHECK(secp256k1_num_eq(&rnum, &r2num));
71712b27 348 /* The result can only be zero if at least one of the factors was zero. */
79359302 349 CHECK(secp256k1_scalar_is_zero(&r) == (secp256k1_scalar_is_zero(&s) || secp256k1_scalar_is_zero(&s2)));
71712b27 350 /* The results can only be equal to one of the factors if that factor was zero, or the other factor was one. */
79359302
PW
351 CHECK(secp256k1_num_eq(&rnum, &snum) == (secp256k1_scalar_is_zero(&s) || secp256k1_scalar_is_one(&s2)));
352 CHECK(secp256k1_num_eq(&rnum, &s2num) == (secp256k1_scalar_is_zero(&s2) || secp256k1_scalar_is_one(&s)));
79359302
PW
353 }
354
355 {
71712b27 356 /* Check that comparison with zero matches comparison with zero on the number. */
79359302 357 CHECK(secp256k1_num_is_zero(&snum) == secp256k1_scalar_is_zero(&s));
71712b27 358 /* Check that comparison with the half order is equal to testing for high scalar. */
79359302
PW
359 CHECK(secp256k1_scalar_is_high(&s) == (secp256k1_num_cmp(&snum, &secp256k1_ge_consts->half_order) > 0));
360 secp256k1_scalar_t neg;
79359302
PW
361 secp256k1_scalar_negate(&neg, &s);
362 secp256k1_num_t negnum;
79359302
PW
363 secp256k1_num_sub(&negnum, &secp256k1_ge_consts->order, &snum);
364 secp256k1_num_mod(&negnum, &secp256k1_ge_consts->order);
71712b27 365 /* Check that comparison with the half order is equal to testing for high scalar after negation. */
79359302 366 CHECK(secp256k1_scalar_is_high(&neg) == (secp256k1_num_cmp(&negnum, &secp256k1_ge_consts->half_order) > 0));
71712b27 367 /* Negating should change the high property, unless the value was already zero. */
79359302
PW
368 CHECK((secp256k1_scalar_is_high(&s) == secp256k1_scalar_is_high(&neg)) == secp256k1_scalar_is_zero(&s));
369 secp256k1_num_t negnum2;
79359302 370 secp256k1_scalar_get_num(&negnum2, &neg);
71712b27 371 /* Negating a scalar should be equal to (order - n) mod order on the number. */
79359302
PW
372 CHECK(secp256k1_num_eq(&negnum, &negnum2));
373 secp256k1_scalar_add(&neg, &neg, &s);
71712b27 374 /* Adding a number to its negation should result in zero. */
79359302
PW
375 CHECK(secp256k1_scalar_is_zero(&neg));
376 secp256k1_scalar_negate(&neg, &neg);
71712b27 377 /* Negating zero should still result in zero. */
79359302 378 CHECK(secp256k1_scalar_is_zero(&neg));
79359302
PW
379 }
380
381 {
71712b27 382 /* Test that scalar inverses are equal to the inverse of their number modulo the order. */
79359302
PW
383 if (!secp256k1_scalar_is_zero(&s)) {
384 secp256k1_scalar_t inv;
79359302
PW
385 secp256k1_scalar_inverse(&inv, &s);
386 secp256k1_num_t invnum;
79359302
PW
387 secp256k1_num_mod_inverse(&invnum, &snum, &secp256k1_ge_consts->order);
388 secp256k1_num_t invnum2;
79359302
PW
389 secp256k1_scalar_get_num(&invnum2, &inv);
390 CHECK(secp256k1_num_eq(&invnum, &invnum2));
391 secp256k1_scalar_mul(&inv, &inv, &s);
71712b27 392 /* Multiplying a scalar with its inverse must result in one. */
79359302
PW
393 CHECK(secp256k1_scalar_is_one(&inv));
394 secp256k1_scalar_inverse(&inv, &inv);
71712b27 395 /* Inverting one must result in one. */
79359302 396 CHECK(secp256k1_scalar_is_one(&inv));
79359302
PW
397 }
398 }
399
400 {
71712b27 401 /* Test commutativity of add. */
79359302 402 secp256k1_scalar_t r1, r2;
79359302
PW
403 secp256k1_scalar_add(&r1, &s1, &s2);
404 secp256k1_scalar_add(&r2, &s2, &s1);
405 CHECK(secp256k1_scalar_eq(&r1, &r2));
79359302
PW
406 }
407
52132078
PW
408 {
409 /* Test add_bit. */
410 int bit = secp256k1_rand32() % 256;
411 secp256k1_scalar_t b;
1e6c77c3 412 secp256k1_scalar_set_int(&b, 1);
52132078
PW
413 CHECK(secp256k1_scalar_is_one(&b));
414 for (int i = 0; i < bit; i++) {
415 secp256k1_scalar_add(&b, &b, &b);
416 }
417 secp256k1_scalar_t r1 = s1, r2 = s1;
418 secp256k1_scalar_add(&r1, &r1, &b);
419 if (!(secp256k1_scalar_get_bits(&s1, 255, 1) == 1 && secp256k1_scalar_get_bits(&r1, 255, 1) == 0)) {
420 /* No overflow happened. */
421 secp256k1_scalar_add_bit(&r2, bit);
422 CHECK(secp256k1_scalar_eq(&r1, &r2));
423 }
424 }
425
79359302 426 {
71712b27 427 /* Test commutativity of mul. */
79359302 428 secp256k1_scalar_t r1, r2;
79359302
PW
429 secp256k1_scalar_mul(&r1, &s1, &s2);
430 secp256k1_scalar_mul(&r2, &s2, &s1);
431 CHECK(secp256k1_scalar_eq(&r1, &r2));
79359302
PW
432 }
433
434 {
71712b27 435 /* Test associativity of add. */
79359302 436 secp256k1_scalar_t r1, r2;
79359302
PW
437 secp256k1_scalar_add(&r1, &s1, &s2);
438 secp256k1_scalar_add(&r1, &r1, &s);
439 secp256k1_scalar_add(&r2, &s2, &s);
440 secp256k1_scalar_add(&r2, &s1, &r2);
441 CHECK(secp256k1_scalar_eq(&r1, &r2));
79359302
PW
442 }
443
444 {
71712b27 445 /* Test associativity of mul. */
79359302 446 secp256k1_scalar_t r1, r2;
79359302
PW
447 secp256k1_scalar_mul(&r1, &s1, &s2);
448 secp256k1_scalar_mul(&r1, &r1, &s);
449 secp256k1_scalar_mul(&r2, &s2, &s);
450 secp256k1_scalar_mul(&r2, &s1, &r2);
451 CHECK(secp256k1_scalar_eq(&r1, &r2));
79359302
PW
452 }
453
454 {
71712b27 455 /* Test distributitivity of mul over add. */
79359302 456 secp256k1_scalar_t r1, r2, t;
79359302
PW
457 secp256k1_scalar_add(&r1, &s1, &s2);
458 secp256k1_scalar_mul(&r1, &r1, &s);
459 secp256k1_scalar_mul(&r2, &s1, &s);
460 secp256k1_scalar_mul(&t, &s2, &s);
461 secp256k1_scalar_add(&r2, &r2, &t);
462 CHECK(secp256k1_scalar_eq(&r1, &r2));
79359302 463 }
1d52a8b1
PW
464
465 {
71712b27 466 /* Test square. */
1d52a8b1
PW
467 secp256k1_scalar_t r1, r2;
468 secp256k1_scalar_sqr(&r1, &s1);
469 secp256k1_scalar_mul(&r2, &s1, &s1);
470 CHECK(secp256k1_scalar_eq(&r1, &r2));
471 }
79359302
PW
472}
473
474void run_scalar_tests(void) {
475 for (int i = 0; i < 128 * count; i++) {
476 scalar_test();
477 }
478}
479
09ca4f32
PD
480/***** FIELD TESTS *****/
481
482void random_fe(secp256k1_fe_t *x) {
483 unsigned char bin[32];
d907ebc0
PW
484 do {
485 secp256k1_rand256(bin);
486 if (secp256k1_fe_set_b32(x, bin)) {
487 return;
488 }
489 } while(1);
09ca4f32
PD
490}
491
6d6102fe
PD
492void random_fe_non_zero(secp256k1_fe_t *nz) {
493 int tries = 10;
09ca4f32 494 while (--tries >= 0) {
6d6102fe
PD
495 random_fe(nz);
496 secp256k1_fe_normalize(nz);
497 if (!secp256k1_fe_is_zero(nz))
09ca4f32
PD
498 break;
499 }
71712b27 500 /* Infinitesimal probability of spurious failure here */
0592d117 501 CHECK(tries >= 0);
09ca4f32
PD
502}
503
6d6102fe
PD
504void random_fe_non_square(secp256k1_fe_t *ns) {
505 random_fe_non_zero(ns);
506 secp256k1_fe_t r;
507 if (secp256k1_fe_sqrt(&r, ns)) {
508 secp256k1_fe_negate(ns, ns, 1);
509 }
510}
511
f16be77f
PD
512int check_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
513 secp256k1_fe_t an = *a; secp256k1_fe_normalize(&an);
514 secp256k1_fe_t bn = *b; secp256k1_fe_normalize(&bn);
515 return secp256k1_fe_equal(&an, &bn);
516}
517
518int check_fe_inverse(const secp256k1_fe_t *a, const secp256k1_fe_t *ai) {
519 secp256k1_fe_t x; secp256k1_fe_mul(&x, a, ai);
520 secp256k1_fe_t one; secp256k1_fe_set_int(&one, 1);
521 return check_fe_equal(&x, &one);
522}
523
2cad067a 524void run_field_inv(void) {
f16be77f
PD
525 secp256k1_fe_t x, xi, xii;
526 for (int i=0; i<10*count; i++) {
527 random_fe_non_zero(&x);
528 secp256k1_fe_inv(&xi, &x);
529 CHECK(check_fe_inverse(&x, &xi));
530 secp256k1_fe_inv(&xii, &xi);
531 CHECK(check_fe_equal(&x, &xii));
532 }
533}
534
2cad067a 535void run_field_inv_var(void) {
f16be77f
PD
536 secp256k1_fe_t x, xi, xii;
537 for (int i=0; i<10*count; i++) {
538 random_fe_non_zero(&x);
539 secp256k1_fe_inv_var(&xi, &x);
540 CHECK(check_fe_inverse(&x, &xi));
541 secp256k1_fe_inv_var(&xii, &xi);
542 CHECK(check_fe_equal(&x, &xii));
543 }
544}
545
2cad067a 546void run_field_inv_all(void) {
f16be77f 547 secp256k1_fe_t x[16], xi[16], xii[16];
71712b27 548 /* Check it's safe to call for 0 elements */
f16be77f
PD
549 secp256k1_fe_inv_all(0, xi, x);
550 for (int i=0; i<count; i++) {
551 size_t len = (secp256k1_rand32() & 15) + 1;
3276e7d4 552 for (size_t j=0; j<len; j++)
f16be77f
PD
553 random_fe_non_zero(&x[j]);
554 secp256k1_fe_inv_all(len, xi, x);
3276e7d4 555 for (size_t j=0; j<len; j++)
f16be77f
PD
556 CHECK(check_fe_inverse(&x[j], &xi[j]));
557 secp256k1_fe_inv_all(len, xii, xi);
3276e7d4 558 for (size_t j=0; j<len; j++)
f16be77f
PD
559 CHECK(check_fe_equal(&x[j], &xii[j]));
560 }
561}
562
2cad067a 563void run_field_inv_all_var(void) {
f16be77f 564 secp256k1_fe_t x[16], xi[16], xii[16];
71712b27 565 /* Check it's safe to call for 0 elements */
f16be77f
PD
566 secp256k1_fe_inv_all_var(0, xi, x);
567 for (int i=0; i<count; i++) {
568 size_t len = (secp256k1_rand32() & 15) + 1;
3276e7d4 569 for (size_t j=0; j<len; j++)
f16be77f
PD
570 random_fe_non_zero(&x[j]);
571 secp256k1_fe_inv_all_var(len, xi, x);
3276e7d4 572 for (size_t j=0; j<len; j++)
f16be77f
PD
573 CHECK(check_fe_inverse(&x[j], &xi[j]));
574 secp256k1_fe_inv_all_var(len, xii, xi);
3276e7d4 575 for (size_t j=0; j<len; j++)
f16be77f
PD
576 CHECK(check_fe_equal(&x[j], &xii[j]));
577 }
578}
579
2cad067a 580void run_sqr(void) {
59447da3
PD
581 secp256k1_fe_t x, s;
582
59447da3
PD
583 {
584 secp256k1_fe_set_int(&x, 1);
585 secp256k1_fe_negate(&x, &x, 1);
586
587 for (int i=1; i<=512; ++i) {
588 secp256k1_fe_mul_int(&x, 2);
589 secp256k1_fe_normalize(&x);
590 secp256k1_fe_sqr(&s, &x);
59447da3
PD
591 }
592 }
59447da3
PD
593}
594
09ca4f32
PD
595void test_sqrt(const secp256k1_fe_t *a, const secp256k1_fe_t *k) {
596 secp256k1_fe_t r1, r2;
597 int v = secp256k1_fe_sqrt(&r1, a);
0592d117 598 CHECK((v == 0) == (k == NULL));
09ca4f32
PD
599
600 if (k != NULL) {
71712b27 601 /* Check that the returned root is +/- the given known answer */
09ca4f32
PD
602 secp256k1_fe_negate(&r2, &r1, 1);
603 secp256k1_fe_add(&r1, k); secp256k1_fe_add(&r2, k);
604 secp256k1_fe_normalize(&r1); secp256k1_fe_normalize(&r2);
0592d117 605 CHECK(secp256k1_fe_is_zero(&r1) || secp256k1_fe_is_zero(&r2));
09ca4f32
PD
606 }
607}
608
2cad067a 609void run_sqrt(void) {
09ca4f32 610 secp256k1_fe_t ns, x, s, t;
6d6102fe 611
71712b27 612 /* Check sqrt(0) is 0 */
6d6102fe
PD
613 secp256k1_fe_set_int(&x, 0);
614 secp256k1_fe_sqr(&s, &x);
615 test_sqrt(&s, &x);
616
71712b27 617 /* Check sqrt of small squares (and their negatives) */
6d6102fe
PD
618 for (int i=1; i<=100; i++) {
619 secp256k1_fe_set_int(&x, i);
09ca4f32
PD
620 secp256k1_fe_sqr(&s, &x);
621 test_sqrt(&s, &x);
6d6102fe 622 secp256k1_fe_negate(&t, &s, 1);
09ca4f32
PD
623 test_sqrt(&t, NULL);
624 }
6d6102fe 625
71712b27 626 /* Consistency checks for large random values */
6d6102fe
PD
627 for (int i=0; i<10; i++) {
628 random_fe_non_square(&ns);
629 for (int j=0; j<count; j++) {
630 random_fe(&x);
631 secp256k1_fe_sqr(&s, &x);
632 test_sqrt(&s, &x);
633 secp256k1_fe_negate(&t, &s, 1);
634 test_sqrt(&t, NULL);
635 secp256k1_fe_mul(&t, &s, &ns);
636 test_sqrt(&t, NULL);
637 }
638 }
09ca4f32
PD
639}
640
9338dbf7
PW
641/***** GROUP TESTS *****/
642
643int ge_equals_ge(const secp256k1_ge_t *a, const secp256k1_ge_t *b) {
644 if (a->infinity && b->infinity)
645 return 1;
646 return check_fe_equal(&a->x, &b->x) && check_fe_equal(&a->y, &b->y);
647}
648
649void ge_equals_gej(const secp256k1_ge_t *a, const secp256k1_gej_t *b) {
650 secp256k1_ge_t bb;
651 secp256k1_gej_t bj = *b;
652 secp256k1_ge_set_gej_var(&bb, &bj);
653 CHECK(ge_equals_ge(a, &bb));
654}
655
656void gej_equals_gej(const secp256k1_gej_t *a, const secp256k1_gej_t *b) {
657 secp256k1_ge_t aa, bb;
658 secp256k1_gej_t aj = *a, bj = *b;
659 secp256k1_ge_set_gej_var(&aa, &aj);
660 secp256k1_ge_set_gej_var(&bb, &bj);
661 CHECK(ge_equals_ge(&aa, &bb));
662}
663
2cad067a 664void test_ge(void) {
9338dbf7
PW
665 secp256k1_ge_t a, b, i, n;
666 random_group_element_test(&a);
667 random_group_element_test(&b);
668 n = a;
669 secp256k1_fe_normalize(&a.y);
670 secp256k1_fe_negate(&n.y, &a.y, 1);
671 secp256k1_ge_set_infinity(&i);
672 random_field_element_magnitude(&a.x);
673 random_field_element_magnitude(&a.y);
674 random_field_element_magnitude(&b.x);
675 random_field_element_magnitude(&b.y);
676 random_field_element_magnitude(&n.x);
677 random_field_element_magnitude(&n.y);
678
679 secp256k1_gej_t aj, bj, ij, nj;
680 random_group_element_jacobian_test(&aj, &a);
681 random_group_element_jacobian_test(&bj, &b);
682 secp256k1_gej_set_infinity(&ij);
683 random_group_element_jacobian_test(&nj, &n);
684 random_field_element_magnitude(&aj.x);
685 random_field_element_magnitude(&aj.y);
686 random_field_element_magnitude(&aj.z);
687 random_field_element_magnitude(&bj.x);
688 random_field_element_magnitude(&bj.y);
689 random_field_element_magnitude(&bj.z);
690 random_field_element_magnitude(&nj.x);
691 random_field_element_magnitude(&nj.y);
692 random_field_element_magnitude(&nj.z);
693
71712b27 694 /* gej + gej adds */
9338dbf7
PW
695 secp256k1_gej_t aaj; secp256k1_gej_add_var(&aaj, &aj, &aj);
696 secp256k1_gej_t abj; secp256k1_gej_add_var(&abj, &aj, &bj);
697 secp256k1_gej_t aij; secp256k1_gej_add_var(&aij, &aj, &ij);
698 secp256k1_gej_t anj; secp256k1_gej_add_var(&anj, &aj, &nj);
699 secp256k1_gej_t iaj; secp256k1_gej_add_var(&iaj, &ij, &aj);
700 secp256k1_gej_t iij; secp256k1_gej_add_var(&iij, &ij, &ij);
701
71712b27 702 /* gej + ge adds */
9338dbf7
PW
703 secp256k1_gej_t aa; secp256k1_gej_add_ge_var(&aa, &aj, &a);
704 secp256k1_gej_t ab; secp256k1_gej_add_ge_var(&ab, &aj, &b);
705 secp256k1_gej_t ai; secp256k1_gej_add_ge_var(&ai, &aj, &i);
706 secp256k1_gej_t an; secp256k1_gej_add_ge_var(&an, &aj, &n);
707 secp256k1_gej_t ia; secp256k1_gej_add_ge_var(&ia, &ij, &a);
708 secp256k1_gej_t ii; secp256k1_gej_add_ge_var(&ii, &ij, &i);
709
71712b27 710 /* const gej + ge adds */
9338dbf7
PW
711 secp256k1_gej_t aac; secp256k1_gej_add_ge(&aac, &aj, &a);
712 secp256k1_gej_t abc; secp256k1_gej_add_ge(&abc, &aj, &b);
713 secp256k1_gej_t anc; secp256k1_gej_add_ge(&anc, &aj, &n);
714 secp256k1_gej_t iac; secp256k1_gej_add_ge(&iac, &ij, &a);
715
716 CHECK(secp256k1_gej_is_infinity(&an));
717 CHECK(secp256k1_gej_is_infinity(&anj));
718 CHECK(secp256k1_gej_is_infinity(&anc));
719 gej_equals_gej(&aa, &aaj);
720 gej_equals_gej(&aa, &aac);
721 gej_equals_gej(&ab, &abj);
722 gej_equals_gej(&ab, &abc);
723 gej_equals_gej(&an, &anj);
724 gej_equals_gej(&an, &anc);
725 gej_equals_gej(&ia, &iaj);
726 gej_equals_gej(&ai, &aij);
727 gej_equals_gej(&ii, &iij);
728 ge_equals_gej(&a, &ai);
729 ge_equals_gej(&a, &ai);
730 ge_equals_gej(&a, &iaj);
731 ge_equals_gej(&a, &iaj);
732 ge_equals_gej(&a, &iac);
733}
734
2cad067a 735void run_ge(void) {
9338dbf7
PW
736 for (int i = 0; i < 2000*count; i++) {
737 test_ge();
738 }
739}
740
09ca4f32
PD
741/***** ECMULT TESTS *****/
742
2cad067a 743void run_ecmult_chain(void) {
71712b27 744 /* random starting point A (on the curve) */
d907ebc0
PW
745 secp256k1_fe_t ax; VERIFY_CHECK(secp256k1_fe_set_hex(&ax, "8b30bbe9ae2a990696b22f670709dff3727fd8bc04d3362c6c7bf458e2846004", 64));
746 secp256k1_fe_t ay; VERIFY_CHECK(secp256k1_fe_set_hex(&ay, "a357ae915c4a65281309edf20504740f0eb3343990216b4f81063cb65f2f7e0f", 64));
f11ff5be 747 secp256k1_gej_t a; secp256k1_gej_set_xy(&a, &ax, &ay);
71712b27 748 /* two random initial factors xn and gn */
4adf6b2a 749 secp256k1_num_t xn;
4adf6b2a
PW
750 secp256k1_num_set_hex(&xn, "84cc5452f7fde1edb4d38a8ce9b1b84ccef31f146e569be9705d357a42985407", 64);
751 secp256k1_num_t gn;
4adf6b2a 752 secp256k1_num_set_hex(&gn, "a1e58d22553dcd42b23980625d4c57a96e9323d42b3152e5ca2c3990edc7c9de", 64);
71712b27 753 /* two small multipliers to be applied to xn and gn in every iteration: */
4adf6b2a 754 secp256k1_num_t xf;
4adf6b2a
PW
755 secp256k1_num_set_hex(&xf, "1337", 4);
756 secp256k1_num_t gf;
4adf6b2a 757 secp256k1_num_set_hex(&gf, "7113", 4);
71712b27 758 /* accumulators with the resulting coefficients to A and G */
4adf6b2a 759 secp256k1_num_t ae;
4adf6b2a
PW
760 secp256k1_num_set_int(&ae, 1);
761 secp256k1_num_t ge;
4adf6b2a 762 secp256k1_num_set_int(&ge, 0);
71712b27 763 /* the point being computed */
f11ff5be
PW
764 secp256k1_gej_t x = a;
765 const secp256k1_num_t *order = &secp256k1_ge_consts->order;
404c30a8 766 for (int i=0; i<200*count; i++) {
71712b27 767 /* in each iteration, compute X = xn*X + gn*G; */
b1483f87 768 secp256k1_ecmult(&x, &x, &xn, &gn);
71712b27
GM
769 /* also compute ae and ge: the actual accumulated factors for A and G */
770 /* if X was (ae*A+ge*G), xn*X + gn*G results in (xn*ae*A + (xn*ge+gn)*G) */
f11ff5be
PW
771 secp256k1_num_mod_mul(&ae, &ae, &xn, order);
772 secp256k1_num_mod_mul(&ge, &ge, &xn, order);
4adf6b2a 773 secp256k1_num_add(&ge, &ge, &gn);
2f9e831d 774 secp256k1_num_mod(&ge, order);
71712b27 775 /* modify xn and gn */
f11ff5be
PW
776 secp256k1_num_mod_mul(&xn, &xn, &xf, order);
777 secp256k1_num_mod_mul(&gn, &gn, &gf, order);
404c30a8 778
71712b27 779 /* verify */
404c30a8
PW
780 if (i == 19999) {
781 char res[132]; int resl = 132;
782 secp256k1_gej_get_hex(res, &resl, &x);
0592d117 783 CHECK(strcmp(res, "(D6E96687F9B10D092A6F35439D86CEBEA4535D0D409F53586440BD74B933E830,B95CBCA2C77DA786539BE8FD53354D2D3B4F566AE658045407ED6015EE1B2A88)") == 0);
404c30a8 784 }
4adf6b2a 785 }
71712b27 786 /* redo the computation, but directly with the resulting ae and ge coefficients: */
b1483f87 787 secp256k1_gej_t x2; secp256k1_ecmult(&x2, &a, &ae, &ge);
404c30a8 788 char res[132]; int resl = 132;
f11ff5be 789 char res2[132]; int resl2 = 132;
404c30a8 790 secp256k1_gej_get_hex(res, &resl, &x);
f11ff5be 791 secp256k1_gej_get_hex(res2, &resl2, &x2);
0592d117
PW
792 CHECK(strcmp(res, res2) == 0);
793 CHECK(strlen(res) == 131);
a41f32e6
PW
794}
795
eb0be8ee 796void test_point_times_order(const secp256k1_gej_t *point) {
b5c9ee75
PW
797 /* X * (point + G) + (order-X) * (pointer + G) = 0 */
798 secp256k1_num_t x;
799 random_num_order_test(&x);
800 secp256k1_num_t nx;
801 secp256k1_num_sub(&nx, &secp256k1_ge_consts->order, &x);
802 secp256k1_gej_t res1, res2;
803 secp256k1_ecmult(&res1, point, &x, &x); /* calc res1 = x * point + x * G; */
804 secp256k1_ecmult(&res2, point, &nx, &nx); /* calc res2 = (order - x) * point + (order - x) * G; */
805 secp256k1_gej_add_var(&res1, &res1, &res2);
806 CHECK(secp256k1_gej_is_infinity(&res1));
4e0ed539
PW
807}
808
2cad067a 809void run_point_times_order(void) {
d907ebc0 810 secp256k1_fe_t x; VERIFY_CHECK(secp256k1_fe_set_hex(&x, "02", 2));
4e0ed539 811 for (int i=0; i<500; i++) {
09ca4f32
PD
812 secp256k1_ge_t p;
813 if (secp256k1_ge_set_xo(&p, &x, 1)) {
0592d117 814 CHECK(secp256k1_ge_is_valid(&p));
09ca4f32
PD
815 secp256k1_gej_t j;
816 secp256k1_gej_set_ge(&j, &p);
0592d117 817 CHECK(secp256k1_gej_is_valid(&j));
09ca4f32
PD
818 test_point_times_order(&j);
819 }
910d0de4 820 secp256k1_fe_sqr(&x, &x);
4e0ed539 821 }
910d0de4
PW
822 char c[65]; int cl=65;
823 secp256k1_fe_get_hex(c, &cl, &x);
0592d117 824 CHECK(strcmp(c, "7603CB59B0EF6C63FE6084792A0C378CDB3233A80F8A9A09A877DEAD31B38C45") == 0);
4e0ed539
PW
825}
826
eb0be8ee 827void test_wnaf(const secp256k1_num_t *number, int w) {
4adf6b2a 828 secp256k1_num_t x, two, t;
4adf6b2a
PW
829 secp256k1_num_set_int(&x, 0);
830 secp256k1_num_set_int(&two, 2);
0b730597 831 int wnaf[256];
eb0be8ee 832 int bits = secp256k1_ecmult_wnaf(wnaf, number, w);
0b730597 833 CHECK(bits <= 256);
4e0ed539 834 int zeroes = -1;
b1483f87 835 for (int i=bits-1; i>=0; i--) {
4adf6b2a 836 secp256k1_num_mul(&x, &x, &two);
b1483f87 837 int v = wnaf[i];
4e0ed539 838 if (v) {
71712b27 839 CHECK(zeroes == -1 || zeroes >= w-1); /* check that distance between non-zero elements is at least w-1 */
4e0ed539 840 zeroes=0;
71712b27
GM
841 CHECK((v & 1) == 1); /* check non-zero elements are odd */
842 CHECK(v <= (1 << (w-1)) - 1); /* check range below */
843 CHECK(v >= -(1 << (w-1)) - 1); /* check range above */
4e0ed539 844 } else {
71712b27 845 CHECK(zeroes != -1); /* check that no unnecessary zero padding exists */
4e0ed539
PW
846 zeroes++;
847 }
4adf6b2a
PW
848 secp256k1_num_set_int(&t, v);
849 secp256k1_num_add(&x, &x, &t);
4e0ed539 850 }
0b730597
PW
851 secp256k1_num_t xcopy = x, ncopy = *number;
852 secp256k1_num_mod(&xcopy, &secp256k1_ge_consts->order);
853 secp256k1_num_mod(&ncopy, &secp256k1_ge_consts->order);
854 CHECK(secp256k1_num_eq(&xcopy, &ncopy)); /* check that wnaf represents number */
4e0ed539
PW
855}
856
2cad067a 857void run_wnaf(void) {
d06e61cb 858 secp256k1_num_t n;
404c30a8 859 for (int i=0; i<count; i++) {
d06e61cb
PW
860 random_num_order(&n);
861 if (i % 1)
862 secp256k1_num_negate(&n);
eb0be8ee 863 test_wnaf(&n, 4+(i%10));
4e0ed539
PW
864 }
865}
a41f32e6 866
a9f5c8b8
PW
867void random_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *key, const secp256k1_scalar_t *msg, int *recid) {
868 secp256k1_scalar_t nonce;
dd08f037 869 do {
a9f5c8b8 870 random_scalar_order_test(&nonce);
dd08f037 871 } while(!secp256k1_ecdsa_sig_sign(sig, key, msg, &nonce, recid));
dd08f037
PW
872}
873
2cad067a 874void test_ecdsa_sign_verify(void) {
a9f5c8b8 875 secp256k1_scalar_t msg, key;
a9f5c8b8 876 random_scalar_order_test(&msg);
a9f5c8b8 877 random_scalar_order_test(&key);
764332d0
PW
878 secp256k1_gej_t pubj; secp256k1_ecmult_gen(&pubj, &key);
879 secp256k1_ge_t pub; secp256k1_ge_set_gej(&pub, &pubj);
d41e93a5 880 secp256k1_ecdsa_sig_t sig;
dd08f037 881 random_sign(&sig, &key, &msg, NULL);
a9f5c8b8 882 secp256k1_num_t msg_num;
a9f5c8b8
PW
883 secp256k1_scalar_get_num(&msg_num, &msg);
884 CHECK(secp256k1_ecdsa_sig_verify(&sig, &pub, &msg_num));
885 secp256k1_num_inc(&msg_num);
886 CHECK(!secp256k1_ecdsa_sig_verify(&sig, &pub, &msg_num));
0a07e62f
PW
887}
888
2cad067a 889void run_ecdsa_sign_verify(void) {
404c30a8 890 for (int i=0; i<10*count; i++) {
0a07e62f
PW
891 test_ecdsa_sign_verify();
892 }
893}
894
2cad067a 895void test_ecdsa_end_to_end(void) {
25f4aec0
PW
896 unsigned char privkey[32];
897 unsigned char message[32];
898
71712b27 899 /* Generate a random key and message. */
25f4aec0
PW
900 {
901 secp256k1_num_t msg, key;
25f4aec0 902 random_num_order_test(&msg);
25f4aec0
PW
903 random_num_order_test(&key);
904 secp256k1_num_get_bin(privkey, 32, &key);
905 secp256k1_num_get_bin(message, 32, &msg);
25f4aec0
PW
906 }
907
71712b27 908 /* Construct and verify corresponding public key. */
ae6bc76e 909 CHECK(secp256k1_ec_seckey_verify(privkey) == 1);
9974d869 910 unsigned char pubkey[65]; int pubkeylen = 65;
ae6bc76e
PW
911 CHECK(secp256k1_ec_pubkey_create(pubkey, &pubkeylen, privkey, secp256k1_rand32() % 2) == 1);
912 CHECK(secp256k1_ec_pubkey_verify(pubkey, pubkeylen));
25f4aec0 913
71712b27 914 /* Verify private key import and export. */
25f4aec0 915 unsigned char seckey[300]; int seckeylen = 300;
ae6bc76e 916 CHECK(secp256k1_ec_privkey_export(privkey, seckey, &seckeylen, secp256k1_rand32() % 2) == 1);
25f4aec0 917 unsigned char privkey2[32];
ae6bc76e 918 CHECK(secp256k1_ec_privkey_import(privkey2, seckey, seckeylen) == 1);
25f4aec0
PW
919 CHECK(memcmp(privkey, privkey2, 32) == 0);
920
71712b27 921 /* Optionally tweak the keys using addition. */
25f4aec0
PW
922 if (secp256k1_rand32() % 3 == 0) {
923 unsigned char rnd[32];
924 secp256k1_rand256_test(rnd);
ae6bc76e
PW
925 int ret1 = secp256k1_ec_privkey_tweak_add(privkey, rnd);
926 int ret2 = secp256k1_ec_pubkey_tweak_add(pubkey, pubkeylen, rnd);
25f4aec0
PW
927 CHECK(ret1 == ret2);
928 if (ret1 == 0) return;
9974d869 929 unsigned char pubkey2[65]; int pubkeylen2 = 65;
ae6bc76e 930 CHECK(secp256k1_ec_pubkey_create(pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1);
25f4aec0
PW
931 CHECK(memcmp(pubkey, pubkey2, pubkeylen) == 0);
932 }
933
71712b27 934 /* Optionally tweak the keys using multiplication. */
25f4aec0
PW
935 if (secp256k1_rand32() % 3 == 0) {
936 unsigned char rnd[32];
937 secp256k1_rand256_test(rnd);
ae6bc76e
PW
938 int ret1 = secp256k1_ec_privkey_tweak_mul(privkey, rnd);
939 int ret2 = secp256k1_ec_pubkey_tweak_mul(pubkey, pubkeylen, rnd);
25f4aec0
PW
940 CHECK(ret1 == ret2);
941 if (ret1 == 0) return;
9974d869 942 unsigned char pubkey2[65]; int pubkeylen2 = 65;
ae6bc76e 943 CHECK(secp256k1_ec_pubkey_create(pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1);
25f4aec0
PW
944 CHECK(memcmp(pubkey, pubkey2, pubkeylen) == 0);
945 }
946
71712b27 947 /* Sign. */
9974d869 948 unsigned char signature[72]; int signaturelen = 72;
25f4aec0
PW
949 while(1) {
950 unsigned char rnd[32];
951 secp256k1_rand256_test(rnd);
952 if (secp256k1_ecdsa_sign(message, 32, signature, &signaturelen, privkey, rnd) == 1) {
953 break;
954 }
955 }
71712b27 956 /* Verify. */
25f4aec0 957 CHECK(secp256k1_ecdsa_verify(message, 32, signature, signaturelen, pubkey, pubkeylen) == 1);
71712b27 958 /* Destroy signature and verify again. */
25f4aec0
PW
959 signature[signaturelen - 1 - secp256k1_rand32() % 20] += 1 + (secp256k1_rand32() % 255);
960 CHECK(secp256k1_ecdsa_verify(message, 32, signature, signaturelen, pubkey, pubkeylen) != 1);
961
71712b27 962 /* Compact sign. */
9974d869 963 unsigned char csignature[64]; int recid = 0;
25f4aec0
PW
964 while(1) {
965 unsigned char rnd[32];
966 secp256k1_rand256_test(rnd);
967 if (secp256k1_ecdsa_sign_compact(message, 32, csignature, privkey, rnd, &recid) == 1) {
968 break;
969 }
970 }
71712b27 971 /* Recover. */
9974d869 972 unsigned char recpubkey[65]; int recpubkeylen = 0;
25f4aec0
PW
973 CHECK(secp256k1_ecdsa_recover_compact(message, 32, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) == 1);
974 CHECK(recpubkeylen == pubkeylen);
975 CHECK(memcmp(pubkey, recpubkey, pubkeylen) == 0);
71712b27 976 /* Destroy signature and verify again. */
25f4aec0
PW
977 csignature[secp256k1_rand32() % 64] += 1 + (secp256k1_rand32() % 255);
978 CHECK(secp256k1_ecdsa_recover_compact(message, 32, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) != 1 ||
979 memcmp(pubkey, recpubkey, pubkeylen) != 0);
980 CHECK(recpubkeylen == pubkeylen);
3fd6253e 981
25f4aec0
PW
982}
983
2cad067a 984void run_ecdsa_end_to_end(void) {
25f4aec0
PW
985 for (int i=0; i<64*count; i++) {
986 test_ecdsa_end_to_end();
987 }
988}
989
6e052878
PW
990/* Tests several edge cases. */
991void test_ecdsa_edge_cases(void) {
3bf029d6
PW
992 const unsigned char msg32[32] = {
993 'T', 'h', 'i', 's', ' ', 'i', 's', ' ',
994 'a', ' ', 'v', 'e', 'r', 'y', ' ', 's',
995 'e', 'c', 'r', 'e', 't', ' ', 'm', 'e',
996 's', 's', 'a', 'g', 'e', '.', '.', '.'
997 };
998 const unsigned char sig64[64] = {
6e052878
PW
999 /* Generated by signing the above message with nonce 'This is the nonce we will use...'
1000 * and secret key 0 (which is not valid), resulting in recid 0. */
3bf029d6
PW
1001 0x67, 0xCB, 0x28, 0x5F, 0x9C, 0xD1, 0x94, 0xE8,
1002 0x40, 0xD6, 0x29, 0x39, 0x7A, 0xF5, 0x56, 0x96,
1003 0x62, 0xFD, 0xE4, 0x46, 0x49, 0x99, 0x59, 0x63,
1004 0x17, 0x9A, 0x7D, 0xD1, 0x7B, 0xD2, 0x35, 0x32,
1005 0x4B, 0x1B, 0x7D, 0xF3, 0x4C, 0xE1, 0xF6, 0x8E,
1006 0x69, 0x4F, 0xF6, 0xF1, 0x1A, 0xC7, 0x51, 0xDD,
1007 0x7D, 0xD7, 0x3E, 0x38, 0x7E, 0xE4, 0xFC, 0x86,
1008 0x6E, 0x1B, 0xE8, 0xEC, 0xC7, 0xDD, 0x95, 0x57
1009 };
1010 unsigned char pubkey[65];
1011 int pubkeylen = 65;
1012 CHECK(!secp256k1_ecdsa_recover_compact(msg32, 32, sig64, pubkey, &pubkeylen, 0, 0));
1013 CHECK(secp256k1_ecdsa_recover_compact(msg32, 32, sig64, pubkey, &pubkeylen, 0, 1));
1014 CHECK(!secp256k1_ecdsa_recover_compact(msg32, 32, sig64, pubkey, &pubkeylen, 0, 2));
1015 CHECK(!secp256k1_ecdsa_recover_compact(msg32, 32, sig64, pubkey, &pubkeylen, 0, 3));
6e052878
PW
1016
1017 /* signature (r,s) = (4,4), which can be recovered with all 4 recids. */
1018 const unsigned char sigb64[64] = {
1019 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1020 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1021 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1022 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
1023 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1024 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1025 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1026 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
1027 };
1028 unsigned char pubkeyb[33];
1029 int pubkeyblen = 33;
1030 for (int recid = 0; recid < 4; recid++) {
1031 unsigned char sigbder[8] = {0x30, 0x06, 0x02, 0x01, 0x04, 0x02, 0x01, 0x04};
1032 CHECK(secp256k1_ecdsa_recover_compact(msg32, 32, sigb64, pubkeyb, &pubkeyblen, 1, recid));
1033 CHECK(secp256k1_ecdsa_verify(msg32, 32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 1);
1034 /* Damage signature. */
1035 sigbder[7]++;
1036 CHECK(secp256k1_ecdsa_verify(msg32, 32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 0);
1037 }
3bf029d6
PW
1038}
1039
6e052878
PW
1040void run_ecdsa_edge_cases(void) {
1041 test_ecdsa_edge_cases();
3bf029d6 1042}
25f4aec0 1043
dd08f037 1044#ifdef ENABLE_OPENSSL_TESTS
a9f5c8b8 1045EC_KEY *get_openssl_key(const secp256k1_scalar_t *key) {
12e29b32
PW
1046 unsigned char privkey[300];
1047 int privkeylen;
1048 int compr = secp256k1_rand32() & 1;
1049 const unsigned char* pbegin = privkey;
dd08f037 1050 EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_secp256k1);
ffffc878 1051 CHECK(secp256k1_eckey_privkey_serialize(privkey, &privkeylen, key, compr));
0592d117
PW
1052 CHECK(d2i_ECPrivateKey(&ec_key, &pbegin, privkeylen));
1053 CHECK(EC_KEY_check_key(ec_key));
dd08f037
PW
1054 return ec_key;
1055}
1056
2cad067a 1057void test_ecdsa_openssl(void) {
a9f5c8b8 1058 secp256k1_scalar_t key, msg;
dd08f037
PW
1059 unsigned char message[32];
1060 secp256k1_rand256_test(message);
eca6cdb1 1061 secp256k1_scalar_set_b32(&msg, message, NULL);
a9f5c8b8 1062 random_scalar_order_test(&key);
dd08f037
PW
1063 secp256k1_gej_t qj;
1064 secp256k1_ecmult_gen(&qj, &key);
1065 secp256k1_ge_t q;
1066 secp256k1_ge_set_gej(&q, &qj);
1067 EC_KEY *ec_key = get_openssl_key(&key);
0592d117 1068 CHECK(ec_key);
dd08f037 1069 unsigned char signature[80];
9974d869 1070 unsigned int sigsize = 80;
0592d117 1071 CHECK(ECDSA_sign(0, message, sizeof(message), signature, &sigsize, ec_key));
dd08f037 1072 secp256k1_ecdsa_sig_t sig;
0592d117 1073 CHECK(secp256k1_ecdsa_sig_parse(&sig, signature, sigsize));
a9f5c8b8 1074 secp256k1_num_t msg_num;
a9f5c8b8
PW
1075 secp256k1_scalar_get_num(&msg_num, &msg);
1076 CHECK(secp256k1_ecdsa_sig_verify(&sig, &q, &msg_num));
dd08f037 1077 secp256k1_num_inc(&sig.r);
a9f5c8b8 1078 CHECK(!secp256k1_ecdsa_sig_verify(&sig, &q, &msg_num));
dd08f037
PW
1079
1080 random_sign(&sig, &key, &msg, NULL);
9974d869
GM
1081 int secp_sigsize = 80;
1082 CHECK(secp256k1_ecdsa_sig_serialize(signature, &secp_sigsize, &sig));
1083 CHECK(ECDSA_verify(0, message, sizeof(message), signature, secp_sigsize, ec_key) == 1);
dd08f037 1084
dd08f037 1085 EC_KEY_free(ec_key);
dd08f037
PW
1086}
1087
2cad067a 1088void run_ecdsa_openssl(void) {
dd08f037
PW
1089 for (int i=0; i<10*count; i++) {
1090 test_ecdsa_openssl();
1091 }
1092}
1093#endif
1094
404c30a8 1095int main(int argc, char **argv) {
71712b27 1096 /* find iteration count */
3fd6253e
PW
1097 if (argc > 1) {
1098 count = strtol(argv[1], NULL, 0);
1099 }
1100
71712b27 1101 /* find random seed */
3fd6253e
PW
1102 uint64_t seed;
1103 if (argc > 2) {
1104 seed = strtoull(argv[2], NULL, 0);
1105 } else {
1106 FILE *frand = fopen("/dev/urandom", "r");
1107 if (!frand || !fread(&seed, sizeof(seed), 1, frand)) {
1108 seed = time(NULL) * 1337;
1109 }
1110 fclose(frand);
1111 }
1112 secp256k1_rand_seed(seed);
404c30a8 1113
dd08f037 1114 printf("test count = %i\n", count);
3fd6253e 1115 printf("random seed = %llu\n", (unsigned long long)seed);
dd08f037 1116
71712b27 1117 /* initialize */
04e34d18 1118 secp256k1_start(SECP256K1_START_SIGN | SECP256K1_START_VERIFY);
4adf6b2a 1119
71712b27 1120 /* num tests */
3f44e1ad 1121 run_num_smalltests();
404c30a8 1122
71712b27 1123 /* scalar tests */
79359302
PW
1124 run_scalar_tests();
1125
71712b27 1126 /* field tests */
f16be77f
PD
1127 run_field_inv();
1128 run_field_inv_var();
1129 run_field_inv_all();
1130 run_field_inv_all_var();
59447da3 1131 run_sqr();
09ca4f32
PD
1132 run_sqrt();
1133
71712b27 1134 /* group tests */
9338dbf7
PW
1135 run_ge();
1136
71712b27 1137 /* ecmult tests */
404c30a8
PW
1138 run_wnaf();
1139 run_point_times_order();
1140 run_ecmult_chain();
1141
71712b27 1142 /* ecdsa tests */
404c30a8 1143 run_ecdsa_sign_verify();
25f4aec0 1144 run_ecdsa_end_to_end();
6e052878 1145 run_ecdsa_edge_cases();
dd08f037
PW
1146#ifdef ENABLE_OPENSSL_TESTS
1147 run_ecdsa_openssl();
1148#endif
910d0de4 1149
9974d869 1150 printf("random run = %llu\n", (unsigned long long)secp256k1_rand32() + ((unsigned long long)secp256k1_rand32() << 32));
bff11e91 1151
71712b27 1152 /* shutdown */
25f4aec0 1153 secp256k1_stop();
a41f32e6
PW
1154 return 0;
1155}
This page took 0.188472 seconds and 4 git commands to generate.