void SecretShare::modSqrt(mpz_t* result, mpz_t* x, int size){ mpz_t* power = (mpz_t*)malloc(sizeof(mpz_t) * size); for(int i = 0; i < size; i++){ mpz_init(power[i]); mpz_add_ui(power[i], fieldSize, 1); mpz_div_ui(power[i], power[i], 4); } modPow(result, x, power, size); for(int i = 0; i < size; i++) mpz_clear(power[i]); }
int gmpmee_millerrabin_safe_init(gmpmee_millerrabin_safe_state state, mpz_t n) { mpz_t m; gmpmee_millerrabin_init(state->nstate, n); mpz_init(m); /* Note that if n i even, then m we do not have n=2m+1, but this does not matter, since n will anyway be deemed a non-prime in this case. */ mpz_sub_ui(m, n, 1); mpz_div_ui(m, m, 2); gmpmee_millerrabin_init(state->mstate, m); mpz_clear(m); }
/* * \brief Encrypts/decrypts a message using the RSA algorithm. * * \param result a field to populate with the result of your RSA calculation. * \param message the message to perform RSA on. (probably a cert in this case) * \param e the encryption key from the key_file passed in through the * command-line arguments * \param n the modulus for RSA from the modulus_file passed in through * the command-line arguments * * Fill in this function with your proj0 solution or see staff solutions. */ static void perform_rsa(mpz_t result, mpz_t message, mpz_t e, mpz_t n) { int odd_num; mpz_set_str(result, "1", 10); odd_num = mpz_odd_p(e); while (mpz_cmp_ui(e, 0) > 0) { if (odd_num) { mpz_mul(result, result, message); mpz_mod(result, result, n); mpz_sub_ui(e, e, 1); } mpz_mul(message, message, message); mpz_mod(message, message, n); mpz_div_ui(e, e, 2); odd_num = mpz_odd_p(e); } }
/* s <- 1 + r/1! + r^2/2! + ... + r^l/l! while MPFR_EXP(r^l/l!)+MPFR_EXPR(r)>-q using naive method with O(l) multiplications. Return the number of iterations l. The absolute error on s is less than 3*l*(l+1)*2^(-q). Version using fixed-point arithmetic with mpz instead of mpfr for internal computations. s must have at least qn+1 limbs (qn should be enough, but currently fails since mpz_mul_2exp(s, s, q-1) reallocates qn+1 limbs) */ static unsigned long mpfr_exp2_aux (mpz_t s, mpfr_srcptr r, mp_prec_t q, mp_exp_t *exps) { unsigned long l; mp_exp_t dif; mp_size_t qn; mpz_t t, rr; mp_exp_t expt, expr; TMP_DECL(marker); TMP_MARK(marker); qn = 1 + (q-1)/BITS_PER_MP_LIMB; expt = 0; *exps = 1 - (mp_exp_t) q; /* s = 2^(q-1) */ MY_INIT_MPZ(t, 2*qn+1); MY_INIT_MPZ(rr, qn+1); mpz_set_ui(t, 1); mpz_set_ui(s, 1); mpz_mul_2exp(s, s, q-1); expr = mpfr_get_z_exp(rr, r); /* no error here */ l = 0; do { l++; mpz_mul(t, t, rr); expt += expr; dif = *exps + mpz_sizeinbase(s, 2) - expt - mpz_sizeinbase(t, 2); /* truncates the bits of t which are < ulp(s) = 2^(1-q) */ expt += mpz_normalize(t, t, (mp_exp_t) q-dif); /* error at most 2^(1-q) */ mpz_div_ui(t, t, l); /* error at most 2^(1-q) */ /* the error wrt t^l/l! is here at most 3*l*ulp(s) */ MPFR_ASSERTD (expt == *exps); mpz_add(s, s, t); /* no error here: exact */ /* ensures rr has the same size as t: after several shifts, the error on rr is still at most ulp(t)=ulp(s) */ expr += mpz_normalize(rr, rr, mpz_sizeinbase(t, 2)); } while (mpz_cmp_ui(t, 0)); TMP_FREE(marker); return l; }
/* * \brief Encrypts/decrypts a message using the RSA algorithm. * * \param result a field to populate with the result of your RSA calculation. * \param message the message to perform RSA on. (probably a cert in this case) * \param e the encryption key from the key_file passed in through the * command-line arguments * \param n the modulus for RSA from the modulus_file passed in through * the command-line arguments * * Fill in this function with your proj0 solution or see staff solutions. */ static void perform_rsa(mpz_t result, mpz_t message, mpz_t e, mpz_t n) { mpz_t odd; mpz_init(odd); mpz_add_ui(result, result, 1); while (mpz_cmp_ui(e, 0)){ mpz_mod_ui(odd, e, 2); if (mpz_cmp_ui(odd, 0)) { mpz_mul(result, result, message); mpz_mod(result, result, n); mpz_sub_ui(e, e, 1); } else { mpz_mul(message, message, message); mpz_mod(message, message, n); mpz_div_ui(e, e, 2); } } mpz_clear(odd); }
/* s <- 1 + r/1! + r^2/2! + ... + r^l/l! while MPFR_EXP(r^l/l!)+MPFR_EXPR(r)>-q using naive method with O(l) multiplications. Return the number of iterations l. The absolute error on s is less than 3*l*(l+1)*2^(-q). Version using fixed-point arithmetic with mpz instead of mpfr for internal computations. s must have at least qn+1 limbs (qn should be enough, but currently fails since mpz_mul_2exp(s, s, q-1) reallocates qn+1 limbs) */ static int mpfr_exp2_aux (mpz_t s, mpfr_srcptr r, int q, int *exps) { int l, dif, qn; mpz_t t, rr; mp_exp_t expt, expr; TMP_DECL(marker); TMP_MARK(marker); qn = 1 + (q-1)/BITS_PER_MP_LIMB; MY_INIT_MPZ(t, 2*qn+1); /* 2*qn+1 is neeeded since mpz_div_2exp may need an extra limb */ MY_INIT_MPZ(rr, qn+1); mpz_set_ui(t, 1); expt=0; mpz_set_ui(s, 1); mpz_mul_2exp(s, s, q-1); *exps = 1-q; /* s = 2^(q-1) */ expr = mpfr_get_z_exp(rr, r); /* no error here */ l = 0; do { l++; mpz_mul(t, t, rr); expt=expt+expr; dif = *exps + mpz_sizeinbase(s, 2) - expt - mpz_sizeinbase(t, 2); /* truncates the bits of t which are < ulp(s) = 2^(1-q) */ expt += mpz_normalize(t, t, q-dif); /* error at most 2^(1-q) */ mpz_div_ui(t, t, l); /* error at most 2^(1-q) */ /* the error wrt t^l/l! is here at most 3*l*ulp(s) */ #ifdef DEBUG if (expt != *exps) { fprintf(stderr, "Error: expt != exps %d %d\n", expt, *exps); exit(1); } #endif mpz_add(s, s, t); /* no error here: exact */ /* ensures rr has the same size as t: after several shifts, the error on rr is still at most ulp(t)=ulp(s) */ expr += mpz_normalize(rr, rr, mpz_sizeinbase(t, 2)); } while (mpz_cmp_ui(t, 0)); TMP_FREE(marker); return l; }
int main (int argc, char **argv) { mpz_t base, exp, mod; mpz_t r1, r2, t1, exp2, base2; mp_size_t base_size, exp_size, mod_size; int i; int reps = 100; 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 (base); mpz_init (exp); mpz_init (mod); mpz_init (r1); mpz_init (r2); mpz_init (t1); mpz_init (exp2); mpz_init (base2); for (i = 0; i < reps; i++) { mpz_urandomb (bs, rands, 32); size_range = mpz_get_ui (bs) % 13 + 2; do /* Loop until mathematically well-defined. */ { mpz_urandomb (bs, rands, size_range); base_size = mpz_get_ui (bs); mpz_rrandomb (base, rands, base_size); mpz_urandomb (bs, rands, 7L); exp_size = mpz_get_ui (bs); mpz_rrandomb (exp, rands, exp_size); } while (mpz_cmp_ui (base, 0) == 0 && mpz_cmp_ui (exp, 0) == 0); do { mpz_urandomb (bs, rands, size_range); mod_size = mpz_get_ui (bs); mpz_rrandomb (mod, rands, mod_size); } while (mpz_cmp_ui (mod, 0) == 0); mpz_urandomb (bs, rands, 2); bsi = mpz_get_ui (bs); if ((bsi & 1) != 0) mpz_neg (base, base); /* printf ("%ld %ld %ld\n", SIZ (base), SIZ (exp), SIZ (mod)); */ mpz_powm (r1, base, exp, mod); mpz_set_ui (r2, 1); mpz_set (base2, base); mpz_set (exp2, exp); mpz_mod (r2, r2, mod); /* needed when exp==0 and mod==1 */ while (mpz_cmp_ui (exp2, 0) != 0) { mpz_mod_ui (t1, exp2, 2); if (mpz_cmp_ui (t1, 0) != 0) { mpz_mul (r2, r2, base2); mpz_mod (r2, r2, mod); } mpz_mul (base2, base2, base2); mpz_mod (base2, base2, mod); mpz_div_ui (exp2, exp2, 2); } if (mpz_cmp (r1, r2) != 0) { fprintf (stderr, "\nIncorrect results for operands:\n"); debug_mp (base, -16); debug_mp (exp, -16); debug_mp (mod, -16); fprintf (stderr, "mpz_powm result:\n"); debug_mp (r1, -16); fprintf (stderr, "reference result:\n"); debug_mp (r2, -16); abort (); } } mpz_clear (bs); mpz_clear (base); mpz_clear (exp); mpz_clear (mod); mpz_clear (r1); mpz_clear (r2); mpz_clear (t1); mpz_clear (exp2); mpz_clear (base2); tests_end (); exit (0); }
/* s <- 1 + r/1! + r^2/2! + ... + r^l/l! while MPFR_EXP(r^l/l!)+MPFR_EXPR(r)>-q using Brent/Kung method with O(sqrt(l)) multiplications. Return l. Uses m multiplications of full size and 2l/m of decreasing size, i.e. a total equivalent to about m+l/m full multiplications, i.e. 2*sqrt(l) for m=sqrt(l). Version using mpz. ss must have at least (sizer+1) limbs. The error is bounded by (l^2+4*l) ulps where l is the return value. */ static unsigned long mpfr_exp2_aux2 (mpz_t s, mpfr_srcptr r, mp_prec_t q, mp_exp_t *exps) { mp_exp_t expr, *expR, expt; mp_size_t sizer; mp_prec_t ql; unsigned long l, m, i; mpz_t t, *R, rr, tmp; TMP_DECL(marker); /* estimate value of l */ MPFR_ASSERTD (MPFR_GET_EXP (r) < 0); l = q / (- MPFR_GET_EXP (r)); m = __gmpfr_isqrt (l); /* we access R[2], thus we need m >= 2 */ if (m < 2) m = 2; TMP_MARK(marker); R = (mpz_t*) TMP_ALLOC((m+1)*sizeof(mpz_t)); /* R[i] is r^i */ expR = (mp_exp_t*) TMP_ALLOC((m+1)*sizeof(mp_exp_t)); /* exponent for R[i] */ sizer = 1 + (MPFR_PREC(r)-1)/BITS_PER_MP_LIMB; mpz_init(tmp); MY_INIT_MPZ(rr, sizer+2); MY_INIT_MPZ(t, 2*sizer); /* double size for products */ mpz_set_ui(s, 0); *exps = 1-q; /* 1 ulp = 2^(1-q) */ for (i = 0 ; i <= m ; i++) MY_INIT_MPZ(R[i], sizer+2); expR[1] = mpfr_get_z_exp(R[1], r); /* exact operation: no error */ expR[1] = mpz_normalize2(R[1], R[1], expR[1], 1-q); /* error <= 1 ulp */ mpz_mul(t, R[1], R[1]); /* err(t) <= 2 ulps */ mpz_div_2exp(R[2], t, q-1); /* err(R[2]) <= 3 ulps */ expR[2] = 1-q; for (i = 3 ; i <= m ; i++) { mpz_mul(t, R[i-1], R[1]); /* err(t) <= 2*i-2 */ mpz_div_2exp(R[i], t, q-1); /* err(R[i]) <= 2*i-1 ulps */ expR[i] = 1-q; } mpz_set_ui (R[0], 1); mpz_mul_2exp (R[0], R[0], q-1); expR[0] = 1-q; /* R[0]=1 */ mpz_set_ui (rr, 1); expr = 0; /* rr contains r^l/l! */ /* by induction: err(rr) <= 2*l ulps */ l = 0; ql = q; /* precision used for current giant step */ do { /* all R[i] must have exponent 1-ql */ if (l != 0) for (i = 0 ; i < m ; i++) expR[i] = mpz_normalize2 (R[i], R[i], expR[i], 1-ql); /* the absolute error on R[i]*rr is still 2*i-1 ulps */ expt = mpz_normalize2 (t, R[m-1], expR[m-1], 1-ql); /* err(t) <= 2*m-1 ulps */ /* computes t = 1 + r/(l+1) + ... + r^(m-1)*l!/(l+m-1)! using Horner's scheme */ for (i = m-1 ; i-- != 0 ; ) { mpz_div_ui(t, t, l+i+1); /* err(t) += 1 ulp */ mpz_add(t, t, R[i]); } /* now err(t) <= (3m-2) ulps */ /* now multiplies t by r^l/l! and adds to s */ mpz_mul(t, t, rr); expt += expr; expt = mpz_normalize2(t, t, expt, *exps); /* err(t) <= (3m-1) + err_rr(l) <= (3m-2) + 2*l */ MPFR_ASSERTD (expt == *exps); mpz_add(s, s, t); /* no error here */ /* updates rr, the multiplication of the factors l+i could be done using binary splitting too, but it is not sure it would save much */ mpz_mul(t, rr, R[m]); /* err(t) <= err(rr) + 2m-1 */ expr += expR[m]; mpz_set_ui (tmp, 1); for (i = 1 ; i <= m ; i++) mpz_mul_ui (tmp, tmp, l + i); mpz_fdiv_q(t, t, tmp); /* err(t) <= err(rr) + 2m */ expr += mpz_normalize(rr, t, ql); /* err_rr(l+1) <= err_rr(l) + 2m+1 */ ql = q - *exps - mpz_sizeinbase(s, 2) + expr + mpz_sizeinbase(rr, 2); l += m; } while ((size_t) expr+mpz_sizeinbase(rr, 2) > (size_t)((int)-q)); TMP_FREE(marker); mpz_clear(tmp); return l; }
int ecpp_test(unsigned long n) { mpz_t a, b, x0, y0, xt, yt, tmp; int z; int is_prime = 0; if (n <= USHRT_MAX) { return sieve_test(n); } mpz_init(a); mpz_init(b); mpz_init(x0); mpz_init(y0); mpz_init(xt); mpz_init(yt); mpz_init(tmp); #ifdef DEBUG gmp_fprintf(stderr, "\nTesting %d with ECPP...\n", n); #endif /* DEBUG */ for (;;) /* keep trying while the curve order factoring fails */ { for (;;) /* keep trying while n divides curve discriminant */ { /* initialise a random point P = (x0, y0) * and a random elliptic curve E(a, b): y^2 = x^3 + a*x + b * with b expressed in terms of (a, x0, y0) so the point lies on the curve */ mpz_set_ui(a, rand() % n); mpz_set_ui(x0, rand() % n); mpz_set_ui(y0, rand() % n); mpz_init(b); mpz_mul(b, y0, y0); mpz_mul(tmp, x0, x0); mpz_submul(b, tmp, x0); mpz_submul(b, a, x0); mpz_mod_ui(b, b, n); #ifdef DEBUG gmp_fprintf(stderr, "\n\tn = %d\n", n); gmp_fprintf(stderr, "\tE: y^2 = x^3 + %Zd * x + %Zd\n", a, b); gmp_fprintf(stderr, "\tP = (%Zd,%Zd,1)\n", x0, y0); #endif /* DEBUG */ /* the discriminant of the curve and n are required to be coprimes * -- if not, then either * A) n divides the discriminant -- a new curve must be generated * B) n is composite and a proper factor is found -- the algorithm can * terminate */ ec_discriminant(tmp, a, b); #ifdef DEBUG mpz_mod_ui(tmp, tmp, n); gmp_fprintf(stderr, "\tdelta(E/GF(n)) = %Zd\n", tmp); #endif /* DEBUG */ mpz_gcd_ui(tmp, tmp, n); #ifdef DEBUG gmp_fprintf(stderr, "\tgcd(delta, n) = %Zd\n", tmp); #endif /* DEBUG */ if (0 == mpz_cmp_ui(tmp, 1)) { break; } else if (0 != mpz_cmp_ui(tmp, n)) { #ifdef DEBUG gmp_fprintf(stderr, "\tfound a proper factor, %d is composite\n", n); #endif /* DEBUG */ is_prime = 0; goto cleanup_and_return; } } /* P + P != 0, or a new curve is generated */ z = ec_add(xt, yt, x0, y0, 1, x0, y0, 1, n, a); #ifdef DEBUG gmp_fprintf(stderr, "\t2 * P = (%Zd,%Zd,%d)\n", xt, yt, z); #endif /* DEBUG */ if (0 == z) { continue; } /* the curve order algorithm failing indicates n is composite */ if (!(ec_order(tmp, a, b, n))) { #ifdef DEBUG gmp_fprintf(stderr, "\tcurve order algorithm failed, %d must be composite\n", n); #endif /* DEBUG */ is_prime = 0; break; } #ifdef DEBUG gmp_fprintf(stderr, "\t|E/GF(n)| = %Zd\n", tmp); #endif /* DEBUG */ /* the curve order should be the multiple of 2 and a "probable prime" n -- * if the order is not even, a new curve is generated */ if (!mpz_even_p(tmp)) { #ifdef DEBUG gmp_fprintf(stderr, "\t|E/GF(n)| is odd, generating new curve...\n"); #endif /* DEBUG */ continue; } /* order * P = 0, or n is composite */ z = ec_times(xt, yt, x0, y0, 1, tmp, n, a); #ifdef DEBUG gmp_fprintf(stderr, "\t|E| * P = (%Zd,%Zd,%d)\n", xt, yt, z); #endif /* DEBUG */ if (0 != z) { #ifdef DEBUG gmp_fprintf(stderr, "\t|E| * P is non-zero, %d is composite\n", n); #endif /* DEBUG */ is_prime = 0; break; } /* at this point, order/2 being a prime implies n is a prime -- * a recursive call to ecpp_test is used to test order/2 for primality */ mpz_div_ui(tmp, tmp, 2); if (ecpp_test(mpz_get_ui(tmp))) { is_prime = 1; break; } } cleanup_and_return: mpz_clear(a); mpz_clear(b); mpz_clear(x0); mpz_clear(y0); mpz_clear(xt); mpz_clear(yt); mpz_clear(tmp); return is_prime; }
void benchmark_optimize_exp() { int REPS; int prec; int i, k, r, J, best_r, best_J; double best_time, best_here; double t1, t2, elapsed; double mpfr_time; int accuracy, min_accuracy; mpz_t x, y, dummy; mpfr_t mx, my; mpfr_init(mx); mpfr_init(my); mpz_init(x); mpz_init(y); mpz_init(dummy); printf(" prec acc J r mpfr this faster\n"); for (prec=53; prec<30000; prec+=prec/4) { if (prec < 300) REPS = 100; else if (prec < 600) REPS = 50; else if (prec < 1200) REPS = 10; else REPS = 2; mpz_set_ui(x, 37); mpz_mul_2exp(x, x, prec); mpz_div_ui(x, x, 100); min_accuracy = prec; best_time = 1e100; best_r = 0; best_J = 0; mpfr_set_prec(mx, prec); mpfr_set_prec(my, prec); mpfr_set_str(mx, "0.37", 10, GMP_RNDN); mpfr_time = 1e100; for (i=0; i<10; i++) { t1 = timing(); for (k=0; k<REPS; k++) { mpfr_exp(my, mx, GMP_RNDN); } t2 = timing(); elapsed = (t2-t1)/REPS; if (elapsed < mpfr_time) mpfr_time = elapsed; } for (J=1; J<MAX_SERIES_STEPS; J++) { for (r=0; r*r<prec+30; r++) { for (i=0; i<3; i++) { t1 = timing(); for (k=0; k<REPS; k++) { exp_series(y, dummy, x, prec, r, J, 2); } t2 = timing(); elapsed = (t2-t1) / REPS; if (elapsed < best_time) { best_time = elapsed; best_r = r; best_J = J; } } mpfr_set_z(mx, y, GMP_RNDN); mpfr_div_2ui(mx, mx, prec, GMP_RNDN); //mpfr_printf("Value: %Rf\n", mx); mpfr_sub(mx, mx, my, GMP_RNDN); mpfr_abs(mx, mx, GMP_RNDN); if (!mpfr_zero_p(mx)) { accuracy = -(int)mpfr_get_exp(mx)+1; if (accuracy < min_accuracy) { min_accuracy = accuracy; } } } } mpfr_time *= 1000; best_time *= 1000; printf("%5d %5d %3d %3d %8d %8d %.3f\n", prec, min_accuracy, best_J, best_r, (int)mpfr_time, (int)best_time, mpfr_time/best_time); } mpfr_clear(mx); mpfr_clear(my); mpz_clear(x); mpz_clear(y); mpz_clear(dummy); }
/* Compute the first 2^m terms from the hypergeometric series with x = p / 2^r */ static int GENERIC (mpfr_ptr y, mpz_srcptr p, long r, int m) { unsigned long n,i,k,j,l; int is_p_one; mpz_t* P,*S; #ifdef A mpz_t *T; #endif mpz_t* ptoj; #ifdef R_IS_RATIONAL mpz_t* qtoj; mpfr_t tmp; #endif mp_exp_t diff, expo; mp_prec_t precy = MPFR_PREC(y); MPFR_TMP_DECL(marker); MPFR_TMP_MARK(marker); MPFR_CLEAR_FLAGS(y); n = 1UL << m; P = (mpz_t*) MPFR_TMP_ALLOC ((m+1) * sizeof(mpz_t)); S = (mpz_t*) MPFR_TMP_ALLOC ((m+1) * sizeof(mpz_t)); ptoj = (mpz_t*) MPFR_TMP_ALLOC ((m+1) * sizeof(mpz_t)); /* ptoj[i] = mantissa^(2^i) */ #ifdef A T = (mpz_t*) MPFR_TMP_ALLOC ((m+1) * sizeof(mpz_t)); #endif #ifdef R_IS_RATIONAL qtoj = (mpz_t*) MPFR_TMP_ALLOC ((m+1) * sizeof(mpz_t)); #endif for (i = 0 ; i <= m ; i++) { mpz_init (P[i]); mpz_init (S[i]); mpz_init (ptoj[i]); #ifdef R_IS_RATIONAL mpz_init (qtoj[i]); #endif #ifdef A mpz_init (T[i]); #endif } mpz_set (ptoj[0], p); #ifdef C # if C2 != 1 mpz_mul_ui (ptoj[0], ptoj[0], C2); # endif #endif is_p_one = mpz_cmp_ui(ptoj[0], 1) == 0; #ifdef A # ifdef B mpz_set_ui (T[0], A1 * B1); # else mpz_set_ui (T[0], A1); # endif #endif if (!is_p_one) for (i = 1 ; i < m ; i++) mpz_mul (ptoj[i], ptoj[i-1], ptoj[i-1]); #ifdef R_IS_RATIONAL mpz_set_si (qtoj[0], r); for (i = 1 ; i <= m ; i++) mpz_mul(qtoj[i], qtoj[i-1], qtoj[i-1]); #endif mpz_set_ui (P[0], 1); mpz_set_ui (S[0], 1); k = 0; for (i = 1 ; i < n ; i++) { k++; #ifdef A # ifdef B mpz_set_ui (T[k], (A1 + A2*i)*(B1+B2*i)); # else mpz_set_ui (T[k], A1 + A2*i); # endif #endif #ifdef C # ifdef NO_FACTORIAL mpz_set_ui (P[k], (C1 + C2 * (i-1))); mpz_set_ui (S[k], 1); # else mpz_set_ui (P[k], (i+1) * (C1 + C2 * (i-1))); mpz_set_ui (S[k], i+1); # endif #else # ifdef NO_FACTORIAL mpz_set_ui (P[k], 1); # else mpz_set_ui (P[k], i+1); # endif mpz_set (S[k], P[k]); #endif for (j = i+1, l = 0 ; (j & 1) == 0 ; l++, j>>=1, k--) { if (!is_p_one) mpz_mul (S[k], S[k], ptoj[l]); #ifdef A # ifdef B # if (A2*B2) != 1 mpz_mul_ui (P[k], P[k], A2*B2); # endif # else # if A2 != 1 mpz_mul_ui (P[k], P[k], A2); # endif #endif mpz_mul (S[k], S[k], T[k-1]); #endif mpz_mul (S[k-1], S[k-1], P[k]); #ifdef R_IS_RATIONAL mpz_mul (S[k-1], S[k-1], qtoj[l]); #else mpz_mul_2exp (S[k-1], S[k-1], r*(1<<l)); #endif mpz_add (S[k-1], S[k-1], S[k]); mpz_mul (P[k-1], P[k-1], P[k]); #ifdef A mpz_mul (T[k-1], T[k-1], T[k]); #endif } } diff = mpz_sizeinbase(S[0],2) - 2*precy; expo = diff; if (diff >= 0) mpz_div_2exp(S[0],S[0],diff); else mpz_mul_2exp(S[0],S[0],-diff); diff = mpz_sizeinbase(P[0],2) - precy; expo -= diff; if (diff >=0) mpz_div_2exp(P[0],P[0],diff); else mpz_mul_2exp(P[0],P[0],-diff); mpz_tdiv_q(S[0], S[0], P[0]); mpfr_set_z(y, S[0], GMP_RNDD); MPFR_SET_EXP (y, MPFR_GET_EXP (y) + expo); #ifdef R_IS_RATIONAL /* exact division */ mpz_div_ui (qtoj[m], qtoj[m], r); mpfr_init2 (tmp, MPFR_PREC(y)); mpfr_set_z (tmp, qtoj[m] , GMP_RNDD); mpfr_div (y, y, tmp, GMP_RNDD); mpfr_clear (tmp); #else mpfr_div_2ui(y, y, r*(i-1), GMP_RNDN); #endif for (i = 0 ; i <= m ; i++) { mpz_clear (P[i]); mpz_clear (S[i]); mpz_clear (ptoj[i]); #ifdef R_IS_RATIONAL mpz_clear (qtoj[i]); #endif #ifdef A mpz_clear (T[i]); #endif } MPFR_TMP_FREE (marker); return 0; }
BN BN::operator/(unsigned div) const { BN result; mpz_div_ui(PTR(result.dp), BNP, div); return result; }
VOID MakeSafePrime(MakePrimeParams *_pParams) { // 5, 7, 11, 23, 47, 59, 83, 107, 167, 179, 227, 263, 347, 359, 383, 467, 479, // 503, 563, 587, 719, 839, 863, 887, 983, 1019, 1187, 1283, 1307, 1319, 1367, // 1439, 1487, 1523, 1619, 1823, 1907... const uint32_t StepVal=2; BOOL Success; UINT Bits; uint32_t MaxSmallPrimeSqr; // uint32_t tmpUI; const clock_t clock1=clock(); clock_t clock2; _pParams->Cnt[0]=0; _pParams->Cnt[1]=0; _pParams->Cnt[2]=0; _pParams->mSecs =0; UpdateLabels(_pParams); Bits=mpz_sizeinbase(_pParams->mpzP, 2); if(Bits>MAX_BITS_FOR_SAFE) { return; } else if(mpz_cmp_ui(_pParams->mpzP, 5)<=0) { mpz_set_ui(_pParams->mpzP, 5); return; } CTrialDivisionPrimeTest* pTrialDivisionTest =new CTrialDivisionPrimeTest(); MaxSmallPrimeSqr=pTrialDivisionTest->GetMaxSmallPrime(); MaxSmallPrimeSqr*=MaxSmallPrimeSqr; CMillerRabinTest* pMillerRabinTest =new CMillerRabinTest(Bits); CStrongLucasSelfridgeTest* pStrongLucasSelfridgeTest; uint32_t ulMaxBits=2*Bits + mp_bits_per_limb; mpz_init2(_pParams->mpzP2, ulMaxBits); mpz_init(_pParams->mpzP3); do { if(Busy==FALSE)break; mpz_setbit(_pParams->mpzP, 0); //Чётное if(_pParams->Blum) mpz_setbit(_pParams->mpzP, 1); mpz_set(_pParams->mpzP2, _pParams->mpzP); mpz_clrbit(_pParams->mpzP2, 0);//-1 //TrialDivisionTest Не проверяет на 2, //поэтому пока не делим _pParams->mpzP2 на 2, сделаем это позже. // MessageBox(_pParams->hWnd, TEXT(""), TEXT(""), MB_OK); Success=pTrialDivisionTest->Test(_pParams->mpzP, _pParams->mpzP2); _pParams->Cnt[0]++; if(!Success){ mpz_add_ui(_pParams->mpzP, _pParams->mpzP, StepVal); continue;} //А сейчас уже надо делить на 2 mpz_div_ui(_pParams->mpzP2, _pParams->mpzP2, 2); Success=pMillerRabinTest->Test(_pParams->mpzP, 14); if(Success) Success=pMillerRabinTest->Test(_pParams->mpzP2, 14); _pParams->Cnt[1]++; if(_pParams->Cnt[1]%17==0) { clock2=clock(); _pParams->mSecs=(int)( (((float)(clock2)-(float)clock1)/CLOCKS_PER_SEC)*1000); } else if(_pParams->Cnt[1]%7==0) { UpdateLabels(_pParams); ProcessMessages(NULL); } if(!Success){mpz_add_ui(_pParams->mpzP, _pParams->mpzP, StepVal); continue;} pStrongLucasSelfridgeTest=new CStrongLucasSelfridgeTest(Bits); Success=pStrongLucasSelfridgeTest->Test(_pParams->mpzP); _pParams->Cnt[2]++; if(!Success){delete pStrongLucasSelfridgeTest; mpz_add_ui(_pParams->mpzP, _pParams->mpzP, StepVal); continue;} delete pStrongLucasSelfridgeTest; break; }while(1); clock2=clock(); _pParams->mSecs=(int)( (((float)(clock2)-(float)clock1)/CLOCKS_PER_SEC)*1000); UpdateLabels(_pParams); ProcessMessages(NULL); delete pMillerRabinTest; delete pTrialDivisionTest; mpz_clear(_pParams->mpzP2); mpz_clear(_pParams->mpzP3); }//--//
void miller_rabin(mpz_t n) { if(mpz_cmp_ui(n , 2) == 0) { gmp_printf("\n%Zd is a prime number\n" , n); exit(2); } mpz_t rem; mpz_init(rem); mpz_mmod_ui(rem , n , 2); if(mpz_cmp_ui(rem , 0) == 0) { gmp_printf("\n%Zd is not a prime number\n" , n); exit(2); } mpz_t n_minus_1; mpz_init(n_minus_1); mpz_sub_ui(n_minus_1 , n , 1); mpz_t r , s ; mpz_inits(r , s , NULL); mpz_set(s , n_minus_1); mpz_mmod_ui(rem , s , 2); while(mpz_cmp_ui(rem , 0) == 0) { mpz_add_ui(r , r , 1); mpz_div_ui(s , s , 2); mpz_mmod_ui(rem , s , 2); } mpz_t a; mpz_init(a); gmp_randstate_t state; gmp_randinit_default(state); int seed; //struct timeval* t; //gettimeofday(t , NULL); //seed = t->tv_usec; //seed = 4546; //printf("\nEnter seed - "); //scanf("%d" , &seed); gmp_randseed_ui (state , seed ); mpz_urandomm (a , state , n_minus_1); mpz_add_ui(a , a , 1); gmp_printf("\na is - %Zd\n" , a); mpz_t a_pow_s; mpz_init(a_pow_s); mpz_powm(rem , a , s , n); if(mpz_cmp_ui(rem , 1) == 0) { gmp_printf("\nThe given number %Zd is a prime number \n" , n); exit(0); } mpz_t two_pow_j; mpz_init(two_pow_j); mpz_set_ui(two_pow_j , 1); mpz_t j;; mpz_init(j); mpz_set_ui(j , 0); mpz_t product; mpz_init(product); while(mpz_cmp(j , r) != 0) { mpz_mul(product , two_pow_j , s); mpz_powm(rem , a , product , n); if(mpz_cmp(rem , n_minus_1) == 0) { gmp_printf("\nThe given number %Zd is a prime number \n" , n); exit(1); } mpz_mul_ui(two_pow_j , two_pow_j , 2); mpz_add_ui(j , j , 1); } gmp_printf("\nThe given number %Zd is NOT a prime number \n" , n); }
BigInt BigInt::operator / (uint16_t b) const { BigInt ret; mpz_div_ui(ret.mImpl,mImpl,b); return ret; }
BN& BN::operator/=(unsigned div) { BN tmp(*this); mpz_div_ui(BNP, REF(tmp.dp), div); return *this; }
/* s <- 1 + r/1! + r^2/2! + ... + r^l/l! while MPFR_EXP(r^l/l!)+MPFR_EXPR(r)>-q using Brent/Kung method with O(sqrt(l)) multiplications. Return l. Uses m multiplications of full size and 2l/m of decreasing size, i.e. a total equivalent to about m+l/m full multiplications, i.e. 2*sqrt(l) for m=sqrt(l). Version using mpz. ss must have at least (sizer+1) limbs. The error is bounded by (l^2+4*l) ulps where l is the return value. */ static int mpfr_exp2_aux2 (mpz_t s, mpfr_srcptr r, int q, int *exps) { int expr, l, m, i, sizer, *expR, expt, ql; unsigned long int c; mpz_t t, *R, rr, tmp; TMP_DECL(marker); /* estimate value of l */ l = q / (-MPFR_EXP(r)); m = (int) _mpfr_isqrt (l); /* we access R[2], thus we need m >= 2 */ if (m < 2) m = 2; TMP_MARK(marker); R = (mpz_t*) TMP_ALLOC((m+1)*sizeof(mpz_t)); /* R[i] stands for r^i */ expR = (int*) TMP_ALLOC((m+1)*sizeof(int)); /* exponent for R[i] */ sizer = 1 + (MPFR_PREC(r)-1)/BITS_PER_MP_LIMB; mpz_init(tmp); MY_INIT_MPZ(rr, sizer+2); MY_INIT_MPZ(t, 2*sizer); /* double size for products */ mpz_set_ui(s, 0); *exps = 1-q; /* initialize s to zero, 1 ulp = 2^(1-q) */ for (i=0;i<=m;i++) MY_INIT_MPZ(R[i], sizer+2); expR[1] = mpfr_get_z_exp(R[1], r); /* exact operation: no error */ expR[1] = mpz_normalize2(R[1], R[1], expR[1], 1-q); /* error <= 1 ulp */ mpz_mul(t, R[1], R[1]); /* err(t) <= 2 ulps */ mpz_div_2exp(R[2], t, q-1); /* err(R[2]) <= 3 ulps */ expR[2] = 1-q; for (i=3;i<=m;i++) { mpz_mul(t, R[i-1], R[1]); /* err(t) <= 2*i-2 */ mpz_div_2exp(R[i], t, q-1); /* err(R[i]) <= 2*i-1 ulps */ expR[i] = 1-q; } mpz_set_ui(R[0], 1); mpz_mul_2exp(R[0], R[0], q-1); expR[0]=1-q; /* R[0]=1 */ mpz_set_ui(rr, 1); expr=0; /* rr contains r^l/l! */ /* by induction: err(rr) <= 2*l ulps */ l = 0; ql = q; /* precision used for current giant step */ do { /* all R[i] must have exponent 1-ql */ if (l) for (i=0;i<m;i++) { expR[i] = mpz_normalize2(R[i], R[i], expR[i], 1-ql); } /* the absolute error on R[i]*rr is still 2*i-1 ulps */ expt = mpz_normalize2(t, R[m-1], expR[m-1], 1-ql); /* err(t) <= 2*m-1 ulps */ /* computes t = 1 + r/(l+1) + ... + r^(m-1)*l!/(l+m-1)! using Horner's scheme */ for (i=m-2;i>=0;i--) { mpz_div_ui(t, t, l+i+1); /* err(t) += 1 ulp */ mpz_add(t, t, R[i]); } /* now err(t) <= (3m-2) ulps */ /* now multiplies t by r^l/l! and adds to s */ mpz_mul(t, t, rr); expt += expr; expt = mpz_normalize2(t, t, expt, *exps); /* err(t) <= (3m-1) + err_rr(l) <= (3m-2) + 2*l */ #ifdef DEBUG if (expt != *exps) { fprintf(stderr, "Error: expt != exps %d %d\n", expt, *exps); exit(1); } #endif mpz_add(s, s, t); /* no error here */ /* updates rr, the multiplication of the factors l+i could be done using binary splitting too, but it is not sure it would save much */ mpz_mul(t, rr, R[m]); /* err(t) <= err(rr) + 2m-1 */ expr += expR[m]; mpz_set_ui (tmp, 1); for (i=1, c=1; i<=m; i++) { if (l+i > ~((unsigned long int) 0)/c) { mpz_mul_ui(tmp, tmp, c); c = l+i; } else c *= (unsigned long int) l+i; } if (c != 1) mpz_mul_ui (tmp, tmp, c); /* tmp is exact */ mpz_fdiv_q(t, t, tmp); /* err(t) <= err(rr) + 2m */ expr += mpz_normalize(rr, t, ql); /* err_rr(l+1) <= err_rr(l) + 2m+1 */ ql = q - *exps - mpz_sizeinbase(s, 2) + expr + mpz_sizeinbase(rr, 2); l+=m; } while (expr+mpz_sizeinbase(rr, 2) > -q); TMP_FREE(marker); mpz_clear(tmp); return l; }
void poly_init(QS_t * qs_inf, poly_t * poly_inf, mpz_t N) { unsigned long num_primes = qs_inf->num_primes; unsigned long s = (qs_inf->bits-1)/28+1; if (s <= 2) s = 3; prime_t * factor_base = qs_inf->factor_base; unsigned long fact_approx, fact, span; unsigned long sieve_size = qs_inf->sieve_size; unsigned long small_primes = qs_inf->small_primes; long min; poly_inf->s = s; poly_inf->B = (unsigned long*) flint_stack_alloc(qs_inf->prec+1); poly_inf->B_terms = (unsigned long*) flint_stack_alloc(s*(qs_inf->prec+1)); poly_inf->A = (unsigned long*) flint_stack_alloc(qs_inf->prec+1); poly_inf->target_A = (unsigned long*) flint_stack_alloc(qs_inf->prec+1); poly_inf->A_ind = (unsigned long*) flint_stack_alloc(s); poly_inf->A_modp = (unsigned long*) flint_stack_alloc(s); poly_inf->A_inv2B = (uint32_t**) flint_stack_alloc(s); poly_inf->inv_p2 = (double*) flint_stack_alloc_bytes(s*sizeof(double)); poly_inf->A_inv = (uint32_t *) flint_stack_alloc_bytes(num_primes*sizeof(uint32_t)); poly_inf->soln1 = (uint32_t *) flint_stack_alloc_bytes(num_primes*sizeof(uint32_t)); poly_inf->soln2 = (uint32_t *) flint_stack_alloc_bytes(num_primes*sizeof(uint32_t)); poly_inf->posn1 = (uint32_t *) flint_stack_alloc_bytes(num_primes*sizeof(uint32_t)); poly_inf->posn2 = (uint32_t *) flint_stack_alloc_bytes(num_primes*sizeof(uint32_t)); uint32_t ** A_inv2B = poly_inf->A_inv2B; A_inv2B[0] = (uint32_t *) flint_stack_alloc_bytes(num_primes*s*sizeof(uint32_t)); mpz_init(poly_inf->A_mpz); mpz_init(poly_inf->B_mpz); mpz_init(poly_inf->C); for (unsigned long i = 1; i < s; i++) { A_inv2B[i] = A_inv2B[i-1] + num_primes; } mpz_t temp; mpz_init(temp); mpz_mul_ui(temp, N, 2*qs_inf->k); mpz_sqrt(temp, temp); mpz_div_ui(temp, temp, 47*sieve_size/100); mpz_to_fmpz(poly_inf->target_A, temp); mpz_root(temp, temp, s); fact_approx = mpz_get_ui(temp); for (fact = 0; fact_approx >= factor_base[fact].p; fact++); span = num_primes/s/s/2; if (span < 6*s) span = 6*s; min = fact - span/2; if (min < (long) small_primes) min = small_primes; if (min + span >= qs_inf->num_primes - 1) span = num_primes - min - 1; fact = min + span/2; #if POLY_PARAMS printf("min = FB[%ld], span = %ld, number of factors = %ld\n", min, span, s); #endif poly_inf->min = min; poly_inf->fact = fact; poly_inf->span = span; mpz_clear(temp); }
void tiny_poly_init(QS_t * qs_inf, poly_t * poly_inf, mpz_t N) { unsigned long num_primes = qs_inf->num_primes; unsigned long s = (qs_inf->bits-1)/28+1; if (s <= 2) s = 3; prime_t * factor_base = qs_inf->factor_base; unsigned long fact_approx, fact, span; long min; poly_inf->s = s; poly_inf->B_terms = (unsigned long*) flint_stack_alloc(s); poly_inf->A_ind = (unsigned long*) flint_stack_alloc(s); poly_inf->A_modp = (unsigned long*) flint_stack_alloc(s); poly_inf->A_inv2B = (unsigned long**) flint_stack_alloc(s); poly_inf->inv_p2 = (double*) flint_stack_alloc_bytes(s*sizeof(double)); poly_inf->A_inv = (unsigned long*) flint_stack_alloc(num_primes); poly_inf->soln1 = (unsigned long*) flint_stack_alloc(num_primes); poly_inf->soln2 = (unsigned long*) flint_stack_alloc(num_primes); unsigned long ** A_inv2B = poly_inf->A_inv2B; A_inv2B[0] = (unsigned long *) flint_stack_alloc(num_primes*s); mpz_init(poly_inf->C); unsigned long i; for (i = 1; i < s; i++) { A_inv2B[i] = A_inv2B[i-1] + num_primes; } mpz_t temp; mpz_init(temp); mpz_mul_ui(temp, N, 2*qs_inf->k); mpz_sqrt(temp, temp); mpz_div_ui(temp, temp, 300); poly_inf->target_A = mpz_get_ui(temp); mpz_root(temp, temp, s); fact_approx = mpz_get_ui(temp); for (fact = 0; fact_approx >= factor_base[fact].p; fact++); span = num_primes/s/s/2; if (span < 6*s) span = 6*s; min = fact - span/2; if (min < SMALL_PRIMES) min = SMALL_PRIMES; if (min + span >= num_primes - 1) span = num_primes - min - 1; fact = min + span/2; #if POLY_PARAMS printf("num_primes = %ld, min = FB[%ld], span = %ld, number of factors = %ld\n", num_primes, min, span, s); #endif poly_inf->min = min; poly_inf->fact = fact; poly_inf->span = span; mpz_clear(temp); }