BigInt& BigInt::operator += (const BigInt &b) { mpz_add(mImpl,mImpl,b.mImpl); return *this; }
// set op to (op1 + op2) mod d, using tmp for the calculation inline static void mpz_addm( mpz_t op, const mpz_t op1, const mpz_t op2, const mpz_t d, mpz_t tmp ) { mpz_add(tmp, op1, op2); mpz_mod(op, tmp, d); }
void pvsAdd(BigInt result, const BigInt a, const BigInt b) { mpz_add( result, a, b ); }
int main (int argc, char **argv) { mpz_t op1, op2, ref; int i, j, chain_len; gmp_randstate_t rands; mpz_t bs; unsigned long bsi, size_range; int reps = 200; if (argc == 2) reps = atoi (argv[1]); tests_start (); gmp_randinit_default(rands); check_data (); mpz_init (bs); mpz_init (op1); mpz_init (op2); mpz_init (ref); mpz_init (gcd1); mpz_init (gcd2); mpz_init (temp1); mpz_init (temp2); mpz_init (s); mpz_init (t); for (i = 0; i < reps; i++) { /* Generate plain operands with unknown gcd. These types of operands have proven to trigger certain bugs in development versions of the gcd code. The "hgcd->row[3].rsize > M" ASSERT is not triggered by the division chain code below, but that is most likely just a result of that other ASSERTs are triggered before it. */ mpz_urandomb (bs, rands, 32); size_range = mpz_get_ui (bs) % 16 + 2; mpz_urandomb (bs, rands, size_range); mpz_urandomb (op1, rands, mpz_get_ui (bs) + MIN_OPERAND_BITSIZE); mpz_urandomb (bs, rands, size_range); mpz_urandomb (op2, rands, mpz_get_ui (bs) + MIN_OPERAND_BITSIZE); mpz_urandomb (bs, rands, 2); bsi = mpz_get_ui (bs); if ((bsi & 1) != 0) mpz_neg (op1, op1); if ((bsi & 2) != 0) mpz_neg (op2, op2); one_test (op1, op2, NULL, i); /* Generate a division chain backwards, allowing otherwise unlikely huge quotients. */ mpz_set_ui (op1, 0); mpz_urandomb (bs, rands, 32); mpz_urandomb (bs, rands, mpz_get_ui (bs) % 16 + 1); mpz_rrandomb (op2, rands, mpz_get_ui (bs)); mpz_add_ui (op2, op2, 1); mpz_set (ref, op2); mpz_urandomb (bs, rands, 32); chain_len = mpz_get_ui (bs) % 50; for (j = 0; j < chain_len; j++) { mpz_urandomb (bs, rands, 32); mpz_urandomb (bs, rands, mpz_get_ui (bs) % 12 + 1); mpz_rrandomb (temp2, rands, mpz_get_ui (bs) + 1); mpz_add_ui (temp2, temp2, 1); mpz_mul (temp1, op2, temp2); mpz_add (op1, op1, temp1); /* Don't generate overly huge operands. */ if (SIZ (op1) > 1000) break; mpz_urandomb (bs, rands, 32); mpz_urandomb (bs, rands, mpz_get_ui (bs) % 12 + 1); mpz_rrandomb (temp2, rands, mpz_get_ui (bs) + 1); mpz_add_ui (temp2, temp2, 1); mpz_mul (temp1, op1, temp2); mpz_add (op2, op2, temp1); /* Don't generate overly huge operands. */ if (SIZ (op2) > 1000) break; } one_test (op1, op2, ref, i); } mpz_clear (bs); mpz_clear (op1); mpz_clear (op2); mpz_clear (ref); mpz_clear (gcd1); mpz_clear (gcd2); mpz_clear (temp1); mpz_clear (temp2); mpz_clear (s); mpz_clear (t); gmp_randclear(rands); tests_end (); exit (0); }
void tpm_bn_add(tpm_bn_t res, tpm_bn_t a, tpm_bn_t b) { mpz_add(res, a, b); }
/* compute in y an approximation of sum(x^k/k/k!, k=1..infinity), and return e such that the absolute error is bound by 2^e ulp(y) */ static mp_exp_t mpfr_eint_aux (mpfr_t y, mpfr_srcptr x) { mpfr_t eps; /* dynamic (absolute) error bound on t */ mpfr_t erru, errs; mpz_t m, s, t, u; mp_exp_t e, sizeinbase; mp_prec_t w = MPFR_PREC(y); unsigned long k; MPFR_GROUP_DECL (group); /* for |x| <= 1, we have S := sum(x^k/k/k!, k=1..infinity) = x + R(x) where |R(x)| <= (x/2)^2/(1-x/2) <= 2*(x/2)^2 thus |R(x)/x| <= |x|/2 thus if |x| <= 2^(-PREC(y)) we have |S - o(x)| <= ulp(y) */ if (MPFR_GET_EXP(x) <= - (mp_exp_t) w) { mpfr_set (y, x, GMP_RNDN); return 0; } mpz_init (s); /* initializes to 0 */ mpz_init (t); mpz_init (u); mpz_init (m); MPFR_GROUP_INIT_3 (group, 31, eps, erru, errs); e = mpfr_get_z_exp (m, x); /* x = m * 2^e */ MPFR_ASSERTD (mpz_sizeinbase (m, 2) == MPFR_PREC (x)); if (MPFR_PREC (x) > w) { e += MPFR_PREC (x) - w; mpz_tdiv_q_2exp (m, m, MPFR_PREC (x) - w); } /* remove trailing zeroes from m: this will speed up much cases where x is a small integer divided by a power of 2 */ k = mpz_scan1 (m, 0); mpz_tdiv_q_2exp (m, m, k); e += k; /* initialize t to 2^w */ mpz_set_ui (t, 1); mpz_mul_2exp (t, t, w); mpfr_set_ui (eps, 0, GMP_RNDN); /* eps[0] = 0 */ mpfr_set_ui (errs, 0, GMP_RNDN); for (k = 1;; k++) { /* let eps[k] be the absolute error on t[k]: since t[k] = trunc(t[k-1]*m*2^e/k), we have eps[k+1] <= 1 + eps[k-1]*m*2^e/k + t[k-1]*m*2^(1-w)*2^e/k = 1 + (eps[k-1] + t[k-1]*2^(1-w))*m*2^e/k = 1 + (eps[k-1]*2^(w-1) + t[k-1])*2^(1-w)*m*2^e/k */ mpfr_mul_2ui (eps, eps, w - 1, GMP_RNDU); mpfr_add_z (eps, eps, t, GMP_RNDU); MPFR_MPZ_SIZEINBASE2 (sizeinbase, m); mpfr_mul_2si (eps, eps, sizeinbase - (w - 1) + e, GMP_RNDU); mpfr_div_ui (eps, eps, k, GMP_RNDU); mpfr_add_ui (eps, eps, 1, GMP_RNDU); mpz_mul (t, t, m); if (e < 0) mpz_tdiv_q_2exp (t, t, -e); else mpz_mul_2exp (t, t, e); mpz_tdiv_q_ui (t, t, k); mpz_tdiv_q_ui (u, t, k); mpz_add (s, s, u); /* the absolute error on u is <= 1 + eps[k]/k */ mpfr_div_ui (erru, eps, k, GMP_RNDU); mpfr_add_ui (erru, erru, 1, GMP_RNDU); /* and that on s is the sum of all errors on u */ mpfr_add (errs, errs, erru, GMP_RNDU); /* we are done when t is smaller than errs */ if (mpz_sgn (t) == 0) sizeinbase = 0; else MPFR_MPZ_SIZEINBASE2 (sizeinbase, t); if (sizeinbase < MPFR_GET_EXP (errs)) break; } /* the truncation error is bounded by (|t|+eps)/k*(|x|/k + |x|^2/k^2 + ...) <= (|t|+eps)/k*|x|/(k-|x|) */ mpz_abs (t, t); mpfr_add_z (eps, eps, t, GMP_RNDU); mpfr_div_ui (eps, eps, k, GMP_RNDU); mpfr_abs (erru, x, GMP_RNDU); /* |x| */ mpfr_mul (eps, eps, erru, GMP_RNDU); mpfr_ui_sub (erru, k, erru, GMP_RNDD); if (MPFR_IS_NEG (erru)) { /* the truncated series does not converge, return fail */ e = w; } else { mpfr_div (eps, eps, erru, GMP_RNDU); mpfr_add (errs, errs, eps, GMP_RNDU); mpfr_set_z (y, s, GMP_RNDN); mpfr_div_2ui (y, y, w, GMP_RNDN); /* errs was an absolute error bound on s. We must convert it to an error in terms of ulp(y). Since ulp(y) = 2^(EXP(y)-PREC(y)), we must divide the error by 2^(EXP(y)-PREC(y)), but since we divided also y by 2^w = 2^PREC(y), we must simply divide by 2^EXP(y). */ e = MPFR_GET_EXP (errs) - MPFR_GET_EXP (y); } MPFR_GROUP_CLEAR (group); mpz_clear (s); mpz_clear (t); mpz_clear (u); mpz_clear (m); return e; }
int main (int argc, char **argv) { gmp_randstate_ptr rands; unsigned long maxnbits, maxdbits, nbits, dbits; mpz_t n, d, q, r, tz, junk; mp_size_t maxnn, maxdn, nn, dn, clearn, i; mp_ptr np, dup, dnp, qp, rp, junkp; mp_limb_t t; gmp_pi1_t dinv; long count = COUNT; mp_ptr scratch; mp_limb_t ran; mp_size_t alloc, itch; mp_limb_t rran0, rran1, qran0, qran1; TMP_DECL; if (argc > 1) { char *end; count = strtol (argv[1], &end, 0); if (*end || count <= 0) { fprintf (stderr, "Invalid test count: %s.\n", argv[1]); return 1; } } maxdbits = MAX_DN; maxnbits = MAX_NN; tests_start (); rands = RANDS; mpz_init (n); mpz_init (d); mpz_init (q); mpz_init (r); mpz_init (tz); mpz_init (junk); maxnn = maxnbits / GMP_NUMB_BITS + 1; maxdn = maxdbits / GMP_NUMB_BITS + 1; TMP_MARK; qp = TMP_ALLOC_LIMBS (maxnn + 2) + 1; rp = TMP_ALLOC_LIMBS (maxnn + 2) + 1; dnp = TMP_ALLOC_LIMBS (maxdn); alloc = 1; scratch = __GMP_ALLOCATE_FUNC_LIMBS (alloc); for (test = -300; test < count; test++) { nbits = random_word (rands) % (maxnbits - GMP_NUMB_BITS) + 2 * GMP_NUMB_BITS; if (test < 0) dbits = (test + 300) % (nbits - 1) + 1; else dbits = random_word (rands) % (nbits - 1) % maxdbits + 1; #if RAND_UNIFORM #define RANDFUNC mpz_urandomb #else #define RANDFUNC mpz_rrandomb #endif do RANDFUNC (d, rands, dbits); while (mpz_sgn (d) == 0); dn = SIZ (d); dup = PTR (d); MPN_COPY (dnp, dup, dn); dnp[dn - 1] |= GMP_NUMB_HIGHBIT; if (test % 2 == 0) { RANDFUNC (n, rands, nbits); nn = SIZ (n); ASSERT_ALWAYS (nn >= dn); } else { do { RANDFUNC (q, rands, random_word (rands) % (nbits - dbits + 1)); RANDFUNC (r, rands, random_word (rands) % mpz_sizeinbase (d, 2)); mpz_mul (n, q, d); mpz_add (n, n, r); nn = SIZ (n); } while (nn > maxnn || nn < dn); } ASSERT_ALWAYS (nn <= maxnn); ASSERT_ALWAYS (dn <= maxdn); mpz_urandomb (junk, rands, nbits); junkp = PTR (junk); np = PTR (n); mpz_urandomb (tz, rands, 32); t = mpz_get_ui (tz); if (t % 17 == 0) { dnp[dn - 1] = GMP_NUMB_MAX; dup[dn - 1] = GMP_NUMB_MAX; } switch ((int) t % 16) { case 0: clearn = random_word (rands) % nn; for (i = clearn; i < nn; i++) np[i] = 0; break; case 1: mpn_sub_1 (np + nn - dn, dnp, dn, random_word (rands)); break; case 2: mpn_add_1 (np + nn - dn, dnp, dn, random_word (rands)); break; } if (dn >= 2) invert_pi1 (dinv, dnp[dn - 1], dnp[dn - 2]); rran0 = random_word (rands); rran1 = random_word (rands); qran0 = random_word (rands); qran1 = random_word (rands); qp[-1] = qran0; qp[nn - dn + 1] = qran1; rp[-1] = rran0; ran = random_word (rands); if ((double) (nn - dn) * dn < 1e5) { /* Test mpn_sbpi1_div_qr */ if (dn > 2) { MPN_COPY (rp, np, nn); if (nn > dn) MPN_COPY (qp, junkp, nn - dn); qp[nn - dn] = mpn_sbpi1_div_qr (qp, rp, nn, dnp, dn, dinv.inv32); check_one (qp, rp, np, nn, dnp, dn, "mpn_sbpi1_div_qr", 0); } /* Test mpn_sbpi1_divappr_q */ if (dn > 2) { MPN_COPY (rp, np, nn); if (nn > dn) MPN_COPY (qp, junkp, nn - dn); qp[nn - dn] = mpn_sbpi1_divappr_q (qp, rp, nn, dnp, dn, dinv.inv32); check_one (qp, NULL, np, nn, dnp, dn, "mpn_sbpi1_divappr_q", 1); } /* Test mpn_sbpi1_div_q */ if (dn > 2) { MPN_COPY (rp, np, nn); if (nn > dn) MPN_COPY (qp, junkp, nn - dn); qp[nn - dn] = mpn_sbpi1_div_q (qp, rp, nn, dnp, dn, dinv.inv32); check_one (qp, NULL, np, nn, dnp, dn, "mpn_sbpi1_div_q", 0); } /* Test mpn_sb_div_qr_sec */ itch = 3 * nn + 4; if (itch + 1 > alloc) { scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1); alloc = itch + 1; } scratch[itch] = ran; MPN_COPY (rp, np, nn); if (nn >= dn) MPN_COPY (qp, junkp, nn - dn + 1); mpn_sb_div_qr_sec (qp, rp, nn, dup, dn, scratch); ASSERT_ALWAYS (ran == scratch[itch]); check_one (qp, rp, np, nn, dup, dn, "mpn_sb_div_qr_sec", 0); /* Test mpn_sb_div_r_sec */ itch = nn + 2 * dn + 2; if (itch + 1 > alloc) { scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1); alloc = itch + 1; } scratch[itch] = ran; MPN_COPY (rp, np, nn); mpn_sb_div_r_sec (rp, nn, dup, dn, scratch); ASSERT_ALWAYS (ran == scratch[itch]); /* Note: Since check_one cannot cope with random-only functions, we pass qp[] from the previous function, mpn_sb_div_qr_sec. */ check_one (qp, rp, np, nn, dup, dn, "mpn_sb_div_r_sec", 0); } /* Test mpn_dcpi1_div_qr */ if (dn >= 6 && nn - dn >= 3) { MPN_COPY (rp, np, nn); if (nn > dn) MPN_COPY (qp, junkp, nn - dn); qp[nn - dn] = mpn_dcpi1_div_qr (qp, rp, nn, dnp, dn, &dinv); ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - dn + 1] == qran1); ASSERT_ALWAYS (rp[-1] == rran0); check_one (qp, rp, np, nn, dnp, dn, "mpn_dcpi1_div_qr", 0); } /* Test mpn_dcpi1_divappr_q */ if (dn >= 6 && nn - dn >= 3) { MPN_COPY (rp, np, nn); if (nn > dn) MPN_COPY (qp, junkp, nn - dn); qp[nn - dn] = mpn_dcpi1_divappr_q (qp, rp, nn, dnp, dn, &dinv); ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - dn + 1] == qran1); ASSERT_ALWAYS (rp[-1] == rran0); check_one (qp, NULL, np, nn, dnp, dn, "mpn_dcpi1_divappr_q", 1); } /* Test mpn_dcpi1_div_q */ if (dn >= 6 && nn - dn >= 3) { MPN_COPY (rp, np, nn); if (nn > dn) MPN_COPY (qp, junkp, nn - dn); qp[nn - dn] = mpn_dcpi1_div_q (qp, rp, nn, dnp, dn, &dinv); ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - dn + 1] == qran1); ASSERT_ALWAYS (rp[-1] == rran0); check_one (qp, NULL, np, nn, dnp, dn, "mpn_dcpi1_div_q", 0); } /* Test mpn_mu_div_qr */ if (nn - dn > 2 && dn >= 2) { itch = mpn_mu_div_qr_itch (nn, dn, 0); if (itch + 1 > alloc) { scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1); alloc = itch + 1; } scratch[itch] = ran; MPN_COPY (qp, junkp, nn - dn); MPN_ZERO (rp, dn); rp[dn] = rran1; qp[nn - dn] = mpn_mu_div_qr (qp, rp, np, nn, dnp, dn, scratch); ASSERT_ALWAYS (ran == scratch[itch]); ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - dn + 1] == qran1); ASSERT_ALWAYS (rp[-1] == rran0); ASSERT_ALWAYS (rp[dn] == rran1); check_one (qp, rp, np, nn, dnp, dn, "mpn_mu_div_qr", 0); } /* Test mpn_mu_divappr_q */ if (nn - dn > 2 && dn >= 2) { itch = mpn_mu_divappr_q_itch (nn, dn, 0); if (itch + 1 > alloc) { scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1); alloc = itch + 1; } scratch[itch] = ran; MPN_COPY (qp, junkp, nn - dn); qp[nn - dn] = mpn_mu_divappr_q (qp, np, nn, dnp, dn, scratch); ASSERT_ALWAYS (ran == scratch[itch]); ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - dn + 1] == qran1); check_one (qp, NULL, np, nn, dnp, dn, "mpn_mu_divappr_q", 4); } /* Test mpn_mu_div_q */ if (nn - dn > 2 && dn >= 2) { itch = mpn_mu_div_q_itch (nn, dn, 0); if (itch + 1> alloc) { scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1); alloc = itch + 1; } scratch[itch] = ran; MPN_COPY (qp, junkp, nn - dn); qp[nn - dn] = mpn_mu_div_q (qp, np, nn, dnp, dn, scratch); ASSERT_ALWAYS (ran == scratch[itch]); ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - dn + 1] == qran1); check_one (qp, NULL, np, nn, dnp, dn, "mpn_mu_div_q", 0); } if (1) { itch = nn + 1; if (itch + 1> alloc) { scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1); alloc = itch + 1; } scratch[itch] = ran; mpn_div_q (qp, np, nn, dup, dn, scratch); ASSERT_ALWAYS (ran == scratch[itch]); ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - dn + 1] == qran1); check_one (qp, NULL, np, nn, dup, dn, "mpn_div_q", 0); } if (dn >= 2 && nn >= 2) { mp_limb_t qh; /* mpn_divrem_2 */ MPN_COPY (rp, np, nn); qp[nn - 2] = qp[nn-1] = qran1; qh = mpn_divrem_2 (qp, 0, rp, nn, dnp + dn - 2); ASSERT_ALWAYS (qp[nn - 2] == qran1); ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - 1] == qran1); qp[nn - 2] = qh; check_one (qp, rp, np, nn, dnp + dn - 2, 2, "mpn_divrem_2", 0); /* Missing: divrem_2 with fraction limbs. */ /* mpn_div_qr_2 */ qp[nn - 2] = qran1; qh = mpn_div_qr_2 (qp, rp, np, nn, dup + dn - 2); ASSERT_ALWAYS (qp[nn - 2] == qran1); ASSERT_ALWAYS (qp[-1] == qran0); ASSERT_ALWAYS (qp[nn - 1] == qran1); qp[nn - 2] = qh; check_one (qp, rp, np, nn, dup + dn - 2, 2, "mpn_div_qr_2", 0); } } __GMP_FREE_FUNC_LIMBS (scratch, alloc); TMP_FREE; mpz_clear (n); mpz_clear (d); mpz_clear (q); mpz_clear (r); mpz_clear (tz); mpz_clear (junk); tests_end (); return 0; }
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 = 200; gmp_randstate_ptr rands; mpz_t bs; unsigned long bsi, size_range; tests_start (); rands = RANDS; mpz_init (bs); if (argc == 2) reps = atoi (argv[1]); 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) % 16 + 2; /* 0..131071 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); }
int signedshortmessage( unsigned char *sm, unsigned long long *smlen, const unsigned char *m, unsigned long long mlen, const unsigned char *sk, unsigned long long sklen ) { init_all(); /* See Handbook of Elliptic and Hyperelliptic Curve Cryptography, page 570 f */ mpz_t k_mpz; mpz_t sk_mpz; mpz_t hm_mpz; mpz_t u; mpz_t s; mpz_init(k_mpz); mpz_init(sk_mpz); mpz_init(hm_mpz); mpz_init(u); mpz_init(s); bytearray_to_mpz_t(hm_mpz, m, mlen); bytearray_to_mpz_t(sk_mpz, sk, sklen); divclass E; divclass_init(E); int i; do { do { gen_keypair(k_mpz, E); divclass_make_affine(E, E); divclass_hash(u, E); } while(mpz_cmp_ui(u, 0) == 0); mpz_invert(s, k_mpz, p); mpz_mul(sk_mpz, sk_mpz, u); mpz_add(hm_mpz, hm_mpz, sk_mpz); mpz_mul(s, s, hm_mpz); mpz_mod(s, s, p); } while(mpz_cmp_ui(s, 0) == 0); /* Copy message to signed message */ for(i = 0; i < SHORTMESSAGE_BYTES; i++) { sm[i] = m[i]; } /* Append signature */ mpz_t_to_bytearray(sm + SHORTMESSAGE_BYTES, SECRETKEY_BYTES, u); mpz_t_to_bytearray(sm + SHORTMESSAGE_BYTES + SECRETKEY_BYTES, SECRETKEY_BYTES, s); *smlen = SIGNATURE_BYTES; mpz_clear(k_mpz); mpz_clear(sk_mpz); mpz_clear(hm_mpz); mpz_clear(u); mpz_clear(s); clear_all(); return 0; }
void gmp_num::set_add(num* a, num* b) { mpz_add(val, *num2mpz(a), *num2mpz(b)); }
/** * <p>Factorises a big integer using Pollard's rho method and some tweaks</a> * <p> * Pollard's rho (ρ) method is a special-purpose integer factorisation algorithm used * for factoring integers with small factors. As you know, they are not that unusual. * </p> * * @param n The big integer * @param c The seed index, 0 for autoselection of seed value * @param output The buffer to which to add [probable] prime factors * @param outputPtr The buffer's pointer * @param initialRootOrder The initial root order * @return Whether the factorisation was successful */ boolean factorisePollardsRho(Bignum n, llong c, Buffer output, long* outputPtr, int initialRootOrder) { if (c > SEED_LIMIT) return false; llong cc = *(seeds + c); if (c == 0) { selectSeed(cc, n); } int i, m, cd; String prime; int itr; int rootOrder = initialRootOrder, pRootOrder = 1, r; #define f(X) mpz_mul(X, X, X); mpz_add_ui(X, X, cc) Bignum factor; mpz_init_set(factor, n); Bignum d; mpz_init(d); Bignum x; mpz_init_set_ui(x, cc); Bignum y; mpz_init_set_ui(y, cc); Bignum conjA; mpz_init(conjA); Bignum conjB; mpz_init(conjB); #define recursion(X, Y) factorisePollardsRho(X, c + 1, output, outputPtr, Y) for (;;) { pRootOrder = maxRoot(factor); if (pRootOrder != 1) { rootOrder *= pRootOrder; mpz_root(factor, factor, pRootOrder); } else { //There may exist a number b = (A = ⌊√n⌋ + 1)² − n such that B = √b is an integer //in which case n = (A − B)(A + B) [n is(!) odd composite]. If not, the only the //trivial iteration of A (A += 1) seems to be the one not consuming your entire //CPU and it is also guaranteed to find the factors, but it is just so slow. mpz_sqrt(conjA, factor); mpz_add_ui(conjA, conjA, 1); mpz_mul(conjB, conjA, conjA); mpz_sub(conjB, conjB, factor); if (mpz_root(conjB, conjB, 2)) { mpz_sub(factor, conjA, conjB); if (recursion(factor, rootOrder) == false) return false; mpz_add(factor, conjA, conjB); return recursion(factor, rootOrder); } } itr = 0; do // Pollard // http://en.wikipedia.org/wiki/Pollard's_rho_algorithm#Variants { if (c) { if (itr++ > MAX_ITERATIONS_C) return false; } else if (cc >= 10000) if (itr++ > MAX_ITERATIONS) return recursion(factor, rootOrder); //Floyd f(x); f(y); f(y); mpz_mod(x, x, factor); mpz_mod(y, y, factor); mpz_sub(d, x, y); mpz_abs(d, d); mpz_gcd(d, d, factor); } while (equals(d, 1)); if (mpz_cmp(factor, d) == 0) { if (isPrime(factor)) { String strFactor = bignumToString(factor); for (r = 0; r < rootOrder; r++) { appendToBuffer(output, *outputPtr, strFactor); appendToBuffer(output, (*outputPtr) + 1, "\n"); (*outputPtr) += 2; } return true; } return recursion(factor, rootOrder); } if (isNotPrime(d)) { cd = contDiv(factor, factor, d, null, null, 0); if (recursion(d, rootOrder * cd) == false) return false; if (equals(factor, 1)) return true; } else { contDiv(factor, factor, d, output, outputPtr, rootOrder); if (equals(factor, 1)) return true; } if (isPrime(factor)) { String strFactor = bignumToString(factor); for (r = 0; r < rootOrder; r++) { appendToBuffer(output, *outputPtr, strFactor); appendToBuffer(output, (*outputPtr) + 1, "\n"); (*outputPtr) += 2; } return true; } } return true; }
void RLRequest::rl_sadd(){ if(args.size()<2){ connection->write_error("ERR wrong number of arguments for 'sadd' command"); return; } string &sname = args[0]; string sizekey = _encode_compdata_size_key(sname, CompDataType::SET); uint32_t new_mem = 0; std::string out; leveldb::WriteBatch write_batch; leveldb::Status status; for(uint32_t i=1; i<args.size(); i++){ string key = _encode_set_key(sname, args[i]); status = connection->server->db[connection->db_index]->Get( connection->server->read_options, key, &out); if(status.IsNotFound()) { // set value write_batch.Put(key, "\1"); ++new_mem; } } if(new_mem == 0){ connection->write_integer("0", 1); return; } // update size! status = connection->server->db[connection->db_index]->Get( connection->server->read_options, sizekey, &out); mpz_t delta; mpz_init(delta); mpz_set_ui(delta, new_mem); char *str_oldv = NULL; if(status.IsNotFound()){ str_oldv = strdup("0"); }else if(status.ok()){ str_oldv = (char*)malloc(out.size()+1); memcpy(str_oldv, out.data(), out.size()); str_oldv[out.size()] = 0; }else{ connection->write_error("SADD ERROR 1"); return; } mpz_t old_v; mpz_init(old_v); mpz_set_str(old_v, str_oldv, 10); free(str_oldv); mpz_add(old_v, old_v, delta); char *str_newv=mpz_get_str(NULL, 10, old_v); char *str_delta=mpz_get_str(NULL, 10, delta); mpz_clear(delta); mpz_clear(old_v); write_batch.Put(sizekey, str_newv); status = connection->server->db[connection->db_index]->Write(connection->server->write_options, &write_batch); if(!status.ok()) { connection->write_error("SADD ERROR 2"); }else{ connection->write_integer(str_delta, strlen(str_delta)); } free(str_newv); free(str_delta); }
int mpfr_zeta_ui (mpfr_ptr z, unsigned long m, mp_rnd_t r) { MPFR_ZIV_DECL (loop); if (m == 0) { mpfr_set_ui (z, 1, r); mpfr_div_2ui (z, z, 1, r); MPFR_CHANGE_SIGN (z); MPFR_RET (0); } else if (m == 1) { MPFR_SET_INF (z); MPFR_SET_POS (z); return 0; } else /* m >= 2 */ { mp_prec_t p = MPFR_PREC(z); unsigned long n, k, err, kbits; mpz_t d, t, s, q; mpfr_t y; int inex; if (m >= p) /* 2^(-m) < ulp(1) = 2^(1-p). This means that 2^(-m) <= 1/2*ulp(1). We have 3^(-m)+4^(-m)+... < 2^(-m) i.e. zeta(m) < 1+2*2^(-m) for m >= 3 */ { if (m == 2) /* necessarily p=2 */ return mpfr_set_ui_2exp (z, 13, -3, r); else if (r == GMP_RNDZ || r == GMP_RNDD || (r == GMP_RNDN && m > p)) { mpfr_set_ui (z, 1, r); return -1; } else { mpfr_set_ui (z, 1, r); mpfr_nextabove (z); return 1; } } /* now treat also the case where zeta(m) - (1+1/2^m) < 1/2*ulp(1), and the result is either 1+2^(-m) or 1+2^(-m)+2^(1-p). */ mpfr_init2 (y, 31); if (m >= p / 2) /* otherwise 4^(-m) > 2^(-p) */ { /* the following is a lower bound for log(3)/log(2) */ mpfr_set_str_binary (y, "1.100101011100000000011010001110"); mpfr_mul_ui (y, y, m, GMP_RNDZ); /* lower bound for log2(3^m) */ if (mpfr_cmp_ui (y, p + 2) >= 0) { mpfr_clear (y); mpfr_set_ui (z, 1, GMP_RNDZ); mpfr_div_2ui (z, z, m, GMP_RNDZ); mpfr_add_ui (z, z, 1, GMP_RNDZ); if (r != GMP_RNDU) return -1; mpfr_nextabove (z); return 1; } } mpz_init (s); mpz_init (d); mpz_init (t); mpz_init (q); p += MPFR_INT_CEIL_LOG2(p); /* account of the n term in the error */ p += MPFR_INT_CEIL_LOG2(p) + 15; /* initial value */ MPFR_ZIV_INIT (loop, p); for(;;) { /* 0.39321985067869744 = log(2)/log(3+sqrt(8)) */ n = 1 + (unsigned long) (0.39321985067869744 * (double) p); err = n + 4; mpfr_set_prec (y, p); /* computation of the d[k] */ mpz_set_ui (s, 0); mpz_set_ui (t, 1); mpz_mul_2exp (t, t, 2 * n - 1); /* t[n] */ mpz_set (d, t); for (k = n; k > 0; k--) { count_leading_zeros (kbits, k); kbits = BITS_PER_MP_LIMB - kbits; /* if k^m is too large, use mpz_tdiv_q */ if (m * kbits > 2 * BITS_PER_MP_LIMB) { /* if we know in advance that k^m > d, then floor(d/k^m) will be zero below, so there is no need to compute k^m */ kbits = (kbits - 1) * m + 1; /* k^m has at least kbits bits */ if (kbits > mpz_sizeinbase (d, 2)) mpz_set_ui (q, 0); else { mpz_ui_pow_ui (q, k, m); mpz_tdiv_q (q, d, q); } } else /* use several mpz_tdiv_q_ui calls */ { unsigned long km = k, mm = m - 1; while (mm > 0 && km < ULONG_MAX / k) { km *= k; mm --; } mpz_tdiv_q_ui (q, d, km); while (mm > 0) { km = k; mm --; while (mm > 0 && km < ULONG_MAX / k) { km *= k; mm --; } mpz_tdiv_q_ui (q, q, km); } } if (k % 2) mpz_add (s, s, q); else mpz_sub (s, s, q); /* we have d[k] = sum(t[i], i=k+1..n) with t[i] = n*(n+i-1)!*4^i/(n-i)!/(2i)! t[k-1]/t[k] = k*(2k-1)/(n-k+1)/(n+k-1)/2 */ #if (BITS_PER_MP_LIMB == 32) #define KMAX 46341 /* max k such that k*(2k-1) < 2^32 */ #elif (BITS_PER_MP_LIMB == 64) #define KMAX 3037000500 #endif #ifdef KMAX if (k <= KMAX) mpz_mul_ui (t, t, k * (2 * k - 1)); else #endif { mpz_mul_ui (t, t, k); mpz_mul_ui (t, t, 2 * k - 1); } mpz_div_2exp (t, t, 1); if (n < 1UL << (BITS_PER_MP_LIMB / 2)) /* (n - k + 1) * (n + k - 1) < n^2 */ mpz_divexact_ui (t, t, (n - k + 1) * (n + k - 1)); else { mpz_divexact_ui (t, t, n - k + 1); mpz_divexact_ui (t, t, n + k - 1); } mpz_add (d, d, t); } /* multiply by 1/(1-2^(1-m)) = 1 + 2^(1-m) + 2^(2-m) + ... */ mpz_div_2exp (t, s, m - 1); do { err ++; mpz_add (s, s, t); mpz_div_2exp (t, t, m - 1); } while (mpz_cmp_ui (t, 0) > 0); /* divide by d[n] */ mpz_mul_2exp (s, s, p); mpz_tdiv_q (s, s, d); mpfr_set_z (y, s, GMP_RNDN); mpfr_div_2ui (y, y, p, GMP_RNDN); err = MPFR_INT_CEIL_LOG2 (err); if (MPFR_LIKELY(MPFR_CAN_ROUND (y, p - err, MPFR_PREC(z), r))) break; MPFR_ZIV_NEXT (loop, p); } MPFR_ZIV_FREE (loop); mpz_clear (d); mpz_clear (t); mpz_clear (q); mpz_clear (s); inex = mpfr_set (z, y, r); mpfr_clear (y); return inex; } }
int main() { const int urfd = open("/dev/urandom", O_RDONLY); mpz_t p, q, n; fprintf(stderr, "Generating group...\n"); init_random_prime(p, urfd, 512, 3); init_random_prime(q, urfd, 512, 7); print(" p:", p); print(" q:", q); mpz_init(n); mpz_mul(n, p, q); print(" n:", n); fprintf(stderr, "Performing extended Euclid...\n"); mpz_t u, v; xgcd(u, v, p, q); mpz_mul(u, u, p); mpz_mul(v, v, q); print (" u:", u); print (" v:", v); fprintf(stderr, "Picking random element...\n"); mpz_t e; random_element(e, urfd, 1024, n); print(" e:", e); fprintf(stderr, "Tweaking...\n"); int a = is_quadratic_residue(e, p); int b = is_quadratic_residue(e, q); fprintf(stderr, " residue state: [%d, %d]\n", a, b); int mul_2 = 0, negate = 0; if (a ^ b) { mul_2 = 1; a ^= 1; } if (!a) { negate = 1; a ^= 1; b ^= 1; } fprintf(stderr, " tweaks: 2:%d -:%d\n", mul_2, negate); if (negate) { mpz_neg(e, e); } if (mul_2) { mpz_mul_ui(e, e, 2); } if (negate || mul_2) mpz_mod(e, e, n); print(" tweaked e:", e); uint8_t root; read(urfd, &root, 1); root &= 3; fprintf(stderr, "Calculating root %d...\n", root); mpz_t pp1over4, qp1over4; mpz_init_set(pp1over4, p); mpz_add_ui(pp1over4, pp1over4, 1); mpz_cdiv_q_2exp(pp1over4, pp1over4, 2); mpz_init_set(qp1over4, q); mpz_add_ui(qp1over4, qp1over4, 1); mpz_cdiv_q_2exp(qp1over4, qp1over4, 2); mpz_t proot, qroot; mpz_init_set(proot, e); mpz_powm(proot, e, pp1over4, p); mpz_init_set(qroot, e); mpz_powm(qroot, e, qp1over4, q); if (root & 1) mpz_neg(proot, proot); if (root & 2) mpz_neg(qroot, qroot); mpz_mul(proot, proot, v); mpz_mul(qroot, qroot, u); mpz_add(proot, proot, qroot); mpz_mod(proot, proot, n); print(" sig:", proot); fprintf(stderr, "Compressing signature...\n"); mpz_t zsig; mpz_t ncopy; mpz_init_set(ncopy, n); signature_compress(zsig, proot, ncopy); print(" zsig:", zsig); mpz_t zsigcopy, t, t2; mpz_init(t); mpz_init(t2); mpz_init(zsigcopy); fprintf(stderr, "Performing 1000000 verifications\n"); const uint64_t start_time = time_now(); unsigned i; for (i = 0; i < 1000000; ++i) { mpz_set(zsigcopy, zsig); mpz_mul(zsigcopy, zsigcopy, zsigcopy); mpz_mul(zsigcopy, zsigcopy, e); mpz_mod(zsigcopy, zsigcopy, n); if (0 == mpz_sgn(zsigcopy)) abort(); mpz_sqrtrem(t, t2, zsigcopy); if (mpz_sgn(t2)) abort(); } const uint64_t end_time = time_now(); fprintf(stderr, "verify time: %f\n", ((double) (end_time - start_time)) / 1000000); return 0; }
int main() { int i, z; /* Initialize constants */ mpz_init_set_str(c[0], "1", 10); mpz_init_set_str(c[1], "5", 10); /* Initialize variables */ for (i = 0; i < VARS; i++) { mpz_init(v[i]); } /* Goal: ? a^5H */ mpz_add(v[1], v[1], c[1]); mpz_add(v[35], v[35], c[0]); while (1) { if (0) { } else if (mpz_cmp(v[35], c[0]) >= 0) { /* H => mZ */ mpz_sub(v[35], v[35], c[0]); mpz_add(v[12], v[12], c[0]); mpz_add(v[0], v[0], c[0]); } else if (mpz_cmp(v[1], c[0]) >= 0 && mpz_cmp(v[12], c[0]) >= 0) { /* am => af */ mpz_sub(v[1], v[1], c[0]); mpz_sub(v[12], v[12], c[0]); mpz_add(v[1], v[1], c[0]); mpz_add(v[7], v[7], c[0]); } else if (mpz_cmp(v[12], c[0]) >= 0) { /* m => J */ mpz_sub(v[12], v[12], c[0]); mpz_add(v[37], v[37], c[0]); } else if (mpz_cmp(v[1], c[0]) >= 0 && mpz_cmp(v[7], c[0]) >= 0) { /* af => aB */ mpz_sub(v[1], v[1], c[0]); mpz_sub(v[7], v[7], c[0]); mpz_add(v[1], v[1], c[0]); mpz_add(v[15], v[15], c[0]); } else if (mpz_cmp(v[7], c[0]) >= 0) { /* f => k */ mpz_sub(v[7], v[7], c[0]); mpz_add(v[10], v[10], c[0]); } else if (mpz_cmp(v[1], c[0]) >= 0 && mpz_cmp(v[15], c[0]) >= 0) { /* aB => u */ mpz_sub(v[1], v[1], c[0]); mpz_sub(v[15], v[15], c[0]); mpz_add(v[22], v[22], c[0]); } else if (mpz_cmp(v[15], c[0]) >= 0) { /* B => u */ mpz_sub(v[15], v[15], c[0]); mpz_add(v[22], v[22], c[0]); } else if (mpz_cmp(v[22], c[0]) >= 0) { /* u => cL */ mpz_sub(v[22], v[22], c[0]); mpz_add(v[3], v[3], c[0]); mpz_add(v[38], v[38], c[0]); } else if (mpz_cmp(v[38], c[0]) >= 0) { /* L => eG */ mpz_sub(v[38], v[38], c[0]); mpz_add(v[4], v[4], c[0]); mpz_add(v[32], v[32], c[0]); } else if (mpz_cmp(v[32], c[0]) >= 0) { /* G => f */ mpz_sub(v[32], v[32], c[0]); mpz_add(v[7], v[7], c[0]); } else if (mpz_cmp(v[3], c[0]) >= 0 && mpz_cmp(v[10], c[0]) >= 0) { /* ck => cr */ mpz_sub(v[3], v[3], c[0]); mpz_sub(v[10], v[10], c[0]); mpz_add(v[3], v[3], c[0]); mpz_add(v[21], v[21], c[0]); } else if (mpz_cmp(v[10], c[0]) >= 0) { /* k => d */ mpz_sub(v[10], v[10], c[0]); mpz_add(v[5], v[5], c[0]); } else if (mpz_cmp(v[3], c[0]) >= 0 && mpz_cmp(v[21], c[0]) >= 0) { /* cr => b */ mpz_sub(v[3], v[3], c[0]); mpz_sub(v[21], v[21], c[0]); mpz_add(v[2], v[2], c[0]); } else if (mpz_cmp(v[21], c[0]) >= 0) { /* r => b */ mpz_sub(v[21], v[21], c[0]); mpz_add(v[2], v[2], c[0]); } else if (mpz_cmp(v[2], c[0]) >= 0 && mpz_cmp(v[0], c[0]) >= 0) { /* bZ => yZ */ mpz_sub(v[2], v[2], c[0]); mpz_sub(v[0], v[0], c[0]); mpz_add(v[26], v[26], c[0]); mpz_add(v[0], v[0], c[0]); } else if (mpz_cmp(v[2], c[0]) >= 0) { /* b => j */ mpz_sub(v[2], v[2], c[0]); mpz_add(v[11], v[11], c[0]); } else if (mpz_cmp(v[26], c[0]) >= 0 && mpz_cmp(v[0], c[0]) >= 0) { /* yZ => t */ mpz_sub(v[26], v[26], c[0]); mpz_sub(v[0], v[0], c[0]); mpz_add(v[23], v[23], c[0]); } else if (mpz_cmp(v[26], c[0]) >= 0) { /* y => t */ mpz_sub(v[26], v[26], c[0]); mpz_add(v[23], v[23], c[0]); } else if (mpz_cmp(v[23], c[0]) >= 0) { /* t => iK */ mpz_sub(v[23], v[23], c[0]); mpz_add(v[8], v[8], c[0]); mpz_add(v[36], v[36], c[0]); } else if (mpz_cmp(v[36], c[0]) >= 0) { /* K => lE */ mpz_sub(v[36], v[36], c[0]); mpz_add(v[13], v[13], c[0]); mpz_add(v[30], v[30], c[0]); } else if (mpz_cmp(v[30], c[0]) >= 0) { /* E => b */ mpz_sub(v[30], v[30], c[0]); mpz_add(v[2], v[2], c[0]); } else if (mpz_cmp(v[8], c[0]) >= 0 && mpz_cmp(v[11], c[0]) >= 0) { /* ij => is */ mpz_sub(v[8], v[8], c[0]); mpz_sub(v[11], v[11], c[0]); mpz_add(v[8], v[8], c[0]); mpz_add(v[20], v[20], c[0]); } else if (mpz_cmp(v[11], c[0]) >= 0) { /* j => I */ mpz_sub(v[11], v[11], c[0]); mpz_add(v[34], v[34], c[0]); } else if (mpz_cmp(v[8], c[0]) >= 0 && mpz_cmp(v[20], c[0]) >= 0) { /* is => x */ mpz_sub(v[8], v[8], c[0]); mpz_sub(v[20], v[20], c[0]); mpz_add(v[27], v[27], c[0]); } else if (mpz_cmp(v[20], c[0]) >= 0) { /* s => x */ mpz_sub(v[20], v[20], c[0]); mpz_add(v[27], v[27], c[0]); } else if (mpz_cmp(v[27], c[0]) >= 0) { /* x => DZ */ mpz_sub(v[27], v[27], c[0]); mpz_add(v[31], v[31], c[0]); mpz_add(v[0], v[0], c[0]); } else if (mpz_cmp(v[31], c[0]) >= 0) { /* D => j */ mpz_sub(v[31], v[31], c[0]); mpz_add(v[11], v[11], c[0]); } else if (mpz_cmp(v[34], c[0]) >= 0) { /* I => k */ mpz_sub(v[34], v[34], c[0]); mpz_add(v[10], v[10], c[0]); } else if (mpz_cmp(v[5], c[0]) >= 0 && mpz_cmp(v[0], c[0]) >= 0) { /* dZ => wZ */ mpz_sub(v[5], v[5], c[0]); mpz_sub(v[0], v[0], c[0]); mpz_add(v[24], v[24], c[0]); mpz_add(v[0], v[0], c[0]); } else if (mpz_cmp(v[5], c[0]) >= 0) { /* d => h */ mpz_sub(v[5], v[5], c[0]); mpz_add(v[9], v[9], c[0]); } else if (mpz_cmp(v[24], c[0]) >= 0 && mpz_cmp(v[0], c[0]) >= 0) { /* wZ => o */ mpz_sub(v[24], v[24], c[0]); mpz_sub(v[0], v[0], c[0]); mpz_add(v[16], v[16], c[0]); } else if (mpz_cmp(v[24], c[0]) >= 0) { /* w => o */ mpz_sub(v[24], v[24], c[0]); mpz_add(v[16], v[16], c[0]); } else if (mpz_cmp(v[16], c[0]) >= 0) { /* o => d */ mpz_sub(v[16], v[16], c[0]); mpz_add(v[5], v[5], c[0]); } else if (mpz_cmp(v[9], c[0]) >= 0 && mpz_cmp(v[13], c[0]) >= 0) { /* hl => lp */ mpz_sub(v[9], v[9], c[0]); mpz_sub(v[13], v[13], c[0]); mpz_add(v[13], v[13], c[0]); mpz_add(v[19], v[19], c[0]); } else if (mpz_cmp(v[9], c[0]) >= 0) { /* h => g */ mpz_sub(v[9], v[9], c[0]); mpz_add(v[6], v[6], c[0]); } else if (mpz_cmp(v[13], c[0]) >= 0 && mpz_cmp(v[19], c[0]) >= 0) { /* lp => v */ mpz_sub(v[13], v[13], c[0]); mpz_sub(v[19], v[19], c[0]); mpz_add(v[25], v[25], c[0]); } else if (mpz_cmp(v[19], c[0]) >= 0) { /* p => v */ mpz_sub(v[19], v[19], c[0]); mpz_add(v[25], v[25], c[0]); } else if (mpz_cmp(v[25], c[0]) >= 0) { /* v => CZ */ mpz_sub(v[25], v[25], c[0]); mpz_add(v[29], v[29], c[0]); mpz_add(v[0], v[0], c[0]); } else if (mpz_cmp(v[29], c[0]) >= 0) { /* C => h */ mpz_sub(v[29], v[29], c[0]); mpz_add(v[9], v[9], c[0]); } else if (mpz_cmp(v[4], c[0]) >= 0 && mpz_cmp(v[6], c[0]) >= 0) { /* eg => en */ mpz_sub(v[4], v[4], c[0]); mpz_sub(v[6], v[6], c[0]); mpz_add(v[4], v[4], c[0]); mpz_add(v[17], v[17], c[0]); } else if (mpz_cmp(v[6], c[0]) >= 0) { /* g => q */ mpz_sub(v[6], v[6], c[0]); mpz_add(v[18], v[18], c[0]); } else if (mpz_cmp(v[4], c[0]) >= 0 && mpz_cmp(v[17], c[0]) >= 0) { /* en => z */ mpz_sub(v[4], v[4], c[0]); mpz_sub(v[17], v[17], c[0]); mpz_add(v[28], v[28], c[0]); } else if (mpz_cmp(v[17], c[0]) >= 0) { /* n => z */ mpz_sub(v[17], v[17], c[0]); mpz_add(v[28], v[28], c[0]); } else if (mpz_cmp(v[28], c[0]) >= 0) { /* z => aF */ mpz_sub(v[28], v[28], c[0]); mpz_add(v[1], v[1], c[0]); mpz_add(v[33], v[33], c[0]); } else if (mpz_cmp(v[33], c[0]) >= 0) { /* F => g */ mpz_sub(v[33], v[33], c[0]); mpz_add(v[6], v[6], c[0]); } else if (mpz_cmp(v[1], c[0]) >= 0 && mpz_cmp(v[18], c[0]) >= 0) { /* aq => A */ mpz_sub(v[1], v[1], c[0]); mpz_sub(v[18], v[18], c[0]); mpz_add(v[14], v[14], c[0]); } else if (mpz_cmp(v[18], c[0]) >= 0) { /* q => A */ mpz_sub(v[18], v[18], c[0]); mpz_add(v[14], v[14], c[0]); } else if (mpz_cmp(v[14], c[0]) >= 0) { /* A => m */ mpz_sub(v[14], v[14], c[0]); mpz_add(v[12], v[12], c[0]); } else if (mpz_cmp(v[37], c[0]) >= 0) { /* J */ mpz_sub(v[37], v[37], c[0]); } else { break; } } z = 1; for (i = 0; i < VARS; i++) { if (mpz_cmp_ui(v[i], 0) > 0) { if (!z) { printf(" "); } z = 0; printf("%s", n[i]); if (mpz_cmp_ui(v[i], 1) > 0) { printf("^"); mpz_out_str(stdout, 10, v[i]); } } } if (z) { printf("1"); } printf("\n"); return 0; }
void add_bi(mpz_t res, mpz_t a, mpz_t b) { mpz_add(res,a,b); }
main (int argc, char *argv[]) { mpz_t n, c, x1, x2, product, t, g, t1, t2; unsigned long max, range, terms, j, ans; mpz_init (n); mpz_init (c); mpz_init (x1); mpz_init (x2); mpz_init (product); mpz_init (t); mpz_init (g); mpz_init (t1); mpz_init (t2); initialize: mpz_set_str (n, argv[1], 10); gmp_printf("n = %Zd\n", n); mpz_set_str (c, argv[2], 10); max = atoi(argv[3]); restart: mpz_set_ui (x1, 2); mpz_add_ui (x2, c, 4); range = 1; mpz_set_ui (product, 1); terms = 0; compute_diff: while ( terms <= max ) { for (j=1; j<=range; j++) { mpz_mul (t, x2, x2); mpz_add (t, t, c); mpz_fdiv_r ( x2, t, n ); mpz_sub (t, x1, x2); mpz_mul (t, product, t); mpz_fdiv_r (product, t, n); terms++; if ((terms%10) == 0) { mpz_set (t1, n); mpz_set (t2, product); gcd (g, t1, t2); if (mpz_cmp_ui (g, 1) > 0) { gmp_printf("g = %Zd\n",g); goto terminate; } mpz_set_ui (product, 1); } } reset: mpz_set (x1, x2); range = 2*range; for (j=1; j<=range; j++) { mpz_mul (t, x2, x2); mpz_add (t, t, c); mpz_fdiv_r (x2, t, n); } } gmp_printf("n = %Zd --- no factor found for c = %Zd!!!\n", n, c); printf("Enter 1 to input new c, 0 to stop\n"); scanf("%d",&ans); if (ans != 1) goto terminate; printf("Enter new c value:"); gmp_scanf("%Zd",&c); goto restart; terminate: mpz_clear (g); mpz_clear (t); mpz_clear (product); mpz_clear (x2); mpz_clear (x1); mpz_clear (c); mpz_clear (n); mpz_clear (t1); mpz_clear (t2); exit (0); }
int main(int argc, const char *argv[]) { int res; char *str; mpz_t largenum; if (argc <= 0) { fprintf(stderr, "usage: %s\n", argv[0]); exit(EXIT_SUCCESS); } fprintf(stderr, "setting pitch\n"); orient_range.orient.pitch = 180; orient_range.pitch_range = 10; fprintf(stderr, "setting roll\n"); orient_range.orient.roll = 0; orient_range.roll_range = 10; fprintf(stderr, "setting azimuth\n"); orient_range.orient.azimuth = 0; orient_range.azimuth_range = 0; mpz_init_set_str(one, "1", 10); mpz_init_set_str(two, "2", 10); gmp_randinit_default(randstate); sleep(1); if (syscall(__NR_orientlock_read, &orient_range) == -1) { fprintf(stderr, "error: Unable to obtain lock\n"); exit(EXIT_FAILURE); } fp = fopen("./integer", "r"); if ((fgets(integer, INTEGER_BUF_SIZE, fp)) == NULL) { fprintf(stderr, "error: Unable to read from file"); exit(EXIT_FAILURE); } chomp_line(integer); mpz_init(largenum); mpz_init_set_str(largenum, integer, 10); str = mpz_to_str(largenum); if (!str) return EXIT_FAILURE; /* * We simply return the prime number itself if the base is prime. * (We use the GMP probabilistic function with 10 repetitions). */ res = mpz_probab_prime_p(largenum, 10); if (res) { printf("%s is a prime number\n", str); free(str); mpz_add(largenum, largenum, one); } printf("Prime factors for %s are: ", str); free(str); factor(largenum); printf("\n"); fclose(fp); if (syscall(__NR_orientunlock_read, &orient_range) == -1) { fprintf(stderr, "error: Unable to unlock\n"); exit(EXIT_FAILURE); } return EXIT_SUCCESS; }
//入力の行列の逆行列を返す //対角成分が0の場合考える matrix *tfel_invert(const matrix *D, const EC_PAIRING p) { int i, j, k, l; mpz_t order; mpz_init(order); mpz_set(order, *pairing_get_order(p)); matrix *temp1, *inv; //逆行列求める行列のコピー temp1 = tfel_matrix_copy(D); //ここに逆行列が入る inv = tfel_matrix_init(D->dim); for(i = 0; i < D->dim; i++) { mpz_set_str(inv->M[i][i], "1", 10); } //一時的なデータを蓄える mpz_t buf1, buf2, buf3, buf4, *temp_v1, *temp_v2; mpz_init(buf1); mpz_init(buf2); mpz_init(buf3); mpz_init(buf4); temp_v1 = (mpz_t*)malloc(sizeof(mpz_t)*temp1->dim); temp_v2 = (mpz_t*)malloc(sizeof(mpz_t)*temp1->dim); for(i = 0; i < temp1->dim; i++) { mpz_init(temp_v1[i]); mpz_init(temp_v2[i]); } //すごく汚い掃き出し法 for(i=0; i < temp1->dim; i++) { mpz_invert(buf1, temp1->M[i][i], order); //j行j列の乗法の逆元求める(1) for(j=0; j < temp1->dim; j++) { mpz_mul(buf2, buf1, temp1->M[i][j]); mpz_set(temp1->M[i][j], buf2); //(1)をi行全体にかける(2) //mpz_set(temp_v1[j], buf2); //(2)のコピー mpz_mod(temp_v1[j], buf2, order); mpz_mul(buf2, buf1, inv->M[i][j]); mpz_set(inv->M[i][j], buf2); //単位行列の方にも同様の操作 //mpz_set(temp_v2[j], buf2); mpz_mod(temp_v2[j], buf2, order); } //ここまでokだと思う…… for(k=0; k < temp1->dim; k++) { if(i == k) continue; //element_neg(buf1, temp1->M[k][i]); //i行以外の行のj列の加法の逆元求める(3) mpz_neg(buf1, temp1->M[k][i]); for(l=0; l < temp1->dim; l++) { mpz_mul(buf3, buf1, temp_v1[l]); //(3)×(2) mpz_add(buf4, buf3, temp1->M[k][l]); //(4) mpz_set(temp1->M[k][l], buf4); mpz_mul(buf3, buf1, temp_v2[l]); mpz_add(buf4, buf3, inv->M[k][l]); mpz_mod(inv->M[k][l], buf4, order); //単位行列の方にも同様の操作 } } } //invert check→ok!! mpz_t temp_1, temp_2, result; mpz_init(temp_1); mpz_init(temp_2); for(k = 0; k < D->dim; k++) { for(i = 0; i < D->dim; i++) { mpz_init_set_ui(result, 0); for(j = 0; j < D->dim; j++) { mpz_mul(temp_1, D->M[k][j], inv->M[j][i]); mpz_add(temp_2, temp_1, result); mpz_mod(result, temp_2, order); } if(k == i) { if(mpz_get_ui(result) != 1) { printf("error\n"); goto clear; } } else { if(mpz_get_ui(result) != 0) { printf("error\n"); goto clear; } } } } clear: mpz_clear(temp_1); mpz_clear(temp_2); mpz_clear(result); //invert check mpz_clear(order); mpz_clear(buf1); mpz_clear(buf2); mpz_clear(buf3); mpz_clear(buf4); for(i=0; i < temp1->dim; i++) { mpz_clear(temp_v1[i]); mpz_clear(temp_v2[i]); } free(temp_v1); free(temp_v2); tfel_matrix_clear(temp1); return inv; }
void LLLoperations::SWAPI(int k, int kmax, MutableMatrix *A, MutableMatrix *Achange, // can be NULL MutableMatrix *lambda) { int i; mpz_t a,b,B,C1,C2,D,D1,lam; ring_elem rD1,rD,rlam; A->interchange_columns(k,k-1); if (Achange) Achange->interchange_columns(k,k-1); mpz_init(a); mpz_init(b); mpz_init(B); mpz_init(C1); mpz_init(C2); lambda->get_entry(k-1,k-1,rD1); lambda->get_entry(k,k,rD); mpz_init_set(D1,rD1.get_mpz()); mpz_init_set(D,rD.get_mpz()); if (lambda->get_entry(k-1,k,rlam)) mpz_init_set(lam,rlam.get_mpz()); else mpz_init(lam); // Interchange both of these columns, except for these three terms: if (k >= 2) { lambda->interchange_columns(k,k-1); lambda->set_entry(k-1,k,globalZZ->from_int(lam)); lambda->set_entry(k,k,globalZZ->from_int(D)); lambda->set_entry(k,k-1,globalZZ->from_int(0)); // (k-1,k-1) is set below. } // B := (D#(k-2) * D#k + lam^2) // D#(k-1); if (k == 1) mpz_set(a,D); else { ring_elem rD2; lambda->get_entry(k-2,k-2,rD2); mpz_mul(a,rD2.get_mpz(),D); } mpz_mul(b,lam,lam); mpz_add(a,a,b); mpz_fdiv_q(B,a,D1); lambda->set_entry(k-1,k-1,globalZZ->from_int(B)); // scan(k+1..C.kmax, i-> ( // t := lambda#(i,k); // lambda#(i,k) = (D#k * lambda#(i,k-1) - lam * t) // D#(k-1); // lambda#(i,k-1) = (B*t + lam*lambda#(i,k))//(D#k);)); for (i=k+1; i<=kmax; i++) { ring_elem s,t; bool s_notzero = lambda->get_entry(k-1,i,s); bool t_notzero = lambda->get_entry(k,i,t); if (s_notzero) mpz_mul(a,D, s.get_mpz()); else mpz_set_ui(a,0); // lambda#(i,k) = (D#k * lambda#(i,k-1) - lam * t) // D#(k-1); if (t_notzero) mpz_mul(b,lam,t.get_mpz()); else mpz_set_ui(b,0); mpz_sub(a,a,b); mpz_fdiv_q(C1,a,D1); // lambda#(i,k-1) = (B*t + lam*lambda#(i,k))//(D#k);)); mpz_mul(b,lam,C1); if (t_notzero) mpz_mul(a,B,t.get_mpz()); else mpz_set_ui(a,0); mpz_add(a,a,b); mpz_fdiv_q(C2,a,D); lambda->set_entry(k,i,globalZZ->from_int(C1)); // These two lines will remove t,s. lambda->set_entry(k-1,i,globalZZ->from_int(C2)); } mpz_clear(a); mpz_clear(b); mpz_clear(B); mpz_clear(C1); mpz_clear(C2); mpz_clear(D1); mpz_clear(D); mpz_clear(lam); }
void one_test (mpz_t op1, mpz_t op2, mpz_t ref, int i) { /* printf ("%ld %ld %ld\n", SIZ (op1), SIZ (op2), SIZ (ref)); fflush (stdout); */ /* fprintf (stderr, "op1="); debug_mp (op1, -16); fprintf (stderr, "op2="); debug_mp (op2, -16); */ mpz_gcdext (gcd1, s, NULL, op1, op2); if (ref && mpz_cmp (ref, gcd1) != 0) { fprintf (stderr, "ERROR in test %d\n", i); fprintf (stderr, "mpz_gcdext returned incorrect result\n"); fprintf (stderr, "op1="); debug_mp (op1, -16); fprintf (stderr, "op2="); debug_mp (op2, -16); fprintf (stderr, "expected result:\n"); debug_mp (ref, -16); fprintf (stderr, "mpz_gcdext returns:\n");debug_mp (gcd1, -16); abort (); } if (!gcdext_valid_p(op1, op2, gcd1, s)) { fprintf (stderr, "ERROR in test %d\n", i); fprintf (stderr, "mpz_gcdext returned invalid result\n"); fprintf (stderr, "op1="); debug_mp (op1, -16); fprintf (stderr, "op2="); debug_mp (op2, -16); fprintf (stderr, "mpz_gcdext returns:\n");debug_mp (gcd1, -16); abort (); } mpz_gcd (gcd2, op1, op2); if (mpz_cmp (gcd2, gcd1) != 0) { fprintf (stderr, "ERROR in test %d\n", i); fprintf (stderr, "mpz_gcd returned incorrect result\n"); fprintf (stderr, "op1="); debug_mp (op1, -16); fprintf (stderr, "op2="); debug_mp (op2, -16); fprintf (stderr, "expected result:\n"); debug_mp (gcd1, -16); fprintf (stderr, "mpz_gcd returns:\n"); debug_mp (gcd2, -16); abort (); } /* This should probably move to t-gcd_ui.c */ if (mpz_fits_ulong_p (op1) || mpz_fits_ulong_p (op2)) { if (mpz_fits_ulong_p (op1)) mpz_gcd_ui (gcd2, op2, mpz_get_ui (op1)); else mpz_gcd_ui (gcd2, op1, mpz_get_ui (op2)); if (mpz_cmp (gcd2, gcd1)) { fprintf (stderr, "ERROR in test %d\n", i); fprintf (stderr, "mpz_gcd_ui returned incorrect result\n"); fprintf (stderr, "op1="); debug_mp (op1, -16); fprintf (stderr, "op2="); debug_mp (op2, -16); fprintf (stderr, "expected result:\n"); debug_mp (gcd1, -16); fprintf (stderr, "mpz_gcd_ui returns:\n"); debug_mp (gcd2, -16); abort (); } } mpz_gcdext (gcd2, temp1, temp2, op1, op2); mpz_mul (temp1, temp1, op1); mpz_mul (temp2, temp2, op2); mpz_add (temp1, temp1, temp2); if (mpz_cmp (gcd1, gcd2) != 0 || mpz_cmp (gcd2, temp1) != 0) { fprintf (stderr, "ERROR in test %d\n", i); fprintf (stderr, "mpz_gcdext returned incorrect result\n"); fprintf (stderr, "op1="); debug_mp (op1, -16); fprintf (stderr, "op2="); debug_mp (op2, -16); fprintf (stderr, "expected result:\n"); debug_mp (gcd1, -16); fprintf (stderr, "mpz_gcdext returns:\n");debug_mp (gcd2, -16); abort (); } }
bool gfc_assign_data_value (gfc_expr *lvalue, gfc_expr *rvalue, mpz_t index, mpz_t *repeat) { gfc_ref *ref; gfc_expr *init; gfc_expr *expr = NULL; gfc_constructor *con; gfc_constructor *last_con; gfc_symbol *symbol; gfc_typespec *last_ts; mpz_t offset; symbol = lvalue->symtree->n.sym; init = symbol->value; last_ts = &symbol->ts; last_con = NULL; mpz_init_set_si (offset, 0); /* Find/create the parent expressions for subobject references. */ for (ref = lvalue->ref; ref; ref = ref->next) { /* Break out of the loop if we find a substring. */ if (ref->type == REF_SUBSTRING) { /* A substring should always be the last subobject reference. */ gcc_assert (ref->next == NULL); break; } /* Use the existing initializer expression if it exists. Otherwise create a new one. */ if (init == NULL) expr = gfc_get_expr (); else expr = init; /* Find or create this element. */ switch (ref->type) { case REF_ARRAY: if (ref->u.ar.as->rank == 0) { gcc_assert (ref->u.ar.as->corank > 0); if (init == NULL) free (expr); continue; } if (init && expr->expr_type != EXPR_ARRAY) { gfc_error_1 ("'%s' at %L already is initialized at %L", lvalue->symtree->n.sym->name, &lvalue->where, &init->where); goto abort; } if (init == NULL) { /* The element typespec will be the same as the array typespec. */ expr->ts = *last_ts; /* Setup the expression to hold the constructor. */ expr->expr_type = EXPR_ARRAY; expr->rank = ref->u.ar.as->rank; } if (ref->u.ar.type == AR_ELEMENT) get_array_index (&ref->u.ar, &offset); else mpz_set (offset, index); /* Check the bounds. */ if (mpz_cmp_si (offset, 0) < 0) { gfc_error ("Data element below array lower bound at %L", &lvalue->where); goto abort; } else if (repeat != NULL && ref->u.ar.type != AR_ELEMENT) { mpz_t size, end; gcc_assert (ref->u.ar.type == AR_FULL && ref->next == NULL); mpz_init_set (end, offset); mpz_add (end, end, *repeat); if (spec_size (ref->u.ar.as, &size)) { if (mpz_cmp (end, size) > 0) { mpz_clear (size); gfc_error ("Data element above array upper bound at %L", &lvalue->where); goto abort; } mpz_clear (size); } con = gfc_constructor_lookup (expr->value.constructor, mpz_get_si (offset)); if (!con) { con = gfc_constructor_lookup_next (expr->value.constructor, mpz_get_si (offset)); if (con != NULL && mpz_cmp (con->offset, end) >= 0) con = NULL; } /* Overwriting an existing initializer is non-standard but usually only provokes a warning from other compilers. */ if (con != NULL && con->expr != NULL) { /* Order in which the expressions arrive here depends on whether they are from data statements or F95 style declarations. Therefore, check which is the most recent. */ gfc_expr *exprd; exprd = (LOCATION_LINE (con->expr->where.lb->location) > LOCATION_LINE (rvalue->where.lb->location)) ? con->expr : rvalue; if (gfc_notify_std (GFC_STD_GNU, "re-initialization of %qs at %L", symbol->name, &exprd->where) == false) return false; } while (con != NULL) { gfc_constructor *next_con = gfc_constructor_next (con); if (mpz_cmp (con->offset, end) >= 0) break; if (mpz_cmp (con->offset, offset) < 0) { gcc_assert (mpz_cmp_si (con->repeat, 1) > 0); mpz_sub (con->repeat, offset, con->offset); } else if (mpz_cmp_si (con->repeat, 1) > 0 && mpz_get_si (con->offset) + mpz_get_si (con->repeat) > mpz_get_si (end)) { int endi; splay_tree_node node = splay_tree_lookup (con->base, mpz_get_si (con->offset)); gcc_assert (node && con == (gfc_constructor *) node->value && node->key == (splay_tree_key) mpz_get_si (con->offset)); endi = mpz_get_si (con->offset) + mpz_get_si (con->repeat); if (endi > mpz_get_si (end) + 1) mpz_set_si (con->repeat, endi - mpz_get_si (end)); else mpz_set_si (con->repeat, 1); mpz_set (con->offset, end); node->key = (splay_tree_key) mpz_get_si (end); break; } else gfc_constructor_remove (con); con = next_con; } con = gfc_constructor_insert_expr (&expr->value.constructor, NULL, &rvalue->where, mpz_get_si (offset)); mpz_set (con->repeat, *repeat); repeat = NULL; mpz_clear (end); break; } else { mpz_t size; if (spec_size (ref->u.ar.as, &size)) { if (mpz_cmp (offset, size) >= 0) { mpz_clear (size); gfc_error ("Data element above array upper bound at %L", &lvalue->where); goto abort; } mpz_clear (size); } } con = gfc_constructor_lookup (expr->value.constructor, mpz_get_si (offset)); if (!con) { con = gfc_constructor_insert_expr (&expr->value.constructor, NULL, &rvalue->where, mpz_get_si (offset)); } else if (mpz_cmp_si (con->repeat, 1) > 0) { /* Need to split a range. */ if (mpz_cmp (con->offset, offset) < 0) { gfc_constructor *pred_con = con; con = gfc_constructor_insert_expr (&expr->value.constructor, NULL, &con->where, mpz_get_si (offset)); con->expr = gfc_copy_expr (pred_con->expr); mpz_add (con->repeat, pred_con->offset, pred_con->repeat); mpz_sub (con->repeat, con->repeat, offset); mpz_sub (pred_con->repeat, offset, pred_con->offset); } if (mpz_cmp_si (con->repeat, 1) > 0) { gfc_constructor *succ_con; succ_con = gfc_constructor_insert_expr (&expr->value.constructor, NULL, &con->where, mpz_get_si (offset) + 1); succ_con->expr = gfc_copy_expr (con->expr); mpz_sub_ui (succ_con->repeat, con->repeat, 1); mpz_set_si (con->repeat, 1); } } break; case REF_COMPONENT: if (init == NULL) { /* Setup the expression to hold the constructor. */ expr->expr_type = EXPR_STRUCTURE; expr->ts.type = BT_DERIVED; expr->ts.u.derived = ref->u.c.sym; } else gcc_assert (expr->expr_type == EXPR_STRUCTURE); last_ts = &ref->u.c.component->ts; /* Find the same element in the existing constructor. */ con = find_con_by_component (ref->u.c.component, expr->value.constructor); if (con == NULL) { /* Create a new constructor. */ con = gfc_constructor_append_expr (&expr->value.constructor, NULL, NULL); con->n.component = ref->u.c.component; } break; default: gcc_unreachable (); } if (init == NULL) { /* Point the container at the new expression. */ if (last_con == NULL) symbol->value = expr; else last_con->expr = expr; } init = con->expr; last_con = con; } mpz_clear (offset); gcc_assert (repeat == NULL); if (ref || last_ts->type == BT_CHARACTER) { if (lvalue->ts.u.cl->length == NULL && !(ref && ref->u.ss.length != NULL)) return false; expr = create_character_initializer (init, last_ts, ref, rvalue); } else { /* Overwriting an existing initializer is non-standard but usually only provokes a warning from other compilers. */ if (init != NULL) { /* Order in which the expressions arrive here depends on whether they are from data statements or F95 style declarations. Therefore, check which is the most recent. */ expr = (LOCATION_LINE (init->where.lb->location) > LOCATION_LINE (rvalue->where.lb->location)) ? init : rvalue; if (gfc_notify_std (GFC_STD_GNU, "re-initialization of %qs at %L", symbol->name, &expr->where) == false) return false; } expr = gfc_copy_expr (rvalue); if (!gfc_compare_types (&lvalue->ts, &expr->ts)) gfc_convert_type (expr, &lvalue->ts, 0); } if (last_con == NULL) symbol->value = expr; else last_con->expr = expr; return true; abort: if (!init) gfc_free_expr (expr); mpz_clear (offset); return false; }
/* f <- 1 - r/2! + r^2/4! + ... + (-1)^l r^l/(2l)! + ... Assumes |r| < 1/2, and f, r have the same precision. Returns e such that the error on f is bounded by 2^e ulps. */ static int mpfr_cos2_aux (mpfr_ptr f, mpfr_srcptr r) { mpz_t x, t, s; mpfr_exp_t ex, l, m; mpfr_prec_t p, q; unsigned long i, maxi, imax; MPFR_ASSERTD(mpfr_get_exp (r) <= -1); /* compute minimal i such that i*(i+1) does not fit in an unsigned long, assuming that there are no padding bits. */ maxi = 1UL << (CHAR_BIT * sizeof(unsigned long) / 2); if (maxi * (maxi / 2) == 0) /* test checked at compile time */ { /* can occur only when there are padding bits. */ /* maxi * (maxi-1) is representable iff maxi * (maxi / 2) != 0 */ do maxi /= 2; while (maxi * (maxi / 2) == 0); } mpz_init (x); mpz_init (s); mpz_init (t); ex = mpfr_get_z_2exp (x, r); /* r = x*2^ex */ /* remove trailing zeroes */ l = mpz_scan1 (x, 0); ex += l; mpz_fdiv_q_2exp (x, x, l); /* since |r| < 1, r = x*2^ex, and x is an integer, necessarily ex < 0 */ p = mpfr_get_prec (f); /* same than r */ /* bound for number of iterations */ imax = p / (-mpfr_get_exp (r)); imax += (imax == 0); q = 2 * MPFR_INT_CEIL_LOG2(imax) + 4; /* bound for (3l)^2 */ mpz_set_ui (s, 1); /* initialize sum with 1 */ mpz_mul_2exp (s, s, p + q); /* scale all values by 2^(p+q) */ mpz_set (t, s); /* invariant: t is previous term */ for (i = 1; (m = mpz_sizeinbase (t, 2)) >= q; i += 2) { /* adjust precision of x to that of t */ l = mpz_sizeinbase (x, 2); if (l > m) { l -= m; mpz_fdiv_q_2exp (x, x, l); ex += l; } /* multiply t by r */ mpz_mul (t, t, x); mpz_fdiv_q_2exp (t, t, -ex); /* divide t by i*(i+1) */ if (i < maxi) mpz_fdiv_q_ui (t, t, i * (i + 1)); else { mpz_fdiv_q_ui (t, t, i); mpz_fdiv_q_ui (t, t, i + 1); } /* if m is the (current) number of bits of t, we can consider that all operations on t so far had precision >= m, so we can prove by induction that the relative error on t is of the form (1+u)^(3l)-1, where |u| <= 2^(-m), and l=(i+1)/2 is the # of loops. Since |(1+x^2)^(1/x) - 1| <= 4x/3 for |x| <= 1/2, for |u| <= 1/(3l)^2, the absolute error is bounded by 4/3*(3l)*2^(-m)*t <= 4*l since |t| < 2^m. Therefore the error on s is bounded by 2*l*(l+1). */ /* add or subtract to s */ if (i % 4 == 1) mpz_sub (s, s, t); else mpz_add (s, s, t); } mpfr_set_z (f, s, MPFR_RNDN); mpfr_div_2ui (f, f, p + q, MPFR_RNDN); mpz_clear (x); mpz_clear (s); mpz_clear (t); l = (i - 1) / 2; /* number of iterations */ return 2 * MPFR_INT_CEIL_LOG2 (l + 1) + 1; /* bound is 2l(l+1) */ }
void gfc_advance_section (mpz_t *section_index, gfc_array_ref *ar, mpz_t *offset_ret) { int i; mpz_t delta; mpz_t tmp; bool forwards; int cmp; for (i = 0; i < ar->dimen; i++) { if (ar->dimen_type[i] != DIMEN_RANGE) continue; if (ar->stride[i]) { mpz_add (section_index[i], section_index[i], ar->stride[i]->value.integer); if (mpz_cmp_si (ar->stride[i]->value.integer, 0) >= 0) forwards = true; else forwards = false; } else { mpz_add_ui (section_index[i], section_index[i], 1); forwards = true; } if (ar->end[i]) cmp = mpz_cmp (section_index[i], ar->end[i]->value.integer); else cmp = mpz_cmp (section_index[i], ar->as->upper[i]->value.integer); if ((cmp > 0 && forwards) || (cmp < 0 && !forwards)) { /* Reset index to start, then loop to advance the next index. */ if (ar->start[i]) mpz_set (section_index[i], ar->start[i]->value.integer); else mpz_set (section_index[i], ar->as->lower[i]->value.integer); } else break; } mpz_set_si (*offset_ret, 0); mpz_init_set_si (delta, 1); mpz_init (tmp); for (i = 0; i < ar->dimen; i++) { mpz_sub (tmp, section_index[i], ar->as->lower[i]->value.integer); mpz_mul (tmp, tmp, delta); mpz_add (*offset_ret, tmp, *offset_ret); mpz_sub (tmp, ar->as->upper[i]->value.integer, ar->as->lower[i]->value.integer); mpz_add_ui (tmp, tmp, 1); mpz_mul (delta, tmp, delta); } mpz_clear (tmp); mpz_clear (delta); }
int main (int argc, char **argv) { mpz_t x2; mpz_t x, rem; mpz_t temp, temp2; mp_size_t x2_size; int i; int reps = 20000; gmp_randstate_ptr rands; mpz_t bs; unsigned long size_range; tests_start (); rands = RANDS; mpz_init (bs); if (argc == 2) reps = atoi (argv[1]); mpz_init (x2); mpz_init (x); mpz_init (rem); mpz_init (temp); mpz_init (temp2); for (i = 0; i < reps; i++) { mpz_urandomb (bs, rands, 32); size_range = mpz_get_ui (bs) % 12 + 2; /* 0..8191 bit operands */ mpz_urandomb (bs, rands, size_range); x2_size = mpz_get_ui (bs); mpz_rrandomb (x2, rands, x2_size); /* printf ("%ld\n", SIZ (x2)); */ mpz_sqrtrem (x, rem, x2); mpz_mul (temp, x, x); /* Is square of result > argument? */ if (mpz_cmp (temp, x2) > 0) dump_abort (x2, x, rem); mpz_add_ui (temp2, x, 1); mpz_mul (temp2, temp2, temp2); /* Is square of (result + 1) <= argument? */ if (mpz_cmp (temp2, x2) <= 0) dump_abort (x2, x, rem); mpz_add (temp2, temp, rem); /* Is the remainder wrong? */ if (mpz_cmp (x2, temp2) != 0) dump_abort (x2, x, rem); } mpz_clear (bs); mpz_clear (x2); mpz_clear (x); mpz_clear (rem); mpz_clear (temp); mpz_clear (temp2); tests_end (); exit (0); }
/* compute in s an approximation of S3 = c*sum((h(k)+h(n+k))*y^k/k!/(n+k)!,k=0..infinity) where h(k) = 1 + 1/2 + ... + 1/k k=0: h(n) k=1: 1+h(n+1) k=2: 3/2+h(n+2) Returns e such that the error is bounded by 2^e ulp(s). */ static mpfr_exp_t mpfr_yn_s3 (mpfr_ptr s, mpfr_srcptr y, mpfr_srcptr c, unsigned long n) { unsigned long k, zz; mpfr_t t, u; mpz_t p, q; /* p/q will store h(k)+h(n+k) */ mpfr_exp_t exps, expU; zz = mpfr_get_ui (y, MPFR_RNDU); /* y = z^2/4 */ MPFR_ASSERTN (zz < ULONG_MAX - 2); zz += 2; /* z^2 <= 2^zz */ mpz_init_set_ui (p, 0); mpz_init_set_ui (q, 1); /* initialize p/q to h(n) */ for (k = 1; k <= n; k++) { /* p/q + 1/k = (k*p+q)/(q*k) */ mpz_mul_ui (p, p, k); mpz_add (p, p, q); mpz_mul_ui (q, q, k); } mpfr_init2 (t, MPFR_PREC(s)); mpfr_init2 (u, MPFR_PREC(s)); mpfr_fac_ui (t, n, MPFR_RNDN); mpfr_div (t, c, t, MPFR_RNDN); /* c/n! */ mpfr_mul_z (u, t, p, MPFR_RNDN); mpfr_div_z (s, u, q, MPFR_RNDN); exps = MPFR_EXP (s); expU = exps; for (k = 1; ;k ++) { /* update t */ mpfr_mul (t, t, y, MPFR_RNDN); mpfr_div_ui (t, t, k, MPFR_RNDN); mpfr_div_ui (t, t, n + k, MPFR_RNDN); /* update p/q: p/q + 1/k + 1/(n+k) = [p*k*(n+k) + q*(n+k) + q*k]/(q*k*(n+k)) */ mpz_mul_ui (p, p, k); mpz_mul_ui (p, p, n + k); mpz_addmul_ui (p, q, n + 2 * k); mpz_mul_ui (q, q, k); mpz_mul_ui (q, q, n + k); mpfr_mul_z (u, t, p, MPFR_RNDN); mpfr_div_z (u, u, q, MPFR_RNDN); exps = MPFR_EXP (u); if (exps > expU) expU = exps; mpfr_add (s, s, u, MPFR_RNDN); exps = MPFR_EXP (s); if (exps > expU) expU = exps; if (MPFR_EXP (u) + (mpfr_exp_t) MPFR_PREC (u) < MPFR_EXP (s) && zz / (2 * k) < k + n) break; } mpfr_clear (t); mpfr_clear (u); mpz_clear (p); mpz_clear (q); exps = expU - MPFR_EXP (s); /* the error is bounded by (6k^2+33/2k+11) 2^exps ulps <= 8*(k+2)^2 2^exps ulps */ return 3 + 2 * MPFR_INT_CEIL_LOG2(k + 2) + exps; }
void generate_mod (int limb_bits, int nail_bits) { int numb_bits = limb_bits - nail_bits; int i, divisor; mpz_init_set_ui (pp, 0L); mpz_init_set_ui (pp_norm, 0L); mpz_init_set_ui (pp_inverted, 0L); /* no more than limb_bits many factors in a one limb modulus (and of course in reality nothing like that many) */ factor_alloc = limb_bits; factor = (struct factor_t *) malloc (factor_alloc * sizeof (*factor)); rawfactor = (struct rawfactor_t *) malloc (factor_alloc * sizeof (*rawfactor)); if (numb_bits % 4 != 0) { strcpy (mod34_excuse, "GMP_NUMB_BITS % 4 != 0"); goto use_pp; } max_divisor = 2*limb_bits; max_divisor_bits = log2_ceil (max_divisor); if (numb_bits / 4 < max_divisor_bits) { /* Wind back to one limb worth of max_divisor, if that will let us use mpn_mod_34lsub1. */ max_divisor = limb_bits; max_divisor_bits = log2_ceil (max_divisor); if (numb_bits / 4 < max_divisor_bits) { strcpy (mod34_excuse, "GMP_NUMB_BITS / 4 too small"); goto use_pp; } } { /* Can use mpn_mod_34lsub1, find small factors of 2^mod34_bits-1. */ mpz_t m, q, r; int multiplicity; mod34_bits = (numb_bits / 4) * 3; /* mpn_mod_34lsub1 returns a full limb value, PERFSQR_MOD_34 folds it at the mod34_bits mark, adding the two halves for a remainder of at most mod34_bits+1 many bits */ mod_bits = mod34_bits + 1; mpz_init_set_ui (m, 1L); mpz_mul_2exp (m, m, mod34_bits); mpz_sub_ui (m, m, 1L); mpz_init (q); mpz_init (r); for (i = 3; i <= max_divisor; i++) { if (! isprime (i)) continue; mpz_tdiv_qr_ui (q, r, m, (unsigned long) i); if (mpz_sgn (r) != 0) continue; /* if a repeated prime is found it's used as an i^n in one factor */ divisor = 1; multiplicity = 0; do { if (divisor > max_divisor / i) break; multiplicity++; mpz_set (m, q); mpz_tdiv_qr_ui (q, r, m, (unsigned long) i); } while (mpz_sgn (r) == 0); //ASSERT (nrawfactor < factor_alloc); rawfactor[nrawfactor].divisor = i; rawfactor[nrawfactor].multiplicity = multiplicity; nrawfactor++; } mpz_clear (m); mpz_clear (q); mpz_clear (r); } if (nrawfactor <= 2) { mpz_t new_pp; sprintf (mod34_excuse, "only %d small factor%s", nrawfactor, nrawfactor == 1 ? "" : "s"); use_pp: /* reset to two limbs of max_divisor, in case the mpn_mod_34lsub1 code tried with just one */ max_divisor = 2*limb_bits; max_divisor_bits = log2_ceil (max_divisor); mpz_init (new_pp); nrawfactor = 0; mod_bits = MIN (numb_bits, limb_bits - max_divisor_bits); /* one copy of each small prime */ mpz_set_ui (pp, 1L); for (i = 3; i <= max_divisor; i++) { if (! isprime (i)) continue; mpz_mul_ui (new_pp, pp, (unsigned long) i); if (mpz_sizeinbase (new_pp, 2) > mod_bits) break; mpz_set (pp, new_pp); //ASSERT (nrawfactor < factor_alloc); rawfactor[nrawfactor].divisor = i; rawfactor[nrawfactor].multiplicity = 1; nrawfactor++; } /* Plus an extra copy of one or more of the primes selected, if that still fits in max_divisor and the total in mod_bits. Usually only 3 or 5 will be candidates */ for (i = nrawfactor-1; i >= 0; i--) { if (rawfactor[i].divisor > max_divisor / rawfactor[i].divisor) continue; mpz_mul_ui (new_pp, pp, (unsigned long) rawfactor[i].divisor); if (mpz_sizeinbase (new_pp, 2) > mod_bits) continue; mpz_set (pp, new_pp); rawfactor[i].multiplicity++; } mod_bits = mpz_sizeinbase (pp, 2); mpz_set (pp_norm, pp); while (mpz_sizeinbase (pp_norm, 2) < numb_bits) mpz_add (pp_norm, pp_norm, pp_norm); mpz_preinv_invert (pp_inverted, pp_norm, numb_bits); mpz_clear (new_pp); } /* start the factor array */ for (i = 0; i < nrawfactor; i++) { int j; //ASSERT (nfactor < factor_alloc); factor[nfactor].divisor = 1; for (j = 0; j < rawfactor[i].multiplicity; j++) factor[nfactor].divisor *= rawfactor[i].divisor; nfactor++; } combine: /* Combine entries in the factor array. Combine the smallest entry with the biggest one that will fit with it (ie. under max_divisor), then repeat that with the new smallest entry. */ qsort (factor, nfactor, sizeof (factor[0]), f_cmp_divisor); for (i = nfactor-1; i >= 1; i--) { if (factor[i].divisor <= max_divisor / factor[0].divisor) { factor[0].divisor *= factor[i].divisor; COLLAPSE_ELEMENT (factor, i, nfactor); goto combine; } } total_fraction = 1.0; for (i = 0; i < nfactor; i++) { mpz_init (factor[i].inverse); mpz_invert_ui_2exp (factor[i].inverse, (unsigned long) factor[i].divisor, (unsigned long) mod_bits); mpz_init (factor[i].mask); square_mask (factor[i].mask, factor[i].divisor); /* fraction of possible squares */ factor[i].fraction = (double) mpz_popcount (factor[i].mask) / factor[i].divisor; /* total fraction of possible squares */ total_fraction *= factor[i].fraction; } /* best tests first (ie. smallest fraction) */ qsort (factor, nfactor, sizeof (factor[0]), f_cmp_fraction); }
//rop <- (rop² + a) mod n void f(mpz_t rop) { mpz_pow_ui(xSquared, rop, 2); mpz_add(xSquared, xSquared, a); mpz_mod(rop, xSquared, n); }
int main (int argc, char *argv[]) { const char usage[] = "usage: findlc [-dv] m2exp [low_merit [high_merit]]\n"; int f; int v_lose, m_lose, v_best, m_best; int c; int debug = 1; int cnt_high_merit; mpz_t m; unsigned long int m2exp; #define DIMS 6 /* dimensions run in spectral test */ mpf_t v[DIMS-1]; /* spectral test result (there's no v for 1st dimension */ mpf_t f_merit, low_merit, high_merit; mpz_t acc, minus8; mpz_t min, max; mpz_t s; mpz_init (m); mpz_init (a); for (f = 0; f < DIMS-1; f++) mpf_init (v[f]); mpf_init (f_merit); mpf_init_set_d (low_merit, .1); mpf_init_set_d (high_merit, .1); while ((c = getopt (argc, argv, "a:di:hv")) != -1) switch (c) { case 'd': /* debug */ g_debug++; break; case 'v': /* print version */ puts (rcsid[1]); exit (0); case 'h': case '?': default: fputs (usage, stderr); exit (1); } argc -= optind; argv += optind; if (argc < 1) { fputs (usage, stderr); exit (1); } /* Install signal handler. */ if (SIG_ERR == signal (SIGSEGV, sh_status)) { perror ("signal (SIGSEGV)"); exit (1); } if (SIG_ERR == signal (SIGHUP, sh_status)) { perror ("signal (SIGHUP)"); exit (1); } printf ("findlc: version: %s\n", rcsid[1]); m2exp = atol (argv[0]); mpz_init_set_ui (m, 1); mpz_mul_2exp (m, m, m2exp); printf ("m = 0x"); mpz_out_str (stdout, 16, m); puts (""); if (argc > 1) /* have low_merit */ mpf_set_str (low_merit, argv[1], 0); if (argc > 2) /* have high_merit */ mpf_set_str (high_merit, argv[2], 0); if (debug) { fprintf (stderr, "low_merit = "); mpf_out_str (stderr, 10, 2, low_merit); fprintf (stderr, "; high_merit = "); mpf_out_str (stderr, 10, 2, high_merit); fputs ("\n", stderr); } mpz_init (minus8); mpz_set_si (minus8, -8L); mpz_init_set_ui (acc, 0); mpz_init (s); mpz_init_set_d (min, 0.01 * pow (2.0, (double) m2exp)); mpz_init_set_d (max, 0.99 * pow (2.0, (double) m2exp)); mpz_true_random (s, m2exp); /* Start. */ mpz_setbit (s, 0); /* Make it odd. */ v_best = m_best = 2*(DIMS-1); for (;;) { mpz_add (acc, acc, s); mpz_mod_2exp (acc, acc, m2exp); #if later mpz_and_si (a, acc, -8L); #else mpz_and (a, acc, minus8); #endif mpz_add_ui (a, a, 5); if (mpz_cmp (a, min) <= 0 || mpz_cmp (a, max) >= 0) continue; spectral_test (v, DIMS, a, m); for (f = 0, v_lose = m_lose = 0, cnt_high_merit = DIMS-1; f < DIMS-1; f++) { merit (f_merit, f + 2, v[f], m); if (mpf_cmp_ui (v[f], 1 << (30 / (f + 2) + (f == 2))) < 0) v_lose++; if (mpf_cmp (f_merit, low_merit) < 0) m_lose++; if (mpf_cmp (f_merit, high_merit) >= 0) cnt_high_merit--; } if (0 == v_lose && 0 == m_lose) { mpz_out_str (stdout, 10, a); puts (""); fflush (stdout); if (0 == cnt_high_merit) break; /* leave loop */ } if (v_lose < v_best) { v_best = v_lose; printf ("best (v_lose=%d; m_lose=%d): ", v_lose, m_lose); mpz_out_str (stdout, 10, a); puts (""); fflush (stdout); } if (m_lose < m_best) { m_best = m_lose; printf ("best (v_lose=%d; m_lose=%d): ", v_lose, m_lose); mpz_out_str (stdout, 10, a); puts (""); fflush (stdout); } } mpz_clear (m); mpz_clear (a); for (f = 0; f < DIMS-1; f++) mpf_clear (v[f]); mpf_clear (f_merit); mpf_clear (low_merit); mpf_clear (high_merit); printf ("done.\n"); return 0; }
BigInt BigInt::operator + (const BigInt &b) const { BigInt ret; mpz_add(ret.mImpl,mImpl,b.mImpl); return ret; }