7#ifndef SECP256K1_MODINV64_IMPL_H
8#define SECP256K1_MODINV64_IMPL_H
24static int64_t secp256k1_modinv64_abs(int64_t v) {
34 const int64_t M62 = (int64_t)(UINT64_MAX >> 2);
37 for (i = 0; i < 4; ++i) {
38 if (i < alen) c += (int128_t)a->
v[i] * factor;
39 r->
v[i] = (int64_t)c & M62; c >>= 62;
41 if (4 < alen) c += (int128_t)a->
v[4] * factor;
50 secp256k1_modinv64_mul_62(&am, a, alen, 1);
51 secp256k1_modinv64_mul_62(&bm, b, 5, factor);
52 for (i = 0; i < 4; ++i) {
57 for (i = 4; i >= 0; --i) {
58 if (am.
v[i] < bm.
v[i])
return -1;
59 if (am.
v[i] > bm.
v[i])
return 1;
70 const int64_t M62 = (int64_t)(UINT64_MAX >> 2);
71 int64_t r0 = r->
v[0], r1 = r->
v[1], r2 = r->
v[2], r3 = r->
v[3], r4 = r->
v[4];
72 int64_t cond_add, cond_negate;
77 for (i = 0; i < 5; ++i) {
91 r0 += modinfo->
modulus.
v[0] & cond_add;
92 r1 += modinfo->
modulus.
v[1] & cond_add;
93 r2 += modinfo->
modulus.
v[2] & cond_add;
94 r3 += modinfo->
modulus.
v[3] & cond_add;
95 r4 += modinfo->
modulus.
v[4] & cond_add;
96 cond_negate = sign >> 63;
97 r0 = (r0 ^ cond_negate) - cond_negate;
98 r1 = (r1 ^ cond_negate) - cond_negate;
99 r2 = (r2 ^ cond_negate) - cond_negate;
100 r3 = (r3 ^ cond_negate) - cond_negate;
101 r4 = (r4 ^ cond_negate) - cond_negate;
103 r1 += r0 >> 62; r0 &= M62;
104 r2 += r1 >> 62; r1 &= M62;
105 r3 += r2 >> 62; r2 &= M62;
106 r4 += r3 >> 62; r3 &= M62;
111 r0 += modinfo->
modulus.
v[0] & cond_add;
112 r1 += modinfo->
modulus.
v[1] & cond_add;
113 r2 += modinfo->
modulus.
v[2] & cond_add;
114 r3 += modinfo->
modulus.
v[3] & cond_add;
115 r4 += modinfo->
modulus.
v[4] & cond_add;
117 r1 += r0 >> 62; r0 &= M62;
118 r2 += r1 >> 62; r1 &= M62;
119 r3 += r2 >> 62; r2 &= M62;
120 r4 += r3 >> 62; r3 &= M62;
165 uint64_t u = 1, v = 0, q = 0, r = 1;
166 uint64_t c1, c2, f = f0, g = g0, x, y, z;
169 for (i = 0; i < 62; ++i) {
187 eta = (eta ^ c1) - (c1 + 1);
208 VERIFY_CHECK((int128_t)t->
u * t->
r - (int128_t)t->
v * t->
q == ((int128_t)1) << 62);
224 uint64_t u = 1, v = 0, q = 0, r = 1;
225 uint64_t f = f0, g = g0, m;
227 int i = 62, limit, zeros;
250 tmp = f; f = g; g = -tmp;
251 tmp = u; u = q; q = -tmp;
252 tmp = v; v = r; r = -tmp;
256 limit = ((int)eta + 1) > i ? i : ((int)eta + 1);
259 m = (UINT64_MAX >> (64 - limit)) & 63U;
262 w = (f * g * (f * f - 2)) & m;
266 limit = ((int)eta + 1) > i ? i : ((int)eta + 1);
269 m = (UINT64_MAX >> (64 - limit)) & 15U;
272 w = f + (((f + 1) & 4) << 1);
289 VERIFY_CHECK((int128_t)t->
u * t->
r - (int128_t)t->
v * t->
q == ((int128_t)1) << 62);
301 const int64_t M62 = (int64_t)(UINT64_MAX >> 2);
302 const int64_t d0 = d->
v[0], d1 = d->
v[1], d2 = d->
v[2], d3 = d->
v[3], d4 = d->
v[4];
303 const int64_t e0 = e->
v[0], e1 = e->
v[1], e2 = e->
v[2], e3 = e->
v[3], e4 = e->
v[4];
304 const int64_t u = t->
u, v = t->
v, q = t->
q, r = t->
r;
305 int64_t md, me, sd, se;
312 VERIFY_CHECK((secp256k1_modinv64_abs(u) + secp256k1_modinv64_abs(v)) >= 0);
313 VERIFY_CHECK((secp256k1_modinv64_abs(q) + secp256k1_modinv64_abs(r)) >= 0);
314 VERIFY_CHECK((secp256k1_modinv64_abs(u) + secp256k1_modinv64_abs(v)) <= M62 + 1);
315 VERIFY_CHECK((secp256k1_modinv64_abs(q) + secp256k1_modinv64_abs(r)) <= M62 + 1);
320 md = (u & sd) + (v & se);
321 me = (q & sd) + (r & se);
323 cd = (int128_t)u * d0 + (int128_t)v * e0;
324 ce = (int128_t)q * d0 + (int128_t)r * e0;
329 cd += (int128_t)modinfo->
modulus.
v[0] * md;
330 ce += (int128_t)modinfo->
modulus.
v[0] * me;
335 cd += (int128_t)u * d1 + (int128_t)v * e1;
336 ce += (int128_t)q * d1 + (int128_t)r * e1;
338 cd += (int128_t)modinfo->
modulus.
v[1] * md;
339 ce += (int128_t)modinfo->
modulus.
v[1] * me;
341 d->
v[0] = (int64_t)cd & M62; cd >>= 62;
342 e->
v[0] = (int64_t)ce & M62; ce >>= 62;
344 cd += (int128_t)u * d2 + (int128_t)v * e2;
345 ce += (int128_t)q * d2 + (int128_t)r * e2;
347 cd += (int128_t)modinfo->
modulus.
v[2] * md;
348 ce += (int128_t)modinfo->
modulus.
v[2] * me;
350 d->
v[1] = (int64_t)cd & M62; cd >>= 62;
351 e->
v[1] = (int64_t)ce & M62; ce >>= 62;
353 cd += (int128_t)u * d3 + (int128_t)v * e3;
354 ce += (int128_t)q * d3 + (int128_t)r * e3;
356 cd += (int128_t)modinfo->
modulus.
v[3] * md;
357 ce += (int128_t)modinfo->
modulus.
v[3] * me;
359 d->
v[2] = (int64_t)cd & M62; cd >>= 62;
360 e->
v[2] = (int64_t)ce & M62; ce >>= 62;
362 cd += (int128_t)u * d4 + (int128_t)v * e4;
363 ce += (int128_t)q * d4 + (int128_t)r * e4;
364 cd += (int128_t)modinfo->
modulus.
v[4] * md;
365 ce += (int128_t)modinfo->
modulus.
v[4] * me;
366 d->
v[3] = (int64_t)cd & M62; cd >>= 62;
367 e->
v[3] = (int64_t)ce & M62; ce >>= 62;
369 d->
v[4] = (int64_t)cd;
370 e->
v[4] = (int64_t)ce;
384 const int64_t M62 = (int64_t)(UINT64_MAX >> 2);
385 const int64_t f0 = f->
v[0], f1 = f->
v[1], f2 = f->
v[2], f3 = f->
v[3], f4 = f->
v[4];
386 const int64_t g0 = g->
v[0], g1 = g->
v[1], g2 = g->
v[2], g3 = g->
v[3], g4 = g->
v[4];
387 const int64_t u = t->
u, v = t->
v, q = t->
q, r = t->
r;
390 cf = (int128_t)u * f0 + (int128_t)v * g0;
391 cg = (int128_t)q * f0 + (int128_t)r * g0;
396 cf += (int128_t)u * f1 + (int128_t)v * g1;
397 cg += (int128_t)q * f1 + (int128_t)r * g1;
398 f->
v[0] = (int64_t)cf & M62; cf >>= 62;
399 g->
v[0] = (int64_t)cg & M62; cg >>= 62;
401 cf += (int128_t)u * f2 + (int128_t)v * g2;
402 cg += (int128_t)q * f2 + (int128_t)r * g2;
403 f->
v[1] = (int64_t)cf & M62; cf >>= 62;
404 g->
v[1] = (int64_t)cg & M62; cg >>= 62;
406 cf += (int128_t)u * f3 + (int128_t)v * g3;
407 cg += (int128_t)q * f3 + (int128_t)r * g3;
408 f->
v[2] = (int64_t)cf & M62; cf >>= 62;
409 g->
v[2] = (int64_t)cg & M62; cg >>= 62;
411 cf += (int128_t)u * f4 + (int128_t)v * g4;
412 cg += (int128_t)q * f4 + (int128_t)r * g4;
413 f->
v[3] = (int64_t)cf & M62; cf >>= 62;
414 g->
v[3] = (int64_t)cg & M62; cg >>= 62;
416 f->
v[4] = (int64_t)cf;
417 g->
v[4] = (int64_t)cg;
427 const int64_t M62 = (int64_t)(UINT64_MAX >> 2);
428 const int64_t u = t->
u, v = t->
v, q = t->
q, r = t->
r;
436 cf = (int128_t)u * fi + (int128_t)v * gi;
437 cg = (int128_t)q * fi + (int128_t)r * gi;
443 for (i = 1; i < len; ++i) {
446 cf += (int128_t)u * fi + (int128_t)v * gi;
447 cg += (int128_t)q * fi + (int128_t)r * gi;
448 f->
v[i - 1] = (int64_t)cf & M62; cf >>= 62;
449 g->
v[i - 1] = (int64_t)cg & M62; cg >>= 62;
452 f->
v[len - 1] = (int64_t)cf;
453 g->
v[len - 1] = (int64_t)cg;
467 for (i = 0; i < 12; ++i) {
494 VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, 5, &SECP256K1_SIGNED62_ONE, 0) == 0);
496 VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, 5, &SECP256K1_SIGNED62_ONE, -1) == 0 ||
497 secp256k1_modinv64_mul_cmp_62(&f, 5, &SECP256K1_SIGNED62_ONE, 1) == 0 ||
498 (secp256k1_modinv64_mul_cmp_62(x, 5, &SECP256K1_SIGNED62_ONE, 0) == 0 &&
499 secp256k1_modinv64_mul_cmp_62(&d, 5, &SECP256K1_SIGNED62_ONE, 0) == 0 &&
500 (secp256k1_modinv64_mul_cmp_62(&f, 5, &modinfo->
modulus, 1) == 0 ||
501 secp256k1_modinv64_mul_cmp_62(&f, 5, &modinfo->
modulus, -1) == 0)));
521 int64_t cond, fn, gn;
542 for (j = 1; j < len; ++j) {
546 if (cond == 0)
break;
552 cond = ((int64_t)len - 2) >> 63;
553 cond |= fn ^ (fn >> 63);
554 cond |= gn ^ (gn >> 63);
557 f.
v[len - 2] |= (uint64_t)fn << 62;
558 g.
v[len - 2] |= (uint64_t)gn << 62;
574 VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&g, len, &SECP256K1_SIGNED62_ONE, 0) == 0);
576 VERIFY_CHECK(secp256k1_modinv64_mul_cmp_62(&f, len, &SECP256K1_SIGNED62_ONE, -1) == 0 ||
577 secp256k1_modinv64_mul_cmp_62(&f, len, &SECP256K1_SIGNED62_ONE, 1) == 0 ||
578 (secp256k1_modinv64_mul_cmp_62(x, 5, &SECP256K1_SIGNED62_ONE, 0) == 0 &&
579 secp256k1_modinv64_mul_cmp_62(&d, 5, &SECP256K1_SIGNED62_ONE, 0) == 0 &&
580 (secp256k1_modinv64_mul_cmp_62(&f, len, &modinfo->
modulus, 1) == 0 ||
581 secp256k1_modinv64_mul_cmp_62(&f, len, &modinfo->
modulus, -1) == 0)));
static int64_t secp256k1_modinv64_divsteps_62_var(int64_t eta, uint64_t f0, uint64_t g0, secp256k1_modinv64_trans2x2 *t)
static void secp256k1_modinv64_normalize_62(secp256k1_modinv64_signed62 *r, int64_t sign, const secp256k1_modinv64_modinfo *modinfo)
static void secp256k1_modinv64(secp256k1_modinv64_signed62 *x, const secp256k1_modinv64_modinfo *modinfo)
static void secp256k1_modinv64_var(secp256k1_modinv64_signed62 *x, const secp256k1_modinv64_modinfo *modinfo)
static void secp256k1_modinv64_update_fg_62_var(int len, secp256k1_modinv64_signed62 *f, secp256k1_modinv64_signed62 *g, const secp256k1_modinv64_trans2x2 *t)
static void secp256k1_modinv64_update_fg_62(secp256k1_modinv64_signed62 *f, secp256k1_modinv64_signed62 *g, const secp256k1_modinv64_trans2x2 *t)
static int64_t secp256k1_modinv64_divsteps_62(int64_t eta, uint64_t f0, uint64_t g0, secp256k1_modinv64_trans2x2 *t)
static void secp256k1_modinv64_update_de_62(secp256k1_modinv64_signed62 *d, secp256k1_modinv64_signed62 *e, const secp256k1_modinv64_trans2x2 *t, const secp256k1_modinv64_modinfo *modinfo)
static SECP256K1_INLINE int secp256k1_ctz64_var(uint64_t x)
#define VERIFY_CHECK(cond)
secp256k1_modinv64_signed62 modulus