void checkprimes (unsigned long p1, unsigned long p2, unsigned long p3) { mpz_t b, f; if (p1 - 1 != p2 - 1 + p3 - 1) { printf ("checkprimes(%lu, %lu, %lu) wrong\n", p1, p2, p3); printf (" %lu - 1 != %lu - 1 + %lu - 1 \n", p1, p2, p3); abort (); } mpz_init (b); mpz_init (f); checkWilson (b, p1); /* b = (p1-1)! */ checkWilson (f, p2); /* f = (p2-1)! */ mpz_divexact (b, b, f); checkWilson (f, p3); /* f = (p3-1)! */ mpz_divexact (b, b, f); /* b = (p1-1)!/((p2-1)!(p3-1)!) */ mpz_bin_uiui (f, p1 - 1, p2 - 1); if (mpz_cmp (f, b) != 0) { printf ("checkprimes(%lu, %lu, %lu) wrong\n", p1, p2, p3); printf (" got "); mpz_out_str (stdout, 10, b); printf("\n"); printf (" want "); mpz_out_str (stdout, 10, f); printf("\n"); abort (); } mpz_clear (b); mpz_clear (f); }
/** * Computes the product of the first w primes such that the product <= B */ void mpz_bounded_primorial(int* w, mpz_t primorial, mpz_t phi, const mpz_t B) { mpz_t p; mpz_t t; if (mpz_cmp_ui(B, 1) <= 0) { mpz_set_ui(primorial, 0); mpz_set_ui(phi, 0); *w = 0; return; } mpz_init_set_ui(p, 1); mpz_init(t); mpz_set_ui(primorial, 1); mpz_set_ui(phi, 1); *w = 0; do { mpz_nextprime(p, p); (*w) ++; mpz_mul(primorial, primorial, p); mpz_sub_ui(t, p, 1); mpz_mul(phi, phi, t); } while (mpz_cmp(primorial, B) <= 0); mpz_divexact(primorial, primorial, p); mpz_divexact(phi, phi, t); (*w) --; mpz_clear(p); mpz_clear(t); }
void Qdet(mpq_t D, Qmat Min) { Qmat M; int n, i, j, k; mpz_t tmp, Dnum, Dden; n = Min->nrows; if (n == 1) { mpq_set(det, Min->entry[0][0]); return; } M = Qmat(n, n); for (i=0; i < n; i++) for (j=0; j < n; j++) mpq_set(M->entry[i][j], Min->entry[i][j]); compute_row_lcm(row_lcm, M); compute_col_lcm(col_lcm, M); mpz_init(tmp); mpz_init(Dnum); mpz_init_set_ui(Dden, 1); while ((k = choose_row_or_col(M, row_lcm, col_lcm))) { if (k > 0) /* the choice was row k-1 */ { i = k-1; mpz_mul(Dden, Dden, row_lcm[i]); for (j=0; j < n; j++) { mpz_divexact(tmp, row_lcm[i], mpq_denref(M->entry[i][j])); mpz_mul(mpq_numref(M->entry[i][j]), mpq_numref(M->entry[i][j]), tmp); } compute_col_lcm(col_lcm, M); } else /* the choice was col -k-1 */ { j = -k-1; mpz_mul(Dden, Dden, col_lcm[j]); for (i=0; i < n; i++) { mpz_divexact(tmp, col_lcm[j], mpq_denref(M->entry[i][j])); mpz_mul(mpq_numref(M->entry[i][j]), mpq_numref(M->entry[i][j]), tmp); } compute_row_lcm(row_lcm, M); } } mpz_clear(tmp); { Zmat M_integer; M_integer = Zmat_ctor(n, n); for (i=0; i < n; i++) for (j=0; j < n; j++) mpz_set(M_integer[i][j], mpq_numref(M->entry[i][j])); Zdet(Dnum, M_integer); Zmat_dtor(M_integer); mpz_set(mpq_numref(D), Dnum); mpz_set(mpq_denref(D), Dden); mpq_canonicalize(D); } Qmat_dtor(M); }
static PyObject * GMPy_MPZ_Function_Divexact(PyObject *self, PyObject *args) { PyObject *x, *y; MPZ_Object *result, *tempx= NULL, *tempy = NULL; if(PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("divexact() requires 'mpz','mpz' arguments"); return NULL; } if (!(result = GMPy_MPZ_New(NULL))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } x = PyTuple_GET_ITEM(args, 0); y = PyTuple_GET_ITEM(args, 1); if (MPZ_Check(x) && MPZ_Check(y)) { if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("divexact() division by 0"); Py_DECREF((PyObject*)result); return NULL; } mpz_divexact(result->z, MPZ(x), MPZ(y)); } else { if (!(tempx = GMPy_MPZ_From_Integer(x, NULL)) || !(tempy = GMPy_MPZ_From_Integer(y, NULL))) { TYPE_ERROR("divexact() requires 'mpz','mpz' arguments"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } if (mpz_sgn(MPZ(tempy)) == 0) { ZERO_ERROR("divexact() division by 0"); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } mpz_divexact(result->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); } return (PyObject*)result; }
/* * Store a value in a PP structure. * Input: * pp_pp* pp: pointer to the PP structure to store in * mpq_t value: the value to store * int parent: the parent to refer to * int self: TRUE if value represents 1/parent, FALSE if it represents the * resolution of pp[parent] * Returns: * Nothing. * Effect: * The specified value is stored in the specified PP structure, with a * reference to the specified parent. Internal variables are updated * accordingly. * * For a given value q, the caller is expected to have determined the * greatest prime power p^k dividing the denominator of q. In this case, * the pp structure should be that for p^k. * * The parent is used solely for determining a final solution vector. * If the value is a source value (i.e. 1/r representing the integer * r in the solution vector), the parent should be set to r, and self should * be TRUE. If not, the parent is assumed to be a fully resolved PP structure * storing a walk result that specifies the actual vector contribution * (possibly recursively), and self should be FALSE. */ void pp_save_any(pp_pp* pp, mpq_t value, int parent, int self) { int i; mpz_t zvalue; pp_value* v; ZINIT(&zvalue, "pp_save_any zvalue"); /* new value = mpq_numref(value) * (denominator / mpq_denref(value)) * new_pp() setting of denominator guarantees exactness */ mpz_divexact(zvalue, pp->denominator, mpq_denref(value)); mpz_mul(zvalue, zvalue, mpq_numref(value)); /* adding to total may change required fixed size, at worst once per pp */ mpz_add(pp->total, pp->total, zvalue); if (pp->total->_mp_size > pp->valnumsize) { Dprintf("pp_%d: growing to %d with total %Zd (denom %Zd)\n", pp->pp, pp->total->_mp_size, pp->total, pp->denominator); pp_grownum(pp, pp->total->_mp_size); } ++pp->valsize; pp_grow(pp, pp->valsize); v = pp_value_i(pp, pp->valsize - 1); v->parent = parent; v->self = self; v->inv = (pp->invdenom * mod_ui(zvalue, pp->p)) % pp->p; /* ref: MAX_P */ mpx_set_z(ppv_mpx(v), pp->valnumsize, zvalue); pp->invtotal = (pp->invtotal + v->inv) % pp->p; pp_insert_last(pp); ZCLEAR(&zvalue, "pp_save_any zvalue"); }
static Variant HHVM_FUNCTION(gmp_divexact, const Variant& dataA, const Variant& dataB) { mpz_t gmpDataA, gmpDataB, gmpReturn; if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_DIVEXACT, gmpDataA, dataA)) { return false; } if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_DIVEXACT, gmpDataB, dataB)) { mpz_clear(gmpDataA); return false; } if (mpz_sgn(gmpDataB) == 0) { raise_warning(cs_GMP_INVALID_VALUE_MUST_NOT_BE_ZERO, cs_GMP_FUNC_NAME_GMP_DIVEXACT); mpz_clear(gmpDataA); mpz_clear(gmpDataB); return false; } mpz_init(gmpReturn); mpz_divexact(gmpReturn, gmpDataA, gmpDataB); Variant ret = NEWOBJ(GMPResource)(gmpReturn); mpz_clear(gmpDataA); mpz_clear(gmpDataB); mpz_clear(gmpReturn); return ret; }
unsigned long int nCr(unsigned long int n, unsigned long int r) { mpz_t a,b,c, answer; unsigned long int ret; mpz_init(answer); mpz_init(a); mpz_init(b); mpz_init(c); if(n>r) { mpz_fac_ui(a,n); mpz_fac_ui(b,r); mpz_fac_ui(c,n-r); mpz_mul(b,b,c); mpz_divexact(answer,a,b); } else { mpz_set_ui(answer,0); } ret = mpz_get_ui(answer); mpz_clear(answer); mpz_clear(a); mpz_clear(b); mpz_clear(c); return ret; }
void UniZRootZ_ByFactor(std::vector<mpz_ptr> & rootlist,const poly_z & f) { static mpz_t b,a; std::vector<poly_z> faclist; std::vector<uint> deglist; mpz_init(b); mpz_init(a); UniFacZ(f,b,faclist,deglist); uint totalroots=0; for(uint i=0; i<faclist.size(); i++) { if(faclist[i].size()==2) { mpz_set(a,faclist[i][1]); mpz_neg(b,faclist[i][0]); if(mpz_divisible_p(b,a)!=0) { totalroots++; resize_z_list(rootlist,totalroots); mpz_divexact(rootlist[totalroots-1],b,a); } } } mpz_clear(b); mpz_clear(a); clear_poly_z_list(faclist); std::sort(rootlist.begin(),rootlist.end(),mpz_ptr_less); return ; }
int factor(mpz_t x_1, mpz_t x_2, mpz_t d, mpz_t n, mpz_t tmp, mpz_t *factors) { int num_factors = 0; while (IS_ONE(n) != 0 && IS_PRIME(n) == 0) { /*pollard(x_1, x_2, d, n, 2, 1, MAX_NUMBER_OF_TRIES);*/ pollard_brent(x_1, x_2, d, n, 2, 3, MAX_NUMBER_OF_TRIES); if(FAILED(d)) { return 0; } while (IS_ONE(d) != 0 && IS_PRIME(d) == 0) { /*pollard(x_2, x_2, tmp, d, 2, 1, MAX_NUMBER_OF_TRIES);*/ pollard_brent(x_1, x_2, d, n, 2, 3, MAX_NUMBER_OF_TRIES); if(FAILED(tmp)) { return 0; } mpz_set(d, tmp); } do { ADD_FACTOR(factors, num_factors, d); mpz_divexact(n, n, d); } while (mpz_divisible_p(n, d)); } if(IS_ONE(n) != 0) { ADD_FACTOR(factors, num_factors, n); } return num_factors; }
/* See Cohen 1.5.3 */ int modified_cornacchia(mpz_t x, mpz_t y, mpz_t D, mpz_t p) { int result = 0; mpz_t a, b, c, d; if (mpz_cmp_ui(p, 2) == 0) { mpz_add_ui(x, D, 8); if (mpz_perfect_square_p(x)) { mpz_sqrt(x, x); mpz_set_ui(y, 1); result = 1; } return result; } if (mpz_jacobi(D, p) == -1) /* No solution */ return 0; mpz_init(a); mpz_init(b); mpz_init(c); mpz_init(d); sqrtmod(x, D, p, a, b, c, d); if ( (mpz_even_p(D) && mpz_odd_p(x)) || (mpz_odd_p(D) && mpz_even_p(x)) ) mpz_sub(x, p, x); mpz_mul_ui(a, p, 2); mpz_set(b, x); mpz_sqrt(c, p); mpz_mul_ui(c, c, 2); /* Euclidean algorithm */ while (mpz_cmp(b, c) > 0) { mpz_set(d, a); mpz_set(a, b); mpz_mod(b, d, b); } mpz_mul_ui(c, p, 4); mpz_mul(a, b, b); mpz_sub(a, c, a); /* a = 4p - b^2 */ mpz_abs(d, D); /* d = |D| */ if (mpz_divisible_p(a, d)) { mpz_divexact(c, a, d); if (mpz_perfect_square_p(c)) { mpz_set(x, b); mpz_sqrt(y, c); result = 1; } } mpz_clear(a); mpz_clear(b); mpz_clear(c); mpz_clear(d); return result; }
void Integer::gcd(const Integer& a, const Integer& b) { assert(this != &a); assert(this != &b); assert(a.divisible(b)); #ifdef GINV_INTEGER_ALLOCATOR reallocate(abs(a.mMpz._mp_size) - abs(b.mMpz._mp_size) + 1); #endif // GINV_INTEGER_ALLOCATOR mpz_divexact(&mMpz, &a.mMpz, &b.mMpz); }
void mpz_lcm (mpz_ptr r, mpz_srcptr u, mpz_srcptr v) { mpz_t g; mp_size_t usize, vsize; TMP_DECL; usize = SIZ (u); vsize = SIZ (v); if (usize == 0 || vsize == 0) { SIZ (r) = 0; return; } usize = ABS (usize); vsize = ABS (vsize); if (vsize == 1 || usize == 1) { mp_limb_t vl, gl, c; mp_srcptr up; mp_ptr rp; if (usize == 1) { usize = vsize; MPZ_SRCPTR_SWAP (u, v); } MPZ_REALLOC (r, usize+1); up = PTR(u); vl = PTR(v)[0]; gl = mpn_gcd_1 (up, usize, vl); vl /= gl; rp = PTR(r); c = mpn_mul_1 (rp, up, usize, vl); rp[usize] = c; usize += (c != 0); SIZ(r) = usize; return; } TMP_MARK; MPZ_TMP_INIT (g, usize); /* v != 0 implies |gcd(u,v)| <= |u| */ mpz_gcd (g, u, v); mpz_divexact (g, u, g); mpz_mul (r, g, v); SIZ (r) = ABS (SIZ (r)); /* result always positive */ TMP_FREE; }
/** \brief 整系数多项式本原部分. \param f 整系数多项式. \param r 本原部分. \return 本原部分,其lc为正整数. */ void UniPPZ(poly_z & r,const poly_z & f) { mpz_t a; mpz_init(a); UniContZ(a,f); r.resize(f.size()); for(size_t i=0;i<f.size();i++) { mpz_divexact(r[i],f[i],a); } mpz_clear(a); }
///@brief test doc bool divide(ElementType& result, const ElementType& a, const ElementType& b) const { if (mpz_divisible_p(&a, &b)) { mpz_divexact(&result, &a, &b); return true; } else return false; }
static int insert_factor(mpz_t n, mpz_t* farray, int nfacs, mpz_t f) { int i, j; mpz_t t, t2; if (mpz_cmp_ui(f, 1) <= 0) return nfacs; /* skip duplicates */ for (i = 0; i < nfacs; i++) if (mpz_cmp(farray[i], f) == 0) break; if (i != nfacs) { return nfacs; } /* Look for common factors in all the existing set */ /* for (i = 0; i < nfacs; i++) gmp_printf(" F[%d] = %Zd\n", i, farray[i]); */ mpz_init(t); mpz_init(t2); for (i = 0; i < nfacs; i++) { mpz_gcd(t, farray[i], f); if (mpz_cmp_ui(t, 1) == 0) /* t=1: F and f unchanged */ continue; mpz_divexact(t2, farray[i], t); /* t2 = F/t */ mpz_divexact(f, f, t); /* f = f/t */ /* Remove the old farray[i] */ for (j = i+1; j < nfacs; j++) mpz_set(farray[j-1], farray[j]); mpz_set_ui(farray[nfacs--], 0); /* Insert F/t, t, f/t */ nfacs = insert_factor(n, farray, nfacs, t2); nfacs = insert_factor(n, farray, nfacs, t); nfacs = insert_factor(n, farray, nfacs, f); i=0; break; } /* If nothing common, insert it. */ if (i == nfacs) mpz_set(farray[nfacs++], f); mpz_clear(t); mpz_clear(t2); return nfacs; }
// Liefert die Primfaktorzerlegung einer Zahl als String. char *factorize(mpz_t number) { // Primtest (Miller-Rabin). if (mpz_probab_prime_p(number, 10) > 0) return mpz_get_str(NULL, 10, number); mpz_t factor, cofactor; mpz_init(factor); mpz_init(cofactor); char *str1, *str2, *result; int B1 = INITB1, B2 = INITB2, curves = INITCURVES; // Zunaechst eine einfache Probedivision. trial(number, factor, 3e3); if (mpz_cmp_si(factor, 1) == 0) { // Zweite Strategie: Pollard-Rho. do { rho(number, factor, 4e4); } while (mpz_cmp(factor, number) == 0); // Falls immer noch kein Faktor gefunden wurde, mit ECM fortfahren. while (mpz_cmp_si(factor, 1) == 0) { ecm(number, factor, B1, B2, curves); if (mpz_cmp(factor, number) == 0) { mpz_set_si(factor, 1); B1 = INITB1; B2 = INITB2; curves = INITCURVES; continue; } // Anpassung der Parameter. B1 *= 4; B2 *= 5; curves = (curves * 5) / 2; } } mpz_divexact(cofactor, number, factor); str1 = factorize(factor); str2 = factorize(cofactor); result = (char *) malloc(strlen(str1) + strlen(str2) + 4); strcpy(result, str1); strcat(result, " * "); strcat(result, str2); mpz_clear(factor); mpz_clear(cofactor); return result; }
void init_ecpp_gcds(void) { if (_gcdinit == 0) { mpz_init(_gcd_small); mpz_init(_gcd_large); _GMP_pn_primorial(_gcd_small, 3000); _GMP_pn_primorial(_gcd_large, 20000); mpz_divexact(_gcd_large, _gcd_large, _gcd_small); mpz_divexact_ui(_gcd_small, _gcd_small, 2*3*5); mpz_init(_lcm_small); _GMP_lcm_of_consecutive_integers(300, _lcm_small); _gcdinit = 1; } }
static void initpq(params_t params) //calculate system parameters that can be determined from p and q //also initialize the elliptic curve library so points can be used { mpz_init(params->p1onq); mpz_add_ui(params->p1onq, params->p, 1); mpz_divexact(params->p1onq, params->p1onq, params->q); //initialize the elliptic curve library curve_init(params->curve, params->p, params->q); fp2_init(params->zeta); fp2_set_cbrt_unity(params->zeta, params->p); }
unsigned long my_div_estimate_threshold() { const double log10 = 3.321928; clock_t begin, end, diff1, diff2; mpz_t y, x; unsigned long digits = 100, min_digits, max_digits, prec, stage = 1; div_threshold = 0; for (;;) { if (stage == 1) digits *= 2; else digits = (min_digits + max_digits)/2; prec = (unsigned long) (digits * log10) + 32; my_init(prec); mpz_init(y); mpz_init(x); mpz_ui_pow_ui(y, 10, digits); mpz_ui_pow_ui(x, 10, digits/10); begin = clock(); my_divexact(y, y, x); end = clock(); diff1 = end - begin; mpz_ui_pow_ui(y, 10, digits); begin = clock(); mpz_divexact(y, y, x); end = clock(); diff2 = end - begin; my_clear(); mpz_clear(y); mpz_clear(x); printf("digits %ld, my %ld, mpz %ld\n", digits, diff1, diff2); if (stage == 1) { if (diff1 >= 10 && diff1 < diff2) { stage = 2; min_digits = digits/2; max_digits = digits; } } else { if (diff1 < diff2) max_digits = digits; else min_digits = digits; if (max_digits - min_digits < 100) break; } } return (unsigned long) (digits * log10); }
/* f /= gcd(f,g), g /= gcd(f,g) */ void fac_remove_gcd(mpz_t p, fac_t fp, mpz_t g, fac_t fg) { long int i, j, k, c; fac_resize(fmul, min(fp->num_facs, fg->num_facs)); for (i=j=k=0; i<fp->num_facs && j<fg->num_facs; ) { if (fp->fac[i] == fg->fac[j]) { c = min(fp->pow[i], fg->pow[j]); fp->pow[i] -= c; fg->pow[j] -= c; fmul->fac[k] = fp->fac[i]; fmul->pow[k] = c; i++; j++; k++; } else if (fp->fac[i] < fg->fac[j]) { i++; } else { j++; } } fmul->num_facs = k; assert(k <= fmul->max_facs); if (fmul->num_facs) { bs_mul(gcd, 0, fmul->num_facs); #if HAVE_DIVEXACT_PREINV mpz_invert_mod_2exp (mgcd, gcd); mpz_divexact_pre (p, p, gcd, mgcd); mpz_divexact_pre (g, g, gcd, mgcd); #else #define SIZ(x) x->_mp_size mpz_divexact(p, p, gcd); mpz_divexact(g, g, gcd); #endif fac_compact(fp); fac_compact(fg); } }
void init_ecpp_gcds(UV nsize) { if (_gcdinit == 0) { mpz_init(_gcd_small); mpz_init(_gcd_large); _GMP_pn_primorial(_gcd_small, 3000); /* This is never re-adjusted -- first number proved sets the size */ nsize *= 20; if (nsize < 20000) nsize = 20000; else if (nsize > 500000) nsize = 500000; _GMP_pn_primorial(_gcd_large, nsize); mpz_divexact(_gcd_large, _gcd_large, _gcd_small); mpz_divexact_ui(_gcd_small, _gcd_small, 2*3*5); _gcdinit = 1; } }
int main(void) { mpz_t a, b; mpz_init(a); mpz_init(b); /* 40C20 */ mpz_fac_ui(a, 40); mpz_fac_ui(b, 20); mpz_mul(b, b, b); mpz_divexact(a, a, b); gmp_printf("%Zd\n", a); return 0; }
void choose(mpz_t ans, int n, int r) { factorial(ans, n); mpz_t smaller; factorial(smaller, r); mpz_t third; factorial(third, n-r); /* gmp_printf("smaller is: %Zd\n", smaller); */ /* gmp_printf("third is: %Zd\n", third); */ mpz_mul(smaller, smaller, third); /* gmp_printf("top is: %Zd\n", ans); */ /* gmp_printf("smaller is: %Zd\n", smaller); */ mpz_divexact(ans, ans, smaller); }
void decrypt(mpz_t c){ //set big_temp = c^d mod n^2 mpz_powm(big_temp, c, d, n_square); //set big_temp = big_temp -1 mpz_sub_ui(big_temp, big_temp, 1); //divide big_temp by n mpz_divexact(big_temp, big_temp, n); //d^-1 * big_temp mpz_mul(big_temp, d_inverse, big_temp); mpz_mod(c, big_temp, n); }
/* * Algorithm as seen in the initial paper. Simple optimizations * have been added. rop and op can be aliases. */ static void dlog_s(djcs_private_key *vk, mpz_t rop, mpz_t op) { mpz_t a, t1, t2, t3, kfact; mpz_inits(a, t1, t2, t3, kfact, NULL); /* Optimization: L(a mod n^(j+1)) = L(a mod n^(s+1)) mod n^j * where j <= s */ mpz_mod(a, op, vk->n[vk->s]); mpz_sub_ui(a, a, 1); mpz_divexact(a, a, vk->n[0]); mpz_set_ui(rop, 0); for (unsigned long j = 1; j <= vk->s; ++j) { /* t1 = L(a mod n^j+1) */ mpz_mod(t1, a, vk->n[j-1]); /* t2 = i */ mpz_set(t2, rop); mpz_set_ui(kfact, 1); for (unsigned long k = 2; k <= j; ++k) { /* i = i - 1 */ mpz_sub_ui(rop, rop, 1); mpz_mul_ui(kfact, kfact, k); /* t2 = t2 * i mod n^j */ mpz_mul(t2, t2, rop); mpz_mod(t2, t2, vk->n[j-1]); /* t1 = t1 - (t2 * n^(k-1)) * k!^(-1)) mod n^j */ mpz_invert(t3, kfact, vk->n[j-1]); mpz_mul(t3, t3, t2); mpz_mod(t3, t3, vk->n[j-1]); mpz_mul(t3, t3, vk->n[k-2]); mpz_mod(t3, t3, vk->n[j-1]); mpz_sub(t1, t1, t3); mpz_mod(t1, t1, vk->n[j-1]); } mpz_set(rop, t1); } mpz_zeros(a, t1, t2, t3, kfact, NULL); mpz_clears(a, t1, t2, t3, kfact, NULL); }
/* div */ static int divide(void *a, void *b, void *c, void *d) { mpz_t tmp; LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); if (c != NULL) { mpz_init(tmp); mpz_divexact(tmp, a, b); } if (d != NULL) { mpz_mod(d, a, b); } if (c != NULL) { mpz_set(c, tmp); mpz_clear(tmp); } return CRYPT_OK; }
/* See Cohen 1.5.2 */ int cornacchia(mpz_t x, mpz_t y, mpz_t D, mpz_t p) { int result = 0; mpz_t a, b, c, d; if (mpz_jacobi(D, p) < 0) /* No solution */ return 0; mpz_init(a); mpz_init(b); mpz_init(c); mpz_init(d); sqrtmod(x, D, p, a, b, c, d); mpz_set(a, p); mpz_set(b, x); mpz_sqrt(c, p); while (mpz_cmp(b,c) > 0) { mpz_set(d, a); mpz_set(a, b); mpz_mod(b, d, b); } mpz_mul(a, b, b); mpz_sub(a, p, a); /* a = p - b^2 */ mpz_abs(d, D); /* d = |D| */ if (mpz_divisible_p(a, d)) { mpz_divexact(c, a, d); if (mpz_perfect_square_p(c)) { mpz_set(x, b); mpz_sqrt(y, c); result = 1; } } mpz_clear(a); mpz_clear(b); mpz_clear(c); mpz_clear(d); return result; }
void fmpz_divexact(fmpz_t f, const fmpz_t g, const fmpz_t h) { fmpz c1 = *g; fmpz c2 = *h; if (fmpz_is_zero(h)) { flint_printf("Exception (fmpz_divexact). Division by zero.\n"); abort(); } if (!COEFF_IS_MPZ(c1)) /* g is small, h must be also or division isn't exact */ { fmpz_set_si(f, c1 / c2); } else /* g is large */ { __mpz_struct * mpz_ptr = _fmpz_promote(f); if (!COEFF_IS_MPZ(c2)) /* h is small */ { if (c2 > 0) /* h > 0 */ { flint_mpz_divexact_ui(mpz_ptr, COEFF_TO_PTR(c1), c2); _fmpz_demote_val(f); /* division by h may result in small value */ } else { flint_mpz_divexact_ui(mpz_ptr, COEFF_TO_PTR(c1), -c2); _fmpz_demote_val(f); /* division by h may result in small value */ fmpz_neg(f, f); } } else /* both are large */ { mpz_divexact(mpz_ptr, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2)); _fmpz_demote_val(f); /* division by h may result in small value */ } } }
void *SumThread(void *context) { PSUM_THREAD_CONTEXT tcontext = (PSUM_THREAD_CONTEXT)context; while (mpz_cmp(tcontext->factor, tcontext->end) < 0) { //Check if the number is divisible by the factor if (mpz_divisible_p(tcontext->num, tcontext->factor) != 0) { pthread_mutex_lock(tcontext->termMutex); //Add the factor mpz_add(*tcontext->sum, *tcontext->sum, tcontext->factor); //Add the other factor in the pair mpz_divexact(tcontext->otherfactor, tcontext->num, tcontext->factor); mpz_add(*tcontext->sum, *tcontext->sum, tcontext->otherfactor); //Bail early if we've exceeded our number if (mpz_cmp(*tcontext->sum, tcontext->num) > 0) { pthread_mutex_unlock(tcontext->termMutex); break; } pthread_mutex_unlock(tcontext->termMutex); } //This is a valid cancellation point pthread_testcancel(); mpz_add_ui(tcontext->factor, tcontext->factor, 1); } pthread_mutex_lock(tcontext->termMutex); (*tcontext->termCount)++; pthread_cond_signal(tcontext->termVar); pthread_mutex_unlock(tcontext->termMutex); pthread_exit(NULL); }
/* 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 */ }