/*------------------------------------------------------------------------*/ static uint32 lift_roots(sieve_fb_t *s, curr_poly_t *c, uint64 p, uint32 num_roots) { uint32 i; uint32 degree = s->degree; uint64_2gmp(p, s->p); mpz_mul(s->p2, s->p, s->p); mpz_tdiv_r(s->nmodp2, c->trans_N, s->p2); mpz_sub(s->tmp1, c->trans_m0, c->mp_sieve_size); mpz_tdiv_r(s->m0, s->tmp1, s->p2); for (i = 0; i < num_roots; i++) { mpz_powm_ui(s->tmp1, s->roots[i], (mp_limb_t)degree, s->p2); mpz_sub(s->tmp1, s->nmodp2, s->tmp1); if (mpz_cmp_ui(s->tmp1, (mp_limb_t)0) < 0) mpz_add(s->tmp1, s->tmp1, s->p2); mpz_tdiv_q(s->tmp1, s->tmp1, s->p); mpz_powm_ui(s->tmp2, s->roots[i], (mp_limb_t)(degree-1), s->p); mpz_mul_ui(s->tmp2, s->tmp2, (mp_limb_t)degree); mpz_invert(s->tmp2, s->tmp2, s->p); mpz_mul(s->tmp1, s->tmp1, s->tmp2); mpz_tdiv_r(s->tmp1, s->tmp1, s->p); mpz_addmul(s->roots[i], s->tmp1, s->p); mpz_sub(s->roots[i], s->roots[i], s->m0); if (mpz_cmp_ui(s->roots[i], (mp_limb_t)0) < 0) mpz_add(s->roots[i], s->roots[i], s->p2); } return num_roots; }
int is_residue_test(){ printf("\n\nTesting the is_residue function\n"); if(debug)printf("testing is residue for a residue\n"); unsigned int test_prime = 7; unsigned int test_rand = 2384832; mpz_t p; mpz_init_set_ui(p,test_prime); if(debug){ printf("\ninitial p:"); mpz_out_str(stdout,10,p); printf("\n"); } mpz_t p2; mpz_init_set_ui(p2,test_rand); mpz_mul(p2,p2,p2); if(debug){ printf("\ninitial p2:"); mpz_out_str(stdout,10,p2); printf("\n"); } mpz_tdiv_r(p2,p2,p); if(debug){ printf("initial p2^2 (mod p):"); mpz_out_str(stdout,10,p2); printf("\n"); } int result1 = is_residue_modp(p2,p); if(debug)printf("is_residue returns %d for the residue\n", result1); unsigned int test_prime2 = 19; unsigned int test_rand2 = 348909; mpz_t q; mpz_init_set_ui(q,test_prime2); mpz_t q2; mpz_init_set_ui(q2,test_rand2); mpz_mul(q2, q2, p); mpz_tdiv_r(q2,q2,q); int result2 = is_residue_modp(q2,q); if(debug)printf("is_residue returns %d for the nonresidue\n", result2); int res = !result1||result2; if(!res) printf("is_residue PASSED!\n"); else printf("is_residue FAILED!\n"); return res; //if 1 is false or 2 is true then we fail }
void ovm_q_rem(oregister_t *l, oregister_t *r) { switch (r->t) { case t_void: ovm_raise(except_floating_point_error); case t_word: if (r->v.w == 0) ovm_raise(except_floating_point_error); if (r->v.w > 0) mpz_mul_ui(ozr(r), ozs(l), r->v.w); else { mpz_set_si(ozr(r), r->v.w); mpz_mul(ozr(r), ozs(l), ozr(r)); } mpz_tdiv_r(ozr(l), ozr(l), ozr(r)); mpq_canonicalize(oqr(l)); check_mpq(l); break; case t_float: l->t = t_float; l->v.d = fmod(mpq_get_d(oqr(l)), r->v.d); break; case t_mpz: mpz_mul(ozr(r), ozs(l), ozr(r)); mpz_tdiv_r(ozr(l), ozr(l), ozr(r)); check_mpq(l); break; case t_rat: mpq_set_si(oqr(r), rat_num(r->v.r), rat_den(r->v.r)); case t_mpq: mpq_div(oqr(l), oqr(l), oqr(r)); mpz_tdiv_r(ozr(l), ozr(l), ozs(l)); mpz_mul(ozs(l), ozs(l), ozs(r)); mpq_canonicalize(oqr(l)); if (mpq_sgn(oqr(r)) < 0) mpq_neg(oqr(l), oqr(l)); check_mpq(l); break; case t_mpr: l->t = t_mpr; mpfr_set_q(orr(l), oqr(l), thr_rnd); mpfr_fmod(orr(l), orr(l), orr(r), thr_rnd); break; default: ovm_raise(except_not_a_real_number); } }
double PrimeTester::EulerLagrangeLifchitzTest(const Bn& primePrev, bool bSophieGermain) { ((m_tmpNext = primePrev) <<= 1) += bSophieGermain ? 1 : -1; unsigned mod = m_tmpNext.get_ui() % 8; if (bSophieGermain) { mpz_powm(m_tmp_R.get_mpz_t(), BN_2.get_mpz_t(), primePrev.get_mpz_t(), m_tmpNext.get_mpz_t()); } else { mpz_sub_ui(m_tmp_N_Minus1.get_mpz_t(), primePrev.get_mpz_t(), 1); mpz_powm(m_tmp_R.get_mpz_t(), BN_2.get_mpz_t(), m_tmp_N_Minus1.get_mpz_t(), m_tmpNext.get_mpz_t()); } if (mod == (bSophieGermain ? 7 : 1)) { if (m_tmp_R==1) return 1; } else if (mod == (bSophieGermain ? 3 : 5)) { mpz_add_ui(m_tmp_T.get_mpz_t(), m_tmp_R.get_mpz_t(), 1); if (m_tmp_T == m_tmpNext) return 1; } mpz_mul(m_tmp_T.get_mpz_t(), m_tmp_R.get_mpz_t(), m_tmp_R.get_mpz_t()); mpz_tdiv_r(m_tmp_R.get_mpz_t(), m_tmp_T.get_mpz_t(), m_tmpNext.get_mpz_t()); // derive Fermat test remainder m_tmp_T = (m_tmpNext - m_tmp_R) << 24; mpz_tdiv_q(m_tmp_T.get_mpz_t(), m_tmp_T.get_mpz_t(), m_tmpNext.get_mpz_t()); int64_t len = m_tmp_T.get_ui(); // if (!(((n - r) << FRACTIONAL_BITS) / n).AsInt64(len) || len >= (1<<FRACTIONAL_BITS)) // Throw(E_FAIL); return double(len) / (1 << FRACTIONAL_BITS); }
void mpz_fdiv_r (mpz_ptr rem, mpz_srcptr dividend, mpz_srcptr divisor) { mp_size_t divisor_size = SIZ (divisor); mpz_t temp_divisor; /* N.B.: lives until function returns! */ TMP_DECL; TMP_MARK; /* We need the original value of the divisor after the remainder has been preliminary calculated. We have to copy it to temporary space if it's the same variable as REM. */ if (rem == divisor) { MPZ_TMP_INIT (temp_divisor, ABS (divisor_size)); mpz_set (temp_divisor, divisor); divisor = temp_divisor; } mpz_tdiv_r (rem, dividend, divisor); if ((divisor_size ^ SIZ (dividend)) < 0 && SIZ (rem) != 0) mpz_add (rem, rem, divisor); TMP_FREE; }
/* functions */ u3_noun u3qa_mod(u3_atom a, u3_atom b) { #if 0 if ( b == 3 && a == 2684227708 ) { printf("dword at 0x27ff84ff8 is %" PRIu64 "\r\n", *(c3_d *)0x27ff84ff8); *(c3_d *)0x27ff84ff8 = 25; printf("see, we modified it\r\n"); } #endif if ( 0 == b ) { return u3m_bail(c3__exit); } else { mpz_t a_mp, b_mp; u3r_mp(a_mp, a); u3r_mp(b_mp, b); mpz_tdiv_r(a_mp, a_mp, b_mp); mpz_clear(b_mp); return u3i_mp(a_mp); } }
void mpz_mod (mpz_ptr rem, mpz_srcptr dividend, mpz_srcptr divisor) { mp_size_t divisor_size = divisor->_mp_size; mpz_t temp_divisor; /* N.B.: lives until function returns! */ TMP_DECL (marker); TMP_MARK (marker); /* We need the original value of the divisor after the remainder has been preliminary calculated. We have to copy it to temporary space if it's the same variable as REM. */ if (rem == divisor) { MPZ_TMP_INIT (temp_divisor, ABS (divisor_size)); mpz_set (temp_divisor, divisor); divisor = temp_divisor; } mpz_tdiv_r (rem, dividend, divisor); if (rem->_mp_size != 0) { if (dividend->_mp_size < 0) { if (divisor->_mp_size < 0) mpz_sub (rem, rem, divisor); else mpz_add (rem, rem, divisor); } } TMP_FREE (marker); }
void qsieve_muladddiv(mpz_t x, mpz_t y, mpz_t z, mpz_t w, mpz_t q, mpz_t r) { mpz_mul(TB, x, y); if(x != z && y != z) mpz_add(TB, TB, z); if(q != r) mpz_tdiv_r(r, TB, w); if(w != q) qsieve_divide(TB, w, q); }
void qsieve_divide(mpz_t x, mpz_t y, mpz_t z) { if(x != z) mpz_tdiv_r(TD, x, y); if(y != z) mpz_tdiv_q(TC, x, y); if(x != z) if(TD!=x) mpz_set(x, TD); if(y != z) if(TC!=z) mpz_set(z, TC); }
static PyObject * Pygmpy_t_mod(PyObject *self, PyObject *args) { PyObject *x, *y; PympzObject *r, *tempx, *tempy; if(PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("t_mod() requires 'mpz','mpz' arguments"); return NULL; } x = PyTuple_GET_ITEM(args, 0); y = PyTuple_GET_ITEM(args, 1); if (!(r = Pympz_new())) return NULL; if (CHECK_MPZANY(x) && CHECK_MPZANY(y)) { if (mpz_sgn(Pympz_AS_MPZ(y)) == 0) { ZERO_ERROR("t_mod() division by 0"); Py_DECREF((PyObject*)r); return NULL; } mpz_tdiv_r(r->z, Pympz_AS_MPZ(x), Pympz_AS_MPZ(y)); } else { tempx = Pympz_From_Integer(x); tempy = Pympz_From_Integer(y); if (!tempx || !tempy) { TYPE_ERROR("t_mod() requires 'mpz','mpz' arguments"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)r); return NULL; } if (mpz_sgn(Pympz_AS_MPZ(tempy)) == 0) { ZERO_ERROR("t_mod() division by 0"); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); Py_DECREF((PyObject*)r); return NULL; } mpz_tdiv_r(r->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); } return (PyObject*)r; }
static Variant HHVM_FUNCTION(gmp_div_r, const Variant& dataA, const Variant& dataB, int64_t round = GMP_ROUND_ZERO) { mpz_t gmpDataA, gmpDataB, gmpReturn; if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_DIV_R, gmpDataA, dataA)) { return false; } if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_DIV_R, gmpDataB, dataB)) { mpz_clear(gmpDataA); return false; } if (mpz_sgn(gmpDataB) == 0) { mpz_clear(gmpDataA); mpz_clear(gmpDataB); raise_warning(cs_GMP_INVALID_VALUE_MUST_NOT_BE_ZERO, cs_GMP_FUNC_NAME_GMP_DIV_R); return false; } mpz_init(gmpReturn); switch (round) { case GMP_ROUND_ZERO: mpz_tdiv_r(gmpReturn, gmpDataA, gmpDataB); break; case GMP_ROUND_PLUSINF: mpz_cdiv_r(gmpReturn, gmpDataA, gmpDataB); break; case GMP_ROUND_MINUSINF: mpz_fdiv_r(gmpReturn, gmpDataA, gmpDataB); break; default: mpz_clear(gmpDataA); mpz_clear(gmpDataB); mpz_clear(gmpReturn); return null_variant; } mpz_clear(gmpDataA); mpz_clear(gmpDataB); Variant ret; if (dataB.isInteger() && dataB.getInt64() >= 0) { ret = (int64_t)mpz_get_ui(gmpReturn); } else { ret = NEWOBJ(GMPResource)(gmpReturn); } mpz_clear(gmpReturn); return ret; }
static Py_hash_t Pympq_hash(PympqObject *self) { #ifdef _PyHASH_MODULUS Py_hash_t hash = 0; mpz_t temp, temp1, mask; if (self->hash_cache != -1) return self->hash_cache; mpz_inoc(temp); mpz_inoc(temp1); mpz_inoc(mask); mpz_set_si(mask, 1); mpz_mul_2exp(mask, mask, _PyHASH_BITS); mpz_sub_ui(mask, mask, 1); if (!mpz_invert(temp, mpq_denref(self->q), mask)) { mpz_cloc(temp); mpz_cloc(temp1); mpz_cloc(mask); hash = _PyHASH_INF; if (mpz_sgn(mpq_numref(self->q))<0) hash = -hash; self->hash_cache = hash; return hash; } mpz_set(temp1, mask); mpz_sub_ui(temp1, temp1, 2); mpz_powm(temp, mpq_denref(self->q), temp1, mask); mpz_tdiv_r(temp1, mpq_numref(self->q), mask); mpz_mul(temp, temp, temp1); hash = (Py_hash_t)mpn_mod_1(temp->_mp_d, mpz_size(temp), _PyHASH_MODULUS); if (mpz_sgn(mpq_numref(self->q))<0) hash = -hash; if (hash==-1) hash = -2; mpz_cloc(temp); mpz_cloc(temp1); mpz_cloc(mask); self->hash_cache = hash; return hash; #else PyObject *temp; if (self->hash_cache != -1) return self->hash_cache; if (!(temp = Pympq_To_PyFloat(self))) { SYSTEM_ERROR("Could not convert 'mpq' to float."); return -1; } self->hash_cache = PyObject_Hash(temp); Py_DECREF(temp); return self->hash_cache; #endif }
void mpz_correct_mod(mpz_t result, mpz_t n, mpz_t d) { mpz_tdiv_r(result, n, d); mpz_t temp; mpz_init(temp); mpz_fdiv_q_2exp(temp, d, 1); if (mpz_cmp(result, temp) > 0) { mpz_sub(result, d, result); } mpz_clear(temp); }
int checkpoly_siqs(siqs_poly *poly, mpz_t n) { //check that b^2 == N mod a //and that c == (b*b - n)/a mpz_t t1,t2,t3,t4; mpz_init(t1); mpz_init(t2); mpz_init(t3); mpz_init(t4); mpz_set(t1, n); mpz_tdiv_r(t3, t1, poly->mpz_poly_a); //zDiv(&t1,&poly->poly_a,&t2,&t3); mpz_mul(t2, poly->mpz_poly_b, poly->mpz_poly_b); //zMul(&poly->poly_b,&poly->poly_b,&t2); mpz_tdiv_r(t4, t2, poly->mpz_poly_a); //zDiv(&t2,&poly->poly_a,&t1,&t4); if (mpz_cmp(t3,t4) != 0) { printf("\nError in checkpoly: %s^2 !== N mod %s\n", mpz_conv2str(&gstr1.s, 10, poly->mpz_poly_b), mpz_conv2str(&gstr2.s, 10, poly->mpz_poly_a)); if (mpz_sgn(poly->mpz_poly_b) < 0) printf("b is negative\n"); } if (mpz_kronecker(n, poly->mpz_poly_a) != 1) printf("\nError in checkpoly: (a|N) != 1\n"); mpz_mul(t2, poly->mpz_poly_b, poly->mpz_poly_b); //zMul(&poly->poly_b,&poly->poly_b,&t2); mpz_sub(t2, t2, n); mpz_tdiv_q(t4, t2, poly->mpz_poly_a); //zDiv(&t2,&poly->poly_a,&t1,&t4); if (mpz_cmp(t4,poly->mpz_poly_c) != 0) printf("\nError in checkpoly: c != (b^2 - n)/a\n"); mpz_clear(t1); mpz_clear(t2); mpz_clear(t3); mpz_clear(t4); return 0; }
obj bignum_remainder( obj a, obj b ) { mpz_t r, a1, b1; OBJ_TO_MPZ(a1, a); OBJ_TO_MPZ(b1, b); mpz_init(r); mpz_tdiv_r(r, a1, b1); return bignum_compact(r); }
void mpz_divexact (mpz_ptr quot, mpz_srcptr num, mpz_srcptr den) { mp_ptr qp; mp_size_t qn; mp_srcptr np, dp; mp_size_t nn, dn; TMP_DECL; #if WANT_ASSERT { mpz_t rem; mpz_init (rem); mpz_tdiv_r (rem, num, den); ASSERT (SIZ(rem) == 0); mpz_clear (rem); } #endif nn = ABSIZ (num); dn = ABSIZ (den); if (nn < dn) { /* This special case avoids segfaults below when the function is incorrectly called with |N| < |D|, N != 0. It also handles the well-defined case N = 0. */ SIZ(quot) = 0; return; } qn = nn - dn + 1; TMP_MARK; if (quot == num || quot == den) qp = TMP_ALLOC_LIMBS (qn); else qp = MPZ_REALLOC (quot, qn); np = PTR(num); dp = PTR(den); mpn_divexact (qp, np, nn, dp, dn); MPN_NORMALIZE (qp, qn); if (qp != PTR(quot)) MPN_COPY (MPZ_REALLOC (quot, qn), qp, qn); SIZ(quot) = (SIZ(num) ^ SIZ(den)) >= 0 ? qn : -qn; TMP_FREE; }
/*------------------------------------------------------------------------*/ static void lift_roots(sieve_fb_t *s, poly_coeff_t *c, uint32 p, uint32 num_roots) { /* we have num_roots arithmetic progressions mod p; convert the progressions to be mod p^2, using Hensel lifting, and then move the origin of the result trans_m0 units to the left. */ uint32 i; unsigned long degree = s->degree; mpz_set_ui(s->p, (unsigned long)p); mpz_mul(s->pp, s->p, s->p); mpz_tdiv_r(s->nmodpp, c->trans_N, s->pp); mpz_tdiv_r(s->tmp3, c->trans_m0, s->pp); for (i = 0; i < num_roots; i++) { uint64_2gmp(s->roots[i], s->gmp_root); mpz_powm_ui(s->tmp1, s->gmp_root, degree, s->pp); mpz_sub(s->tmp1, s->nmodpp, s->tmp1); if (mpz_cmp_ui(s->tmp1, (mp_limb_t)0) < 0) mpz_add(s->tmp1, s->tmp1, s->pp); mpz_tdiv_q(s->tmp1, s->tmp1, s->p); mpz_powm_ui(s->tmp2, s->gmp_root, degree-1, s->p); mpz_mul_ui(s->tmp2, s->tmp2, degree); mpz_invert(s->tmp2, s->tmp2, s->p); mpz_mul(s->tmp1, s->tmp1, s->tmp2); mpz_tdiv_r(s->tmp1, s->tmp1, s->p); mpz_addmul(s->gmp_root, s->tmp1, s->p); mpz_sub(s->gmp_root, s->gmp_root, s->tmp3); if (mpz_cmp_ui(s->gmp_root, (unsigned long)0) < 0) mpz_add(s->gmp_root, s->gmp_root, s->pp); s->roots[i] = gmp2uint64(s->gmp_root); } }
int getRecurringDigits(int n){ int count = 1; mpz_set_si(num, n); mpz_set_si(powTen,10); while(1){ mpz_sub_ui(powTenMinusOne, powTen, 1UL); mpz_tdiv_r(rem, powTenMinusOne, num); if(mpz_cmp_ui(rem,0)==0) { break; } mpz_mul_ui(powTen,powTen,10); count++; } return count; }
static bool EulerLagrangeLifchitzPrimalityTestFast(const mpz_class& n, bool fSophieGermain, unsigned int& nLength, CPrimalityTestParams& testParams) { static const mpz_class mpzTwo = 2; // Faster GMP version mpz_t& mpzE = testParams.mpzE; mpz_t& mpzR = testParams.mpzR; mpz_t& mpzRplusOne = testParams.mpzRplusOne; mpz_sub_ui(mpzE, n.get_mpz_t(), 1); mpz_tdiv_q_2exp(mpzE, mpzE, 1); mpz_powm(mpzR, mpzTwo.get_mpz_t(), mpzE, n.get_mpz_t()); unsigned int nMod8 = mpz_get_ui(n.get_mpz_t()) % 8; bool fPassedTest = false; if (fSophieGermain && (nMod8 == 7)) // Euler & Lagrange fPassedTest = !mpz_cmp_ui(mpzR, 1); else if (fSophieGermain && (nMod8 == 3)) // Lifchitz { mpz_add_ui(mpzRplusOne, mpzR, 1); fPassedTest = !mpz_cmp(mpzRplusOne, n.get_mpz_t()); } else if ((!fSophieGermain) && (nMod8 == 5)) // Lifchitz { mpz_add_ui(mpzRplusOne, mpzR, 1); fPassedTest = !mpz_cmp(mpzRplusOne, n.get_mpz_t()); } else if ((!fSophieGermain) && (nMod8 == 1)) // LifChitz fPassedTest = !mpz_cmp_ui(mpzR, 1); if (fPassedTest) { return true; } // Failed test, calculate fractional length mpz_mul(mpzE, mpzR, mpzR); mpz_tdiv_r(mpzR, mpzE, n.get_mpz_t()); // derive Fermat test remainder mpz_sub(mpzE, n.get_mpz_t(), mpzR); mpz_mul_2exp(mpzR, mpzE, DifficultyFractionalBits); mpz_tdiv_q(mpzE, mpzR, n.get_mpz_t()); unsigned int nFractionalLength = mpz_get_ui(mpzE); nLength = (nLength & DifficultyChainLengthMask) | nFractionalLength; return false; }
/*------------------------------------------------------------------*/ static void compute_remainder_tree(uint32 first, uint32 last, relation_batch_t *rb, mpz_t numerator) { /* recursively compute numerator % (each relation in rb->relations) */ uint32 mid = (first + last) / 2; mpz_t relation_prod, remainder; /* recursion base case: numerator already fits in an mp_t, so manually compute the remainder and postprocess each relation */ if (mpz_size(numerator) * GMP_LIMB_BITS/32 <= MAX_MP_WORDS) { if (mpz_sgn(numerator) > 0) { mp_t num; gmp2mp(numerator, &num); while (first <= last) check_relation(rb, first++, &num); } return; } /* multiply together the unfactored parts of all the relations from first to last */ mpz_init(relation_prod); mpz_init(remainder); multiply_relations(first, last, rb, relation_prod); /* use the remainder to deal with the left and right halves of the relation list */ if (mpz_cmp(numerator, relation_prod) < 0) { mpz_clear(relation_prod); compute_remainder_tree(first, mid, rb, numerator); compute_remainder_tree(mid + 1, last, rb, numerator); } else { mpz_tdiv_r(remainder, numerator, relation_prod); mpz_clear(relation_prod); compute_remainder_tree(first, mid, rb, remainder); compute_remainder_tree(mid + 1, last, rb, remainder); } mpz_clear(remainder); }
/* functions */ u2_weak // transfer j2_mbc(Pt1, mod)(u2_wire wir_r, u2_atom a, // retain u2_atom b) // retain { if ( _0 == b ) { return u2_none; } else { mpz_t a_mp, b_mp; u2_mp(a_mp, a); u2_mp(b_mp, b); mpz_tdiv_r(a_mp, a_mp, b_mp); mpz_clear(b_mp); return u2_rl_mp(wir_r, a_mp); } }
/* u4_op_mod(): ** ** Produce (b % a). */ u4_atom u4_op_mod(u4_lane lane, u4_atom a, u4_atom b) { if ( u4_n_zero(a) ) { return u4_bull; } else { mpz_t mp_a, mp_b; u4_a_gmp(a, mp_a); u4_a_gmp(b, mp_b); mpz_tdiv_r(mp_b, mp_b, mp_a); mpz_clear(mp_a); return u4_k_atom_gmp(lane, mp_b); } }
/* u3_zx_mod_c(): */ u3_fox u3_zx_mod_c(u3_z z, u3_fox a, u3_fox b) { if ( 0 == b ) { return u3_zc_tank(z, c3__exit); } else { mpz_t mp_a, mp_b; u3_lr_mp(z, mp_a, a); u3_lr_mp(z, mp_b, b); mpz_tdiv_r(mp_a, mp_a, mp_b); mpz_clear(mp_b); return u3_zc_mp(z, mp_a); } }
/*-------------------------------------------------------------------------*/ static uint32 check_poly(curr_poly_t *c, mpz_t *coeffs, mpz_t lin0, mpz_t gmp_N, uint32 degree) { uint32 i; mpz_set(c->gmp_help1, coeffs[degree]); mpz_set(c->gmp_help2, c->gmp_p); for (i = degree; i; i--) { mpz_mul(c->gmp_help1, c->gmp_help1, lin0); mpz_neg(c->gmp_help1, c->gmp_help1); mpz_addmul(c->gmp_help1, coeffs[i-1], c->gmp_help2); mpz_mul(c->gmp_help2, c->gmp_help2, c->gmp_p); } mpz_tdiv_r(c->gmp_help1, c->gmp_help1, gmp_N); if (mpz_cmp_ui(c->gmp_help1, (mp_limb_t)0) != 0) { printf("error: corrupt polynomial expand\n"); return 0; } return 1; }
void sieve_xy_run_deg6(root_sieve_t *rs) { uint32 i; sieve_xyz_t *xyz = &rs->xyzdata; int64 z_base = xyz->z_base; sieve_xy_t *xy = &rs->xydata; sieve_prime_t *lattice_primes = xy->lattice_primes; uint32 num_lattice_primes; msieve_obj *obj = rs->data->obj; double direction[3] = {0, 1, 0}; double line_min, line_max; uint16 cutoff_score; xydata_t xydata[MAX_CRT_FACTORS]; plane_heap_t plane_heap; uint64 inv_xy; uint64 inv_xyz; compute_line_size(rs->max_norm, &rs->apoly, rs->dbl_p, rs->dbl_d, direction, -10000, 10000, &line_min, &line_max); if (line_min > line_max) return; num_lattice_primes = xy->num_lattice_primes = find_lattice_primes(rs->primes, rs->num_primes, xyz->lattice_size, lattice_primes, &xy->lattice_size, line_max - line_min); inv_xy = mp_modinv_2(xyz->lattice_size, xy->lattice_size); inv_xyz = mp_modinv_2(xy->lattice_size, xyz->lattice_size); uint64_2gmp(xy->lattice_size, xy->tmp1); uint64_2gmp(inv_xy, xy->tmp2); uint64_2gmp(xyz->lattice_size, xy->tmp3); uint64_2gmp(inv_xyz, xy->tmp4); mpz_mul(xy->mp_lattice_size, xy->tmp1, xy->tmp3); mpz_mul(xy->crt0, xy->tmp2, xy->tmp3); mpz_mul(xy->crt1, xy->tmp1, xy->tmp4); xy->dbl_lattice_size = mpz_get_d(xy->mp_lattice_size); xydata_alloc(lattice_primes, num_lattice_primes, xyz->lattice_size, xydata); plane_heap.num_entries = 0; for (i = 0; i < xyz->num_lattices; i++) { lattice_t *curr_lattice_xyz = xyz->lattices + i; xydata_init(xydata, num_lattice_primes, curr_lattice_xyz, z_base); find_hits(rs, xydata, num_lattice_primes, i, &plane_heap); } xydata_free(xydata, num_lattice_primes); qsort(plane_heap.entries, plane_heap.num_entries, sizeof(plane_t), compare_planes); cutoff_score = 0.9 * plane_heap.entries[0].plane.score; for (i = 0; i < plane_heap.num_entries; i++) { plane_t *curr_plane = plane_heap.entries + i; lattice_t *lattice_xy = &curr_plane->plane; lattice_t *lattice_xyz = xyz->lattices + curr_plane->which_lattice_xyz; if (lattice_xy->score < cutoff_score) break; line_min = xyz->y_line_min[curr_plane->which_z_block]; line_max = xyz->y_line_max[curr_plane->which_z_block]; z_base = xyz->z_base + curr_plane->which_z_block * xyz->lattice_size; xy->apoly = rs->apoly; xy->apoly.coeff[3] += z_base * rs->dbl_p; xy->apoly.coeff[2] -= z_base * rs->dbl_d; mpz_set_d(xy->tmp1, line_min); mpz_tdiv_q(xy->y_base, xy->tmp1, xy->mp_lattice_size); mpz_mul(xy->y_base, xy->y_base, xy->mp_lattice_size); xy->y_blocks = (line_max - line_min) / xy->dbl_lattice_size; uint64_2gmp(lattice_xy->x, xy->tmp1); uint64_2gmp(lattice_xyz->x, xy->tmp2); mpz_mul(xy->resclass_x, xy->tmp1, xy->crt0); mpz_addmul(xy->resclass_x, xy->tmp2, xy->crt1); uint64_2gmp(lattice_xy->y, xy->tmp1); uint64_2gmp(lattice_xyz->y, xy->tmp2); mpz_mul(xy->resclass_y, xy->tmp1, xy->crt0); mpz_addmul(xy->resclass_y, xy->tmp2, xy->crt1); mpz_tdiv_r(xy->resclass_x, xy->resclass_x, xy->mp_lattice_size); mpz_tdiv_r(xy->resclass_y, xy->resclass_y, xy->mp_lattice_size); xy->curr_score = lattice_xyz->score + lattice_xy->score; rs->curr_z = z_base + lattice_xyz->z; sieve_x_run_deg6(rs); if (obj->flags & MSIEVE_FLAG_STOP_SIEVING) break; } }
int main (int argc, char **argv) { mpz_t dividend, divisor; mpz_t quotient, remainder; mpz_t quotient2, remainder2; mpz_t temp; mp_size_t dividend_size, divisor_size; int i; int reps = 1000; gmp_randstate_ptr rands; mpz_t bs; unsigned long bsi, size_range; tests_start (); TESTS_REPS (reps, argv, argc); rands = RANDS; mpz_init (bs); mpz_init (dividend); mpz_init (divisor); mpz_init (quotient); mpz_init (remainder); mpz_init (quotient2); mpz_init (remainder2); mpz_init (temp); for (i = 0; i < reps; i++) { mpz_urandomb (bs, rands, 32); size_range = mpz_get_ui (bs) % 18 + 2; /* 0..524288 bit operands */ do { mpz_urandomb (bs, rands, size_range); divisor_size = mpz_get_ui (bs); mpz_rrandomb (divisor, rands, divisor_size); } while (mpz_sgn (divisor) == 0); mpz_urandomb (bs, rands, size_range); dividend_size = mpz_get_ui (bs) + divisor_size; mpz_rrandomb (dividend, rands, dividend_size); mpz_urandomb (bs, rands, 2); bsi = mpz_get_ui (bs); if ((bsi & 1) != 0) mpz_neg (dividend, dividend); if ((bsi & 2) != 0) mpz_neg (divisor, divisor); /* printf ("%ld %ld\n", SIZ (dividend), SIZ (divisor)); */ mpz_tdiv_qr (quotient, remainder, dividend, divisor); mpz_tdiv_q (quotient2, dividend, divisor); mpz_tdiv_r (remainder2, dividend, divisor); /* First determine that the quotients and remainders computed with different functions are equal. */ if (mpz_cmp (quotient, quotient2) != 0) dump_abort (dividend, divisor); if (mpz_cmp (remainder, remainder2) != 0) dump_abort (dividend, divisor); /* Check if the sign of the quotient is correct. */ if (mpz_cmp_ui (quotient, 0) != 0) if ((mpz_cmp_ui (quotient, 0) < 0) != ((mpz_cmp_ui (dividend, 0) ^ mpz_cmp_ui (divisor, 0)) < 0)) dump_abort (dividend, divisor); /* Check if the remainder has the same sign as the dividend (quotient rounded towards 0). */ if (mpz_cmp_ui (remainder, 0) != 0) if ((mpz_cmp_ui (remainder, 0) < 0) != (mpz_cmp_ui (dividend, 0) < 0)) dump_abort (dividend, divisor); mpz_mul (temp, quotient, divisor); mpz_add (temp, temp, remainder); if (mpz_cmp (temp, dividend) != 0) dump_abort (dividend, divisor); mpz_abs (temp, divisor); mpz_abs (remainder, remainder); if (mpz_cmp (remainder, temp) >= 0) dump_abort (dividend, divisor); } mpz_clear (bs); mpz_clear (dividend); mpz_clear (divisor); mpz_clear (quotient); mpz_clear (remainder); mpz_clear (quotient2); mpz_clear (remainder2); mpz_clear (temp); tests_end (); exit (0); }
/*------------------------------------------------------------------------*/ static uint32 get_composite_roots(sieve_fb_t *s, curr_poly_t *c, uint32 which_poly, uint64 p, uint32 num_factors, uint32 *factors, uint32 num_roots_min, uint32 num_roots_max) { uint32 i, j, k, i0, i1, i2, i3, i4, i5, i6; uint32 crt_p[MAX_P_FACTORS]; uint32 num_roots[MAX_P_FACTORS]; uint64 prod[MAX_P_FACTORS]; uint32 roots[MAX_P_FACTORS][MAX_POLYSELECT_DEGREE]; aprog_t *aprogs = s->aprog_data.aprogs; uint32 degree = s->degree; for (i = 0, j = 1; i < num_factors; i++) { aprog_t *a; if (i > 0 && factors[i] == factors[i-1]) continue; a = aprogs + factors[i]; if (a->num_roots[which_poly] == 0) return 0; j *= a->num_roots[which_poly]; } if (j < num_roots_min || j > num_roots_max) return INVALID_NUM_ROOTS; for (i = j = 0; j < MAX_P_FACTORS && i < num_factors; i++, j++) { aprog_t *a = aprogs + factors[i]; uint32 power_limit; num_roots[j] = a->num_roots[which_poly]; crt_p[j] = a->p; power_limit = (uint32)(-1) / a->p; for (k = 0; k < num_roots[j]; k++) { roots[j][k] = a->roots[which_poly][k]; } while (i < num_factors - 1 && factors[i] == factors[i+1]) { uint32 nmodp, new_power; if (crt_p[j] > power_limit) return 0; new_power = crt_p[j] * a->p; nmodp = mpz_tdiv_ui(c->trans_N, (mp_limb_t)new_power); for (k = 0; k < num_roots[j]; k++) { roots[j][k] = lift_root_32(nmodp, roots[j][k], crt_p[j], a->p, degree); } crt_p[j] = new_power; i++; } } if (i < num_factors) return 0; num_factors = j; if (num_factors == 1) { for (i = 0; i < num_roots[0]; i++) mpz_set_ui(s->roots[i], (mp_limb_t)roots[0][i]); return num_roots[0]; } for (i = 0; i < num_factors; i++) { prod[i] = p / crt_p[i]; prod[i] = prod[i] * mp_modinv_1((uint32)(prod[i] % crt_p[i]), crt_p[i]); } mpz_set_ui(s->accum[i], (mp_limb_t)0); uint64_2gmp(p, s->p); i0 = i1 = i2 = i3 = i4 = i5 = i6 = i = 0; switch (num_factors) { case 7: for (i6 = num_roots[6] - 1; (int32)i6 >= 0; i6--) { uint64_2gmp(prod[6], s->accum[6]); mpz_mul_ui(s->accum[6], s->accum[6], (mp_limb_t)roots[6][i6]); mpz_add(s->accum[6], s->accum[6], s->accum[7]); case 6: for (i5 = num_roots[5] - 1; (int32)i5 >= 0; i5--) { uint64_2gmp(prod[5], s->accum[5]); mpz_mul_ui(s->accum[5], s->accum[5], (mp_limb_t)roots[5][i5]); mpz_add(s->accum[5], s->accum[5], s->accum[6]); case 5: for (i4 = num_roots[4] - 1; (int32)i4 >= 0; i4--) { uint64_2gmp(prod[4], s->accum[4]); mpz_mul_ui(s->accum[4], s->accum[4], (mp_limb_t)roots[4][i4]); mpz_add(s->accum[4], s->accum[4], s->accum[5]); case 4: for (i3 = num_roots[3] - 1; (int32)i3 >= 0; i3--) { uint64_2gmp(prod[3], s->accum[3]); mpz_mul_ui(s->accum[3], s->accum[3], (mp_limb_t)roots[3][i3]); mpz_add(s->accum[3], s->accum[3], s->accum[4]); case 3: for (i2 = num_roots[2] - 1; (int32)i2 >= 0; i2--) { uint64_2gmp(prod[2], s->accum[2]); mpz_mul_ui(s->accum[2], s->accum[2], (mp_limb_t)roots[2][i2]); mpz_add(s->accum[2], s->accum[2], s->accum[3]); case 2: for (i1 = num_roots[1] - 1; (int32)i1 >= 0; i1--) { uint64_2gmp(prod[1], s->accum[1]); mpz_mul_ui(s->accum[1], s->accum[1], (mp_limb_t)roots[1][i1]); mpz_add(s->accum[1], s->accum[1], s->accum[2]); for (i0 = num_roots[0] - 1; (int32)i0 >= 0; i0--) { uint64_2gmp(prod[0], s->accum[0]); mpz_mul_ui(s->accum[0], s->accum[0], (mp_limb_t)roots[0][i0]); mpz_add(s->accum[0], s->accum[0], s->accum[1]); mpz_tdiv_r(s->accum[0], s->accum[0], s->p); mpz_set(s->roots[i++], s->accum[0]); }}}}}}} } return i; }
int mbrent(fact_obj_t *fobj) { /* run pollard's rho algorithm on n with Brent's modification, returning the first factor found in f, or else 0 for failure. use f(x) = x^2 + c see, for example, bressoud's book. use montgomery arithmetic. */ mpz_t x,y,q,g,ys,t1,t2,cc; uint32 i=0,k,r,m,c; int it; int imax = fobj->rho_obj.iterations; //initialize local arbs mpz_init(x); mpz_init(y); mpz_init(q); mpz_init(g); mpz_init(ys); mpz_init(t1); mpz_init(t2); mpz_init(cc); //starting state of algorithm. r = 1; m = 10; i = 0; it = 0; c = fobj->rho_obj.curr_poly; mpz_set_ui(cc, fobj->rho_obj.polynomials[c]); mpz_set_ui(q, 1); mpz_set_ui(y, 0); mpz_set_ui(g, 1); do { mpz_set(x,y); for(i=0;i<=r;i++) { mpz_mul(t1,y,y); //y = (y*y + c) mod n mpz_add_ui(t1, t1, c); mpz_tdiv_r(t1, t1, fobj->rho_obj.gmp_n); } k=0; do { mpz_set(ys, y); for(i=1;i<=MIN(m,r-k);i++) { mpz_mul(t1,y,y); //y=(y*y + c)%n mpz_add_ui(t1, t1, c); mpz_tdiv_r(y, t1, fobj->rho_obj.gmp_n); mpz_sub(t1, x, y); //q = q*abs(x-y) mod n if (mpz_sgn(t1) < 0) mpz_add(t1, t1, fobj->rho_obj.gmp_n); mpz_mul(q, t1, q); mpz_tdiv_r(q, q, fobj->rho_obj.gmp_n); } mpz_gcd(g, q, fobj->rho_obj.gmp_n); k+=m; it++; if (it>imax) { mpz_set_ui(fobj->rho_obj.gmp_f, 0); goto free; } if (mpz_sgn(g) < 0) mpz_neg(g, g); } while (k<r && (mpz_get_ui(g) == 1)); r*=2; } while (mpz_get_ui(g) == 1); if (mpz_cmp(g,fobj->rho_obj.gmp_n) == 0) { //back track it=0; do { mpz_mul(t1, ys, ys); //ys = (ys*ys + c) mod n mpz_add_ui(t1, t1, c); mpz_tdiv_r(ys, t1, fobj->rho_obj.gmp_n); mpz_sub(t1, ys, x); if (mpz_sgn(t1) < 0) mpz_add(t1, t1, fobj->rho_obj.gmp_n); mpz_gcd(g, t1, fobj->rho_obj.gmp_n); it++; if (it>imax) { mpz_set_ui(fobj->rho_obj.gmp_f, 0); goto free; } if (mpz_sgn(g) < 0) mpz_neg(g, g); } while ((mpz_size(g) == 1) && (mpz_get_ui(g) == 1)); if (mpz_cmp(g,fobj->rho_obj.gmp_n) == 0) { mpz_set_ui(fobj->rho_obj.gmp_f, 0); goto free; } else { mpz_set(fobj->rho_obj.gmp_f, g); goto free; } } else { mpz_set(fobj->rho_obj.gmp_f, g); goto free; } free: if (VFLAG >= 0) printf("\n"); mpz_clear(x); mpz_clear(y); mpz_clear(q); mpz_clear(g); mpz_clear(ys); mpz_clear(t1); mpz_clear(t2); mpz_clear(cc); return it; }
mpz_t* modBigInt(mpz_t x, mpz_t y) { mpz_t* answer = EMALLOC(sizeof(mpz_t)); mpz_tdiv_r(*answer, x, y); return answer; }
static int pol_expand(curr_poly_t *c, mpz_t gmp_N, mpz_t high_coeff, mpz_t gmp_p, mpz_t gmp_d, double coeff_bound, uint32 degree) { uint32 i, j; if (mpz_cmp_ui(c->gmp_p, (mp_limb_t)1) == 0) mpz_set_ui(c->gmp_help1, (mp_limb_t)1); else { if (!mpz_invert(c->gmp_help1, gmp_d, gmp_p)) return 0; } mpz_set(c->gmp_b[1], c->gmp_help1); for (i = 2; i < degree; i++) mpz_mul(c->gmp_b[i], c->gmp_b[i-1], c->gmp_help1); mpz_set(c->gmp_c[1], gmp_d); for (i = 2; i <= degree; i++) mpz_mul(c->gmp_c[i], c->gmp_c[i-1], gmp_d); mpz_set(c->gmp_a[degree], high_coeff); mpz_set(c->gmp_help2, gmp_N); for (i = degree - 1; (int32)i >= 0; i--) { mpz_mul(c->gmp_help3, c->gmp_a[i+1], c->gmp_c[i+1]); mpz_sub(c->gmp_help3, c->gmp_help2, c->gmp_help3); mpz_tdiv_q(c->gmp_help2, c->gmp_help3, gmp_p); if (i > 0) { mpz_tdiv_q(c->gmp_a[i], c->gmp_help2, c->gmp_c[i]); mpz_mul(c->gmp_help3, c->gmp_help2, c->gmp_b[i]); mpz_sub(c->gmp_help3, c->gmp_help3, c->gmp_a[i]); mpz_tdiv_r(c->gmp_help4, c->gmp_help3, gmp_p); if (mpz_sgn(c->gmp_help4) < 0) mpz_add(c->gmp_help4, c->gmp_help4, gmp_p); mpz_add(c->gmp_a[i], c->gmp_a[i], c->gmp_help4); } } mpz_set(c->gmp_a[0], c->gmp_help2); mpz_tdiv_q_2exp(c->gmp_help1, gmp_d, (mp_limb_t)1); for (i = 0; i < degree; i++) { for (j = 0; j < MAX_CORRECT_STEPS && mpz_cmpabs(c->gmp_a[i], c->gmp_help1) > 0; j++) { if (mpz_sgn(c->gmp_a[i]) < 0) { mpz_add(c->gmp_a[i], c->gmp_a[i], gmp_d); mpz_sub(c->gmp_a[i+1], c->gmp_a[i+1], gmp_p); } else { mpz_sub(c->gmp_a[i], c->gmp_a[i], gmp_d); mpz_add(c->gmp_a[i+1], c->gmp_a[i+1], gmp_p); } } if (j == MAX_CORRECT_STEPS) return 0; } #if 0 gmp_printf("%+Zd\n", c->gmp_lina[0]); gmp_printf("%+Zd\n", c->gmp_lina[1]); for (i = 0; i <= degree; i++) gmp_printf("%+Zd\n", c->gmp_a[i]); printf("coeff ratio = %.5lf\n", fabs(mpz_get_d(c->gmp_a[degree-2])) / coeff_bound); #endif if (check_poly(c, c->gmp_a, c->gmp_lina[0], gmp_N, degree) != 1) { return 0; } if (mpz_cmpabs_d(c->gmp_a[degree - 2], coeff_bound) > 0) { return 1; } return 2; }