Example #1
0
BigInt& BigInt::operator += (const BigInt &b)
{
	mpz_add(mImpl,mImpl,b.mImpl);
	return *this;
}
Example #2
0
// set op to (op1 + op2) mod d, using tmp for the calculation
inline static void mpz_addm( mpz_t op, const mpz_t op1, const mpz_t op2, const mpz_t d, mpz_t tmp )
{
	mpz_add(tmp, op1, op2);
	mpz_mod(op, tmp, d);
}
Example #3
0
File: PVS.c Project: Gaspi/pvs2C
void pvsAdd(BigInt result, const BigInt a, const BigInt b) {
  mpz_add( result, a, b );
}
Example #4
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 tpm_bn_add(tpm_bn_t res, tpm_bn_t a, tpm_bn_t b)
{
  mpz_add(res, a, b);
}
Example #6
0
/* compute in y an approximation of sum(x^k/k/k!, k=1..infinity),
   and return e such that the absolute error is bound by 2^e ulp(y) */
static mp_exp_t
mpfr_eint_aux (mpfr_t y, mpfr_srcptr x)
{
  mpfr_t eps; /* dynamic (absolute) error bound on t */
  mpfr_t erru, errs;
  mpz_t m, s, t, u;
  mp_exp_t e, sizeinbase;
  mp_prec_t w = MPFR_PREC(y);
  unsigned long k;
  MPFR_GROUP_DECL (group);

  /* for |x| <= 1, we have S := sum(x^k/k/k!, k=1..infinity) = x + R(x)
     where |R(x)| <= (x/2)^2/(1-x/2) <= 2*(x/2)^2
     thus |R(x)/x| <= |x|/2
     thus if |x| <= 2^(-PREC(y)) we have |S - o(x)| <= ulp(y) */

  if (MPFR_GET_EXP(x) <= - (mp_exp_t) w)
    {
      mpfr_set (y, x, GMP_RNDN);
      return 0;
    }

  mpz_init (s); /* initializes to 0 */
  mpz_init (t);
  mpz_init (u);
  mpz_init (m);
  MPFR_GROUP_INIT_3 (group, 31, eps, erru, errs);
  e = mpfr_get_z_exp (m, x); /* x = m * 2^e */
  MPFR_ASSERTD (mpz_sizeinbase (m, 2) == MPFR_PREC (x));
  if (MPFR_PREC (x) > w)
    {
      e += MPFR_PREC (x) - w;
      mpz_tdiv_q_2exp (m, m, MPFR_PREC (x) - w);
    }
  /* remove trailing zeroes from m: this will speed up much cases where
     x is a small integer divided by a power of 2 */
  k = mpz_scan1 (m, 0);
  mpz_tdiv_q_2exp (m, m, k);
  e += k;
  /* initialize t to 2^w */
  mpz_set_ui (t, 1);
  mpz_mul_2exp (t, t, w);
  mpfr_set_ui (eps, 0, GMP_RNDN); /* eps[0] = 0 */
  mpfr_set_ui (errs, 0, GMP_RNDN);
  for (k = 1;; k++)
    {
      /* let eps[k] be the absolute error on t[k]:
         since t[k] = trunc(t[k-1]*m*2^e/k), we have
         eps[k+1] <= 1 + eps[k-1]*m*2^e/k + t[k-1]*m*2^(1-w)*2^e/k
                  =  1 + (eps[k-1] + t[k-1]*2^(1-w))*m*2^e/k
                  = 1 + (eps[k-1]*2^(w-1) + t[k-1])*2^(1-w)*m*2^e/k */
      mpfr_mul_2ui (eps, eps, w - 1, GMP_RNDU);
      mpfr_add_z (eps, eps, t, GMP_RNDU);
      MPFR_MPZ_SIZEINBASE2 (sizeinbase, m);
      mpfr_mul_2si (eps, eps, sizeinbase - (w - 1) + e, GMP_RNDU);
      mpfr_div_ui (eps, eps, k, GMP_RNDU);
      mpfr_add_ui (eps, eps, 1, GMP_RNDU);
      mpz_mul (t, t, m);
      if (e < 0)
        mpz_tdiv_q_2exp (t, t, -e);
      else
        mpz_mul_2exp (t, t, e);
      mpz_tdiv_q_ui (t, t, k);
      mpz_tdiv_q_ui (u, t, k);
      mpz_add (s, s, u);
      /* the absolute error on u is <= 1 + eps[k]/k */
      mpfr_div_ui (erru, eps, k, GMP_RNDU);
      mpfr_add_ui (erru, erru, 1, GMP_RNDU);
      /* and that on s is the sum of all errors on u */
      mpfr_add (errs, errs, erru, GMP_RNDU);
      /* we are done when t is smaller than errs */
      if (mpz_sgn (t) == 0)
        sizeinbase = 0;
      else
        MPFR_MPZ_SIZEINBASE2 (sizeinbase, t);
      if (sizeinbase < MPFR_GET_EXP (errs))
        break;
    }
  /* the truncation error is bounded by (|t|+eps)/k*(|x|/k + |x|^2/k^2 + ...)
     <= (|t|+eps)/k*|x|/(k-|x|) */
  mpz_abs (t, t);
  mpfr_add_z (eps, eps, t, GMP_RNDU);
  mpfr_div_ui (eps, eps, k, GMP_RNDU);
  mpfr_abs (erru, x, GMP_RNDU); /* |x| */
  mpfr_mul (eps, eps, erru, GMP_RNDU);
  mpfr_ui_sub (erru, k, erru, GMP_RNDD);
  if (MPFR_IS_NEG (erru))
    {
      /* the truncated series does not converge, return fail */
      e = w;
    }
  else
    {
      mpfr_div (eps, eps, erru, GMP_RNDU);
      mpfr_add (errs, errs, eps, GMP_RNDU);
      mpfr_set_z (y, s, GMP_RNDN);
      mpfr_div_2ui (y, y, w, GMP_RNDN);
      /* errs was an absolute error bound on s. We must convert it to an error
         in terms of ulp(y). Since ulp(y) = 2^(EXP(y)-PREC(y)), we must
         divide the error by 2^(EXP(y)-PREC(y)), but since we divided also
         y by 2^w = 2^PREC(y), we must simply divide by 2^EXP(y). */
      e = MPFR_GET_EXP (errs) - MPFR_GET_EXP (y);
    }
  MPFR_GROUP_CLEAR (group);
  mpz_clear (s);
  mpz_clear (t);
  mpz_clear (u);
  mpz_clear (m);
  return e;
}
Example #7
0
int
main (int argc, char **argv)
{
  gmp_randstate_ptr rands;
  unsigned long maxnbits, maxdbits, nbits, dbits;
  mpz_t n, d, q, r, tz, junk;
  mp_size_t maxnn, maxdn, nn, dn, clearn, i;
  mp_ptr np, dup, dnp, qp, rp, junkp;
  mp_limb_t t;
  gmp_pi1_t dinv;
  long count = COUNT;
  mp_ptr scratch;
  mp_limb_t ran;
  mp_size_t alloc, itch;
  mp_limb_t rran0, rran1, qran0, qran1;
  TMP_DECL;

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

  maxdbits = MAX_DN;
  maxnbits = MAX_NN;

  tests_start ();
  rands = RANDS;

  mpz_init (n);
  mpz_init (d);
  mpz_init (q);
  mpz_init (r);
  mpz_init (tz);
  mpz_init (junk);

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

  TMP_MARK;

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

  alloc = 1;
  scratch = __GMP_ALLOCATE_FUNC_LIMBS (alloc);

  for (test = -300; test < count; test++)
    {
      nbits = random_word (rands) % (maxnbits - GMP_NUMB_BITS) + 2 * GMP_NUMB_BITS;

      if (test < 0)
	dbits = (test + 300) % (nbits - 1) + 1;
      else
	dbits = random_word (rands) % (nbits - 1) % maxdbits + 1;

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

      do
	RANDFUNC (d, rands, dbits);
      while (mpz_sgn (d) == 0);
      dn = SIZ (d);
      dup = PTR (d);
      MPN_COPY (dnp, dup, dn);
      dnp[dn - 1] |= GMP_NUMB_HIGHBIT;

      if (test % 2 == 0)
	{
	  RANDFUNC (n, rands, nbits);
	  nn = SIZ (n);
	  ASSERT_ALWAYS (nn >= dn);
	}
      else
	{
	  do
	    {
	      RANDFUNC (q, rands, random_word (rands) % (nbits - dbits + 1));
	      RANDFUNC (r, rands, random_word (rands) % mpz_sizeinbase (d, 2));
	      mpz_mul (n, q, d);
	      mpz_add (n, n, r);
	      nn = SIZ (n);
	    }
	  while (nn > maxnn || nn < dn);
	}

      ASSERT_ALWAYS (nn <= maxnn);
      ASSERT_ALWAYS (dn <= maxdn);

      mpz_urandomb (junk, rands, nbits);
      junkp = PTR (junk);

      np = PTR (n);

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

      if (t % 17 == 0)
	{
	  dnp[dn - 1] = GMP_NUMB_MAX;
	  dup[dn - 1] = GMP_NUMB_MAX;
	}

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

      if (dn >= 2)
	invert_pi1 (dinv, dnp[dn - 1], dnp[dn - 2]);

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

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

      ran = random_word (rands);

      if ((double) (nn - dn) * dn < 1e5)
	{
	  /* Test mpn_sbpi1_div_qr */
	  if (dn > 2)
	    {
	      MPN_COPY (rp, np, nn);
	      if (nn > dn)
		MPN_COPY (qp, junkp, nn - dn);
	      qp[nn - dn] = mpn_sbpi1_div_qr (qp, rp, nn, dnp, dn, dinv.inv32);
	      check_one (qp, rp, np, nn, dnp, dn, "mpn_sbpi1_div_qr", 0);
	    }

	  /* Test mpn_sbpi1_divappr_q */
	  if (dn > 2)
	    {
	      MPN_COPY (rp, np, nn);
	      if (nn > dn)
		MPN_COPY (qp, junkp, nn - dn);
	      qp[nn - dn] = mpn_sbpi1_divappr_q (qp, rp, nn, dnp, dn, dinv.inv32);
	      check_one (qp, NULL, np, nn, dnp, dn, "mpn_sbpi1_divappr_q", 1);
	    }

	  /* Test mpn_sbpi1_div_q */
	  if (dn > 2)
	    {
	      MPN_COPY (rp, np, nn);
	      if (nn > dn)
		MPN_COPY (qp, junkp, nn - dn);
	      qp[nn - dn] = mpn_sbpi1_div_q (qp, rp, nn, dnp, dn, dinv.inv32);
	      check_one (qp, NULL, np, nn, dnp, dn, "mpn_sbpi1_div_q", 0);
	    }

	  /* Test mpn_sb_div_qr_sec */
	  itch = 3 * nn + 4;
	  if (itch + 1 > alloc)
	    {
	      scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1);
	      alloc = itch + 1;
	    }
	  scratch[itch] = ran;
	  MPN_COPY (rp, np, nn);
	  if (nn >= dn)
	    MPN_COPY (qp, junkp, nn - dn + 1);
	  mpn_sb_div_qr_sec (qp, rp, nn, dup, dn, scratch);
	  ASSERT_ALWAYS (ran == scratch[itch]);
	  check_one (qp, rp, np, nn, dup, dn, "mpn_sb_div_qr_sec", 0);

	  /* Test mpn_sb_div_r_sec */
	  itch = nn + 2 * dn + 2;
	  if (itch + 1 > alloc)
	    {
	      scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1);
	      alloc = itch + 1;
	    }
	  scratch[itch] = ran;
	  MPN_COPY (rp, np, nn);
	  mpn_sb_div_r_sec (rp, nn, dup, dn, scratch);
	  ASSERT_ALWAYS (ran == scratch[itch]);
	  /* Note: Since check_one cannot cope with random-only functions, we
	     pass qp[] from the previous function, mpn_sb_div_qr_sec.  */
	  check_one (qp, rp, np, nn, dup, dn, "mpn_sb_div_r_sec", 0);
	}

      /* Test mpn_dcpi1_div_qr */
      if (dn >= 6 && nn - dn >= 3)
	{
	  MPN_COPY (rp, np, nn);
	  if (nn > dn)
	    MPN_COPY (qp, junkp, nn - dn);
	  qp[nn - dn] = mpn_dcpi1_div_qr (qp, rp, nn, dnp, dn, &dinv);
	  ASSERT_ALWAYS (qp[-1] == qran0);  ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
	  ASSERT_ALWAYS (rp[-1] == rran0);
	  check_one (qp, rp, np, nn, dnp, dn, "mpn_dcpi1_div_qr", 0);
	}

      /* Test mpn_dcpi1_divappr_q */
      if (dn >= 6 && nn - dn >= 3)
	{
	  MPN_COPY (rp, np, nn);
	  if (nn > dn)
	    MPN_COPY (qp, junkp, nn - dn);
	  qp[nn - dn] = mpn_dcpi1_divappr_q (qp, rp, nn, dnp, dn, &dinv);
	  ASSERT_ALWAYS (qp[-1] == qran0);  ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
	  ASSERT_ALWAYS (rp[-1] == rran0);
	  check_one (qp, NULL, np, nn, dnp, dn, "mpn_dcpi1_divappr_q", 1);
	}

      /* Test mpn_dcpi1_div_q */
      if (dn >= 6 && nn - dn >= 3)
	{
	  MPN_COPY (rp, np, nn);
	  if (nn > dn)
	    MPN_COPY (qp, junkp, nn - dn);
	  qp[nn - dn] = mpn_dcpi1_div_q (qp, rp, nn, dnp, dn, &dinv);
	  ASSERT_ALWAYS (qp[-1] == qran0);  ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
	  ASSERT_ALWAYS (rp[-1] == rran0);
	  check_one (qp, NULL, np, nn, dnp, dn, "mpn_dcpi1_div_q", 0);
	}

     /* Test mpn_mu_div_qr */
      if (nn - dn > 2 && dn >= 2)
	{
	  itch = mpn_mu_div_qr_itch (nn, dn, 0);
	  if (itch + 1 > alloc)
	    {
	      scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1);
	      alloc = itch + 1;
	    }
	  scratch[itch] = ran;
	  MPN_COPY (qp, junkp, nn - dn);
	  MPN_ZERO (rp, dn);
	  rp[dn] = rran1;
	  qp[nn - dn] = mpn_mu_div_qr (qp, rp, np, nn, dnp, dn, scratch);
	  ASSERT_ALWAYS (ran == scratch[itch]);
	  ASSERT_ALWAYS (qp[-1] == qran0);  ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
	  ASSERT_ALWAYS (rp[-1] == rran0);  ASSERT_ALWAYS (rp[dn] == rran1);
	  check_one (qp, rp, np, nn, dnp, dn, "mpn_mu_div_qr", 0);
	}

      /* Test mpn_mu_divappr_q */
      if (nn - dn > 2 && dn >= 2)
	{
	  itch = mpn_mu_divappr_q_itch (nn, dn, 0);
	  if (itch + 1 > alloc)
	    {
	      scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1);
	      alloc = itch + 1;
	    }
	  scratch[itch] = ran;
	  MPN_COPY (qp, junkp, nn - dn);
	  qp[nn - dn] = mpn_mu_divappr_q (qp, np, nn, dnp, dn, scratch);
	  ASSERT_ALWAYS (ran == scratch[itch]);
	  ASSERT_ALWAYS (qp[-1] == qran0);  ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
	  check_one (qp, NULL, np, nn, dnp, dn, "mpn_mu_divappr_q", 4);
	}

      /* Test mpn_mu_div_q */
      if (nn - dn > 2 && dn >= 2)
	{
	  itch = mpn_mu_div_q_itch (nn, dn, 0);
	  if (itch + 1> alloc)
	    {
	      scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1);
	      alloc = itch + 1;
	    }
	  scratch[itch] = ran;
	  MPN_COPY (qp, junkp, nn - dn);
	  qp[nn - dn] = mpn_mu_div_q (qp, np, nn, dnp, dn, scratch);
	  ASSERT_ALWAYS (ran == scratch[itch]);
	  ASSERT_ALWAYS (qp[-1] == qran0);  ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
	  check_one (qp, NULL, np, nn, dnp, dn, "mpn_mu_div_q", 0);
	}

      if (1)
	{
	  itch = nn + 1;
	  if (itch + 1> alloc)
	    {
	      scratch = __GMP_REALLOCATE_FUNC_LIMBS (scratch, alloc, itch + 1);
	      alloc = itch + 1;
	    }
	  scratch[itch] = ran;
	  mpn_div_q (qp, np, nn, dup, dn, scratch);
	  ASSERT_ALWAYS (ran == scratch[itch]);
	  ASSERT_ALWAYS (qp[-1] == qran0);  ASSERT_ALWAYS (qp[nn - dn + 1] == qran1);
	  check_one (qp, NULL, np, nn, dup, dn, "mpn_div_q", 0);
	}

      if (dn >= 2 && nn >= 2)
	{
	  mp_limb_t qh;

	  /* mpn_divrem_2 */
	  MPN_COPY (rp, np, nn);
	  qp[nn - 2] = qp[nn-1] = qran1;

	  qh = mpn_divrem_2 (qp, 0, rp, nn, dnp + dn - 2);
	  ASSERT_ALWAYS (qp[nn - 2] == qran1);
	  ASSERT_ALWAYS (qp[-1] == qran0);  ASSERT_ALWAYS (qp[nn - 1] == qran1);
	  qp[nn - 2] = qh;
	  check_one (qp, rp, np, nn, dnp + dn - 2, 2, "mpn_divrem_2", 0);

	  /* Missing: divrem_2 with fraction limbs. */

	  /* mpn_div_qr_2 */
	  qp[nn - 2] = qran1;

	  qh = mpn_div_qr_2 (qp, rp, np, nn, dup + dn - 2);
	  ASSERT_ALWAYS (qp[nn - 2] == qran1);
	  ASSERT_ALWAYS (qp[-1] == qran0);  ASSERT_ALWAYS (qp[nn - 1] == qran1);
	  qp[nn - 2] = qh;
	  check_one (qp, rp, np, nn, dup + dn - 2, 2, "mpn_div_qr_2", 0);
	}
    }

  __GMP_FREE_FUNC_LIMBS (scratch, alloc);

  TMP_FREE;

  mpz_clear (n);
  mpz_clear (d);
  mpz_clear (q);
  mpz_clear (r);
  mpz_clear (tz);
  mpz_clear (junk);

  tests_end ();
  return 0;
}
Example #8
0
int
main (int argc, char **argv)
{
  mpz_t dividend, divisor;
  mpz_t quotient, remainder;
  mpz_t quotient2, remainder2;
  mpz_t temp;
  mp_size_t dividend_size, divisor_size;
  int i;
  int reps = 200;
  gmp_randstate_ptr rands;
  mpz_t bs;
  unsigned long bsi, size_range;

  tests_start ();
  rands = RANDS;

  mpz_init (bs);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  tests_end ();
  exit (0);
}
Example #9
0
int signedshortmessage(
		unsigned char *sm,
		unsigned long long *smlen,
		const unsigned char *m,
		unsigned long long mlen,
		const unsigned char *sk,
		unsigned long long sklen
		)
{
	init_all();

	/* See Handbook of Elliptic and Hyperelliptic Curve Cryptography, page 570 f */
	mpz_t k_mpz;
	mpz_t sk_mpz;
	mpz_t hm_mpz;
	mpz_t u;
	mpz_t s;

	mpz_init(k_mpz);
	mpz_init(sk_mpz);
	mpz_init(hm_mpz);
	mpz_init(u);
	mpz_init(s);

	bytearray_to_mpz_t(hm_mpz, m, mlen);
	bytearray_to_mpz_t(sk_mpz, sk, sklen);

	divclass E;
	divclass_init(E);
	int i;

	do
	{
		do
		{
			gen_keypair(k_mpz, E);

			divclass_make_affine(E, E);
			divclass_hash(u, E);
		}
		while(mpz_cmp_ui(u, 0) == 0);
		mpz_invert(s, k_mpz, p);

		mpz_mul(sk_mpz, sk_mpz, u);
		mpz_add(hm_mpz, hm_mpz, sk_mpz);
		mpz_mul(s, s, hm_mpz);
		mpz_mod(s, s, p);
	}
	while(mpz_cmp_ui(s, 0) == 0);

	/* Copy message to signed message */
	for(i = 0; i < SHORTMESSAGE_BYTES; i++)
	{
		sm[i] = m[i];
	}

	/* Append signature */
	mpz_t_to_bytearray(sm + SHORTMESSAGE_BYTES, SECRETKEY_BYTES, u);
	mpz_t_to_bytearray(sm + SHORTMESSAGE_BYTES + SECRETKEY_BYTES, SECRETKEY_BYTES, s);

	*smlen = SIGNATURE_BYTES;

	mpz_clear(k_mpz);
	mpz_clear(sk_mpz);
	mpz_clear(hm_mpz);
	mpz_clear(u);
	mpz_clear(s);

	clear_all();
	return 0;
}
Example #10
0
void gmp_num::set_add(num* a, num* b) {
	mpz_add(val, *num2mpz(a), *num2mpz(b));
}
/**
 * <p>Factorises a big integer using Pollard's rho method and some tweaks</a>
 * <p>
 *   Pollard's rho (ρ) method is a special-purpose integer factorisation algorithm used
 *   for factoring integers with small factors. As you know, they are not that unusual.
 * </p>
 *
 * @param   n                 The big integer
 * @param   c                 The seed index, 0 for autoselection of seed value
 * @param   output            The buffer to which to add [probable] prime factors
 * @param   outputPtr         The buffer's pointer
 * @param   initialRootOrder  The initial root order
 * @return                    Whether the factorisation was successful
 */
boolean factorisePollardsRho(Bignum n, llong c, Buffer output, long* outputPtr, int initialRootOrder)
{
    if (c > SEED_LIMIT)
        return false;

    llong cc = *(seeds + c);
    if (c == 0)
        { selectSeed(cc, n); }

    int i, m, cd;
    String prime;
    int itr;

    int rootOrder = initialRootOrder, pRootOrder = 1, r;

    #define f(X)  mpz_mul(X, X, X);  mpz_add_ui(X, X, cc)

    Bignum factor; mpz_init_set(factor, n);
    Bignum d; mpz_init(d);
    Bignum x; mpz_init_set_ui(x, cc);
    Bignum y; mpz_init_set_ui(y, cc);
    Bignum conjA; mpz_init(conjA);
    Bignum conjB; mpz_init(conjB);


    #define recursion(X, Y)  factorisePollardsRho(X, c + 1, output, outputPtr, Y)


    for (;;)
    {
        pRootOrder = maxRoot(factor);
	if (pRootOrder != 1)
	{
	    rootOrder *= pRootOrder;
	    mpz_root(factor, factor, pRootOrder);
	}
	else
	{
	    //There may exist a number b = (A = ⌊√n⌋ + 1)² − n such that B = √b is an integer
	    //in which case n = (A − B)(A + B)  [n is(!) odd composite]. If not, the only the
	    //trivial iteration of A (A += 1) seems to be the one not consuming your entire
	    //CPU and it is also guaranteed to find the factors, but it is just so slow.

	    mpz_sqrt(conjA, factor);
	    mpz_add_ui(conjA, conjA, 1);
	    mpz_mul(conjB, conjA, conjA);
	    mpz_sub(conjB, conjB, factor);

	    if (mpz_root(conjB, conjB, 2))
	    {
		mpz_sub(factor, conjA, conjB);
	        if (recursion(factor, rootOrder) == false)
		    return false;

		mpz_add(factor, conjA, conjB);
		return recursion(factor, rootOrder);
	    }
	}


        itr = 0;
	do // Pollard  //                  http://en.wikipedia.org/wiki/Pollard's_rho_algorithm#Variants
	{
	    if (c)
	    {
	        if (itr++ > MAX_ITERATIONS_C)
		    return false;
	    }
	    else if (cc >= 10000)
	        if (itr++ > MAX_ITERATIONS)
	            return recursion(factor, rootOrder);

	    //Floyd
	    f(x); f(y); f(y);
	    mpz_mod(x, x, factor);
	    mpz_mod(y, y, factor);

	    mpz_sub(d, x, y);
	    mpz_abs(d, d);
	    mpz_gcd(d, d, factor);
	}
	  while (equals(d, 1));


	if (mpz_cmp(factor, d) == 0)
	{
	    if (isPrime(factor))
	    {
	        String strFactor = bignumToString(factor);
	        for (r = 0; r < rootOrder; r++)
		{
		    appendToBuffer(output, *outputPtr, strFactor);
		    appendToBuffer(output, (*outputPtr) + 1, "\n");
		    (*outputPtr) += 2;
		}
	        return true;
	    }
	    return recursion(factor, rootOrder);
	}

	if (isNotPrime(d))
	{
	    cd = contDiv(factor, factor, d, null, null, 0);

            if (recursion(d, rootOrder * cd) == false)
	        return false;

	    if (equals(factor, 1))
	        return true;
	}
	else
	{
	    contDiv(factor, factor, d, output, outputPtr, rootOrder);

	    if (equals(factor, 1))
	        return true;
	}
        
	if (isPrime(factor))
	{
	    String strFactor = bignumToString(factor);
	    for (r = 0; r < rootOrder; r++)
	    {
	        appendToBuffer(output, *outputPtr, strFactor);
		appendToBuffer(output, (*outputPtr) + 1, "\n");
		(*outputPtr) += 2;
	    }
	    return true;
	}
    }

    return true;
}
Example #12
0
void RLRequest::rl_sadd(){
    if(args.size()<2){
        connection->write_error("ERR wrong number of arguments for 'sadd' command");
        return;
    }
    string &sname = args[0];
    string sizekey = _encode_compdata_size_key(sname, CompDataType::SET);
    uint32_t new_mem = 0;

    std::string out;
    leveldb::WriteBatch write_batch;
    leveldb::Status status;

    for(uint32_t i=1; i<args.size(); i++){
        string key = _encode_set_key(sname, args[i]);

        status = connection->server->db[connection->db_index]->Get(
            connection->server->read_options, key, &out);

        if(status.IsNotFound()) {
            // set value
            write_batch.Put(key, "\1");
            ++new_mem;
        }
    }
    if(new_mem == 0){
        connection->write_integer("0", 1);
        return;
    }
    // update size!
    status = connection->server->db[connection->db_index]->Get(
        connection->server->read_options, sizekey, &out);

    mpz_t delta;
    mpz_init(delta);
    mpz_set_ui(delta, new_mem);

    char *str_oldv = NULL;
    if(status.IsNotFound()){
        str_oldv = strdup("0");
    }else if(status.ok()){
        str_oldv = (char*)malloc(out.size()+1);
        memcpy(str_oldv, out.data(), out.size());
        str_oldv[out.size()] = 0;
    }else{
        connection->write_error("SADD ERROR 1");
        return;
    }

    mpz_t old_v;
    mpz_init(old_v);
    mpz_set_str(old_v, str_oldv, 10);
    free(str_oldv);
    mpz_add(old_v, old_v, delta);
    char *str_newv=mpz_get_str(NULL, 10, old_v);
    char *str_delta=mpz_get_str(NULL, 10, delta);
    mpz_clear(delta);
    mpz_clear(old_v);

    write_batch.Put(sizekey, str_newv);

    status = connection->server->db[connection->db_index]->Write(connection->server->write_options, &write_batch);

    if(!status.ok()) {
        connection->write_error("SADD ERROR 2");
    }else{
        connection->write_integer(str_delta, strlen(str_delta));
    }
    free(str_newv);
    free(str_delta);
}
Example #13
0
int
mpfr_zeta_ui (mpfr_ptr z, unsigned long m, mp_rnd_t r)
{
  MPFR_ZIV_DECL (loop);

  if (m == 0)
    {
      mpfr_set_ui (z, 1, r);
      mpfr_div_2ui (z, z, 1, r);
      MPFR_CHANGE_SIGN (z);
      MPFR_RET (0);
    }
  else if (m == 1)
    {
      MPFR_SET_INF (z);
      MPFR_SET_POS (z);
      return 0;
    }
  else /* m >= 2 */
    {
      mp_prec_t p = MPFR_PREC(z);
      unsigned long n, k, err, kbits;
      mpz_t d, t, s, q;
      mpfr_t y;
      int inex;

      if (m >= p) /* 2^(-m) < ulp(1) = 2^(1-p). This means that
                     2^(-m) <= 1/2*ulp(1). We have 3^(-m)+4^(-m)+... < 2^(-m)
                     i.e. zeta(m) < 1+2*2^(-m) for m >= 3 */

        {
          if (m == 2) /* necessarily p=2 */
            return mpfr_set_ui_2exp (z, 13, -3, r);
          else if (r == GMP_RNDZ || r == GMP_RNDD || (r == GMP_RNDN && m > p))
            {
              mpfr_set_ui (z, 1, r);
              return -1;
            }
          else
            {
              mpfr_set_ui (z, 1, r);
              mpfr_nextabove (z);
              return 1;
            }
        }

      /* now treat also the case where zeta(m) - (1+1/2^m) < 1/2*ulp(1),
         and the result is either 1+2^(-m) or 1+2^(-m)+2^(1-p). */
      mpfr_init2 (y, 31);

      if (m >= p / 2) /* otherwise 4^(-m) > 2^(-p) */
        {
          /* the following is a lower bound for log(3)/log(2) */
          mpfr_set_str_binary (y, "1.100101011100000000011010001110");
          mpfr_mul_ui (y, y, m, GMP_RNDZ); /* lower bound for log2(3^m) */
          if (mpfr_cmp_ui (y, p + 2) >= 0)
            {
              mpfr_clear (y);
              mpfr_set_ui (z, 1, GMP_RNDZ);
              mpfr_div_2ui (z, z, m, GMP_RNDZ);
              mpfr_add_ui (z, z, 1, GMP_RNDZ);
              if (r != GMP_RNDU)
                return -1;
              mpfr_nextabove (z);
              return 1;
            }
        }

      mpz_init (s);
      mpz_init (d);
      mpz_init (t);
      mpz_init (q);

      p += MPFR_INT_CEIL_LOG2(p); /* account of the n term in the error */

      p += MPFR_INT_CEIL_LOG2(p) + 15; /* initial value */

      MPFR_ZIV_INIT (loop, p);
      for(;;)
        {
          /* 0.39321985067869744 = log(2)/log(3+sqrt(8)) */
          n = 1 + (unsigned long) (0.39321985067869744 * (double) p);
          err = n + 4;

          mpfr_set_prec (y, p);

          /* computation of the d[k] */
          mpz_set_ui (s, 0);
          mpz_set_ui (t, 1);
          mpz_mul_2exp (t, t, 2 * n - 1); /* t[n] */
          mpz_set (d, t);
          for (k = n; k > 0; k--)
            {
              count_leading_zeros (kbits, k);
              kbits = BITS_PER_MP_LIMB - kbits;
              /* if k^m is too large, use mpz_tdiv_q */
              if (m * kbits > 2 * BITS_PER_MP_LIMB)
                {
                  /* if we know in advance that k^m > d, then floor(d/k^m) will
                     be zero below, so there is no need to compute k^m */
                  kbits = (kbits - 1) * m + 1;
                  /* k^m has at least kbits bits */
                  if (kbits > mpz_sizeinbase (d, 2))
                    mpz_set_ui (q, 0);
                  else
                    {
                      mpz_ui_pow_ui (q, k, m);
                      mpz_tdiv_q (q, d, q);
                    }
                }
              else /* use several mpz_tdiv_q_ui calls */
                {
                  unsigned long km = k, mm = m - 1;
                  while (mm > 0 && km < ULONG_MAX / k)
                    {
                      km *= k;
                      mm --;
                    }
                  mpz_tdiv_q_ui (q, d, km);
                  while (mm > 0)
                    {
                      km = k;
                      mm --;
                      while (mm > 0 && km < ULONG_MAX / k)
                        {
                          km *= k;
                          mm --;
                        }
                      mpz_tdiv_q_ui (q, q, km);
                    }
                }
              if (k % 2)
                mpz_add (s, s, q);
              else
                mpz_sub (s, s, q);

              /* we have d[k] = sum(t[i], i=k+1..n)
                 with t[i] = n*(n+i-1)!*4^i/(n-i)!/(2i)!
                 t[k-1]/t[k] = k*(2k-1)/(n-k+1)/(n+k-1)/2 */
#if (BITS_PER_MP_LIMB == 32)
#define KMAX 46341 /* max k such that k*(2k-1) < 2^32 */
#elif (BITS_PER_MP_LIMB == 64)
#define KMAX 3037000500
#endif
#ifdef KMAX
              if (k <= KMAX)
                mpz_mul_ui (t, t, k * (2 * k - 1));
              else
#endif
                {
                  mpz_mul_ui (t, t, k);
                  mpz_mul_ui (t, t, 2 * k - 1);
                }
              mpz_div_2exp (t, t, 1);
              if (n < 1UL << (BITS_PER_MP_LIMB / 2))
                /* (n - k + 1) * (n + k - 1) < n^2 */
                mpz_divexact_ui (t, t, (n - k + 1) * (n + k - 1));
              else
                {
                  mpz_divexact_ui (t, t, n - k + 1);
                  mpz_divexact_ui (t, t, n + k - 1);
                }
              mpz_add (d, d, t);
            }

          /* multiply by 1/(1-2^(1-m)) = 1 + 2^(1-m) + 2^(2-m) + ... */
          mpz_div_2exp (t, s, m - 1);
          do
            {
              err ++;
              mpz_add (s, s, t);
              mpz_div_2exp (t, t, m - 1);
            }
          while (mpz_cmp_ui (t, 0) > 0);

          /* divide by d[n] */
          mpz_mul_2exp (s, s, p);
          mpz_tdiv_q (s, s, d);
          mpfr_set_z (y, s, GMP_RNDN);
          mpfr_div_2ui (y, y, p, GMP_RNDN);

          err = MPFR_INT_CEIL_LOG2 (err);

          if (MPFR_LIKELY(MPFR_CAN_ROUND (y, p - err, MPFR_PREC(z), r)))
            break;

          MPFR_ZIV_NEXT (loop, p);
        }
      MPFR_ZIV_FREE (loop);

      mpz_clear (d);
      mpz_clear (t);
      mpz_clear (q);
      mpz_clear (s);
      inex = mpfr_set (z, y, r);
      mpfr_clear (y);
      return inex;
    }
}
Example #14
0
File: rw.c Project: agl/rwb0fuz1024
int
main() {
  const int urfd = open("/dev/urandom", O_RDONLY);

  mpz_t p, q, n;

  fprintf(stderr, "Generating group...\n");
  init_random_prime(p, urfd, 512, 3);
  init_random_prime(q, urfd, 512, 7);

  print("  p:", p);
  print("  q:", q);

  mpz_init(n);
  mpz_mul(n, p, q);

  print("  n:", n);

  fprintf(stderr, "Performing extended Euclid...\n");
  mpz_t u, v;
  xgcd(u, v, p, q);
  mpz_mul(u, u, p);
  mpz_mul(v, v, q);

  print ("  u:", u);
  print ("  v:", v);

  fprintf(stderr, "Picking random element...\n");
  mpz_t e;
  random_element(e, urfd, 1024, n);
  print("  e:", e);

  fprintf(stderr, "Tweaking...\n");

  int a = is_quadratic_residue(e, p);
  int b = is_quadratic_residue(e, q);

  fprintf(stderr, "  residue state: [%d, %d]\n", a, b);

  int mul_2 = 0, negate = 0;

  if (a ^ b) {
    mul_2 = 1;
    a ^= 1;
  }

  if (!a) {
    negate = 1;
    a ^= 1;
    b ^= 1;
  }

  fprintf(stderr, "  tweaks: 2:%d -:%d\n", mul_2, negate);
  if (negate) {
    mpz_neg(e, e);
  }
  if (mul_2) {
    mpz_mul_ui(e, e, 2);
  }
  if (negate || mul_2)
    mpz_mod(e, e, n);

  print("  tweaked e:", e);

  uint8_t root;
  read(urfd, &root, 1);
  root &= 3;

  fprintf(stderr, "Calculating root %d...\n", root);

  mpz_t pp1over4, qp1over4;

  mpz_init_set(pp1over4, p);
  mpz_add_ui(pp1over4, pp1over4, 1);
  mpz_cdiv_q_2exp(pp1over4, pp1over4, 2);

  mpz_init_set(qp1over4, q);
  mpz_add_ui(qp1over4, qp1over4, 1);
  mpz_cdiv_q_2exp(qp1over4, qp1over4, 2);

  mpz_t proot, qroot;

  mpz_init_set(proot, e);
  mpz_powm(proot, e, pp1over4, p);

  mpz_init_set(qroot, e);
  mpz_powm(qroot, e, qp1over4, q);

  if (root & 1)
    mpz_neg(proot, proot);
  if (root & 2)
    mpz_neg(qroot, qroot);

  mpz_mul(proot, proot, v);
  mpz_mul(qroot, qroot, u);
  mpz_add(proot, proot, qroot);
  mpz_mod(proot, proot, n);

  print("  sig:", proot);

  fprintf(stderr, "Compressing signature...\n");

  mpz_t zsig;
  mpz_t ncopy;
  mpz_init_set(ncopy, n);
  signature_compress(zsig, proot, ncopy);

  print("  zsig:", zsig);

  mpz_t zsigcopy, t, t2;

  mpz_init(t);
  mpz_init(t2);
  mpz_init(zsigcopy);

  fprintf(stderr, "Performing 1000000 verifications\n");
  const uint64_t start_time = time_now();
  unsigned i;
  for (i = 0; i < 1000000; ++i) {
    mpz_set(zsigcopy, zsig);
    mpz_mul(zsigcopy, zsigcopy, zsigcopy);
    mpz_mul(zsigcopy, zsigcopy, e);
    mpz_mod(zsigcopy, zsigcopy, n);
    if (0 == mpz_sgn(zsigcopy))
      abort();

    mpz_sqrtrem(t, t2, zsigcopy);

    if (mpz_sgn(t2))
      abort();
  }

  const uint64_t end_time = time_now();
  fprintf(stderr, "verify time: %f\n", ((double) (end_time - start_time)) / 1000000);

  return 0;
}
Example #15
0
int main()
{
	int i, z;

	/* Initialize constants */
	mpz_init_set_str(c[0], "1", 10);
	mpz_init_set_str(c[1], "5", 10);

	/* Initialize variables */
	for (i = 0; i < VARS; i++) {
		mpz_init(v[i]);
	}

	/* Goal: ? a^5H */
	mpz_add(v[1], v[1], c[1]);
	mpz_add(v[35], v[35], c[0]);

	while (1) {
		if (0) {
		} else if (mpz_cmp(v[35], c[0]) >= 0) {
			/* H => mZ */
			mpz_sub(v[35], v[35], c[0]);
			mpz_add(v[12], v[12], c[0]);
			mpz_add(v[0], v[0], c[0]);
		} else if (mpz_cmp(v[1], c[0]) >= 0 && mpz_cmp(v[12], c[0]) >= 0) {
			/* am => af */
			mpz_sub(v[1], v[1], c[0]);
			mpz_sub(v[12], v[12], c[0]);
			mpz_add(v[1], v[1], c[0]);
			mpz_add(v[7], v[7], c[0]);
		} else if (mpz_cmp(v[12], c[0]) >= 0) {
			/* m => J */
			mpz_sub(v[12], v[12], c[0]);
			mpz_add(v[37], v[37], c[0]);
		} else if (mpz_cmp(v[1], c[0]) >= 0 && mpz_cmp(v[7], c[0]) >= 0) {
			/* af => aB */
			mpz_sub(v[1], v[1], c[0]);
			mpz_sub(v[7], v[7], c[0]);
			mpz_add(v[1], v[1], c[0]);
			mpz_add(v[15], v[15], c[0]);
		} else if (mpz_cmp(v[7], c[0]) >= 0) {
			/* f => k */
			mpz_sub(v[7], v[7], c[0]);
			mpz_add(v[10], v[10], c[0]);
		} else if (mpz_cmp(v[1], c[0]) >= 0 && mpz_cmp(v[15], c[0]) >= 0) {
			/* aB => u */
			mpz_sub(v[1], v[1], c[0]);
			mpz_sub(v[15], v[15], c[0]);
			mpz_add(v[22], v[22], c[0]);
		} else if (mpz_cmp(v[15], c[0]) >= 0) {
			/* B => u */
			mpz_sub(v[15], v[15], c[0]);
			mpz_add(v[22], v[22], c[0]);
		} else if (mpz_cmp(v[22], c[0]) >= 0) {
			/* u => cL */
			mpz_sub(v[22], v[22], c[0]);
			mpz_add(v[3], v[3], c[0]);
			mpz_add(v[38], v[38], c[0]);
		} else if (mpz_cmp(v[38], c[0]) >= 0) {
			/* L => eG */
			mpz_sub(v[38], v[38], c[0]);
			mpz_add(v[4], v[4], c[0]);
			mpz_add(v[32], v[32], c[0]);
		} else if (mpz_cmp(v[32], c[0]) >= 0) {
			/* G => f */
			mpz_sub(v[32], v[32], c[0]);
			mpz_add(v[7], v[7], c[0]);
		} else if (mpz_cmp(v[3], c[0]) >= 0 && mpz_cmp(v[10], c[0]) >= 0) {
			/* ck => cr */
			mpz_sub(v[3], v[3], c[0]);
			mpz_sub(v[10], v[10], c[0]);
			mpz_add(v[3], v[3], c[0]);
			mpz_add(v[21], v[21], c[0]);
		} else if (mpz_cmp(v[10], c[0]) >= 0) {
			/* k => d */
			mpz_sub(v[10], v[10], c[0]);
			mpz_add(v[5], v[5], c[0]);
		} else if (mpz_cmp(v[3], c[0]) >= 0 && mpz_cmp(v[21], c[0]) >= 0) {
			/* cr => b */
			mpz_sub(v[3], v[3], c[0]);
			mpz_sub(v[21], v[21], c[0]);
			mpz_add(v[2], v[2], c[0]);
		} else if (mpz_cmp(v[21], c[0]) >= 0) {
			/* r => b */
			mpz_sub(v[21], v[21], c[0]);
			mpz_add(v[2], v[2], c[0]);
		} else if (mpz_cmp(v[2], c[0]) >= 0 && mpz_cmp(v[0], c[0]) >= 0) {
			/* bZ => yZ */
			mpz_sub(v[2], v[2], c[0]);
			mpz_sub(v[0], v[0], c[0]);
			mpz_add(v[26], v[26], c[0]);
			mpz_add(v[0], v[0], c[0]);
		} else if (mpz_cmp(v[2], c[0]) >= 0) {
			/* b => j */
			mpz_sub(v[2], v[2], c[0]);
			mpz_add(v[11], v[11], c[0]);
		} else if (mpz_cmp(v[26], c[0]) >= 0 && mpz_cmp(v[0], c[0]) >= 0) {
			/* yZ => t */
			mpz_sub(v[26], v[26], c[0]);
			mpz_sub(v[0], v[0], c[0]);
			mpz_add(v[23], v[23], c[0]);
		} else if (mpz_cmp(v[26], c[0]) >= 0) {
			/* y => t */
			mpz_sub(v[26], v[26], c[0]);
			mpz_add(v[23], v[23], c[0]);
		} else if (mpz_cmp(v[23], c[0]) >= 0) {
			/* t => iK */
			mpz_sub(v[23], v[23], c[0]);
			mpz_add(v[8], v[8], c[0]);
			mpz_add(v[36], v[36], c[0]);
		} else if (mpz_cmp(v[36], c[0]) >= 0) {
			/* K => lE */
			mpz_sub(v[36], v[36], c[0]);
			mpz_add(v[13], v[13], c[0]);
			mpz_add(v[30], v[30], c[0]);
		} else if (mpz_cmp(v[30], c[0]) >= 0) {
			/* E => b */
			mpz_sub(v[30], v[30], c[0]);
			mpz_add(v[2], v[2], c[0]);
		} else if (mpz_cmp(v[8], c[0]) >= 0 && mpz_cmp(v[11], c[0]) >= 0) {
			/* ij => is */
			mpz_sub(v[8], v[8], c[0]);
			mpz_sub(v[11], v[11], c[0]);
			mpz_add(v[8], v[8], c[0]);
			mpz_add(v[20], v[20], c[0]);
		} else if (mpz_cmp(v[11], c[0]) >= 0) {
			/* j => I */
			mpz_sub(v[11], v[11], c[0]);
			mpz_add(v[34], v[34], c[0]);
		} else if (mpz_cmp(v[8], c[0]) >= 0 && mpz_cmp(v[20], c[0]) >= 0) {
			/* is => x */
			mpz_sub(v[8], v[8], c[0]);
			mpz_sub(v[20], v[20], c[0]);
			mpz_add(v[27], v[27], c[0]);
		} else if (mpz_cmp(v[20], c[0]) >= 0) {
			/* s => x */
			mpz_sub(v[20], v[20], c[0]);
			mpz_add(v[27], v[27], c[0]);
		} else if (mpz_cmp(v[27], c[0]) >= 0) {
			/* x => DZ */
			mpz_sub(v[27], v[27], c[0]);
			mpz_add(v[31], v[31], c[0]);
			mpz_add(v[0], v[0], c[0]);
		} else if (mpz_cmp(v[31], c[0]) >= 0) {
			/* D => j */
			mpz_sub(v[31], v[31], c[0]);
			mpz_add(v[11], v[11], c[0]);
		} else if (mpz_cmp(v[34], c[0]) >= 0) {
			/* I => k */
			mpz_sub(v[34], v[34], c[0]);
			mpz_add(v[10], v[10], c[0]);
		} else if (mpz_cmp(v[5], c[0]) >= 0 && mpz_cmp(v[0], c[0]) >= 0) {
			/* dZ => wZ */
			mpz_sub(v[5], v[5], c[0]);
			mpz_sub(v[0], v[0], c[0]);
			mpz_add(v[24], v[24], c[0]);
			mpz_add(v[0], v[0], c[0]);
		} else if (mpz_cmp(v[5], c[0]) >= 0) {
			/* d => h */
			mpz_sub(v[5], v[5], c[0]);
			mpz_add(v[9], v[9], c[0]);
		} else if (mpz_cmp(v[24], c[0]) >= 0 && mpz_cmp(v[0], c[0]) >= 0) {
			/* wZ => o */
			mpz_sub(v[24], v[24], c[0]);
			mpz_sub(v[0], v[0], c[0]);
			mpz_add(v[16], v[16], c[0]);
		} else if (mpz_cmp(v[24], c[0]) >= 0) {
			/* w => o */
			mpz_sub(v[24], v[24], c[0]);
			mpz_add(v[16], v[16], c[0]);
		} else if (mpz_cmp(v[16], c[0]) >= 0) {
			/* o => d */
			mpz_sub(v[16], v[16], c[0]);
			mpz_add(v[5], v[5], c[0]);
		} else if (mpz_cmp(v[9], c[0]) >= 0 && mpz_cmp(v[13], c[0]) >= 0) {
			/* hl => lp */
			mpz_sub(v[9], v[9], c[0]);
			mpz_sub(v[13], v[13], c[0]);
			mpz_add(v[13], v[13], c[0]);
			mpz_add(v[19], v[19], c[0]);
		} else if (mpz_cmp(v[9], c[0]) >= 0) {
			/* h => g */
			mpz_sub(v[9], v[9], c[0]);
			mpz_add(v[6], v[6], c[0]);
		} else if (mpz_cmp(v[13], c[0]) >= 0 && mpz_cmp(v[19], c[0]) >= 0) {
			/* lp => v */
			mpz_sub(v[13], v[13], c[0]);
			mpz_sub(v[19], v[19], c[0]);
			mpz_add(v[25], v[25], c[0]);
		} else if (mpz_cmp(v[19], c[0]) >= 0) {
			/* p => v */
			mpz_sub(v[19], v[19], c[0]);
			mpz_add(v[25], v[25], c[0]);
		} else if (mpz_cmp(v[25], c[0]) >= 0) {
			/* v => CZ */
			mpz_sub(v[25], v[25], c[0]);
			mpz_add(v[29], v[29], c[0]);
			mpz_add(v[0], v[0], c[0]);
		} else if (mpz_cmp(v[29], c[0]) >= 0) {
			/* C => h */
			mpz_sub(v[29], v[29], c[0]);
			mpz_add(v[9], v[9], c[0]);
		} else if (mpz_cmp(v[4], c[0]) >= 0 && mpz_cmp(v[6], c[0]) >= 0) {
			/* eg => en */
			mpz_sub(v[4], v[4], c[0]);
			mpz_sub(v[6], v[6], c[0]);
			mpz_add(v[4], v[4], c[0]);
			mpz_add(v[17], v[17], c[0]);
		} else if (mpz_cmp(v[6], c[0]) >= 0) {
			/* g => q */
			mpz_sub(v[6], v[6], c[0]);
			mpz_add(v[18], v[18], c[0]);
		} else if (mpz_cmp(v[4], c[0]) >= 0 && mpz_cmp(v[17], c[0]) >= 0) {
			/* en => z */
			mpz_sub(v[4], v[4], c[0]);
			mpz_sub(v[17], v[17], c[0]);
			mpz_add(v[28], v[28], c[0]);
		} else if (mpz_cmp(v[17], c[0]) >= 0) {
			/* n => z */
			mpz_sub(v[17], v[17], c[0]);
			mpz_add(v[28], v[28], c[0]);
		} else if (mpz_cmp(v[28], c[0]) >= 0) {
			/* z => aF */
			mpz_sub(v[28], v[28], c[0]);
			mpz_add(v[1], v[1], c[0]);
			mpz_add(v[33], v[33], c[0]);
		} else if (mpz_cmp(v[33], c[0]) >= 0) {
			/* F => g */
			mpz_sub(v[33], v[33], c[0]);
			mpz_add(v[6], v[6], c[0]);
		} else if (mpz_cmp(v[1], c[0]) >= 0 && mpz_cmp(v[18], c[0]) >= 0) {
			/* aq => A */
			mpz_sub(v[1], v[1], c[0]);
			mpz_sub(v[18], v[18], c[0]);
			mpz_add(v[14], v[14], c[0]);
		} else if (mpz_cmp(v[18], c[0]) >= 0) {
			/* q => A */
			mpz_sub(v[18], v[18], c[0]);
			mpz_add(v[14], v[14], c[0]);
		} else if (mpz_cmp(v[14], c[0]) >= 0) {
			/* A => m */
			mpz_sub(v[14], v[14], c[0]);
			mpz_add(v[12], v[12], c[0]);
		} else if (mpz_cmp(v[37], c[0]) >= 0) {
			/* J */
			mpz_sub(v[37], v[37], c[0]);
		} else {
			break;
		}
	}

	z = 1;
	for (i = 0; i < VARS; i++) {
		if (mpz_cmp_ui(v[i], 0) > 0) {
			if (!z) {
				printf(" ");
			}
			z = 0;
			printf("%s", n[i]);
			if (mpz_cmp_ui(v[i], 1) > 0) {
				printf("^");
				mpz_out_str(stdout, 10, v[i]);
			}
		}
	}
	if (z) {
		printf("1");
	}
	printf("\n");

	return 0;
}
Example #16
0
void add_bi(mpz_t res, mpz_t a, mpz_t b) {
    mpz_add(res,a,b);
}
main (int argc, char *argv[]) {
  mpz_t n, c, x1, x2, product, t, g, t1, t2;
  unsigned long max, range, terms, j, ans;

  mpz_init (n);
  mpz_init (c);
  mpz_init (x1);
  mpz_init (x2);
  mpz_init (product);
  mpz_init (t);
  mpz_init (g);
  mpz_init (t1);
  mpz_init (t2);

initialize:
  mpz_set_str (n, argv[1], 10);
  gmp_printf("n = %Zd\n", n);
  mpz_set_str (c, argv[2], 10);
  max = atoi(argv[3]);

restart:
  mpz_set_ui (x1, 2);
  mpz_add_ui (x2, c, 4);
  range = 1;
  mpz_set_ui (product, 1);
  terms = 0;

compute_diff:
  while ( terms <= max ) {
    for (j=1; j<=range; j++) {
      mpz_mul (t, x2, x2);
      mpz_add (t, t, c);
      mpz_fdiv_r ( x2, t, n );
      mpz_sub (t, x1, x2);
      mpz_mul (t, product, t);
      mpz_fdiv_r (product, t, n);
      terms++;
      if ((terms%10) == 0) {
        mpz_set (t1, n);
        mpz_set (t2, product);
        gcd (g, t1, t2);
        if (mpz_cmp_ui (g, 1) > 0) {
          gmp_printf("g = %Zd\n",g);
          goto terminate;
        }
        mpz_set_ui (product, 1);
      }
    }

reset:
    mpz_set (x1, x2);
    range = 2*range;
    for (j=1; j<=range; j++) {
      mpz_mul (t, x2, x2);
      mpz_add (t, t, c);
      mpz_fdiv_r (x2, t, n);
    }
  }

  gmp_printf("n = %Zd --- no factor found for c = %Zd!!!\n", n, c);
  printf("Enter 1 to input new c, 0 to stop\n");
  scanf("%d",&ans);
  if (ans != 1) goto terminate;
  printf("Enter new c value:");
  gmp_scanf("%Zd",&c);
  goto restart;

terminate:
  mpz_clear (g);
  mpz_clear (t);
  mpz_clear (product);
  mpz_clear (x2);
  mpz_clear (x1);
  mpz_clear (c);
  mpz_clear (n);
  mpz_clear (t1);
  mpz_clear (t2);
  exit (0);

}
Example #18
0
int main(int argc, const char *argv[])
{
	int res;
	char *str;
	mpz_t largenum;

	if (argc <= 0) {
		fprintf(stderr, "usage: %s\n", argv[0]);
		exit(EXIT_SUCCESS);
	}

	fprintf(stderr, "setting pitch\n");
	orient_range.orient.pitch   = 180;
	orient_range.pitch_range    = 10;

	fprintf(stderr, "setting roll\n");
	orient_range.orient.roll    = 0;
	orient_range.roll_range     = 10;

	fprintf(stderr, "setting azimuth\n");
	orient_range.orient.azimuth = 0;
	orient_range.azimuth_range  = 0;

	mpz_init_set_str(one, "1", 10);
	mpz_init_set_str(two, "2", 10);

	gmp_randinit_default(randstate);

	sleep(1);

	if (syscall(__NR_orientlock_read, &orient_range) == -1) {
		fprintf(stderr, "error: Unable to obtain lock\n");
		exit(EXIT_FAILURE);
	}

	fp = fopen("./integer", "r");

	if ((fgets(integer, INTEGER_BUF_SIZE, fp)) == NULL) {
			fprintf(stderr, "error: Unable to read from file");
			exit(EXIT_FAILURE);
	}
	chomp_line(integer);

	mpz_init(largenum);
	mpz_init_set_str(largenum, integer, 10);

	str = mpz_to_str(largenum);
	if (!str)
		return EXIT_FAILURE;

	/*
	 * We simply return the prime number itself if the base is prime.
	 * (We use the GMP probabilistic function with 10 repetitions).
	 */
	res = mpz_probab_prime_p(largenum, 10);
	if (res) {
		printf("%s is a prime number\n", str);
		free(str);
		mpz_add(largenum, largenum, one);
	}

	printf("Prime factors for %s are:  ", str);
	free(str);

	factor(largenum);
	printf("\n");

	fclose(fp);

	if (syscall(__NR_orientunlock_read, &orient_range) == -1) {
		fprintf(stderr, "error: Unable to unlock\n");
		exit(EXIT_FAILURE);
	}

	return EXIT_SUCCESS;
}
Example #19
0
//入力の行列の逆行列を返す
//対角成分が0の場合考える
matrix *tfel_invert(const matrix *D, const EC_PAIRING p) {
    int i, j, k, l;
	mpz_t order;
	mpz_init(order);
	mpz_set(order, *pairing_get_order(p));

	matrix *temp1, *inv;

	//逆行列求める行列のコピー
	temp1 = tfel_matrix_copy(D);
	//ここに逆行列が入る
	inv = tfel_matrix_init(D->dim);
	for(i = 0; i < D->dim; i++) {
		mpz_set_str(inv->M[i][i], "1", 10);
	}

	//一時的なデータを蓄える
	mpz_t buf1, buf2, buf3, buf4, *temp_v1, *temp_v2;
	mpz_init(buf1);
	mpz_init(buf2);
	mpz_init(buf3);
	mpz_init(buf4);
	temp_v1 = (mpz_t*)malloc(sizeof(mpz_t)*temp1->dim);
	temp_v2 = (mpz_t*)malloc(sizeof(mpz_t)*temp1->dim);

	for(i = 0; i < temp1->dim; i++) {
		mpz_init(temp_v1[i]);
		mpz_init(temp_v2[i]);
	}

	//すごく汚い掃き出し法
	for(i=0; i < temp1->dim; i++) {
		mpz_invert(buf1, temp1->M[i][i], order); //j行j列の乗法の逆元求める(1)

		for(j=0; j < temp1->dim; j++) {
			mpz_mul(buf2, buf1, temp1->M[i][j]);
			mpz_set(temp1->M[i][j], buf2); //(1)をi行全体にかける(2)
			//mpz_set(temp_v1[j], buf2); //(2)のコピー
			mpz_mod(temp_v1[j], buf2, order);

			mpz_mul(buf2, buf1, inv->M[i][j]);
			mpz_set(inv->M[i][j], buf2); //単位行列の方にも同様の操作
			//mpz_set(temp_v2[j], buf2);
			mpz_mod(temp_v2[j], buf2, order);
		} //ここまでokだと思う……

		for(k=0; k < temp1->dim; k++) {
			if(i == k) continue;
			//element_neg(buf1, temp1->M[k][i]); //i行以外の行のj列の加法の逆元求める(3)
			mpz_neg(buf1, temp1->M[k][i]);
			for(l=0; l < temp1->dim; l++) {
				mpz_mul(buf3, buf1, temp_v1[l]); //(3)×(2)
				mpz_add(buf4, buf3, temp1->M[k][l]); //(4)
				mpz_set(temp1->M[k][l], buf4);

				mpz_mul(buf3, buf1, temp_v2[l]);
				mpz_add(buf4, buf3, inv->M[k][l]);
				mpz_mod(inv->M[k][l], buf4, order); //単位行列の方にも同様の操作
			}
		}
	}

	//invert check→ok!!
			mpz_t temp_1, temp_2, result;
			mpz_init(temp_1);
			mpz_init(temp_2);

			for(k = 0; k < D->dim; k++) {
				for(i = 0; i < D->dim; i++) {
					mpz_init_set_ui(result, 0);
					for(j = 0; j < D->dim; j++) {
						mpz_mul(temp_1, D->M[k][j], inv->M[j][i]);
						mpz_add(temp_2, temp_1, result);
						mpz_mod(result, temp_2, order);
					}
					if(k == i) {
						if(mpz_get_ui(result) != 1) {
							printf("error\n");
							goto clear;
						}
					}
					else {
						if(mpz_get_ui(result) != 0) {
							printf("error\n");
							goto clear;
						}
					}
				}
			}
clear:
			mpz_clear(temp_1);
			mpz_clear(temp_2);
			mpz_clear(result);
			//invert check

	mpz_clear(order);
	mpz_clear(buf1);
	mpz_clear(buf2);
	mpz_clear(buf3);
	mpz_clear(buf4);
	for(i=0; i < temp1->dim; i++) {
		mpz_clear(temp_v1[i]);
		mpz_clear(temp_v2[i]);
	}
	free(temp_v1);
	free(temp_v2);
	tfel_matrix_clear(temp1);
	return inv;
}
Example #20
0
void LLLoperations::SWAPI(int k, int kmax,
                          MutableMatrix *A,
                          MutableMatrix *Achange, // can be NULL
                          MutableMatrix *lambda)
{
  int i;
  mpz_t a,b,B,C1,C2,D,D1,lam;
  ring_elem rD1,rD,rlam;

  A->interchange_columns(k,k-1);
  if (Achange) Achange->interchange_columns(k,k-1);

  mpz_init(a);
  mpz_init(b);
  mpz_init(B);
  mpz_init(C1);
  mpz_init(C2);

  lambda->get_entry(k-1,k-1,rD1);
  lambda->get_entry(k,k,rD);
  mpz_init_set(D1,rD1.get_mpz());
  mpz_init_set(D,rD.get_mpz());

  if (lambda->get_entry(k-1,k,rlam))
    mpz_init_set(lam,rlam.get_mpz());
  else
    mpz_init(lam);

  // Interchange both of these columns, except for these three terms:
  if (k >= 2)
    {
      lambda->interchange_columns(k,k-1);
      lambda->set_entry(k-1,k,globalZZ->from_int(lam));
      lambda->set_entry(k,k,globalZZ->from_int(D));
      lambda->set_entry(k,k-1,globalZZ->from_int(0));
      // (k-1,k-1) is set below.
    }

  // B := (D#(k-2) * D#k + lam^2) // D#(k-1);
  if (k == 1)
    mpz_set(a,D);
  else
    {
      ring_elem rD2;
      lambda->get_entry(k-2,k-2,rD2);
      mpz_mul(a,rD2.get_mpz(),D);
    }
  mpz_mul(b,lam,lam);
  mpz_add(a,a,b);
  mpz_fdiv_q(B,a,D1);
  lambda->set_entry(k-1,k-1,globalZZ->from_int(B));

  // scan(k+1..C.kmax, i-> (
  //     t := lambda#(i,k);
  //     lambda#(i,k) = (D#k * lambda#(i,k-1) - lam * t) // D#(k-1);
  //     lambda#(i,k-1) = (B*t + lam*lambda#(i,k))//(D#k);));
  for (i=k+1; i<=kmax; i++)
    {
      ring_elem s,t;
      bool s_notzero = lambda->get_entry(k-1,i,s);
      bool t_notzero = lambda->get_entry(k,i,t);
      if (s_notzero)
        mpz_mul(a,D, s.get_mpz());
      else
        mpz_set_ui(a,0);
      // lambda#(i,k) = (D#k * lambda#(i,k-1) - lam * t) // D#(k-1);
      if (t_notzero)
        mpz_mul(b,lam,t.get_mpz());
      else
        mpz_set_ui(b,0);
      mpz_sub(a,a,b);
      mpz_fdiv_q(C1,a,D1);

      // lambda#(i,k-1) = (B*t + lam*lambda#(i,k))//(D#k);));
      mpz_mul(b,lam,C1);
      if (t_notzero)
        mpz_mul(a,B,t.get_mpz());
      else
        mpz_set_ui(a,0);

      mpz_add(a,a,b);
      mpz_fdiv_q(C2,a,D);

      lambda->set_entry(k,i,globalZZ->from_int(C1));  // These two lines will remove t,s.
      lambda->set_entry(k-1,i,globalZZ->from_int(C2));
    }
  mpz_clear(a);
  mpz_clear(b);
  mpz_clear(B);
  mpz_clear(C1);
  mpz_clear(C2);
  mpz_clear(D1);
  mpz_clear(D);
  mpz_clear(lam);
}
Example #21
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 ();
    }
}
Example #22
0
File: data.c Project: LihuaWu/gcc
bool
gfc_assign_data_value (gfc_expr *lvalue, gfc_expr *rvalue, mpz_t index,
		       mpz_t *repeat)
{
  gfc_ref *ref;
  gfc_expr *init;
  gfc_expr *expr = NULL;
  gfc_constructor *con;
  gfc_constructor *last_con;
  gfc_symbol *symbol;
  gfc_typespec *last_ts;
  mpz_t offset;

  symbol = lvalue->symtree->n.sym;
  init = symbol->value;
  last_ts = &symbol->ts;
  last_con = NULL;
  mpz_init_set_si (offset, 0);

  /* Find/create the parent expressions for subobject references.  */
  for (ref = lvalue->ref; ref; ref = ref->next)
    {
      /* Break out of the loop if we find a substring.  */
      if (ref->type == REF_SUBSTRING)
	{
	  /* A substring should always be the last subobject reference.  */
	  gcc_assert (ref->next == NULL);
	  break;
	}

      /* Use the existing initializer expression if it exists.  Otherwise
	 create a new one.  */
      if (init == NULL)
	expr = gfc_get_expr ();
      else
	expr = init;

      /* Find or create this element.  */
      switch (ref->type)
	{
	case REF_ARRAY:
	  if (ref->u.ar.as->rank == 0)
	    {
	      gcc_assert (ref->u.ar.as->corank > 0);
	      if (init == NULL)
		free (expr);
	      continue;
	    }

	  if (init && expr->expr_type != EXPR_ARRAY)
	    {
	      gfc_error_1 ("'%s' at %L already is initialized at %L",
			   lvalue->symtree->n.sym->name, &lvalue->where,
			   &init->where);
	      goto abort;
	    }

	  if (init == NULL)
	    {
	      /* The element typespec will be the same as the array
		 typespec.  */
	      expr->ts = *last_ts;
	      /* Setup the expression to hold the constructor.  */
	      expr->expr_type = EXPR_ARRAY;
	      expr->rank = ref->u.ar.as->rank;
	    }

	  if (ref->u.ar.type == AR_ELEMENT)
	    get_array_index (&ref->u.ar, &offset);
	  else
	    mpz_set (offset, index);

	  /* Check the bounds.  */
	  if (mpz_cmp_si (offset, 0) < 0)
	    {
	      gfc_error ("Data element below array lower bound at %L",
			 &lvalue->where);
	      goto abort;
	    }
	  else if (repeat != NULL
		   && ref->u.ar.type != AR_ELEMENT)
	    {
	      mpz_t size, end;
	      gcc_assert (ref->u.ar.type == AR_FULL
			  && ref->next == NULL);
	      mpz_init_set (end, offset);
	      mpz_add (end, end, *repeat);
	      if (spec_size (ref->u.ar.as, &size))
		{
		  if (mpz_cmp (end, size) > 0)
		    {
		      mpz_clear (size);
		      gfc_error ("Data element above array upper bound at %L",
				 &lvalue->where);
		      goto abort;
		    }
		  mpz_clear (size);
		}

	      con = gfc_constructor_lookup (expr->value.constructor,
					    mpz_get_si (offset));
	      if (!con)
		{
		  con = gfc_constructor_lookup_next (expr->value.constructor,
						     mpz_get_si (offset));
		  if (con != NULL && mpz_cmp (con->offset, end) >= 0)
		    con = NULL;
		}

	      /* Overwriting an existing initializer is non-standard but
		 usually only provokes a warning from other compilers.  */
	      if (con != NULL && con->expr != NULL)
		{
		  /* Order in which the expressions arrive here depends on
		     whether they are from data statements or F95 style
		     declarations.  Therefore, check which is the most
		     recent.  */
		  gfc_expr *exprd;
		  exprd = (LOCATION_LINE (con->expr->where.lb->location)
			   > LOCATION_LINE (rvalue->where.lb->location))
			  ? con->expr : rvalue;
		  if (gfc_notify_std (GFC_STD_GNU,
				      "re-initialization of %qs at %L",
				      symbol->name, &exprd->where) == false)
		    return false;
		}

	      while (con != NULL)
		{
		  gfc_constructor *next_con = gfc_constructor_next (con);

		  if (mpz_cmp (con->offset, end) >= 0)
		    break;
		  if (mpz_cmp (con->offset, offset) < 0)
		    {
		      gcc_assert (mpz_cmp_si (con->repeat, 1) > 0);
		      mpz_sub (con->repeat, offset, con->offset);
		    }
		  else if (mpz_cmp_si (con->repeat, 1) > 0
			   && mpz_get_si (con->offset)
			      + mpz_get_si (con->repeat) > mpz_get_si (end))
		    {
		      int endi;
		      splay_tree_node node
			= splay_tree_lookup (con->base,
					     mpz_get_si (con->offset));
		      gcc_assert (node
				  && con == (gfc_constructor *) node->value
				  && node->key == (splay_tree_key)
						  mpz_get_si (con->offset));
		      endi = mpz_get_si (con->offset)
			     + mpz_get_si (con->repeat);
		      if (endi > mpz_get_si (end) + 1)
			mpz_set_si (con->repeat, endi - mpz_get_si (end));
		      else
			mpz_set_si (con->repeat, 1);
		      mpz_set (con->offset, end);
		      node->key = (splay_tree_key) mpz_get_si (end);
		      break;
		    }
		  else
		    gfc_constructor_remove (con);
		  con = next_con;
		}

	      con = gfc_constructor_insert_expr (&expr->value.constructor,
						 NULL, &rvalue->where,
						 mpz_get_si (offset));
	      mpz_set (con->repeat, *repeat);
	      repeat = NULL;
	      mpz_clear (end);
	      break;
	    }
	  else
	    {
	      mpz_t size;
	      if (spec_size (ref->u.ar.as, &size))
		{
		  if (mpz_cmp (offset, size) >= 0)
		    {
		      mpz_clear (size);
		      gfc_error ("Data element above array upper bound at %L",
		                 &lvalue->where);
		      goto abort;
		    }
		  mpz_clear (size);
		}
	    }

	  con = gfc_constructor_lookup (expr->value.constructor,
					mpz_get_si (offset));
	  if (!con)
	    {
	      con = gfc_constructor_insert_expr (&expr->value.constructor,
						 NULL, &rvalue->where,
						 mpz_get_si (offset));
	    }
	  else if (mpz_cmp_si (con->repeat, 1) > 0)
	    {
	      /* Need to split a range.  */
	      if (mpz_cmp (con->offset, offset) < 0)
		{
		  gfc_constructor *pred_con = con;
		  con = gfc_constructor_insert_expr (&expr->value.constructor,
						     NULL, &con->where,
						     mpz_get_si (offset));
		  con->expr = gfc_copy_expr (pred_con->expr);
		  mpz_add (con->repeat, pred_con->offset, pred_con->repeat);
		  mpz_sub (con->repeat, con->repeat, offset);
		  mpz_sub (pred_con->repeat, offset, pred_con->offset);
		}
	      if (mpz_cmp_si (con->repeat, 1) > 0)
		{
		  gfc_constructor *succ_con;
		  succ_con
		    = gfc_constructor_insert_expr (&expr->value.constructor,
						   NULL, &con->where,
						   mpz_get_si (offset) + 1);
		  succ_con->expr = gfc_copy_expr (con->expr);
		  mpz_sub_ui (succ_con->repeat, con->repeat, 1);
		  mpz_set_si (con->repeat, 1);
		}
	    }
	  break;

	case REF_COMPONENT:
	  if (init == NULL)
	    {
	      /* Setup the expression to hold the constructor.  */
	      expr->expr_type = EXPR_STRUCTURE;
	      expr->ts.type = BT_DERIVED;
	      expr->ts.u.derived = ref->u.c.sym;
	    }
	  else
	    gcc_assert (expr->expr_type == EXPR_STRUCTURE);
	  last_ts = &ref->u.c.component->ts;

	  /* Find the same element in the existing constructor.  */
	  con = find_con_by_component (ref->u.c.component,
				       expr->value.constructor);

	  if (con == NULL)
	    {
	      /* Create a new constructor.  */
	      con = gfc_constructor_append_expr (&expr->value.constructor,
						 NULL, NULL);
	      con->n.component = ref->u.c.component;
	    }
	  break;

	default:
	  gcc_unreachable ();
	}

      if (init == NULL)
	{
	  /* Point the container at the new expression.  */
	  if (last_con == NULL)
	    symbol->value = expr;
	  else
	    last_con->expr = expr;
	}
      init = con->expr;
      last_con = con;
    }

  mpz_clear (offset);
  gcc_assert (repeat == NULL);

  if (ref || last_ts->type == BT_CHARACTER)
    {
      if (lvalue->ts.u.cl->length == NULL && !(ref && ref->u.ss.length != NULL))
	return false;
      expr = create_character_initializer (init, last_ts, ref, rvalue);
    }
  else
    {
      /* Overwriting an existing initializer is non-standard but usually only
	 provokes a warning from other compilers.  */
      if (init != NULL)
	{
	  /* Order in which the expressions arrive here depends on whether
	     they are from data statements or F95 style declarations.
	     Therefore, check which is the most recent.  */
	  expr = (LOCATION_LINE (init->where.lb->location)
		  > LOCATION_LINE (rvalue->where.lb->location))
	       ? init : rvalue;
	  if (gfc_notify_std (GFC_STD_GNU,
			      "re-initialization of %qs at %L",
			      symbol->name, &expr->where) == false)
	    return false;
	}

      expr = gfc_copy_expr (rvalue);
      if (!gfc_compare_types (&lvalue->ts, &expr->ts))
	gfc_convert_type (expr, &lvalue->ts, 0);
    }

  if (last_con == NULL)
    symbol->value = expr;
  else
    last_con->expr = expr;

  return true;

abort:
  if (!init)
    gfc_free_expr (expr);
  mpz_clear (offset);
  return false;
}
Example #23
0
/* f <- 1 - r/2! + r^2/4! + ... + (-1)^l r^l/(2l)! + ...
   Assumes |r| < 1/2, and f, r have the same precision.
   Returns e such that the error on f is bounded by 2^e ulps.
*/
static int
mpfr_cos2_aux (mpfr_ptr f, mpfr_srcptr r)
{
  mpz_t x, t, s;
  mpfr_exp_t ex, l, m;
  mpfr_prec_t p, q;
  unsigned long i, maxi, imax;

  MPFR_ASSERTD(mpfr_get_exp (r) <= -1);

  /* compute minimal i such that i*(i+1) does not fit in an unsigned long,
     assuming that there are no padding bits. */
  maxi = 1UL << (CHAR_BIT * sizeof(unsigned long) / 2);
  if (maxi * (maxi / 2) == 0) /* test checked at compile time */
    {
      /* can occur only when there are padding bits. */
      /* maxi * (maxi-1) is representable iff maxi * (maxi / 2) != 0 */
      do
        maxi /= 2;
      while (maxi * (maxi / 2) == 0);
    }

  mpz_init (x);
  mpz_init (s);
  mpz_init (t);
  ex = mpfr_get_z_2exp (x, r); /* r = x*2^ex */

  /* remove trailing zeroes */
  l = mpz_scan1 (x, 0);
  ex += l;
  mpz_fdiv_q_2exp (x, x, l);

  /* since |r| < 1, r = x*2^ex, and x is an integer, necessarily ex < 0 */

  p = mpfr_get_prec (f); /* same than r */
  /* bound for number of iterations */
  imax = p / (-mpfr_get_exp (r));
  imax += (imax == 0);
  q = 2 * MPFR_INT_CEIL_LOG2(imax) + 4; /* bound for (3l)^2 */

  mpz_set_ui (s, 1); /* initialize sum with 1 */
  mpz_mul_2exp (s, s, p + q); /* scale all values by 2^(p+q) */
  mpz_set (t, s); /* invariant: t is previous term */
  for (i = 1; (m = mpz_sizeinbase (t, 2)) >= q; i += 2)
    {
      /* adjust precision of x to that of t */
      l = mpz_sizeinbase (x, 2);
      if (l > m)
        {
          l -= m;
          mpz_fdiv_q_2exp (x, x, l);
          ex += l;
        }
      /* multiply t by r */
      mpz_mul (t, t, x);
      mpz_fdiv_q_2exp (t, t, -ex);
      /* divide t by i*(i+1) */
      if (i < maxi)
        mpz_fdiv_q_ui (t, t, i * (i + 1));
      else
        {
          mpz_fdiv_q_ui (t, t, i);
          mpz_fdiv_q_ui (t, t, i + 1);
        }
      /* if m is the (current) number of bits of t, we can consider that
         all operations on t so far had precision >= m, so we can prove
         by induction that the relative error on t is of the form
         (1+u)^(3l)-1, where |u| <= 2^(-m), and l=(i+1)/2 is the # of loops.
         Since |(1+x^2)^(1/x) - 1| <= 4x/3 for |x| <= 1/2,
         for |u| <= 1/(3l)^2, the absolute error is bounded by
         4/3*(3l)*2^(-m)*t <= 4*l since |t| < 2^m.
         Therefore the error on s is bounded by 2*l*(l+1). */
      /* add or subtract to s */
      if (i % 4 == 1)
        mpz_sub (s, s, t);
      else
        mpz_add (s, s, t);
    }

  mpfr_set_z (f, s, MPFR_RNDN);
  mpfr_div_2ui (f, f, p + q, MPFR_RNDN);

  mpz_clear (x);
  mpz_clear (s);
  mpz_clear (t);

  l = (i - 1) / 2; /* number of iterations */
  return 2 * MPFR_INT_CEIL_LOG2 (l + 1) + 1; /* bound is 2l(l+1) */
}
Example #24
0
File: data.c Project: LihuaWu/gcc
void 
gfc_advance_section (mpz_t *section_index, gfc_array_ref *ar,
		     mpz_t *offset_ret)
{
  int i;
  mpz_t delta;
  mpz_t tmp; 
  bool forwards;
  int cmp;

  for (i = 0; i < ar->dimen; i++)
    {
      if (ar->dimen_type[i] != DIMEN_RANGE)
	continue;

      if (ar->stride[i])
	{
	  mpz_add (section_index[i], section_index[i],
		   ar->stride[i]->value.integer);
	if (mpz_cmp_si (ar->stride[i]->value.integer, 0) >= 0)
	  forwards = true;
	else
	  forwards = false;
	}
      else
	{
	  mpz_add_ui (section_index[i], section_index[i], 1);
	  forwards = true;
	}
      
      if (ar->end[i])
	cmp = mpz_cmp (section_index[i], ar->end[i]->value.integer);
      else
	cmp = mpz_cmp (section_index[i], ar->as->upper[i]->value.integer);

      if ((cmp > 0 && forwards) || (cmp < 0 && !forwards))
	{
	  /* Reset index to start, then loop to advance the next index.  */
	  if (ar->start[i])
	    mpz_set (section_index[i], ar->start[i]->value.integer);
	  else
	    mpz_set (section_index[i], ar->as->lower[i]->value.integer);
	}
      else
	break;
    }

  mpz_set_si (*offset_ret, 0);
  mpz_init_set_si (delta, 1);
  mpz_init (tmp);
  for (i = 0; i < ar->dimen; i++)
    {
      mpz_sub (tmp, section_index[i], ar->as->lower[i]->value.integer);
      mpz_mul (tmp, tmp, delta);
      mpz_add (*offset_ret, tmp, *offset_ret);

      mpz_sub (tmp, ar->as->upper[i]->value.integer, 
	       ar->as->lower[i]->value.integer);
      mpz_add_ui (tmp, tmp, 1);
      mpz_mul (delta, tmp, delta);
    }
  mpz_clear (tmp);
  mpz_clear (delta);
}
Example #25
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_ptr rands;
  mpz_t bs;
  unsigned long size_range;

  tests_start ();
  rands = RANDS;

  mpz_init (bs);

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

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

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

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

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

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

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

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

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

      mpz_add (temp2, temp, rem);

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

  mpz_clear (bs);
  mpz_clear (x2);
  mpz_clear (x);
  mpz_clear (rem);
  mpz_clear (temp);
  mpz_clear (temp2);

  tests_end ();
  exit (0);
}
Example #26
0
File: yn.c Project: Kirija/XPIR
/* compute in s an approximation of
   S3 = c*sum((h(k)+h(n+k))*y^k/k!/(n+k)!,k=0..infinity)
   where h(k) = 1 + 1/2 + ... + 1/k
   k=0: h(n)
   k=1: 1+h(n+1)
   k=2: 3/2+h(n+2)
   Returns e such that the error is bounded by 2^e ulp(s).
*/
static mpfr_exp_t
mpfr_yn_s3 (mpfr_ptr s, mpfr_srcptr y, mpfr_srcptr c, unsigned long n)
{
  unsigned long k, zz;
  mpfr_t t, u;
  mpz_t p, q; /* p/q will store h(k)+h(n+k) */
  mpfr_exp_t exps, expU;

  zz = mpfr_get_ui (y, MPFR_RNDU); /* y = z^2/4 */
  MPFR_ASSERTN (zz < ULONG_MAX - 2);
  zz += 2; /* z^2 <= 2^zz */
  mpz_init_set_ui (p, 0);
  mpz_init_set_ui (q, 1);
  /* initialize p/q to h(n) */
  for (k = 1; k <= n; k++)
    {
      /* p/q + 1/k = (k*p+q)/(q*k) */
      mpz_mul_ui (p, p, k);
      mpz_add (p, p, q);
      mpz_mul_ui (q, q, k);
    }
  mpfr_init2 (t, MPFR_PREC(s));
  mpfr_init2 (u, MPFR_PREC(s));
  mpfr_fac_ui (t, n, MPFR_RNDN);
  mpfr_div (t, c, t, MPFR_RNDN);    /* c/n! */
  mpfr_mul_z (u, t, p, MPFR_RNDN);
  mpfr_div_z (s, u, q, MPFR_RNDN);
  exps = MPFR_EXP (s);
  expU = exps;
  for (k = 1; ;k ++)
    {
      /* update t */
      mpfr_mul (t, t, y, MPFR_RNDN);
      mpfr_div_ui (t, t, k, MPFR_RNDN);
      mpfr_div_ui (t, t, n + k, MPFR_RNDN);
      /* update p/q:
         p/q + 1/k + 1/(n+k) = [p*k*(n+k) + q*(n+k) + q*k]/(q*k*(n+k)) */
      mpz_mul_ui (p, p, k);
      mpz_mul_ui (p, p, n + k);
      mpz_addmul_ui (p, q, n + 2 * k);
      mpz_mul_ui (q, q, k);
      mpz_mul_ui (q, q, n + k);
      mpfr_mul_z (u, t, p, MPFR_RNDN);
      mpfr_div_z (u, u, q, MPFR_RNDN);
      exps = MPFR_EXP (u);
      if (exps > expU)
        expU = exps;
      mpfr_add (s, s, u, MPFR_RNDN);
      exps = MPFR_EXP (s);
      if (exps > expU)
        expU = exps;
      if (MPFR_EXP (u) + (mpfr_exp_t) MPFR_PREC (u) < MPFR_EXP (s) &&
          zz / (2 * k) < k + n)
        break;
    }
  mpfr_clear (t);
  mpfr_clear (u);
  mpz_clear (p);
  mpz_clear (q);
  exps = expU - MPFR_EXP (s);
  /* the error is bounded by (6k^2+33/2k+11) 2^exps ulps
     <= 8*(k+2)^2 2^exps ulps */
  return 3 + 2 * MPFR_INT_CEIL_LOG2(k + 2) + exps;
}
Example #27
0
void
generate_mod (int limb_bits, int nail_bits)
{
  int    numb_bits = limb_bits - nail_bits;
  int    i, divisor;

  mpz_init_set_ui (pp, 0L);
  mpz_init_set_ui (pp_norm, 0L);
  mpz_init_set_ui (pp_inverted, 0L);

  /* no more than limb_bits many factors in a one limb modulus (and of
     course in reality nothing like that many) */
  factor_alloc = limb_bits;
  factor = (struct factor_t *) malloc (factor_alloc * sizeof (*factor));
  rawfactor = (struct rawfactor_t *)
    malloc (factor_alloc * sizeof (*rawfactor));

  if (numb_bits % 4 != 0)
    {
      strcpy (mod34_excuse, "GMP_NUMB_BITS % 4 != 0");
      goto use_pp;
    }

  max_divisor = 2*limb_bits;
  max_divisor_bits = log2_ceil (max_divisor);

  if (numb_bits / 4 < max_divisor_bits)
    {
      /* Wind back to one limb worth of max_divisor, if that will let us use
         mpn_mod_34lsub1.  */
      max_divisor = limb_bits;
      max_divisor_bits = log2_ceil (max_divisor);

      if (numb_bits / 4 < max_divisor_bits)
        {
          strcpy (mod34_excuse, "GMP_NUMB_BITS / 4 too small");
          goto use_pp;
        }
    }

  {
    /* Can use mpn_mod_34lsub1, find small factors of 2^mod34_bits-1. */
    mpz_t  m, q, r;
    int    multiplicity;

    mod34_bits = (numb_bits / 4) * 3;

    /* mpn_mod_34lsub1 returns a full limb value, PERFSQR_MOD_34 folds it at
       the mod34_bits mark, adding the two halves for a remainder of at most
       mod34_bits+1 many bits */
    mod_bits = mod34_bits + 1;

    mpz_init_set_ui (m, 1L);
    mpz_mul_2exp (m, m, mod34_bits);
    mpz_sub_ui (m, m, 1L);

    mpz_init (q);
    mpz_init (r);

    for (i = 3; i <= max_divisor; i++)
      {
        if (! isprime (i))
          continue;

        mpz_tdiv_qr_ui (q, r, m, (unsigned long) i);
        if (mpz_sgn (r) != 0)
          continue;

        /* if a repeated prime is found it's used as an i^n in one factor */
        divisor = 1;
        multiplicity = 0;
        do
          {
            if (divisor > max_divisor / i)
              break;
            multiplicity++;
            mpz_set (m, q);
            mpz_tdiv_qr_ui (q, r, m, (unsigned long) i);
          }
        while (mpz_sgn (r) == 0);

        //ASSERT (nrawfactor < factor_alloc);
        rawfactor[nrawfactor].divisor = i;
        rawfactor[nrawfactor].multiplicity = multiplicity;
        nrawfactor++;
      }

    mpz_clear (m);
    mpz_clear (q);
    mpz_clear (r);
  }

  if (nrawfactor <= 2)
    {
      mpz_t  new_pp;

      sprintf (mod34_excuse, "only %d small factor%s",
               nrawfactor, nrawfactor == 1 ? "" : "s");

    use_pp:
      /* reset to two limbs of max_divisor, in case the mpn_mod_34lsub1 code
         tried with just one */
      max_divisor = 2*limb_bits;
      max_divisor_bits = log2_ceil (max_divisor);

      mpz_init (new_pp);
      nrawfactor = 0;
      mod_bits = MIN (numb_bits, limb_bits - max_divisor_bits);

      /* one copy of each small prime */
      mpz_set_ui (pp, 1L);
      for (i = 3; i <= max_divisor; i++)
        {
          if (! isprime (i))
            continue;

          mpz_mul_ui (new_pp, pp, (unsigned long) i);
          if (mpz_sizeinbase (new_pp, 2) > mod_bits)
            break;
          mpz_set (pp, new_pp);

          //ASSERT (nrawfactor < factor_alloc);
          rawfactor[nrawfactor].divisor = i;
          rawfactor[nrawfactor].multiplicity = 1;
          nrawfactor++;
        }

      /* Plus an extra copy of one or more of the primes selected, if that
         still fits in max_divisor and the total in mod_bits.  Usually only
         3 or 5 will be candidates */
      for (i = nrawfactor-1; i >= 0; i--)
        {
          if (rawfactor[i].divisor > max_divisor / rawfactor[i].divisor)
            continue;
          mpz_mul_ui (new_pp, pp, (unsigned long) rawfactor[i].divisor);
          if (mpz_sizeinbase (new_pp, 2) > mod_bits)
            continue;
          mpz_set (pp, new_pp);

          rawfactor[i].multiplicity++;
        }

      mod_bits = mpz_sizeinbase (pp, 2);

      mpz_set (pp_norm, pp);
      while (mpz_sizeinbase (pp_norm, 2) < numb_bits)
        mpz_add (pp_norm, pp_norm, pp_norm);

      mpz_preinv_invert (pp_inverted, pp_norm, numb_bits);

      mpz_clear (new_pp);
    }

  /* start the factor array */
  for (i = 0; i < nrawfactor; i++)
    {
      int  j;
      //ASSERT (nfactor < factor_alloc);
      factor[nfactor].divisor = 1;
      for (j = 0; j < rawfactor[i].multiplicity; j++)
        factor[nfactor].divisor *= rawfactor[i].divisor;
      nfactor++;
    }

 combine:
  /* Combine entries in the factor array.  Combine the smallest entry with
     the biggest one that will fit with it (ie. under max_divisor), then
     repeat that with the new smallest entry. */
  qsort (factor, nfactor, sizeof (factor[0]), f_cmp_divisor);
  for (i = nfactor-1; i >= 1; i--)
    {
      if (factor[i].divisor <= max_divisor / factor[0].divisor)
        {
          factor[0].divisor *= factor[i].divisor;
          COLLAPSE_ELEMENT (factor, i, nfactor);
          goto combine;
        }
    }

  total_fraction = 1.0;
  for (i = 0; i < nfactor; i++)
    {
      mpz_init (factor[i].inverse);
      mpz_invert_ui_2exp (factor[i].inverse,
                          (unsigned long) factor[i].divisor,
                          (unsigned long) mod_bits);

      mpz_init (factor[i].mask);
      square_mask (factor[i].mask, factor[i].divisor);

      /* fraction of possible squares */
      factor[i].fraction = (double) mpz_popcount (factor[i].mask)
        / factor[i].divisor;

      /* total fraction of possible squares */
      total_fraction *= factor[i].fraction;
    }

  /* best tests first (ie. smallest fraction) */
  qsort (factor, nfactor, sizeof (factor[0]), f_cmp_fraction);
}
Example #28
0
//rop <- (rop² + a) mod n
void f(mpz_t rop)
{
	mpz_pow_ui(xSquared, rop, 2);
	mpz_add(xSquared, xSquared, a);
	mpz_mod(rop, xSquared, n);
}
Example #29
0
int
main (int argc, char *argv[])
{
  const char usage[] = "usage: findlc [-dv] m2exp [low_merit [high_merit]]\n";
  int f;
  int v_lose, m_lose, v_best, m_best;
  int c;
  int debug = 1;
  int cnt_high_merit;
  mpz_t m;
  unsigned long int m2exp;
#define DIMS 6			/* dimensions run in spectral test */
  mpf_t v[DIMS-1];		/* spectral test result (there's no v
				   for 1st dimension */
  mpf_t f_merit, low_merit, high_merit;
  mpz_t acc, minus8;
  mpz_t min, max;
  mpz_t s;


  mpz_init (m);
  mpz_init (a);
  for (f = 0; f < DIMS-1; f++)
    mpf_init (v[f]);
  mpf_init (f_merit);
  mpf_init_set_d (low_merit, .1);
  mpf_init_set_d (high_merit, .1);

  while ((c = getopt (argc, argv, "a:di:hv")) != -1)
    switch (c)
      {
      case 'd':			/* debug */
	g_debug++;
	break;

      case 'v':			/* print version */
	puts (rcsid[1]);
	exit (0);

      case 'h':
      case '?':
      default:
	fputs (usage, stderr);
	exit (1);
      }

  argc -= optind;
  argv += optind;

  if (argc < 1)
    {
      fputs (usage, stderr);
      exit (1);
    }

  /* Install signal handler. */
  if (SIG_ERR == signal (SIGSEGV, sh_status))
    {
      perror ("signal (SIGSEGV)");
      exit (1);
    }
  if (SIG_ERR == signal (SIGHUP, sh_status))
    {
      perror ("signal (SIGHUP)");
      exit (1);
    }

  printf ("findlc: version: %s\n", rcsid[1]);
  m2exp = atol (argv[0]);
  mpz_init_set_ui (m, 1);
  mpz_mul_2exp (m, m, m2exp);
  printf ("m = 0x");
  mpz_out_str (stdout, 16, m);
  puts ("");

  if (argc > 1)			/* have low_merit */
    mpf_set_str (low_merit, argv[1], 0);
  if (argc > 2)			/* have high_merit */
    mpf_set_str (high_merit, argv[2], 0);

  if (debug)
    {
      fprintf (stderr, "low_merit = ");
      mpf_out_str (stderr, 10, 2, low_merit);
      fprintf (stderr, "; high_merit = ");
      mpf_out_str (stderr, 10, 2, high_merit);
      fputs ("\n", stderr);
    }

  mpz_init (minus8);
  mpz_set_si (minus8, -8L);
  mpz_init_set_ui (acc, 0);
  mpz_init (s);
  mpz_init_set_d (min, 0.01 * pow (2.0, (double) m2exp));
  mpz_init_set_d (max, 0.99 * pow (2.0, (double) m2exp));

  mpz_true_random (s, m2exp);	/* Start.  */
  mpz_setbit (s, 0);		/* Make it odd.  */

  v_best = m_best = 2*(DIMS-1);
  for (;;)
    {
      mpz_add (acc, acc, s);
      mpz_mod_2exp (acc, acc, m2exp);
#if later
      mpz_and_si (a, acc, -8L);
#else
      mpz_and (a, acc, minus8);
#endif
      mpz_add_ui (a, a, 5);
      if (mpz_cmp (a, min) <= 0 || mpz_cmp (a, max) >= 0)
	continue;

      spectral_test (v, DIMS, a, m);
      for (f = 0, v_lose = m_lose = 0, cnt_high_merit = DIMS-1;
	   f < DIMS-1; f++)
	{
	  merit (f_merit, f + 2, v[f], m);

	  if (mpf_cmp_ui (v[f], 1 << (30 / (f + 2) + (f == 2))) < 0)
	    v_lose++;

	  if (mpf_cmp (f_merit, low_merit) < 0)
	    m_lose++;

	  if (mpf_cmp (f_merit, high_merit) >= 0)
	    cnt_high_merit--;
	}

      if (0 == v_lose && 0 == m_lose)
	{
	  mpz_out_str (stdout, 10, a); puts (""); fflush (stdout);
	  if (0 == cnt_high_merit)
	    break;		/* leave loop */
	}
      if (v_lose < v_best)
	{
	  v_best = v_lose;
	  printf ("best (v_lose=%d; m_lose=%d): ", v_lose, m_lose);
	  mpz_out_str (stdout, 10, a); puts (""); fflush (stdout);
	}
      if (m_lose < m_best)
	{
	  m_best = m_lose;
	  printf ("best (v_lose=%d; m_lose=%d): ", v_lose, m_lose);
	  mpz_out_str (stdout, 10, a); puts (""); fflush (stdout);
	}
    }

  mpz_clear (m);
  mpz_clear (a);
  for (f = 0; f < DIMS-1; f++)
    mpf_clear (v[f]);
  mpf_clear (f_merit);
  mpf_clear (low_merit);
  mpf_clear (high_merit);

  printf ("done.\n");
  return 0;
}
Example #30
0
BigInt BigInt::operator + (const BigInt &b) const
{
	BigInt ret;
	mpz_add(ret.mImpl,mImpl,b.mImpl);
	return ret;
}