25 #ifndef CRYPTO3_VDF_CHIA_FUNCTIONS_HPP
26 #define CRYPTO3_VDF_CHIA_FUNCTIONS_HPP
40 #if defined(CRYPTO3_VDF_GMP) || defined(CRYPTO3_VDF_MPIR)
49 bool bleqa = (mpz_cmp(state.
form.
b, state.
form.
a) <= 0);
51 if (mpz_cmp(state.
form.
b, state.
form.
a) > 0 && bleqa) {
58 mpz_mul_si(state.
ra, state.
form.
a, -3);
59 bool falb = (mpz_cmp(state.
ra, state.
form.
b) < 0);
61 mpz_mul_2exp(state.
ra, state.
form.
a, 1);
63 if (mpz_cmp(state.
r, state.
ra) >= 0 && falb) {
71 mpz_fdiv_q(state.
r, state.
r, state.
ra);
72 mpz_mul(state.
ra, state.
r, state.
form.
a);
73 mpz_addmul(state.
form.
c, state.
ra, state.
r);
75 mpz_mul_2exp(state.
ra, state.
ra, 1);
88 int a_b = mpz_cmpabs(f.
a, f.
b);
89 int c_b = mpz_cmpabs(f.
c, f.
b);
91 if (a_b < 0 || c_b < 0) {
95 int a_c = mpz_cmp(f.
a, f.
c);
102 if (a_c == 0 && mpz_sgn(f.
b) < 0) {
110 inline static void fast_reduce(state_type<T> &state) {
112 int64_t u, v, w, x, u_, v_, w_, x_;
113 int64_t delta, gamma,
sgn;
114 int64_t a, b, c, a_, b_, c_;
115 int64_t aa, ab, ac, ba, bb, bc, ca, cb, cc;
116 signed long int a_exp, b_exp, c_exp, max_exp, min_exp;
118 while (!test_reduction(state.form)) {
120 a = mpz_get_si_2exp(&a_exp, state.form.a);
121 b = mpz_get_si_2exp(&b_exp, state.form.b);
122 c = mpz_get_si_2exp(&c_exp, state.form.c);
127 if (max_exp < b_exp) {
130 if (min_exp > b_exp) {
134 if (max_exp < c_exp) {
137 if (min_exp > c_exp) {
150 a >>= (max_exp - a_exp);
151 b >>= (max_exp - b_exp);
152 c >>= (max_exp - c_exp);
166 delta = b >= 0 ? (b + c) / (c << 1) : -(-b + c) / (c << 1);
171 c_ = a - delta * gamma;
203 mpz_mul_si(state.faa, state.form.a, aa);
204 mpz_mul_si(state.fab, state.form.b, ab);
205 mpz_mul_si(state.fac, state.form.c, ac);
207 mpz_mul_si(state.fba, state.form.a, ba);
208 mpz_mul_si(state.fbb, state.form.b, bb);
209 mpz_mul_si(state.fbc, state.form.c, bc);
211 mpz_mul_si(state.fca, state.form.a, ca);
212 mpz_mul_si(state.fcb, state.form.b, cb);
213 mpz_mul_si(state.fcc, state.form.c, cc);
215 mpz_add(state.form.a, state.faa, state.fab);
216 mpz_add(state.form.a, state.form.a, state.fac);
218 mpz_add(state.form.b, state.fba, state.fbb);
219 mpz_add(state.form.b, state.form.b, state.fbc);
221 mpz_add(state.form.c, state.fca, state.fcb);
222 mpz_add(state.form.c, state.form.c, state.fcc);
227 inline static long mpz_bits(I x) {
228 if (x->_mp_size == 0) {
231 return mpz_sizeinbase(x, 2);
234 inline static void mpz_addmul_si(mpz_t r, mpz_t x,
long u) {
236 mpz_addmul_ui(r, x, u);
238 mpz_submul_ui(r, x, -u);
242 inline static uint64_t signed_shift(uint64_t op,
int shift) {
249 return op >> (-shift);
254 inline static int64_t mpz_get_si_2exp(
signed long int *exp,
const mpz_t op) {
255 uint64_t size = mpz_size(op);
256 uint64_t last = mpz_getlimbn(op, size - 1);
258 int lg2 =
LOG2(last) + 1;
260 ret = signed_shift(last, 63 - *exp);
262 *exp += (size - 1) * 64;
263 uint64_t prev = mpz_getlimbn(op, size - 2);
264 ret += signed_shift(prev, -1 - lg2);
266 if (mpz_sgn(op) < 0) {
267 return -((int64_t)ret);
273 static void mpz_xgcd_partial(state_type<T> &state) {
274 mp_limb_signed_t aa2, aa1, bb2, bb1, rr1, rr2, qq, bb, t1, t2, t3, i;
275 mp_limb_signed_t bits, bits1, bits2;
277 mpz_set_si(state.y, 0);
278 mpz_set_si(state.x, -1);
280 while (*state.bx->_mp_d != 0 && mpz_cmp(state.bx, state.L) > 0) {
281 bits2 = mpz_bits(state.by);
282 bits1 = mpz_bits(state.bx);
283 bits = __GMP_MAX(bits2, bits1) - GMP_LIMB_BITS + 1;
288 mpz_tdiv_q_2exp(state.r, state.by, bits);
289 rr2 = mpz_get_ui(state.r);
290 mpz_tdiv_q_2exp(state.r, state.bx, bits);
291 rr1 = mpz_get_ui(state.r);
292 mpz_tdiv_q_2exp(state.r, state.L, bits);
293 bb = mpz_get_ui(state.r);
301 for (i = 0; rr1 != 0 && rr1 > bb; i++) {
309 if (t1 < -t3 || rr1 - t1 < t2 - aa1) {
313 if (t1 < -t2 || rr1 - t1 < t3 - bb1) {
327 mpz_fdiv_qr(state.ra, state.by, state.by, state.bx);
328 mpz_swap(state.by, state.bx);
330 mpz_submul(state.y, state.x, state.ra);
331 mpz_swap(state.y, state.x);
333 mpz_mul_si(state.r, state.by, bb2);
335 mpz_addmul_ui(state.r, state.bx, aa2);
337 mpz_submul_ui(state.r, state.bx, -aa2);
339 mpz_mul_si(state.bx, state.bx, aa1);
341 mpz_addmul_ui(state.bx, state.by, bb1);
343 mpz_submul_ui(state.bx, state.by, -bb1);
345 mpz_set(state.by, state.r);
347 mpz_mul_si(state.r, state.y, bb2);
349 mpz_addmul_ui(state.r, state.x, aa2);
351 mpz_submul_ui(state.r, state.x, -aa2);
353 mpz_mul_si(state.x, state.x, aa1);
355 mpz_addmul_ui(state.x, state.y, bb1);
357 mpz_submul_ui(state.x, state.y, -bb1);
359 mpz_set(state.y, state.r);
361 if (mpz_sgn(state.bx) < 0) {
362 mpz_neg(state.x, state.x);
363 mpz_neg(state.bx, state.bx);
365 if (mpz_sgn(state.by) < 0) {
366 mpz_neg(state.y, state.y);
367 mpz_neg(state.by, state.by);
372 if (mpz_sgn(state.by) < 0) {
373 mpz_neg(state.y, state.y);
374 mpz_neg(state.x, state.x);
375 mpz_neg(state.by, state.by);
381 static void nudupl(state_type<T> &state) {
383 mpz_gcdext(state.G, state.y, NULL, state.form.b, state.form.a);
385 #if defined(CRYPTO3_VDF_GMP)
387 mpz_divexact(state.By, state.form.a, state.G);
388 mpz_divexact(state.Dy, state.form.b, state.G);
390 #elif defined(CRYPTO3_VDF_MPIR)
392 mpz_divexact_gcd(state.By, state.form.a, state.G);
393 mpz_divexact_gcd(state.Dy, state.form.b, state.G);
397 mpz_mul(state.bx, state.y, state.form.c);
398 mpz_mod(state.bx, state.bx, state.By);
400 mpz_set(state.by, state.By);
402 if (mpz_cmpabs(state.by, state.L) <= 0) {
403 mpz_mul(state.dx, state.bx, state.Dy);
404 mpz_sub(state.dx, state.dx, state.form.c);
405 mpz_divexact(state.dx, state.dx, state.By);
406 mpz_mul(state.form.a, state.by, state.by);
407 mpz_mul(state.form.c, state.bx, state.bx);
408 mpz_add(state.t, state.bx, state.by);
409 mpz_mul(state.t, state.t, state.t);
410 mpz_sub(state.form.b, state.form.b, state.t);
411 mpz_add(state.form.b, state.form.b, state.form.a);
412 mpz_add(state.form.b, state.form.b, state.form.c);
413 mpz_mul(state.t, state.G, state.dx);
414 mpz_sub(state.form.c, state.form.c, state.t);
418 mpz_xgcd_partial(state);
420 mpz_neg(state.x, state.x);
421 if (mpz_sgn((state.x)) > 0) {
422 mpz_neg(state.y, state.y);
424 mpz_neg(state.by, state.by);
427 mpz_mul(state.ax, state.G, state.x);
428 mpz_mul(state.ay, state.G, state.y);
430 mpz_mul(state.t, state.Dy, state.bx);
431 mpz_submul(state.t, state.form.c, state.x);
432 mpz_divexact(state.dx, state.t, state.By);
433 mpz_mul(state.Q1, state.y, state.dx);
434 mpz_add(state.dy, state.Q1, state.Dy);
435 mpz_add(state.form.b, state.dy, state.Q1);
436 mpz_mul(state.form.b, state.form.b, state.G);
437 mpz_divexact(state.dy, state.dy, state.x);
438 mpz_mul(state.form.a, state.by, state.by);
439 mpz_mul(state.form.c, state.bx, state.bx);
440 mpz_add(state.t, state.bx, state.by);
441 mpz_submul(state.form.b, state.t, state.t);
442 mpz_add(state.form.b, state.form.b, state.form.a);
443 mpz_add(state.form.b, state.form.b, state.form.c);
444 mpz_submul(state.form.a, state.ay, state.dy);
445 mpz_submul(state.form.c, state.ax, state.dx);
449 static inline void discriminant_generator(state_type<T> &state,
const T &d) {
452 mpz_set_ui(state.form.a, 2);
453 mpz_set_ui(state.form.b, 1);
454 mpz_set_ui(state.form.b, 1);
455 mpz_mul(state.form.c, state.form.b, state.form.b);
456 mpz_sub(state.form.c, state.form.c, d);
457 mpz_mul_ui(denom, state.form.a, 4);
458 mpz_fdiv_q(state.form.c, state.form.c, denom);
463 #elif defined(CRYPTO3_VDF_FLINT)
471 inline static void normalize(state_type<T> &state) {
472 fmpz_neg(state.r, state.form.a);
473 if (fmpz_cmp(state.form.b, state.r) > 0 && fmpz_cmp(state.form.b, state.form.a) <= 0) {
477 fmpz_sub(state.r, state.form.a, state.form.b);
478 fmpz_mul_2exp(state.ra, state.form.a, 1);
479 fmpz_fdiv_q(state.r, state.r, state.ra);
480 fmpz_mul(state.ra, state.r, state.form.a);
481 fmpz_addmul(state.form.c, state.ra, state.r);
482 fmpz_addmul(state.form.c, state.r, state.form.b);
483 fmpz_mul_2exp(state.ra, state.ra, 1);
484 fmpz_add(state.form.b, state.form.b, state.ra);
495 inline static bool test_reduction(binary_quadratic_form<T> &f) {
496 int a_b = fmpz_cmpabs(f.a, f.b);
497 int c_b = fmpz_cmpabs(f.c, f.b);
499 if (a_b < 0 || c_b < 0) {
503 int a_c = fmpz_cmp(f.a, f.c);
510 if (a_c == 0 && fmpz_sgn(f.b) < 0) {
523 inline static void reduce(state_type<T> &state) {
526 while (((cmp = fmpz_cmp(state.form.a, state.form.c)) > 0) ||
527 (cmp == 0 && fmpz_sgn(state.form.b) < 0)) {
528 fmpz_add(state.s, state.form.c, state.form.b);
531 fmpz_mul_2exp(state.p, state.form.c, 1);
532 fmpz_fdiv_q(state.s, state.s, state.p);
534 fmpz_set(state.previous_form.a, state.form.a);
535 fmpz_set(state.previous_form.b, state.form.b);
538 fmpz_set(state.form.a, state.form.c);
539 fmpz_neg(state.form.b, state.form.b);
542 fmpz_mul(state.p, state.s, state.form.c);
543 fmpz_mul_2exp(state.p, state.p, 1);
546 fmpz_add(state.form.b, state.form.b, state.p);
549 fmpz_mul(state.p, state.previous_form.b, state.s);
552 fmpz_mul(state.s, state.s, state.s);
555 fmpz_mul(state.form.c, state.form.c, state.s);
558 fmpz_sub(state.form.c, state.form.c, state.p);
561 fmpz_add(state.form.c, state.form.c, state.previous_form.a);
567 inline static void fast_reduce(state_type<T> &state) {
569 int64_t u, v, w, x, u_, v_, w_, x_;
570 int64_t delta, gamma,
sgn;
571 int64_t a, b, c, a_, b_, c_;
572 int64_t aa, ab, ac, ba, bb, bc, ca, cb, cc;
573 signed long int a_exp, b_exp, c_exp, max_exp, min_exp;
575 while (!test_reduction(state.form)) {
577 a = fmpz_get_si_2exp(&a_exp, state.form.a);
578 b = fmpz_get_si_2exp(&b_exp, state.form.b);
579 c = fmpz_get_si_2exp(&c_exp, state.form.c);
584 if (max_exp < b_exp) {
587 if (min_exp > b_exp) {
591 if (max_exp < c_exp) {
594 if (min_exp > c_exp) {
607 a >>= (max_exp - a_exp);
608 b >>= (max_exp - b_exp);
609 c >>= (max_exp - c_exp);
623 delta = b >= 0 ? (b + c) / (c << 1) : -(-b + c) / (c << 1);
628 c_ = a - delta * gamma;
660 fmpz_mul_si(state.faa, state.form.a, aa);
661 fmpz_mul_si(state.fab, state.form.b, ab);
662 fmpz_mul_si(state.fac, state.form.c, ac);
664 fmpz_mul_si(state.fba, state.form.a, ba);
665 fmpz_mul_si(state.fbb, state.form.b, bb);
666 fmpz_mul_si(state.fbc, state.form.c, bc);
668 fmpz_mul_si(state.fca, state.form.a, ca);
669 fmpz_mul_si(state.fcb, state.form.b, cb);
670 fmpz_mul_si(state.fcc, state.form.c, cc);
672 fmpz_add(state.form.a, state.faa, state.fab);
673 fmpz_add(state.form.a, state.form.a, state.fac);
675 fmpz_add(state.form.b, state.fba, state.fbb);
676 fmpz_add(state.form.b, state.form.b, state.fbc);
678 fmpz_add(state.form.c, state.fca, state.fcb);
679 fmpz_add(state.form.c, state.form.c, state.fcc);
684 inline static long fmpz_bits(I x) {
685 if (x->_mp_size == 0) {
688 return fmpz_sizeinbase(x, 2);
691 inline static void fmpz_addmul_si(fmpz_t r, fmpz_t x,
long u) {
693 fmpz_addmul_ui(r, x, u);
695 fmpz_submul_ui(r, x, -u);
699 inline static uint64_t signed_shift(uint64_t op,
int shift) {
706 return op >> (-shift);
711 inline static int64_t fmpz_get_si_2exp(
signed long int *exp,
const fmpz_t op) {
712 uint64_t size = fmpz_size(op);
713 uint64_t last = op[size - 1];
715 int lg2 =
LOG2(last) + 1;
717 ret = signed_shift(last, 63 - *exp);
719 *exp += (size - 1) * 64;
720 uint64_t prev = op[size - 2];
721 ret += signed_shift(prev, -1 - lg2);
723 if (fmpz_sgn(op) < 0) {
724 return -((int64_t)ret);
731 void fast_gcdinv(fmpz_t g, fmpz_t x,
const fmpz_t a,
const fmpz_t n) {
732 int ret = fmpz_invmod(x, a, n);
738 fmpz_gcdinv(g, x, a, n);
743 static void nudupl(state_type<T> &state) {
745 fmpz_xgcd(state.G, state.y, NULL, state.form.b, state.form.a);
747 fmpz_divexact(state.By, state.form.a, state.G);
748 fmpz_divexact(state.Dy, state.form.b, state.G);
750 fmpz_mul(state.bx, state.y, state.form.c);
751 fmpz_mod(state.bx, state.bx, state.By);
753 fmpz_set(state.by, state.By);
755 if (fmpz_cmpabs(state.by, state.L) <= 0) {
756 fmpz_mul(state.dx, state.bx, state.Dy);
757 fmpz_sub(state.dx, state.dx, state.form.c);
758 fmpz_divexact(state.dx, state.dx, state.By);
759 fmpz_mul(state.form.a, state.by, state.by);
760 fmpz_mul(state.form.c, state.bx, state.bx);
761 fmpz_add(state.t, state.bx, state.by);
762 fmpz_mul(state.t, state.t, state.t);
763 fmpz_sub(state.form.b, state.form.b, state.t);
764 fmpz_add(state.form.b, state.form.b, state.form.a);
765 fmpz_add(state.form.b, state.form.b, state.form.c);
766 fmpz_mul(state.t, state.G, state.dx);
767 fmpz_sub(state.form.c, state.form.c, state.t);
771 fmpz_xgcd_partial(state.y, state.x, state.by, state.bx, state.L);
773 fmpz_neg(state.x, state.x);
774 if (fmpz_sgn((state.x)) > 0) {
775 fmpz_neg(state.y, state.y);
777 fmpz_neg(state.by, state.by);
780 fmpz_mul(state.ax, state.G, state.x);
781 fmpz_mul(state.ay, state.G, state.y);
783 fmpz_mul(state.t, state.Dy, state.bx);
784 fmpz_submul(state.t, state.form.c, state.x);
785 fmpz_divexact(state.dx, state.t, state.By);
786 fmpz_mul(state.Q1, state.y, state.dx);
787 fmpz_add(state.dy, state.Q1, state.Dy);
788 fmpz_add(state.form.b, state.dy, state.Q1);
789 fmpz_mul(state.form.b, state.form.b, state.G);
790 fmpz_divexact(state.dy, state.dy, state.x);
791 fmpz_mul(state.form.a, state.by, state.by);
792 fmpz_mul(state.form.c, state.bx, state.bx);
793 fmpz_add(state.t, state.bx, state.by);
794 fmpz_submul(state.form.b, state.t, state.t);
795 fmpz_add(state.form.b, state.form.b, state.form.a);
796 fmpz_add(state.form.b, state.form.b, state.form.c);
797 fmpz_submul(state.form.a, state.ay, state.dy);
798 fmpz_submul(state.form.c, state.ax, state.dx);
802 static inline void discriminant_generator(state_type<T> &state,
const T &d) {
805 fmpz_set_ui(state.form.a, 2);
806 fmpz_set_ui(state.form.b, 1);
807 fmpz_mul(state.form.c, state.form.b, state.form.b);
808 fmpz_sub(state.form.c, state.form.c, d);
809 fmpz_mul_ui(denom, state.form.a, 4);
810 fmpz_fdiv_q(state.form.c, state.form.c, denom);
815 #elif defined(CRYPTO3_VDF_BOOST)
818 inline static void normalize(state_type<T> &state) {
819 bool bleqa = (state.form.b <= state.forma.a);
820 state.form.a = -state.form.a;
821 if (state.form.b > state.form.a && bleqa) {
825 state.form.a = -state.form.a;
826 state.r = state.form.a - state.form.b;
828 state.ra = state.form.a * -3;
829 bool falb = (state.ra < state.form.b < 0);
831 state.ra = state.form.a << 1;
833 if (state.r >= state.ra && falb) {
834 state.form.c += state.form.a + state.form.b;
835 state.form.b += state.ra;
840 state.r = state.r / state.ra;
841 state.ra = state.r * state.form.a;
842 state.form.c += state.ra * state.r;
843 state.form.c += state.r * state.form.b;
845 state.form.b += state.ra;
856 inline static bool test_reduction(binary_quadratic_form<T> &f) {
857 int a_b = mpz_cmpabs(f.a, f.b);
858 int c_b = mpz_cmpabs(f.c, f.b);
860 if (a_b < 0 || c_b < 0) {
864 int a_c = mpz_cmp(f.a, f.c);
871 if (a_c == 0 && mpz_sgn(f.b) < 0) {
879 inline static void fast_reduce(state_type<T> &state) {
881 int64_t u, v, w, x, u_, v_, w_, x_;
882 int64_t delta, gamma,
sgn;
883 int64_t a, b, c, a_, b_, c_;
884 int64_t aa, ab, ac, ba, bb, bc, ca, cb, cc;
885 signed long int a_exp, b_exp, c_exp, max_exp, min_exp;
887 while (!test_reduction(state.form)) {
889 a = mpz_get_si_2exp(&a_exp, state.form.a);
890 b = mpz_get_si_2exp(&b_exp, state.form.b);
891 c = mpz_get_si_2exp(&c_exp, state.form.c);
896 if (max_exp < b_exp) {
899 if (min_exp > b_exp) {
903 if (max_exp < c_exp) {
906 if (min_exp > c_exp) {
919 a >>= (max_exp - a_exp);
920 b >>= (max_exp - b_exp);
921 c >>= (max_exp - c_exp);
935 delta = b >= 0 ? (b + c) / (c << 1) : -(-b + c) / (c << 1);
940 c_ = a - delta * gamma;
972 state.faa = state.form.a * aa;
973 state.fab = state.form.b * ab;
974 state.fac = state.form.c * ac;
976 state.fba = state.form.a * ba;
977 state.fbb = state.form.b * bb;
978 state.fbc = state.form.c * bc;
980 state.fca = state.form.a * ca;
981 state.fcb = state.form.b * cb;
982 state.fcc = state.form.c * cc;
984 state.form.a = state.faa + state.fab + state.fac;
985 state.form.b = state.fba + state.fbb + state.fbc;
986 state.form.c = state.fca + state.fcb + state.fcc;
990 template<
typename Backend, expression_
template_option ExpressionTemplates>
991 inline static long mpz_bits(number<Backend, ExpressionTemplates> x) {
992 if (x->_mp_size == 0) {
995 return mpz_sizeinbase(x, 2);
998 inline static uint64_t signed_shift(uint64_t op,
int shift) {
1005 return op >> (-shift);
1010 template<
typename Backend, expression_
template_option ExpressionTemplates>
1011 inline static int64_t mpz_get_si_2exp(
signed long int *exp,
1012 const number<Backend, ExpressionTemplates> &op) {
1013 uint64_t size = mpz_size(op);
1014 uint64_t last = mpz_getlimbn(op, size - 1);
1016 int lg2 =
LOG2(last) + 1;
1018 ret = signed_shift(last, 63 - *exp);
1020 *exp += (size - 1) * 64;
1021 uint64_t prev = mpz_getlimbn(op, size - 2);
1022 ret += signed_shift(prev, -1 - lg2);
1024 if (mpz_sgn(op) < 0) {
1025 return -((int64_t)ret);
1030 template<
typename T>
1031 static void mpz_xgcd_partial(state_type<T> &state) {
1032 mp_limb_signed_t aa2, aa1, bb2, bb1, rr1, rr2, qq, bb, t1, t2, t3, i;
1033 mp_limb_signed_t bits, bits1, bits2;
1035 mpz_set_si(state.y, 0);
1036 mpz_set_si(state.x, -1);
1038 while (*state.bx->_mp_d != 0 && mpz_cmp(state.bx, state.L) > 0) {
1039 bits2 = mpz_bits(state.by);
1040 bits1 = mpz_bits(state.bx);
1041 bits = __GMP_MAX(bits2, bits1) - GMP_LIMB_BITS + 1;
1046 mpz_tdiv_q_2exp(state.r, state.by, bits);
1047 rr2 = mpz_get_ui(state.r);
1048 mpz_tdiv_q_2exp(state.r, state.bx, bits);
1049 rr1 = mpz_get_ui(state.r);
1050 mpz_tdiv_q_2exp(state.r, state.L, bits);
1051 bb = mpz_get_ui(state.r);
1059 for (i = 0; rr1 != 0 && rr1 > bb; i++) {
1062 t1 = rr2 - qq * rr1;
1063 t2 = aa2 - qq * aa1;
1064 t3 = bb2 - qq * bb1;
1067 if (t1 < -t3 || rr1 - t1 < t2 - aa1) {
1071 if (t1 < -t2 || rr1 - t1 < t3 - bb1) {
1085 mpz_fdiv_qr(state.ra, state.by, state.by, state.bx);
1086 mpz_swap(state.by, state.bx);
1088 mpz_submul(state.y, state.x, state.ra);
1089 mpz_swap(state.y, state.x);
1091 mpz_mul_si(state.r, state.by, bb2);
1093 mpz_addmul_ui(state.r, state.bx, aa2);
1095 mpz_submul_ui(state.r, state.bx, -aa2);
1097 mpz_mul_si(state.bx, state.bx, aa1);
1099 mpz_addmul_ui(state.bx, state.by, bb1);
1101 mpz_submul_ui(state.bx, state.by, -bb1);
1103 mpz_set(state.by, state.r);
1105 mpz_mul_si(state.r, state.y, bb2);
1107 mpz_addmul_ui(state.r, state.x, aa2);
1109 mpz_submul_ui(state.r, state.x, -aa2);
1111 mpz_mul_si(state.x, state.x, aa1);
1113 mpz_addmul_ui(state.x, state.y, bb1);
1115 mpz_submul_ui(state.x, state.y, -bb1);
1117 mpz_set(state.y, state.r);
1119 if (mpz_sgn(state.bx) < 0) {
1120 mpz_neg(state.x, state.x);
1121 mpz_neg(state.bx, state.bx);
1123 if (mpz_sgn(state.by) < 0) {
1124 mpz_neg(state.y, state.y);
1125 mpz_neg(state.by, state.by);
1130 if (mpz_sgn(state.by) < 0) {
1131 mpz_neg(state.y, state.y);
1132 mpz_neg(state.x, state.x);
1133 mpz_neg(state.by, state.by);
1138 template<
typename T>
1139 static void nudupl(state_type<T> &state) {
1141 mpz_gcdext(state.G, state.y, NULL, state.form.b, state.form.a);
1143 state.By = state.form.a / state.G;
1144 state.Dy = state.form.b / state.G;
1146 state.bx = (state.y * state.form.c) % state.By;
1147 state.by = state.By;
1149 if (state.by <= state.L) {
1150 state.dx = state.bx * state.Dy;
1151 state.dx = state.dx - state.form.c;
1153 state.dx = statte.dx / state.By;
1155 state.form.a = state.by * state.by;
1156 state.form.c = state.bx * state.bx;
1158 state.t = state.bx + state.by;
1161 state.form.b = state.form.b - state.t;
1162 state.form.b = state.form.b + state.form.a;
1163 state.form.b = state.form.b + state.form.c;
1165 state.t = state.G * state.dx;
1166 state.form.c = state.form.c - state.t;
1170 mpz_xgcd_partial(state);
1176 state.by = -state.by;
1179 state.ax = state.G * state.x;
1180 state.ay = state.G * state.y;
1182 state.t = state.Dy * state.bx;
1183 state.t -= state.form.c * state.x;
1185 state.dx = state.t / state.By;
1187 state.Q1 = state.y * state.dx;
1188 state.dy = state.dy + state.Q1;
1189 state.form.b = state.dy + state.Q1;
1190 state.form.b = state.form.b * state.G;
1191 state.dy = state.dy / state.x;
1192 state.form.a = state.by * state.by;
1193 state.form.c = state.bx * state.bx;
1194 state.t = state.bx + state.by;
1195 state.form.b -= state.t * state.t;
1196 state.form.b = state.form.b + state.form.a;
1197 state.form.b = state.form.b + state.form.c;
1198 state.form.a -= state.ay * state.dy;
1199 state.form.c -= state.ax * state.dx;
#define LOG2(X)
Definition: chia_policy.hpp:80
constexpr nil::crypto3::detail::remove_complex_t< T > abs(T x)
computes the absolute value
Definition: algebra/include/nil/crypto3/algebra/scalar/math.hpp:76
T sgn(T x)
Sign function.
Definition: math/include/nil/crypto3/math/expressions/math.hpp:46
Definition: chia_functions.hpp:34
chia_policy policy_type
Definition: chia_functions.hpp:35
Definition: chia_policy.hpp:88
form_type form
Definition: chia_policy.hpp:143
number_type ra
Definition: chia_policy.hpp:138
number_type r
Definition: chia_policy.hpp:138
Definition: chia_policy.hpp:78
constexpr static const int64_t threshold
Definition: chia_policy.hpp:82
constexpr static const int64_t exp_threshold
Definition: chia_policy.hpp:84