7 #ifndef SECP256K1_GROUP_IMPL_H
8 #define SECP256K1_GROUP_IMPL_H
39 #if defined(EXHAUSTIVE_TEST_ORDER)
40 # if EXHAUSTIVE_TEST_ORDER == 199
42 0xFA7CC9A7, 0x0737F2DB, 0xA749DD39, 0x2B4FB069,
43 0x3B017A7D, 0xA808C2F1, 0xFB12940C, 0x9EA66C18,
44 0x78AC123A, 0x5ED8AEF3, 0x8732BC91, 0x1F3A2868,
45 0x48DF246C, 0x808DAE72, 0xCFE52572, 0x7F0501ED
49 # elif EXHAUSTIVE_TEST_ORDER == 13
51 0xedc60018, 0xa51a786b, 0x2ea91f4d, 0x4c9416c0,
52 0x9de54c3b, 0xa1316554, 0x6cf4345c, 0x7277ef15,
53 0x54cb1b6b, 0xdc8c1273, 0x087844ea, 0x43f4603e,
54 0x0eaf9a43, 0xf6effe55, 0x939f806d, 0x37adf8ac
58 # error No known generator for the specified exhaustive test group order.
65 0x79BE667EUL, 0xF9DCBBACUL, 0x55A06295UL, 0xCE870B07UL,
66 0x029BFCDBUL, 0x2DCE28D9UL, 0x59F2815BUL, 0x16F81798UL,
67 0x483ADA77UL, 0x26A3C465UL, 0x5DA4FBFCUL, 0x0E1108A8UL,
68 0xFD17B448UL, 0xA6855419UL, 0x9C47D08FUL, 0xFB10D4B8UL
77 secp256k1_fe_sqr(&zi2, zi);
78 secp256k1_fe_mul(&zi3, &zi2, zi);
79 secp256k1_fe_mul(&r->
x, &a->
x, &zi2);
80 secp256k1_fe_mul(&r->
y, &a->
y, &zi3);
90 static int secp256k1_ge_is_infinity(
const secp256k1_ge *a) {
96 secp256k1_fe_normalize_weak(&r->
y);
97 secp256k1_fe_negate(&r->
y, &r->
y, 1);
103 secp256k1_fe_inv(&a->
z, &a->
z);
104 secp256k1_fe_sqr(&z2, &a->
z);
105 secp256k1_fe_mul(&z3, &a->
z, &z2);
106 secp256k1_fe_mul(&a->
x, &a->
x, &z2);
107 secp256k1_fe_mul(&a->
y, &a->
y, &z3);
108 secp256k1_fe_set_int(&a->
z, 1);
119 secp256k1_fe_inv_var(&a->
z, &a->
z);
120 secp256k1_fe_sqr(&z2, &a->
z);
121 secp256k1_fe_mul(&z3, &a->
z, &z2);
122 secp256k1_fe_mul(&a->
x, &a->
x, &z2);
123 secp256k1_fe_mul(&a->
y, &a->
y, &z3);
124 secp256k1_fe_set_int(&a->
z, 1);
135 for (i = 0; i < len; i++) {
136 if (!a[i].infinity) {
137 az[count++] = a[i].
z;
142 secp256k1_fe_inv_all_var(azi, az, count);
146 for (i = 0; i < len; i++) {
148 if (!a[i].infinity) {
149 secp256k1_ge_set_gej_zinv(&r[i], &a[i], &azi[count++]);
161 secp256k1_fe_inv(&zi, &a[i].z);
162 secp256k1_ge_set_gej_zinv(&r[i], &a[i], &zi);
166 secp256k1_fe_mul(&zi, &zi, &zr[i]);
168 secp256k1_ge_set_gej_zinv(&r[i], &a[i], &zi);
188 secp256k1_fe_mul(&zs, &zs, &zr[i]);
191 secp256k1_ge_set_gej_zinv(&r[i], &a[i], &zs);
198 secp256k1_fe_clear(&r->
x);
199 secp256k1_fe_clear(&r->
y);
200 secp256k1_fe_clear(&r->
z);
203 static void secp256k1_ge_set_infinity(
secp256k1_ge *r) {
205 secp256k1_fe_clear(&r->
x);
206 secp256k1_fe_clear(&r->
y);
211 secp256k1_fe_clear(&r->
x);
212 secp256k1_fe_clear(&r->
y);
213 secp256k1_fe_clear(&r->
z);
218 secp256k1_fe_clear(&r->
x);
219 secp256k1_fe_clear(&r->
y);
225 secp256k1_fe_sqr(&x2, x);
226 secp256k1_fe_mul(&x3, x, &x2);
228 secp256k1_fe_set_int(&c,
CURVE_B);
229 secp256k1_fe_add(&c, &x3);
230 return secp256k1_fe_sqrt(&r->
y, &c);
234 if (!secp256k1_ge_set_xquad(r, x)) {
237 secp256k1_fe_normalize_var(&r->
y);
238 if (secp256k1_fe_is_odd(&r->
y) != odd) {
239 secp256k1_fe_negate(&r->
y, &r->
y, 1);
249 secp256k1_fe_set_int(&r->
z, 1);
255 secp256k1_fe_sqr(&r, &a->
z); secp256k1_fe_mul(&r, &r, x);
256 r2 = a->
x; secp256k1_fe_normalize_weak(&r2);
257 return secp256k1_fe_equal_var(&r, &r2);
265 secp256k1_fe_normalize_weak(&r->
y);
266 secp256k1_fe_negate(&r->
y, &r->
y, 1);
269 static int secp256k1_gej_is_infinity(
const secp256k1_gej *a) {
273 static int secp256k1_gej_is_valid_var(
const secp256k1_gej *a) {
283 secp256k1_fe_sqr(&y2, &a->
y);
284 secp256k1_fe_sqr(&x3, &a->
x); secp256k1_fe_mul(&x3, &x3, &a->
x);
285 secp256k1_fe_sqr(&z2, &a->
z);
286 secp256k1_fe_sqr(&z6, &z2); secp256k1_fe_mul(&z6, &z6, &z2);
287 secp256k1_fe_mul_int(&z6,
CURVE_B);
288 secp256k1_fe_add(&x3, &z6);
289 secp256k1_fe_normalize_weak(&x3);
290 return secp256k1_fe_equal_var(&y2, &x3);
293 static int secp256k1_ge_is_valid_var(
const secp256k1_ge *a) {
299 secp256k1_fe_sqr(&y2, &a->
y);
300 secp256k1_fe_sqr(&x3, &a->
x); secp256k1_fe_mul(&x3, &x3, &a->
x);
301 secp256k1_fe_set_int(&c,
CURVE_B);
302 secp256k1_fe_add(&x3, &c);
303 secp256k1_fe_normalize_weak(&x3);
304 return secp256k1_fe_equal_var(&y2, &x3);
329 secp256k1_fe_set_int(rzr, 1);
336 secp256k1_fe_normalize_weak(rzr);
337 secp256k1_fe_mul_int(rzr, 2);
340 secp256k1_fe_mul(&r->
z, &a->
z, &a->
y);
341 secp256k1_fe_mul_int(&r->
z, 2);
342 secp256k1_fe_sqr(&t1, &a->
x);
343 secp256k1_fe_mul_int(&t1, 3);
344 secp256k1_fe_sqr(&t2, &t1);
345 secp256k1_fe_sqr(&t3, &a->
y);
346 secp256k1_fe_mul_int(&t3, 2);
347 secp256k1_fe_sqr(&t4, &t3);
348 secp256k1_fe_mul_int(&t4, 2);
349 secp256k1_fe_mul(&t3, &t3, &a->
x);
351 secp256k1_fe_mul_int(&r->
x, 4);
352 secp256k1_fe_negate(&r->
x, &r->
x, 4);
353 secp256k1_fe_add(&r->
x, &t2);
354 secp256k1_fe_negate(&t2, &t2, 1);
355 secp256k1_fe_mul_int(&t3, 6);
356 secp256k1_fe_add(&t3, &t2);
357 secp256k1_fe_mul(&r->
y, &t1, &t3);
358 secp256k1_fe_negate(&t2, &t4, 2);
359 secp256k1_fe_add(&r->
y, &t2);
364 secp256k1_gej_double_var(r, a, rzr);
369 secp256k1_fe z22, z12, u1, u2, s1, s2, h, i, i2, h2, h3, t;
379 secp256k1_fe_set_int(rzr, 1);
386 secp256k1_fe_sqr(&z22, &b->
z);
387 secp256k1_fe_sqr(&z12, &a->
z);
388 secp256k1_fe_mul(&u1, &a->
x, &z22);
389 secp256k1_fe_mul(&u2, &b->
x, &z12);
390 secp256k1_fe_mul(&s1, &a->
y, &z22); secp256k1_fe_mul(&s1, &s1, &b->
z);
391 secp256k1_fe_mul(&s2, &b->
y, &z12); secp256k1_fe_mul(&s2, &s2, &a->
z);
392 secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
393 secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2);
394 if (secp256k1_fe_normalizes_to_zero_var(&h)) {
395 if (secp256k1_fe_normalizes_to_zero_var(&i)) {
396 secp256k1_gej_double_var(r, a, rzr);
399 secp256k1_fe_set_int(rzr, 0);
405 secp256k1_fe_sqr(&i2, &i);
406 secp256k1_fe_sqr(&h2, &h);
407 secp256k1_fe_mul(&h3, &h, &h2);
408 secp256k1_fe_mul(&h, &h, &b->
z);
412 secp256k1_fe_mul(&r->
z, &a->
z, &h);
413 secp256k1_fe_mul(&t, &u1, &h2);
414 r->
x = t; secp256k1_fe_mul_int(&r->
x, 2); secp256k1_fe_add(&r->
x, &h3); secp256k1_fe_negate(&r->
x, &r->
x, 3); secp256k1_fe_add(&r->
x, &i2);
415 secp256k1_fe_negate(&r->
y, &r->
x, 5); secp256k1_fe_add(&r->
y, &t); secp256k1_fe_mul(&r->
y, &r->
y, &i);
416 secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1);
417 secp256k1_fe_add(&r->
y, &h3);
422 secp256k1_fe z12, u1, u2, s1, s2, h, i, i2, h2, h3, t;
425 secp256k1_gej_set_ge(r, b);
430 secp256k1_fe_set_int(rzr, 1);
437 secp256k1_fe_sqr(&z12, &a->
z);
438 u1 = a->
x; secp256k1_fe_normalize_weak(&u1);
439 secp256k1_fe_mul(&u2, &b->
x, &z12);
440 s1 = a->
y; secp256k1_fe_normalize_weak(&s1);
441 secp256k1_fe_mul(&s2, &b->
y, &z12); secp256k1_fe_mul(&s2, &s2, &a->
z);
442 secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
443 secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2);
444 if (secp256k1_fe_normalizes_to_zero_var(&h)) {
445 if (secp256k1_fe_normalizes_to_zero_var(&i)) {
446 secp256k1_gej_double_var(r, a, rzr);
449 secp256k1_fe_set_int(rzr, 0);
455 secp256k1_fe_sqr(&i2, &i);
456 secp256k1_fe_sqr(&h2, &h);
457 secp256k1_fe_mul(&h3, &h, &h2);
461 secp256k1_fe_mul(&r->
z, &a->
z, &h);
462 secp256k1_fe_mul(&t, &u1, &h2);
463 r->
x = t; secp256k1_fe_mul_int(&r->
x, 2); secp256k1_fe_add(&r->
x, &h3); secp256k1_fe_negate(&r->
x, &r->
x, 3); secp256k1_fe_add(&r->
x, &i2);
464 secp256k1_fe_negate(&r->
y, &r->
x, 5); secp256k1_fe_add(&r->
y, &t); secp256k1_fe_mul(&r->
y, &r->
y, &i);
465 secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1);
466 secp256k1_fe_add(&r->
y, &h3);
471 secp256k1_fe az, z12, u1, u2, s1, s2, h, i, i2, h2, h3, t;
480 secp256k1_fe_sqr(&bzinv2, bzinv);
481 secp256k1_fe_mul(&bzinv3, &bzinv2, bzinv);
482 secp256k1_fe_mul(&r->
x, &b->
x, &bzinv2);
483 secp256k1_fe_mul(&r->
y, &b->
y, &bzinv3);
484 secp256k1_fe_set_int(&r->
z, 1);
497 secp256k1_fe_mul(&az, &a->
z, bzinv);
499 secp256k1_fe_sqr(&z12, &az);
500 u1 = a->
x; secp256k1_fe_normalize_weak(&u1);
501 secp256k1_fe_mul(&u2, &b->
x, &z12);
502 s1 = a->
y; secp256k1_fe_normalize_weak(&s1);
503 secp256k1_fe_mul(&s2, &b->
y, &z12); secp256k1_fe_mul(&s2, &s2, &az);
504 secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
505 secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2);
506 if (secp256k1_fe_normalizes_to_zero_var(&h)) {
507 if (secp256k1_fe_normalizes_to_zero_var(&i)) {
508 secp256k1_gej_double_var(r, a, NULL);
514 secp256k1_fe_sqr(&i2, &i);
515 secp256k1_fe_sqr(&h2, &h);
516 secp256k1_fe_mul(&h3, &h, &h2);
517 r->
z = a->
z; secp256k1_fe_mul(&r->
z, &r->
z, &h);
518 secp256k1_fe_mul(&t, &u1, &h2);
519 r->
x = t; secp256k1_fe_mul_int(&r->
x, 2); secp256k1_fe_add(&r->
x, &h3); secp256k1_fe_negate(&r->
x, &r->
x, 3); secp256k1_fe_add(&r->
x, &i2);
520 secp256k1_fe_negate(&r->
y, &r->
x, 5); secp256k1_fe_add(&r->
y, &t); secp256k1_fe_mul(&r->
y, &r->
y, &i);
521 secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1);
522 secp256k1_fe_add(&r->
y, &h3);
529 secp256k1_fe zz, u1, u2, s1, s2, t, tt, m, n, q, rr;
531 int infinity, degenerate;
585 secp256k1_fe_sqr(&zz, &a->
z);
586 u1 = a->
x; secp256k1_fe_normalize_weak(&u1);
587 secp256k1_fe_mul(&u2, &b->
x, &zz);
588 s1 = a->
y; secp256k1_fe_normalize_weak(&s1);
589 secp256k1_fe_mul(&s2, &b->
y, &zz);
590 secp256k1_fe_mul(&s2, &s2, &a->
z);
591 t = u1; secp256k1_fe_add(&t, &u2);
592 m = s1; secp256k1_fe_add(&m, &s2);
593 secp256k1_fe_sqr(&rr, &t);
594 secp256k1_fe_negate(&m_alt, &u2, 1);
595 secp256k1_fe_mul(&tt, &u1, &m_alt);
596 secp256k1_fe_add(&rr, &tt);
599 degenerate = secp256k1_fe_normalizes_to_zero(&m) &
600 secp256k1_fe_normalizes_to_zero(&rr);
607 secp256k1_fe_mul_int(&rr_alt, 2);
608 secp256k1_fe_add(&m_alt, &u1);
610 secp256k1_fe_cmov(&rr_alt, &rr, !degenerate);
611 secp256k1_fe_cmov(&m_alt, &m, !degenerate);
616 secp256k1_fe_sqr(&n, &m_alt);
617 secp256k1_fe_mul(&q, &n, &t);
622 secp256k1_fe_sqr(&n, &n);
623 secp256k1_fe_cmov(&n, &m, degenerate);
624 secp256k1_fe_sqr(&t, &rr_alt);
625 secp256k1_fe_mul(&r->
z, &a->
z, &m_alt);
626 infinity = secp256k1_fe_normalizes_to_zero(&r->
z) * (1 - a->
infinity);
627 secp256k1_fe_mul_int(&r->
z, 2);
628 secp256k1_fe_negate(&q, &q, 1);
629 secp256k1_fe_add(&t, &q);
630 secp256k1_fe_normalize_weak(&t);
632 secp256k1_fe_mul_int(&t, 2);
633 secp256k1_fe_add(&t, &q);
634 secp256k1_fe_mul(&t, &t, &rr_alt);
635 secp256k1_fe_add(&t, &n);
636 secp256k1_fe_negate(&r->
y, &t, 3);
637 secp256k1_fe_normalize_weak(&r->
y);
638 secp256k1_fe_mul_int(&r->
x, 4);
639 secp256k1_fe_mul_int(&r->
y, 4);
644 secp256k1_fe_cmov(&r->
z, &fe_1, a->
infinity);
652 secp256k1_fe_sqr(&zz, s);
653 secp256k1_fe_mul(&r->
x, &r->
x, &zz);
654 secp256k1_fe_mul(&r->
y, &r->
y, &zz);
655 secp256k1_fe_mul(&r->
y, &r->
y, s);
656 secp256k1_fe_mul(&r->
z, &r->
z, s);
663 secp256k1_fe_normalize(&x);
665 secp256k1_fe_normalize(&y);
666 secp256k1_fe_to_storage(&r->
x, &x);
667 secp256k1_fe_to_storage(&r->
y, &y);
671 secp256k1_fe_from_storage(&r->
x, &a->
x);
672 secp256k1_fe_from_storage(&r->
y, &a->
y);
677 secp256k1_fe_storage_cmov(&r->
x, &a->
x, flag);
678 secp256k1_fe_storage_cmov(&r->
y, &a->
y, flag);
681 #ifdef USE_ENDOMORPHISM
684 0x7ae96a2bul, 0x657c0710ul, 0x6e64479eul, 0xac3434e9ul,
685 0x9cf04975ul, 0x12f58995ul, 0xc1396c28ul, 0x719501eeul
688 secp256k1_fe_mul(&r->
x, &r->
x, &beta);
692 static int secp256k1_gej_has_quad_y_var(
const secp256k1_gej *a) {
702 secp256k1_fe_mul(&yz, &a->
y, &a->
z);
703 return secp256k1_fe_is_quad_var(&yz);
#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0)
#define SECP256K1_GE_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p)
A group element of the secp256k1 curve, in affine coordinates.
A group element of the secp256k1 curve, in jacobian coordinates.
#define VERIFY_CHECK(cond)