7#ifndef SECP256K1_GROUP_IMPL_H
8#define SECP256K1_GROUP_IMPL_H
13#define SECP256K1_G_ORDER_13 SECP256K1_GE_CONST(\
14 0xc3459c3d, 0x35326167, 0xcd86cce8, 0x07a2417f,\
15 0x5b8bd567, 0xde8538ee, 0x0d507b0c, 0xd128f5bb,\
16 0x8e467fec, 0xcd30000a, 0x6cc1184e, 0x25d382c2,\
17 0xa2f4494e, 0x2fbe9abc, 0x8b64abac, 0xd005fb24\
19#define SECP256K1_G_ORDER_199 SECP256K1_GE_CONST(\
20 0x226e653f, 0xc8df7744, 0x9bacbf12, 0x7d1dcbf9,\
21 0x87f05b2a, 0xe7edbd28, 0x1f564575, 0xc48dcf18,\
22 0xa13872c2, 0xe933bb17, 0x5d9ffd5b, 0xb5b6e10c,\
23 0x57fe3c00, 0xbaaaa15a, 0xe003ec3e, 0x9c269bae\
28#define SECP256K1_G SECP256K1_GE_CONST(\
29 0x79BE667EUL, 0xF9DCBBACUL, 0x55A06295UL, 0xCE870B07UL,\
30 0x029BFCDBUL, 0x2DCE28D9UL, 0x59F2815BUL, 0x16F81798UL,\
31 0x483ADA77UL, 0x26A3C465UL, 0x5DA4FBFCUL, 0x0E1108A8UL,\
32 0xFD17B448UL, 0xA6855419UL, 0x9C47D08FUL, 0xFB10D4B8UL\
43#if defined(EXHAUSTIVE_TEST_ORDER)
44# if EXHAUSTIVE_TEST_ORDER == 13
48 0x3d3486b2, 0x159a9ca5, 0xc75638be, 0xb23a69bc,
49 0x946a45ab, 0x24801247, 0xb4ed2b8e, 0x26b6a417
51# elif EXHAUSTIVE_TEST_ORDER == 199
55 0x2cca28fa, 0xfc614b80, 0x2a3db42b, 0x00ba00b1,
56 0xbea8d943, 0xdace9ab2, 0x9536daea, 0x0074defb
59# error No known generator for the specified exhaustive test group order.
71 secp256k1_fe_sqr(&zi2, zi);
72 secp256k1_fe_mul(&zi3, &zi2, zi);
73 secp256k1_fe_mul(&
r->x, &
a->x, &zi2);
74 secp256k1_fe_mul(&
r->y, &
a->y, &zi3);
75 r->infinity =
a->infinity;
90 secp256k1_fe_normalize_weak(&
r->y);
91 secp256k1_fe_negate(&
r->y, &
r->y, 1);
96 r->infinity =
a->infinity;
97 secp256k1_fe_inv(&
a->z, &
a->z);
98 secp256k1_fe_sqr(&z2, &
a->z);
99 secp256k1_fe_mul(&z3, &
a->z, &z2);
100 secp256k1_fe_mul(&
a->x, &
a->x, &z2);
101 secp256k1_fe_mul(&
a->y, &
a->y, &z3);
102 secp256k1_fe_set_int(&
a->z, 1);
110 secp256k1_ge_set_infinity(
r);
113 secp256k1_fe_inv_var(&
a->z, &
a->z);
114 secp256k1_fe_sqr(&z2, &
a->z);
115 secp256k1_fe_mul(&z3, &
a->z, &z2);
116 secp256k1_fe_mul(&
a->x, &
a->x, &z2);
117 secp256k1_fe_mul(&
a->y, &
a->y, &z3);
118 secp256k1_fe_set_int(&
a->z, 1);
119 secp256k1_ge_set_xy(
r, &
a->x, &
a->y);
127 for (i = 0; i <
len; i++) {
129 secp256k1_ge_set_infinity(&
r[i]);
135 secp256k1_fe_mul(&
r[i].x, &
r[last_i].x, &
a[i].z);
143 secp256k1_fe_inv_var(&u, &
r[last_i].x);
148 if (!
a[i].infinity) {
149 secp256k1_fe_mul(&
r[last_i].x, &
r[i].x, &u);
150 secp256k1_fe_mul(&u, &u, &
a[last_i].z);
157 for (i = 0; i <
len; i++) {
158 if (!
a[i].infinity) {
159 secp256k1_ge_set_gej_zinv(&
r[i], &
a[i], &
r[i].x);
170 secp256k1_fe_normalize_weak(&
a[i].y);
177 secp256k1_fe_mul(&zs, &zs, &zr[i]);
183 secp256k1_ge_set_gej_zinv(&
a[i], &tmpa, &zs);
190 secp256k1_fe_clear(&
r->x);
191 secp256k1_fe_clear(&
r->y);
192 secp256k1_fe_clear(&
r->z);
197 secp256k1_fe_clear(&
r->x);
198 secp256k1_fe_clear(&
r->y);
203 secp256k1_fe_clear(&
r->x);
204 secp256k1_fe_clear(&
r->y);
205 secp256k1_fe_clear(&
r->z);
210 secp256k1_fe_clear(&
r->x);
211 secp256k1_fe_clear(&
r->y);
217 secp256k1_fe_sqr(&x2, x);
218 secp256k1_fe_mul(&x3, x, &x2);
220 secp256k1_fe_add(&x3, &secp256k1_fe_const_b);
221 if (!secp256k1_fe_sqrt(&
r->y, &x3)) {
224 secp256k1_fe_normalize_var(&
r->y);
225 if (secp256k1_fe_is_odd(&
r->y) != odd) {
226 secp256k1_fe_negate(&
r->y, &
r->y, 1);
233 r->infinity =
a->infinity;
236 secp256k1_fe_set_int(&
r->z, 1);
242 secp256k1_fe_sqr(&
r, &
a->z); secp256k1_fe_mul(&
r, &
r, x);
243 r2 =
a->x; secp256k1_fe_normalize_weak(&r2);
244 return secp256k1_fe_equal_var(&
r, &r2);
248 r->infinity =
a->infinity;
252 secp256k1_fe_normalize_weak(&
r->y);
253 secp256k1_fe_negate(&
r->y, &
r->y, 1);
266 secp256k1_fe_sqr(&y2, &
a->y);
267 secp256k1_fe_sqr(&x3, &
a->x); secp256k1_fe_mul(&x3, &x3, &
a->x);
268 secp256k1_fe_add(&x3, &secp256k1_fe_const_b);
269 secp256k1_fe_normalize_weak(&x3);
270 return secp256k1_fe_equal_var(&y2, &x3);
277 r->infinity =
a->infinity;
288 secp256k1_fe_mul(&
r->z, &
a->z, &
a->y);
289 secp256k1_fe_sqr(&
s, &
a->y);
290 secp256k1_fe_sqr(&
l, &
a->x);
291 secp256k1_fe_mul_int(&
l, 3);
292 secp256k1_fe_half(&
l);
293 secp256k1_fe_negate(&t, &
s, 1);
294 secp256k1_fe_mul(&t, &t, &
a->x);
295 secp256k1_fe_sqr(&
r->x, &
l);
296 secp256k1_fe_add(&
r->x, &t);
297 secp256k1_fe_add(&
r->x, &t);
298 secp256k1_fe_sqr(&
s, &
s);
299 secp256k1_fe_add(&t, &
r->x);
300 secp256k1_fe_mul(&
r->y, &t, &
l);
301 secp256k1_fe_add(&
r->y, &
s);
302 secp256k1_fe_negate(&
r->y, &
r->y, 2);
317 secp256k1_gej_set_infinity(
r);
319 secp256k1_fe_set_int(rzr, 1);
326 secp256k1_fe_normalize_weak(rzr);
329 secp256k1_gej_double(
r,
a);
334 secp256k1_fe z22, z12, u1, u2, s1, s2, h, i, h2, h3, t;
343 secp256k1_fe_set_int(rzr, 1);
349 secp256k1_fe_sqr(&z22, &b->
z);
350 secp256k1_fe_sqr(&z12, &
a->z);
351 secp256k1_fe_mul(&u1, &
a->x, &z22);
352 secp256k1_fe_mul(&u2, &b->
x, &z12);
353 secp256k1_fe_mul(&s1, &
a->y, &z22); secp256k1_fe_mul(&s1, &s1, &b->
z);
354 secp256k1_fe_mul(&s2, &b->
y, &z12); secp256k1_fe_mul(&s2, &s2, &
a->z);
355 secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
356 secp256k1_fe_negate(&i, &s2, 1); secp256k1_fe_add(&i, &s1);
357 if (secp256k1_fe_normalizes_to_zero_var(&h)) {
358 if (secp256k1_fe_normalizes_to_zero_var(&i)) {
359 secp256k1_gej_double_var(
r,
a, rzr);
362 secp256k1_fe_set_int(rzr, 0);
364 secp256k1_gej_set_infinity(
r);
370 secp256k1_fe_mul(&t, &h, &b->
z);
374 secp256k1_fe_mul(&
r->z, &
a->z, &t);
376 secp256k1_fe_sqr(&h2, &h);
377 secp256k1_fe_negate(&h2, &h2, 1);
378 secp256k1_fe_mul(&h3, &h2, &h);
379 secp256k1_fe_mul(&t, &u1, &h2);
381 secp256k1_fe_sqr(&
r->x, &i);
382 secp256k1_fe_add(&
r->x, &h3);
383 secp256k1_fe_add(&
r->x, &t);
384 secp256k1_fe_add(&
r->x, &t);
386 secp256k1_fe_add(&t, &
r->x);
387 secp256k1_fe_mul(&
r->y, &t, &i);
388 secp256k1_fe_mul(&h3, &h3, &s1);
389 secp256k1_fe_add(&
r->y, &h3);
397 secp256k1_gej_set_ge(
r, b);
402 secp256k1_fe_set_int(rzr, 1);
408 secp256k1_fe_sqr(&z12, &
a->z);
409 u1 =
a->x; secp256k1_fe_normalize_weak(&u1);
410 secp256k1_fe_mul(&u2, &b->
x, &z12);
411 s1 =
a->y; secp256k1_fe_normalize_weak(&s1);
412 secp256k1_fe_mul(&s2, &b->
y, &z12); secp256k1_fe_mul(&s2, &s2, &
a->z);
413 secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
414 secp256k1_fe_negate(&i, &s2, 1); secp256k1_fe_add(&i, &s1);
415 if (secp256k1_fe_normalizes_to_zero_var(&h)) {
416 if (secp256k1_fe_normalizes_to_zero_var(&i)) {
417 secp256k1_gej_double_var(
r,
a, rzr);
420 secp256k1_fe_set_int(rzr, 0);
422 secp256k1_gej_set_infinity(
r);
431 secp256k1_fe_mul(&
r->z, &
a->z, &h);
433 secp256k1_fe_sqr(&h2, &h);
434 secp256k1_fe_negate(&h2, &h2, 1);
435 secp256k1_fe_mul(&h3, &h2, &h);
436 secp256k1_fe_mul(&t, &u1, &h2);
438 secp256k1_fe_sqr(&
r->x, &i);
439 secp256k1_fe_add(&
r->x, &h3);
440 secp256k1_fe_add(&
r->x, &t);
441 secp256k1_fe_add(&
r->x, &t);
443 secp256k1_fe_add(&t, &
r->x);
444 secp256k1_fe_mul(&
r->y, &t, &i);
445 secp256k1_fe_mul(&h3, &h3, &s1);
446 secp256k1_fe_add(&
r->y, &h3);
451 secp256k1_fe az, z12, u1, u2, s1, s2, h, i, h2, h3, t;
456 secp256k1_fe_sqr(&bzinv2, bzinv);
457 secp256k1_fe_mul(&bzinv3, &bzinv2, bzinv);
458 secp256k1_fe_mul(&
r->x, &b->
x, &bzinv2);
459 secp256k1_fe_mul(&
r->y, &b->
y, &bzinv3);
460 secp256k1_fe_set_int(&
r->z, 1);
476 secp256k1_fe_mul(&az, &
a->z, bzinv);
478 secp256k1_fe_sqr(&z12, &az);
479 u1 =
a->x; secp256k1_fe_normalize_weak(&u1);
480 secp256k1_fe_mul(&u2, &b->
x, &z12);
481 s1 =
a->y; secp256k1_fe_normalize_weak(&s1);
482 secp256k1_fe_mul(&s2, &b->
y, &z12); secp256k1_fe_mul(&s2, &s2, &az);
483 secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2);
484 secp256k1_fe_negate(&i, &s2, 1); secp256k1_fe_add(&i, &s1);
485 if (secp256k1_fe_normalizes_to_zero_var(&h)) {
486 if (secp256k1_fe_normalizes_to_zero_var(&i)) {
487 secp256k1_gej_double_var(
r,
a, NULL);
489 secp256k1_gej_set_infinity(
r);
495 secp256k1_fe_mul(&
r->z, &
a->z, &h);
497 secp256k1_fe_sqr(&h2, &h);
498 secp256k1_fe_negate(&h2, &h2, 1);
499 secp256k1_fe_mul(&h3, &h2, &h);
500 secp256k1_fe_mul(&t, &u1, &h2);
502 secp256k1_fe_sqr(&
r->x, &i);
503 secp256k1_fe_add(&
r->x, &h3);
504 secp256k1_fe_add(&
r->x, &t);
505 secp256k1_fe_add(&
r->x, &t);
507 secp256k1_fe_add(&t, &
r->x);
508 secp256k1_fe_mul(&
r->y, &t, &i);
509 secp256k1_fe_mul(&h3, &h3, &s1);
510 secp256k1_fe_add(&
r->y, &h3);
516 secp256k1_fe zz, u1, u2, s1, s2, t, tt, m, n, q, rr;
518 int infinity, degenerate;
572 secp256k1_fe_sqr(&zz, &
a->z);
573 u1 =
a->x; secp256k1_fe_normalize_weak(&u1);
574 secp256k1_fe_mul(&u2, &b->
x, &zz);
575 s1 =
a->y; secp256k1_fe_normalize_weak(&s1);
576 secp256k1_fe_mul(&s2, &b->
y, &zz);
577 secp256k1_fe_mul(&s2, &s2, &
a->z);
578 t = u1; secp256k1_fe_add(&t, &u2);
579 m = s1; secp256k1_fe_add(&m, &s2);
580 secp256k1_fe_sqr(&rr, &t);
581 secp256k1_fe_negate(&m_alt, &u2, 1);
582 secp256k1_fe_mul(&tt, &u1, &m_alt);
583 secp256k1_fe_add(&rr, &tt);
586 degenerate = secp256k1_fe_normalizes_to_zero(&m) &
587 secp256k1_fe_normalizes_to_zero(&rr);
594 secp256k1_fe_mul_int(&rr_alt, 2);
595 secp256k1_fe_add(&m_alt, &u1);
597 secp256k1_fe_cmov(&rr_alt, &rr, !degenerate);
598 secp256k1_fe_cmov(&m_alt, &m, !degenerate);
603 secp256k1_fe_sqr(&n, &m_alt);
604 secp256k1_fe_negate(&q, &t, 2);
605 secp256k1_fe_mul(&q, &q, &n);
610 secp256k1_fe_sqr(&n, &n);
611 secp256k1_fe_cmov(&n, &m, degenerate);
612 secp256k1_fe_sqr(&t, &rr_alt);
613 secp256k1_fe_mul(&
r->z, &
a->z, &m_alt);
614 infinity = secp256k1_fe_normalizes_to_zero(&
r->z) & ~a->infinity;
615 secp256k1_fe_add(&t, &q);
617 secp256k1_fe_mul_int(&t, 2);
618 secp256k1_fe_add(&t, &q);
619 secp256k1_fe_mul(&t, &t, &rr_alt);
620 secp256k1_fe_add(&t, &n);
621 secp256k1_fe_negate(&
r->y, &t, 3);
622 secp256k1_fe_half(&
r->y);
625 secp256k1_fe_cmov(&
r->x, &b->
x,
a->infinity);
626 secp256k1_fe_cmov(&
r->y, &b->
y,
a->infinity);
627 secp256k1_fe_cmov(&
r->z, &secp256k1_fe_one,
a->infinity);
628 r->infinity = infinity;
635 secp256k1_fe_sqr(&zz,
s);
636 secp256k1_fe_mul(&
r->x, &
r->x, &zz);
637 secp256k1_fe_mul(&
r->y, &
r->y, &zz);
638 secp256k1_fe_mul(&
r->y, &
r->y,
s);
639 secp256k1_fe_mul(&
r->z, &
r->z,
s);
646 secp256k1_fe_normalize(&x);
648 secp256k1_fe_normalize(&y);
649 secp256k1_fe_to_storage(&
r->x, &x);
650 secp256k1_fe_to_storage(&
r->y, &y);
654 secp256k1_fe_from_storage(&
r->x, &
a->x);
655 secp256k1_fe_from_storage(&
r->y, &
a->y);
660 secp256k1_fe_cmov(&
r->x, &
a->x, flag);
661 secp256k1_fe_cmov(&
r->y, &
a->y, flag);
662 secp256k1_fe_cmov(&
r->z, &
a->z, flag);
664 r->infinity ^= (
r->infinity ^
a->infinity) & flag;
668 secp256k1_fe_storage_cmov(&
r->x, &
a->x, flag);
669 secp256k1_fe_storage_cmov(&
r->y, &
a->y, flag);
674 secp256k1_fe_mul(&
r->x, &
r->x, &secp256k1_const_beta);
677static int secp256k1_ge_is_in_correct_subgroup(
const secp256k1_ge* ge) {
678#ifdef EXHAUSTIVE_TEST_ORDER
683 secp256k1_gej_set_infinity(&out);
684 for (i = 0; i < 32; ++i) {
685 secp256k1_gej_double_var(&out, &out, NULL);
687 secp256k1_gej_add_ge_var(&out, &out, ge, NULL);
690 return secp256k1_gej_is_infinity(&out);
#define VERIFY_CHECK(cond)
#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0)
#define SECP256K1_G_ORDER_13
#define SECP256K1_G_ORDER_199
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
#define EXHAUSTIVE_TEST_ORDER