/* Helper function for ref_zn_array_unpack(). Inverse operation of ref_zn_array_pack_helper(); each output coefficient occupies ceil(b / ULONG_BITS) ulongs. Running time is soft-linear in output length. */ void ref_zn_array_unpack_helper (ulong* res, const mpz_t op, size_t n, unsigned b, unsigned k) { ZNP_ASSERT (n >= 1); ZNP_ASSERT (mpz_sizeinbase (op, 2) <= n * b + k); unsigned w = CEIL_DIV (b, ULONG_BITS); mpz_t y; mpz_init (y); if (n == 1) { // base case unsigned i; mpz_tdiv_q_2exp (y, op, k); for (i = 0; i < w; i++) { res[i] = mpz_get_ui (y); mpz_tdiv_q_2exp (y, y, ULONG_BITS); } } else { // recursively split into top and bottom halves mpz_tdiv_q_2exp (y, op, (n / 2) * b + k); ref_zn_array_unpack_helper (res + w * (n / 2), y, n - n / 2, b, 0); mpz_tdiv_r_2exp (y, op, (n / 2) * b + k); ref_zn_array_unpack_helper (res, y, n / 2, b, k); } mpz_clear (y); }
/* Select the 2, 4, or 6 numbers we will try to factor. */ static void choose_m(mpz_t* mlist, long D, mpz_t u, mpz_t v, mpz_t N, mpz_t t, mpz_t Nminus1) { int i; mpz_add_ui(Nminus1, N, 1); mpz_add(mlist[0], Nminus1, u); mpz_sub(mlist[1], Nminus1, u); for (i = 2; i < 6; i++) mpz_set_ui(mlist[i], 0); if (D == -3) { /* If reading Cohen, be sure to see the errata for page 474. */ mpz_mul_si(t, v, 3); mpz_add(t, t, u); mpz_tdiv_q_2exp(t, t, 1); mpz_add(mlist[2], Nminus1, t); mpz_sub(mlist[3], Nminus1, t); mpz_mul_si(t, v, -3); mpz_add(t, t, u); mpz_tdiv_q_2exp(t, t, 1); mpz_add(mlist[4], Nminus1, t); mpz_sub(mlist[5], Nminus1, t); } else if (D == -4) { mpz_mul_ui(t, v, 2); mpz_add(mlist[2], Nminus1, t); mpz_sub(mlist[3], Nminus1, t); } /* m must not be prime */ for (i = 0; i < 6; i++) if (mpz_sgn(mlist[i]) && _GMP_is_prob_prime(mlist[i])) mpz_set_ui(mlist[i], 0); }
/* Key comes in form .... M_2 M_1 K_0, unmask is K_i = K_i-1 * M_i mod Q */ int gostdsa_unmask_key (const struct ecc_curve *ecc, mpz_t key) { unsigned bits = ecc_bit_size (ecc); unsigned keybits = mpz_sizeinbase (key, 2); mpz_t unmasked, temp, temp2, q; if (keybits <= bits) return 0; mpz_init (unmasked); mpz_init (temp); mpz_init (temp2); mpz_roinit_n (q, ecc->q.m, ecc->q.size); mpz_tdiv_r_2exp (unmasked, key, bits); mpz_tdiv_q_2exp (key, key, bits); keybits -= bits; while (keybits > bits) { mpz_tdiv_r_2exp (temp2, key, bits); mpz_tdiv_q_2exp (key, key, bits); keybits -= bits; mpz_mul (temp, unmasked, temp2); mpz_mod (unmasked, temp, q); } mpz_mul (temp, unmasked, key); mpz_mod (key, temp, q); mpz_clear (temp2); mpz_clear (temp); mpz_clear (unmasked); return 0; }
static inline void fib_matrix_pow (mpz_t a, mpz_t b, mpz_t c, mpz_t d, mpz_t term) { mpz_t half_term; if (mpz_cmp_ui (term, 1) == 0) return; mpz_init (half_term); if (mpz_even_p (term)) { mpz_tdiv_q_2exp (half_term, term, 1); fib_matrix_pow (a, b, c, d, half_term); fib_matrix_square (a, b, c, d); } else { mpz_t e, f, g, h; mpz_init_set (e, a); mpz_init_set (f, b); mpz_init_set (g, c); mpz_init_set (h, d); mpz_sub_ui (half_term, term, 1); mpz_tdiv_q_2exp (half_term, half_term, 1); fib_matrix_pow (a, b, c, d, half_term); fib_matrix_square (a, b, c, d); fib_matrix_mul (a, b, c, d, e, f, g, h); mpz_clear (e); mpz_clear (f); mpz_clear (g); mpz_clear (h); } mpz_clear (half_term); }
int checkBl(mpz_t n, uint32 *qli, fb_list *fb, mpz_t *Bl, int s) { //check that Bl^2 == N mod ql and Bl == 0 mod qj for 1<=j<=s, j != l int i,j,p,q; mpz_t t1,t2; mpz_init(t1); mpz_init(t2); for (i=0;i<s;i++) { p = fb->list->prime[qli[i]]; mpz_tdiv_q_2exp(t2, Bl[i], 1); //zShiftRight(&t2,&Bl[i],1); mpz_mul(t1, t2, t2); //zSqr(&t2,&t1); if (mpz_tdiv_ui(t1,p) % mpz_tdiv_ui(n,p) != 0) printf("%s^2 mod %u != N mod %u\n",mpz_conv2str(&gstr1.s, 10, Bl[i]),p,p); for (j=0;j<s;j++) { if (j==i) continue; q = fb->list->prime[qli[j]]; mpz_tdiv_q_2exp(t2, Bl[i], 1); //zShiftRight(&t2,&Bl[i],1); if (mpz_tdiv_ui(t2,q) != 0) printf("%s mod %u != 0\n",mpz_conv2str(&gstr1.s, 10, Bl[i]),q); } } mpz_clear(t1); mpz_clear(t2); return 0; }
static void zp_halve(element_ptr n, element_ptr a) { mpz_ptr z = a->data; if (mpz_odd_p(z)) { mpz_add(n->data, z, a->field->order); mpz_tdiv_q_2exp(n->data, n->data, 1); } else { mpz_tdiv_q_2exp(n->data, a->data, 1); } }
void gmp_halve(mpz_ptr value, mpz_ptr order) { if (mpz_odd_p(value)) { mpz_add(value, value, order); mpz_tdiv_q_2exp(value, value, 1); } else { mpz_tdiv_q_2exp(value, value, 1); } }
static void mpfr_const_euler_S2_aux (mpz_t P, mpz_t Q, mpz_t T, unsigned long n, unsigned long a, unsigned long b, int need_P) { if (a + 1 == b) { mpz_set_ui (P, n); if (a > 1) mpz_mul_si (P, P, 1 - (long) a); mpz_set (T, P); mpz_set_ui (Q, a); mpz_mul_ui (Q, Q, a); } else { unsigned long c = (a + b) / 2; mpz_t P2, Q2, T2; mpfr_const_euler_S2_aux (P, Q, T, n, a, c, 1); mpz_init (P2); mpz_init (Q2); mpz_init (T2); mpfr_const_euler_S2_aux (P2, Q2, T2, n, c, b, 1); mpz_mul (T, T, Q2); mpz_mul (T2, T2, P); mpz_add (T, T, T2); if (need_P) mpz_mul (P, P, P2); mpz_mul (Q, Q, Q2); mpz_clear (P2); mpz_clear (Q2); mpz_clear (T2); /* divide by 2 if possible */ { unsigned long v2; v2 = mpz_scan1 (P, 0); c = mpz_scan1 (Q, 0); if (c < v2) v2 = c; c = mpz_scan1 (T, 0); if (c < v2) v2 = c; if (v2) { mpz_tdiv_q_2exp (P, P, v2); mpz_tdiv_q_2exp (Q, Q, v2); mpz_tdiv_q_2exp (T, T, v2); } } } }
// Check Fermat probable primality test (2-PRP): 2 ** (n-1) = 1 (mod n) // true: n is probable prime // false: n is composite; set fractional length in the nLength output static bool FermatProbablePrimalityTestFast(const mpz_class& n, unsigned int& nLength, CPrimalityTestParams& testParams, bool fFastFail = false) { mpz_class& mpzNMinusOne = testParams.mpzNMinusOne; mpz_class& mpzE = testParams.mpzE; mpz_class& mpzBase = testParams.mpzBase; mpz_class& mpzR = testParams.mpzR; mpz_class& mpzR2 = testParams.mpzR2; mpz_class& mpzFrac = testParams.mpzFrac; mpzNMinusOne = n - 1; unsigned int nTrailingZeros = mpz_scan1(mpzNMinusOne.get_mpz_t(), 0); if ((nTrailingZeros > 9)) nTrailingZeros = 9; // Euler's criterion: 2 ** ((n-1)/2) needs to be either -1 or 1 (mod n) mpz_tdiv_q_2exp(mpzE.get_mpz_t(), mpzNMinusOne.get_mpz_t(), nTrailingZeros); unsigned int nShiftCount = (1U << (nTrailingZeros - 1)) - 1; mpzBase = mpzTwo << nShiftCount; mpz_powm(mpzR.get_mpz_t(), mpzBase.get_mpz_t(), mpzE.get_mpz_t(), n.get_mpz_t()); if ((mpzR == 1 || mpzR == mpzNMinusOne)) return true; if ((fFastFail)) return false; // Failed test, calculate fractional length mpzR2 = mpzR * mpzR; mpzR = mpzR2 % n; // derive Fermat test remainder mpzFrac = n - mpzR; mpzFrac <<= nFractionalBits; mpzFrac /= n; unsigned int nFractionalLength = mpzFrac.get_ui(); if ((nFractionalLength >= (1 << nFractionalBits))) return false; nLength = (nLength & TARGET_LENGTH_MASK) | nFractionalLength; return false; }
static inline uint64_t s_bignum_2_uint64_t(MP_INT *v) { uint64_t ret; uint32_t lo, hi; MP_INT posv; MP_INT z_lo; MP_INT z_hi; bool is_neg = (mpz_sgn(v) < 0) ? true : false; mpz_init(&z_lo); mpz_init(&z_hi); if (is_neg == true) { mpz_init(&posv); mpz_neg(&posv, v); v = &posv; } mpz_tdiv_q_2exp(&z_hi, v, 32); mpz_tdiv_r_2exp(&z_lo, v, 32); hi = mpz_get_ui(&z_hi); lo = mpz_get_ui(&z_lo); mpz_clear(&z_hi); mpz_clear(&z_lo); ret = ((uint64_t)hi << 32) | (uint64_t)lo; if (is_neg == true) { ret--; ret = ~ret; mpz_clear(&posv); } return ret; }
static obj bignum_compact(mpz_t a) { INT_64 b; UINT_32 c; if(abs(a[0]._mp_size) > 64/mp_bits_per_limb) return mpz_to_bignum(a); if(abs(a[0]._mp_size) < 64/mp_bits_per_limb) c = 0; else { mpz_t d; mpz_init(d); mpz_tdiv_q_2exp(d, a, CHAR_BIT*sizeof(unsigned long int)); c=mpz_get_ui(d); if(mpz_sgn(a) > 0 && (c&(1<<(CHAR_BIT*sizeof(unsigned long int)-1)))) return mpz_to_bignum(a); } #ifndef HAVE_INT_64 b.digits[0] = c >> 16; b.digits[1] = c & 0xffff; c = mpz_get_ui(a); b.digits[2] = c >> 16; b.digits[3] = c & 0xffff; if(mpz_sgn(a) < 0) b = int_64_neg(b); #else b = c; b <<= 32; b |= mpz_get_ui(a); if(mpz_sgn(a) < 0) b = -b; #endif return int_64_compact(b); }
/* Implements Legendre symbol only, requiring that p is an odd prime */ static int mpz_ui_kronecker (mp_limb_t ul, const mpz_t p) { mpz_t t, u; int r; mpz_init_set_ui (u, ul); mpz_init_set (t, p); mpz_sub_ui (t, t, 1); mpz_tdiv_q_2exp (t, t, 1); mpz_powm (t, u, t, p); r = mpz_cmp_ui (t, 1); if (r < 0) r = 0; else if (r == 0) r = 1; else { mpz_sub (t, p, t); ASSERT (mpz_cmp_ui (t, 1) == 0); r = -1; } mpz_clear (t); mpz_clear (u); return r; }
static PyObject * GMPy_MPZ_t_div_2exp(PyObject *self, PyObject *args) { mp_bitcnt_t nbits; MPZ_Object *result, *tempx; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("t_div_2exp() requires 'mpz','int' arguments"); return NULL; } nbits = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); if (nbits == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { return NULL; } tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); result = GMPy_MPZ_New(NULL); if (!tempx || !result) { Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempx); return NULL; } mpz_tdiv_q_2exp(result->z, tempx->z, nbits); Py_DECREF((PyObject*)tempx); return (PyObject*)result; }
ring_elem RingZZ::remainderAndQuotient(const ring_elem f, const ring_elem g, ring_elem ") const { mpz_ptr q = new_elem(); mpz_ptr r = new_elem(); int gsign = mpz_sgn(g.get_mpz()); mpz_t gg, ghalf; mpz_init(gg); mpz_init(ghalf); mpz_abs(gg,g.get_mpz()); mpz_fdiv_qr(q, r, f.get_mpz(), gg); mpz_tdiv_q_2exp(ghalf, gg, 1); if (mpz_cmp(r,ghalf) > 0) // r > ghalf { mpz_sub(r,r,gg); mpz_add_ui(q,q,1); } if (gsign < 0) mpz_neg(q,q); mpz_clear(gg); mpz_clear(ghalf); quot = ring_elem(q); return ring_elem(r); }
void BigNum::add(BigNum & r, BigNum & x, BigNum & y) // result of x + y will be stored in r, x and y will be changed { //r.denominator = x.denominator + y.denominator; if (x.denominator >= y.denominator) { r.denominator = x.denominator; mpz_mul_2exp(y.numerator, y.numerator, x.denominator - y.denominator); } else { r.denominator = y.denominator; mpz_mul_2exp(x.numerator, x.numerator, y.denominator - x.denominator); } mpz_add(r.numerator, x.numerator, y.numerator); r.zero_flag = false; // any result should be > 0 unsigned index = 0; while(!mpz_tstbit(r.numerator, index)) // mpz_tstbit(r.numerator, index) == 0, test 0 bit by bit ++index; if (index > 0) // reduce numerator and denominator as much as possible { mpz_tdiv_q_2exp(r.numerator, r.numerator, index); r.denominator = r.denominator - index; } return; }
int mpz_remove_twos (mpz_t x) { mp_bitcnt_t r = mpz_scan1(x, 0); mpz_tdiv_q_2exp (x, x, r); return r; }
static obj bignum_shr( obj a, INT_32 b) { mpz_t r, a1; OBJ_TO_MPZ(a1, a); mpz_init(r); mpz_tdiv_q_2exp(r, a1, b); return bignum_compact(r); }
//-------------------------------------------------- // square root in extended Fp //-------------------------------------------------- int bn254_fp2_sqrt(Element z, const Element x) { mpz_t _v; int m, r, i; field_precomp_sqrt_p ps; Element *t = field(z)->tmp; if (!element_is_sqr(x)) { return FALSE; } ps = ((field_precomp_p)(field(x)->precomp))->ps; element_set(t[0], ps->n_v); // t0 = n^v r = ps->e; // r = e mpz_init_set(_v, ps->v); mpz_sub_ui(_v, _v, 1); mpz_tdiv_q_2exp(_v, _v, 1); element_pow(t[1], x, _v); // t1 = x^{(v-1)/2} element_sqr(t[2], t[1]); element_mul(t[2], t[2], x); // t2 = x*t1^2 element_mul(t[1], x, t[1]); // t1 = x*t1 mpz_clear(_v); while (!element_is_one(t[2])) { m = 0; element_set(t[3], t[2]); do { element_sqr(t[3], t[3]); m++; } while (!element_is_one(t[3]) && m < r); r = r - m - 1; element_set(t[3], t[0]); for (i = 1; i <= r; i++) { element_sqr(t[3], t[3]); } // t3 = t2^{r-m-1} element_sqr(t[0], t[3]); // t0 = t3^2 r = m; element_mul(t[1], t[1], t[3]);// t1 = t1*t3 element_mul(t[2], t[2], t[0]);// t2 = t2*t0 } element_set(z, t[1]); return TRUE; }
static void gf3m_sqrt(element_t e, element_t a) { field_ptr f = e->field; mpz_t t; mpz_init(t); // t == (field_order + 1) / 4 mpz_set(t, f->order); mpz_add_ui(t, t, 1); mpz_tdiv_q_2exp(t, t, 2); element_pow_mpz(e, a, t); mpz_clear(t); }
/* First version -- uses Taylor series for exp(x) directly, broken into two pieces Note: this version is currently not used in the benchmark below */ void fix_exp(mpz_t z, mpz_t x, int prec) { int k; int r = 8; //prec += 20; //mpz_set(_exp_x, x); //mpz_tdiv_q_2exp(_exp_x, _exp_x, r); mpz_tdiv_q_2exp(_exp_x, x, r); mpz_set_ui(_exp_s0, 1); mpz_mul_2exp(_exp_s0, _exp_s0, prec); mpz_set(_exp_s1, _exp_s0); mpz_mul(_exp_x2, _exp_x, _exp_x); mpz_tdiv_q_2exp(_exp_x2,_exp_x2,prec); mpz_set(_exp_a, _exp_x2); k = 2; while(1) { mpz_tdiv_q_ui(_exp_a, _exp_a, k); if (mpz_sgn(_exp_a) == 0) break; mpz_add(_exp_s0, _exp_s0, _exp_a); k += 1; mpz_tdiv_q_ui(_exp_a, _exp_a, k); if (mpz_sgn(_exp_a) == 0) break; mpz_add(_exp_s1, _exp_s1, _exp_a); k += 1; mpz_mul(_exp_a, _exp_a, _exp_x2); mpz_tdiv_q_2exp(_exp_a,_exp_a,prec); if (mpz_sgn(_exp_a) == 0) break; } mpz_mul(_exp_s1, _exp_s1, _exp_x); mpz_tdiv_q_2exp(_exp_s1,_exp_s1,prec); mpz_add(_exp_s0, _exp_s0, _exp_s1); for(k=0; k<r; k++) { mpz_mul(_exp_s0, _exp_s0, _exp_s0); mpz_tdiv_q_2exp(_exp_s0,_exp_s0,prec); } //mpz_tdiv_q_ui(z, _exp_s0, 20); mpz_set(z, _exp_s0); }
/* fix the sign of Re(z) or Im(z) in case it is zero, and Re(x) is zero. sign_eps is 0 if Re(x) = +0, 1 if Re(x) = -0 sign_a is the sign bit of Im(x). Assume y is an integer (does nothing otherwise). */ static void fix_sign (mpc_ptr z, int sign_eps, int sign_a, mpfr_srcptr y) { int ymod4 = -1; mpfr_exp_t ey; mpz_t my; unsigned long int t; mpz_init (my); ey = mpfr_get_z_exp (my, y); /* normalize so that my is odd */ t = mpz_scan1 (my, 0); ey += (mpfr_exp_t) t; mpz_tdiv_q_2exp (my, my, t); /* y = my*2^ey */ /* compute y mod 4 (in case y is an integer) */ if (ey >= 2) ymod4 = 0; else if (ey == 1) ymod4 = mpz_tstbit (my, 0) * 2; /* correct if my < 0 */ else if (ey == 0) { ymod4 = mpz_tstbit (my, 1) * 2 + mpz_tstbit (my, 0); if (mpz_cmp_ui (my , 0) < 0) ymod4 = 4 - ymod4; } else /* y is not an integer */ goto end; if (mpfr_zero_p (mpc_realref(z))) { /* we assume y is always integer in that case (FIXME: prove it): (eps+I*a)^y = +0 + I*a^y for y = 1 mod 4 and sign_eps = 0 (eps+I*a)^y = -0 - I*a^y for y = 3 mod 4 and sign_eps = 0 */ MPC_ASSERT (ymod4 == 1 || ymod4 == 3); if ((ymod4 == 3 && sign_eps == 0) || (ymod4 == 1 && sign_eps == 1)) mpfr_neg (mpc_realref(z), mpc_realref(z), MPFR_RNDZ); } else if (mpfr_zero_p (mpc_imagref(z))) { /* we assume y is always integer in that case (FIXME: prove it): (eps+I*a)^y = a^y - 0*I for y = 0 mod 4 and sign_a = sign_eps (eps+I*a)^y = -a^y +0*I for y = 2 mod 4 and sign_a = sign_eps */ MPC_ASSERT (ymod4 == 0 || ymod4 == 2); if ((ymod4 == 0 && sign_a == sign_eps) || (ymod4 == 2 && sign_a != sign_eps)) mpfr_neg (mpc_imagref(z), mpc_imagref(z), MPFR_RNDZ); } end: mpz_clear (my); }
int mpz_millerrabin (mpz_srcptr n, int reps) { int r; mpz_t nm1, nm3, x, y, q; unsigned long int k; gmp_randstate_t rstate; int is_prime; TMP_DECL; TMP_MARK; MPZ_TMP_INIT (nm1, SIZ (n) + 1); mpz_sub_ui (nm1, n, 1L); MPZ_TMP_INIT (x, SIZ (n) + 1); MPZ_TMP_INIT (y, 2 * SIZ (n)); /* mpz_powm_ui needs excessive memory!!! */ /* Perform a Fermat test. */ mpz_set_ui (x, 210L); mpz_powm (y, x, nm1, n); if (mpz_cmp_ui (y, 1L) != 0) { TMP_FREE; return 0; } MPZ_TMP_INIT (q, SIZ (n)); /* Find q and k, where q is odd and n = 1 + 2**k * q. */ k = mpz_scan1 (nm1, 0L); mpz_tdiv_q_2exp (q, nm1, k); /* n-3 */ MPZ_TMP_INIT (nm3, SIZ (n) + 1); mpz_sub_ui (nm3, n, 3L); ASSERT (mpz_cmp_ui (nm3, 1L) >= 0); gmp_randinit_default (rstate); is_prime = 1; for (r = 0; r < reps && is_prime; r++) { /* 2 to n-2 inclusive, don't want 1, 0 or -1 */ mpz_urandomm (x, rstate, nm3); mpz_add_ui (x, x, 2L); is_prime = millerrabin (n, nm1, x, y, q, k); } gmp_randclear (rstate); TMP_FREE; return is_prime; }
/* Return non-zero iff c+i*d is an exact square (a+i*b)^2, with a, b both of the form m*2^e with m, e integers. If so, returns in a+i*b the corresponding square root, with a >= 0. The variables a, b must not overlap with c, d. We have c = a^2 - b^2 and d = 2*a*b. If one of a, b is exact, then both are (see algorithms.tex). Case 1: a <> 0 and b <> 0. Let a = m*2^e and b = n*2^f with m, e, n, f integers, m and n odd (we will treat apart the case a = 0 or b = 0). Then 2*a*b = m*n*2^(e+f+1), thus necessarily e+f >= -1. Assume e < 0, then f >= 0, then a^2 - b^2 = m^2*2^(2e) - n^2*2^(2f) cannot be an integer, since n^2*2^(2f) is an integer, and m^2*2^(2e) is not. Similarly when f < 0 (and thus e >= 0). Thus we have e, f >= 0, and a, b are both integers. Let A = 2a^2, then eliminating b between c = a^2 - b^2 and d = 2*a*b gives A^2 - 2c*A - d^2 = 0, which has solutions c +/- sqrt(c^2+d^2). We thus need c^2+d^2 to be a square, and c + sqrt(c^2+d^2) --- the solution we are interested in --- to be two times a square. Then b = d/(2a) is necessarily an integer. Case 2: a = 0. Then d is necessarily zero, thus it suffices to check whether c = -b^2, i.e., if -c is a square. Case 3: b = 0. Then d is necessarily zero, thus it suffices to check whether c = a^2, i.e., if c is a square. */ static int mpc_perfect_square_p (mpz_t a, mpz_t b, mpz_t c, mpz_t d) { if (mpz_cmp_ui (d, 0) == 0) /* case a = 0 or b = 0 */ { /* necessarily c < 0 here, since we have already considered the case where x is real non-negative and y is real */ MPC_ASSERT (mpz_cmp_ui (c, 0) < 0); mpz_neg (b, c); if (mpz_perfect_square_p (b)) /* case 2 above */ { mpz_sqrt (b, b); mpz_set_ui (a, 0); return 1; /* c + i*d = (0 + i*b)^2 */ } } else /* both a and b are non-zero */ { if (mpz_divisible_2exp_p (d, 1) == 0) return 0; /* d must be even */ mpz_mul (a, c, c); mpz_addmul (a, d, d); /* c^2 + d^2 */ if (mpz_perfect_square_p (a)) { mpz_sqrt (a, a); mpz_add (a, c, a); /* c + sqrt(c^2+d^2) */ if (mpz_divisible_2exp_p (a, 1)) { mpz_tdiv_q_2exp (a, a, 1); if (mpz_perfect_square_p (a)) { mpz_sqrt (a, a); mpz_tdiv_q_2exp (b, d, 1); /* d/2 */ mpz_divexact (b, b, a); /* d/(2a) */ return 1; } } } } return 0; /* not a square */ }
static void check_one (mpz_ptr z) { int inex; int sh, neg; mpfr_t f; mpz_t got; mpfr_init2 (f, MAX( mpz_sizeinbase (z, 2), MPFR_PREC_MIN) ); mpz_init (got); for (sh = -2*GMP_NUMB_BITS ; sh < 2*GMP_NUMB_BITS ; sh++) { for (neg = 0; neg <= 1; neg++) { mpz_neg (z, z); mpfr_set_z (f, z, MPFR_RNDN); if (sh < 0) { mpz_tdiv_q_2exp (z, z, -sh); mpfr_div_2exp (f, f, -sh, MPFR_RNDN); } else { mpz_mul_2exp (z, z, sh); mpfr_mul_2exp (f, f, sh, MPFR_RNDN); } inex = mpfr_get_z (got, f, MPFR_RNDZ); if (mpz_cmp (got, z) != 0) { printf ("Wrong result for shift=%d\n", sh); printf (" f "); mpfr_dump (f); printf (" got "); mpz_dump (got); printf (" want "); mpz_dump (z); exit (1); } if (! SAME_SIGN (inex, - mpfr_cmp_z (f, z))) { printf ("Wrong inexact value for shift=%d\n", sh); printf (" f "); mpfr_dump (f); printf (" got %+d\n", inex); printf (" want %+d\n", -mpfr_cmp_z (f, z)); exit (1); } } } mpfr_clear (f); mpz_clear (got); }
int test__ZmodF_mul_fft_split() { int success = 1; mpz_t x, y, z; mpz_init(x); mpz_init(y); mpz_init(z); mp_limb_t buf[300]; for (unsigned long n = 1; n < 200 && success; n++) { for (unsigned long depth = 0; ((n*FLINT_BITS) % (1 << depth) == 0) && success; depth++) { unsigned long bits = (n*FLINT_BITS) >> depth; unsigned long m = (bits-1)/FLINT_BITS + 1; ZmodF_poly_t poly; ZmodF_poly_init(poly, depth, m, 1); #if DEBUG printf("n = %d, depth = %d, m = %d\n", n, depth, m); #endif for (unsigned long trial = 0; trial < 120; trial++) { random_limbs(buf, n); buf[n] = 0; mpn_to_mpz(x, buf, n); _ZmodF_mul_fft_split(poly, buf, n); for (unsigned long i = 0; i < (1 << depth); i++) { mpz_tdiv_r_2exp(y, x, bits); mpz_tdiv_q_2exp(x, x, bits); mpn_to_mpz(z, poly->coeffs[i], m+1); if (mpz_cmp(z, y)) success = 0; } } ZmodF_poly_clear(poly); } } mpz_clear(x); mpz_clear(y); mpz_clear(z); return success; }
void Element::multiply(Element& A, Element& B) { // Emulate hardware implementation. // Set result to 0 mpz_t result; mpz_init(result); // Modulus: x^163 + x^7 + x^6 + x^3 + 1 (wordlength 163) mpz_t mod; mpz_init(mod); mpz_set_str(mod, "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011001001", 2); //gmp_printf("Mod = %Zx\n", mod); // Length of modulus in base 2 int mod_len = 163; //printf("Len = %d\n", mod_len); int m = 0; for (long i = (long) mod_len; i > 0; i--) { if (mpz_tstbit(A.getMP(), i - 1) == 1) { mpz_xor(result, result, B.getMP()); } if (m == 1) { mpz_xor(result, result, mod); } // Set m & T for next round m = mpz_tstbit(result, mod_len - 1); // Shift T by 1 bit to the left and clear MSB bit mpz_clrbit(result, mod_len - 1); mpz_mul_2exp(result, result, 1); /*printf("[Mult] i = %d - T = ", mod_len - i + 2); gmp_printf("0x%Zx\n", result);*/ } // Shift result back 1 place & place m back in front mpz_tdiv_q_2exp(result, result, 1); if (m == 1) { mpz_setbit(result, 162); } /*printf("[Mult] i = 0 - T = "); gmp_printf("0x%Zx\n", result);*/ // Set result mpz_set(this->a, result); }
/* Select the 2, 4, or 6 numbers we will try to factor. */ static void choose_m(mpz_t* mlist, long D, mpz_t u, mpz_t v, mpz_t N, mpz_t t, mpz_t Nplus1) { int i, j; mpz_add_ui(Nplus1, N, 1); mpz_sub(mlist[0], Nplus1, u); /* N+1-u */ mpz_add(mlist[1], Nplus1, u); /* N+1+u */ for (i = 2; i < 6; i++) mpz_set_ui(mlist[i], 0); if (D == -3) { /* If reading Cohen, be sure to see the errata for page 474. */ mpz_mul_si(t, v, 3); mpz_add(t, t, u); mpz_tdiv_q_2exp(t, t, 1); mpz_sub(mlist[2], Nplus1, t); /* N+1-(u+3v)/2 */ mpz_add(mlist[3], Nplus1, t); /* N+1+(u+3v)/2 */ mpz_mul_si(t, v, -3); mpz_add(t, t, u); mpz_tdiv_q_2exp(t, t, 1); mpz_sub(mlist[4], Nplus1, t); /* N+1-(u-3v)/2 */ mpz_add(mlist[5], Nplus1, t); /* N+1+(u-3v)/2 */ } else if (D == -4) { mpz_mul_ui(t, v, 2); mpz_sub(mlist[2], Nplus1, t); /* N+1-2v */ mpz_add(mlist[3], Nplus1, t); /* N+1+2v */ } /* m must not be prime */ for (i = 0; i < 6; i++) if (mpz_sgn(mlist[i]) && _GMP_is_prob_prime(mlist[i])) mpz_set_ui(mlist[i], 0); /* Sort the m values so we test the smallest first */ for (i = 0; i < 5; i++) if (mpz_sgn(mlist[i])) for (j = i+1; j < 6; j++) if (mpz_sgn(mlist[j]) && mpz_cmp(mlist[i],mlist[j]) > 0) mpz_swap( mlist[i], mlist[j] ); }
double mpzln(mpz_t a) { int l; double r; l = mpz_sizeinbase(a,2); if (l<=1000) r=log(fabs(mpz_get_d(a))); else { mpz_t b; mpz_init(b); mpz_tdiv_q_2exp(b,a,l-900); r=mpz_get_d(b); r=(double)l-900.0+log(fabs(r)); mpz_clear(b); } return r; }
int gmpmee_millerrabin_init(gmpmee_millerrabin_state state, mpz_t n) { mpz_init_set(state->n, n); mpz_init(state->n_minus_1); mpz_init(state->q); mpz_init(state->y); mpz_sub_ui(state->n_minus_1, n, 1L); /* Define q and k such that n = q*2^k+1. */ state->k = mpz_scan1(state->n_minus_1, 0L); mpz_tdiv_q_2exp(state->q, state->n_minus_1, state->k); }
double mpzln(mpz_t a) //calculate ln for arbitrary length integers { //I have no idea how this works - probably should try to understand int l; double r; l = mpz_sizeinbase(a,2); if (l<=1000) r=log(fabs(mpz_get_d(a))); else { mpz_t b; mpz_init(b); mpz_tdiv_q_2exp(b,a,l-900); r=mpz_get_d(b); r=(double)l-900.0+log(fabs(r)); mpz_clear(b); } return r; }