Beispiel #1
0
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);
}
Beispiel #3
0
/*
 * \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);
  }
}
Beispiel #4
0
/* 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;
}
Beispiel #5
0
/*
 * \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);
}
Beispiel #6
0
/* 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;
}
Beispiel #7
0
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);
}
Beispiel #8
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;
}
Beispiel #9
0
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;
}
Beispiel #10
0
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);

}
Beispiel #11
0
/* 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;
}
Beispiel #12
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);
}
Beispiel #15
0
BigInt BigInt::operator / (uint16_t b) const
{
	BigInt ret;
	mpz_div_ui(ret.mImpl,mImpl,b);
	return ret;
}
Beispiel #16
0
BN& BN::operator/=(unsigned div)
{
	BN tmp(*this);
	mpz_div_ui(BNP, REF(tmp.dp), div);
	return *this;
}
Beispiel #17
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 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;
}
Beispiel #18
0
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); 
}
Beispiel #19
0
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); 
}