Beispiel #1
0
int
main (int argc, char **argv)
{
  mpz_t op1, op2, ref;
  int i, j, chain_len;
  gmp_randstate_t rands;
  mpz_t bs;
  unsigned long bsi, size_range;
  int reps = 200;

  if (argc == 2)
     reps = atoi (argv[1]);

  tests_start ();
  gmp_randinit_default(rands);

  check_data ();

  mpz_init (bs);
  mpz_init (op1);
  mpz_init (op2);
  mpz_init (ref);
  mpz_init (gcd1);
  mpz_init (gcd2);
  mpz_init (temp1);
  mpz_init (temp2);
  mpz_init (s);
  mpz_init (t);

  for (i = 0; i < reps; i++)
    {
      /* Generate plain operands with unknown gcd.  These types of operands
	 have proven to trigger certain bugs in development versions of the
	 gcd code.  The "hgcd->row[3].rsize > M" ASSERT is not triggered by
	 the division chain code below, but that is most likely just a result
	 of that other ASSERTs are triggered before it.  */

      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 16 + 2;

      mpz_urandomb (bs, rands, size_range);
      mpz_urandomb (op1, rands, mpz_get_ui (bs) + MIN_OPERAND_BITSIZE);
      mpz_urandomb (bs, rands, size_range);
      mpz_urandomb (op2, rands, mpz_get_ui (bs) + MIN_OPERAND_BITSIZE);

      mpz_urandomb (bs, rands, 2);
      bsi = mpz_get_ui (bs);
      if ((bsi & 1) != 0)
	mpz_neg (op1, op1);
      if ((bsi & 2) != 0)
	mpz_neg (op2, op2);

      one_test (op1, op2, NULL, i);

      /* Generate a division chain backwards, allowing otherwise unlikely huge
	 quotients.  */

      mpz_set_ui (op1, 0);
      mpz_urandomb (bs, rands, 32);
      mpz_urandomb (bs, rands, mpz_get_ui (bs) % 16 + 1);
      mpz_rrandomb (op2, rands, mpz_get_ui (bs));
      mpz_add_ui (op2, op2, 1);
      mpz_set (ref, op2);

      mpz_urandomb (bs, rands, 32);
      chain_len = mpz_get_ui (bs) % 50;

      for (j = 0; j < chain_len; j++)
	{
	  mpz_urandomb (bs, rands, 32);
	  mpz_urandomb (bs, rands, mpz_get_ui (bs) % 12 + 1);
	  mpz_rrandomb (temp2, rands, mpz_get_ui (bs) + 1);
	  mpz_add_ui (temp2, temp2, 1);
	  mpz_mul (temp1, op2, temp2);
	  mpz_add (op1, op1, temp1);

	  /* Don't generate overly huge operands.  */
	  if (SIZ (op1) > 1000)
	    break;

	  mpz_urandomb (bs, rands, 32);
	  mpz_urandomb (bs, rands, mpz_get_ui (bs) % 12 + 1);
	  mpz_rrandomb (temp2, rands, mpz_get_ui (bs) + 1);
	  mpz_add_ui (temp2, temp2, 1);
	  mpz_mul (temp1, op1, temp2);
	  mpz_add (op2, op2, temp1);

	  /* Don't generate overly huge operands.  */
	  if (SIZ (op2) > 1000)
	    break;
	}
      one_test (op1, op2, ref, i);
    }

  mpz_clear (bs);
  mpz_clear (op1);
  mpz_clear (op2);
  mpz_clear (ref);
  mpz_clear (gcd1);
  mpz_clear (gcd2);
  mpz_clear (temp1);
  mpz_clear (temp2);
  mpz_clear (s);
  mpz_clear (t);
  gmp_randclear(rands);
  tests_end ();
  exit (0);
}
void mpz_sqrtmp_r
	(mpz_ptr root, mpz_srcptr a, mpz_srcptr p)
{
	/* ? a \neq 0 */
	if (mpz_get_ui(a) != 0)
	{
		/* ? p = 3 (mod 4) */
		if (mpz_congruent_ui_p(p, 3L, 4L))
		{
			mpz_t foo;
			mpz_init_set(foo, p);
			mpz_add_ui(foo, foo, 1L);
			mpz_fdiv_q_2exp(foo, foo, 2L);
			mpz_powm(root, a, foo, p);
			mpz_clear(foo);
			return;
		}
		/* ! p = 1 (mod 4) */
		else
		{
			/* ! s = (p-1)/4 */
			mpz_t s;
			mpz_init_set(s, p);
			mpz_sub_ui(s, s, 1L);
			mpz_fdiv_q_2exp(s, s, 2L);
			/* ? p = 5 (mod 8) */
			if (mpz_congruent_ui_p(p, 5L, 8L))
			{
				mpz_t foo, b;
				mpz_init(foo);
				mpz_powm(foo, a, s, p);
				mpz_init_set(b, p);
				mpz_add_ui(b, b, 3L);
				mpz_fdiv_q_2exp(b, b, 3L);
				mpz_powm(root, a, b, p);
				/* ? a^{(p-1)/4} = 1 (mod p) */
				if (mpz_cmp_ui(foo, 1L) == 0)
				{
					mpz_clear(foo), mpz_clear(s), mpz_clear(b);
					return;
				}
				/* ! a^{(p-1)/4} = -1 (mod p) */
				else
				{
					do
						mpz_wrandomm(b, p);
					while (mpz_jacobi(b, p) != -1);
					mpz_powm(b, b, s, p);
					mpz_mul(root, root, b);
					mpz_mod(root, root, p);
					mpz_clear(foo), mpz_clear(s), mpz_clear(b);
					return;
				}
			}
			/* ! p = 1 (mod 8) */
			else
			{
				mpz_t foo, bar, b, t;
				mpz_init(foo), mpz_init(bar);
				mpz_powm(foo, a, s, p);
				/* while a^s = 1 (mod p) */
				while (mpz_cmp_ui(foo, 1L) == 0)
				{
					/* ? s odd */
					if (mpz_odd_p(s))
					{
						mpz_add_ui(s, s, 1L);
						mpz_fdiv_q_2exp(s, s, 1L);
						mpz_powm(root, a, s, p);
						mpz_clear(foo), mpz_clear(s);
						return;
					}
					/* ! s even */
					else
					{
						mpz_fdiv_q_2exp(s, s, 1L);
					}
					mpz_powm(foo, a, s, p);
				}
				/* ! a^s = -1 (mod p) */
				mpz_init(b);
				do
					mpz_wrandomm(b, p);
				while (mpz_jacobi(b, p) != -1);
				mpz_init_set(t, p);
				mpz_sub_ui(t, t, 1L);
				mpz_fdiv_q_2exp(t, t, 1L);
				/* while s even */
				while (mpz_even_p(s))
				{
					mpz_fdiv_q_2exp(s, s, 1L);
					mpz_fdiv_q_2exp(t, t, 1L);
					mpz_powm(foo, a, s, p);
					mpz_powm(bar, b, t, p);
					mpz_mul(foo, foo, bar);
					mpz_mod(foo, foo, p);
					mpz_set_si(bar, -1L);
					/* ? a^s * b^t = -1 (mod p) */
					if (mpz_congruent_p(foo, bar, p))
					{
						mpz_set(bar, p);
						mpz_sub_ui(bar, bar, 1L);
						mpz_fdiv_q_2exp(bar, bar, 1L);
						mpz_add(t, t, bar);
					}
				}
				mpz_add_ui(s, s, 1L);
				mpz_fdiv_q_2exp(s, s, 1L);
				mpz_fdiv_q_2exp(t, t, 1L);
				mpz_powm(foo, a, s, p);
				mpz_powm(bar, b, t, p);
				mpz_mul(root, foo, bar);
				mpz_mod(root, root, p);
				mpz_clear(foo), mpz_clear(bar);
				mpz_clear(s), mpz_clear(b), mpz_clear(t);
				return;
			}
		}
	}
	/* error, return zero root */
	mpz_set_ui(root, 0L);
}
Beispiel #3
0
/* get value as a ui, on the assumption it fits */
static int
e_mpq_get_ui_fits (mpq_srcptr q)
{
  return mpz_get_ui (mpq_numref (q));
}
Beispiel #4
0
int
main (int argc, char **argv)
{
  mpz_t base, exp, mod;
  mpz_t r1, r2, base2;
  mp_size_t base_size, exp_size, mod_size;
  unsigned long int exp2;
  int i;
  int reps = 100;
  gmp_randstate_ptr rands;
  mpz_t bs;
  unsigned long bsi, size_range;

  tests_start ();
  rands = RANDS;

  mpz_init (bs);

  if (argc == 2)
     reps = atoi (argv[1]);

  mpz_init (base);
  mpz_init (exp);
  mpz_init (mod);
  mpz_init (r1);
  mpz_init (r2);
  mpz_init (base2);

  for (i = 0; i < reps; i++)
    {
      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 18 + 2;

      do  /* Loop until mathematically well-defined.  */
	{
	  mpz_urandomb (bs, rands, size_range);
	  base_size = mpz_get_ui (bs);
	  mpz_rrandomb (base, rands, base_size);

	  mpz_urandomb (bs, rands, 6L);
	  exp_size = mpz_get_ui (bs);
	  mpz_rrandomb (exp, rands, exp_size);
	  exp2 = mpz_getlimbn (exp, (mp_size_t) 0);
	}
      while (mpz_cmp_ui (base, 0) == 0 && exp2 == 0);

      do
        {
	  mpz_urandomb (bs, rands, size_range);
	  mod_size = mpz_get_ui (bs);
	  mpz_rrandomb (mod, rands, mod_size);
	}
      while (mpz_cmp_ui (mod, 0) == 0);

      mpz_urandomb (bs, rands, 2);
      bsi = mpz_get_ui (bs);
      if ((bsi & 1) != 0)
	mpz_neg (base, base);

      /* printf ("%ld %ld\n", SIZ (base), SIZ (mod)); */

#if 0
      putc ('\n', stderr);
      debug_mp (base, -16);
      debug_mp (mod, -16);
#endif

      mpz_powm_ui (r1, base, exp2, mod);
      MPZ_CHECK_FORMAT (r1);

      mpz_set_ui (r2, 1);
      mpz_set (base2, base);

      mpz_mod (r2, r2, mod);	/* needed when exp==0 and mod==1 */
      while (exp2 != 0)
	{
	  if (exp2 % 2 != 0)
	    {
	      mpz_mul (r2, r2, base2);
	      mpz_mod (r2, r2, mod);
	    }
	  mpz_mul (base2, base2, base2);
	  mpz_mod (base2, base2, mod);
	  exp2 = exp2 / 2;
	}

#if 0
      debug_mp (r1, -16);
      debug_mp (r2, -16);
#endif

      if (mpz_cmp (r1, r2) != 0)
	{
	  fprintf (stderr, "\ntest %d: Incorrect results for operands:\n", i);
	  debug_mp (base, -16);
	  debug_mp (exp, -16);
	  debug_mp (mod, -16);
	  fprintf (stderr, "mpz_powm_ui result:\n");
	  debug_mp (r1, -16);
	  fprintf (stderr, "reference result:\n");
	  debug_mp (r2, -16);
	  abort ();
	}
    }

  mpz_clear (bs);
  mpz_clear (base);
  mpz_clear (exp);
  mpz_clear (mod);
  mpz_clear (r1);
  mpz_clear (r2);
  mpz_clear (base2);

  tests_end ();
  exit (0);
}
void filter_SPV(uint8 parity, uint8 *sieve, uint32 poly_id, uint32 bnum, 
				static_conf_t *sconf, dynamic_conf_t *dconf)
{
	//we have flagged this sieve offset as likely to produce a relation
	//nothing left to do now but check and see.
	int i;
	uint32 bound, tmp, prime, root1, root2;
	int smooth_num;
	sieve_fb *fb;
	sieve_fb_compressed *fbc;
	tiny_fb_element_siqs *fullfb_ptr, *fullfb = sconf->factor_base->tinylist;
	uint8 logp, bits;
	uint32 tmp1, tmp2, tmp3, tmp4, offset, report_num;

	fullfb_ptr = fullfb;
	if (parity)
	{
		fb = dconf->fb_sieve_n;
		fbc = dconf->comp_sieve_n;
	}
	else
	{
		fb = dconf->fb_sieve_p;
		fbc = dconf->comp_sieve_p;
	}

	//the minimum value for the current poly_a and poly_b occur at offset (-b + sqrt(N))/a
	//make it slightly easier for a number to go through full trial division for
	//nearby blocks, since these offsets are more likely to factor over the FB.
	mpz_sub(dconf->gmptmp1, sconf->sqrt_n, dconf->curr_poly->mpz_poly_b);
	mpz_tdiv_q(dconf->gmptmp1, dconf->gmptmp1, dconf->curr_poly->mpz_poly_a);
	if (mpz_sgn(dconf->gmptmp1) < 0)
		mpz_neg(dconf->gmptmp1, dconf->gmptmp1);

	mpz_tdiv_q_2exp(dconf->gmptmp1, dconf->gmptmp1, sconf->qs_blockbits);
	if (abs(bnum - mpz_get_ui(dconf->gmptmp1)) == 0)
		dconf->tf_small_cutoff = sconf->tf_small_cutoff - 5;
	else if (abs(bnum - mpz_get_ui(dconf->gmptmp1)) == 1)
		dconf->tf_small_cutoff = sconf->tf_small_cutoff - 3;
	else 
		dconf->tf_small_cutoff = sconf->tf_small_cutoff;

#ifdef QS_TIMING
	gettimeofday(&qs_timing_start, NULL);
#endif

	for (report_num = 0; report_num < dconf->num_reports; report_num++)
	{
		uint64 q64;
#ifdef USE_YAFU_TDIV
		z32 *tmp32 = &dconf->Qvals32[report_num];
#endif		

		//this one qualifies to check further, log that fact.
		dconf->num++;

		smooth_num = -1;

		//this one is close enough, compute 
		//Q(x)/a = (ax + b)^2 - N, where x is the sieve index
		//Q(x)/a = (ax + 2b)x + c;	
		offset = (bnum << sconf->qs_blockbits) + dconf->reports[report_num];

		//multiple precision arithmetic.  all the qstmp's are a global hack
		//but I don't want to Init/Free millions of times if I don't have to.

		mpz_mul_2exp(dconf->gmptmp2, dconf->curr_poly->mpz_poly_b, 1); 
		mpz_mul_ui(dconf->gmptmp1, dconf->curr_poly->mpz_poly_a, offset);

		if (parity)
			mpz_sub(dconf->Qvals[report_num], dconf->gmptmp1, dconf->gmptmp2); 
		else
			mpz_add(dconf->Qvals[report_num], dconf->gmptmp1, dconf->gmptmp2); 

		mpz_mul_ui(dconf->Qvals[report_num], dconf->Qvals[report_num], offset); 
		mpz_add(dconf->Qvals[report_num], dconf->Qvals[report_num], dconf->curr_poly->mpz_poly_c); 

		if (mpz_sgn(dconf->Qvals[report_num]) < 0)
		{
			mpz_neg(dconf->Qvals[report_num], dconf->Qvals[report_num]);
			dconf->fb_offsets[report_num][++smooth_num] = 0;
		}

		//we have two signs to worry about.  the sign of the offset tells us how to calculate ax + b, while
		//the sign of Q(x) tells us how to factor Q(x) (with or without a factor of -1)
		//the square root phase will need to know both.  fboffset holds the sign of Q(x).  the sign of the 
		//offset is stored standalone in the relation structure.
	
		//compute the bound for small primes.  if we can't find enough small
		//primes, then abort the trial division early because it is likely to fail to
		//produce even a partial relation.
		bits = sieve[dconf->reports[report_num]];
		bits = (255 - bits) + sconf->tf_closnuf + 1;

#ifdef USE_YAFU_TDIV
		mpz_to_z32(dconf->Qvals[report_num], tmp32);

		//take care of powers of two
		while ((tmp32->val[0] & 0x1) == 0)
		{
			zShiftRight32_x(tmp32, tmp32, 1);
			dconf->fb_offsets[report_num][++smooth_num] = 1;
			bits++;
		}

#else


		//take care of powers of two
		while (mpz_even_p(dconf->Qvals[report_num]))
		{
			//zShiftRight32_x(Q,Q,1);
			mpz_tdiv_q_2exp(dconf->Qvals[report_num], dconf->Qvals[report_num], 1);
			dconf->fb_offsets[report_num][++smooth_num] = 1;
			bits++;
		}
#endif

		i=2;
		//explicitly trial divide by small primes which we have not
		//been sieving.  because we haven't been sieving, their progressions
		//have not been updated and thus we can't use the faster methods
		//seen below.  fortunately, there shouldn't be many of these to test
		//to speed things up, use multiplication by inverse rather than 
		//division, and do things in batches of 4 so we can use
		//the whole cache line at once (16 byte structure)


		//do the small primes in optimized batches of 4
		bound = (sconf->sieve_small_fb_start - 4);
		
		while ((uint32)i < bound)
		{
			tmp1 = offset + fullfb_ptr->correction[i];
			q64 = (uint64)tmp1 * (uint64)fullfb_ptr->small_inv[i];
			tmp1 = q64 >> 32; 
			//at this point tmp1 is offset / prime
			tmp1 = offset - tmp1 * fullfb_ptr->prime[i];
			//now tmp1 is offset % prime
			i++;

			tmp2 = offset + fullfb_ptr->correction[i];
			q64 = (uint64)tmp2 * (uint64)fullfb_ptr->small_inv[i];
			tmp2 = q64 >> 32; 
			tmp2 = offset - tmp2 * fullfb_ptr->prime[i];
			i++;

			tmp3 = offset + fullfb_ptr->correction[i];
			q64 = (uint64)tmp3 * (uint64)fullfb_ptr->small_inv[i];
			tmp3 = q64 >> 32;
			tmp3 = offset - tmp3 * fullfb_ptr->prime[i];
			i++;

			tmp4 = offset + fullfb_ptr->correction[i];
			q64 = (uint64)tmp4 * (uint64)fullfb_ptr->small_inv[i];
			tmp4 = q64 >> 32; 
			tmp4 = offset - tmp4 * fullfb_ptr->prime[i];
			
			i -= 3;

			root1 = fbc->root1[i];
			root2 = fbc->root2[i];
			
			if (tmp1 == root1 || tmp1 == root2)
			{
				prime = fbc->prime[i];
				logp = fbc->logp[i];
				DIVIDE_ONE_PRIME
			}

			i++;

			root1 = fbc->root1[i];
			root2 = fbc->root2[i];
			
			if (tmp2 == root1 || tmp2 == root2)
			{
				prime = fbc->prime[i];
				logp = fbc->logp[i];
				DIVIDE_ONE_PRIME
			}

			i++;

			root1 = fbc->root1[i];
			root2 = fbc->root2[i];
			
			if (tmp3 == root1 || tmp3 == root2)
			{
				prime = fbc->prime[i];
				logp = fbc->logp[i];
				DIVIDE_ONE_PRIME
			}
Beispiel #6
0
void mpq_vec_to_digest(hash_t* digest, const mpq_t* vec) {
  for(int i = 0; i < NUM_HASH_CHUNKS; i++){
    digest->bit[i] = mpz_get_ui(mpq_numref(vec[i]));
    //gmp_printf("Vec->Digest %Qd %Lu\n", vec[i], digest->bit[i]);
  }
}
Beispiel #7
0
int
mpfi_sin (mpfi_ptr a, mpfi_srcptr b)
{
  int inexact_left, inexact_right, inexact = 0;
  mp_prec_t prec, prec_left, prec_right;
  mpfr_t tmp;
  mpz_t z, zmod4;
  mpz_t quad_left, quad_right;
  int ql_mod4, qr_mod4;

  if (MPFI_NAN_P (b)) {
    mpfr_set_nan (&(a->left));
    mpfr_set_nan (&(a->right));
    MPFR_RET_NAN;
  }

  if (MPFI_INF_P (b)) {
    /* the two endpoints are the same infinite */
    if ( mpfr_cmp (&(b->left), &(b->right)) == 0) {
      mpfr_set_nan (&(a->left));
      mpfr_set_nan (&(a->right));
      MPFR_RET_NAN;
    }
    mpfr_set_si (&(a->left), -1, MPFI_RNDD);
    mpfr_set_si (&(a->right), 1, MPFI_RNDU);
    return 0;
  }

  mpz_init (quad_left);
  mpz_init (quad_right);
  mpz_init (z);
  /* quad_left gives the quadrant where the left endpoint of b is */
  /* quad_left = floor (2 b->left / pi)                            */
  /* idem for quad_right and b->right                             */
  prec_left = mpfi_quadrant (quad_left, &(b->left));
  prec_right = mpfi_quadrant (quad_right, &(b->right));


  /* if there is at least one period in b, then a = [-1, 1] */
  mpz_sub (z, quad_right, quad_left);
  if (mpz_cmp_ui (z, 4) >= 0) {
    mpfr_set_si (&(a->left), -1, MPFI_RNDD);
    mpfr_set_si (&(a->right), 1, MPFI_RNDU);
    inexact = 0;
  }
  else {
    /* there is less than one period in b */
    /* let us discuss according to the position (quadrant) of the endpoints of b    */

    /* computing precision = maximal precision required to determine the          */
    /* relative position of the endpoints of b and of integer multiples of Pi / 2 */
    prec = mpfi_get_prec (a);
    if (prec_left > prec) prec = prec_left;
    if (prec_right > prec) prec = prec_right;

    mpz_add (z, quad_left, quad_right);
    /* z = quad_right + quad_left */

    mpz_init (zmod4);

    /* qr_mod4 gives the quadrant where the right endpoint of b is */
    /* qr_mod4 = floor (2 b->right / pi) mod 4 */
    mpz_mod_ui (zmod4, quad_right, 4);
    qr_mod4 = mpz_get_ui (zmod4);

    /* quad_left gives the quadrant where the left endpoint of b is */
    /* quad_left = floor (2 b->left / pi) mod 4 */
    mpz_mod_ui (zmod4, quad_left, 4);
    ql_mod4 = mpz_get_ui (zmod4);


    switch (qr_mod4) {
    case 0:
      switch (ql_mod4) {
      case 0:
      case 3:
	inexact_left = mpfr_sin (&(a->left), &(b->left), MPFI_RNDD);
	inexact_right = mpfr_sin (&(a->right), &(b->right), MPFI_RNDU);
	break;
      case 1:
	mpz_add_ui (z, z, 1);
	if (mpfi_cmp_sym_pi (z, &(b->left), &(b->right), prec) >= 0)
	  inexact_right = mpfr_sin (&(a->right), &(b->left), MPFI_RNDU);
	else
	  inexact_right = mpfr_sin (&(a->right), &(b->right), MPFI_RNDU);
	inexact_left = mpfr_set_si (&(a->left), -1, MPFI_RNDD);
	break;
      case 2:
	inexact_left = mpfr_set_si (&(a->left), -1, MPFI_RNDD);
	inexact_right = mpfr_sin (&(a->right), &(b->right), MPFI_RNDU);
	break;
      }
      break;
    case 1:
      switch (ql_mod4) {
      case 0:
	mpz_add_ui (z, z, 1);
	if (mpfi_cmp_sym_pi (z, &(b->right), &(b->left), prec) >= 0)
	  inexact_left = mpfr_sin (&(a->left), &(b->left), MPFI_RNDD);
	else
	  inexact_left = mpfr_sin (&(a->left), &(b->right), MPFI_RNDD);
	inexact_right = mpfr_set_si (&(a->right), 1, MPFI_RNDU);
	break;
      case 1:
        mpfr_init2 (tmp, mpfr_get_prec (&(a->left)));
	inexact_left = mpfr_sin (tmp, &(b->right), MPFI_RNDD);
	inexact_right = mpfr_sin (&(a->right), &(b->left), MPFI_RNDU);
	mpfr_set (&(a->left), tmp, MPFI_RNDD); /* exact */
        mpfr_clear (tmp);
	break;
      case 2:
	inexact_left = mpfr_set_si (&(a->left), -1, MPFI_RNDD);
	inexact_right = mpfr_set_si (&(a->right), 1, MPFI_RNDU);
	break;
      case 3:
	inexact_left = mpfr_sin (&(a->left), &(b->left), MPFI_RNDD);
	inexact_right = mpfr_set_si (&(a->right), 1, MPFI_RNDU);
	break;
      }
      break;
    case 2:
      switch (ql_mod4) {
      case 0:
	inexact_left = mpfr_sin (&(a->left), &(b->right), MPFI_RNDD);
	inexact_right = mpfr_set_si (&(a->right), 1, MPFI_RNDU);
	break;
      case 1:
      case 2:
        mpfr_init2 (tmp, mpfr_get_prec (&(a->left)));
	inexact_left = mpfr_sin (tmp, &(b->right), MPFI_RNDD);
	inexact_right = mpfr_sin (&(a->right), &(b->left), MPFI_RNDU);
	mpfr_set (&(a->left), tmp, MPFI_RNDD); /* exact */
        mpfr_clear (tmp);
	break;
      case 3:
	mpz_add_ui (z, z, 1);
	if (mpfi_cmp_sym_pi (z, &(b->left), &(b->right), prec) >= 0)
	  inexact_left = mpfr_sin (&(a->left), &(b->left), MPFI_RNDD);
	else
	  inexact_left = mpfr_sin (&(a->left), &(b->right), MPFI_RNDD);
	inexact_right = mpfr_set_si (&(a->right), 1, MPFI_RNDU);
	break;
      }
      break;
    case 3:
      switch (ql_mod4) {
      case 0:
	inexact_left = mpfr_set_si (&(a->left), -1, MPFI_RNDD);
	inexact_right = mpfr_set_si (&(a->right), 1, MPFI_RNDU);
	break;
      case 1:
	inexact_right = mpfr_sin (&(a->right), &(b->left), MPFI_RNDU);
	inexact_left = mpfr_set_si (&(a->left), -1, MPFI_RNDD);
	break;
      case 2:
	mpz_add_ui (z, z, 1);
	if (mpfi_cmp_sym_pi (z, &(b->right), &(b->left), prec) >= 0)
	  inexact_right = mpfr_sin (&(a->right), &(b->left), MPFI_RNDU);
	else
	  inexact_right = mpfr_sin (&(a->right), &(b->right), MPFI_RNDU);
	inexact_left = mpfr_set_si (&(a->left), -1, MPFI_RNDD);
	break;
      case 3:
	inexact_left = mpfr_sin (&(a->left), &(b->left), MPFI_RNDD);
	inexact_right = mpfr_sin (&(a->right), &(b->right), MPFI_RNDU);
	break;
      }
      break;
    }

    if (inexact_left) inexact = 1;
    if (inexact_right) inexact += 2;

    mpz_clear (zmod4);
  }

  mpz_clear (quad_left);
  mpz_clear (quad_right);
  mpz_clear (z);

  return inexact;
}
// Return a LookupData struct with relevant fields set for the given terminal
//
// Set lookup_data->index to -1 if no match, to match expected output of
// indexInTerminalGroup, which calls this function to perform the lookup.
//
// NOTE: This function assumes that terminals_size_ is accurate so we can
// iterate up to terminals_size_ entries from the start of the group
// (terminal_data_) without anything horrible happening.  Otherwise, we should
// check the return values from ReadLineFromCharArray and ParseNonterminalLine
// to make sure they work correctly.
//
// Die on failure to parse source_ids
//
LookupData* SeenTerminalGroup::lookup(const char *terminal) const {
  // just for debug output
  char space[1024];
  char *read_buffer = space;

  LookupData *lookup_data = new LookupData;

  mpz_init(lookup_data->index);
  unsigned long int index = 0;
  unsigned long int terminalsSize = mpz_get_ui(terminals_size_);
  const char* current_data_position = group_data_start_;
  size_t bytes_remaining = group_data_size_;

  // Iterate over the group, looking for the input string
  while(index < terminalsSize) {
    unsigned int bytes_read;
    grammartools::ReadLineFromCharArray2(current_data_position,
                                        bytes_read);
    // Parse the line
    const char *read_terminal, *source_ids;
    double probability;
    // just for debug output
    assert(bytes_read + 1 <= 1024);
    strncpy(read_buffer, current_data_position, bytes_read);
    read_buffer[bytes_read] = 0;

    grammartools::ParseNonterminalLine(current_data_position, bytes_read, &read_terminal,
                                       probability, &source_ids);

    auto len = strlen(terminal);
    if ((len == strlen(read_terminal)) && (strncmp(terminal, read_terminal, len) == 0)) {
      lookup_data->parse_status = kCanParse;
      if (probability_ != probability) {
        fprintf(stderr,
          "Probability of terminal group doesn't match in line %s in "
          "SeenTerminalGroup::lookup (should be %f, found %f)!\n",
          read_buffer, probability_, probability);
        exit(EXIT_FAILURE);
      }
      lookup_data->probability = probability_;
      // index is already set correctly
      if (!grammartools::AddSourceIDsFromString(source_ids, 
                                                lookup_data->source_ids)) {
        fprintf(stderr,
          "Could not parse source ids %s in line %s in "
          "SeenTerminalGroup::lookup!\n",
          source_ids, read_buffer);
        exit(EXIT_FAILURE);
      }
      mpz_set_ui(lookup_data->index, index);
      return lookup_data;
    }

    // Increment counters
    index++;
    current_data_position += bytes_read;
    bytes_remaining -= bytes_read;
  }

  // If we are here, then terminal was not found
  lookup_data->parse_status = kTerminalNotFound;
  lookup_data->probability = -1;
  mpz_set_si(lookup_data->index, -1);
  return lookup_data;
}
Beispiel #9
0
int main(void)
{
   int i, result;
   flint_rand_t state;
   mp_limb_t d;
   mpz_t d_m;
   printf("is_prime....");
   fflush(stdout);
   
   flint_randinit(state);
  
   for (i = 0; i < 100000; i++) /* Test that primes pass the test */
   {
      mpz_init(d_m);

      do
      {
         d = n_randtest(state) | 1;
         mpz_set_ui(d_m, d);
         mpz_nextprime(d_m, d_m);
         d = mpz_get_ui(d_m);
      } while (mpz_size(d_m) > 1);

      result = n_is_prime(d);
      if (!result)
      {
         printf("FAIL:\n");
         printf("d = %lu is declared composite\n", d); 
         abort();
      }

      mpz_clear(d_m);
   }
         
   for (i = 0; i < 100000; i++) /* Test that composites do not pass */
   {
      mpz_init(d_m);

      do
      {
         d = n_randtest(state) | 1;
         if (d == 1UL) d++;
         mpz_set_ui(d_m, d);
      } while (mpz_probab_prime_p(d_m, 12));

      result = !n_is_prime(d);
      if (!result)
      {
         printf("FAIL:\n");
         printf("d = %lu is declared prime\n", d); 
         abort();
      }

      mpz_clear(d_m);
   }

   flint_randclear(state);

   printf("PASS\n");
   return 0;
}
Beispiel #10
0
int
mpz_probab_prime_p (mpz_srcptr n, int reps)
{
  mp_limb_t r;
  mpz_t n2;

  /* Handle small and negative n.  */
  if (mpz_cmp_ui (n, 1000000L) <= 0)
    {
      int is_prime;
      if (mpz_cmpabs_ui (n, 1000000L) <= 0)
	{
	  is_prime = isprime (mpz_get_ui (n));
	  return is_prime ? 2 : 0;
	}
      /* Negative number.  Negate and fall out.  */
      PTR(n2) = PTR(n);
      SIZ(n2) = -SIZ(n);
      n = n2;
    }

  /* If n is now even, it is not a prime.  */
  if ((mpz_get_ui (n) & 1) == 0)
    return 0;

#if defined (PP)
  /* Check if n has small factors.  */
#if defined (PP_INVERTED)
  r = MPN_MOD_OR_PREINV_MOD_1 (PTR(n), (mp_size_t) SIZ(n), (mp_limb_t) PP,
                               (mp_limb_t) PP_INVERTED);
#else
  r = mpn_mod_1 (PTR(n), (mp_size_t) SIZ(n), (mp_limb_t) PP);
#endif
  if (r % 3 == 0
#if BITS_PER_MP_LIMB >= 4
      || r % 5 == 0
#endif
#if BITS_PER_MP_LIMB >= 8
      || r % 7 == 0
#endif
#if BITS_PER_MP_LIMB >= 16
      || r % 11 == 0 || r % 13 == 0
#endif
#if BITS_PER_MP_LIMB >= 32
      || r % 17 == 0 || r % 19 == 0 || r % 23 == 0 || r % 29 == 0
#endif
#if BITS_PER_MP_LIMB >= 64
      || r % 31 == 0 || r % 37 == 0 || r % 41 == 0 || r % 43 == 0
      || r % 47 == 0 || r % 53 == 0
#endif
      )
    {
      return 0;
    }
#endif /* PP */

  /* Do more dividing.  We collect small primes, using umul_ppmm, until we
     overflow a single limb.  We divide our number by the small primes product,
     and look for factors in the remainder.  */
  {
    unsigned long int ln2;
    unsigned long int q;
    mp_limb_t p1, p0, p;
    unsigned int primes[15];
    int nprimes;

    nprimes = 0;
    p = 1;
    ln2 = mpz_sizeinbase (n, 2);	/* FIXME: tune this limit */
    for (q = PP_FIRST_OMITTED; q < ln2; q += 2)
      {
	if (isprime (q))
	  {
	    umul_ppmm (p1, p0, p, q);
	    if (p1 != 0)
	      {
		r = MPN_MOD_OR_MODEXACT_1_ODD (PTR(n), (mp_size_t) SIZ(n), p);
		while (--nprimes >= 0)
		  if (r % primes[nprimes] == 0)
		    {
		      ASSERT_ALWAYS (mpn_mod_1 (PTR(n), (mp_size_t) SIZ(n), (mp_limb_t) primes[nprimes]) == 0);
		      return 0;
		    }
		p = q;
		nprimes = 0;
	      }
	    else
	      {
		p = p0;
	      }
	    primes[nprimes++] = q;
	  }
      }
  }

  /* Perform a number of Miller-Rabin tests.  */
  return mpz_millerrabin (n, reps);
}
int
main (int argc, char **argv)
{
  mpz_t dividend;
  mpz_t quotient, remainder;
  mpz_t quotient2, remainder2;
  mpz_t temp;
  mp_size_t dividend_size;
  unsigned long divisor;
  int i;
  int reps = 10000;
  gmp_randstate_ptr rands;
  mpz_t bs;
  unsigned long bsi, size_range;
  unsigned long r_rq, r_q, r_r, r;

  tests_start ();
  rands = RANDS;

  mpz_init (bs);

  if (argc == 2)
     reps = atoi (argv[1]);

  mpz_init (dividend);
  mpz_init (quotient);
  mpz_init (remainder);
  mpz_init (quotient2);
  mpz_init (remainder2);
  mpz_init (temp);

  for (i = 0; i < reps; i++)
    {
      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 10 + 2; /* 0..2047 bit operands */

      do
	{
	  mpz_rrandomb (bs, rands, 64);
	  divisor = mpz_get_ui (bs);
	}
      while (divisor == 0);

      mpz_urandomb (bs, rands, size_range);
      dividend_size = mpz_get_ui (bs);
      mpz_rrandomb (dividend, rands, dividend_size);

      mpz_urandomb (bs, rands, 2);
      bsi = mpz_get_ui (bs);
      if ((bsi & 1) != 0)
	mpz_neg (dividend, dividend);

      /* printf ("%ld\n", SIZ (dividend)); */

      r_rq = mpz_cdiv_qr_ui (quotient, remainder, dividend, divisor);
      r_q = mpz_cdiv_q_ui (quotient2, dividend, divisor);
      r_r = mpz_cdiv_r_ui (remainder2, dividend, divisor);
      r = mpz_cdiv_ui (dividend, divisor);

      /* First determine that the quotients and remainders computed
	 with different functions are equal.  */
      if (mpz_cmp (quotient, quotient2) != 0)
	dump_abort ("quotients from mpz_cdiv_qr_ui and mpz_cdiv_q_ui differ",
		    dividend, divisor);
      if (mpz_cmp (remainder, remainder2) != 0)
	dump_abort ("remainders from mpz_cdiv_qr_ui and mpz_cdiv_r_ui differ",
		    dividend, divisor);

      /* Check if the sign of the quotient is correct.  */
      if (mpz_cmp_ui (quotient, 0) != 0)
	if ((mpz_cmp_ui (quotient, 0) < 0)
	    != (mpz_cmp_ui (dividend, 0) < 0))
	dump_abort ("quotient sign wrong", dividend, divisor);

      /* Check if the remainder has the opposite sign as the (positive) divisor
	 (quotient rounded towards minus infinity).  */
      if (mpz_cmp_ui (remainder, 0) != 0)
	if (mpz_cmp_ui (remainder, 0) > 0)
	  dump_abort ("remainder sign wrong", dividend, divisor);

      mpz_mul_ui (temp, quotient, divisor);
      mpz_add (temp, temp, remainder);
      if (mpz_cmp (temp, dividend) != 0)
	dump_abort ("n mod d != n - [n/d]*d", dividend, divisor);

      mpz_abs (remainder, remainder);
      if (mpz_cmp_ui (remainder, divisor) >= 0)
	dump_abort ("remainder greater than divisor", dividend, divisor);

      if (mpz_cmp_ui (remainder, r_rq) != 0)
	dump_abort ("remainder returned from mpz_cdiv_qr_ui is wrong",
		    dividend, divisor);
      if (mpz_cmp_ui (remainder, r_q) != 0)
	dump_abort ("remainder returned from mpz_cdiv_q_ui is wrong",
		    dividend, divisor);
      if (mpz_cmp_ui (remainder, r_r) != 0)
	dump_abort ("remainder returned from mpz_cdiv_r_ui is wrong",
		    dividend, divisor);
      if (mpz_cmp_ui (remainder, r) != 0)
	dump_abort ("remainder returned from mpz_cdiv_ui is wrong",
		    dividend, divisor);
    }

  mpz_clear (bs);
  mpz_clear (dividend);
  mpz_clear (quotient);
  mpz_clear (remainder);
  mpz_clear (quotient2);
  mpz_clear (remainder2);
  mpz_clear (temp);

  tests_end ();
  exit (0);
}
/* assuming slaves (workers)) are all homogenous, let them all do the calculations
 regarding primes sieving, calculating the smoothness base and the modular roots */
int main(int argc, char **argv) {
	MPI_Init(&argc, &argv);
	MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
	MPI_Comm_size(MPI_COMM_WORLD, &mpi_group_size);
	int len;
	MPI_Get_processor_name(processor_name, &len);

	gettimeofday(&start_global, NULL);
	print_lib_version();

	mpz_init(N);
	mpz_t B;
	mpz_init(B);

	unsigned long int uBase;
	int64_t nb_primes;
	modular_root_t *modular_roots;

	uint64_t i, j;

	if (argc < 2) {
		PRINT(my_rank, "usage: %s Number_to_factorize\n", argv[0]);
		exit(2);
	}

	if (mpz_init_set_str(N, argv[1], 10) == -1) {
		PRINT(my_rank, "Cannot load N %s\n", argv[1]);
		exit(2);
	}

	mpz_t sqrtN, rem;
	mpz_init(sqrtN);
	mpz_init(rem);
	mpz_sqrtrem(sqrtN, rem, N);

	if (mpz_cmp_ui(rem, 0) != 0) /* if not perfect square, calculate the ceiling */
		mpz_add_ui(sqrtN, sqrtN, 1);
	else /* N is a perfect square, factored! */
	{
		PRINT(my_rank, "\n<<<[FACTOR]>>> %s\n", mpz_get_str(NULL, 10, sqrtN));
		return 0;
	}

	if (mpz_probab_prime_p(N, 10) > 0) /* don't bother factoring */
	{
		PRINT(my_rank, "N:%s is prime\n", mpz_get_str(NULL, 10, N));
		exit(0);
	}

	OPEN_LOG_FILE("freq");

//--------------------------------------------------------
//  calculate the smoothness base for the given N
//--------------------------------------------------------
	get_smoothness_base(B, N); /* if N is too small, the program will surely fail, please consider a pen and paper instead */
	uBase = mpz_get_ui(B);
	PRINT(my_rank, "n: %s\tBase: %s\n",
			mpz_get_str(NULL, 10, N), mpz_get_str(NULL, 10, B));

//--------------------------------------------------------
// sieve primes that are less than the smoothness base using Eratosthenes sieve
//--------------------------------------------------------
	START_TIMER();
	nb_primes = sieve_primes_up_to((int64_t) (uBase));

	PRINT(my_rank, "\tPrimes found %" PRId64 " [Smoothness Base %lu]\n",
			nb_primes, uBase);
	STOP_TIMER_PRINT_TIME("\tEratosthenes Sieving done");

//--------------------------------------------------------
// fill the primes array with primes to which n is a quadratic residue
//--------------------------------------------------------
	START_TIMER();
	primes = calloc(nb_primes, sizeof(int64_t));
	nb_qr_primes = fill_primes_with_quadratic_residue(primes, N);

	/*for(i=0; i<nb_qr_primes; i++)
	 PRINT(my_rank, "%" PRId64 "\n", primes[i]);*/

	PRINT(my_rank, "\tN-Quadratic primes found %" PRId64 "\n", nb_qr_primes);
	STOP_TIMER_PRINT_TIME("\tQuadratic prime filtering done");

//--------------------------------------------------------
// calculate modular roots
//--------------------------------------------------------
	START_TIMER();
	modular_roots = calloc(nb_qr_primes, sizeof(modular_root_t));
	mpz_t tmp, r1, r2;
	mpz_init(tmp);
	mpz_init(r1);
	mpz_init(r2);

	for (i = 0; i < nb_qr_primes; i++) {
		mpz_set_ui(tmp, (unsigned long) primes[i]);
		mpz_sqrtm(r1, N, tmp); /* calculate the modular root */
		mpz_neg(r2, r1); /* -q mod n */
		mpz_mod(r2, r2, tmp);

		modular_roots[i].root1 = mpz_get_ui(r1);
		modular_roots[i].root2 = mpz_get_ui(r2);
	}
	mpz_clear(tmp);
	mpz_clear(r1);
	mpz_clear(r2);
	STOP_TIMER_PRINT_TIME("Modular roots calculation done");

//--------------------------------------------------------
//         ***** initialize the matrix *****
//--------------------------------------------------------
	if (my_rank == 0) /* only the master have the matrix */
	{
		START_TIMER();
		init_matrix(&matrix, nb_qr_primes + NB_VECTORS_OFFSET, nb_qr_primes);
		mpz_init2(tmp_matrix_row, nb_qr_primes);
		STOP_TIMER_PRINT_TIME("Matrix initialized");
	}

//--------------------------------------------------------
// [Sieving] - everyones sieves including the master
//--------------------------------------------------------
	START_TIMER();

	mpz_t x, sieving_index, next_sieving_index, relative_start, global_step;
	unsigned long ui_index, SIEVING_STEP = 50000; /* we sieve for 50000 elements at each loop */
	int LOCAL_SIEVING_ROUNDS = 10; /* number of iterations a worker sieves before communicating results to the master */
	unsigned long sieving_round = 0;
	unsigned long nb_big_rounds = 0;

	uint64_t p_pow;
	smooth_number_t *x_squared;

	x_squared = calloc(SIEVING_STEP, sizeof(smooth_number_t));

	if (my_rank == 0)
		smooth_numbers = calloc(nb_qr_primes + NB_VECTORS_OFFSET,
				sizeof(smooth_number_t));
	else
		temp_slaves_smooth_numbers = calloc(500, sizeof(smooth_number_t));
	/* TODO: this is not properly correct, using a linkedlist is better to keep track of temporary
	 * smooth numbers at the slaves nodes however it's pretty rare to find 500 smooth numbers in
	 * 50000 * 10 interval. */

	mpz_init_set(x, sqrtN);
	mpz_init(global_step);
	mpz_init(relative_start);
	mpz_init(sieving_index);
	mpz_init(next_sieving_index);

	mpz_t p;
	mpz_init(p);
	mpz_t str;
	mpz_init_set(str, sieving_index);
	PRINT(my_rank, "\n[%s] Sieving ...\n", processor_name);

//--------------------------------------------------------
// Init before sieving
//--------------------------------------------------------
	for (i = 0; i < SIEVING_STEP; i++) {
		mpz_init(x_squared[i].value_x);
		mpz_init(x_squared[i].value_x_squared);

		mpz_init2(x_squared[i].factors_vect, nb_qr_primes);
		mpz_add_ui(x, x, 1);
	}

	int nb_smooth_per_round = 0;
	char s[512];

//--------------------------------------------------------
// WHILE smooth numbers found less than the primes in the smooth base + NB_VECTORS_OFFSET for master
// Or master asked for more smooth numbers from slaves
//--------------------------------------------------------
	while (1) {
		mpz_set_ui(global_step, nb_big_rounds); /* calculates the coordinate where the workers start sieving from */
		mpz_mul_ui(global_step, global_step, (unsigned long) mpi_group_size);
		mpz_mul_ui(global_step, global_step, SIEVING_STEP);
		mpz_mul_ui(global_step, global_step, LOCAL_SIEVING_ROUNDS);
		mpz_add(global_step, global_step, sqrtN);

		mpz_set_ui(relative_start, SIEVING_STEP);
		mpz_mul_ui(relative_start, relative_start, LOCAL_SIEVING_ROUNDS);
		mpz_mul_ui(relative_start, relative_start, (unsigned long) my_rank);
		mpz_add(relative_start, relative_start, global_step);

		mpz_set(sieving_index, relative_start);
		mpz_set(next_sieving_index, relative_start);

		for (sieving_round = 0; sieving_round < LOCAL_SIEVING_ROUNDS; /* each slave sieves for LOCAL_SIEVING_ROUNDS rounds */
		sieving_round++) {
			nb_smooth_per_round = 0;
			mpz_set(x, next_sieving_index); /* sieve numbers from sieving_index to sieving_index + sieving_step */
			mpz_set(sieving_index, next_sieving_index);

			if (my_rank == 0) {
				printf("\r");
				printf(
						"\t\tSieving at: %s30 <--> Smooth numbers found: %" PRId64 "/%" PRId64 "",
						mpz_get_str(NULL, 10, sieving_index),
						nb_global_smooth_numbers_found, nb_qr_primes);
				fflush(stdout);
			}

			for (i = 0; i < SIEVING_STEP; i++) {
				mpz_set(x_squared[i].value_x, x);

				mpz_pow_ui(x_squared[i].value_x_squared, x, 2); /* calculate value_x_squared <- x²-n */
				mpz_sub(x_squared[i].value_x_squared,
						x_squared[i].value_x_squared, N);

				mpz_clear(x_squared[i].factors_vect);
				mpz_init2(x_squared[i].factors_vect, nb_qr_primes); /* reconstruct a new fresh 0ed vector of size nb_qr_primes bits */

				mpz_add_ui(x, x, 1);
			}
			mpz_set(next_sieving_index, x);

//--------------------------------------------------------
// eliminate factors in the x_squared array, those who are 'destructed' to 1 are smooth
//--------------------------------------------------------
			for (i = 0; i < nb_qr_primes; i++) {
				mpz_set_ui(p, (unsigned long) primes[i]);
				mpz_set(x, sieving_index);

				/* get the first multiple of p that is directly larger that sieving_index
				 * Quadratic SIEVING: all elements from this number and in positions multiples of root1 and root2
				 * are also multiples of p */
				get_sieving_start_index(x, x, p, modular_roots[i].root1);
				mpz_set(str, x);
				mpz_sub(x, x, sieving_index); /* x contains index of first number that is divisible by p */

				for (j = mpz_get_ui(x); j < SIEVING_STEP; j += primes[i]) {
					p_pow = mpz_remove(x_squared[j].value_x_squared,
							x_squared[j].value_x_squared, p); /* eliminate all factors of p */

					if (p_pow & 1) /* mark bit if odd power of p exists in this x_squared[j] */
					{
						mpz_setbit(x_squared[j].factors_vect, i);
					}

					if (mpz_cmp_ui(x_squared[j].value_x_squared, 1) == 0) {
						save_smooth_number(x_squared[j]);
						nb_smooth_per_round++;
					}
					/* sieve next element located p steps from here */
				}

				/* same goes for root2 */
				if (modular_roots[i].root2 == modular_roots[i].root1)
					continue;

				mpz_set(x, sieving_index);

				get_sieving_start_index(x, x, p, modular_roots[i].root2);
				mpz_set(str, x);
				mpz_sub(x, x, sieving_index);

				for (j = mpz_get_ui(x); j < SIEVING_STEP; j += primes[i]) {
					p_pow = mpz_remove(x_squared[j].value_x_squared,
							x_squared[j].value_x_squared, p);

					if (p_pow & 1) {
						mpz_setbit(x_squared[j].factors_vect, i);
					}

					if (mpz_cmp_ui(x_squared[j].value_x_squared, 1) == 0) {
						save_smooth_number(x_squared[j]);
						nb_smooth_per_round++;
					}
				}
			}
		}

		if (my_rank == 0) /* master gathers smooth numbers from slaves */
		{
			gather_smooth_numbers();
			notify_slaves();
		} else /* slaves send their smooth numbers to master */
		{
			send_smooth_numbers_to_master();
			nb_global_smooth_numbers_found = get_server_notification();
		}

		if (nb_global_smooth_numbers_found >= nb_qr_primes + NB_VECTORS_OFFSET)
			break;

		nb_big_rounds++;
	}

	STOP_TIMER_PRINT_TIME("\nSieving DONE");

	if (my_rank == 0) {
		uint64_t t = 0;

//--------------------------------------------------------
//the matrix ready, start Gauss elimination. The Matrix is filled on the call of save_smooth_number()
//--------------------------------------------------------
		START_TIMER();
		gauss_elimination(&matrix);
		STOP_TIMER_PRINT_TIME("\nGauss elimination done");

		uint64_t row_index = nb_qr_primes + NB_VECTORS_OFFSET - 1; /* last row in the matrix */
		int nb_linear_relations = 0;
		mpz_t linear_relation_z, solution_z;
		mpz_init(linear_relation_z);
		mpz_init(solution_z);

		get_matrix_row(linear_relation_z, &matrix, row_index--); /* get the last few rows in the Gauss eliminated matrix*/
		while (mpz_cmp_ui(linear_relation_z, 0) == 0) {
			nb_linear_relations++;
			get_matrix_row(linear_relation_z, &matrix, row_index--);
		}

		PRINT(my_rank, "\tLinear dependent relations found : %d\n",
				nb_linear_relations);

//--------------------------------------------------------
// Factor
//--------------------------------------------------------
		//We use the last linear relation to reconstruct our solution
		START_TIMER();
		PRINT(my_rank, "%s", "\nFactorizing..\n");
		mpz_t solution_X, solution_Y;
		mpz_init(solution_X);
		mpz_init(solution_Y);

		/* we start testing from the first linear relation encountered in the matrix */
		for (j = nb_linear_relations; j > 0; j--) {
			PRINT(my_rank, "Trying %d..\n", nb_linear_relations - j + 1);
			mpz_set_ui(solution_X, 1);
			mpz_set_ui(solution_Y, 1);

			get_identity_row(solution_z, &matrix,
					nb_qr_primes + NB_VECTORS_OFFSET - j + 1);

			for (i = 0; i < nb_qr_primes; i++) {
				if (mpz_tstbit(solution_z, i)) {
					mpz_mul(solution_X, solution_X, smooth_numbers[i].value_x);
					mpz_mod(solution_X, solution_X, N); /* reduce x to modulo N */

					mpz_mul(solution_Y, solution_Y,
							smooth_numbers[i].value_x_squared);
					/*TODO: handling huge stuff here, there is no modulo N like in the solution_X case!
					 * eliminate squares as long as you go*/
				}
			}

			mpz_sqrt(solution_Y, solution_Y);
			mpz_mod(solution_Y, solution_Y, N); /* y = sqrt(MUL(xi²-n)) mod N */

			mpz_sub(solution_X, solution_X, solution_Y);

			mpz_gcd(solution_X, solution_X, N);

			if (mpz_cmp(solution_X, N) != 0 && mpz_cmp_ui(solution_X, 1) != 0) /* factor can be 1 or N, try another relation */
				break;
		}
		mpz_cdiv_q(solution_Y, N, solution_X);

		PRINT(my_rank, "\n>>>>>>>>>>> FACTORED %s =\n",
				mpz_get_str(NULL, 10, N));
		PRINT(
				my_rank,
				"\tFactor 1: %s \n\tFactor 2: %s",
				mpz_get_str(NULL, 10, solution_X), mpz_get_str(NULL, 10, solution_Y));

		sprintf(s, "\n>>>>>>>>>>> FACTORED %s =\n", mpz_get_str(NULL, 10, N));
		APPEND_TO_LOG_FILE(s);
		sprintf(s, "\tFactor 1: %s \n\tFactor 2: %s",
				mpz_get_str(NULL, 10, solution_X),
				mpz_get_str(NULL, 10, solution_Y));
		APPEND_TO_LOG_FILE(s);

		gettimeofday(&end_global, NULL);
		timersub(&end_global, &start_global, &elapsed);
		sprintf(s, "****** TOTAL TIME: %.3f ms\n",
				elapsed.tv_sec * 1000 + elapsed.tv_usec / (double) 1000);
		APPEND_TO_LOG_FILE(s);

		STOP_TIMER_PRINT_TIME("\nFactorizing done");
	}

	PRINT(my_rank, "%s", "\nCleaning memory..\n");

	/********************** clear the x_squared array **********************/
	for (i = 0; i < SIEVING_STEP; i++) {
		mpz_clear(x_squared[i].value_x);
		mpz_clear(x_squared[i].value_x_squared);
		//free(x_squared[i].factors_exp);
		mpz_clear(x_squared[i].factors_vect);
	}
	free(x_squared);
	/********************** clear the x_squared array **********************/

	free(modular_roots);
	/********************** clear the smooth_numbers array **********************/
	if (my_rank == 0) {
		for (i = 0; i < nb_qr_primes + NB_VECTORS_OFFSET; i++) {
			mpz_clear(smooth_numbers[i].value_x);
			mpz_clear(smooth_numbers[i].value_x_squared);
			mpz_clear(smooth_numbers[i].factors_vect);
			//free(smooth_numbers[i].factors_exp);
		}
		free(smooth_numbers);
	} else {
		for (i = 0; i < 500; i++) {
			mpz_clear(temp_slaves_smooth_numbers[i].value_x);
			mpz_clear(temp_slaves_smooth_numbers[i].value_x_squared);
			mpz_clear(temp_slaves_smooth_numbers[i].factors_vect);
		}
		free(temp_slaves_smooth_numbers);
	}
	/********************** clear the smooth_numbers array **********************/

	free(primes);
	/********************** clear mpz _t **********************/mpz_clear(B);
	mpz_clear(N);
	sqrtN, rem;
	mpz_clear(x);
	mpz_clear(sieving_index);
	mpz_clear(next_sieving_index);
	mpz_clear(p);
	mpz_clear(str);
	/********************** clear mpz _t **********************/

	free_matrix(&matrix);

	gettimeofday(&end_global, NULL);
	timersub(&end_global, &start_global, &elapsed);
	PRINT(my_rank, "****** TOTAL TIME: %.3f ms\n",
			elapsed.tv_sec * 1000 + elapsed.tv_usec / (double) 1000);
	show_mem_usage();

	MPI_Finalize();

	return 0;
}
Beispiel #13
0
int main(void)
{
   int i, result;
   flint_rand_t state;
   
   printf("is_oddprime_binary....");
   fflush(stdout);
   
   flint_randinit(state);

   n_compute_primes(10000);

   for (i = 0; i < 100000; i++) /* Test that primes pass the test */
   {
      mp_limb_t d;
      mpz_t d_m;
      
      mpz_init(d_m);

      do
      {
         d = n_randint(state, flint_primes_cutoff) | 1;
         if (d == 1UL) d += 2;
         mpz_set_ui(d_m, d);
         mpz_nextprime(d_m, d_m);
         d = mpz_get_ui(d_m);
      } while (d > flint_primes_cutoff);

      result = n_is_oddprime_binary(d);
      
      if (!result)
      {
         printf("FAIL:\n");
         printf("d = %lu is declared composite\n", d); 
         abort();
      }

      mpz_clear(d_m);
   }
         
   for (i = 0; i < 100000; i++) /* Test that not too many composites pass */
   {
      mp_limb_t d;
      mpz_t d_m;
      
      mpz_init(d_m);

      do
      {
         d = n_randint(state, flint_primes_cutoff) | 1;
         mpz_set_ui(d_m, d);
      } while ((mpz_probab_prime_p(d_m, 12)) || (d > flint_primes_cutoff));

      result = !n_is_oddprime_binary(d);

      if (!result)
      {
         printf("FAIL:\n");
         printf("d = %lu is declared prime\n", d); 
         abort();
      }

      mpz_clear(d_m);
   }

   flint_randclear(state);

   printf("PASS\n");
   return 0;
}
Beispiel #14
0
void
check_all (mpz_ptr want, mpz_srcptr x_orig, mpz_srcptr y_orig)
{
  mpz_t  got, x, y;
  int    negx, negy, swap, inplace;

  mpz_init (got);
  mpz_init_set (x, x_orig);
  mpz_init_set (y, y_orig);

  for (swap = 0; swap < 2; swap++)
    {
      mpz_swap (x, y);

      for (negx = 0; negx < 2; negx++)
	{
	  mpz_neg (x, x);

	  for (negy = 0; negy < 2; negy++)
	    {
	      mpz_neg (y, y);

	      for (inplace = 0; inplace <= 1; inplace++)
		{
		  if (inplace)
		    { mpz_set (got, x); mpz_lcm (got, got, y); }
		  else
		    mpz_lcm (got, x, y);
		  MPZ_CHECK_FORMAT (got);

		  if (mpz_cmp (got, want) != 0)
		    {
		      printf ("mpz_lcm wrong, inplace=%d\n", inplace);
		    fail:
		      mpz_trace ("x", x);
		      mpz_trace ("y", y);
		      mpz_trace ("got", got);
		      mpz_trace ("want", want);
		      abort ();
		    }

		  if (mpz_fits_ulong_p (y))
		    {
		      unsigned long  yu = mpz_get_ui (y);
		      if (inplace)
			{ mpz_set (got, x); mpz_lcm_ui (got, got, yu); }
		      else
			mpz_lcm_ui (got, x, yu);

		      if (mpz_cmp (got, want) != 0)
			{
			  printf ("mpz_lcm_ui wrong, inplace=%d\n", inplace);
			  printf    ("yu=%lu\n", yu);
			  goto fail;
			}
		    }
		}
	    }
	}
    }

  mpz_clear (got);
  mpz_clear (x);
  mpz_clear (y);
}
Beispiel #15
0
int
main (int argc, char *argv[])
{
  char *progname = argv[0];
  mpz_t fr, to;
  mpz_t fr2, to2;
  unsigned long sieve_lim;
  unsigned long est_n_primes;
  unsigned char *s;
  mpz_t tmp;
  mpz_t siev_sqr_lim;

  while (argc != 1)
    {
      if (strcmp (argv[1], "-c") == 0)
	{
	  flag_count = 1;
	  argv++;
	  argc--;
	}
      else if (strcmp (argv[1], "-p") == 0)
	{
	  flag_print = 2;
	  argv++;
	  argc--;
	}
      else if (strcmp (argv[1], "-g") == 0)
	{
	  flag_maxgap = 1;
	  argv++;
	  argc--;
	}
      else
	break;
    }

  if (flag_count || flag_maxgap)
    flag_print--;		/* clear unless an explicit -p  */

  mpz_init (fr);
  mpz_init (to);
  mpz_init (fr2);
  mpz_init (to2);

  if (argc == 3)
    {
      mpz_set_str (fr, argv[1], 0);
      if (argv[2][0] == '+')
	{
	  mpz_set_str (to, argv[2] + 1, 0);
	  mpz_add (to, to, fr);
	}
      else
	mpz_set_str (to, argv[2], 0);
    }
  else if (argc == 2)
    {
      mpz_set_ui (fr, 0);
      mpz_set_str (to, argv[1], 0);
    }
  else
    {
      fprintf (stderr, "usage: %s [-c] [-p] [-g] [from [+]]to\n", progname);
      exit (1);
    }

  mpz_set (fr2, fr);
  if (mpz_cmp_ui (fr2, 3) < 0)
    {
      mpz_set_ui (fr2, 2);
      report (fr2);
      mpz_set_ui (fr2, 3);
    }
  mpz_setbit (fr2, 0);				/* make odd */
  mpz_sub_ui (to2, to, 1);
  mpz_setbit (to2, 0);				/* make odd */

  mpz_init (tmp);
  mpz_init (siev_sqr_lim);

  mpz_sqrt (tmp, to2);
#define SIEVE_LIMIT 10000000
  if (mpz_cmp_ui (tmp, SIEVE_LIMIT) < 0)
    {
      sieve_lim = mpz_get_ui (tmp);
    }
  else
    {
      sieve_lim = SIEVE_LIMIT;
      mpz_sub (tmp, to2, fr2);
      if (mpz_cmp_ui (tmp, sieve_lim) < 0)
	sieve_lim = mpz_get_ui (tmp);	/* limit sieving for small ranges */
    }
  mpz_set_ui (siev_sqr_lim, sieve_lim + 1);
  mpz_mul_ui (siev_sqr_lim, siev_sqr_lim, sieve_lim + 1);

  est_n_primes = (size_t) (sieve_lim / log((double) sieve_lim) * 1.13) + 10;
  primes = malloc (est_n_primes * sizeof primes[0]);
  make_primelist (sieve_lim);
  assert (est_n_primes >= n_primes);

#if DEBUG
  printf ("sieve_lim = %lu\n", sieve_lim);
  printf ("n_primes = %lu (3..%u)\n",
	  n_primes, primes[n_primes - 1].prime);
#endif

#define S (1 << 15)		/* FIXME: Figure out L1 cache size */
  s = malloc (S/2);
  while (mpz_cmp (fr2, to2) <= 0)
    {
      unsigned long rsize;
      rsize = S;
      mpz_add_ui (tmp, fr2, rsize);
      if (mpz_cmp (tmp, to2) > 0)
	{
	  mpz_sub (tmp, to2, fr2);
	  rsize = mpz_get_ui (tmp) + 2;
	}
#if DEBUG
      printf ("Sieving region ["); mpz_out_str (stdout, 10, fr2);
      printf (","); mpz_add_ui (tmp, fr2, rsize - 2);
      mpz_out_str (stdout, 10, tmp); printf ("]\n");
#endif
      sieve_region (s, fr2, rsize);
      find_primes (s, fr2, rsize / 2, siev_sqr_lim);

      mpz_add_ui (fr2, fr2, S);
    }
  free (s);

  if (flag_count)
    printf ("Pi(interval) = %lu\n", total_primes);

  if (flag_maxgap)
    printf ("max gap: %lu\n", maxgap);

  return 0;
}
Beispiel #16
0
int
main (int argc, char **argv)
{
  mpz_t x2;
  mpz_t x, rem;
  mpz_t temp, temp2;
  mp_size_t x2_size;
  int i;
  int reps = 20000;
  gmp_randstate_t rands;
  mpz_t bs;
  unsigned long size_range;

  tests_start ();
  gmp_randinit_default(rands);

  mpz_init (bs);

  if (argc == 2)
    reps = atoi (argv[1]);

  mpz_init (x2);
  mpz_init (x);
  mpz_init (rem);
  mpz_init (temp);
  mpz_init (temp2);

  for (i = 0; i < reps; i++)
    {
      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 12 + 2; /* 0..8191 bit operands */

      mpz_urandomb (bs, rands, size_range);
      x2_size = mpz_get_ui (bs);
      mpz_rrandomb (x2, rands, x2_size);

      /* printf ("%ld\n", SIZ (x2)); */

      mpz_sqrtrem (x, rem, x2);
      mpz_mul (temp, x, x);

      /* Is square of result > argument?  */
      if (mpz_cmp (temp, x2) > 0)
	dump_abort (x2, x, rem);

      mpz_add_ui (temp2, x, 1);
      mpz_mul (temp2, temp2, temp2);

      /* Is square of (result + 1) <= argument?  */
      if (mpz_cmp (temp2, x2) <= 0)
	dump_abort (x2, x, rem);

      mpz_add (temp2, temp, rem);

      /* Is the remainder wrong?  */
      if (mpz_cmp (x2, temp2) != 0)
	dump_abort (x2, x, rem);
    }

  mpz_clear (bs);
  mpz_clear (x2);
  mpz_clear (x);
  mpz_clear (rem);
  mpz_clear (temp);
  mpz_clear (temp2);
  gmp_randclear(rands);
  tests_end ();
  exit (0);
}
Beispiel #17
0
int
main (int argc, char **argv)
{
  mpz_t op1, op2;
  mpz_t prod, quot;
  mp_size_t size;
  int i;
  int reps = 20000;
  gmp_randstate_ptr rands;
  mpz_t bs;
  unsigned long bsi, size_range;

  tests_start ();
  rands = RANDS;

  mp_trace_base = -16;

  mpz_init (bs);

  if (argc == 2)
     reps = atoi (argv[1]);

  mpz_init (op1);
  mpz_init (op2);
  mpz_init (prod);
  mpz_init (quot);

  for (i = 0; i < reps; i++)
    {
      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 10 + 2; /* 0..2047 bit operands */

      mpz_urandomb (bs, rands, size_range);
      size = mpz_get_ui (bs);
      mpz_rrandomb (op1, rands, size);

      do
	{
	  mpz_urandomb (bs, rands, size_range);
	  size = mpz_get_ui (bs);
	  mpz_rrandomb (op2, rands, size);
	}
      while (mpz_sgn (op2) == 0);

      mpz_urandomb (bs, rands, 2);
      bsi = mpz_get_ui (bs);
      if ((bsi & 1) != 0)
	mpz_neg (op1, op1);
      if ((bsi & 2) != 0)
	mpz_neg (op2, op2);

      mpz_mul (prod, op1, op2);

      mpz_divexact (quot, prod, op2);
      MPZ_CHECK_FORMAT (quot);

      if (mpz_cmp (quot, op1) != 0)
        {
          printf ("Wrong results:\n");
          mpz_trace ("  got     ", quot);
          mpz_trace ("  want    ", op1);
          mpz_trace ("  dividend", prod);
          mpz_trace ("  divisor ", op2);
          abort ();
        }
    }

  mpz_clear (bs);
  mpz_clear (op1);
  mpz_clear (op2);
  mpz_clear (prod);
  mpz_clear (quot);

  tests_end ();
  exit (0);
}
Beispiel #18
0
int main(long argc, char *argv[])
{
  if(argc != 4)
  {
      printf("Three arguments required\n");
      printf("Usage: test6 a b c calculates pi(a*b^c)\n");
      exit(1);
  }

  //Legacy GMP code below; the input must fit in a 64 bit unsigned integer
  mpz_t n;
  mpz_init(n);

  mpz_ui_pow_ui(n,atol(argv[2]), atol(argv[3]));
  mpz_mul_ui(n, n, atol(argv[1]));
  uint64_t n2 = mpz_get_ui(n);

  uint64_t* s = malloc((n2/64+3)*sizeof(uint64_t));
  assert(s != NULL);


  //for wheel mod 6
  uint64_t word1 = 0x28A28A28A28A28A2;
  uint64_t word2 = 0xA28A28A28A28A28A;
  uint64_t word3 = 0x8A28A28A28A28A28;

  uint64_t k;

  for(k=0; k <= n2/64; k+=3)
  {
    s[k]=word1;
    s[k+1]=word2;
    s[k+2]=word3;
  }

  uint64_t sieve_to=floor(sqrt(n2));

  uint64_t i,j;

  i=5;								//5 is the first number which is relatively prime to 6
  int next = 4;             					//If i%6 = 5 then add 2 to i; if i%6 = 1 then add 4 to i;
  while (i<=sieve_to)
  {
    next = 6 - next;						//Alternate jumps of 2 and 4 to move through all the numbers congruent to +/- 1 mod 6
    if(TEST(s,i)!=0)						//Only sieve by primes
    {
      for(j=i*i; j<=n2; j+= 6*i)  CLEAR(s,j); 			//since i*i is always 1 (mod 6), this sieves out all the multiples of i congruent to 1 (mod 6)
      for(j=i*(i + next); j<=n2; j+= 6*i)  CLEAR(s,j); 		//i*(i+next) is the first multiple of i which exceeds i*i and is congruent to -1 (mod 6)
    }
    i += next;							//Advance pointer to the next number which is congruent to +/- 1
  }

  s[0] &= (~0 - 0xF);     					//Remove sieve entries for numbers less than 5;
  s[0] += 0xC;            					//Put in the correct entries; 2 and 3 are prime, 1100b = 4d + 8d = 12d = 0xC

 #if 0 
  for(i=0; i<=n2; i++)
    if(TEST(s,i)>0) printf("%" PRIu64 "\n",i);
#endif 

  //Note ridiculous macro format required to print unit64_t without generating a compiler warning                                              
  printf("%" PRIu64 "\n", count_bits(s,0,n2));

  return(0);
}
Beispiel #19
0
static PyObject *
GMPy_Integer_Pow(PyObject *b, PyObject *e, PyObject *m, CTXT_Object *context)
{
    MPZ_Object *result = NULL, *tempb = NULL, *tempe = NULL, *tempm = NULL;
    int has_mod;

    /* Try to parse the modulus value first. */

    if (m == Py_None) {
        has_mod = 0;
    }
    else {
        has_mod = 1;
        if (!IS_INTEGER(m)) {
            Py_RETURN_NOTIMPLEMENTED;
        }
        else {
            if (!(tempm = GMPy_MPZ_From_Integer(m, context))) {
                goto err;
            }
        }
    }

    result = GMPy_MPZ_New(context);
    tempb = GMPy_MPZ_From_Integer(b, context);
    tempe = GMPy_MPZ_From_Integer(e, context);

    if (!tempb || !tempe || !result) {
        goto err;
    }

    if (!has_mod) {
        /* When no modulo is present, the exponent must fit in unsigned long.
         */
        unsigned long el;

        if (mpz_sgn(tempe->z) < 0) {
            VALUE_ERROR("pow() exponent cannot be negative");
            goto err;
        }

        if (!mpz_fits_ulong_p(tempe->z)) {
            VALUE_ERROR("pow() outrageous exponent");
            goto err;
        }

        el = mpz_get_ui(tempe->z);
        mpz_pow_ui(result->z, tempb->z, el);
    }
    else {
        /* Modulo is present. */
        int sign;
        mpz_t mm, base, exp;

        sign = mpz_sgn(tempm->z);
        if (sign == 0) {
            VALUE_ERROR("pow() 3rd argument cannot be 0");
            goto err;
        }

        mpz_inoc(mm);
        mpz_abs(mm, tempm->z);

        /* A negative exponent is allowed if inverse exists. */
        if (mpz_sgn(tempe->z) < 0) {
            mpz_inoc(base);
            mpz_inoc(exp);

            if (!mpz_invert(base, tempb->z, mm)) {
                VALUE_ERROR("pow() base not invertible");
                mpz_cloc(base);
                mpz_cloc(exp);
                mpz_cloc(mm);
                goto err;
            }
            else {
                mpz_abs(exp, tempe->z);
            }

            mpz_powm(result->z, base, exp, mm);
            mpz_cloc(base);
            mpz_cloc(exp);
        }
        else {
            mpz_powm(result->z, tempb->z, tempe->z, mm);
        }
        mpz_cloc(mm);

        /* Python uses a rather peculiar convention for negative modulos
         * If the modulo is negative, result should be in the interval
         * m < r <= 0 .
         */
        if ((sign < 0) && (mpz_sgn(MPZ(result)) > 0)) {
            mpz_add(result->z, result->z, tempm->z);
        }
    }
    Py_XDECREF((PyObject*)tempb);
    Py_XDECREF((PyObject*)tempe);
    Py_XDECREF((PyObject*)tempm);
    return (PyObject*)result;

  err:
    Py_XDECREF((PyObject*)tempb);
    Py_XDECREF((PyObject*)tempe);
    Py_XDECREF((PyObject*)tempm);
    Py_DECREF((PyObject*)result);
    return NULL;
}
Beispiel #20
0
num_t
num_int_part_sel(pseltype_t op_type, num_t hi, num_t lo, num_t a)
{
	num_t r, m;
	unsigned long mask_shl, lo_ui;

	r = num_new_z(N_TEMP, NULL);
	m = num_new_z(N_TEMP, NULL);
	a = num_new_z(N_TEMP, a);
	hi = num_new_z(N_TEMP, hi);
	if (lo != NULL)
		lo = num_new_z(N_TEMP, lo);

	switch (op_type) {
	case PSEL_SINGLE:
		lo = num_new_z(N_TEMP, hi);
		break;

	case PSEL_FRANGE:
		break;

	case PSEL_DRANGE:
		if (mpz_cmp_si(Z(lo), 0L) < 0) {
			yyxerror("low index of part select operation must be "
			    "positive");
			return NULL;
		}
		mpz_sub_ui(Z(lo), Z(lo), 1UL);
		mpz_sub(Z(lo), Z(hi), Z(lo));
		break;
	}

	if (mpz_cmp_si(Z(hi), 0L) < 0) {
		yyxerror("high index of part select operation must be "
		    "positive");
		return NULL;
	}

	if (mpz_cmp_si(Z(lo), 0L) < 0) {
		yyxerror("low index of part select operation must be "
		    "positive");
		return NULL;
	}

	if (!mpz_fits_ulong_p(Z(hi))) {
		yyxerror("high index of part select operation needs to fit "
		    "into an unsigned long C datatype");
		return NULL;
	}

	if (!mpz_fits_ulong_p(Z(lo))) {
		yyxerror("low index of part select operation needs to fit "
		    "into an unsigned long C datatype");
		return NULL;
	}

	lo_ui = mpz_get_ui(Z(lo));
	mask_shl = 1 + (mpz_get_ui(Z(hi)) - lo_ui);

	/*
	 * We do the part sel by:
	 *  (1) shifting right by 'lo'
	 *  (2) anding with ((1 << mask_shl)-1)
	 */
	mpz_div_2exp(Z(r), Z(a), lo_ui);
	mpz_set_ui(Z(m), 1UL);
	mpz_mul_2exp(Z(m), Z(m), mask_shl);
	mpz_sub_ui(Z(m), Z(m), 1UL);

	mpz_and(Z(r), Z(r), Z(m));

	return r;
}
Beispiel #21
0
int
main (int argc, char **argv)
{
  mpz_t dividend, divisor;
  mpz_t quotient, remainder;
  mpz_t quotient2, remainder2;
  mpz_t temp;
  mp_size_t dividend_size, divisor_size;
  int i;
  int reps = 1000;
  gmp_randstate_t rands;
  mpz_t bs;
  unsigned long bsi, size_range;

  tests_start ();

  special_tests();

  gmp_randinit_default(rands);

  mpz_init (bs);

  if (argc == 2)
     reps = atoi (argv[1]);

  mpz_init (dividend);
  mpz_init (divisor);
  mpz_init (quotient);
  mpz_init (remainder);
  mpz_init (quotient2);
  mpz_init (remainder2);
  mpz_init (temp);

  for (i = 0; i < reps; i++)
    {
      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 16 + 2; /* 0..131071 bit operands */

      do
	{
	  mpz_urandomb (bs, rands, size_range);
	  divisor_size = mpz_get_ui (bs);
	  mpz_rrandomb (divisor, rands, divisor_size);
	}
      while (mpz_sgn (divisor) == 0);

      mpz_urandomb (bs, rands, size_range);
      dividend_size = mpz_get_ui (bs) + divisor_size;
      mpz_rrandomb (dividend, rands, dividend_size);

      mpz_urandomb (bs, rands, 2);
      bsi = mpz_get_ui (bs);
      if ((bsi & 1) != 0)
	mpz_neg (dividend, dividend);
      if ((bsi & 2) != 0)
	mpz_neg (divisor, divisor);

      /* printf ("%ld %ld\n", SIZ (dividend), SIZ (divisor)); */

      mpz_tdiv_qr (quotient, remainder, dividend, divisor);
      mpz_tdiv_q (quotient2, dividend, divisor);
      mpz_tdiv_r (remainder2, dividend, divisor);

      /* First determine that the quotients and remainders computed
	 with different functions are equal.  */
      if (mpz_cmp (quotient, quotient2) != 0)
   dump_abort (dividend, divisor);
      if (mpz_cmp (remainder, remainder2) != 0)
	dump_abort (dividend, divisor);

      /* Check if the sign of the quotient is correct.  */
      if (mpz_cmp_ui (quotient, 0) != 0)
	if ((mpz_cmp_ui (quotient, 0) < 0)
	    != ((mpz_cmp_ui (dividend, 0) ^ mpz_cmp_ui (divisor, 0)) < 0))
	dump_abort (dividend, divisor);

      /* Check if the remainder has the same sign as the dividend
	 (quotient rounded towards 0).  */
      if (mpz_cmp_ui (remainder, 0) != 0)
	if ((mpz_cmp_ui (remainder, 0) < 0) != (mpz_cmp_ui (dividend, 0) < 0))
	  dump_abort (dividend, divisor);

      mpz_mul (temp, quotient, divisor);
      mpz_add (temp, temp, remainder);
      if (mpz_cmp (temp, dividend) != 0)
	dump_abort (dividend, divisor);

      mpz_abs (temp, divisor);
      mpz_abs (remainder, remainder);
      if (mpz_cmp (remainder, temp) >= 0)
	dump_abort (dividend, divisor);
    }

  mpz_clear (bs);
  mpz_clear (dividend);
  mpz_clear (divisor);
  mpz_clear (quotient);
  mpz_clear (remainder);
  mpz_clear (quotient2);
  mpz_clear (remainder2);
  mpz_clear (temp);
  gmp_randclear(rands);
  tests_end ();
  exit (0);
}
Beispiel #22
0
void
check_random (int argc, char *argv[])
{
  gmp_randstate_ptr rands = RANDS;
  mpz_t   a, c, d, ra, rc;
  int     i;
  int     want;
  int     reps = 10000;
  mpz_t bs;
  unsigned long size_range, size;

  if (argc >= 2)
    reps = atoi (argv[1]);

  mpz_init (bs);

  mpz_init (a);
  mpz_init (c);
  mpz_init (d);
  mpz_init (ra);
  mpz_init (rc);

  for (i = 0; i < reps; i++)
    {
      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 16 + 1; /* 0..65536 bit operands */

      mpz_urandomb (bs, rands, size_range);
      size = mpz_get_ui (bs);
      mpz_rrandomb (a, rands, size);

      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 16 + 1; /* 0..65536 bit operands */

      mpz_urandomb (bs, rands, size_range);
      size = mpz_get_ui (bs);
      mpz_rrandomb (c, rands, size);

      do
	{
	  mpz_urandomb (bs, rands, 32);
	  size_range = mpz_get_ui (bs) % 16 + 1; /* 0..65536 bit operands */

	  mpz_urandomb (bs, rands, size_range);
	  size = mpz_get_ui (bs);
	  mpz_rrandomb (d, rands, size);
	}
      while (SIZ(d) == 0);

      mpz_negrandom (a, rands);
      MPZ_CHECK_FORMAT (a);
      mpz_negrandom (c, rands);
      MPZ_CHECK_FORMAT (c);
      mpz_negrandom (d, rands);

      mpz_fdiv_r (ra, a, d);
      mpz_fdiv_r (rc, c, d);

      want = (mpz_cmp (ra, rc) == 0);
      check_one (a, c, d, want);

      mpz_sub (ra, ra, rc);
      mpz_sub (a, a, ra);
      MPZ_CHECK_FORMAT (a);
      check_one (a, c, d, 1);

      if (! mpz_pow2abs_p (d))
        {
	  refmpz_combit (a, urandom() % (8*GMP_LIMB_BITS));
	  check_one (a, c, d, 0);
        }
    }

  mpz_clear (bs);

  mpz_clear (a);
  mpz_clear (c);
  mpz_clear (d);
  mpz_clear (ra);
  mpz_clear (rc);
}
Beispiel #23
0
static bool bp_script_eval(parr *stack, const cstring *script,
			   const struct bp_tx *txTo, unsigned int nIn,
			   unsigned int flags, int nHashType)
{
	struct const_buffer pc = { script->str, script->len };
	struct const_buffer pend = { script->str + script->len, 0 };
	struct const_buffer pbegincodehash = { script->str, script->len };
	struct bscript_op op;
	bool rc = false;
	cstring *vfExec = cstr_new(NULL);
	parr *altstack = parr_new(0, buffer_freep);
	mpz_t bn, bn_Zero, bn_One;
	mpz_init(bn);
	mpz_init_set_ui(bn_Zero, 0);
	mpz_init_set_ui(bn_One,1);

	if (script->len > MAX_SCRIPT_SIZE)
		goto out;

	unsigned int nOpCount = 0;
	bool fRequireMinimal = (flags & SCRIPT_VERIFY_MINIMALDATA) != 0;

	struct bscript_parser bp;
	bsp_start(&bp, &pc);

	while (pc.p < pend.p) {
		bool fExec = !count_false(vfExec);

		if (!bsp_getop(&op, &bp))
			goto out;
		enum opcodetype opcode = op.op;

		if (op.data.len > MAX_SCRIPT_ELEMENT_SIZE)
			goto out;
		if (opcode > OP_16 && ++nOpCount > MAX_OPS_PER_SCRIPT)
			goto out;
		if (disabled_op[opcode])
			goto out;

		if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) {
			if (fRequireMinimal && !CheckMinimalPush(&op.data, opcode))
				goto out;
			stack_push(stack, (struct buffer *) &op.data);
		} else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF))
		switch (opcode) {

		//
		// Push value
		//
		case OP_1NEGATE:
		case OP_1:
		case OP_2:
		case OP_3:
		case OP_4:
		case OP_5:
		case OP_6:
		case OP_7:
		case OP_8:
		case OP_9:
		case OP_10:
		case OP_11:
		case OP_12:
		case OP_13:
		case OP_14:
		case OP_15:
		case OP_16:
			mpz_set_si(bn, (int)opcode - (int)(OP_1 - 1));
			stack_push_str(stack, bn_getvch(bn));
			break;

		//
		// Control
		//
		case OP_NOP:
			break;

		case OP_CHECKLOCKTIMEVERIFY: {
			if (!(flags & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)) {
				// not enabled; treat as a NOP2
				if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
					goto out;
				break;
			}

			if (stack->len < 1)
				goto out;

			// Note that elsewhere numeric opcodes are limited to
			// operands in the range -2**31+1 to 2**31-1, however it is
			// legal for opcodes to produce results exceeding that
			// range. This limitation is implemented by CastToBigNum's
			// default 4-byte limit.
			//
			// If we kept to that limit we'd have a year 2038 problem,
			// even though the nLockTime field in transactions
			// themselves is uint32 which only becomes meaningless
			// after the year 2106.
			//
			// Thus as a special case we tell CastToBigNum to accept up
			// to 5-byte bignums, which are good until 2**39-1, well
			// beyond the 2**32-1 limit of the nLockTime field itself.

			if (!CastToBigNum(bn, stacktop(stack, -1), fRequireMinimal, 5))
				goto out;

			// In the rare event that the argument may be < 0 due to
			// some arithmetic being done first, you can always use
			// 0 MAX CHECKLOCKTIMEVERIFY.
			if (mpz_sgn(bn) < 0)
				goto out;

			uint64_t nLockTime = mpz_get_ui(bn);

			// Actually compare the specified lock time with the transaction.
			if (!CheckLockTime(nLockTime, txTo, nIn))
				goto out;

			break;
		}

		case OP_CHECKSEQUENCEVERIFY:
		{
			if (!(flags & SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)) {
				// not enabled; treat as a NOP3
				if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
					goto out;
				break;
			}

			if (stack->len < 1)
				goto out;

			// nSequence, like nLockTime, is a 32-bit unsigned integer
			// field. See the comment in CHECKLOCKTIMEVERIFY regarding
			// 5-byte numeric operands.
			if (!CastToBigNum(bn, stacktop(stack, -1), fRequireMinimal, 5))
				goto out;

			// In the rare event that the argument may be < 0 due to
			// some arithmetic being done first, you can always use
			// 0 MAX CHECKSEQUENCEVERIFY.
			if (mpz_sgn(bn) < 0)
				goto out;

			uint32_t nSequence = mpz_get_ui(bn);

			// To provide for future soft-fork extensibility, if the
			// operand has the disabled lock-time flag set,
			// CHECKSEQUENCEVERIFY behaves as a NOP.
			if ((nSequence & SEQUENCE_LOCKTIME_DISABLE_FLAG) != 0)
				break;

			// Compare the specified sequence number with the input.
			if (!CheckSequence(nSequence, txTo, nIn))
				goto out;

			break;
		}

		case OP_NOP1: case OP_NOP4: case OP_NOP5:
		case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10:
			if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
				goto out;
			break;

		case OP_IF:
		case OP_NOTIF: {
			// <expression> if [statements] [else [statements]] endif
			bool fValue = false;
			if (fExec) {
				if (stack->len < 1)
					goto out;
				struct buffer *vch = stacktop(stack, -1);
				fValue = CastToBool(vch);
				if (opcode == OP_NOTIF)
					fValue = !fValue;
				popstack(stack);
			}
			uint8_t vc = (uint8_t) fValue;
			cstr_append_c(vfExec, vc);
			break;
		}

		case OP_ELSE: {
			if (vfExec->len == 0)
				goto out;
			uint8_t *v = (uint8_t *) &vfExec->str[vfExec->len - 1];
			*v = !(*v);
			break;
		}

		case OP_ENDIF:
			if (vfExec->len == 0)
				goto out;
			cstr_erase(vfExec, vfExec->len - 1, 1);
			break;

		case OP_VERIFY: {
			if (stack->len < 1)
				goto out;
			bool fValue = CastToBool(stacktop(stack, -1));
			if (fValue)
				popstack(stack);
			else
				goto out;
			break;
		}

		case OP_RETURN:
			goto out;

		//
		// Stack ops
		//
		case OP_TOALTSTACK:
			if (stack->len < 1)
				goto out;
			stack_push(altstack, stacktop(stack, -1));
			popstack(stack);
			break;

		case OP_FROMALTSTACK:
			if (altstack->len < 1)
				goto out;
			stack_push(stack, stacktop(altstack, -1));
			popstack(altstack);
			break;

		case OP_2DROP:
			// (x1 x2 -- )
			if (stack->len < 2)
				goto out;
			popstack(stack);
			popstack(stack);
			break;

		case OP_2DUP: {
			// (x1 x2 -- x1 x2 x1 x2)
			if (stack->len < 2)
				goto out;
			struct buffer *vch1 = stacktop(stack, -2);
			struct buffer *vch2 = stacktop(stack, -1);
			stack_push(stack, vch1);
			stack_push(stack, vch2);
			break;
		}

		case OP_3DUP: {
			// (x1 x2 x3 -- x1 x2 x3 x1 x2 x3)
			if (stack->len < 3)
				goto out;
			struct buffer *vch1 = stacktop(stack, -3);
			struct buffer *vch2 = stacktop(stack, -2);
			struct buffer *vch3 = stacktop(stack, -1);
			stack_push(stack, vch1);
			stack_push(stack, vch2);
			stack_push(stack, vch3);
			break;
		}

		case OP_2OVER: {
			// (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2)
			if (stack->len < 4)
				goto out;
			struct buffer *vch1 = stacktop(stack, -4);
			struct buffer *vch2 = stacktop(stack, -3);
			stack_push(stack, vch1);
			stack_push(stack, vch2);
			break;
		}

		case OP_2ROT: {
			// (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2)
			if (stack->len < 6)
				goto out;
			struct buffer *vch1 = stack_take(stack, -6);
			struct buffer *vch2 = stack_take(stack, -5);
			parr_remove_range(stack, stack->len - 6, 2);
			stack_push_nocopy(stack, vch1);
			stack_push_nocopy(stack, vch2);
			break;
		}

		case OP_2SWAP:
			// (x1 x2 x3 x4 -- x3 x4 x1 x2)
			if (stack->len < 4)
				goto out;
			stack_swap(stack, -4, -2);
			stack_swap(stack, -3, -1);
			break;

		case OP_IFDUP: {
			// (x - 0 | x x)
			if (stack->len < 1)
				goto out;
			struct buffer *vch = stacktop(stack, -1);
			if (CastToBool(vch))
				stack_push(stack, vch);
			break;
		}

		case OP_DEPTH:
			// -- stacksize
			mpz_set_ui(bn, stack->len);
			stack_push_str(stack, bn_getvch(bn));
			break;

		case OP_DROP:
			// (x -- )
			if (stack->len < 1)
				goto out;
			popstack(stack);
			break;

		case OP_DUP: {
			// (x -- x x)
			if (stack->len < 1)
				goto out;
			struct buffer *vch = stacktop(stack, -1);
			stack_push(stack, vch);
			break;
		}

		case OP_NIP:
			// (x1 x2 -- x2)
			if (stack->len < 2)
				goto out;
			parr_remove_idx(stack, stack->len - 2);
			break;

		case OP_OVER: {
			// (x1 x2 -- x1 x2 x1)
			if (stack->len < 2)
				goto out;
			struct buffer *vch = stacktop(stack, -2);
			stack_push(stack, vch);
			break;
		}

		case OP_PICK:
		case OP_ROLL: {
			// (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn)
			// (xn ... x2 x1 x0 n - ... x2 x1 x0 xn)
			if (stack->len < 2)
				goto out;

			int n = stackint(stack, -1, fRequireMinimal);
			popstack(stack);
			if (n < 0 || n >= (int)stack->len)
				goto out;
			struct buffer *vch = stacktop(stack, -n-1);
			if (opcode == OP_ROLL) {
				vch = buffer_copy(vch->p, vch->len);
				parr_remove_idx(stack,
							 stack->len - n - 1);
				stack_push_nocopy(stack, vch);
			} else
				stack_push(stack, vch);
			break;
		}

		case OP_ROT: {
			// (x1 x2 x3 -- x2 x3 x1)
			//  x2 x1 x3  after first swap
			//  x2 x3 x1  after second swap
			if (stack->len < 3)
				goto out;
			stack_swap(stack, -3, -2);
			stack_swap(stack, -2, -1);
			break;
		}

		case OP_SWAP: {
			// (x1 x2 -- x2 x1)
			if (stack->len < 2)
				goto out;
			stack_swap(stack, -2, -1);
			break;
		}

		case OP_TUCK: {
			// (x1 x2 -- x2 x1 x2)
			if (stack->len < 2)
				goto out;
			struct buffer *vch = stacktop(stack, -1);
			stack_insert(stack, vch, -2);
			break;
		}

		case OP_SIZE: {
			// (in -- in size)
			if (stack->len < 1)
				goto out;
			struct buffer *vch = stacktop(stack, -1);
			mpz_set_ui(bn, vch->len);
			stack_push_str(stack, bn_getvch(bn));
			break;
		}


		case OP_EQUAL:
		case OP_EQUALVERIFY: {
			// (x1 x2 - bool)
			if (stack->len < 2)
				goto out;
			struct buffer *vch1 = stacktop(stack, -2);
			struct buffer *vch2 = stacktop(stack, -1);
			bool fEqual = buffer_equal(vch1, vch2);
			// OP_NOTEQUAL is disabled because it would be too easy to say
			// something like n != 1 and have some wiseguy pass in 1 with extra
			// zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001)
			//if (opcode == OP_NOTEQUAL)
			//	fEqual = !fEqual;
			popstack(stack);
			popstack(stack);
			stack_push_str(stack, fEqual ? bn_getvch(bn_One) : bn_getvch(bn_Zero));
			if (opcode == OP_EQUALVERIFY) {
				if (fEqual)
					popstack(stack);
				else
					goto out;
			}
			break;
		}

		//
		// Numeric
		//
		case OP_1ADD:
		case OP_1SUB:
		case OP_NEGATE:
		case OP_ABS:
		case OP_NOT:
		case OP_0NOTEQUAL: {
			// (in -- out)
			if (stack->len < 1)
				goto out;
			if (!CastToBigNum(bn, stacktop(stack, -1), fRequireMinimal, nDefaultMaxNumSize))
				goto out;
			switch (opcode)
			{
			case OP_1ADD:
				mpz_add_ui(bn, bn, 1);
				break;
			case OP_1SUB:
				mpz_sub_ui(bn, bn, 1);
				break;
			case OP_NEGATE:
				mpz_neg(bn, bn);
				break;
			case OP_ABS:
				mpz_abs(bn, bn);
				break;
			case OP_NOT:
				mpz_set_ui(bn, mpz_sgn(bn) == 0 ? 1 : 0);
				break;
			case OP_0NOTEQUAL:
				mpz_set_ui(bn, mpz_sgn(bn) == 0 ? 0 : 1);
				break;
			default:
				// impossible
				goto out;
			}
			popstack(stack);
			stack_push_str(stack, bn_getvch(bn));
			break;
		}

		case OP_ADD:
		case OP_SUB:
		case OP_BOOLAND:
		case OP_BOOLOR:
		case OP_NUMEQUAL:
		case OP_NUMEQUALVERIFY:
		case OP_NUMNOTEQUAL:
		case OP_LESSTHAN:
		case OP_GREATERTHAN:
		case OP_LESSTHANOREQUAL:
		case OP_GREATERTHANOREQUAL:
		case OP_MIN:
		case OP_MAX: {
			// (x1 x2 -- out)
			if (stack->len < 2)
				goto out;

			mpz_t bn1, bn2;
			mpz_init(bn1);
			mpz_init(bn2);
			if (!CastToBigNum(bn1, stacktop(stack, -2), fRequireMinimal, nDefaultMaxNumSize) ||
			    !CastToBigNum(bn2, stacktop(stack, -1), fRequireMinimal, nDefaultMaxNumSize)) {
				mpz_clear(bn1);
				mpz_clear(bn2);
				goto out;
			}

			switch (opcode)
			{
			case OP_ADD:
				mpz_add(bn, bn1, bn2);
				break;
			case OP_SUB:
				mpz_sub(bn, bn1, bn2);
				break;
			case OP_BOOLAND:
				mpz_set_ui(bn,
				    !(mpz_sgn(bn1) == 0) && !(mpz_sgn(bn2) == 0) ?
				    1 : 0);
				break;
			case OP_BOOLOR:
				mpz_set_ui(bn,
				    !(mpz_sgn(bn1) == 0) || !(mpz_sgn(bn2) == 0) ?
				    1 : 0);
				break;
			case OP_NUMEQUAL:
			case OP_NUMEQUALVERIFY:
				mpz_set_ui(bn,
				    mpz_cmp(bn1, bn2) == 0 ?  1 : 0);
				break;
			case OP_NUMNOTEQUAL:
				mpz_set_ui(bn,
				    mpz_cmp(bn1, bn2) != 0 ?  1 : 0);
				break;
			case OP_LESSTHAN:
				mpz_set_ui(bn,
				    mpz_cmp(bn1, bn2) < 0 ?  1 : 0);
				break;
			case OP_GREATERTHAN:
				mpz_set_ui(bn,
				    mpz_cmp(bn1, bn2) > 0 ?  1 : 0);
				break;
			case OP_LESSTHANOREQUAL:
				mpz_set_ui(bn,
				    mpz_cmp(bn1, bn2) <= 0 ?  1 : 0);
				break;
			case OP_GREATERTHANOREQUAL:
				mpz_set_ui(bn,
				    mpz_cmp(bn1, bn2) >= 0 ?  1 : 0);
				break;
			case OP_MIN:
				if (mpz_cmp(bn1, bn2) < 0)
					mpz_set(bn, bn1);
				else
					mpz_set(bn, bn2);
				break;
			case OP_MAX:
				if (mpz_cmp(bn1, bn2) > 0)
					mpz_set(bn, bn1);
				else
					mpz_set(bn, bn2);
				break;
			default:
				// impossible
				break;
			}
			popstack(stack);
			popstack(stack);
			stack_push_str(stack, bn_getvch(bn));
			mpz_clear(bn1);
			mpz_clear(bn2);

			if (opcode == OP_NUMEQUALVERIFY)
			{
				if (CastToBool(stacktop(stack, -1)))
					popstack(stack);
				else
					goto out;
			}
			break;
		}

		case OP_WITHIN: {
			// (x min max -- out)
			if (stack->len < 3)
				goto out;
			mpz_t bn1, bn2, bn3;
			mpz_init(bn1);
			mpz_init(bn2);
			mpz_init(bn3);
			bool rc1 = CastToBigNum(bn1, stacktop(stack, -3), fRequireMinimal, nDefaultMaxNumSize);
			bool rc2 = CastToBigNum(bn2, stacktop(stack, -2), fRequireMinimal, nDefaultMaxNumSize);
			bool rc3 = CastToBigNum(bn3, stacktop(stack, -1), fRequireMinimal, nDefaultMaxNumSize);
			bool fValue = (mpz_cmp(bn2, bn1) <= 0 &&
				       mpz_cmp(bn1, bn3) < 0);
			popstack(stack);
			popstack(stack);
			popstack(stack);
			stack_push_str(stack, fValue ? bn_getvch(bn_One) : bn_getvch(bn_Zero));
			mpz_clear(bn1);
			mpz_clear(bn2);
			mpz_clear(bn3);
			if (!rc1 || !rc2 || !rc3)
				goto out;
			break;
		}

		//
		// Crypto
		//
		case OP_RIPEMD160:
		case OP_SHA1:
		case OP_SHA256:
		case OP_HASH160:
		case OP_HASH256: {
			// (in -- hash)
			if (stack->len < 1)
				goto out;
			struct buffer *vch = stacktop(stack, -1);
			unsigned int hashlen;
			unsigned char md[32];

			switch (opcode) {
			case OP_RIPEMD160:
				hashlen = 20;
				ripemd160(vch->p, vch->len, md);
				break;
			case OP_SHA1:
				hashlen = 20;
				sha1_Raw(vch->p, vch->len, md);
				break;
			case OP_SHA256:
				hashlen = 32;
				sha256_Raw(vch->p, vch->len, md);
				break;
			case OP_HASH160:
				hashlen = 20;
				bu_Hash160(md, vch->p, vch->len);
				break;
			case OP_HASH256:
				hashlen = 32;
				bu_Hash(md, vch->p, vch->len);
				break;
			default:
				// impossible
				goto out;
			}

			popstack(stack);
			struct buffer buf = { md, hashlen };
			stack_push(stack, &buf);
			break;
		}

		case OP_CODESEPARATOR:
			// Hash starts after the code separator
			memcpy(&pbegincodehash, &pc, sizeof(pc));
			break;

		case OP_CHECKSIG:
		case OP_CHECKSIGVERIFY: {
			// (sig pubkey -- bool)
			if (stack->len < 2)
				goto out;

			struct buffer *vchSig	= stacktop(stack, -2);
			struct buffer *vchPubKey = stacktop(stack, -1);

			// Subset of script starting at the most recent codeseparator
			cstring *scriptCode = cstr_new_buf(pbegincodehash.p,
                                                pbegincodehash.len);

			// Drop the signature, since there's no way for
			// a signature to sign itself
			string_find_del(scriptCode, vchSig);

			if (!CheckSignatureEncoding(vchSig, flags) || !CheckPubKeyEncoding(vchPubKey, flags)) {
				cstr_free(scriptCode, true);
				goto out;
			}

			bool fSuccess = bp_checksig(vchSig, vchPubKey,
						       scriptCode,
						       txTo, nIn);

			cstr_free(scriptCode, true);

			popstack(stack);
			popstack(stack);
			stack_push_str(stack, fSuccess ? bn_getvch(bn_One) : bn_getvch(bn_Zero));
			if (opcode == OP_CHECKSIGVERIFY)
			{
				if (fSuccess)
					popstack(stack);
				else
					goto out;
			}
			break;
		}

		case OP_CHECKMULTISIG:
		case OP_CHECKMULTISIGVERIFY: {
			// ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool)

			int i = 1;
			if ((int)stack->len < i)
				goto out;

			int nKeysCount = stackint(stack, -i, fRequireMinimal);
			if (nKeysCount < 0 || nKeysCount > MAX_PUBKEYS_PER_MULTISIG)
				goto out;
			nOpCount += nKeysCount;
			if (nOpCount > MAX_OPS_PER_SCRIPT)
				goto out;
			int ikey = ++i;
			i += nKeysCount;
			if ((int)stack->len < i)
				goto out;

			int nSigsCount = stackint(stack, -i, fRequireMinimal);
			if (nSigsCount < 0 || nSigsCount > nKeysCount)
				goto out;
			int isig = ++i;
			i += nSigsCount;
			if ((int)stack->len < i)
				goto out;

			// Subset of script starting at the most recent codeseparator
			cstring *scriptCode = cstr_new_buf(pbegincodehash.p,
                                                pbegincodehash.len);

			// Drop the signatures, since there's no way for
			// a signature to sign itself
			int k;
			for (k = 0; k < nSigsCount; k++)
			{
				struct buffer *vchSig =stacktop(stack, -isig-k);
				string_find_del(scriptCode, vchSig);
			}

			bool fSuccess = true;
			while (fSuccess && nSigsCount > 0)
			{
				struct buffer *vchSig	= stacktop(stack, -isig);
				struct buffer *vchPubKey = stacktop(stack, -ikey);

				// Note how this makes the exact order of pubkey/signature evaluation
				// distinguishable by CHECKMULTISIG NOT if the STRICTENC flag is set.
				// See the script_(in)valid tests for details.
				if (!CheckSignatureEncoding(vchSig, flags) || !CheckPubKeyEncoding(vchPubKey, flags)) {
					cstr_free(scriptCode, true);
					goto out;
				}

				// Check signature
				bool fOk = bp_checksig(vchSig, vchPubKey,
							  scriptCode, txTo, nIn);

				if (fOk) {
					isig++;
					nSigsCount--;
				}
				ikey++;
				nKeysCount--;

				// If there are more signatures left than keys left,
				// then too many signatures have failed
				if (nSigsCount > nKeysCount)
					fSuccess = false;
			}

			cstr_free(scriptCode, true);

			// Clean up stack of actual arguments
			while (i-- > 1)
				popstack(stack);

			// A bug causes CHECKMULTISIG to consume one extra argument
			// whose contents were not checked in any way.
			//
			// Unfortunately this is a potential source of mutability,
			// so optionally verify it is exactly equal to zero prior
			// to removing it from the stack.
			if ((int)stack->len < 1)
				goto out;
			if ((flags & SCRIPT_VERIFY_NULLDUMMY) && stacktop(stack, -1)->len)
				goto out;
			popstack(stack);

			stack_push_str(stack, fSuccess ? bn_getvch(bn_One) : bn_getvch(bn_Zero));

			if (opcode == OP_CHECKMULTISIGVERIFY)
			{
				if (fSuccess)
					popstack(stack);
				else
					goto out;
			}
			break;
		}

		default:
			goto out;
		}

		// Size limits
		if (stack->len + altstack->len > 1000)
			goto out;
	}

	rc = (vfExec->len == 0 && bp.error == false);

out:
	mpz_clears(bn, bn_Zero, bn_One, NULL);
	parr_free(altstack, true);
	cstr_free(vfExec, true);
	return rc;
}
Beispiel #24
0
int
main (int argc, char **argv)
{
  gmp_randstate_ptr rands;
  unsigned long maxnbits, maxdbits, nbits, dbits;
  mpz_t n, d, tz;
  mp_size_t maxnn, maxdn, nn, dn, clearn, i;
  mp_ptr np, dp, qp, rp;
  mp_limb_t rh;
  mp_limb_t t;
  mp_limb_t dinv;
  int count = COUNT;
  mp_ptr scratch;
  mp_limb_t ran;
  mp_size_t alloc, itch;
  mp_limb_t rran0, rran1, qran0, qran1;
  TMP_DECL;

  if (argc > 1)
    {
      char *end;
      count = strtol (argv[1], &end, 0);
      if (*end || count <= 0)
	{
	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
	  return 1;
	}
    }


  maxdbits = MAX_DN;
  maxnbits = MAX_NN;

  tests_start ();
  rands = RANDS;

  mpz_init (n);
  mpz_init (d);
  mpz_init (tz);

  maxnn = maxnbits / GMP_NUMB_BITS + 1;
  maxdn = maxdbits / GMP_NUMB_BITS + 1;

  TMP_MARK;

  qp = TMP_ALLOC_LIMBS (maxnn + 2) + 1;
  rp = TMP_ALLOC_LIMBS (maxnn + 2) + 1;

  alloc = 1;
  scratch = __GMP_ALLOCATE_FUNC_LIMBS (alloc);

  for (test = 0; test < count;)
    {
      nbits = random_word (rands) % (maxnbits - GMP_NUMB_BITS) + 2 * GMP_NUMB_BITS;
      if (maxdbits > nbits)
	dbits = random_word (rands) % nbits + 1;
      else
	dbits = random_word (rands) % maxdbits + 1;

#if RAND_UNIFORM
#define RANDFUNC mpz_urandomb
#else
#define RANDFUNC mpz_rrandomb
#endif

      do
	{
	  RANDFUNC (n, rands, nbits);
	  do
	    {
	      RANDFUNC (d, rands, dbits);
	    }
	  while (mpz_sgn (d) == 0);

	  np = PTR (n);
	  dp = PTR (d);
	  nn = SIZ (n);
	  dn = SIZ (d);
	}
      while (nn < dn);

      dp[0] |= 1;

      mpz_urandomb (tz, rands, 32);
      t = mpz_get_ui (tz);

      if (t % 17 == 0)
	dp[0] = GMP_NUMB_MAX;

      switch ((int) t % 16)
	{
	case 0:
	  clearn = random_word (rands) % nn;
	  for (i = 0; i <= clearn; i++)
	    np[i] = 0;
	  break;
	case 1:
	  mpn_sub_1 (np + nn - dn, dp, dn, random_word (rands));
	  break;
	case 2:
	  mpn_add_1 (np + nn - dn, dp, dn, random_word (rands));
	  break;
	}

      test++;

      binvert_limb (dinv, dp[0]);

      rran0 = random_word (rands);
      rran1 = random_word (rands);
      qran0 = random_word (rands);
      qran1 = random_word (rands);

      qp[-1] = qran0;
      qp[nn - dn + 1] = qran1;
      rp[-1] = rran0;

      ran = random_word (rands);

      if ((double) (nn - dn) * dn < 1e5)
	{
	  if (nn > dn)
	    {
	      /* Test mpn_sbpi1_bdiv_qr */
	      MPN_ZERO (qp, nn - dn);
	      MPN_ZERO (rp, dn);
	      MPN_COPY (rp, np, nn);
	      rh = mpn_sbpi1_bdiv_qr (qp, rp, nn, dp, dn, -dinv);
	      ASSERT_ALWAYS (qp[-1] == qran0);  ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
	      ASSERT_ALWAYS (rp[-1] == rran0);
	      check_one (qp, rp + nn - dn, rh, np, nn, dp, dn, "mpn_sbpi1_bdiv_qr");
	    }

	  if (nn > dn)
	    {
	      /* Test mpn_sbpi1_bdiv_q */
	      MPN_COPY (rp, np, nn);
	      MPN_ZERO (qp, nn - dn);
	      mpn_sbpi1_bdiv_q (qp, rp, nn - dn, dp, MIN(dn,nn-dn), -dinv);
	      ASSERT_ALWAYS (qp[-1] == qran0);  ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
	      ASSERT_ALWAYS (rp[-1] == rran0);
	      check_one (qp, NULL, 0, np, nn, dp, dn, "mpn_sbpi1_bdiv_q");
	    }
	}

      if (dn >= 4 && nn - dn >= 2)
	{
	  /* Test mpn_dcpi1_bdiv_qr */
	  MPN_COPY (rp, np, nn);
	  MPN_ZERO (qp, nn - dn);
	  rh = mpn_dcpi1_bdiv_qr (qp, rp, nn, dp, dn, -dinv);
	  ASSERT_ALWAYS (qp[-1] == qran0);  ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
	  ASSERT_ALWAYS (rp[-1] == rran0);
	  check_one (qp, rp + nn - dn, rh, np, nn, dp, dn, "mpn_dcpi1_bdiv_qr");
	}

      if (dn >= 4 && nn - dn >= 2)
	{
	  /* Test mpn_dcpi1_bdiv_q */
	  MPN_COPY (rp, np, nn);
	  MPN_ZERO (qp, nn - dn);
	  mpn_dcpi1_bdiv_q (qp, rp, nn - dn, dp, MIN(dn,nn-dn), -dinv);
	  ASSERT_ALWAYS (qp[-1] == qran0);  ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
	  ASSERT_ALWAYS (rp[-1] == rran0);
	  check_one (qp, NULL, 0, np, nn, dp, dn, "mpn_dcpi1_bdiv_q");
	}

      if (nn > dn)
	{
	  /* Test mpn_bdiv_qr */
	  itch = mpn_bdiv_qr_itch (nn, dn);
	  if (itch + 1 > alloc)
	    {
	      scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1);
	      alloc = itch + 1;
	    }
	  scratch[itch] = ran;
	  MPN_ZERO (qp, nn - dn);
	  MPN_ZERO (rp, dn);
	  rp[dn] = rran1;
	  rh = mpn_bdiv_qr (qp, rp, np, nn, dp, dn, scratch);
	  ASSERT_ALWAYS (ran == scratch[itch]);
	  ASSERT_ALWAYS (qp[-1] == qran0);  ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
	  ASSERT_ALWAYS (rp[-1] == rran0);  ASSERT_ALWAYS (rp[dn] == rran1);

	  check_one (qp, rp, rh, np, nn, dp, dn, "mpn_bdiv_qr");
	}

      if (nn - dn < 2 || dn < 2)
	continue;

      /* Test mpn_mu_bdiv_qr */
      itch = mpn_mu_bdiv_qr_itch (nn, dn);
      if (itch + 1 > alloc)
	{
	  scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1);
	  alloc = itch + 1;
	}
      scratch[itch] = ran;
      MPN_ZERO (qp, nn - dn);
      MPN_ZERO (rp, dn);
      rp[dn] = rran1;
      rh = mpn_mu_bdiv_qr (qp, rp, np, nn, dp, dn, scratch);
      ASSERT_ALWAYS (ran == scratch[itch]);
      ASSERT_ALWAYS (qp[-1] == qran0);  ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
      ASSERT_ALWAYS (rp[-1] == rran0);  ASSERT_ALWAYS (rp[dn] == rran1);
      check_one (qp, rp, rh, np, nn, dp, dn, "mpn_mu_bdiv_qr");

      /* Test mpn_mu_bdiv_q */
      itch = mpn_mu_bdiv_q_itch (nn, dn);
      if (itch + 1 > alloc)
	{
	  scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1);
	  alloc = itch + 1;
	}
      scratch[itch] = ran;
      MPN_ZERO (qp, nn - dn + 1);
      mpn_mu_bdiv_q (qp, np, nn - dn, dp, dn, scratch);
      ASSERT_ALWAYS (ran == scratch[itch]);
      ASSERT_ALWAYS (qp[-1] == qran0);  ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
      check_one (qp, NULL, 0, np, nn, dp, dn, "mpn_mu_bdiv_q");
    }

  __GMP_FREE_FUNC_LIMBS (scratch, alloc);

  TMP_FREE;

  mpz_clear (n);
  mpz_clear (d);
  mpz_clear (tz);

  tests_end ();
  return 0;
}
Beispiel #25
0
int
main (int argc, char **argv)
{
  mpz_t  op1, op2;
  mp_size_t size;
  int i;
  int reps = 10000;
  FILE *fp;
  int base, base_out;
  gmp_randstate_ptr rands;
  mpz_t bs;
  unsigned long bsi, size_range;
  size_t nread;

  tests_start ();
  rands = RANDS;

  mpz_init (bs);

  if (argc == 2)
    reps = atoi (argv[1]);

  mpz_init (op1);
  mpz_init (op2);

  fp = fopen (FILENAME, "w+");

  for (i = 0; i < reps; i++)
    {
      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 10 + 2;

      mpz_urandomb (bs, rands, size_range);
      size = mpz_get_ui (bs);
      mpz_rrandomb (op1, rands, size);
      mpz_urandomb (bs, rands, 1);
      bsi = mpz_get_ui (bs);
      if ((bsi & 1) != 0)
	mpz_neg (op1, op1);

      mpz_urandomb (bs, rands, 16);
      bsi = mpz_get_ui (bs);
      base = bsi % 62 + 1;
      if (base == 1)
	base = 0;

      if (i % 2 == 0 && base <= 36)
	base_out = -base;
      else
	base_out = base;

      rewind (fp);
      if (mpz_out_str (fp, base_out, op1) == 0
	  || putc (' ', fp) == EOF
	  || fflush (fp) != 0)
	{
	  printf ("mpz_out_str write error\n");
	  abort ();
	}

      rewind (fp);
      nread = mpz_inp_str (op2, fp, base);
      if (nread == 0)
	{
	  if (ferror (fp))
	    printf ("mpz_inp_str stream read error\n");
	  else
	    printf ("mpz_inp_str data conversion error\n");
	  abort ();
	}

      if (nread != ftell(fp))
	{
	  printf ("mpz_inp_str nread doesn't match ftell\n");
	  printf ("  nread  %lu\n", (unsigned long) nread);
	  printf ("  ftell  %ld\n", ftell(fp));
	  abort ();
	}

      if (mpz_cmp (op1, op2))
	{
	  printf ("ERROR\n");
	  printf ("op1  = "); debug_mp (op1, -16);
	  printf ("op2  = "); debug_mp (op2, -16);
	  printf ("base = %d\n", base);
	  abort ();
	}
    }

  fclose (fp);

  unlink (FILENAME);

  mpz_clear (bs);
  mpz_clear (op1);
  mpz_clear (op2);

  tests_end ();
  exit (0);
}
Beispiel #26
0
static unsigned long get_int(void *a)
{
   LTC_ARGCHK(a != NULL);
   return mpz_get_ui(a);
}
Beispiel #27
0
u32_t*
mpz_trialdiv(mpz_t N,u32_t*pbuf,u32_t ncp,char*errmsg)
{
u32_t np,np1,i,e2,nlimb;

if(mpz_sgn(N)<=0){
if(mpz_sgn(N)==0)return pbuf;
mpz_neg(N,N);
}

if(mibuf_alloc<ncp){
if(mibuf_alloc> 0)free(mibuf);
mibuf_alloc= ncp;
mibuf= xmalloc(mibuf_alloc*sizeof(*mibuf));
}

e2= 0;
while((mpz_get_ui(N)%2)==0){
mpz_fdiv_q_2exp(N,N,1);
e2++;
}

nlimb= N[0]._mp_size;
if(lbuf_alloc<nlimb){
if(lbuf_alloc> 0)free(lbuf);
lbuf_alloc= nlimb;
lbuf= xmalloc(lbuf_alloc*sizeof(*lbuf));
}

memcpy(lbuf,N[0]._mp_d,nlimb*sizeof(*lbuf));
np= 0;
for(i= 0;i<ncp;i++){
mp_limb_t x,p,r;

p= pbuf[i];
x= mpqs_256_inv_table[(p&255)/2];
x= 2*x-p*x*x;
x= 2*x-p*x*x;
x= 2*x-p*x*x;
r= mpz_asm_td(p,x,lbuf,nlimb);
if(r!=0){
if(errmsg!=NULL)
Schlendrian("%s : %u does not divide\n",errmsg,pbuf[i]);
memcpy(lbuf,N[0]._mp_d,nlimb*sizeof(*lbuf));
continue;
}
while(lbuf[nlimb-1]==0)nlimb--;
if(errmsg==NULL)memcpy(N[0]._mp_d,lbuf,nlimb*sizeof(*lbuf));
mibuf[np]= x;
pbuf[np++]= p;
}
np1= np;
if(errmsg!=NULL)memcpy(N[0]._mp_d,lbuf,nlimb*sizeof(*lbuf));
for(i= 0;i<np1;i++){
mp_limb_t x,p,r;

p= pbuf[i];
x= mibuf[i];
for(;;){
r= mpz_asm_td(p,x,lbuf,nlimb);
if(r!=0){
memcpy(lbuf,N[0]._mp_d,nlimb*sizeof(*lbuf));
break;
}
while(lbuf[nlimb-1]==0)nlimb--;
memcpy(N[0]._mp_d,lbuf,nlimb*sizeof(*lbuf));
pbuf[np++]= p;
}
}
N[0]._mp_size= nlimb;
for(i= 0;i<e2;i++)
pbuf[np++]= 2;
return pbuf+np;
}/*:1*/
Beispiel #28
0
/* Find primes in region [fr,fr+rsize).  Requires that fr is odd and that
   rsize is even.  The sieving array s should be aligned for "long int" and
   have rsize/2 entries, rounded up to the nearest multiple of "long int".  */
void
sieve_region (unsigned char *s, mpz_t fr, unsigned long rsize)
{
  unsigned long ssize = rsize / 2;
  unsigned long start, start2, prime;
  unsigned long i;
  mpz_t tmp;

  mpz_init (tmp);

#if 0
  /* initialize sieving array */
  for (ii = 0; ii < (ssize + sizeof (long) - 1) / sizeof (long); ii++)
    ((long *) s) [ii] = ~0L;
#else
  {
    signed long k;
    long *se = (long *) (s + ((ssize + sizeof (long) - 1) & -sizeof (long)));
    for (k = -((ssize + sizeof (long) - 1) / sizeof (long)); k < 0; k++)
      se[k] = ~0L;
  }
#endif

  for (i = 0; i < n_primes; i++)
    {
      prime = primes[i].prime;

      if (primes[i].rem >= 0)
	{
	  start2 = primes[i].rem;
	}
      else
	{
	  mpz_set_ui (tmp, prime);
	  mpz_mul_ui (tmp, tmp, prime);
	  if (mpz_cmp (fr, tmp) <= 0)
	    {
	      mpz_sub (tmp, tmp, fr);
	      if (mpz_cmp_ui (tmp, 2 * ssize) > 0)
		break;		/* avoid overflow at next line, also speedup */
	      start = mpz_get_ui (tmp);
	    }
	  else
	    {
	      start = (prime - mpz_tdiv_ui (fr, prime)) % prime;
	      if (start % 2 != 0)
		start += prime;		/* adjust if even divisable */
	    }
	  start2 = start / 2;
	}

#if 0
      for (ii = start2; ii < ssize; ii += prime)
	s[ii] = 0;
      primes[i].rem = ii - ssize;
#else
      {
	signed long k;
	unsigned char *se = s + ssize; /* point just beyond sieving range */
	for (k = start2 - ssize; k < 0; k += prime)
	  se[k] = 0;
	primes[i].rem = k;
      }
#endif
    }
  mpz_clear (tmp);
}
Beispiel #29
0
int ecpp_test(unsigned long n)
{
  mpz_t a, b,
        x0, y0,
        xt, yt,
        tmp;
  int z;
  int is_prime = 0;

  if (n <= USHRT_MAX)
  {
    return sieve_test(n);
  }

  mpz_init(a);
  mpz_init(b);
  mpz_init(x0);
  mpz_init(y0);
  mpz_init(xt);
  mpz_init(yt);
  mpz_init(tmp);

#ifdef DEBUG
  gmp_fprintf(stderr, "\nTesting %d with ECPP...\n", n);
#endif /* DEBUG */

  for (;;) /* keep trying while the curve order factoring fails */
  {
    for (;;) /* keep trying while n divides curve discriminant */
    {
      /* initialise a random point P = (x0, y0)
       * and a random elliptic curve E(a, b): y^2 = x^3 + a*x + b
       * with b expressed in terms of (a, x0, y0) so the point lies on the curve
       */

      mpz_set_ui(a, rand() % n);
      mpz_set_ui(x0, rand() % n);
      mpz_set_ui(y0, rand() % n);
      mpz_init(b);

      mpz_mul(b, y0, y0);
      mpz_mul(tmp, x0, x0);
      mpz_submul(b, tmp, x0);
      mpz_submul(b, a, x0);
      mpz_mod_ui(b, b, n);

#ifdef DEBUG
      gmp_fprintf(stderr, "\n\tn = %d\n", n);
      gmp_fprintf(stderr, "\tE: y^2 = x^3 + %Zd * x + %Zd\n", a, b);
      gmp_fprintf(stderr, "\tP = (%Zd,%Zd,1)\n", x0, y0);
#endif /* DEBUG */

      /* the discriminant of the curve and n are required to be coprimes
       * -- if not, then either
       *   A) n divides the discriminant -- a new curve must be generated
       *   B) n is composite and a proper factor is found -- the algorithm can
       *      terminate
       */

      ec_discriminant(tmp, a, b);

#ifdef DEBUG
      mpz_mod_ui(tmp, tmp, n);
      gmp_fprintf(stderr, "\tdelta(E/GF(n)) = %Zd\n", tmp);
#endif /* DEBUG */

      mpz_gcd_ui(tmp, tmp, n);

#ifdef DEBUG
      gmp_fprintf(stderr, "\tgcd(delta, n) = %Zd\n", tmp);
#endif /* DEBUG */

      if (0 == mpz_cmp_ui(tmp, 1))
      {
        break;
      }
      else if (0 != mpz_cmp_ui(tmp, n))
      {
#ifdef DEBUG
        gmp_fprintf(stderr, "\tfound a proper factor, %d is composite\n", n);
#endif /* DEBUG */
        is_prime = 0;
        goto cleanup_and_return;
      }
    }

    /* P + P != 0, or a new curve is generated
     */
    z = ec_add(xt, yt, x0, y0, 1, x0, y0, 1, n, a);

#ifdef DEBUG
    gmp_fprintf(stderr, "\t2 * P = (%Zd,%Zd,%d)\n", xt, yt, z);
#endif /* DEBUG */

    if (0 == z)
    {
      continue;
    }

    /* the curve order algorithm failing indicates n is composite
     */
    if (!(ec_order(tmp, a, b, n)))
    {
#ifdef DEBUG
      gmp_fprintf(stderr,
          "\tcurve order algorithm failed, %d must be composite\n", n);
#endif /* DEBUG */

      is_prime = 0;
      break;
    }

#ifdef DEBUG
    gmp_fprintf(stderr, "\t|E/GF(n)| = %Zd\n", tmp);
#endif /* DEBUG */

    /* the curve order should be the multiple of 2 and a "probable prime" n --
     * if the order is not even, a new curve is generated
     */
    if (!mpz_even_p(tmp))
    {
#ifdef DEBUG
      gmp_fprintf(stderr, "\t|E/GF(n)| is odd, generating new curve...\n");
#endif /* DEBUG */
      continue;
    }

    /* order * P = 0, or n is composite
     */
    z = ec_times(xt, yt, x0, y0, 1, tmp, n, a);

#ifdef DEBUG
    gmp_fprintf(stderr, "\t|E| * P = (%Zd,%Zd,%d)\n", xt, yt, z);
#endif /* DEBUG */

    if (0 != z)
    {
#ifdef DEBUG
      gmp_fprintf(stderr, "\t|E| * P is non-zero, %d is composite\n", n);
#endif /* DEBUG */
      is_prime = 0;
      break;
    }

    /* at this point, order/2 being a prime implies n is a prime --
     * a recursive call to ecpp_test is used to test order/2 for primality
     */
    mpz_div_ui(tmp, tmp, 2);
    if (ecpp_test(mpz_get_ui(tmp)))
    {
      is_prime = 1;
      break;
    }
  }

cleanup_and_return:
  mpz_clear(a);
  mpz_clear(b);
  mpz_clear(x0);
  mpz_clear(y0);
  mpz_clear(xt);
  mpz_clear(yt);
  mpz_clear(tmp);

  return is_prime;
}
Beispiel #30
0
void
one_test (mpz_t op1, mpz_t op2, mpz_t ref, int i)
{
  /*
  printf ("%ld %ld %ld\n", SIZ (op1), SIZ (op2), SIZ (ref));
  fflush (stdout);
  */

  /*
  fprintf (stderr, "op1=");  debug_mp (op1, -16);
  fprintf (stderr, "op2=");  debug_mp (op2, -16);
  */

  mpz_gcdext (gcd1, s, NULL, op1, op2);

  if (ref && mpz_cmp (ref, gcd1) != 0)
    {
      fprintf (stderr, "ERROR in test %d\n", i);
      fprintf (stderr, "mpz_gcdext returned incorrect result\n");
      fprintf (stderr, "op1=");                 debug_mp (op1, -16);
      fprintf (stderr, "op2=");                 debug_mp (op2, -16);
      fprintf (stderr, "expected result:\n");   debug_mp (ref, -16);
      fprintf (stderr, "mpz_gcdext returns:\n");debug_mp (gcd1, -16);
      abort ();
    }

  if (!gcdext_valid_p(op1, op2, gcd1, s))
    {
      fprintf (stderr, "ERROR in test %d\n", i);
      fprintf (stderr, "mpz_gcdext returned invalid result\n");
      fprintf (stderr, "op1=");                 debug_mp (op1, -16);
      fprintf (stderr, "op2=");                 debug_mp (op2, -16);
      fprintf (stderr, "mpz_gcdext returns:\n");debug_mp (gcd1, -16);
      abort ();
    }

  mpz_gcd (gcd2, op1, op2);
  if (mpz_cmp (gcd2, gcd1) != 0)
    {
      fprintf (stderr, "ERROR in test %d\n", i);
      fprintf (stderr, "mpz_gcd returned incorrect result\n");
      fprintf (stderr, "op1=");                 debug_mp (op1, -16);
      fprintf (stderr, "op2=");                 debug_mp (op2, -16);
      fprintf (stderr, "expected result:\n");   debug_mp (gcd1, -16);
      fprintf (stderr, "mpz_gcd returns:\n");   debug_mp (gcd2, -16);
      abort ();
    }

  /* This should probably move to t-gcd_ui.c */
  if (mpz_fits_ulong_p (op1) || mpz_fits_ulong_p (op2))
    {
      if (mpz_fits_ulong_p (op1))
	mpz_gcd_ui (gcd2, op2, mpz_get_ui (op1));
      else
	mpz_gcd_ui (gcd2, op1, mpz_get_ui (op2));
      if (mpz_cmp (gcd2, gcd1))
	{
	  fprintf (stderr, "ERROR in test %d\n", i);
	  fprintf (stderr, "mpz_gcd_ui returned incorrect result\n");
	  fprintf (stderr, "op1=");                 debug_mp (op1, -16);
	  fprintf (stderr, "op2=");                 debug_mp (op2, -16);
	  fprintf (stderr, "expected result:\n");   debug_mp (gcd1, -16);
	  fprintf (stderr, "mpz_gcd_ui returns:\n");   debug_mp (gcd2, -16);
	  abort ();
	}
    }

  mpz_gcdext (gcd2, temp1, temp2, op1, op2);
  mpz_mul (temp1, temp1, op1);
  mpz_mul (temp2, temp2, op2);
  mpz_add (temp1, temp1, temp2);
  
  if (mpz_cmp (gcd1, gcd2) != 0
      || mpz_cmp (gcd2, temp1) != 0)
    {
      fprintf (stderr, "ERROR in test %d\n", i);
      fprintf (stderr, "mpz_gcdext returned incorrect result\n");
      fprintf (stderr, "op1=");                 debug_mp (op1, -16);
      fprintf (stderr, "op2=");                 debug_mp (op2, -16);
      fprintf (stderr, "expected result:\n");   debug_mp (gcd1, -16);
      fprintf (stderr, "mpz_gcdext returns:\n");debug_mp (gcd2, -16);
      abort ();
    }
}