ecc_point* double_p(ecc_point p){ ecc_point* result; result= malloc(sizeof(ecc_point)); mpz_init((*result).x); mpz_init((*result).y); printf("DP "); if (mpz_cmp_ui(p.y,0)!=0){ mpz_t s,d_y,d_x,y; mpz_init(d_y); mpz_init(s); mpz_init(y); mpz_init(d_x); mpz_pow_ui(s,p.x,2); mpz_mul_si(s,s,3); mpz_add(s,s,a); mpz_mul_si(d_y,p.y,2); mpz_mod(d_y,d_y,prime); mpz_invert(d_y,d_y,prime); mpz_mul(s,s,d_y); mpz_mod(s,s,prime); mpz_mul_ui(d_x,p.x,2); mpz_pow_ui((*result).x,s,2); mpz_sub((*result).x,(*result).x,d_x); mpz_mod((*result).x,(*result).x,prime); mpz_neg((*result).y,p.y); mpz_sub(d_x,p.x,(*result).x); mpz_mul(s,s,d_x); mpz_add((*result).y,(*result).y,s); mpz_mod((*result).y,(*result).y,prime); }else result=INFINITY_POINT; return 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 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); }
void check_samples (void) { { long y; mpz_set_ui (x, 1L); y = 0; mpz_mul_si (got, x, y); mpz_set_si (want, y); compare_si (y); mpz_set_ui (x, 1L); y = 1; mpz_mul_si (got, x, y); mpz_set_si (want, y); compare_si (y); mpz_set_ui (x, 1L); y = -1; mpz_mul_si (got, x, y); mpz_set_si (want, y); compare_si (y); mpz_set_ui (x, 1L); y = LONG_MIN; mpz_mul_si (got, x, y); mpz_set_si (want, y); compare_si (y); mpz_set_ui (x, 1L); y = LONG_MAX; mpz_mul_si (got, x, y); mpz_set_si (want, y); compare_si (y); } { unsigned long y; mpz_set_ui (x, 1L); y = 0; mpz_mul_ui (got, x, y); mpz_set_ui (want, y); compare_ui (y); mpz_set_ui (x, 1L); y = 1; mpz_mul_ui (got, x, y); mpz_set_ui (want, y); compare_ui (y); mpz_set_ui (x, 1L); y = ULONG_MAX; mpz_mul_ui (got, x, y); mpz_set_ui (want, y); compare_ui (y); } }
/* * Function: compute_bbp_first_sum_gmp * -------------------- * Computes the first summand in the BBP formula using GNU GMP. * * d: digit to be calculated * base: the base * c: a fixed positive integer * p: a simple polynomial like x or x^2 * start_at_0: start the summation at k=0, if true, at k=1, otherwise. Most * instances of the BBP formula, such as pi, have you start at 0. * But some, such as log(2), have you start at 1. * * returns: the value of the first sum */ void compute_bbp_first_sum_gmp(mpf_t sum, unsigned long int d, int base, long int c, void (*p)(mpz_t, mpz_t), bool start_at_0) { mpf_set_d(sum, 0.0); signed long int k_start = start_at_0 ? 0 : 1; mpz_t k; mpz_init_set_si(k, k_start); double upper = floor((double) d / (double) c); while (mpz_cmp_d(k, upper) <= 0) { mpz_t poly_result; mpz_init(poly_result); (*p)(poly_result, k); mpz_t num; mpz_init(num); mpz_t exponent; mpz_init_set(exponent, k); mpz_mul_si(exponent, exponent, c); mpz_mul_si(exponent, exponent, -1); mpz_add_ui(exponent, exponent, d); modular_pow_gmp(num, base, exponent, poly_result); mpf_t num_float; mpf_init(num_float); mpf_set_z(num_float, num); mpz_clear(num); mpz_clear(exponent); mpf_t denom; mpf_init_set_d(denom, mpz_get_d(poly_result)); mpz_clear(poly_result); mpf_t quotient; mpf_init(quotient); mpf_div(quotient, num_float, denom); mpf_clear(num_float); mpf_clear(denom); mpf_add(sum, sum, quotient); mpf_clear(quotient); mod_one_gmp(sum, sum); mpz_add_ui(k, k, 1); } mpz_clear(k); mod_one_gmp(sum, sum); }
static PyObject * Pyxmpz_inplace_mul(PyObject *a, PyObject *b) { mpz_t tempz; mpir_si temp_si; int overflow; if (PyIntOrLong_Check(b)) { temp_si = PyLong_AsSIAndOverflow(b, &overflow); if (overflow) { mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, b); mpz_mul(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a), tempz); mpz_cloc(tempz); } else { mpz_mul_si(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a), temp_si); } Py_INCREF(a); return a; } if (CHECK_MPZANY(b)) { mpz_mul(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(b)); Py_INCREF(a); return a; } Py_RETURN_NOTIMPLEMENTED; }
static PyObject * GMPy_XMPZ_IMul_Slot(PyObject *self, PyObject *other) { if (PyIntOrLong_Check(other)) { int error; native_si temp = GMPy_Integer_AsNative_siAndError(other, &error); if (!error) { mpz_mul_si(MPZ(self), MPZ(self), temp); } else { mpz_set_PyIntOrLong(global.tempz, other); mpz_mul(MPZ(self), MPZ(self), global.tempz); } Py_INCREF(self); return self; } if (CHECK_MPZANY(other)) { mpz_mul(MPZ(self), MPZ(self), MPZ(other)); Py_INCREF(self); return self; } Py_RETURN_NOTIMPLEMENTED; }
/* check relation is correct, i.e. x^2 = p1^e1*p2^e2*... mod N. Return 0 iff the relation is ok. (q is not used here.) */ int check_relation (relation r, unsigned int *fb, mpz_t N) { mpz_t X, Y; unsigned long i, j; int p, res; mpz_init (X); mpz_init (Y); if (r->q == 0) /* full */ mpz_set_ui (Y, 1); else /* partial */ { mpz_set_ui (Y, r->q); mpz_mul_ui (Y, Y, r->q); mpz_mod (Y, Y, N); } mpz_mul (X, r->x, r->x); mpz_mod (X, X, N); for (i = 0; i < r->n; i++) for (j = 0; j < r->e[i]; j++) { p = (r->p[i] == -1) ? -1 : (int) fb[r->p[i]]; mpz_mul_si (Y, Y, p); mpz_mod (Y, Y, N); } res = mpz_cmp (X, Y); mpz_clear (X); mpz_clear (Y); return res; }
static PyObject * GMPy_MPZ_IMul_Slot(PyObject *self, PyObject *other) { MPZ_Object *rz; if (!(rz = GMPy_MPZ_New(NULL))) return NULL; if (CHECK_MPZANY(other)) { mpz_mul(rz->z, MPZ(self), MPZ(other)); return (PyObject*)rz; } if (PyIntOrLong_Check(other)) { int error; long temp = GMPy_Integer_AsLongAndError(other, &error); if (!error) { mpz_mul_si(rz->z, MPZ(self), temp); } else { mpz_t tempz; mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, other); mpz_mul(rz->z, MPZ(self), tempz); mpz_cloc(tempz); } return (PyObject*)rz; } Py_RETURN_NOTIMPLEMENTED; }
void calc(int d,int n,mpz_t r) { mpz_t t; mpz_init(t); mpz_ui_pow_ui(t,2,n/d); mpz_mul_si(t,t,phi(2*d)); mpz_add(r,r,t); mpz_clear(t); }
int main() { int i; mpz_t a,p2; mpz_init_set_si(a,1); mpz_init_set_si(p2,2); gmp_printf("0 %Zd\n",a); for(i=1;i>-1;i++) { mpz_mul_si(a,a,i); if(i&1) mpz_sub(a,a,p2); else mpz_add(a,a,p2); gmp_printf("%d %Zd\n",i,a); mpz_mul_si(p2,p2,2); } mpz_clear(p2); mpz_clear(a); return 0; }
int sign_quad() { // Returns sign of c0 z^2 - 2 a0 z - b0 mpz_mul_si(t0, p->a0, -2); mpz_addmul(t0, p->c0, z); mpz_mul(t0, t0, z); mpz_sub(t0, t0, p->b0); return mpz_sgn(t0); }
int sign_quad1() { // Returns sign of c1 z^2 - 2 a1 z - b1 mpz_mul_si(t0, p->a1, -2); mpz_addmul(t0, p->c1, z); mpz_mul(t0, t0, z); mpz_sub(t0, t0, p->b1); return mpz_sgn(t0); }
Value Bignum::multiply(long n) { mpz_t result; mpz_init_set(result, _z); mpz_mul_si(result, result, n); Value value = normalize(result); MPZ_CLEAR(result); return value; }
/** * @brief add an item to the stack * * This function adds an int to the stack * */ void stack_push(Stack *s, int item) { mpz_t tmp; mpz_init_set(tmp, *s); mpz_mul_si(*s, tmp, MAX_PAIRS); mpz_set(tmp, *s); mpz_add_ui(*s, tmp, item); mpz_clear(tmp); }
static void select_curve_params(mpz_t a, mpz_t b, mpz_t g, long D, mpz_t *roots, long i, mpz_t N, mpz_t t) { int N_is_not_1_congruent_3; mpz_set_ui(a, 0); mpz_set_ui(b, 0); if (D == -3) { mpz_set_si(b, -1); } else if (D == -4) { mpz_set_si(a, -1); } else { mpz_sub_ui(t, roots[i], 1728); mpz_mod(t, t, N); /* c = (j * inverse(j-1728)) mod n */ if (mpz_divmod(b, roots[i], t, N, b)) { mpz_mul_si(a, b, -3); /* r = -3c */ mpz_mul_si(b, b, 2); /* s = 2c */ } } mpz_mod(a, a, N); mpz_mod(b, b, N); /* g: 1 < g < Ni && (g/Ni) != -1 && (g%3!=1 || cubic non-residue) */ N_is_not_1_congruent_3 = ! mpz_congruent_ui_p(N, 1, 3); for ( mpz_set_ui(g, 2); mpz_cmp(g, N) < 0; mpz_add_ui(g, g, 1) ) { if (mpz_jacobi(g, N) != -1) continue; if (N_is_not_1_congruent_3) break; mpz_sub_ui(t, N, 1); mpz_tdiv_q_ui(t, t, 3); mpz_powm(t, g, t, N); /* t = g^((Ni-1)/3) mod Ni */ if (mpz_cmp_ui(t, 1) == 0) continue; if (D == -3) { mpz_powm_ui(t, t, 3, N); if (mpz_cmp_ui(t, 1) != 0) /* Additional check when D == -3 */ continue; } break; } if (mpz_cmp(g, N) >= 0) /* No g can be found: N is composite */ mpz_set_ui(g, 0); }
Integer& Integer::mul(Integer& res, const Integer& n1, const int64_t n2) { if (isZero(n1)) return res = Integer::zero; if (isZero(n2)) return res = Integer::zero; // int32_t sgn = sign(n2); // mpz_mul_ui( (mpz_ptr)&res.gmp_rep, (mpz_ptr)&n1.gmp_rep, abs(n2)); // if (sgn <0) res.gmp_rep.size = -res.gmp_rep.size; // if (sgn <0) return res = -res; mpz_mul_si( (mpz_ptr)&res.gmp_rep, (mpz_srcptr)&n1.gmp_rep, n2); return res; }
Integer& Integer::operator *= (const int64_t l) { if (l==0) return *this =Integer::zero; if (isZero(*this)) return *this; // Rep (res.gmp_rep)( MAX(SZ_REP(gmp_rep),1) ); // int32_t sgn = sign(l); // mpz_mul_ui( (mpz_ptr)&(gmp_rep), (mpz_ptr)&gmp_rep, abs(l)); // if (sgn <0) mpz_neg( (mpz_ptr)&gmp_rep, (mpz_ptr)&(gmp_rep) ); mpz_mul_si( (mpz_ptr)&(gmp_rep), (mpz_ptr)&gmp_rep, l); return *this; }
void S1(mpz_t n, uint64_t crn, int8_t* mu, mpz_t result) { mpz_t tmp; mpz_inits(result, tmp, NULL); uint64_t i; for(i=1; i<=crn; i++) { mpz_tdiv_q_ui(tmp, n, i); mpz_mul_si(tmp, tmp, mu[i]); mpz_add(result, result, tmp); } }
int main() { int i; mpz_t r; mpz_init_set_si(r,2); for(i=0;i>-1;i++) { gmp_printf("%d %Zd\n",i,r); mpz_mul_si(r,r,2); mpz_sub_ui(r,r,1); } mpz_clear(r); return 0; }
Integer& Integer::mulin(Integer& res, const int64_t n) { if (isZero(n)) return res = Integer::zero; if (isZero(res)) return res; // int32_t sgn = sign(n); // int32_t sgn = sign(n); // mpz_mul_ui( (mpz_ptr)&res.gmp_rep, (mpz_ptr)&res.gmp_rep, abs(n)); // if (sgn <0) res.gmp_rep.size = -res.gmp_rep.size; // if (sgn <0) return res = -res; mpz_mul_si( (mpz_ptr)&res.gmp_rep, (mpz_ptr)&res.gmp_rep, n); return res; }
/* 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] ); }
Integer Integer::operator * (const int64_t l) const { if (l==0) return Integer::zero; if (isZero(*this)) return Integer::zero; // Rep (res.gmp_rep)( MAX(SZ_REP(gmp_rep),1) ); Integer res; // int32_t sgn = sign(l); // mpz_mul_ui( (mpz_ptr)&(res.gmp_rep), (mpz_ptr)&gmp_rep, abs(l)); // if (sgn <0) (res.gmp_rep).size = -(res.gmp_rep).size; // return Integer((res.gmp_rep)); // if (sgn <0) mpz_neg( (mpz_ptr)&(res.gmp_rep), (mpz_ptr)&(res.gmp_rep) ); mpz_mul_si( (mpz_ptr)&(res.gmp_rep), (mpz_srcptr)&gmp_rep, l); return res; }
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); } } } }
void find_smallest_r (mpz_t r, mpz_t n) { /* Try out successive values of r and test if n^k != 1 (mod r) for every * k <= 4(log n)^2. */ mpz_t max_k; mpz_t logn; mpz_t logn_sqrd; sli_t exp_cl; sli_t exp_fl; mpz_init (max_k); mpz_init (logn); mpz_init (logn_sqrd); /* Compute log n * Ceiling has been applied! */ mpz_logbase2cl (&exp_cl, n); mpz_set_si (logn, exp_cl); /* log n is computed, compute 4 * (log n)^2 * Compute (log n)^2 */ mpz_mul (logn_sqrd, logn, logn); /* Compute max_k */ mpz_mul_si (max_k, logn_sqrd, 4); gmp_printf ("max_k = %Zd\n", max_k); /* Now find the appropriate r: * r = 2; * while (1) { * if (r_good(r, max_k, n)) { * break; * } * r++; * } */ mpz_set_ui (r, 2); while (1) { if (r_good (r, max_k, n)) { break; } mpz_add_ui (r, r, 1); } }
int knuth(int mm,int *epr,mpz_t N,mpz_t D) { double dp, fks, top = -10.0; char found = FALSE; int i, j, bk=0, nk=0, kk, r, p; static int K[]={0,1,2,3,5,6,7,10,11,13,14,15,17,0};// 这些是可能的multiplier epr[0]=1; epr[1]=2; do { kk=K[++nk]; if(kk==0) { kk=K[bk]; found=TRUE;// 把最大的估计值对应的部分再进行一次求素数而不是直接return } mpz_mul_si(D, N, kk); fks=log(2.0)/2.0; r=mpz_tdiv_r_ui(TB, D, 8); if(r==1) fks*=4.0; if(r==5) fks*=2.0; fks-=log((double)kk)/2.0; i=0; j=1; while(j<mm) { p=qsieve->PRIMES[++i]; r=mpz_tdiv_r_ui(TB, D, p); if(qsieve_powmod(r,(p-1)/2,p)<=1) // 求kk*N的前mm个质数,在这些质数下雅可比符号是0或1 { epr[++j]=p; dp=(double)p; if(kk%p==0) fks+=log(dp)/dp; else fks+=2*log(dp)/(dp-1.0);// 每个素数对估价的贡献 } } if(fks>top) { top=fks; bk=nk; // 最大的估价 } } while(!found); return kk; }
void fmpz_mul_si(fmpz_t f, const fmpz_t g, long x) { fmpz c2 = *g; if (x == 0) { fmpz_zero(f); return; } else if (!COEFF_IS_MPZ(c2)) /* c2 is small */ { mp_limb_t prod[2]; mp_limb_t uc2 = FLINT_ABS(c2); mp_limb_t ux = FLINT_ABS(x); /* unsigned limb by limb multiply (assembly for most CPU's) */ umul_ppmm(prod[1], prod[0], uc2, ux); if (!prod[1]) /* result fits in one limb */ { fmpz_set_ui(f, prod[0]); if ((c2 ^ x) < 0L) fmpz_neg(f, f); } else /* result takes two limbs */ { __mpz_struct *mpz_ptr = _fmpz_promote(f); /* two limbs, least significant first, native endian, no nails, stored in prod */ mpz_import(mpz_ptr, 2, -1, sizeof(mp_limb_t), 0, 0, prod); if ((c2 ^ x) < 0L) mpz_neg(mpz_ptr, mpz_ptr); } } else /* c2 is large */ { __mpz_struct *mpz_ptr = _fmpz_promote(f); /* ok without val as if aliased both are large */ mpz_mul_si(mpz_ptr, COEFF_TO_PTR(c2), x); } }
/* ******************************************************************************************* * mpz_extrastronglucas_prp: * Let U_n = LucasU(p,1), V_n = LucasV(p,1), and D=p^2-4. * An "extra strong Lucas pseudoprime" to the base p is a composite n = (2^r)*s+(D/n), where * s is odd and (n,2D)=1, such that either U_s == 0 mod n and V_s == +/-2 mod n, or * V_((2^t)*s) == 0 mod n for some t with 0 <= t < r-1 [(D/n) is the Jacobi symbol] * *******************************************************************************************/ int mpz_extrastronglucas_prp(mpz_t n, long int p) { mpz_t zD; mpz_t s; mpz_t nmj; /* n minus jacobi(D/n) */ mpz_t res; mpz_t uh, vl, vh, ql, qh, tmp; /* these are needed for the LucasU and LucasV part of this function */ long int d = p*p - 4; long int q = 1; unsigned long int r = 0; int ret = 0; int j = 0; if (d == 0) /* Does not produce a proper Lucas sequence */ return PRP_ERROR; if (mpz_cmp_ui(n, 2) < 0) return PRP_COMPOSITE; if (mpz_divisible_ui_p(n, 2)) { if (mpz_cmp_ui(n, 2) == 0) return PRP_PRIME; else return PRP_COMPOSITE; } mpz_init_set_si(zD, d); mpz_init(res); mpz_mul_ui(res, zD, 2); mpz_gcd(res, res, n); if ((mpz_cmp(res, n) != 0) && (mpz_cmp_ui(res, 1) > 0)) { mpz_clear(zD); mpz_clear(res); return PRP_COMPOSITE; } mpz_init(s); mpz_init(nmj); /* nmj = n - (D/n), where (D/n) is the Jacobi symbol */ mpz_set(nmj, n); ret = mpz_jacobi(zD, n); if (ret == -1) mpz_add_ui(nmj, nmj, 1); else if (ret == 1) mpz_sub_ui(nmj, nmj, 1); r = mpz_scan1(nmj, 0); mpz_fdiv_q_2exp(s, nmj, r); /* make sure that either (U_s == 0 mod n and V_s == +/-2 mod n), or */ /* V_((2^t)*s) == 0 mod n for some t with 0 <= t < r-1 */ mpz_init_set_si(uh, 1); mpz_init_set_si(vl, 2); mpz_init_set_si(vh, p); mpz_init_set_si(ql, 1); mpz_init_set_si(qh, 1); mpz_init_set_si(tmp,0); for (j = mpz_sizeinbase(s,2)-1; j >= 1; j--) { /* ql = ql*qh (mod n) */ mpz_mul(ql, ql, qh); mpz_mod(ql, ql, n); if (mpz_tstbit(s,j) == 1) { /* qh = ql*q */ mpz_mul_si(qh, ql, q); /* uh = uh*vh (mod n) */ mpz_mul(uh, uh, vh); mpz_mod(uh, uh, n); /* vl = vh*vl - p*ql (mod n) */ mpz_mul(vl, vh, vl); mpz_mul_si(tmp, ql, p); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n); /* vh = vh*vh - 2*qh (mod n) */ mpz_mul(vh, vh, vh); mpz_mul_si(tmp, qh, 2); mpz_sub(vh, vh, tmp); mpz_mod(vh, vh, n); } else { /* qh = ql */ mpz_set(qh, ql); /* uh = uh*vl - ql (mod n) */ mpz_mul(uh, uh, vl); mpz_sub(uh, uh, ql); mpz_mod(uh, uh, n); /* vh = vh*vl - p*ql (mod n) */ mpz_mul(vh, vh, vl); mpz_mul_si(tmp, ql, p); mpz_sub(vh, vh, tmp); mpz_mod(vh, vh, n); /* vl = vl*vl - 2*ql (mod n) */ mpz_mul(vl, vl, vl); mpz_mul_si(tmp, ql, 2); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n); } } /* ql = ql*qh */ mpz_mul(ql, ql, qh); /* qh = ql*q */ mpz_mul_si(qh, ql, q); /* uh = uh*vl - ql */ mpz_mul(uh, uh, vl); mpz_sub(uh, uh, ql); /* vl = vh*vl - p*ql */ mpz_mul(vl, vh, vl); mpz_mul_si(tmp, ql, p); mpz_sub(vl, vl, tmp); /* ql = ql*qh */ mpz_mul(ql, ql, qh); mpz_mod(uh, uh, n); mpz_mod(vl, vl, n); /* tmp = n-2, for the following comparison */ mpz_sub_ui(tmp, n, 2); /* uh contains LucasU_s and vl contains LucasV_s */ if (((mpz_cmp_ui(uh, 0) == 0) && ((mpz_cmp(vl, tmp) == 0) || (mpz_cmp_si(vl, 2) == 0))) || (mpz_cmp_ui(vl, 0) == 0)) { mpz_clear(zD); mpz_clear(s); mpz_clear(nmj); mpz_clear(res); mpz_clear(uh); mpz_clear(vl); mpz_clear(vh); mpz_clear(ql); mpz_clear(qh); mpz_clear(tmp); return PRP_PRP; } for (j = 1; j < r-1; j++) { /* vl = vl*vl - 2*ql (mod n) */ mpz_mul(vl, vl, vl); mpz_mul_si(tmp, ql, 2); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n); /* ql = ql*ql (mod n) */ mpz_mul(ql, ql, ql); mpz_mod(ql, ql, n); if (mpz_cmp_ui(vl, 0) == 0) { mpz_clear(zD); mpz_clear(s); mpz_clear(nmj); mpz_clear(res); mpz_clear(uh); mpz_clear(vl); mpz_clear(vh); mpz_clear(ql); mpz_clear(qh); mpz_clear(tmp); return PRP_PRP; } } mpz_clear(zD); mpz_clear(s); mpz_clear(nmj); mpz_clear(res); mpz_clear(uh); mpz_clear(vl); mpz_clear(vh); mpz_clear(ql); mpz_clear(qh); mpz_clear(tmp); return PRP_COMPOSITE; }/* method mpz_extrastronglucas_prp */
/* ******************************************************************************* * mpz_lucas_prp: * A "Lucas pseudoprime" with parameters (P,Q) is a composite n with D=P^2-4Q, * (n,2QD)=1 such that U_(n-(D/n)) == 0 mod n [(D/n) is the Jacobi symbol] * *******************************************************************************/ int mpz_lucas_prp(mpz_t n, long int p, long int q) { mpz_t zD; mpz_t res; mpz_t index; mpz_t uh, vl, vh, ql, qh, tmp; /* used for calculating the Lucas U sequence */ int s = 0, j = 0; int ret = 0; long int d = p*p - 4*q; if (d == 0) /* Does not produce a proper Lucas sequence */ return PRP_ERROR; if (mpz_cmp_ui(n, 2) < 0) return PRP_COMPOSITE; if (mpz_divisible_ui_p(n, 2)) { if (mpz_cmp_ui(n, 2) == 0) return PRP_PRIME; else return PRP_COMPOSITE; } mpz_init(index); mpz_init_set_si(zD, d); mpz_init(res); mpz_mul_si(res, zD, q); mpz_mul_ui(res, res, 2); mpz_gcd(res, res, n); if ((mpz_cmp(res, n) != 0) && (mpz_cmp_ui(res, 1) > 0)) { mpz_clear(zD); mpz_clear(res); mpz_clear(index); return PRP_COMPOSITE; } /* index = n-(D/n), where (D/n) is the Jacobi symbol */ mpz_set(index, n); ret = mpz_jacobi(zD, n); if (ret == -1) mpz_add_ui(index, index, 1); else if (ret == 1) mpz_sub_ui(index, index, 1); /* mpz_lucasumod(res, p, q, index, n); */ mpz_init_set_si(uh, 1); mpz_init_set_si(vl, 2); mpz_init_set_si(vh, p); mpz_init_set_si(ql, 1); mpz_init_set_si(qh, 1); mpz_init_set_si(tmp,0); s = mpz_scan1(index, 0); for (j = mpz_sizeinbase(index,2)-1; j >= s+1; j--) { /* ql = ql*qh (mod n) */ mpz_mul(ql, ql, qh); mpz_mod(ql, ql, n); if (mpz_tstbit(index,j) == 1) { /* qh = ql*q */ mpz_mul_si(qh, ql, q); /* uh = uh*vh (mod n) */ mpz_mul(uh, uh, vh); mpz_mod(uh, uh, n); /* vl = vh*vl - p*ql (mod n) */ mpz_mul(vl, vh, vl); mpz_mul_si(tmp, ql, p); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n); /* vh = vh*vh - 2*qh (mod n) */ mpz_mul(vh, vh, vh); mpz_mul_si(tmp, qh, 2); mpz_sub(vh, vh, tmp); mpz_mod(vh, vh, n); } else { /* qh = ql */ mpz_set(qh, ql); /* uh = uh*vl - ql (mod n) */ mpz_mul(uh, uh, vl); mpz_sub(uh, uh, ql); mpz_mod(uh, uh, n); /* vh = vh*vl - p*ql (mod n) */ mpz_mul(vh, vh, vl); mpz_mul_si(tmp, ql, p); mpz_sub(vh, vh, tmp); mpz_mod(vh, vh, n); /* vl = vl*vl - 2*ql (mod n) */ mpz_mul(vl, vl, vl); mpz_mul_si(tmp, ql, 2); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n); } } /* ql = ql*qh */ mpz_mul(ql, ql, qh); /* qh = ql*q */ mpz_mul_si(qh, ql, q); /* uh = uh*vl - ql */ mpz_mul(uh, uh, vl); mpz_sub(uh, uh, ql); /* vl = vh*vl - p*ql */ mpz_mul(vl, vh, vl); mpz_mul_si(tmp, ql, p); mpz_sub(vl, vl, tmp); /* ql = ql*qh */ mpz_mul(ql, ql, qh); for (j = 1; j <= s; j++) { /* uh = uh*vl (mod n) */ mpz_mul(uh, uh, vl); mpz_mod(uh, uh, n); /* vl = vl*vl - 2*ql (mod n) */ mpz_mul(vl, vl, vl); mpz_mul_si(tmp, ql, 2); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n); /* ql = ql*ql (mod n) */ mpz_mul(ql, ql, ql); mpz_mod(ql, ql, n); } mpz_mod(res, uh, n); /* uh contains our return value */ mpz_clear(zD); mpz_clear(index); mpz_clear(uh); mpz_clear(vl); mpz_clear(vh); mpz_clear(ql); mpz_clear(qh); mpz_clear(tmp); if (mpz_cmp_ui(res, 0) == 0) { mpz_clear(res); return PRP_PRP; } else { mpz_clear(res); return PRP_COMPOSITE; } }/* method mpz_lucas_prp */
/* ************************************************************************* * mpz_fibonacci_prp: * A "Fibonacci pseudoprime" with parameters (P,Q), P > 0, Q=+/-1, is a * composite n for which V_n == P mod n * [V is the Lucas V sequence with parameters P,Q] * *************************************************************************/ int mpz_fibonacci_prp(mpz_t n, long int p, long int q) { mpz_t pmodn, zP; mpz_t vl, vh, ql, qh, tmp; /* used for calculating the Lucas V sequence */ int s = 0, j = 0; if (p*p-4*q == 0) return PRP_ERROR; if (((q != 1) && (q != -1)) || (p <= 0)) return PRP_ERROR; if (mpz_cmp_ui(n, 2) < 0) return PRP_COMPOSITE; if (mpz_divisible_ui_p(n, 2)) { if (mpz_cmp_ui(n, 2) == 0) return PRP_PRIME; else return PRP_COMPOSITE; } mpz_init_set_ui(zP, p); mpz_init(pmodn); mpz_mod(pmodn, zP, n); /* mpz_lucasvmod(res, p, q, n, n); */ mpz_init_set_si(vl, 2); mpz_init_set_si(vh, p); mpz_init_set_si(ql, 1); mpz_init_set_si(qh, 1); mpz_init_set_si(tmp,0); s = mpz_scan1(n, 0); for (j = mpz_sizeinbase(n,2)-1; j >= s+1; j--) { /* ql = ql*qh (mod n) */ mpz_mul(ql, ql, qh); mpz_mod(ql, ql, n); if (mpz_tstbit(n,j) == 1) { /* qh = ql*q */ mpz_mul_si(qh, ql, q); /* vl = vh*vl - p*ql (mod n) */ mpz_mul(vl, vh, vl); mpz_mul_si(tmp, ql, p); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n); /* vh = vh*vh - 2*qh (mod n) */ mpz_mul(vh, vh, vh); mpz_mul_si(tmp, qh, 2); mpz_sub(vh, vh, tmp); mpz_mod(vh, vh, n); } else { /* qh = ql */ mpz_set(qh, ql); /* vh = vh*vl - p*ql (mod n) */ mpz_mul(vh, vh, vl); mpz_mul_si(tmp, ql, p); mpz_sub(vh, vh, tmp); mpz_mod(vh, vh, n); /* vl = vl*vl - 2*ql (mod n) */ mpz_mul(vl, vl, vl); mpz_mul_si(tmp, ql, 2); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n); } } /* ql = ql*qh */ mpz_mul(ql, ql, qh); /* qh = ql*q */ mpz_mul_si(qh, ql, q); /* vl = vh*vl - p*ql */ mpz_mul(vl, vh, vl); mpz_mul_si(tmp, ql, p); mpz_sub(vl, vl, tmp); /* ql = ql*qh */ mpz_mul(ql, ql, qh); for (j = 1; j <= s; j++) { /* vl = vl*vl - 2*ql (mod n) */ mpz_mul(vl, vl, vl); mpz_mul_si(tmp, ql, 2); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n); /* ql = ql*ql (mod n) */ mpz_mul(ql, ql, ql); mpz_mod(ql, ql, n); } mpz_mod(vl, vl, n); /* vl contains our return value */ if (mpz_cmp(vl, pmodn) == 0) { mpz_clear(zP); mpz_clear(pmodn); mpz_clear(vl); mpz_clear(vh); mpz_clear(ql); mpz_clear(qh); mpz_clear(tmp); return PRP_PRP; } mpz_clear(zP); mpz_clear(pmodn); mpz_clear(vl); mpz_clear(vh); mpz_clear(ql); mpz_clear(qh); mpz_clear(tmp); return PRP_COMPOSITE; }/* method mpz_fibonacci_prp */
void w3j_intterm(mpz_t sum, long j1, long j2, long j3, long m1, long m2, long m3) { mpz_t term,h; mpz_init(term); mpz_init(h); long I1 = 0; if(j1-j3+m2>I1) I1=j1-j3+m2; if(j2-j3-m1>I1) I1=j2-j3-m1; long I2 = j1+j2-j3; if(j1-m1<I2) I2=j1-m1; if(j2+m2<I2) I2=j2+m2; mpz_set_ui(sum,0); long sgn=1; if(iabs(I1)%2==1) sgn=-1; for(long k=I1; k<=I2; k++) { // sum+=sgn*binomialCoefficient(j1+j2-j3,k)*binomialCoefficient(j1-j2+j3,j1-m1-k) // *binomialCoefficient(-j1+j2+j3,j2+m2-k); binomialCoefficient(term, j1+j2-j3, k); binomialCoefficient(h,j1-j2+j3,j1-m1-k); mpz_mul(term,term,h); binomialCoefficient(h,-j1+j2+j3,j2+m2-k); mpz_mul(term,term,h); mpz_mul_si(term,term,sgn); mpz_add(sum,sum,term); sgn*= -1; } mpz_clear(h); mpz_clear(term); }