int
aks (mpz_t n)
{
  mpz_t r;
  mpz_t a;
  mpz_t max_a;
  mpz_t gcd_rslt;
  mpz_t totient_r;
  mpf_t ftotient_r;
  mpf_t sqrt_rslt;
  mpf_t sqrt_rslt2;
  mpf_t temp;
  mpf_t temp2;
  sli_t logn;
/* For the sake of maple kernel */
  int argc = 0;
  char **argv;
  char err[2048];
  mpz_init (r);
  mpz_init (a);
  mpz_init (max_a);
  mpz_init (gcd_rslt);
  mpz_init (totient_r);
  mpf_init (ftotient_r);
  mpf_init (sqrt_rslt);
  mpf_init (sqrt_rslt2);
  mpf_init (temp);
  mpf_init (temp2);
/* 1. If (n = a^k for a in N and b > 1) output COMPOSITE */
  if (mpz_perfect_power_p (n) != 0)
    {
      printf ("Step 1 detected composite\n");
      return FALSE;
    }
/* 2. Find the smallest r such that or(n) > 4(log n)^2 */
  find_smallest_r (r, n);
  gmp_printf ("good r seems to be %Zd\n", r);
/* 3. If 1 < gcd(a, n) < n for some a <= r, output COMPOSITE */
/* for (a = 1; a <= r; a++) {
* gcd_rslt = gcd(a, n);
* if (gcd_rslt > 1 && gcd_rslt < n) {
* return FALSE;
* }
* }
*/
  for (mpz_set_ui (a, 1);
       mpz_cmp (a, r) < 0 || mpz_cmp (a, r) == 0; mpz_add_ui (a, a, 1))
    {
      mpz_gcd (gcd_rslt, a, n);
      if (mpz_cmp_ui (gcd_rslt, 1) > 0 && mpz_cmp (gcd_rslt, n) < 0)
	{
	  printf ("Step 3 detected composite\n");
	  return FALSE;
	}
    }
/* 4. If n <= r, output PRIME */
  if (mpz_cmp (n, r) < 0 || mpz_cmp (n, r) == 0)
    {
      printf ("Step 4 detected prime\n");
      return TRUE;
    }
/* 5. For a = 1 to floor(2*sqrt(totient(r))*(log n)
* if ( (X+a)^n != X^n + a (mod X^r-1, n) ), output COMPOSITE
*
* Choices of implementation to evaluate the polynomial equality:
* (1) Implement powermodreduce on polynomial ourselves (tough manly way)
* (2) Use MAPLE (not so manly, but less painful)
*/
/* Compute totient(r), since r is prime, this is simply r-1 */
  mpz_sub_ui (totient_r, r, 1);
/* Compute log n (ceilinged) */
  mpz_logbase2cl (&logn, n);
/* Compute sqrt(totient(r)) */
  mpf_set_z (ftotient_r, totient_r);
  mpf_sqrt (sqrt_rslt, ftotient_r);
/* Compute 2*sqrt(totient(r)) */
  mpf_mul_ui (sqrt_rslt2, sqrt_rslt, 2);
/* Compute 2*sqrt(totient(r))*(log n) */
  mpf_set (temp, sqrt_rslt2);
  mpf_set_si (temp2, logn);
  mpf_mul (temp, temp, temp2);
/* Finally, compute max_a, after lots of singing and dancing */
  mpf_floor (temp, temp);
  mpz_set_f (max_a, temp);
  gmp_printf ("max_a = %Zd\n", max_a);
/* Now evaluate the polynomial equality with the help of maple kernel */
/* Set up maple kernel incantations */
  MKernelVector kv;
  MCallBackVectorDesc cb = { textCallBack,
    0,				/* errorCallBack not used */
    0,				/* statusCallBack not used */
    0,				/* readLineCallBack not used */
    0,				/* redirectCallBack not used */
    0,				/* streamCallBack not used */
    0,				/* queryInterrupt not used */
    0				/* callBackCallBack not used */
  };
/* Initialize Maple */
  if ((kv = StartMaple (argc, argv, &cb, NULL, NULL, err)) == NULL)
    {
      printf ("Could not start Maple, %s\n", err);
      exit (666);
    }
/* Here comes the complexity and bottleneck */
/* for (a = 1; a <= max_a; a++) {
* if (!poly_eq_holds(kv, a, n, r)) {
* return FALSE;
* }
* }
*/
/* Make max_a only up to 5 */
  mpz_set_ui (max_a, 5);
  for (mpz_set_ui (a, 1);
       mpz_cmp (a, max_a) < 0 || mpz_cmp (a, max_a) == 0;
       mpz_add_ui (a, a, 1))
    {
      if (!poly_eq_holds (kv, a, n, r))
	{
	  printf ("Step 5 detected composite\n");
	  return FALSE;
	}
    }
/* 6. Output PRIME */
  printf ("Step 6 detected prime\n");
  return TRUE;
}
Exemplo n.º 2
0
int
main(void)
{
    int i, result;
    FLINT_TEST_INIT(state);

    flint_printf("sub_ui....");
    fflush(stdout);

    

    for (i = 0; i < 10000 * flint_test_multiplier(); i++)
    {
        fmpz_t a, b;
        mpz_t d, e, f;
        ulong x;

        fmpz_init(a);
        fmpz_init(b);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);

        fmpz_randtest(a, state, 200);

        fmpz_get_mpz(d, a);
        x = n_randtest(state);

        fmpz_sub_ui(b, a, x);
        flint_mpz_sub_ui(e, d, x);

        fmpz_get_mpz(f, b);

        result = (mpz_cmp(e, f) == 0);
        if (!result)
        {
            flint_printf("FAIL:\n");
            gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %wu\n", d, e, f, x);
            abort();
        }

        fmpz_clear(a);
        fmpz_clear(b);

        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
    }

    /* Check aliasing of a and b */
    for (i = 0; i < 10000 * flint_test_multiplier(); i++)
    {
        fmpz_t a;
        mpz_t d, e, f;
        ulong x;

        fmpz_init(a);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);

        fmpz_randtest(a, state, 200);

        fmpz_get_mpz(d, a);
        x = n_randtest(state);

        fmpz_sub_ui(a, a, x);
        flint_mpz_sub_ui(e, d, x);

        fmpz_get_mpz(f, a);

        result = (mpz_cmp(e, f) == 0);
        if (!result)
        {
            flint_printf("FAIL:\n");
            gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %wu\n", d, e, f, x);
            abort();
        }

        fmpz_clear(a);

        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
    }

    FLINT_TEST_CLEANUP(state);
    
    flint_printf("PASS\n");
    return 0;
}
Exemplo n.º 3
0
int
main(void)
{
    int i;
    mp_size_t j;

    gmp_randstate_t state;

    tests_start();
    fflush(stdout);

    gmp_randinit_default(state);

    for (i = 0; i < 10000; i++)
    {
        mp_limb_t total_limbs;
        mp_limb_t * in;
        mp_limb_t * out;
        mp_bitcnt_t bits;
        mp_size_t limbs;
        long length;
        mp_limb_t ** poly;
        
        mpn_rrandom(&total_limbs, state, 1);
        total_limbs = total_limbs % 1000 + 1;
        in = malloc(total_limbs*sizeof(mp_limb_t));
        out = calloc(total_limbs, sizeof(mp_limb_t));
        mpn_rrandom(&bits, state, 1);
        bits = bits % 200 + 1;
        limbs = (2*bits - 1)/GMP_LIMB_BITS + 1;
        length = (total_limbs*GMP_LIMB_BITS - 1)/bits + 1;
        
        poly = malloc(length*sizeof(mp_limb_t *));
        for (j = 0; j < length; j++)
           poly[j] = malloc((limbs + 1)*sizeof(mp_limb_t));

        mpn_urandomb(in, state, total_limbs*GMP_LIMB_BITS);

        mpir_fft_split_bits(poly, in, total_limbs, bits, limbs);
        mpir_fft_combine_bits(out, poly, length, bits, limbs, total_limbs);
        
        for (j = 0; j < total_limbs; j++)
        {
           if (in[j] != out[j])
           {
              printf("FAIL:\n");
              gmp_printf("Error in limb %ld, %Mu != %Mu\n", j, in[j], out[j]);
              abort();
           }
        }

        free(in);
        free(out);

        for (j = 0; j < length; j++)
           free(poly[j]);

        free(poly);
    }

    gmp_randclear(state);
    
    tests_end();
    return 0;
}
Exemplo n.º 4
0
int
main(void)
{
    int i, result;
    flint_rand_t state;

    printf("equal....");
    fflush(stdout);

    flint_randinit(state);

    for (i = 0; i < 100000; i++)
    {
        fmpz_t a, b;

        fmpz_init(a);
        fmpz_init(b);

        fmpz_randtest(a, state, 200);
        fmpz_set(b, a);

        result = (fmpz_equal(a, b));
        if (!result)
        {
            printf("FAIL:\n");
            printf("a = "), fmpz_print(a), printf("\n");
            printf("b = "), fmpz_print(b), printf("\n");
            abort();
        }

        fmpz_clear(a);
        fmpz_clear(b);
    }

    for (i = 0; i < 100000; i++)
    {
        fmpz_t a, b;
        mpz_t c, d;

        fmpz_init(a);
        fmpz_init(b);

        mpz_init(c);
        mpz_init(d);

        fmpz_randtest(a, state, 200);
        fmpz_randtest(b, state, 200);

        fmpz_get_mpz(c, a);
        fmpz_get_mpz(d, b);

        result = (fmpz_equal(a, b) == (mpz_cmp(c, d) == 0));
        if (!result)
        {
            printf("FAIL:\n");
            gmp_printf("c = %Zd, d = %Zd\n", c, d);
            abort();
        }

        fmpz_clear(a);
        fmpz_clear(b);

        mpz_clear(c);
        mpz_clear(d);
    }

    flint_randclear(state);
    _fmpz_cleanup();
    printf("PASS\n");
    return 0;
}
Exemplo n.º 5
0
int is_aks_prime(mpz_t n)
{
  mpz_t *px, *py;
  int retval;
  UV i, s, r, a;
  UV starta = 1;
  int _verbose = get_verbose_level();

  if (mpz_cmp_ui(n, 4) < 0)
    return (mpz_cmp_ui(n, 1) <= 0) ? 0 : 1;

  /* Just for performance: check small divisors: 2*3*5*7*11*13*17*19*23 */
  if (mpz_gcd_ui(0, n, 223092870UL) != 1 && mpz_cmp_ui(n, 23) > 0)
    return 0;

  if (mpz_perfect_power_p(n))
    return 0;

#if AKS_VARIANT == AKS_VARIANT_V6    /* From the V6 AKS paper */
  {
    mpz_t sqrtn, t;
    double log2n;
    UV limit, startr;
    PRIME_ITERATOR(iter);

    mpz_init(sqrtn);
    mpz_sqrt(sqrtn, n);

    log2n = mpz_log2(n);
    limit = (UV) floor( log2n * log2n );

    if (_verbose>1) gmp_printf("# AKS checking order_r(%Zd) to %"UVuf"\n", n, (unsigned long) limit);

    /* Using a native r limits us to ~2000 digits in the worst case (r ~ log^5n)
     * but would typically work for 100,000+ digits (r ~ log^3n).  This code is
     * far too slow to matter either way.  Composite r is ok here, but it will
     * always end up prime, so save time and just check primes. */
    retval = 0;
    /* Start order search at a good spot.  Idea from Nemana and Venkaiah. */
    startr = (mpz_sizeinbase(n,2)-1) * (mpz_sizeinbase(n,2)-1);
    startr = (startr < 1002) ? 2 : startr - 100;
    for (r = 2; /* */; r = prime_iterator_next(&iter)) {
      if (mpz_divisible_ui_p(n, r) ) /* r divides n.  composite. */
        { retval = 0; break; }
      if (mpz_cmp_ui(sqrtn, r) <= 0) /* no r <= sqrtn divides n.  prime. */
        { retval = 1; break; }
      if (r < startr) continue;
      if (mpz_order_ui(r, n, limit) > limit)
        { retval = 2; break; }
    }
    prime_iterator_destroy(&iter);
    mpz_clear(sqrtn);
    if (retval != 2) return retval;

    /* Since r is prime, phi(r) = r-1. */
    s = (UV) floor( sqrt(r-1) * log2n );
  }
#elif AKS_VARIANT == AKS_VARIANT_BORNEMANN /* Bernstein + Voloch */
  {
    UV slim;
    double c2, x;
    /* small t = few iters of big poly.  big t = many iters of small poly */
    double const t = (mpz_sizeinbase(n, 2) <= 64) ? 32 : 40;
    double const t1 = (1.0/((t+1)*log(t+1)-t*log(t)));
    double const dlogn = mpz_logn(n);
    mpz_t tmp;
    PRIME_ITERATOR(iter);

    mpz_init(tmp);
    prime_iterator_setprime(&iter, (UV) (t1*t1 * dlogn*dlogn) );
    r = prime_iterator_next(&iter);
    while (!is_primitive_root_uiprime(n,r))
      r = prime_iterator_next(&iter);
    prime_iterator_destroy(&iter);

    slim = (UV) (2*t*(r-1));
    c2 = dlogn * floor(sqrt(r));
    { /* Binary search for first s in [1,slim] where x >= 0 */
      UV bi = 1;
      UV bj = slim;
      while (bi < bj) {
        s = bi + (bj-bi)/2;
        mpz_bin_uiui(tmp, r+s-1, s);
        x = mpz_logn(tmp) / c2 - 1.0;
        if (x < 0)  bi = s+1;
        else        bj = s;
      }
      s = bi-1;
    }
    s = (s+3) >> 1;
    /* Bornemann checks factors up to (s-1)^2, we check to max(r,s) */
    /* slim = (s-1)*(s-1); */
    slim = (r > s) ? r : s;
    if (_verbose > 1) printf("# aks trial to %"UVuf"\n", slim);
    if (_GMP_trial_factor(n, 2, slim) > 1)
      { mpz_clear(tmp); return 0; }
    mpz_sqrt(tmp, n);
    if (mpz_cmp_ui(tmp, slim) <= 0)
      { mpz_clear(tmp); return 1; }
    mpz_clear(tmp);
  }
#elif AKS_VARIANT == AKS_VARIANT_BERN21
  { /* Bernstein 2003, theorem 2.1 (simplified) */
    UV q;
    double slim, scmp, x;
    mpz_t t, t2;
    PRIME_ITERATOR(iter);
    mpz_init(t);  mpz_init(t2);
    r = s = 0;
    while (1) {
      /* todo: Check r|n and r >= sqrt(n) here instead of waiting */
      if (mpz_cmp_ui(n, r) <= 0) break;
      r = prime_iterator_next(&iter);
      q = largest_factor(r-1);
      mpz_set_ui(t, r);
      mpz_powm_ui(t, n, (r-1)/q, t);
      if (mpz_cmp_ui(t, 1) <= 0) continue;
      scmp = 2 * floor(sqrt(r)) * mpz_log2(n);

      slim = 20 * (r-1);

      /* Check viability */
      mpz_bin_uiui(t, q+slim-1, slim); if (mpz_log2(t) < scmp) continue;

      for (s = 2; s < slim; s++) {
        mpz_bin_uiui(t, q+s-1, s);
        if (mpz_log2(t) > scmp) break;
      }
      if (s < slim) break;
    }
    mpz_clear(t);  mpz_clear(t2);
    prime_iterator_destroy(&iter);
    if (_GMP_trial_factor(n, 2, s) > 1)
      return 0;
  }
#elif AKS_VARIANT == AKS_VARIANT_BERN22
  { /* Bernstein 2003, theorem 2.2 (simplified) */
    UV q;
    double slim, scmp, x;
    mpz_t t, t2;
    PRIME_ITERATOR(iter);
    mpz_init(t);  mpz_init(t2);
    r = s = 0;
    while (1) {
      /* todo: Check r|n and r >= sqrt(n) here instead of waiting */
      if (mpz_cmp_ui(n, r) <= 0) break;
      r = prime_iterator_next(&iter);
      if (!is_primitive_root_uiprime(n,r)) continue;
      q = r-1;   /* Since r is prime, phi(r) = r-1 */
      scmp = 2 * floor(sqrt(r-1)) * mpz_log2(n);

      slim = 20 * (r-1);

      /* Check viability */
      mpz_bin_uiui(t, q+slim-1, slim); if (mpz_log2(t) < scmp) continue;

      for (s = 2; s < slim; s++) {
        mpz_bin_uiui(t, q+s-1, s);
        if (mpz_log2(t) > scmp) break;
      }
      if (s < slim) break;
    }
    mpz_clear(t);  mpz_clear(t2);
    prime_iterator_destroy(&iter);
    if (_GMP_trial_factor(n, 2, s) > 1)
      return 0;
  }
#elif AKS_VARIANT == AKS_VARIANT_BERN23
  { /* Bernstein 2003, theorem 2.3 (simplified) */
    UV q, d, limit;
    double slim, scmp, sbin, x, log2n;
    mpz_t t, t2;
    PRIME_ITERATOR(iter);
    mpz_init(t);  mpz_init(t2);
    log2n = mpz_log2(n);
    limit = (UV) floor( log2n * log2n );
    r = 2;
    s = 0;
    while (1) {
      /* todo: Check r|n and r >= sqrt(n) here instead of waiting */
      if (mpz_cmp_ui(n, r) <= 0) break;
      r++;
      UV gcd = mpz_gcd_ui(NULL, n, r);
      if (gcd != 1) { mpz_clear(t); mpz_clear(t2); return 0; }
      UV v = mpz_order_ui(r, n, limit);
      if (v >= limit) continue;

      mpz_set_ui(t2, r);
      totient(t, t2);
      q = mpz_get_ui(t);
      UV phiv = q/v;
      /* printf("phi(%lu)/v = %lu/%lu = %lu\n", r, q, v, phiv); */

      /* This is extremely inefficient. */

      /* Choose an s value we'd be happy with */
      slim = 20 * (r-1);

      /* Quick check to see if it could work with s=slim, d=1 */
      mpz_bin_uiui(t, q+slim-1, slim);
      sbin = mpz_log2(t);
      if (sbin < 2*floor(sqrt(q))*log2n)
        continue;

      for (s = 2; s < slim; s++) {
        mpz_bin_uiui(t, q+s-1, s);
        sbin = mpz_log2(t);
        if (sbin < 2*floor(sqrt(q))*log2n) continue;   /* d=1 */
        /* Check each number dividing phi(r)/v */
        for (d = 2; d < phiv; d++) {
          if ((phiv % d) != 0) continue;
          scmp = 2 * d * floor(sqrt(q/d)) * log2n;
          if (sbin < scmp) break;
        }
        /* if we did not exit early, this s worked for each d.  This s wins. */
        if (d >= phiv) break;
      }
      if (s < slim) break;
    }
    mpz_clear(t);  mpz_clear(t2);
    prime_iterator_destroy(&iter);
    if (_GMP_trial_factor(n, 2, s) > 1)
      return 0;
  }
#elif AKS_VARIANT == AKS_VARIANT_BERN41
  {
    double const log2n = mpz_log2(n);
    /* Tuning: Initial 'r' selection */
    double const r0 = 0.008 * log2n * log2n;
    /* Tuning: Try a larger 'r' if 's' looks very large */
    UV const rmult = 8;
    UV slim;
    mpz_t tmp, tmp2;
    PRIME_ITERATOR(iter);

    mpz_init(tmp);  mpz_init(tmp2);
    /* r has to be at least 3. */
    prime_iterator_setprime(&iter, (r0 < 2) ? 2 : (UV) r0);
    r = prime_iterator_next(&iter);

    /* r must be a primitive root.  For performance, skip if s looks too big. */
    while ( !is_primitive_root_uiprime(n, r) ||
            !bern41_acceptable(n, r, rmult*(r-1), tmp, tmp2) )
      r = prime_iterator_next(&iter);
    prime_iterator_destroy(&iter);

    { /* Binary search for first s in [1,lim] where conditions met */
      UV bi = 1;
      UV bj = rmult * (r-1);
      while (bi < bj) {
        s = bi + (bj-bi)/2;
        if (!bern41_acceptable(n,r,s,tmp,tmp2))  bi = s+1;
        else                                     bj = s;
      }
      s = bj;
      /* Our S goes from 2 to s+1. */
      starta = 2;
      s = s+1;
    }
    /* printf("chose r=%lu s=%lu d = %lu i = %lu j = %lu\n", r, s, d, i, j); */

    /* Check divisibility to s(s-1) to cover both gcd conditions */
    slim = s * (s-1);
    if (_verbose > 1) printf("# aks trial to %"UVuf"\n", slim);
    if (_GMP_trial_factor(n, 2, slim) > 1)
      { mpz_clear(tmp); mpz_clear(tmp2); return 0; }
    /* If we checked divisibility to sqrt(n), then it is prime. */
    mpz_sqrt(tmp, n);
    if (mpz_cmp_ui(tmp, slim) <= 0)
      { mpz_clear(tmp); mpz_clear(tmp2); return 1; }

    /* Check b^(n-1) = 1 mod n for b in [2..s] */
    if (_verbose > 1) printf("# aks checking fermat to %"UVuf"\n", s);
    mpz_sub_ui(tmp2, n, 1);
    for (i = 2; i <= s; i++) {
      mpz_set_ui(tmp, i);
      mpz_powm(tmp, tmp, tmp2, n);
      if (mpz_cmp_ui(tmp, 1) != 0)
        { mpz_clear(tmp); mpz_clear(tmp2); return 0; }
    }

    mpz_clear(tmp);  mpz_clear(tmp2);
  }

#endif

  if (_verbose) gmp_printf("# AKS %Zd.  r = %"UVuf" s = %"UVuf"\n", n, (unsigned long) r, (unsigned long) s);

  /* Create the three polynomials we will use */
  New(0, px, r, mpz_t);
  New(0, py, r, mpz_t);
  if ( !px || !py )
    croak("allocation failure\n");
  for (i = 0; i < r; i++) {
    mpz_init(px[i]);
    mpz_init(py[i]);
  }

  retval = 1;
  for (a = starta; a <= s; a++) {
    retval = test_anr(a, n, r, px, py);
    if (!retval) break;
    if (_verbose>1) { printf("."); fflush(stdout); }
  }
  if (_verbose>1) { printf("\n"); fflush(stdout); };

  /* Free the polynomials */
  for (i = 0; i < r; i++) {
    mpz_clear(px[i]);
    mpz_clear(py[i]);
  }
  Safefree(px);
  Safefree(py);

  return retval;
}
Exemplo n.º 6
0
uint64 *sieve_to_depth(uint32 *seed_p, uint32 num_sp, 
	mpz_t lowlimit, mpz_t highlimit, int count, int num_witnesses, uint64 *num_p)
{
	//public interface to a routine which will sieve a range of integers
	//with the supplied primes and either count or compute the values
	//that survive.  Basically, it is just the sieve, but with no
	//guareentees that what survives the sieving is prime.  The idea is to 
	//remove cheap composites.
	uint64 retval, i, range, tmpl, tmph;
	uint64 *values = NULL;
	mpz_t tmpz;
	mpz_t *offset;

	if (mpz_cmp(highlimit, lowlimit) <= 0)
	{
		printf("error: lowlimit must be less than highlimit\n");
		*num_p = 0;
		return values;
	}	

	offset = (mpz_t *)malloc(sizeof(mpz_t));
	mpz_init(tmpz);
	mpz_init(*offset);
	mpz_set(*offset, lowlimit);
	mpz_sub(tmpz, highlimit, lowlimit);
	range = mpz_get_64(tmpz);

	if (count)
	{
		//this needs to be a range of at least 1e6
		if (range < 1000000)
		{
			//go and get a new range.
			tmpl = 0;
			tmph = 1000000;

			//since this is a small range, we need to 
			//find a bigger range and count them.
			values = GetPRIMESRange(seed_p, num_sp, offset, tmpl, tmph, &retval);

			*num_p = 0;
			//count how many are in the original range of interest
			for (i = 0; i < retval; i++)
			{
				mpz_add_ui(tmpz, *offset, values[i]);
				if ((mpz_cmp(tmpz, lowlimit) >= 0) && (mpz_cmp(highlimit, tmpz) >= 0))
					(*num_p)++;
			}
			free(values);
			values = NULL;
		}
		else
		{
			//check for really big ranges
			uint64 maxrange = 100000000000ULL;

			if (range > maxrange)
			{
				uint32 num_ranges = (uint32)(range / maxrange);
				uint64 remainder = range % maxrange;
				uint32 j;
				
				*num_p = 0;
				tmpl = 0;
				tmph = tmpl + maxrange;
				for (j = 0; j < num_ranges; j++)
				{
					*num_p += spSOE(seed_p, num_sp, offset, tmpl, &tmph, 1, NULL);
					if (VFLAG > 1)
						printf("so far, found %" PRIu64 " primes\n",*num_p);
					tmpl += maxrange;
					tmph = tmpl + maxrange;
				}
				
				if (remainder > 0)
				{
					tmph = tmpl + remainder;
					*num_p += spSOE(seed_p, num_sp, offset, tmpl, &tmph, 1, NULL);
				}
				if (VFLAG > 1)
					printf("so far, found %" PRIu64 " primes\n",*num_p);
			}
			else
			{
				//we're in a sweet spot already, just get the requested range
				*num_p = spSOE(seed_p, num_sp, offset, 0, &range, 1, NULL);
			}
		}

	}
	else
	{
		//this needs to be a range of at least 1e6
		if (range < 1000000)
		{
			//there is slack built into the sieve limit, so go ahead and increase
			//the size of the interval to make it at least 1e6.
			tmpl = 0;
			tmph = tmpl + 1000000;

			//since this is a small range, we need to 
			//find a bigger range and count them.
			values = GetPRIMESRange(seed_p, num_sp, offset, tmpl, tmph, &retval);
			*num_p = 0;
			for (i = 0; i < retval; i++)
			{
				mpz_add_ui(tmpz, *offset, values[i]);
				if ((mpz_cmp(tmpz, lowlimit) >= 0) && (mpz_cmp(highlimit, tmpz) >= 0))
					(*num_p)++;
			}

		}
		else
		{
			//we don't need to mess with the requested range,
			//so GetPRIMESRange will return the requested range directly
			//and the count will be in NUM_P
			values = GetPRIMESRange(seed_p, num_sp, offset, 0, range, num_p);
		}

		if (num_witnesses > 0)
		{
			int pchar = 0;
			thread_soedata_t *thread_data;		//an array of thread data objects
			uint32 lastid;
			int j;

			//allocate thread data structure
			thread_data = (thread_soedata_t *)malloc(THREADS * sizeof(thread_soedata_t));
			
			// conduct PRP tests on all surviving values
			if (VFLAG > 0)
				printf("starting PRP tests with %d witnesses on %" PRIu64 " surviving candidates\n", 
					num_witnesses, *num_p);

			// start the threads
			for (i = 0; i < THREADS - 1; i++)
				start_soe_worker_thread(thread_data + i, 0);

			start_soe_worker_thread(thread_data + i, 1);

			range = *num_p / THREADS;
			lastid = 0;

			// divvy up the range
			for (j = 0; j < THREADS; j++)
			{
				thread_soedata_t *t = thread_data + j;
				
				t->startid = lastid;
				t->stopid = t->startid + range;
				lastid = t->stopid;

				if (VFLAG > 2)
					printf("thread %d computing PRPs from %u to %u\n", 
						(int)i, t->startid, t->stopid);
			}

			// the last one gets any leftover
			if (thread_data[THREADS-1].stopid != (uint32)*num_p)
				thread_data[THREADS-1].stopid = (uint32)*num_p;

			// allocate space for stuff in the threads
			if (THREADS == 1)
			{
				thread_data[0].ddata.primes = values;
			}
			else
			{
				for (j = 0; j < THREADS; j++)
				{
					thread_soedata_t *t = thread_data + j;

					mpz_init(t->tmpz);
					mpz_init(t->offset);
					mpz_init(t->lowlimit);
					mpz_init(t->highlimit);
					mpz_set(t->offset, *offset);
					mpz_set(t->lowlimit, lowlimit);
					mpz_set(t->highlimit, highlimit);
					t->current_line = (uint64)num_witnesses;

					t->ddata.primes = (uint64 *)malloc((t->stopid - t->startid) * sizeof(uint64));
					for (i = t->startid; i < t->stopid; i++)
						t->ddata.primes[i - t->startid] = values[i];
				}
			}

			// now run with the threads
			for (j = 0; j < THREADS; j++)
			{
				thread_soedata_t *t = thread_data + j;

				if (j == (THREADS - 1)) 
				{	
					t->linecount = 0;
					for (i = t->startid; i < t->stopid; i++)
					{
						if (((i & 128) == 0) && (VFLAG > 0))
						{
							int k;
							for (k = 0; k<pchar; k++)
								printf("\b");
							pchar = printf("progress: %d%%",(int)((double)i / (double)(*num_p) * 100.0));
							fflush(stdout);
						}

						mpz_add_ui(tmpz, *offset, t->ddata.primes[i - t->startid]);
						if ((mpz_cmp(tmpz, lowlimit) >= 0) && (mpz_cmp(highlimit, tmpz) >= 0))
						{
							if (mpz_probab_prime_p(tmpz, num_witnesses))
								t->ddata.primes[t->linecount++] = t->ddata.primes[i - t->startid];
						}
					}
				}
				else
				{
					t->command = SOE_COMPUTE_PRPS;

#if defined(WIN32) || defined(_WIN64)
					SetEvent(t->run_event);
#else
					pthread_cond_signal(&t->run_cond);
					pthread_mutex_unlock(&t->run_lock);
#endif

				}
			}

			//wait for each thread to finish
			for (i = 0; i < THREADS; i++) 
			{
				thread_soedata_t *t = thread_data + i;

				if (i < (THREADS - 1)) 
				{
#if defined(WIN32) || defined(_WIN64)
					WaitForSingleObject(t->finish_event, INFINITE);
#else
					pthread_mutex_lock(&t->run_lock);
					while (t->command != SOE_COMMAND_WAIT)
						pthread_cond_wait(&t->run_cond, &t->run_lock);
#endif
				}
			}

			//stop the worker threads
			for (i=0; i<THREADS - 1; i++)
				stop_soe_worker_thread(thread_data + i, 0);

			// combine results and free stuff
			if (THREADS == 1)
			{
				retval = thread_data[0].linecount;
			}
			else
			{
				retval = 0;
				for (i=0; i<THREADS; i++)
				{
					thread_soedata_t *t = thread_data + i;

					for (j=0; j < t->linecount; j++)
						values[retval++] = t->ddata.primes[j];

					free(t->ddata.primes);
					mpz_clear(t->tmpz);
					mpz_clear(t->offset);
					mpz_clear(t->lowlimit);
					mpz_clear(t->highlimit);
				}
			}

			free(thread_data);

			if (VFLAG > 0)
			{
				int k;
				for (k = 0; k<pchar; k++)
					printf("\b");
			}

			*num_p = retval;
			if (VFLAG > 0)
				printf("found %" PRIu64 " PRPs\n", *num_p);
			
		}

		// now dump the requested range of primes to a file, or the
		// screen, both, or neither, depending on the state of a couple
		// global configuration variables
		if (PRIMES_TO_FILE)
		{
			FILE *out;
			if (num_witnesses > 0)
				out = fopen("prp_values.dat", "w");
			else
				out = fopen("sieved_values.dat","w");

			if (out == NULL)
			{
				printf("fopen error: %s\n", strerror(errno));
				printf("can't open file for writing\n");
			}
			else
			{
				for (i = 0; i < *num_p; i++)
				{
					mpz_add_ui(tmpz, *offset, values[i]);
					if ((mpz_cmp(tmpz, lowlimit) >= 0) && (mpz_cmp(highlimit, tmpz) >= 0))
						gmp_fprintf(out,"%Zd\n",tmpz);
				}
				fclose(out);
			}
		}

		if (PRIMES_TO_SCREEN)
		{
			for (i = 0; i < *num_p; i++)
			{
				mpz_add_ui(tmpz, *offset, values[i]);
				if ((mpz_cmp(tmpz, lowlimit) >= 0) && (mpz_cmp(highlimit, tmpz) >= 0))
					gmp_printf("%Zd\n",tmpz);
			}
			printf("\n");
		}			
	}

	mpz_clear(tmpz);
	mpz_clear(*offset);
	free(offset);

	return values;
}
Exemplo n.º 7
0
int main(void)
{
    int i;
    flint_rand_t state;
    
    printf("init_set_readonly....");
    fflush(stdout);
    
    flint_randinit(state);

    /* Create some small fmpz integers, clear the mpz_t */
    for (i = 0; i < 100000; i++)
    {
        fmpz_t f;
        mpz_t z;

        *f = z_randint(state, COEFF_MAX + 1);

        mpz_init(z);
        fmpz_get_mpz(z, f);

        {
            fmpz_t g;

            fmpz_init_set_readonly(g, z);
            fmpz_clear_readonly(g);
        }

        mpz_clear(z);
    }

    /* Create some small fmpz integers, do *not* clear the mpz_t */
    for (i = 0; i < 100000; i++)
    {
        fmpz_t f;
        mpz_t z;

        *f = z_randint(state, COEFF_MAX + 1);

        mpz_init(z);
        fmpz_get_mpz(z, f);

        {
            fmpz_t g;

            fmpz_init_set_readonly(g, z);
        }

        mpz_clear(z);
    }

    /* Create some more fmpz integers */
    for (i = 0; i < 100000; i++)
    {
        fmpz_t f;
        mpz_t z;

        fmpz_init(f);
        fmpz_randtest(f, state, 2 * FLINT_BITS);
        mpz_init(z);
        fmpz_get_mpz(z, f);

        {
            fmpz_t g, h;

            fmpz_init_set_readonly(g, z);
            fmpz_init(h);
            fmpz_set_mpz(h, z);

            if (!fmpz_equal(g, h))
            {
                printf("FAIL:\n\n");
                printf("g = "), fmpz_print(g), printf("\n");
                printf("h = "), fmpz_print(h), printf("\n");
                gmp_printf("z = %Zd\n", z);
            }

            fmpz_clear_readonly(g);
            fmpz_clear(h);
        }

        fmpz_clear(f);
        mpz_clear(z);
    }

    flint_randclear(state);
    _fmpz_cleanup();
    printf("PASS\n");
    return 0;
}
Exemplo n.º 8
0
int
main(void)
{
    int i, result;
    FLINT_TEST_INIT(state);

    flint_printf("fdiv_qr....");
    fflush(stdout);

    

    for (i = 0; i < 10000 * flint_test_multiplier(); i++)
    {
        fmpz_t a, b, c, r;
        mpz_t d, e, f, g, h, s;
        slong j;


        fmpz_init(a);
        fmpz_init(b);
        fmpz_init(c);
        fmpz_init(r);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);
        mpz_init(g);
        mpz_init(h);
        mpz_init(s);

        fmpz_randbits(a, state, 1000);
        do { 
           fmpz_randbits(b, state, 500);
        } while(fmpz_is_zero(b));

        fmpz_get_mpz(d, a);
        fmpz_get_mpz(e, b);

        for (j = 1; j < 100; j++)
           fmpz_fdiv_qr(c, r, a, b);
        mpz_fdiv_qr(f, s, d, e);

        fmpz_get_mpz(g, c);
        fmpz_get_mpz(h, r);

        result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0);
        if (!result)
        {
            flint_printf("FAIL:\n");
            gmp_printf
                ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d,
                 e, f, g, h, s);
            abort();
        }

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(c);
        fmpz_clear(r);

        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
        mpz_clear(g);
        mpz_clear(h);
        mpz_clear(s);
    }

    /* Check aliasing of c and a */
    for (i = 0; i < 10000 * flint_test_multiplier(); i++)
    {
        fmpz_t a, b, c, r;
        mpz_t d, e, f, g, h, s;

        fmpz_init(a);
        fmpz_init(b);
        fmpz_init(c);
        fmpz_init(r);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);
        mpz_init(g);
        mpz_init(h);
        mpz_init(s);

        fmpz_randtest(a, state, 200);
        fmpz_randtest_not_zero(b, state, 200);

        fmpz_get_mpz(d, a);
        fmpz_get_mpz(e, b);

        fmpz_fdiv_qr(a, r, a, b);
        mpz_fdiv_qr(f, s, d, e);

        fmpz_get_mpz(g, a);
        fmpz_get_mpz(h, r);

        result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0);
        if (!result)
        {
            flint_printf("FAIL:\n");
            gmp_printf
                ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d,
                 e, f, g, h, s);
            abort();
        }

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(c);
        fmpz_clear(r);

        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
        mpz_clear(g);
        mpz_clear(h);
        mpz_clear(s);
    }

    /* Check aliasing of c and b */
    for (i = 0; i < 10000 * flint_test_multiplier(); i++)
    {
        fmpz_t a, b, c, r;
        mpz_t d, e, f, g, h, s;

        fmpz_init(a);
        fmpz_init(b);
        fmpz_init(c);
        fmpz_init(r);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);
        mpz_init(g);
        mpz_init(h);
        mpz_init(s);

        fmpz_randtest(a, state, 200);
        fmpz_randtest_not_zero(b, state, 200);

        fmpz_get_mpz(d, a);
        fmpz_get_mpz(e, b);

        fmpz_fdiv_qr(b, r, a, b);
        mpz_fdiv_qr(f, s, d, e);

        fmpz_get_mpz(g, b);
        fmpz_get_mpz(h, r);

        result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0);
        if (!result)
        {
            flint_printf("FAIL:\n");
            gmp_printf
                ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d,
                 e, f, g, h, s);
            abort();
        }

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(c);
        fmpz_clear(r);

        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
        mpz_clear(g);
        mpz_clear(h);
        mpz_clear(s);
    }

    /* Check aliasing of r and a */
    for (i = 0; i < 10000 * flint_test_multiplier(); i++)
    {
        fmpz_t a, b, c, r;
        mpz_t d, e, f, g, h, s;

        fmpz_init(a);
        fmpz_init(b);
        fmpz_init(c);
        fmpz_init(r);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);
        mpz_init(g);
        mpz_init(h);
        mpz_init(s);

        fmpz_randtest(a, state, 200);
        fmpz_randtest_not_zero(b, state, 200);

        fmpz_get_mpz(d, a);
        fmpz_get_mpz(e, b);

        fmpz_fdiv_qr(c, a, a, b);
        mpz_fdiv_qr(f, s, d, e);

        fmpz_get_mpz(g, c);
        fmpz_get_mpz(h, a);

        result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0);
        if (!result)
        {
            flint_printf("FAIL:\n");
            gmp_printf
                ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d,
                 e, f, g, h, s);
            abort();
        }

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(c);
        fmpz_clear(r);

        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
        mpz_clear(g);
        mpz_clear(h);
        mpz_clear(s);
    }

    /* Check aliasing of r and b */
    for (i = 0; i < 10000 * flint_test_multiplier(); i++)
    {
        fmpz_t a, b, c, r;
        mpz_t d, e, f, g, h, s;

        fmpz_init(a);
        fmpz_init(b);
        fmpz_init(c);
        fmpz_init(r);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);
        mpz_init(g);
        mpz_init(h);
        mpz_init(s);

        fmpz_randtest(a, state, 200);
        fmpz_randtest_not_zero(b, state, 200);

        fmpz_get_mpz(d, a);
        fmpz_get_mpz(e, b);

        fmpz_fdiv_qr(c, b, a, b);
        mpz_fdiv_qr(f, s, d, e);

        fmpz_get_mpz(g, c);
        fmpz_get_mpz(h, b);

        result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0);
        if (!result)
        {
            flint_printf("FAIL:\n");
            gmp_printf
                ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d,
                 e, f, g, h, s);
            abort();
        }

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(c);
        fmpz_clear(r);

        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
        mpz_clear(g);
        mpz_clear(h);
        mpz_clear(s);
    }

    FLINT_TEST_CLEANUP(state);
    
    flint_printf("PASS\n");
    return 0;
}
Exemplo n.º 9
0
void run_setup(int num_constraints, int num_inputs,
               int num_outputs, int num_vars, mpz_t p,
               string vkey_file, string pkey_file,
               string unprocessed_vkey_file) {

    std::ifstream Amat("./bin/" + std::string(NAME) + ".qap.matrix_a");
    std::ifstream Bmat("./bin/" + std::string(NAME) + ".qap.matrix_b");
    std::ifstream Cmat("./bin/" + std::string(NAME) + ".qap.matrix_c");

    libsnark::default_r1cs_gg_ppzksnark_pp::init_public_params();
    libsnark::r1cs_constraint_system<FieldT> q;

    int Ai, Aj, Bi, Bj, Ci, Cj;
    mpz_t  Acoef, Bcoef, Ccoef;
    mpz_init(Acoef);
    mpz_init(Bcoef);
    mpz_init(Ccoef);

    Amat >> Ai;
    Amat >> Aj;
    Amat >> Acoef;

    if (mpz_cmpabs(Acoef, p) > 0) {
        gmp_printf("WARNING: Coefficient larger than prime (%Zd > %Zd).\n", Acoef, p);
        mpz_mod(Acoef, Acoef, p);
    }
    if (mpz_sgn(Acoef) == -1) {
        mpz_add(Acoef, p, Acoef);
    }

    //    std::cout << Ai << " " << Aj << " " << Acoef << std::std::endl;

    Bmat >> Bi;
    Bmat >> Bj;
    Bmat >> Bcoef;
    if (mpz_cmpabs(Bcoef, p) > 0) {
        gmp_printf("WARNING: Coefficient larger than prime (%Zd > %Zd).\n", Bcoef, p);
        mpz_mod(Bcoef, Bcoef, p);
    }
    if (mpz_sgn(Bcoef) == -1) {
        mpz_add(Bcoef, p, Bcoef);
    }

    Cmat >> Ci;
    Cmat >> Cj;
    Cmat >> Ccoef;

    if (mpz_cmpabs(Ccoef, p) > 0) {
        gmp_printf("WARNING: Coefficient larger than prime (%Zd > %Zd).\n", Ccoef, p);
        mpz_mod(Ccoef, Ccoef, p);
    }
    if (mpz_sgn(Ccoef) == -1) {
        mpz_mul_si(Ccoef, Ccoef, -1);
    } else if(mpz_sgn(Ccoef) == 1) {
        mpz_mul_si(Ccoef, Ccoef, -1);
        mpz_add(Ccoef, p, Ccoef);
    }

    int num_intermediate_vars = num_vars;
    int num_inputs_outputs = num_inputs + num_outputs;

    q.primary_input_size = num_inputs_outputs;
    q.auxiliary_input_size = num_intermediate_vars;

    for (int currentconstraint = 1; currentconstraint <= num_constraints; currentconstraint++) {
        libsnark::linear_combination<FieldT> A, B, C;

        while(Aj == currentconstraint && Amat) {
            if (Ai <= num_intermediate_vars && Ai != 0) {
                Ai += num_inputs_outputs;
            } else if (Ai > num_intermediate_vars) {
                Ai -= num_intermediate_vars;
            }

            FieldT AcoefT(Acoef);
            A.add_term(Ai, AcoefT);
            if(!Amat) {
                break;
            }
            Amat >> Ai;
            Amat >> Aj;
            Amat >> Acoef;
            if (mpz_cmpabs(Acoef, p) > 0) {
                gmp_printf("WARNING: Coefficient larger than prime (%Zd > %Zd).\n", Acoef, p);
                mpz_mod(Acoef, Acoef, p);
            }
            if (mpz_sgn(Acoef) == -1) {
                mpz_add(Acoef, p, Acoef);
            }
        }

        while(Bj == currentconstraint && Bmat) {
            if (Bi <= num_intermediate_vars && Bi != 0) {
                Bi += num_inputs_outputs;
            } else if (Bi > num_intermediate_vars) {
                Bi -= num_intermediate_vars;
            }
            //         std::cout << Bi << " " << Bj << " " << Bcoef << std::std::endl;
            FieldT BcoefT(Bcoef);
            B.add_term(Bi, BcoefT);
            if (!Bmat) {
                break;
            }
            Bmat >> Bi;
            Bmat >> Bj;
            Bmat >> Bcoef;
            if (mpz_cmpabs(Bcoef, p) > 0) {
                gmp_printf("WARNING: Coefficient larger than prime (%Zd > %Zd).\n", Bcoef, p);
                mpz_mod(Bcoef, Bcoef, p);
            }
            if (mpz_sgn(Bcoef) == -1) {
                mpz_add(Bcoef, p, Bcoef);
            }
        }

        while(Cj == currentconstraint && Cmat) {
            if (Ci <= num_intermediate_vars && Ci != 0) {
                Ci += num_inputs_outputs;
            } else if (Ci > num_intermediate_vars) {
                Ci -= num_intermediate_vars;
            }
            //Libsnark constraints are A*B = C, vs. A*B - C = 0 for Zaatar.
            //Which is why the C coefficient is negated.

            // std::cout << Ci << " " << Cj << " " << Ccoef << std::std::endl;
            FieldT CcoefT(Ccoef);
            C.add_term(Ci, CcoefT);
            if (!Cmat) {
                break;
            }
            Cmat >> Ci;
            Cmat >> Cj;
            Cmat >> Ccoef;
            if (mpz_cmpabs(Ccoef, p) > 0) {
                gmp_printf("WARNING: Coefficient larger than prime (%Zd > %Zd).\n", Ccoef, p);
                mpz_mod(Ccoef, Ccoef, p);
            }
            if (mpz_sgn(Ccoef) == -1) {
                mpz_mul_si(Ccoef, Ccoef, -1);
            } else if (mpz_sgn(Ccoef) == 1) {
                mpz_mul_si(Ccoef, Ccoef, -1);
                mpz_add(Ccoef, p, Ccoef);
            }
        }

        q.add_constraint(libsnark::r1cs_constraint<FieldT>(A, B, C));

        //dump_constraint(r1cs_constraint<FieldT>(A, B, C), va, variable_annotations);
    }

    Amat.close();
    Bmat.close();
    Cmat.close();

    libff::start_profiling();
    libsnark::r1cs_gg_ppzksnark_keypair<libsnark::default_r1cs_gg_ppzksnark_pp> keypair = libsnark::r1cs_gg_ppzksnark_generator<libsnark::default_r1cs_gg_ppzksnark_pp>(q);
    libsnark::r1cs_gg_ppzksnark_processed_verification_key<libsnark::default_r1cs_gg_ppzksnark_pp> pvk = libsnark::r1cs_gg_ppzksnark_verifier_process_vk<libsnark::default_r1cs_gg_ppzksnark_pp>(keypair.vk);


    std::ofstream vkey(vkey_file);
    std::ofstream pkey(pkey_file);

    vkey << pvk;
    pkey << keypair.pk;
    pkey.close(); vkey.close();

    if (unprocessed_vkey_file.length() > 0) {
        std::ofstream unprocessed_vkey(unprocessed_vkey_file);
        unprocessed_vkey << keypair.vk;
        unprocessed_vkey.close();
    }
}
Exemplo n.º 10
0
int quadratic_residue(mpz_t x,mpz_t q,mpz_t n)
{
    int                        leg;
    mpz_t                        tmp,ofac,nr,t,r,c,b;
    unsigned int            mod4;
    mp_bitcnt_t                twofac=0,m,i,ix;

    mod4=mpz_tstbit(n,0);
    if(!mod4) // must be odd
        return 0;

    mod4+=2*mpz_tstbit(n,1);

    leg=mpz_legendre(q,n);
    if(leg!=1)
        return leg;

    mpz_init_set(tmp,n);
	
    if(mod4==3) // directly, x = q^(n+1)/4 mod n
        {
	printf("diretamente\n\n");
        mpz_add_ui(tmp,tmp,1UL);
        mpz_tdiv_q_2exp(tmp,tmp,2);
        mpz_powm(x,q,tmp,n);
	gmp_printf("NUMERO X %Zd \n\n",x);
        mpz_clear(tmp);
        }
    else // Tonelli-Shanks
        {
	printf("Tonelli shanks!!!\n");
        mpz_inits(ofac,t,r,c,b,NULL);

        // split n - 1 into odd number times power of 2 ofac*2^twofac
        mpz_sub_ui(tmp,tmp,1UL);
        twofac=mpz_scan1(tmp,twofac); // largest power of 2 divisor
        if(twofac)
            mpz_tdiv_q_2exp(ofac,tmp,twofac); // shift right

        // look for non-residue
        mpz_init_set_ui(nr,2UL);
        while(mpz_legendre(nr,n)!=-1)
            mpz_add_ui(nr,nr,1UL);

        mpz_powm(c,nr,ofac,n); // c = nr^ofac mod n

        mpz_add_ui(tmp,ofac,1UL);
        mpz_tdiv_q_2exp(tmp,tmp,1);
        mpz_powm(r,q,tmp,n); // r = q^(ofac+1)/2 mod n

        mpz_powm(t,q,ofac,n);
        mpz_mod(t,t,n); // t = q^ofac mod n

        if(mpz_cmp_ui(t,1UL)!=0) // if t = 1 mod n we're done
            {
            m=twofac;
            do
                {
                i=2;
                ix=1;
                while(ix<m)
                    {
                    // find lowest 0 < ix < m | t^2^ix = 1 mod n
                    mpz_powm_ui(tmp,t,i,n); // repeatedly square t
                    if(mpz_cmp_ui(tmp,1UL)==0)
                        break;
                    i<<=1; // i = 2, 4, 8, ...
                    ix++; // ix is log2 i
                    }
                mpz_powm_ui(b,c,1<<(m-ix-1),n); // b = c^2^(m-ix-1) mod n
                mpz_mul(r,r,b);
                mpz_mod(r,r,n); // r = r*b mod n
                mpz_mul(c,b,b);
                mpz_mod(c,c,n); // c = b^2 mod n
                mpz_mul(t,t,c);
                mpz_mod(t,t,n); // t = t b^2 mod n
                m=ix;
                }while(mpz_cmp_ui(t,1UL)!=0); // while t mod n != 1
            }
        mpz_set(x,r);
        mpz_clears(tmp,ofac,nr,t,r,c,b,NULL);
        }

    return 1;
}
Exemplo n.º 11
0
/*==========================================================================
   evaluateSieve:

   Function: searches sieve for relations and sticks them into a matrix, then
             sticks their X and Y values into two arrays XArr and YArr

===========================================================================*/
static void evaluateSieve(
    unsigned long numPrimes,
    unsigned long Mdiv2,
    unsigned long * relations,
    unsigned long ctimesreps,
    unsigned long M,
    unsigned char * sieve,
    mpz_t A,
    mpz_t B,
    mpz_t C,
    unsigned long * soln1,
    unsigned long * soln2,
    unsigned char * flags,
    matrix_t m,
    mpz_t * XArr,
    unsigned long * aind,
    int min,
    int s,
    int * exponents,
    unsigned long * npartials,
    unsigned long * nrelsfound,
    unsigned long * nrelssought,
    mpz_t temp,
    mpz_t temp2,
    mpz_t temp3,
    mpz_t res)
{
     long i,j,ii;
     unsigned int k;
     unsigned int exponent, vv;
     unsigned char extra;
     unsigned int modp;
     unsigned long * sieve2;
     unsigned char bits;
     int numfactors;
     unsigned long relsFound = *nrelsfound;
     unsigned long relSought = *nrelssought;

     mpz_set_ui(temp, 0);
     mpz_set_ui(temp2, 0);
     mpz_set_ui(temp3, 0);
     mpz_set_ui(res, 0);
     i = 0;
     j = 0;
     sieve2 = (unsigned long *) sieve;
#ifdef POLS
     gmp_printf("%Zdx^2%+Zdx\n%+Zd\n",A,B,C);
#endif

     while ( (unsigned long)j < M/sizeof(unsigned long))
     {
        do
        {
           while (!(sieve2[j] & SIEVEMASK)) j++;
           i = j * sizeof(unsigned long);
           j++;
           while (((unsigned long)i < j*sizeof(unsigned long)) && (sieve[i] < threshold)) i++;
        } while (sieve[i] < threshold);

        if (((unsigned long)i<M) && (relsFound < relSought))
        {
           mpz_set_ui(temp,i+ctimesreps);
           mpz_sub_ui(temp, temp, Mdiv2); /* X         */

           mpz_set(temp3, B);             /* B          */
           mpz_addmul(temp3, A, temp);    /* AX+B       */
           mpz_add(temp2, temp3, B);      /* AX+2B      */
           mpz_mul(temp2, temp2, temp);   /* AX^2+2BX   */
           mpz_add(res, temp2, C);        /* AX^2+2BX+C */

           bits = mpz_sizeinbase(res,2) - errorbits;

           numfactors=0;
           extra = 0;
           memset(exponents, 0, firstprime * sizeof(int));

           if (factorBase[0] != 1 && mpz_divisible_ui_p(res, factorBase[0]))
           {
             extra += primeSizes[0];
             if (factorBase[0] == 2) {
                exponent = mpz_scan1(res, 0);
                mpz_tdiv_q_2exp(res, res, exponent);
             } else {
               mpz_set_ui(temp,factorBase[0]);
               exponent = mpz_remove(res,res,temp);
             }
             exponents[0] = exponent;
           }

           exponents[1] = 0;
           if (mpz_divisible_ui_p(res, factorBase[1]))
           {
             extra += primeSizes[1];
             if (factorBase[1] == 2) {
                exponent = mpz_scan1(res, 0);
                mpz_tdiv_q_2exp(res, res, exponent);
             } else {
               mpz_set_ui(temp,factorBase[1]);
               exponent = mpz_remove(res,res,temp);
             }
             exponents[1] = exponent;
           }

           for (k = 2; k < firstprime; k++)
           {
              modp=(i+ctimesreps)%factorBase[k];

              exponents[k] = 0;
              if (soln2[k] != (unsigned long)-1)
              {
                 if ((modp==soln1[k]) || (modp==soln2[k]))
                 {
                    extra+=primeSizes[k];
                    mpz_set_ui(temp,factorBase[k]);
                    exponent = mpz_remove(res,res,temp);
                    CHECK_EXPONENT(exponent, k);
                    PRINT_FB(exponent, k);
                    exponents[k] = exponent;
                 }
              } else if (mpz_divisible_ui_p(res, factorBase[k]))
              {
                 extra += primeSizes[k];
                 mpz_set_ui(temp,factorBase[k]);
                 exponent = mpz_remove(res,res,temp);
                 PRINT_FB(exponent, k);
                 exponents[k] = exponent;
              }
           }
           sieve[i]+=extra;
           if (sieve[i] >= bits)
           {
              vv=((unsigned char)1<<(i&7));
              for (k = firstprime; (k<secondprime)&&(extra<sieve[i]); k++)
              {
                 modp=(i+ctimesreps)%factorBase[k];
                 if (soln2[k] != (unsigned long)-1)
                 {
                    if ((modp==soln1[k]) || (modp==soln2[k]))
                    {
                       extra+=primeSizes[k];
                       mpz_set_ui(temp,factorBase[k]);
                       exponent = mpz_remove(res,res,temp);
                       CHECK_EXPONENT(exponent, k);
                       PRINT_FB(exponent, k);
                       if (exponent)
                         for (ii = 0; ii < (long)exponent; ii++)
                           set_relation(relations, relsFound, ++numfactors, k);
                       if (exponent & 1)
                         insertEntry(m,relsFound,k);
                    }
                 } else if (mpz_divisible_ui_p(res, factorBase[k]))
                 {
                    extra += primeSizes[k];
                    mpz_set_ui(temp,factorBase[k]);
                    exponent = mpz_remove(res,res,temp);
                    PRINT_FB(exponent, k);
                    for (ii = 0; ii < (long)exponent; ii++)
                      set_relation(relations, relsFound, ++numfactors, k);
                    if (exponent & 1)
                      insertEntry(m,relsFound,k);
                 }
              }


              for (k = secondprime; (k<numPrimes)&&(extra<sieve[i]); k++)
              {
                 if (flags[k]&vv)
                 {
                    modp=(i+ctimesreps)%factorBase[k];
                    if ((modp==soln1[k]) || (modp==soln2[k]))
                    {
                       extra+=primeSizes[k];
                       mpz_set_ui(temp,factorBase[k]);
                       exponent = mpz_remove(res,res,temp);
                       CHECK_EXPONENT(exponent, k);
                       PRINT_FB(exponent, k);
                       if (exponent)
                         for (ii = 0; ii < (long)exponent; ii++)
                           set_relation(relations, relsFound, ++numfactors, k);
                       if (exponent & 1)
                         insertEntry(m,relsFound,k);
                    }
                 }
              }

              for (ii =0; ii<s; ii++)
              {
                 xorEntry(m,relsFound,aind[ii]+min);
                 set_relation(relations, relsFound, ++numfactors, aind[ii]+min);
              }

              if (mpz_cmp_ui(res,1000)>0)
              {
                 if (mpz_cmp_ui(res,largeprime)<0)
                 {
                    (*npartials)++;
                 }
                 clearRow(m,numPrimes,relsFound);
#ifdef RELPRINT
                 gmp_printf(" %Zd\n",res);
#endif
              } else
              {
                 mpz_neg(res,res);
                 if (mpz_cmp_ui(res,1000)>0)
                 {
                    if (mpz_cmp_ui(res,largeprime)<0)
                    {
                       (*npartials)++;
                    }
                    clearRow(m,numPrimes,relsFound);
#ifdef RELPRINT
                    gmp_printf(" %Zd\n",res);
#endif
                 } else
                 {
#ifdef RELPRINT
                    printf("....R\n");
#endif
                    for (ii = 0; ii < (long)firstprime; ii++)
                    {
                       int jj;
                       for (jj = 0; jj < exponents[ii]; jj++)
                         set_relation(relations, relsFound, ++numfactors, ii);
                       if (exponents[ii] & 1)
                         insertEntry(m,relsFound,ii);
                    }
                    set_relation(relations, relsFound, 0, numfactors);

                    mpz_init_set(XArr[relsFound], temp3);  /* (AX+B) */

                    relsFound++;
#ifdef COUNT
                    if (relsFound%20==0) fprintf(stderr,"%lu relations, %lu partials.\n", relsFound, *npartials);
#endif
                 }
              }
           } else
           {
              clearRow(m,numPrimes,relsFound);
#ifdef RELPRINT
              printf("\r                                                                    \r");
#endif

           }
           i++;

        } else if (relsFound >= relSought) i++;
     }
     /* Update caller */
     *nrelsfound = relsFound;
     *nrelssought = relSought;
}
Exemplo n.º 12
0
Arquivo: app.c Projeto: jamella/copri
// The generic `main` function.
//
// Define all variables at the beginning to make the C99 compiler
// happy.
int main(int argc, char **argv) {
	mpz_array s, p, out;
	size_t count, i;
	int c, vflg = 0, sflg = 0, rflg = 0, errflg = 0, r = 0;
	char *filename = "primes.lst";

	// #### argument parsing
	// Boring `getopt` argument parsing.
	while ((c = getopt(argc, argv, ":svr")) != -1) {
		switch(c) {
		case 's':
			sflg++;
			break;
		case 'v':
			vflg++;
			break;
		case 'r':
			rflg++;
			break;
		case ':':
			fprintf(stderr, "Option -%c requires an operand\n", optopt);
			errflg++;
			break;
		case '?':
			fprintf(stderr, "Unrecognized option: '-%c'\n", optopt);
			errflg++;
		}
	}

	if (optind < argc) {
		filename = argv[optind];
		if (optind + 1 < argc) errflg++;
	}

	if (rflg && vflg) {
		fprintf(stderr, "\n\t-r and -v can't be used simultaneously!\n\n");
		errflg++;
	}

	// Print the usage and exit if an error occurred during argument parsing.
	if (errflg) {
		fprintf(stderr, "usage: [-vsr] [file]\n"\
                        "\n\t-v        be more verbose"\
                        "\n\t-r        output the found coprimes in raw gmp format"\
                        "\n\t-s        only check if there are coprimes"\
                        "\n\n");
		exit(2);
	}

	// Print the banner.
	if (vflg > 0) {
		PRINT_BANNER;
	}

	// Load the keys.
	array_init(&s, 10);
	count = array_of_file(&s, filename);
	if (count == 0) {
		fprintf(stderr, "Can't load %s\n", filename);
		return 1;
	}
	if (s.used != count) {
		fprintf(stderr, "Array size and load count do not match\n");
		return 2;
	}
	if (s.used == 0) {
		fprintf(stderr, "No primes loaded (empty file)\n");
		return 3;
	}
	// Print the key count.
	if (vflg > 0) {
		printf("%zu public keys loaded\nStarting factorization...\n", s.used);
	}


	// Computing a coprime base for a finite set [Algorithm 18.1](copri.html#computing-a-coprime-base-for-a-finite-set).
	array_init(&p, 10);
	array_cb(&p, &s);

	// Check if we have found more coprime bases.
	if (p.used == s.used) {
		if (vflg > 0)
			printf("No coprime pairs found :-(\n");
		r = 1;
	} else {
		if (vflg > 0 || sflg > 0)
			printf("Found ~%zu coprime pairs!!!\nSearching factors...\n", (p.used - s.used));
		if (sflg == 0) {
			array_init(&out, 9);
			// Use [Algorithm 21.2](copri.html#factoring-a-set-over-a-coprime-base) to find the coprimes in the coprime base.
			array_find_factors(&out, &s, &p);

			// Output the factors.
			if (out.used > 0) {
				if ((out.used % 3) != 0) {
					fprintf(stderr, "Find factors returned an invalid array\n");
				} else {
					if (rflg) {
						for(i = 0; i < out.used; i++)
							mpz_out_raw(stdout, out.array[i]);
					} else {
						for(i = 0; i < out.used; i+=3)
							gmp_printf("\n### Found factors of\n%Zu\n=\n%Zu\nx\n%Zu\n", out.array[i], out.array[i+1], out.array[i+2]);
					}
				}
			}
			array_clear(&out);
		}
	}

	array_clear(&p);
	array_clear(&s);

	return r;
}
Exemplo n.º 13
0
/* Recursive routine to prove via ECPP */
static int ecpp_down(int i, mpz_t Ni, int facstage, int *pmaxH, int* dilist, mpz_t* sfacs, int* nsfacs, char** prooftextptr)
{
  mpz_t a, b, u, v, m, q, minfactor, sqrtn, mD, t, t2;
  mpz_t mlist[6];
  mpz_t qlist[6];
  UV nm1a;
  IV np1lp, np1lq;
  struct ec_affine_point P;
  int k, dindex, pindex, nidigits, facresult, curveresult, downresult, stage, D;
  int verbose = get_verbose_level();

  nidigits = mpz_sizeinbase(Ni, 10);

  downresult = _GMP_is_prob_prime(Ni);
  if (downresult == 0)  return 0;
  if (downresult == 2) {
    if (mpz_sizeinbase(Ni,2) <= 64) {
      /* No need to put anything in the proof */
      if (verbose) printf("%*sN[%d] (%d dig)  PRIME\n", i, "", i, nidigits);
      return 2;
    }
    downresult = 1;
  }
  if (i == 0 && facstage == 2 && miller_rabin_random(Ni, 2, 0) == 0) {
    gmp_printf("\n\n**** BPSW counter-example found?  ****\n**** N = %Zd ****\n\n", Ni);
    return 0;
  }

  VERBOSE_PRINT_N(i, nidigits, *pmaxH, facstage);

  mpz_init(a);  mpz_init(b);
  mpz_init(u);  mpz_init(v);
  mpz_init(m);  mpz_init(q);
  mpz_init(mD); mpz_init(minfactor);  mpz_init(sqrtn);
  mpz_init(t);  mpz_init(t2);
  mpz_init(P.x);mpz_init(P.y);
  for (k = 0; k < 6; k++) {
    mpz_init(mlist[k]);
    mpz_init(qlist[k]);
  }

  /* Any factors q found must be strictly > minfactor.
   * See Atkin and Morain, 1992, section 6.4 */
  mpz_root(minfactor, Ni, 4);
  mpz_add_ui(minfactor, minfactor, 1);
  mpz_mul(minfactor, minfactor, minfactor);
  mpz_sqrt(sqrtn, Ni);

  stage = 0;
  if (nidigits > 700) stage = 1;  /* Too rare to find them */
  if (i == 0 && facstage > 1)  stage = facstage;
  for ( ; stage <= facstage; stage++) {
    int next_stage = (stage > 1) ? stage : 1;
    for (dindex = -1; dindex < 0 || dilist[dindex] != 0; dindex++) {
      int poly_type;  /* just for debugging/verbose */
      int poly_degree;
      int allq = (nidigits < 400);  /* Do all q values together, or not */

      if (dindex == -1) {   /* n-1 and n+1 tests */
        int nm1_success = 0;
        int np1_success = 0;
        const char* ptype = "";
        mpz_sub_ui(m, Ni, 1);
        mpz_sub_ui(t2, sqrtn, 1);
        mpz_tdiv_q_2exp(t2, t2, 1);    /* t2 = minfactor */
        nm1_success = check_for_factor(u, m, t2, t, stage, sfacs, nsfacs, 0);
        mpz_add_ui(m, Ni, 1);
        mpz_add_ui(t2, sqrtn, 1);
        mpz_tdiv_q_2exp(t2, t2, 1);    /* t2 = minfactor */
        np1_success = check_for_factor(v, m, t2, t, stage, sfacs, nsfacs, 0);
        /* If both successful, pick smallest */
        if (nm1_success > 0 && np1_success > 0) {
          if (mpz_cmp(u, v) <= 0) np1_success = 0;
          else                    nm1_success = 0;
        }
        if      (nm1_success > 0) {  ptype = "n-1";  mpz_set(q, u);  D =  1; }
        else if (np1_success > 0) {  ptype = "n+1";  mpz_set(q, v);  D = -1; }
        else                      continue;
        if (verbose) { printf(" %s\n", ptype); fflush(stdout); }
        downresult = ecpp_down(i+1, q, next_stage, pmaxH, dilist, sfacs, nsfacs, prooftextptr);
        if (downresult == 0) goto end_down;   /* composite */
        if (downresult == 1) {   /* nothing found at this stage */
          VERBOSE_PRINT_N(i, nidigits, *pmaxH, facstage);
          continue;
        }
        if (verbose)
          { printf("%*sN[%d] (%d dig) %s", i, "", i, nidigits, ptype); fflush(stdout); }
        curveresult = (nm1_success > 0)
                    ? _GMP_primality_bls_3(Ni, q, &nm1a)
                    : _GMP_primality_bls_15(Ni, q, &np1lp, &np1lq);
        if (verbose) { printf("  %d\n", curveresult); fflush(stdout); }
        if ( ! curveresult ) { /* This ought not happen */
          if (verbose)
            gmp_printf("\n  Could not prove %s with N = %Zd\n", ptype, Ni);
          downresult = 1;
          continue;
        }
        goto end_down;
      }

      pindex = dilist[dindex];
      if (pindex < 0) continue;  /* We marked this for skip */
      /* Get the values for D, degree, and poly type */
      poly_degree = poly_class_poly_num(pindex, &D, NULL, &poly_type);
      if (poly_degree == 0)
        croak("Unknown value in dilist[%d]: %d\n", dindex, pindex);

      if ( (-D % 4) != 3 && (-D % 16) != 4 && (-D % 16) != 8 )
        croak("Invalid discriminant '%d' in list\n", D);
      /* D must also be squarefree in odd divisors, but assume it. */
      /* Make sure we can get a class polynomial for this D. */
      if (poly_degree > 16 && stage == 0) {
        if (verbose) printf(" [1]");
        break;
      }
      /* Make the continue-search vs. backtrack decision */
      if (*pmaxH > 0 && poly_degree > *pmaxH)  break;
      mpz_set_si(mD, D);
      /* (D/N) must be 1, and we have to have a u,v solution */
      if (mpz_jacobi(mD, Ni) != 1)
        continue;
      if ( ! modified_cornacchia(u, v, mD, Ni) )
        continue;

      if (verbose > 1)
        { printf(" %d", D); fflush(stdout); }

      /* We're going to factor all the values for this discriminant then pick
       * the smallest.  This adds a little time, but it means we go down
       * faster.  This makes smaller proofs, and might even save time. */

      choose_m(mlist, D, u, v, Ni, t, t2);
      if (allq) {
        int x, y;
        /* We have 0 to 6 m values.  Try to factor them, put in qlist. */
        for (k = 0; k < 6; k++) {
          mpz_set_ui(qlist[k], 0);
          if (mpz_sgn(mlist[k])) {
            facresult = check_for_factor(qlist[k], mlist[k], minfactor, t, stage, sfacs, nsfacs, poly_degree);
            /* -1 = couldn't find, 0 = no big factors, 1 = found */
            if (facresult <= 0)
              mpz_set_ui(qlist[k], 0);
          }
        }
        /* Sort any q values by size, so we work on the smallest first */
        for (x = 0; x < 5; x++)
          if (mpz_sgn(qlist[x]))
            for (y = x+1; y < 6; y++)
              if (mpz_sgn(qlist[y]) && mpz_cmp(qlist[x],qlist[y]) > 0) {
                mpz_swap( qlist[x], qlist[y] );
                mpz_swap( mlist[x], mlist[y] );
              }
      }
      /* Try to make a proof with the first (smallest) q value.
       * Repeat for others if we have to. */
      for (k = 0; k < 6; k++) {
        int maxH = *pmaxH;
        int minH = (nidigits <= 240) ? 7 : (nidigits+39)/40;

        if (allq) {
          if (mpz_sgn(qlist[k]) == 0) continue;
          mpz_set(m, mlist[k]);
          mpz_set(q, qlist[k]);
        } else {
          if (mpz_sgn(mlist[k]) == 0) continue;
          mpz_set(m, mlist[k]);
          facresult = check_for_factor(q, m, minfactor, t, stage, sfacs, nsfacs, poly_degree);
          if (facresult <= 0) continue;
        }

        if (verbose)
          { printf(" %d (%s %d)\n", D, poly_class_type_name(poly_type), poly_degree); fflush(stdout); }
        if (maxH == 0) {
          maxH = minH-1 + poly_degree;
          if (facstage > 1)              /* We worked hard to get here, */
            maxH = 2*maxH + 10;          /* try hard to make use of it. */
        } else if (maxH > minH && maxH > (poly_degree+2)) {
          maxH--;
        }
        /* Great, now go down. */
        downresult = ecpp_down(i+1, q, next_stage, &maxH, dilist, sfacs, nsfacs, prooftextptr);
        /* Nothing found, look at more polys in the future */
        if (downresult == 1 && *pmaxH > 0)  *pmaxH = maxH;

        if (downresult == 0) goto end_down;   /* composite */
        if (downresult == 1) {   /* nothing found at this stage */
          VERBOSE_PRINT_N(i, nidigits, *pmaxH, facstage);
          continue;
        }

        /* Awesome, we found the q chain and are in STAGE 2 */
        if (verbose)
          { printf("%*sN[%d] (%d dig) %d (%s %d)", i, "", i, nidigits, D, poly_class_type_name(poly_type), poly_degree); fflush(stdout); }

        /* Try with only one or two roots, then 8 if that didn't work. */
        /* TODO: This should be done using a root iterator in find_curve() */
        curveresult = find_curve(a, b, P.x, P.y, D, pindex, m, q, Ni, 1);
        if (curveresult == 1) {
          if (verbose) { printf(" [redo roots]"); fflush(stdout); }
          curveresult = find_curve(a, b, P.x, P.y, D, pindex, m, q, Ni, 8);
        }
        if (verbose) { printf("  %d\n", curveresult); fflush(stdout); }
        if (curveresult == 1) {
          /* Something is wrong.  Very likely the class poly coefficients are
             incorrect.  We've wasted lots of time, and need to try again. */
          dilist[dindex] = -2; /* skip this D value from now on */
          if (verbose) gmp_printf("\n  Invalidated D = %d with N = %Zd\n", D, Ni);
          downresult = 1;
          continue;
        }
        /* We found it was composite or proved it */
        goto end_down;
      } /* k loop for D */
    } /* D */
  } /* fac stage */
  /* Nothing at this level */
  if (downresult != 1) croak("ECPP internal error: downresult is %d at end\n", downresult);
  if (verbose) {
    if (*pmaxH > 0) printf(" (max %d)", *pmaxH);
    printf(" ---\n");
    fflush(stdout);
  }
  if (*pmaxH > 0) *pmaxH = *pmaxH + 2;

end_down:

  if (downresult == 2) {
    if (0 && verbose > 1) {
      gmp_printf("\n");
      if (D == 1) {
        gmp_printf("Type BLS3\nN  %Zd\nQ  %Zd\nA  %"UVuf"\n", Ni, q, nm1a);
      } else if (D == -1) {
        gmp_printf("Type BLS15\nN  %Zd\nQ  %Zd\nLP %"IVdf"\nLQ %"IVdf"\n", Ni, q, np1lp, np1lq);
      } else {
        gmp_printf("Type ECPP\nN  %Zd\nA  %Zd\nB  %Zd\nM  %Zd\nQ  %Zd\nX  %Zd\nY  %Zd\n", Ni, a, b, m, q, P.x, P.y);
      }
      gmp_printf("\n");
      fflush(stdout);
    }
    /* Prepend our proof to anything that exists. */
    if (prooftextptr != 0) {
      char *proofstr, *proofptr;
      int curprooflen = (*prooftextptr == 0) ? 0 : strlen(*prooftextptr);

      if (D == 1) {
        int myprooflen = 20 + 2*(4 + mpz_sizeinbase(Ni, 10)) + 1*21;
        New(0, proofstr, myprooflen + curprooflen + 1, char);
        proofptr = proofstr;
        proofptr += gmp_sprintf(proofptr, "Type BLS3\nN  %Zd\nQ  %Zd\n", Ni,q);
        proofptr += sprintf(proofptr, "A  %"UVuf"\n", nm1a);
      } else if (D == -1) {
Exemplo n.º 14
0
static int check_for_factor(mpz_t f, mpz_t inputn, mpz_t fmin, mpz_t n, int stage, mpz_t* sfacs, int* nsfacs, int degree)
{
  int success, sfaci;
  UV B1;

  /* Use this so we don't modify their input value */
  mpz_set(n, inputn);

  if (mpz_cmp(n, fmin) <= 0) return 0;

#if 0
  /* Use this to really encourage n-1 / n+1 proof types */
  if (degree <= 0) {
    if (stage == 1) return -1;
    if (stage == 0) stage = 1;
  }
#endif

  /* Utilize GMP's fast gcd algorithms.  Trial to 224737+ with two gcds. */
  mpz_tdiv_q_2exp(n, n, mpz_scan1(n, 0));
  while (mpz_divisible_ui_p(n, 3))  mpz_divexact_ui(n, n, 3);
  while (mpz_divisible_ui_p(n, 5))  mpz_divexact_ui(n, n, 5);
  if (mpz_cmp(n, fmin) <= 0) return 0;
  mpz_gcd(f, n, _gcd_small);
  while (mpz_cmp_ui(f, 1) > 0) {
    mpz_divexact(n, n, f);
    mpz_gcd(f, f, n);
  }
  if (mpz_cmp(n, fmin) <= 0) return 0;
  mpz_gcd(f, n, _gcd_large);
  while (mpz_cmp_ui(f, 1) > 0) {
    mpz_divexact(n, n, f);
    mpz_gcd(f, f, n);
  }

  sfaci = 0;
  success = 1;
  while (success) {
    UV nsize = mpz_sizeinbase(n, 2);
    const int do_pm1 = 1;
    const int do_pp1 = 1;
    const int do_pbr = 0;
    const int do_ecm = 0;

    if (mpz_cmp(n, fmin) <= 0) return 0;
    if (is_bpsw_prime(n)) { mpz_set(f, n); return (mpz_cmp(f, fmin) > 0); }

    success = 0;
    B1 = 300 + 3 * nsize;
    if (degree <= 2) B1 += nsize;             /* D1 & D2 are cheap to prove. */
    if (degree <= 0) B1 += 2*nsize;         /* N-1 and N+1 are really cheap. */
    if (degree > 20 && stage <= 1) B1 -= nsize;   /* Less time on big polys. */
    if (degree > 40) B1 -= nsize/2;               /* Less time on big polys. */
    if (stage == 0) {
      /* A relatively small performance hit, makes slightly smaller proofs. */
      if (nsize < 900 && degree <= 2) B1 *= 1.8;
      /* We need to try a bit harder for the large sizes :( */
      if (nsize > 1400)  B1 *= 2;
      if (nsize > 2000)  B1 *= 2;
      if (!success)
        success = _GMP_pminus1_factor(n, f, 100+B1/8, 100+B1);
    } else if (stage >= 1) {
      /* P-1 */
      if ((!success && do_pm1))
        success = _GMP_pminus1_factor(n, f, B1, 6*B1);
      /* Pollard's Rho */
      if ((!success && do_pbr && nsize < 500))
        success = _GMP_pbrent_factor(n, f, nsize % 53, 1000-nsize);
      /* P+1 */
      if ((!success && do_pp1)) {
        UV ppB = (nsize < 2000) ? B1/4 : B1/16;
        success = _GMP_pplus1_factor(n, f, 0, ppB, ppB);
      }
      if ((!success && do_ecm))
        success = _GMP_ecm_factor_projective(n, f, 400, 2000, 1);
#ifdef USE_LIBECM
      /* TODO: LIBECM in other stages */
      /* Note: this will be substantially slower than our code for small sizes
       *       and the small B1/B2 values we're using. */
      if (!success && degree <= 2 && nsize > 600) {
        ecm_params params;
        ecm_init(params);
        params->method = ECM_ECM;
        mpz_set_ui(params->B2, 10*B1);
        mpz_set_ui(params->sigma, 0);
        success = ecm_factor(f, n, B1/4, params);
        ecm_clear(params);
        if (mpz_cmp(f, n) == 0)  success = 0;
        if (success) { printf("ECM FOUND FACTOR\n"); }
      }
#endif
    }
    /* Try any factors found in previous stage 2+ calls */
    while (!success && sfaci < *nsfacs) {
      if (mpz_divisible_p(n, sfacs[sfaci])) {
        mpz_set(f, sfacs[sfaci]);
        success = 1;
      }
      sfaci++;
    }
    if (stage > 1 && !success) {
      if (stage == 2) {
        /* if (!success) success = _GMP_pbrent_factor(n, f, nsize-1, 8192); */
        if (!success) success = _GMP_pminus1_factor(n, f, 6*B1, 60*B1);
        /* p+1 with different initial point and searching farther */
        if (!success) success = _GMP_pplus1_factor(n, f, 1, B1/2, B1/2);
        if (!success) success = _GMP_ecm_factor_projective(n, f, 250, 2500, 8);
      } else if (stage == 3) {
        if (!success) success = _GMP_pbrent_factor(n, f, nsize+1, 16384);
        if (!success) success = _GMP_pminus1_factor(n, f, 60*B1, 600*B1);
        /* p+1 with a third initial point and searching farther */
        if (!success) success = _GMP_pplus1_factor(n, f, 2, 1*B1, 1*B1);
        if (!success) success = _GMP_ecm_factor_projective(n, f, B1/4, B1*4, 5);
      } else if (stage == 4) {
        if (!success) success = _GMP_pminus1_factor(n, f, 300*B1, 300*20*B1);
        if (!success) success = _GMP_ecm_factor_projective(n, f, B1/2, B1*8, 4);
      } else if (stage >= 5) {
        UV B = B1 * (stage-4) * (stage-4) * (stage-4);
        if (!success) success = _GMP_ecm_factor_projective(n, f, B, 10*B, 8+stage);
      }
    }
    if (success) {
      if (mpz_cmp_ui(f, 1) == 0 || mpz_cmp(f, n) == 0) {
        gmp_printf("factoring %Zd resulted in factor %Zd\n", n, f);
        croak("internal error in ECPP factoring");
      }
      /* Add the factor to the saved factors list */
      if (stage > 1 && *nsfacs < MAX_SFACS) {
        /* gmp_printf(" ***** adding factor %Zd ****\n", f); */
        mpz_init_set(sfacs[*nsfacs], f);
        nsfacs[0]++;
      }
      /* Is the factor f what we want? */
      if ( mpz_cmp(f, fmin) > 0 && is_bpsw_prime(f) )  return 1;
      /* Divide out f */
      mpz_divexact(n, n, f);
    }
  }
  /* n is larger than fmin and not prime */
  mpz_set(f, n);
  return -1;
}
Exemplo n.º 15
0
void fib_print (mpz_t result, mpz_t term)
{
	gmp_printf ("F_%Zd = %Zd\n\n", term, result);
}
void print_extProjPoint(ExtProjPoint *op){
	gmp_printf("X : %Zd\nY : %Zd\nZ : %Zd\nT : %Zd\n", op->X, op->Y, op->Z, op->T);
}
Exemplo n.º 17
0
void print_point(Point *pc, char j){
	gmp_printf("X : %Zd\nY : %Zd\nZ : %Zd\n", pc->PQ[j], pc->PQ[j+2], pc->Z);
}
Exemplo n.º 18
0
Arquivo: t-mul.c Projeto: goens/flint2
int
main(void)
{
    int i, result;
    flint_rand_t state;

    printf("mul....");
    fflush(stdout);

    flint_randinit(state);

    for (i = 0; i < 100000; i++)
    {
        fmpz_t a, b, c;
        mpz_t d, e, f, g;

        fmpz_init(a);
        fmpz_init(b);
        fmpz_init(c);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);
        mpz_init(g);

        fmpz_randtest(a, state, 200);
        fmpz_randtest(b, state, 200);

        fmpz_get_mpz(d, a);
        fmpz_get_mpz(e, b);

        fmpz_mul(c, a, b);
        mpz_mul(f, d, e);

        fmpz_get_mpz(g, c);

        result = (mpz_cmp(f, g) == 0);
        if (!result)
        {
            printf("FAIL:\n");
            gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g);
            abort();
        }

        fmpz_clear(a);
        fmpz_clear(b);
        fmpz_clear(c);

        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
        mpz_clear(g);
    }

    /* Check aliasing of a and b */
    for (i = 0; i < 100000; i++)
    {
        fmpz_t a, c;
        mpz_t d, f, g;

        fmpz_init(a);
        fmpz_init(c);

        mpz_init(d);
        mpz_init(f);
        mpz_init(g);

        fmpz_randtest(a, state, 200);

        fmpz_get_mpz(d, a);

        fmpz_mul(c, a, a);
        mpz_mul(f, d, d);

        fmpz_get_mpz(g, c);

        result = (mpz_cmp(f, g) == 0);
        if (!result)
        {
            printf("FAIL:\n");
            gmp_printf("d = %Zd, f = %Zd, g = %Zd\n", d, f, g);
            abort();
        }

        fmpz_clear(a);
        fmpz_clear(c);

        mpz_clear(d);
        mpz_clear(f);
        mpz_clear(g);
    }

    /* Test aliasing of a and c */
    for (i = 0; i < 100000; i++)
    {
        fmpz_t a, b;
        mpz_t d, e, f, g;

        fmpz_init(a);
        fmpz_init(b);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);
        mpz_init(g);

        fmpz_randtest(a, state, 200);
        fmpz_randtest(b, state, 200);

        fmpz_get_mpz(d, a);
        fmpz_get_mpz(e, b);

        fmpz_mul(a, a, b);
        mpz_mul(f, d, e);

        fmpz_get_mpz(g, a);

        result = (mpz_cmp(f, g) == 0);
        if (!result)
        {
            printf("FAIL:\n");
            gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g);
            abort();
        }

        fmpz_clear(a);
        fmpz_clear(b);

        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
        mpz_clear(g);
    }

    /* Test aliasing of b and c */
    for (i = 0; i < 100000; i++)
    {
        fmpz_t a, b;
        mpz_t d, e, f, g;

        fmpz_init(a);
        fmpz_init(b);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);
        mpz_init(g);

        fmpz_randtest(a, state, 200);
        fmpz_randtest(b, state, 200);

        fmpz_get_mpz(d, a);
        fmpz_get_mpz(e, b);

        fmpz_mul(b, a, b);
        mpz_mul(f, d, e);

        fmpz_get_mpz(g, b);

        result = (mpz_cmp(f, g) == 0);
        if (!result)
        {
            printf("FAIL:\n");
            gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g);
            abort();
        }

        fmpz_clear(a);
        fmpz_clear(b);

        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
        mpz_clear(g);
    }

    flint_randclear(state);
    _fmpz_cleanup();
    printf("PASS\n");
    return 0;
}
Exemplo n.º 19
0
int main(void) {
	long sd = 0;
	int t = 20;
	int s,j_rab;//miller
	int result = 0; //miller
	//metavlites gia metatropi keimenou se int k tubalin
	char mystring[MAXCHARS];//my text to encrypt - decrypt hope so
    long int str_len;
    char c;
    mpz_t max_int, c_int, str_int, encrypted,decrypted;
    mpz_init(max_int); mpz_init(c_int); mpz_init(str_int);mpz_init(encrypted); mpz_init(decrypted);
	mpz_t psi, d, n_minus_one;//miller
mpz_t n_prime,n,three,two,a,one,p,q,phi,p_minus_one,q_minus_one,e,gcd,d_priv,t2;
mpz_t seed;
mpz_t ro;//for encry-decry
gmp_randinit(stat,GMP_RAND_ALG_LC,120);
mpz_init(n_prime);
mpz_init(n);//iniatialize
mpz_init(three);
mpz_init(a);
mpz_init(two);
mpz_init(one);
mpz_init(seed);
mpz_init(psi);//for miller-rabin
mpz_init(p);
mpz_init(q);
mpz_init(phi);
mpz_init(p_minus_one);
mpz_init(q_minus_one);
mpz_init(e);
mpz_init(gcd);
mpz_init(d_priv);
mpz_init(ro);
mpz_init(t2);
mpz_set_str(three, "3", 10);
mpz_set_str(two, "2", 10);
mpz_set_str(one, "1", 10);
srand((unsigned)getpid()); //initialize stat
sd = rand();
mpz_set_ui(seed,sd);
gmp_randseed(stat,seed);
int countpq=0;//0 primes pros to paron, kantous 2 (p kai q)
int i = 0;
//printf("Give a message (till %d chars):\n",MAXCHARS-1);
//fgets(mystring,MAXCHARS,stdin);
//

FILE *fp;            /* declare the file pointer */
 fp = fopen ("file.txt", "r");
 while(fgets(mystring, MAXCHARS, fp) != NULL)
    { sscanf (mystring, "%d"); }
fclose(fp);
//
do{ // mehri na vreis 2 prime

do{//RANDOM NUMBER
	mpz_urandomb(n_prime,stat,512);//create a random number
}while((mpz_even_p(n_prime))&& (n_prime<=three));//checking n to be >=3 && n be odd

mpz_init(n_minus_one); //initialize
mpz_sub_ui(n_minus_one, n_prime, 1);//n_minus_one = n-1
	s = 0;
	mpz_init_set(d, n_minus_one);
	while (mpz_even_p(d)) {// gia oso ine artios
		mpz_fdiv_q_2exp(d, d, 1); //shift right
		s++;//inc s
	}
	for (i = 0; i < t; ++i) {
		do{
		mpz_urandomb(a,stat,20);//create random number
		}while(!((a<=(n_prime-two)) && (a>=two)));//checking a must be (2<=a<=n-2)
		 mpz_powm(psi,a,d,n_prime);
		 if(mpz_cmp(psi,one)!=0 && mpz_cmp(psi,n_minus_one)){
			 j_rab=1;
			 while(j_rab<s &&  mpz_cmp(psi,n_minus_one)){
				 mpz_mul(psi,psi,psi); // y^2
				 mpz_mod(psi,psi,n_prime); //psi= psi^2 mod n
				 	 if(mpz_cmp(psi,one)==0){//if y=1
				 		  result = 1; goto exit_miller;
				 	 }
				 	 j_rab++;
			 }
		 	 if(mpz_cmp(psi,n_minus_one)!=0){//if y=n-1
		 		 result = 1; goto exit_miller;
		 	 }
		 }//end external if
}//end for

	if(result!=1){ countpq++; //an ine prime tote save
	if(countpq==1){mpz_set(p,n_prime);}//save p
	else{
		mpz_set(q,n_prime);}//save q
	}
	exit_miller: result = 0;
	if(mpz_cmp(p,q)==0){countpq=0;}//an p kai q idioi pame pali
}while(countpq<2);

	gmp_printf ("p = %Zd\n", p);
	gmp_printf ("q = %Zd\n", q);
mpz_mul(n,p,q); //calculate p*q
	gmp_printf ("n = p*q = %Zd\n", n);
mpz_sub(p_minus_one,p,one);
mpz_sub(q_minus_one,q,one);
	gmp_printf ("p-1 = %Zd\n", p_minus_one);
	gmp_printf ("q-1 = %Zd\n", q_minus_one);
mpz_mul(phi,p_minus_one,q_minus_one);
	gmp_printf ("phi = %Zd\n", phi);

	do{
	mpz_urandomm(e,stat,phi);//create random number e opou < tou phi
    mpz_add(e,e,two);//add two to be bigger the e from ena
	mpz_gcd(gcd,e,phi);
	}while((!(mpz_cmp(gcd,one)==0)));//checking..gcd=1
		gmp_printf ("e = %Zd\n", e);
		gmp_printf ("gcd = %Zd\n", gcd);
	mpz_invert(d_priv,e,phi);//ypologismos antistrofou e mod phi
		gmp_printf ("private key (d) = %Zd\n", d_priv);
			gmp_printf ("public key (n,e) = (%Zd , %Zd)\n", n,e);
////// convert myText to myIntegerText
		    str_len = strlen(mystring);
		    if(mystring[str_len - 1] == '\n')
		       mystring[str_len - 1] = '\0';
		       str_len = strlen(mystring);
		       printf("%s -> %ld \n", mystring, str_len);
		              for(i = str_len - 1; i >= 0; i--){
		                  c = mystring[i];
		                  mpz_mul_ui(ro,ro,BASE); // r=r*BASE
		                  mpz_add_ui(ro, ro, c);     // r=r+c
		              	  }//now ro is mystring as Integers
		     gmp_printf("My text is: %s and has %ld chars.\nAs Integer is:%Zd",mystring, strlen(mystring), ro);
////// encrypt text
		     mpz_powm(encrypted,ro,e,n);//
		     gmp_printf("\nEncrypted message is: %Zd",encrypted);
		     ////
//// create encrypted file
		     fp= fopen("encrypted_file.txt","w");
		     fprintf(fp, encrypted);
		     fclose(fp);
		     ////
////// decrypt text
		     mpz_powm(decrypted,encrypted,d_priv,n);//
		     gmp_printf("\nDecrypted message is: %Zd",decrypted);
////// convert myIntegerText to myText
		     mpz_set(str_int, ro);//integerText to mytext
		     mpz_set_ui(max_int, 1UL);//larger int set
		     for(i = 0; i < 10; i++){// maxlength =100
		         if(mpz_cmp(str_int, max_int) <= 0){
		        	str_len = i;
		        	break;}
		         mpz_mul_ui(max_int, max_int, BASE);}
		     for(i = 0; i < str_len; i++){
		     mpz_mod_ui(c_int, str_int,BASE);        // ekxoreitai sthn metablhth c_int=str_int mod BASE
		     mpz_sub(str_int, str_int, c_int);
		     mpz_tdiv_q_ui(str_int, str_int,BASE);
		     mystring[i] = mpz_get_ui(c_int);}
		     mystring[str_len] = '\0';
		     //printf("Num of Chars--> %ld\n", str_len);
///////plaintext
		     gmp_printf("\nPlaintext message is: %s",mystring);
mpz_clear(n_prime);
mpz_clear(n);//clear
mpz_clear(three);
mpz_clear(a);
mpz_clear(two);
mpz_clear(seed);
mpz_clear(one);
mpz_clear(d);
mpz_clear(n_minus_one);
mpz_clear(psi);
mpz_clear(p);
mpz_clear(q);
mpz_clear(phi);
mpz_clear(p_minus_one);
mpz_clear(q_minus_one);
mpz_clear(e);
mpz_clear(gcd);
	mpz_clear(d_priv);
	mpz_clear(ro);
    mpz_clear(max_int);
    mpz_clear(c_int);
    mpz_clear(str_int);
	mpz_clear(t2);
	mpz_clear(encrypted);
	mpz_clear(decrypted);
	return 0;
}
Exemplo n.º 20
0
int
main(void)
{
    int i, result;
    flint_rand_t state;

    printf("pow_ui....");
    fflush(stdout);

    flint_randinit(state);

    for (i = 0; i < 100000; i++)
    {
        fmpz_t a, b;
        mpz_t d, e, f;
        ulong x;

        fmpz_init(a);
        fmpz_init(b);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);

        fmpz_randtest(a, state, 200);

        fmpz_get_mpz(d, a);
        x = n_randint(state, 20);

        fmpz_pow_ui(b, a, x);
        mpz_pow_ui(e, d, x);

        fmpz_get_mpz(f, b);

        result = (mpz_cmp(e, f) == 0);
        if (!result)
        {
            printf("FAIL:\n");
            gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %lu\n", d, e, f, x);
            abort();
        }

        fmpz_clear(a);
        fmpz_clear(b);

        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
    }

    /* Check aliasing of a and b */
    for (i = 0; i < 100000; i++)
    {
        fmpz_t a;
        mpz_t d, e, f;
        ulong x;

        fmpz_init(a);

        mpz_init(d);
        mpz_init(e);
        mpz_init(f);

        fmpz_randtest(a, state, 200);

        fmpz_get_mpz(d, a);
        x = n_randint(state, 20);

        fmpz_pow_ui(a, a, x);
        mpz_pow_ui(e, d, x);

        fmpz_get_mpz(f, a);

        result = (mpz_cmp(e, f) == 0);
        if (!result)
        {
            printf("FAIL:\n");
            gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %lu\n", d, e, f, x);
            abort();
        }

        fmpz_clear(a);

        mpz_clear(d);
        mpz_clear(e);
        mpz_clear(f);
    }

    flint_randclear(state);
    _fmpz_cleanup();
    printf("PASS\n");
    return 0;
}
Exemplo n.º 21
0
int
main(void)
{
    int i, j, result;
    flint_rand_t state;
    ulong cflags = 0UL;

    mpq_t n1, n2;

    printf("get/set_coeff_mpz....");
    fflush(stdout);

    mpq_init(n1);
    mpq_init(n2);

    flint_randinit(state);

    for (i = 0; i < 1000UL; i++)
    {
        fmpq_poly_t a;
        fmpz_t x1, x2;
        long coeff, len;

        fmpq_poly_init(a);
        fmpz_init(x1);
        fmpz_init(x2);
        len = (long) (n_randint(state, 100) + 1);

        for (j = 0; j < 1000; j++)
        {
            fmpz_randtest(x1, state, 200);
            fmpz_get_mpz(mpq_numref(n1), x1);
            mpz_set_si(mpq_denref(n1), 1);
            coeff = (long) n_randint(state, len);
            fmpq_poly_set_coeff_mpz(a, coeff, mpq_numref(n1));
            fmpq_poly_get_coeff_mpq(n2, a, coeff);

            result = (mpq_equal(n1, n2));
            if (!result)
            {
                printf("FAIL:\n\n");
                printf("a     = "), fmpq_poly_debug(a), printf("\n\n");
                printf("coeff = %ld\n\n", coeff);
                printf("len   = %ld\n\n", len);
                printf("cflags = %lu\n\n", cflags);
                gmp_printf("n1 = %Qd\n\n", n1);
                gmp_printf("n2 = %Qd\n\n", n2);
                abort();
            }
        }

        fmpz_clear(x1);
        fmpz_clear(x2);
        fmpq_poly_clear(a);
    }

    mpq_clear(n1);
    mpq_clear(n2);

    flint_randclear(state);
    _fmpz_cleanup();
    printf("PASS\n");
    return 0;
}
void simulation_single(){

	const int num_lanes=2;
	int lane_size=100;
	const gsl_rng_type * T;
	gsl_rng_env_setup();
	T = gsl_rng_default;
	gsl_rng *r;
	r = gsl_rng_alloc (T);
	unsigned long int seed;
	seed=gen_seed();
		gsl_rng_set(r,seed);
	int fil_length=150;
	int stickers=1;
	//glue-related!
	//int stickers=0;
	mpz_t states;
	mpz_t newstates;
	mpz_t deltastates;
	mpz_init(states);
	mpz_init(newstates);
	mpz_init(deltastates);

	const float timesteps=5000;
	int my_rank;
	MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
	char* filename[60];
  sprintf(filename,"./output_single_filament_compact/run%d.txt",my_rank);
	// sprintf(filename,"./output_single_filament_glue_%.2f/run%d.txt",kstick,my_rank);
	printf("%s\n",filename);
	FILE *fp = fopen(filename, "w");
	if (fp == NULL) {
    	printf("Error");
			return;
    }
	float mu=6.0;
	float glue=1.0;
	float koff=1.0;
	float i;
	int j,k;
	float kstick=0.01;
	float kunstick=0.01;
	float stick_energy=3.0;
	int type=0;

	float nextoff=gsl_ran_exponential(r,1.0/koff);
	float nextstick=gsl_ran_exponential(r,1.0/((fil_length-lane_size-stickers)*kstick));
	float nextunstick=gsl_ran_exponential(r,1.0/(stickers*kunstick));
	//glue-related!
	// float nextstick=VERYBIG;
	// float nextunstick=VERYBIG;
	float peroverlap=kstick;
	double domega;
	float c0=1.0/lane_size;

	int att_depol=0;
	int acc_depol=0;
	int att_stick=0;
	int acc_stick=0;
	int att_unstick=0;
	int acc_unstick=0;
	int att_contr=0;
	int acc_contr=0;
	int att_expan=0;
	int acc_expan=0;
	int att_special=0;
	int acc_special=0;
	float eta=0.2;
	float fraction=0.0;
	float delta=0.0;
	clock_t t1 = clock();
	//printf("before first count: %f fil_length: %d\n",kstick,fil_length);
	count_isl_single(&states,fil_length,stickers,lane_size);
	gmp_printf("states= %Zd\n",states);
	int currpar=0;

	for (i=0;i<timesteps;i=i+0.01){
		fraction=fraction+0.01*delta;
		//printf("%f %f %d\n",fraction,delta,currpar);
		// if ((int)(fraction*20)%2!=currpar){
		// 	fprintf(fp, "fraction=%f delta=%f\n",fraction,delta);
		//
		// }
		// 	currpar=(int)(fraction*20)%2;

		if (fabs(fraction)>1.0){
			//fprintf(fp,"event occurring - i=%f delta=%f fraction=%f\n",i,delta,fraction);
			if (fraction>0){
				delta=check_contraction(fil_length,stickers,lane_size+1,c0,states,r,fp);
				if (delta>VERYBIG/10){

					delta=0;
					fraction=0;
					//fprintf(fp,"delta too big! delta is now %f\n",delta);
				}else{
					lane_size++;
				}

			}
			else{
				delta=check_contraction(fil_length,stickers,lane_size-1,c0,states,r,fp);
				if (delta>VERYBIG/10){
					delta=0;
					fraction=0;
					//fprintf(fp,"delta too big! delta is now %f\n",delta);
				}else{
					lane_size--;
				}
			}
			fraction=0;
			nextstick=i+gsl_ran_exponential(r,1.0/((fil_length-lane_size-stickers)*kstick));


		}

		if (stickers==0){
			nextunstick=VERYBIG;
		}
		if (fil_length-lane_size-stickers<=0){
			nextstick=VERYBIG;
		}
		//fprintf(fp, "fraction=%f delta=%f\n",fraction,delta);
		//printf("%f %f %f %f %d %d %d %d %d %d %d %d %d %d %d %d %d\n", i,nextoff,nextstick,nextunstick,fil_length,stickers,lane_size,att_depol,acc_depol,att_stick,acc_stick,att_unstick,acc_unstick,att_contr,acc_contr,att_expan,acc_expan);
		if (fil_length==0){
			break;
		}
		if ((int)(i*100)%(int)timesteps==0){
			clock_t t2 = clock();
			printf("%d percent %f\n",(int)(i*100)/(int)timesteps,(double)(t2-t1)/CLOCKS_PER_SEC);
		}
		//fprintf(fp,"i=%f\n",i);
		if ((int)(i*100)%50==0){
			fprintf(fp, "%f %f %f %f %d %d %d %d %d %d %d %d %d %d %d %f %f %f %f\n", i,nextoff,nextstick,nextunstick,fil_length,stickers,lane_size,att_depol,acc_depol,att_stick,acc_stick,att_unstick,acc_unstick,att_special,acc_special,((fil_length-lane_size-stickers)*kstick),(stickers*kunstick),delta,fraction);
			//gmp_fprintf(fp,"states= %Zd\n",states);
		}

		if (i>=nextoff){
			type=1;}
		if (i>=nextstick){
			type=2;
		}
		if (i>=nextunstick){
			type=3;
		}

		if (type==1){
			int done=0;
			att_depol=att_depol+1;
			int newlength=fil_length-1;
			// clock_t t3 = clock();
			count_isl_single(&newstates,newlength,stickers,lane_size);
			// clock_t t4 = clock();
			// printf("depol time: %f\n",(double)(t4-t3)/CLOCKS_PER_SEC);
			if (mpz_cmp_d(newstates,0.0)){
				domega=-mu+glue-mpzln(newstates)+mpzln(states);
				//glue-related!
				// domega=-mu+glue+peroverlap-mpzln(newstates)+mpzln(states);
				if (domega<0){
					acc_depol++;
					fil_length=newlength;
					mpz_set(states,newstates);
					done=1;
					// fprintf(fp,"depol - domega=%f\n",domega);
				}


			/*if it's positive, we calculate the probability of acceptance
			 * and test for it*/
				else{
					double prob=exp(-1.0*domega);
					double fromthehat=gsl_rng_uniform(r);
					//printf("metropolising: rng=%f, prob=%f\n",fromthehat,prob);
					if (fromthehat<prob){
						fil_length=newlength;
						acc_depol++;
						mpz_set(states,newstates);
						done=1;
						// fprintf(fp,"depol - domega=%f\n",domega);

					}else{
	          // fprintf(fp,"removal not accepted - domega=%f\n",domega);
	        }
				}
			}
			if (done==0){
					att_special++;
					// clock_t t3 = clock();
					count_isl_single(&newstates,newlength,stickers-1,lane_size);
					// clock_t t4 = clock();
					// printf("special depol time: %f\n",(double)(t4-t3)/CLOCKS_PER_SEC);

					domega=stick_energy-mu+glue-mpzln(newstates)+mpzln(states);
					if (domega<0){

						fil_length=newlength;
						stickers=stickers-1;
						acc_depol++;
						acc_special++;
						mpz_set(states,newstates);
						//fprintf(fp,"depol and removal - domega=%f\n",domega);
					}
					else{
						double prob=exp(-1.0*domega);
						double fromthehat=gsl_rng_uniform(r);
						//printf("metropolising: rng=%f, prob=%f\n",fromthehat,prob);
						if (fromthehat<prob){
							fil_length=newlength;
							stickers=stickers-1;
							acc_depol++;
							acc_special++;
							mpz_set(states,newstates);
							 //fprintf(fp,"depol and removal - domega=%f\n",domega);

						}else{
		          // fprintf(fp,"depol w/unstick not accepted - domega=%f\n",domega);
		        }
					}
			}

			att_contr++;
			att_expan++;
			delta=check_contraction(fil_length,stickers,lane_size,c0,states,r,fp);
			delta=delta/eta;
			// if (delta==-1){
			// 	acc_contr++;
			// }
			// if (delta==+1){
			// 	acc_expan++;
			// }
			// lane_size=lane_size+delta;
			nextoff=i+gsl_ran_exponential(r,1.0/koff);
			nextstick=i+gsl_ran_exponential(r,1.0/((fil_length-lane_size-stickers)*kstick));
			type=0;
		}



		if (type==2){
			att_stick++;
			int newstickers=stickers+1;
			// clock_t t3 = clock();
			count_isl_single(&newstates,fil_length,newstickers,lane_size);
			// clock_t t4 = clock();
			// printf("new sticker time: %f\n",(double)(t4-t3)/CLOCKS_PER_SEC);

			domega=-stick_energy-mpzln(newstates)+mpzln(states);
			if (domega<0){
				stickers=newstickers;
				acc_stick++;
				mpz_set(states,newstates);
				// fprintf(fp,"added sticker - domega=%f\n",domega);

			}


		/*if it's positive, we calculate the probability of acceptance
		 * and test for it*/
			else{
				double prob=exp(-1.0*domega);
				double fromthehat=gsl_rng_uniform(r);
				//printf("metropolising: rng=%f, prob=%f\n",fromthehat,prob);
				if (fromthehat<prob){
					stickers=newstickers;
					acc_stick++;
					mpz_set(states,newstates);
					// fprintf(fp,"added sticker - domega=%f\n",domega);
				}else{
          // fprintf(fp,"addition sticker rejected - domega=%f\n",domega);
        }
			}

			att_contr++;
			att_expan++;
			delta=check_contraction(fil_length,stickers,lane_size,c0,states,r,fp);
			delta=delta/eta;
			// if (delta==-1){
			// 	acc_contr++;
			// }
			// if (delta==+1){
			// 	acc_expan++;
			// }
			// lane_size=lane_size+delta;
			nextstick=i+gsl_ran_exponential(r,1.0/((fil_length-lane_size-stickers)*kstick));
			nextunstick=i+gsl_ran_exponential(r,1.0/(stickers*kunstick));
			type=0;

		}

		if (type==3){
			att_unstick++;
			int newstickers=stickers-1;

			// clock_t t3 = clock();
			count_isl_single(&newstates,fil_length,newstickers,lane_size);
			// clock_t t4 = clock();
			// printf("remove sticker time: %f\n",(double)(t4-t3)/CLOCKS_PER_SEC);
			domega=stick_energy-mpzln(newstates)+mpzln(states);
			if (domega<0){
				acc_unstick++;
				stickers=newstickers;
				mpz_set(states,newstates);
			 //fprintf(fp,"removal - domega=%f\n",domega);
			}


		/*if it's positive, we calculate the probability of acceptance
		 * and test for it*/
			else{
				double prob=exp(-1.0*domega);
				double fromthehat=gsl_rng_uniform(r);
				//printf("metropolising: rng=%f, prob=%f\n",fromthehat,prob);
				if (fromthehat<prob){
					stickers=newstickers;
					acc_unstick++;
					mpz_set(states,newstates);
				 //fprintf(fp,"removal - domega=%f\n",domega);
				}else{
          // fprintf(fp,"removal of sticker not accepted - domega=%f\n",domega);
        }
			}
			att_contr++;
			att_expan++;
			delta=check_contraction(fil_length,stickers,lane_size,c0,states,r,fp);
			delta=delta/eta;

			// if (delta==-1){
			// 	acc_contr++;
			// }
			// if (delta==+1){
			// 	acc_expan++;
			// }
			// lane_size=lane_size+delta;
			nextunstick=i+gsl_ran_exponential(r,1.0/(stickers*kunstick));
			nextstick=i+gsl_ran_exponential(r,1.0/((fil_length-lane_size-stickers)*kstick));
			type=0;

		}



	}
	mpz_clear(states);
  mpz_clear(newstates);
  mpz_clear(deltastates);
  gsl_rng_free (r);
 	fclose(fp);

}
Exemplo n.º 23
0
/* Check divide and conquer division routine. */
void
check_dc_divappr_q_n (void)
{
   mp_limb_t tp[DC_DIVAPPR_Q_N_ITCH(MAX_LIMBS)];
   mp_limb_t np[2*MAX_LIMBS];
   mp_limb_t np2[2*MAX_LIMBS];
   mp_limb_t rp[2*MAX_LIMBS];
   mp_limb_t dp[MAX_LIMBS];
   mp_limb_t qp[MAX_LIMBS];
   mp_limb_t dip, d1ip;

   mp_size_t nn, rn, dn, qn;

   gmp_randstate_t rands;

   int i, j, s;
   gmp_randinit_default(rands);
  
   for (i = 0; i < ITERS; i++)
   {
      dn = (random() % (MAX_LIMBS - 6)) + 6;
      nn = 2*dn;
         
      mpn_rrandom (np, rands, nn);
      mpn_rrandom (dp, rands, dn);
      dp[dn-1] |= GMP_LIMB_HIGHBIT;

      MPN_COPY(np2, np, nn);
      
      mpir_invert_pi2(dip, d1ip, dp[dn - 1], dp[dn - 2]);
      
      qn = nn - dn + 1;
         
      qp[qn - 1] = mpn_dc_divappr_q_n(qp, np, dp, dn, dip, d1ip, tp);
      
      MPN_NORMALIZE(qp, qn);

      if (qn)
      {
         if (qn >= dn) mpn_mul(rp, qp, qn, dp, dn);
         else mpn_mul(rp, dp, dn, qp, qn);

         rn = dn + qn;
         MPN_NORMALIZE(rp, rn);

         s = (rn < nn) ? -1 : (rn > nn) ? 1 : mpn_cmp(rp, np2, nn);
         if (s <= 0) 
         {
            mpn_sub(rp, np2, nn, rp, rn);
            rn = nn;
            MPN_NORMALIZE(rp, rn);
         } else 
         {
            mpn_sub(rp, rp, rn, np2, nn);
            MPN_NORMALIZE(rp, rn);
         }
      } else
      {
         rn = nn;
         MPN_COPY(rp, np, nn);
      }
      
      s = (rn < dn) ? -1 : (rn > dn) ? 1 : mpn_cmp(rp, dp, dn);
      if (s >= 0)
      {
         printf ("failed:\n");
         printf ("nn = %lu, dn = %lu, qn = %lu, rn = %lu\n\n", nn, dn, qn, rn);
         gmp_printf (" np: %Nx\n\n", np2, nn);
         gmp_printf (" dp: %Nx\n\n", dp, dn);
         gmp_printf (" qp: %Nx\n\n", qp, qn);
         gmp_printf (" rp: %Nx\n\n", rp, rn);
         abort ();
      }
   }

   gmp_randclear(rands);
}
Exemplo n.º 24
0
void print_sequential_m (unsigned int n, mpf_t term, mpf_t cos_x){

	printf("########### N = %d ############\n", n);
	gmp_printf("-*- Valor do termo: %F.f\n", term);
	gmp_printf("-*- Valor do cosseno: %F.f\n", cos_x);
}
Exemplo n.º 25
0
/*------------------------------------------------------------------------*/
uint32
handle_collision(poly_coeff_t *c, uint64 p, uint32 special_q,
		uint64 special_q_root, int64 res)
{
	/* the proposed rational coefficient is p*special_q;
	   p and special_q must be coprime. The 'trivial
	   special q' has special_q = 1 and special_q_root = 0 */

	uint64_2gmp(p, c->p);
	mpz_gcd_ui(c->tmp1, c->p, special_q);
	if (mpz_cmp_ui(c->tmp1, 1))
		return 0;

	mpz_mul_ui(c->p, c->p, (unsigned long)special_q);

	/* the corresponding correction to trans_m0 is 
	   special_q_root + res * special_q^2, and can be
	   positive or negative */

	uint64_2gmp(special_q_root, c->tmp1);
	int64_2gmp(res, c->tmp2);
	mpz_set_ui(c->tmp3, special_q);

	mpz_mul(c->tmp3, c->tmp3, c->tmp3);
	mpz_addmul(c->tmp1, c->tmp2, c->tmp3);
	mpz_add(c->m, c->trans_m0, c->tmp1);

	/* a lot can go wrong before this function is called!
	   Check that Kleinjung's modular condition is satisfied */

	mpz_pow_ui(c->tmp1, c->m, c->degree);
	mpz_mul(c->tmp2, c->p, c->p);
	mpz_sub(c->tmp1, c->trans_N, c->tmp1);
	mpz_tdiv_r(c->tmp3, c->tmp1, c->tmp2);
	if (mpz_cmp_ui(c->tmp3, 0)) {
		gmp_printf("crap %Zd %Zd %Zd\n", c->high_coeff, c->p, c->m);
		return 0;
	}

	/* the pair works, now translate the computed m back
	   to the original polynomial. We have

	   computed_m = degree * high_coeff * real_m +
	   			(second_highest_coeff) * p

	   and need to solve for real_m and second_highest_coeff.
	   Per the CADO code: reducing the above modulo
	   degree*high_coeff causes the first term on the right
	   to disappear, so second_highest_coeff can be found
	   modulo degree*high_coeff and real_m then follows */

	mpz_mul_ui(c->tmp1, c->high_coeff, c->degree);
	mpz_tdiv_r(c->tmp2, c->m, c->tmp1);
	mpz_invert(c->tmp3, c->p, c->tmp1);
	mpz_mul(c->tmp2, c->tmp3, c->tmp2);
	mpz_tdiv_r(c->tmp2, c->tmp2, c->tmp1);

	/* make second_highest_coeff as small as possible in
	   absolute value */

	mpz_tdiv_q_2exp(c->tmp3, c->tmp1, 1);
	if (mpz_cmp(c->tmp2, c->tmp3) > 0) {
		mpz_sub(c->tmp2, c->tmp2, c->tmp1);
	}

	/* solve for real_m */
	mpz_submul(c->m, c->tmp2, c->p);
	mpz_tdiv_q(c->m, c->m, c->tmp1);
	return 1;
}
Exemplo n.º 26
0
void print_partial(double x, mpf_t cos_x) {

	printf("Cos(%f):", x);
	gmp_printf(" %F.f\n", cos_x);
}
Exemplo n.º 27
0
int main(int argc, char *argv[])
{

	// declare mpz structs
	mpz_t n; 
	mpz_t zero;
	mpz_t r;
	mpz_t d;
	mpz_t start;
	mpz_t end;
	mpz_t temp;
	mpz_t my_rank_mpz;
	mpz_t local_end;
	mpz_t current_prime;

	mpz_t global_end;

	mpz_init_set_ui(zero, 0);
	mpz_init(d);

	double t1, t2, totaltime;

	int tag = 0;
	int my_rank, p;
	int source, dest, i;

	mpz_init_set_str(n, argv[1], 10); // initialize the key (n)

	mpz_init(global_end);
	mpz_sqrt(global_end, n);

	// MPI boilerplate
	MPI_Status status;
	MPI_Request request;
	MPI_Init(&argc, &argv);
	MPI_Comm_size(MPI_COMM_WORLD, &p);
	MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

	t1 = MPI_Wtime();

	// initialize mpz structs
	mpz_init(r);
	mpz_init(start);
	mpz_init(local_end);
	mpz_init(end);
	mpz_init(temp);
	mpz_init(current_prime);
	mpz_init(my_rank_mpz);
	mpz_init_set_ui(start, 2);
	mpz_set(temp, start);

	size_t temp_window_size = mpz_sizeinbase(temp, 2);

	mpz_add_ui(temp, temp, temp_window_size);

	for (i = 0; i < my_rank; i++){
		temp_window_size = mpz_sizeinbase(temp, 2);
		mpz_add_ui(temp, temp, temp_window_size);	
	}

	mpz_set(start, temp);
	size_t window_size =  mpz_sizeinbase(start, 2);
	mpz_add_ui(local_end, start, window_size);	


	mpz_init_set_ui(my_rank_mpz, my_rank);
	mpz_init_set(end, global_end);
	mpz_nextprime(current_prime, start);
	mpz_init_set_str(n, argv[1], 10);

	int check = 0;
	int flag = 0;
	int found = 0;

	MPI_Irecv(&found, 1, MPI_INTEGER, MPI_ANY_SOURCE, tag, MPI_COMM_WORLD, &request);
	MPI_Barrier(MPI_COMM_WORLD);

	while (mpz_cmp(start, end) <= 0){
		while(mpz_cmp(current_prime, local_end) <= 0 && mpz_cmp(current_prime, end) <= 0){
			mpz_mod(r, n, current_prime);
			if (mpz_cmp(zero, r) == 0){
				mpz_divexact(d, n, current_prime);
				gmp_printf("%Zd %Zd\n", d, current_prime);
				found = 1;
				for (dest = 0; dest < p; dest++){
					MPI_Isend(&found, 1, MPI_INTEGER, dest, tag, MPI_COMM_WORLD, &request);
				}
				break;		
			}
			check++;
			if (check == 500){
				check = 0;
				MPI_Test(&request, &flag, &status);
				if (flag){
					found = 1;
					break;
				}
			}
			mpz_nextprime(current_prime, current_prime);	
		}
		if( found == 1){
			break;
		}

		// calculate new start index

		mpz_set(temp, start);
		size_t temp_window_size = mpz_sizeinbase(start, 2);
		mpz_add_ui(temp, temp, temp_window_size);
		mpz_set(start, local_end);
		for (i = my_rank + 1; i < p; i++){
			temp_window_size = mpz_sizeinbase(temp, 2);
			mpz_add_ui(temp, temp, temp_window_size);
		}

		for (i = 0; i < my_rank; i++){
			temp_window_size = mpz_sizeinbase(temp, 2);
			mpz_add_ui(temp, temp, temp_window_size);
		}

		mpz_set(start, temp);

		temp_window_size = mpz_sizeinbase(start, 2);
		mpz_add_ui(local_end, start, temp_window_size);	

		mpz_nextprime(current_prime, start);
	}

	t2 = MPI_Wtime();
	totaltime = t2 - t1;
	MPI_Barrier(MPI_COMM_WORLD);
	if (my_rank == 0){
		char buf[0x1000];
		snprintf(buf, sizeof(buf), "time_%s", argv[1]);
		FILE *f = fopen(buf, "w");
		double other_totaltime = 0;
		fprintf(f, "0\t%1.2e\n", totaltime);
		for (source = 1; source < p; source++){
			MPI_Recv(&other_totaltime, 1, MPI_DOUBLE, source, tag, MPI_COMM_WORLD, &status);
			fprintf(f, "%d\t%1.2e\n", source, other_totaltime);
		}	
		fclose(f); 
	}
	else{
		MPI_Send(&totaltime, 1, MPI_DOUBLE, 0, tag, MPI_COMM_WORLD);
	}	
	MPI_Finalize();
	return 0;
}
Exemplo n.º 28
0
void print_thread_term (int i, int n, mpf_t term){

	gmp_printf("Thread ->(%d)<- calculou o [%d] termo, que vale: %F.f\n", i, n, term);

}
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);
}
/**
  * Algoritmo de Borwein
  *
  * a1 se aproxima do valor de 1/PI.
  * Cada iteração quadruplica o número de dígitos corretos.
  *
  */
void gmp_borwein()
{
  /*variáveis para calculo com respectivos valores iniciais*/
  mpf_t a0, a1, y0, y1, aux1, aux2;
  /*contador de iterações*/
  long unsigned int k=0;


  //mpf_set_default_prec(33220); /*define a precisao do float em bits*/
  mpf_set_default_prec(33219280);//(33219280); /*define a precisao do float em bits*/
  mpf_init(a0),mpf_init(a1),mpf_init(y0),mpf_init(y1),mpf_init(aux1),mpf_init(aux2); /*Inicializa as variáveis em 0*/

  /*seta os valores inicias das váriaveis de precisão variável*/
  /*a0 = 6-4*sqrt(2)*/
  mpf_set_ui(aux1,2);
  mpf_sqrt(aux1,aux1); /*sqrt(2)*/
  mpf_mul_ui(a0,aux1,4);
  mpf_ui_sub(a0,6,a0);

  //mpf_set_d(a0, 6-4*sqrt(2));
  mpf_sub_ui(y0,aux1,1); /*y0 = sqrt(2)-1*/

  while(k<12)
  {
    /*y1 = (1-sqrt(sqrt((1-pow(y0,4))))) / (1+sqrt(sqrt(1-pow(y0,4))));*/
    mpf_pow_ui(y1,y0,4); /*y1 = pow(y0,4)*/
    mpf_ui_sub(y1,1,y1); /*y1 = 1 - y1*/
    mpf_sqrt(y1,y1);
    mpf_sqrt(y1,y1);
    mpf_ui_sub(aux1,1,y1);
    mpf_add_ui(aux2,y1,1);
    mpf_div(y1,aux1,aux2);

    /*a1 = a0*pow(1 + y1,4) - pow(2,2*k+3)*y1*(1+y1+pow(y1,2));*/
    mpf_add_ui(a1,y1,1); /*a1 = y1+1*/
    mpf_pow_ui(a1,a1,4); /*a1 = a1^4*/
    mpf_mul(a1,a0,a1); /*a1 = a0*a1*/ 

    mpf_pow_ui(aux2,y1,2); /*aux2 = pow(y1,2)*/
    mpf_add(aux2,aux2,y1); /*aux2 += y1*/
    mpf_add_ui(aux2,aux2,1); /*aux2++*/
    mpf_mul(aux2,aux2,y1); /*aux2 *= y1*/

    mpf_set_ui(aux1,2); /* aux1=2 */
    mpf_pow_ui(aux1,aux1,2*k+3); /* aux1 = pow(aux1,2*k+3)*/

    mpf_mul(aux1,aux1,aux2); /*aux1 = aux1*aux2*/

    mpf_sub(a1,a1,aux1);

    
    /*troca os valores das variáveis de maneira eficiente*/
    mpf_swap(a0,a1);
    mpf_swap(y0,y1);
    
    k++;
  
    /*gmp_printf("k=%ld, y1=%.*Ff, 1/PI=%.*Ff\n", k, 20, y1, 20, a1);
    gmp_printf("a0=%.*Ff, y0=%.*Ff\n", 20, a0, 20, y0);*/
  }

  mpf_ui_div(a1,1,a1); /*PI=1/a1*/

  gmp_printf("%.*Ff\n",10000000,a1);

  mpf_clear(a0),mpf_clear(a1),mpf_clear(y0),mpf_clear(y1),mpf_clear(aux1),mpf_clear(aux2); /*Limpa as variáveis da memória*/

  
}