Exemplo n.º 1
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;
}
Exemplo n.º 2
0
static int
mpfr_rem1 (mpfr_ptr rem, long *quo, mpfr_rnd_t rnd_q,
           mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd)
{
  mpfr_exp_t ex, ey;
  int compare, inex, q_is_odd, sign, signx = MPFR_SIGN (x);
  mpz_t mx, my, r;
  int tiny = 0;

  MPFR_ASSERTD (rnd_q == MPFR_RNDN || rnd_q == MPFR_RNDZ);

  if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x) || MPFR_IS_SINGULAR (y)))
    {
      if (MPFR_IS_NAN (x) || MPFR_IS_NAN (y) || MPFR_IS_INF (x)
          || MPFR_IS_ZERO (y))
        {
          /* for remquo, quo is undefined */
          MPFR_SET_NAN (rem);
          MPFR_RET_NAN;
        }
      else                      /* either y is Inf and x is 0 or non-special,
                                   or x is 0 and y is non-special,
                                   in both cases the quotient is zero. */
        {
          if (quo)
            *quo = 0;
          return mpfr_set (rem, x, rnd);
        }
    }

  /* now neither x nor y is NaN, Inf or zero */

  mpz_init (mx);
  mpz_init (my);
  mpz_init (r);

  ex = mpfr_get_z_2exp (mx, x);  /* x = mx*2^ex */
  ey = mpfr_get_z_2exp (my, y);  /* y = my*2^ey */

  /* to get rid of sign problems, we compute it separately:
     quo(-x,-y) = quo(x,y), rem(-x,-y) = -rem(x,y)
     quo(-x,y) = -quo(x,y), rem(-x,y)  = -rem(x,y)
     thus quo = sign(x/y)*quo(|x|,|y|), rem = sign(x)*rem(|x|,|y|) */
  sign = (signx == MPFR_SIGN (y)) ? 1 : -1;
  mpz_abs (mx, mx);
  mpz_abs (my, my);
  q_is_odd = 0;

  /* divide my by 2^k if possible to make operations mod my easier */
  {
    unsigned long k = mpz_scan1 (my, 0);
    ey += k;
    mpz_fdiv_q_2exp (my, my, k);
  }

  if (ex <= ey)
    {
      /* q = x/y = mx/(my*2^(ey-ex)) */

      /* First detect cases where q=0, to avoid creating a huge number
         my*2^(ey-ex): if sx = mpz_sizeinbase (mx, 2) and sy =
         mpz_sizeinbase (my, 2), we have x < 2^(ex + sx) and
         y >= 2^(ey + sy - 1), thus if ex + sx <= ey + sy - 1
         the quotient is 0 */
      if (ex + (mpfr_exp_t) mpz_sizeinbase (mx, 2) <
          ey + (mpfr_exp_t) mpz_sizeinbase (my, 2))
        {
          tiny = 1;
          mpz_set (r, mx);
          mpz_set_ui (mx, 0);
        }
      else
        {
          mpz_mul_2exp (my, my, ey - ex);   /* divide mx by my*2^(ey-ex) */

          /* since mx > 0 and my > 0, we can use mpz_tdiv_qr in all cases */
          mpz_tdiv_qr (mx, r, mx, my);
          /* 0 <= |r| <= |my|, r has the same sign as mx */
        }

      if (rnd_q == MPFR_RNDN)
        q_is_odd = mpz_tstbit (mx, 0);
      if (quo)                  /* mx is the quotient */
        {
          mpz_tdiv_r_2exp (mx, mx, WANTED_BITS);
          *quo = mpz_get_si (mx);
        }
    }
  else                          /* ex > ey */
    {
      if (quo) /* remquo case */
        /* for remquo, to get the low WANTED_BITS more bits of the quotient,
           we first compute R =  X mod Y*2^WANTED_BITS, where X and Y are
           defined below. Then the low WANTED_BITS of the quotient are
           floor(R/Y). */
        mpz_mul_2exp (my, my, WANTED_BITS);     /* 2^WANTED_BITS*Y */

      else if (rnd_q == MPFR_RNDN) /* remainder case */
        /* Let X = mx*2^(ex-ey) and Y = my. Then both X and Y are integers.
           Assume X = R mod Y, then x = X*2^ey = R*2^ey mod (Y*2^ey=y).
           To be able to perform the rounding, we need the least significant
           bit of the quotient, i.e., one more bit in the remainder,
           which is obtained by dividing by 2Y. */
        mpz_mul_2exp (my, my, 1);       /* 2Y */

      mpz_set_ui (r, 2);
      mpz_powm_ui (r, r, ex - ey, my);  /* 2^(ex-ey) mod my */
      mpz_mul (r, r, mx);
      mpz_mod (r, r, my);

      if (quo)                  /* now 0 <= r < 2^WANTED_BITS*Y */
        {
          mpz_fdiv_q_2exp (my, my, WANTED_BITS);   /* back to Y */
          mpz_tdiv_qr (mx, r, r, my);
          /* oldr = mx*my + newr */
          *quo = mpz_get_si (mx);
          q_is_odd = *quo & 1;
        }
      else if (rnd_q == MPFR_RNDN) /* now 0 <= r < 2Y in the remainder case */
        {
          mpz_fdiv_q_2exp (my, my, 1);     /* back to Y */
          /* least significant bit of q */
          q_is_odd = mpz_cmpabs (r, my) >= 0;
          if (q_is_odd)
            mpz_sub (r, r, my);
        }
      /* now 0 <= |r| < |my|, and if needed,
         q_is_odd is the least significant bit of q */
    }

  if (mpz_cmp_ui (r, 0) == 0)
    {
      inex = mpfr_set_ui (rem, 0, MPFR_RNDN);
      /* take into account sign of x */
      if (signx < 0)
        mpfr_neg (rem, rem, MPFR_RNDN);
    }
  else
    {
      if (rnd_q == MPFR_RNDN)
        {
          /* FIXME: the comparison 2*r < my could be done more efficiently
             at the mpn level */
          mpz_mul_2exp (r, r, 1);
          /* if tiny=1, we should compare r with my*2^(ey-ex) */
          if (tiny)
            {
              if (ex + (mpfr_exp_t) mpz_sizeinbase (r, 2) <
                  ey + (mpfr_exp_t) mpz_sizeinbase (my, 2))
                compare = 0; /* r*2^ex < my*2^ey */
              else
                {
                  mpz_mul_2exp (my, my, ey - ex);
                  compare = mpz_cmpabs (r, my);
                }
            }
          else
            compare = mpz_cmpabs (r, my);
          mpz_fdiv_q_2exp (r, r, 1);
          compare = ((compare > 0) ||
                     ((rnd_q == MPFR_RNDN) && (compare == 0) && q_is_odd));
          /* if compare != 0, we need to subtract my to r, and add 1 to quo */
          if (compare)
            {
              mpz_sub (r, r, my);
              if (quo && (rnd_q == MPFR_RNDN))
                *quo += 1;
            }
        }
      /* take into account sign of x */
      if (signx < 0)
        mpz_neg (r, r);
      inex = mpfr_set_z_2exp (rem, r, ex > ey ? ey : ex, rnd);
    }

  if (quo)
    *quo *= sign;

  mpz_clear (mx);
  mpz_clear (my);
  mpz_clear (r);

  return inex;
}
Exemplo n.º 3
0
static int
hgcd_appr_valid_p (mpz_t a, mpz_t b, mp_size_t res0,
		   struct hgcd_ref *ref, mpz_t ref_r0, mpz_t ref_r1,
		   mp_size_t res1, struct hgcd_matrix *hgcd)
{
  mp_size_t n = MAX (mpz_size (a), mpz_size (b));
  mp_size_t s = n/2 + 1;

  mp_bitcnt_t dbits, abits, margin;
  mpz_t appr_r0, appr_r1, t, q;
  struct hgcd_ref appr;

  if (!res0)
    {
      if (!res1)
	return 1;

      fprintf (stderr, "mpn_hgcd_appr returned 1 when no reduction possible.\n");
      return 0;
    }

  /* NOTE: No *_clear calls on error return, since we're going to
     abort anyway. */
  mpz_init (t);
  mpz_init (q);
  hgcd_ref_init (&appr);
  mpz_init (appr_r0);
  mpz_init (appr_r1);

  if (mpz_size (ref_r0) <= s)
    {
      fprintf (stderr, "ref_r0 too small!!!: "); debug_mp (ref_r0, 16);
      return 0;
    }
  if (mpz_size (ref_r1) <= s)
    {
      fprintf (stderr, "ref_r1 too small!!!: "); debug_mp (ref_r1, 16);
      return 0;
    }

  mpz_sub (t, ref_r0, ref_r1);
  dbits = mpz_sizeinbase (t, 2);
  if (dbits > s*GMP_NUMB_BITS)
    {
      fprintf (stderr, "ref |r0 - r1| too large!!!: "); debug_mp (t, 16);
      return 0;
    }

  if (!res1)
    {
      mpz_set (appr_r0, a);
      mpz_set (appr_r1, b);
    }
  else
    {
      unsigned i;

      for (i = 0; i<2; i++)
	{
	  unsigned j;

	  for (j = 0; j<2; j++)
	    {
	      mp_size_t mn = hgcd->n;
	      MPN_NORMALIZE (hgcd->p[i][j], mn);
	      mpz_realloc (appr.m[i][j], mn);
	      MPN_COPY (PTR (appr.m[i][j]), hgcd->p[i][j], mn);
	      SIZ (appr.m[i][j]) = mn;
	    }
	}
      mpz_mul (appr_r0, appr.m[1][1], a);
      mpz_mul (t, appr.m[0][1], b);
      mpz_sub (appr_r0, appr_r0, t);
      if (mpz_sgn (appr_r0) <= 0
	  || mpz_size (appr_r0) <= s)
	{
	  fprintf (stderr, "appr_r0 too small: "); debug_mp (appr_r0, 16);
	  return 0;
	}

      mpz_mul (appr_r1, appr.m[1][0], a);
      mpz_mul (t, appr.m[0][0], b);
      mpz_sub (appr_r1, t, appr_r1);
      if (mpz_sgn (appr_r1) <= 0
	  || mpz_size (appr_r1) <= s)
	{
	  fprintf (stderr, "appr_r1 too small: "); debug_mp (appr_r1, 16);
	  return 0;
	}
    }

  mpz_sub (t, appr_r0, appr_r1);
  abits = mpz_sizeinbase (t, 2);
  if (abits < dbits)
    {
      fprintf (stderr, "|r0 - r1| too small: "); debug_mp (t, 16);
      return 0;
    }

  /* We lose one bit each time we discard the least significant limbs.
     For the lehmer code, that can happen at most s * (GMP_NUMB_BITS)
     / (GMP_NUMB_BITS - 1) times. For the dc code, we lose an entire
     limb (or more?) for each level of recursion. */

  margin = (n/2+1) * GMP_NUMB_BITS / (GMP_NUMB_BITS - 1);
  {
    mp_size_t rn;
    for (rn = n; ABOVE_THRESHOLD (rn, HGCD_APPR_THRESHOLD); rn = (rn + 1)/2)
      margin += GMP_NUMB_BITS;
  }

  if (verbose_flag && abits > dbits)
    fprintf (stderr, "n = %u: sbits = %u: ref #(r0-r1): %u, appr #(r0-r1): %u excess: %d, margin: %u\n",
	     (unsigned) n, (unsigned) s*GMP_NUMB_BITS,
	     (unsigned) dbits, (unsigned) abits,
	     (int) abits - s * GMP_NUMB_BITS, (unsigned) margin);

  if (abits > s*GMP_NUMB_BITS + margin)
    {
      fprintf (stderr, "appr |r0 - r1| much larger than minimal (by %u bits, margin = %u bits)\n",
	       (unsigned) (abits - s*GMP_NUMB_BITS), (unsigned) margin);
      return 0;
    }

  while (mpz_cmp (appr_r0, ref_r0) > 0 || mpz_cmp (appr_r1, ref_r1) > 0)
    {
      ASSERT (mpz_size (appr_r0) > s);
      ASSERT (mpz_size (appr_r1) > s);

      if (mpz_cmp (appr_r0, appr_r1) > 0)
	{
	  if (!sdiv_qr (q, appr_r0, s, appr_r0, appr_r1))
	    break;
	  mpz_addmul (appr.m[0][1], q, appr.m[0][0]);
	  mpz_addmul (appr.m[1][1], q, appr.m[1][0]);
	}
      else
	{
	  if (!sdiv_qr (q, appr_r1, s, appr_r1, appr_r0))
	    break;
	  mpz_addmul (appr.m[0][0], q, appr.m[0][1]);
	  mpz_addmul (appr.m[1][0], q, appr.m[1][1]);
	}
    }

  if (mpz_cmp (appr_r0, ref_r0) != 0
      || mpz_cmp (appr_r1, ref_r1) != 0
      || !hgcd_ref_equal (ref, &appr))
    {
      fprintf (stderr, "appr_r0: "); debug_mp (appr_r0, 16);
      fprintf (stderr, "ref_r0: "); debug_mp (ref_r0, 16);

      fprintf (stderr, "appr_r1: "); debug_mp (appr_r1, 16);
      fprintf (stderr, "ref_r1: "); debug_mp (ref_r1, 16);

      return 0;
    }
  mpz_clear (t);
  mpz_clear (q);
  hgcd_ref_clear (&appr);
  mpz_clear (appr_r0);
  mpz_clear (appr_r1);

  return 1;
}
Exemplo n.º 4
0
static PyObject *
GMPY_mpz_lucasv_mod(PyObject *self, PyObject *args)
{
    /* Adaptation of algorithm found in http://joye.site88.net/papers/JQ96lucas.pdf
     * calculate v[k] (modulo n) of Lucas V sequence for p,q.
     * Note: p^2-4q=0 is not tested, not a proper Lucas sequence!!
     */

    MPZ_Object *result = 0, *p, *q, *k, *n;

    size_t s = 0, j = 0;
    mpz_t vl, vh, ql, qh, tmp;

    if (PyTuple_Size(args) != 4) {
        TYPE_ERROR("lucasv_mod() requires 4 integer arguments");
        return NULL;
    }

    mpz_init(vl);
    mpz_init(vh);
    mpz_init(ql);
    mpz_init(qh);
    mpz_init(tmp);

    p = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL);
    q = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL);
    k = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 2), NULL);
    n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 3), NULL);
    if (!p || !q || !k || !n) {
        TYPE_ERROR("lucasv_mod() requires 4 integer arguments");
        goto cleanup;
    }

    /* Check if p*p - 4*q == 0. */

    mpz_mul(tmp, p->z, p->z);
    mpz_mul_ui(qh, q->z, 4);
    mpz_sub(tmp, tmp, qh);
    if (mpz_sgn(tmp) == 0) {
        VALUE_ERROR("invalid values for p,q in lucasv_mod()");
        goto cleanup;
    }

    /* Check if k < 0. */

    if (mpz_sgn(k->z) < 0) {
        VALUE_ERROR("invalid value for k in lucasv_mod()");
        goto cleanup;
    }

    /* Check if n > 0. */

    if (mpz_sgn(n->z) <= 0) {
        VALUE_ERROR("invalid value for n in lucasv_mod()");
        goto cleanup;
    }

    mpz_set_si(vl, 2);
    mpz_set(vh, p->z);
    mpz_set_si(ql, 1);
    mpz_set_si(qh, 1);
    mpz_set_si(tmp,0);

    s = mpz_scan1(k->z, 0);
    for (j = mpz_sizeinbase(k->z,2)-1; j >= s+1; j--) {
        /* ql = ql*qh (mod n) */
        mpz_mul(ql, ql, qh);
        mpz_mod(ql, ql, n->z);
        if (mpz_tstbit(k->z,j) == 1) {
            /* qh = ql*q */
            mpz_mul(qh, ql, q->z);

            /* vl = vh*vl - p*ql (mod n) */
            mpz_mul(vl, vh, vl);
            mpz_mul(tmp, ql, p->z);
            mpz_sub(vl, vl, tmp);
            mpz_mod(vl, vl, n->z);

            /* vh = vh*vh - 2*qh (mod n) */
            mpz_mul(vh, vh, vh);
            mpz_mul_si(tmp, qh, 2);
            mpz_sub(vh, vh, tmp);
            mpz_mod(vh, vh, n->z);
        }
        else {
            /* qh = ql */
            mpz_set(qh, ql);

            /* vh = vh*vl - p*ql (mod n) */
            mpz_mul(vh, vh, vl);
            mpz_mul(tmp, ql, p->z);
            mpz_sub(vh, vh, tmp);
            mpz_mod(vh, vh, n->z);

            /* vl = vl*vl - 2*ql (mod n) */
            mpz_mul(vl, vl, vl);
            mpz_mul_si(tmp, ql, 2);
            mpz_sub(vl, vl, tmp);
            mpz_mod(vl, vl, n->z);
        }
    }
    /* ql = ql*qh */
    mpz_mul(ql, ql, qh);

    /* qh = ql*q */
    mpz_mul(qh, ql, q->z);

    /* vl = vh*vl - p*ql */
    mpz_mul(vl, vh, vl);
    mpz_mul(tmp, ql, p->z);
    mpz_sub(vl, vl, tmp);

    /* ql = ql*qh */
    mpz_mul(ql, ql, qh);

    for (j = 1; j <= s; j++) {
        /* vl = vl*vl - 2*ql (mod n) */
        mpz_mul(vl, vl, vl);
        mpz_mul_si(tmp, ql, 2);
        mpz_sub(vl, vl, tmp);
        mpz_mod(vl, vl, n->z);

        /* ql = ql*ql (mod n) */
        mpz_mul(ql, ql, ql);
        mpz_mod(ql, ql, n->z);
    }

    if (!(result = GMPy_MPZ_New(NULL)))
        goto cleanup;

    /* vl contains our return value */
    mpz_mod(result->z, vl, n->z);

  cleanup:
    mpz_clear(vl);
    mpz_clear(vh);
    mpz_clear(ql);
    mpz_clear(qh);
    mpz_clear(tmp);
    Py_XDECREF((PyObject*)p);
    Py_XDECREF((PyObject*)q);
    Py_XDECREF((PyObject*)k);
    Py_XDECREF((PyObject*)n);

    return (PyObject*)result;
}
Exemplo n.º 5
0
chunk_t mpz_to_n_autosize(const MP_INT *mp)
{
	int bytes = (mpz_sizeinbase(mp, 2)+7)/8;

	return mpz_to_n(mp, bytes);
}
Exemplo n.º 6
0
void RSA::getPublicKey(char* buffer)
{
	size_t count = (mpz_sizeinbase(m_n, 2) + 7) / 8;
	memset(buffer, 0, 128 - count);
	mpz_export(&buffer[128 - count], nullptr, 1, 1, 0, 0, m_n);
}
Exemplo n.º 7
0
int main(){

  mpz_t p;
  mpz_init(p);


  const char* p_hex = 
    "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f";

  assert(mpz_set_str(p, p_hex, 16) == 0);

  mpz_t q;
  assert(mpz_init_set_str(q, p_hex, 16) == 0);

  assert(mpz_cmp(p,q) == 0);

  char buffer[128];

  assert(mpz_get_str(buffer,10,p) == buffer);
  printf("p = %s\n", buffer);
  printf("p = "); mpz_out_str(stdout,10,p); printf("\n");
  gmp_printf("p = %Zd\n", p);



  int primality = mpz_probab_prime_p(p,50); // proba < 4^(-50) of being wrong
  
  switch(primality){
    case 2:
      printf("p is definitely prime\n"); break;
    case 1:
      printf("p is very probably prime\n"); break;
    case 0:
      printf("p is composite\n"); break;
    default:
      assert(NULL);
  }

  mpz_sub_ui(q,p,50);
  assert(mpz_get_str(buffer,10,q) == buffer);
  printf("q = %s\n", buffer);
  printf("q = "); mpz_out_str(stdout,10,q); printf("\n");

  mpz_nextprime(q,q);
  assert(mpz_get_str(buffer,10,q) == buffer);
  printf("q = %s\n", buffer);
  printf("q = "); mpz_out_str(stdout,10,q); printf("\n");

  mpz_sub_ui(q,p,50);
  mpz_gcd(q,q,p);
  assert(mpz_get_str(buffer,10,q) == buffer);
  printf("q = %s\n", buffer);
  printf("q = "); mpz_out_str(stdout,10,q); printf("\n");

  /*
  printf("please enter a number in hex:");
  assert(mpz_inp_str(q, stdin, 16) != 0);
  printf("q = "); mpz_out_str(stdout,10,q); printf("\n");

  printf("please do it again:");scanf("%s", buffer);
  assert(mpz_set_str(q,buffer,16) == 0);
  printf("q = "); mpz_out_str(stdout,10,q); printf("\n");
  */
  
  unsigned long a[20];
  mpz_import(q,32,1,sizeof(a[0]),0,0,a);
  printf("q = "); mpz_out_str(stdout,16,q); printf("\n");


  printf("size of p in base 16 is:%d\n", mpz_sizeinbase(p,2));

  

  mpz_clear(q);
  mpz_clear(p);

  return 0;
}
Exemplo n.º 8
0
int
mpz_probab_prime_p (mpz_srcptr n, int reps)
{
  mp_limb_t r;

  /* Handle small and negative n.  */
  if (mpz_cmp_ui (n, 1000000L) <= 0)
    {
      int is_prime;
      if (mpz_sgn (n) < 0)
	{
	  /* Negative number.  Negate and call ourselves.  */
	  mpz_t n2;
	  mpz_init (n2);
	  mpz_neg (n2, n);
	  is_prime = mpz_probab_prime_p (n2, reps);
	  mpz_clear (n2);
	  return is_prime;
	}
      is_prime = isprime (mpz_get_ui (n));
      return is_prime ? 2 : 0;
    }

  /* 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), SIZ(n), (mp_limb_t) PP,
                               (mp_limb_t) PP_INVERTED);
#else
  r = mpn_mod_1 (PTR(n), 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) / 30; ln2 = ln2 * ln2;
    for (q = PP_FIRST_OMITTED; q < ln2; q += 2)
      {
	if (isprime (q))
	  {
	    umul_ppmm (p1, p0, p, q);
	    if (p1 != 0)
	      {
		r = mpn_mod_1 (PTR(n), SIZ(n), p);
		while (--nprimes >= 0)
		  if (r % primes[nprimes] == 0)
		    {
		      ASSERT_ALWAYS (mpn_mod_1 (PTR(n), 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);
}
Exemplo n.º 9
0
/* Compute the first 2^m terms from the hypergeometric series
   with x = p / 2^r */
static int
GENERIC (mpfr_ptr y, mpz_srcptr p, long r, int m)
{
  unsigned long n,i,k,j,l;
  int is_p_one;
  mpz_t* P,*S;
#ifdef A
  mpz_t *T;
#endif
  mpz_t* ptoj;
#ifdef R_IS_RATIONAL
  mpz_t* qtoj;
  mpfr_t tmp;
#endif
  mp_exp_t diff, expo;
  mp_prec_t precy = MPFR_PREC(y);
  MPFR_TMP_DECL(marker);

  MPFR_TMP_MARK(marker);
  MPFR_CLEAR_FLAGS(y);
  n = 1UL << m;
  P = (mpz_t*) MPFR_TMP_ALLOC ((m+1) * sizeof(mpz_t));
  S = (mpz_t*) MPFR_TMP_ALLOC ((m+1) * sizeof(mpz_t));
  ptoj = (mpz_t*) MPFR_TMP_ALLOC ((m+1) * sizeof(mpz_t)); /* ptoj[i] = mantissa^(2^i) */
#ifdef A
  T = (mpz_t*) MPFR_TMP_ALLOC ((m+1) * sizeof(mpz_t));
#endif
#ifdef R_IS_RATIONAL
  qtoj = (mpz_t*) MPFR_TMP_ALLOC ((m+1) * sizeof(mpz_t));
#endif
  for (i = 0 ; i <= m ; i++)
    {
      mpz_init (P[i]);
      mpz_init (S[i]);
      mpz_init (ptoj[i]);
#ifdef R_IS_RATIONAL
      mpz_init (qtoj[i]);
#endif
#ifdef A
      mpz_init (T[i]);
#endif
    }
  mpz_set (ptoj[0], p);
#ifdef C
#  if C2 != 1
  mpz_mul_ui (ptoj[0], ptoj[0], C2);
#  endif
#endif
  is_p_one = mpz_cmp_ui(ptoj[0], 1) == 0;
#ifdef A
#  ifdef B
  mpz_set_ui (T[0], A1 * B1);
#  else
  mpz_set_ui (T[0], A1);
#  endif
#endif
  if (!is_p_one)
    for (i = 1 ; i < m ; i++)
      mpz_mul (ptoj[i], ptoj[i-1], ptoj[i-1]);
#ifdef R_IS_RATIONAL
  mpz_set_si (qtoj[0], r);
  for (i = 1 ; i <= m ; i++)
    mpz_mul(qtoj[i], qtoj[i-1], qtoj[i-1]);
#endif
  mpz_set_ui (P[0], 1);
  mpz_set_ui (S[0], 1);

  k = 0;
  for (i = 1 ; i < n ; i++) {
    k++;

#ifdef A
#  ifdef B
    mpz_set_ui (T[k], (A1 + A2*i)*(B1+B2*i));
#  else
    mpz_set_ui (T[k], A1 + A2*i);
#  endif
#endif

#ifdef C
#  ifdef NO_FACTORIAL
    mpz_set_ui (P[k], (C1 + C2 * (i-1)));
    mpz_set_ui (S[k], 1);
#  else
    mpz_set_ui (P[k], (i+1) * (C1 + C2 * (i-1)));
    mpz_set_ui (S[k], i+1);
#  endif
#else
#  ifdef NO_FACTORIAL
    mpz_set_ui (P[k], 1);
#  else
    mpz_set_ui (P[k], i+1);
#  endif
    mpz_set (S[k], P[k]);
#endif

    for (j = i+1, l = 0 ; (j & 1) == 0 ; l++, j>>=1, k--) {
      if (!is_p_one)
        mpz_mul (S[k], S[k], ptoj[l]);
#ifdef A
#  ifdef B
#    if (A2*B2) != 1
      mpz_mul_ui (P[k], P[k], A2*B2);
#    endif
#  else
#    if A2 != 1
      mpz_mul_ui (P[k], P[k], A2);
#  endif
#endif
      mpz_mul (S[k], S[k], T[k-1]);
#endif
      mpz_mul (S[k-1], S[k-1], P[k]);
#ifdef R_IS_RATIONAL
      mpz_mul (S[k-1], S[k-1], qtoj[l]);
#else
      mpz_mul_2exp (S[k-1], S[k-1], r*(1<<l));
#endif
      mpz_add (S[k-1], S[k-1], S[k]);
      mpz_mul (P[k-1], P[k-1], P[k]);
#ifdef A
      mpz_mul (T[k-1], T[k-1], T[k]);
#endif
    }
  }

  diff = mpz_sizeinbase(S[0],2) - 2*precy;
  expo = diff;
  if (diff >= 0)
    mpz_div_2exp(S[0],S[0],diff);
  else
    mpz_mul_2exp(S[0],S[0],-diff);
  diff = mpz_sizeinbase(P[0],2) - precy;
  expo -= diff;
  if (diff >=0)
    mpz_div_2exp(P[0],P[0],diff);
  else
    mpz_mul_2exp(P[0],P[0],-diff);

  mpz_tdiv_q(S[0], S[0], P[0]);
  mpfr_set_z(y, S[0], GMP_RNDD);
  MPFR_SET_EXP (y, MPFR_GET_EXP (y) + expo);

#ifdef R_IS_RATIONAL
  /* exact division */
  mpz_div_ui (qtoj[m], qtoj[m], r);
  mpfr_init2 (tmp, MPFR_PREC(y));
  mpfr_set_z (tmp, qtoj[m] , GMP_RNDD);
  mpfr_div (y, y, tmp, GMP_RNDD);
  mpfr_clear (tmp);
#else
  mpfr_div_2ui(y, y, r*(i-1), GMP_RNDN);
#endif
  for (i = 0 ; i <= m ; i++)
    {
      mpz_clear (P[i]);
      mpz_clear (S[i]);
      mpz_clear (ptoj[i]);
#ifdef R_IS_RATIONAL
      mpz_clear (qtoj[i]);
#endif
#ifdef A
      mpz_clear (T[i]);
#endif
    }
  MPFR_TMP_FREE (marker);
  return 0;
}
Exemplo n.º 10
0
uint32_t tpm_bn_bitsize(tpm_bn_t a)
{
  return mpz_sizeinbase(a, 2);
}
bool
gfc_convert_boz (gfc_expr *expr, gfc_typespec *ts)
{
  size_t buffer_size, boz_bit_size, ts_bit_size;
  int index;
  unsigned char *buffer;

  if (!expr->is_boz)
    return true;

  gcc_assert (expr->expr_type == EXPR_CONSTANT
	      && expr->ts.type == BT_INTEGER);

  /* Don't convert BOZ to logical, character, derived etc.  */
  if (ts->type == BT_REAL)
    {
      buffer_size = size_float (ts->kind);
      ts_bit_size = buffer_size * 8;
    }
  else if (ts->type == BT_COMPLEX)
    {
      buffer_size = size_complex (ts->kind);
      ts_bit_size = buffer_size * 8 / 2;
    }
  else
    return true;

  /* Convert BOZ to the smallest possible integer kind.  */
  boz_bit_size = mpz_sizeinbase (expr->value.integer, 2);

  if (boz_bit_size > ts_bit_size)
    {
      gfc_error_now ("BOZ constant at %L is too large (%ld vs %ld bits)",
		     &expr->where, (long) boz_bit_size, (long) ts_bit_size);
      return false;
    }

  for (index = 0; gfc_integer_kinds[index].kind != 0; ++index)
    {
	if ((unsigned) gfc_integer_kinds[index].bit_size >= ts_bit_size)
	  break;
    }

  expr->ts.kind = gfc_integer_kinds[index].kind;
  buffer_size = MAX (buffer_size, size_integer (expr->ts.kind));

  buffer = (unsigned char*)alloca (buffer_size);
  encode_integer (expr->ts.kind, expr->value.integer, buffer, buffer_size);
  mpz_clear (expr->value.integer);

  if (ts->type == BT_REAL)
    {
      mpfr_init (expr->value.real);
      gfc_interpret_float (ts->kind, buffer, buffer_size, expr->value.real);
    }
  else
    {
      mpfr_init (expr->value.complex.r);
      mpfr_init (expr->value.complex.i);
      gfc_interpret_complex (ts->kind, buffer, buffer_size,
			     expr->value.complex.r, expr->value.complex.i);
    }
  expr->is_boz = 0;  
  expr->ts.type = ts->type;
  expr->ts.kind = ts->kind;

  return true;
}
Exemplo n.º 12
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) */
}
Exemplo n.º 13
0
int check_specialcase(FILE *sieve_log, fact_obj_t *fobj)
{
	//check for some special cases of input number
	//sieve_log is passed in already open, and should return open
	if (mpz_even_p(fobj->qs_obj.gmp_n))
	{
		printf("input must be odd\n");
		return 1;
	}

	if (mpz_probab_prime_p(fobj->qs_obj.gmp_n, NUM_WITNESSES))
	{
		add_to_factor_list(fobj, fobj->qs_obj.gmp_n);
		if (sieve_log != NULL)
			logprint(sieve_log,"prp%d = %s\n", gmp_base10(fobj->qs_obj.gmp_n), 
			mpz_conv2str(&gstr1.s, 10, fobj->qs_obj.gmp_n));
		mpz_set_ui(fobj->qs_obj.gmp_n,1);
		return 1;
	}

	if (mpz_perfect_square_p(fobj->qs_obj.gmp_n))
	{
		mpz_sqrt(fobj->qs_obj.gmp_n,fobj->qs_obj.gmp_n);

		add_to_factor_list(fobj, fobj->qs_obj.gmp_n);
		if (sieve_log != NULL)
			logprint(sieve_log,"prp%d = %s\n",gmp_base10(fobj->qs_obj.gmp_n), 
			mpz_conv2str(&gstr1.s, 10, fobj->qs_obj.gmp_n));
		add_to_factor_list(fobj, fobj->qs_obj.gmp_n);
		if (sieve_log != NULL)
			logprint(sieve_log,"prp%d = %s\n",gmp_base10(fobj->qs_obj.gmp_n),
			mpz_conv2str(&gstr1.s, 10, fobj->qs_obj.gmp_n));

		mpz_set_ui(fobj->qs_obj.gmp_n,1);
		return 1;
	}

	if (mpz_perfect_power_p(fobj->qs_obj.gmp_n))
	{
		if (VFLAG > 0)
			printf("input is a perfect power\n");
		
		factor_perfect_power(fobj, fobj->qs_obj.gmp_n);

		if (sieve_log != NULL)
		{
			uint32 j;
			logprint(sieve_log,"input is a perfect power\n");

			for (j=0; j<fobj->num_factors; j++)
			{
				uint32 k;
				for (k=0; k<fobj->fobj_factors[j].count; k++)
				{
					logprint(sieve_log,"prp%d = %s\n",gmp_base10(fobj->fobj_factors[j].factor), 
						mpz_conv2str(&gstr1.s, 10, fobj->fobj_factors[j].factor));
				}
			}
		}
		return 1;
	}

	if (mpz_sizeinbase(fobj->qs_obj.gmp_n,2) < 115)
	{
		//run MPQS, as SIQS doesn't work for smaller inputs
		//MPQS will take over the log file, so close it now.
		int i;

		// we've verified that the input is not odd or prime.  also
		// do some very quick trial division before calling smallmpqs, which
		// does none of these things.
		for (i=1; i<25; i++)
		{
			if (mpz_tdiv_ui(fobj->qs_obj.gmp_n, spSOEprimes[i]) == 0)
				mpz_tdiv_q_ui(fobj->qs_obj.gmp_n, fobj->qs_obj.gmp_n, spSOEprimes[i]);
		}

		smallmpqs(fobj);
		return 1;	//tells SIQS to not try to close the logfile
	}

	if (gmp_base10(fobj->qs_obj.gmp_n) > 140)
	{
		printf("input too big for SIQS\n");
		return 1;
	}

	return 0;
}
Exemplo n.º 14
0
static PyObject *
obf_encode_circuit(PyObject *self, PyObject *args)
{
    PyObject *py_state, *py_ys, *py_xdegs;
    mpz_t tmp, c_star;
    mpz_t *alphas, *betas;
    int n, m, ydeg;
    int *indices, *pows;
    char *circuit, *fname;
    int fnamelen = sizeof(int) + 5;
    int idx_set_size;
    struct state *s;




    if (!PyArg_ParseTuple(args, "OsOOiii", &py_state, &circuit, &py_ys,
                          &py_xdegs, &ydeg, &n,&m)){
	fprintf(stderr,"!!!!!!!! NOT PARSING !!!!!!!!!!!!!!!!\n");
        return NULL;}
    s = (struct state *) PyCapsule_GetPointer(py_state, NULL);
    if (s == NULL)
        return NULL;
    fname = (char *) malloc(sizeof(char) * fnamelen);
    if (fname == NULL)
        return NULL;

	

	 

	
	int ierr,rank,world_size;
	ierr = MPI_Comm_rank ( MPI_COMM_WORLD, &rank );
	ierr = MPI_Comm_size(MPI_COMM_WORLD,&world_size);
	struct clt_mlm_ser_enc* sent_mlm = stat_ser(&(s->mlm));
	//broadcast_clt_mlm_ser_enc(sent_mlm);
	ser_stat( sent_mlm,&(s->mlm) );

	mpz_init_set(s->nev, s->mlm.gs[0]);
    mpz_init_set(s->nchk, s->mlm.gs[1]);

    mpz_inits(c_star, tmp, NULL);


	rank = 0;
	world_size =1;
	int start_n_loop = rank*n/world_size;
	int stop_n_loop = (rank+1)*n/world_size;
	//int size_n_loop = start_n_loop - stop_n_loop;
	int start_m_loop = rank*m/world_size;
	int stop_m_loop = (rank+1)*m/world_size;
	//int size_m_loop = start_m_loop; 



    alphas = (mpz_t *) malloc(sizeof(mpz_t) * n);
    #pragma omp parallel for
    for (int i = 0; i < n; ++i) {
        mpz_init(alphas[i]);
        mpz_urandomm(alphas[i], s->mlm.rng, s->nchk);
    }
    betas = (mpz_t *) malloc(sizeof(mpz_t) * m);
    #pragma omp parallel for
    for (int i = 0; i < m; ++i) {
        mpz_init(betas[i]);
        mpz_urandomm(betas[i], s->mlm.rng, s->nchk);
    }
	
	std::vector<std::vector<char> > alpha_send = mpz_arr_to_vec(alphas, n);
	std::vector<std::vector<char> > beta_send = mpz_arr_to_vec(betas, m);
	//broadcast_vec_vec(&alpha_send);
	//broadcast_vec_vec(&beta_send);
	vec_to_mpz_array(alphas,alpha_send);
	vec_to_mpz_array(betas,beta_send);


	fprintf(stderr,"Process %d has g[0] = %lu\n",rank,mpz_get_ui(s->mlm.gs[0]));
	fprintf(stderr,"Process %d has pzt = %lu\n",rank,mpz_get_ui(s->mlm.pzt));
	fprintf(stderr,"Process %d has alpha = %lu\n",rank,mpz_get_ui(alphas[2]));

    // The index set is laid out as follows:
    //   - The first 2 * n entries contain X_i,0 and X_i,1
    //   - The next n entries contain Z_i
    //   - The next n entries contain W_i
    //   - The final entry contains Y
    idx_set_size = 4 * n + 1;

    indices = (int *) malloc(sizeof(int) * idx_set_size);
    pows = (int *) malloc(sizeof(int) * idx_set_size);


	//MR
	fprintf(stderr, "m: %d , n: %d \n ", m,n);

	


    for (int i = start_n_loop; i <stop_n_loop ; ++i) {
	fprintf(stderr,"In loop: %d\n",i);        
	mpz_t out, elems[2];
        int deg;
	
	
        mpz_inits(out, elems[0], elems[1], NULL);

        deg = PyLong_AsLong(PyList_GET_ITEM(py_xdegs, i));


	//MR
	//fprintf(stderr, "%d, " ,deg);

        set_indices_pows(indices, pows, 1, 2 * i, 1);
        mpz_set_ui(elems[0], 0);
        mpz_set(elems[1], alphas[i]);
        clt_mlm_encode(&s->mlm, out, 2, elems, 1, indices, pows);
        (void) snprintf(fname, fnamelen, "x_%d_0", i);
        (void) write_element(s->dir, out, fname);
	fprintf(stderr,"Past 1st encode In loop: %d\n",i); 

        set_indices_pows(indices, pows, 1, 2 * i, 1);
        mpz_set_ui(elems[0], 1);
        mpz_set_ui(elems[1], 1);
        clt_mlm_encode(&s->mlm, out, 2, elems, 1, indices, pows);
        (void) snprintf(fname, fnamelen, "u_%d_0", i);
        (void) write_element(s->dir, out, fname);

        set_indices_pows(indices, pows, 1, 2 * i + 1, 1);
        mpz_set_ui(elems[0], 1);
        mpz_set(elems[1], alphas[i]);
        clt_mlm_encode(&s->mlm, out, 2, elems, 1, indices, pows);
	fprintf(stderr,"Past Third encode In loop: %d\n",i);
        (void) snprintf(fname, fnamelen, "x_%d_1", i);
        (void) write_element(s->dir, out, fname);

        set_indices_pows(indices, pows, 1, 2 * i + 1, 1);
        mpz_set_ui(elems[0], 1);
        mpz_set_ui(elems[1], 1);
        clt_mlm_encode(&s->mlm, out, 2, elems, 1, indices, pows);
        (void) snprintf(fname, fnamelen, "u_%d_1", i);
        (void) write_element(s->dir, out, fname);

        mpz_urandomm(elems[0], s->mlm.rng, s->nev);
        mpz_urandomm(elems[1], s->mlm.rng, s->nchk);

        set_indices_pows(indices, pows, 3, 2 * i + 1, deg, 2 * n + i, 1,
                         3 * n + i, 1);
        clt_mlm_encode(&s->mlm, out, 2, elems, 3, indices, pows);
        (void) snprintf(fname, fnamelen, "z_%d_0", i);
        (void) write_element(s->dir, out, fname);

        set_indices_pows(indices, pows, 1, 3 * n + i, 1);
        mpz_set_ui(elems[0], 0);
        clt_mlm_encode(&s->mlm, out, 2, elems, 1, indices, pows);
        (void) snprintf(fname, fnamelen, "w_%d_0", i);
        (void) write_element(s->dir, out, fname);

        mpz_urandomm(elems[0], s->mlm.rng, s->nev);
        mpz_urandomm(elems[1], s->mlm.rng, s->nchk);

        set_indices_pows(indices, pows, 3, 2 * i, deg, 2 * n + i, 1, 3 * n + i, 1);
        clt_mlm_encode(&s->mlm, out, 2, elems, 3, indices, pows);
        (void) snprintf(fname, fnamelen, "z_%d_1", i);
        (void) write_element(s->dir, out, fname);

        set_indices_pows(indices, pows, 1, 3 * n + i, 1);
        mpz_set_ui(elems[0], 0);
        clt_mlm_encode(&s->mlm, out, 2, elems, 1, indices, pows);
        (void) snprintf(fname, fnamelen, "w_%d_1", i);
        (void) write_element(s->dir, out, fname);

        mpz_clears(out, elems[0], elems[1], NULL);
    }


	

    set_indices_pows(indices, pows, 1, 4 * n, 1);
    for (int i = start_m_loop; i < stop_m_loop; ++i) {
        mpz_t out, elems[2];
        mpz_inits(out, elems[0], elems[1], NULL);

        py_to_mpz(elems[0], PyList_GET_ITEM(py_ys, i));
        if (mpz_sgn(elems[0]) == -1) {
            mpz_mod(elems[0], elems[0], s->nev);
        }
        mpz_set(elems[1], betas[i]);
        clt_mlm_encode(&s->mlm, out, 2, elems, 1, indices, pows);
        (void) snprintf(fname, fnamelen, "y_%d", i);
        (void) write_element(s->dir, out, fname);
        mpz_clears(out, elems[0], elems[1], NULL);
    }


   if(rank==0) {
        mpz_t elems[2];
        mpz_init_set_ui(elems[0], 1);
        mpz_init_set_ui(elems[1], 1);
        clt_mlm_encode(&s->mlm, tmp, 2, elems, 1, indices, pows);
        (void) write_element(s->dir, tmp, "v");
        mpz_clears(elems[0], elems[1], NULL);
    }

    if(rank==0){
        struct circuit *c;

        c = circ_parse(circuit);
        {
            int circnamelen;
            char *circname;
            circnamelen = strlen(s->dir) + strlen("/circuit") + 2;
            circname = (char *) malloc(sizeof(char) * circnamelen);
            (void) snprintf(circname, circnamelen, "%s/circuit", s->dir);
            (void) circ_copy_circuit(circuit, circname);
            free(circname);
        }
        (void) circ_evaluate(c, alphas, betas, c_star, s->mlm.q);
        circ_cleanup(c);
    }

//GET ALPHAS AND BETAS BACK TO ROOT! Maybe with a gather?


    if(rank==0){
	{
        mpz_t elems[2];
        // The C* encoding contains everything but the W_i symbols.
        // Here we calculate the appropriate indices and powers.
        for (int i = 0; i < n; ++i) {
            int deg;
            deg = PyLong_AsLong(PyList_GET_ITEM(py_xdegs, i));
            // X_i,0^deg(x_i)
            indices[2 * i] = 2 * i;
            pows[2 * i] = deg;
            // X_i,1^deg(x_i)
            indices[2 * i + 1] = 2 * i + 1;
            pows[2 * i + 1] = deg;
            // Z_i
            indices[2 * n + i] = 2 * n + i;
            pows[2 * n + i] = 1;
        }
        // Y^deg(y)
        indices[3 * n] = 4 * n;
        pows[3 * n] = ydeg;
        // Encode against these indices/powers
        mpz_init_set_ui(elems[0], 0);
        mpz_init_set(elems[1], c_star);
        clt_mlm_encode(&s->mlm, tmp, 2, elems, 3 * n + 1, indices, pows);
    }
    (void) write_element(s->dir, tmp, "c_star");
	}
    mpz_clears(c_star, tmp, NULL);
    fprintf(stderr,"QSIZE= %d\n",(mpz_sizeinbase(s->mlm.q, 2)));
    fprintf(stderr,"Process %d has finished its encoding work!\n",rank);

	MPI_Barrier(MPI_COMM_WORLD);

    Py_RETURN_NONE;
}
Exemplo n.º 15
0
int
main (void)
{
  FILE *out32 = fopen ("fpioconst-32", "w");
  if (out32 == NULL)
    abort ();
  FILE *out64 = fopen ("fpioconst-64", "w");
  if (out64 == NULL)
    abort ();
  FILE *outtable = fopen ("fpioconst-table", "w");
  if (outtable == NULL)
    abort ();
  mpz_t p;
  mpz_init (p);
  for (int i = 0; i <= 14; i++)
    {
      int j = 1 << i;
      mpz_ui_pow_ui (p, 10, j - 1);
      int exp_m = mpz_sizeinbase (p, 2);
      mpz_ui_pow_ui (p, 10, j);
      int exp_p = mpz_sizeinbase (p, 2);
      int size32 = 2 + (exp_p + 31) / 32;
      int size64 = 1 + (exp_p + 63) / 64;
      uint32_t data32[size32];
      uint64_t data64[size64];
      memset (data32, 0, sizeof data32);
      memset (data64, 0, sizeof data64);
      mpz_export (data32 + 2, NULL, -1, 4, 0, 0, p);
      mpz_export (data64 + 1, NULL, -1, 8, 0, 0, p);
      if (i == 0)
	{
	  fprintf (out32, "#define TENS_P%d_IDX\t0\n", i);
	  fprintf (out64, "#define TENS_P%d_IDX\t0\n", i);
	}
      else
	{
	  fprintf (out32, "#define TENS_P%d_IDX\t"
		   "(TENS_P%d_IDX + TENS_P%d_SIZE)\n",
		   i, i - 1, i - 1);
	  fprintf (out64, "#define TENS_P%d_IDX\t"
		   "(TENS_P%d_IDX + TENS_P%d_SIZE)\n",
		   i, i - 1, i - 1);
	}
      fprintf (out32, "#define TENS_P%d_SIZE\t%d\n", i, size32);
      fprintf (out64, "#define TENS_P%d_SIZE\t%d\n", i, size64);
      for (int k = 0; k < size32; k++)
	{
	  if (k == 0)
	    fprintf (out32, "  [TENS_P%d_IDX] = ", i);
	  else if (k % 6 == 5)
	    fprintf (out32, "\n  ");
	  else
	    fprintf (out32, " ");
	  fprintf (out32, "0x%08"PRIx32",", data32[k]);
	}
      for (int k = 0; k < size64; k++)
	{
	  if (k == 0)
	    fprintf (out64, "  [TENS_P%d_IDX] = ", i);
	  else if (k % 3 == 2)
	    fprintf (out64, "\n  ");
	  else
	    fprintf (out64, " ");
	  fprintf (out64, "0x%016"PRIx64"ull,", data64[k]);
	}
      fprintf (out32, "\n\n");
      fprintf (out64, "\n\n");
      const char *t = (i >= 10 ? "\t" : "\t\t");
      if (i == 0)
	fprintf (outtable, "  { TENS_P%d_IDX, TENS_P%d_SIZE,%s%d,\t      },\n",
		 i, i, t, exp_p);
      else
	fprintf (outtable, "  { TENS_P%d_IDX, TENS_P%d_SIZE,%s%d,\t%5d },\n",
		 i, i, t, exp_p, exp_m);
    }
  if (fclose (out32) != 0)
    abort ();
  if (fclose (out64) != 0)
    abort ();
  if (fclose (outtable) != 0)
    abort ();
  return 0;
}
Exemplo n.º 16
0
int main()
{
    unsigned int i,j,a,*SV;
    unsigned char logpi;
    int k,S,r,s1,s2,s,NS,logm,ptr,threshold,epri;
    long M,la,lptr;

    qsieve=gmpinit(-36,0);

    if(initv()<0) return 0;

    hmod=2*mlf+1;
    mpz_set_si(TA, hmod);
    while(!mpz_probab_prime_p(TA, qsieve->NTRY)) mpz_sub_ui(TA, TA, 2); //TT=不大于TT的素数
    hmod=qsieve_getsize(TA);
    hmod2=hmod-2;
    for(k=0;k<hmod;k++) hash[k]=(-1);

    M=50*(long)mm;
    NS=(int)(M/SSIZE);
    if(M%SSIZE!=0) NS++;
    M=SSIZE*(long)NS; // M为不小于50*mm的SSIZE的倍数中最小的 from 以上四行
    logm=0;
    la=M;
    while((la/=2)>0) logm++; // 以2为底
    rp[0]=logp[0]=0;
    for(k=1;k<=mm;k++) //求k*N在每个素数下的二次剩余解,与每个素数的ln(pi)
    {
        r=mpz_tdiv_q_ui(TA, D, epr[k]);
        rp[k]=qsieve_sqrmp(r,epr[k]);
        logp[k]=0;
        r=epr[k];
        while((r/=2)>0) logp[k]++;
    }

    r=mpz_tdiv_q_ui(TA, D, 8);
    if(r==5) logp[1]++;
    if(r==1) logp[1]+=2;

    threshold=logm+mpz_sizeinbase(R, 2)-2*logp[mm];

    jj=0;
    nlp=0;
    mpz_mul_si(DG, D, 2);
    mpz_root(DG, DG, 2);

    mpz_set_si(TA, M);
    qsieve_divide(DG,TA,DG);
    mpz_root(DG, DG, 2);
    if(mpz_tdiv_q_ui(TA, DG, 2)==0) mpz_add_ui(DG, DG, 1);
    if(mpz_tdiv_q_ui(TA, DG, 4)==1) mpz_add_ui(DG, DG, 2); // 令DG等于大于等于DG的数中模4余3的最小的数
    printf("  0%");

    while(1) //不断尝试新的多项式,可以并行计算
    {
        r=qsieve->NTRY;
        qsieve->NTRY=1;
        do
        {
            do {
               mpz_add_ui(DG, DG, 4);
            } while(!(mpz_probab_prime_p(DG, qsieve->NTRY) ? TRUE : FALSE));
            mpz_sub_ui(TA, DG, 1);
            mpz_tdiv_q_ui(TA, TA, 2);
            mpz_powm_sec(TA, D, TA, DG);
        } while(qsieve_getsize(TA)!=1); //直到DD是二次剩余
        qsieve->NTRY=r;
        mpz_add_ui(TA, DG, 1);
        mpz_tdiv_q_ui(TA, TA, 4);
        mpz_powm_sec(B, D, TA, DG);
        mpz_neg(TA, D);
        qsieve_muladddiv(B,B,TA,DG,TA,TA);
        mpz_neg(TA, TA);

        mpz_mul_si(A, B, 2);
        qsieve_extgcd(A,DG,A,A,A);
        qsieve_muladddiv(A,TA,TA,DG,DG,A);
        mpz_mul(TA, A, DG);
        mpz_add(B, B, TA);
        mpz_mul(A, DG, DG);
        qsieve_extgcd(DG,D,IG,IG,IG);
        
        r1[0]=r2[0]=0;
        for(k=1;k<=mm;k++) //s1和s2是两个解
        {
            s=mpz_tdiv_q_ui(TA, B, epr[k]);
            r=mpz_tdiv_q_ui(TA, A, epr[k]);
            r=qsieve_getinvers(r,epr[k]);

            s1=(epr[k]-s+rp[k]);
            s2=(epr[k]-s+epr[k]-rp[k]);
            if(s1 > s2)
            {
                int t = s1;
                s1 = s2;
                s2 = t;
            }
            r1[k]=(int)((((long long)s1)*((long long)r)) % ((long long)epr[k]));
            r2[k]=(int)((((long long)s2)*((long long)r)) % ((long long)epr[k]));
        }
        
        for(ptr=(-NS);ptr<NS;ptr++)
        {
            la=(long)ptr*SSIZE;
            SV=(unsigned int *)sieve;
            for(i=0; i<SSIZE/sizeof(int); i++) *SV++=0;
            for(k=1; k<=mm; k++)
            {
                epri=epr[k];
                logpi=logp[k];
                r=(int)(la%epri);
                s1=(r1[k]-r)%epri;
                if(s1<0) s1+=epri;
                s2=(r2[k]-r)%epri;
                if(s2<0) s2+=epri;

			/* 这部分是筛法的主要部分,数组下标表示多项式P(x)的参数x 
				s1与s2是两个P(x)=0(mod p)的解 */
                for(j=s1;j<SSIZE;j+=epri) sieve[j]+=logpi;
                if(s1==s2) continue;
                for(j=s2;j<SSIZE;j+=epri) sieve[j]+=logpi;
            }

            for(a=0;a<SSIZE;a++) //找那些没有被筛掉的数
            {
                if(sieve[a]<threshold) continue;
                lptr=la+a;
                mpz_set_si(TA, lptr);
                S=0;
                mpz_mul(TA, A, TA);
                mpz_add(TA, TA, B);
                qsieve_muladddiv(TA,IG,TA,D,D,P);
                if(qsieve_getsize(P)<0) mpz_add(P, P, D);
                qsieve_muladddiv(P,P,P,D,D,V);
                mpz_abs(TA, TA);
                if(qsieve_compare(TA,R)<0) S=1;
                if(S==1) mpz_sub(V, D, V);
                if(V!=TA) mpz_set(TA, V);
                e[0]=S;
                for(k=1;k<=mm;k++) e[k]=0;
                if(!factored(lptr,TA)) continue;
                if(gotcha())
                {
                    mpz_gcd(P, TA, N);
                    qsieve_getsize(P);
                    printf("\b\b\b\b100%\nFactors are\n");
                    qsieve_outnum(P,stdout);
                    qsieve_divide(N,P,N);
                    qsieve_outnum(N,stdout);
                    return 0;
                }
            }
        }
    }
    return 0;
}
Exemplo n.º 17
0
TYPE
SCM_TO_TYPE_PROTO (SCM val)
{
  if (SCM_I_INUMP (val))
    {
      scm_t_signed_bits n = SCM_I_INUM (val);
#if SIZEOF_TYPE != 0 && SIZEOF_TYPE > SIZEOF_SCM_T_BITS
      return n;
#else
      if (n >= TYPE_MIN && n <= TYPE_MAX)
	return n;
      else
	{
	  goto out_of_range;
	}
#endif
    }
  else if (SCM_BIGP (val))
    {
      if (TYPE_MIN >= SCM_MOST_NEGATIVE_FIXNUM
	  && TYPE_MAX <= SCM_MOST_POSITIVE_FIXNUM)
	goto out_of_range;
      else if (TYPE_MIN >= LONG_MIN && TYPE_MAX <= LONG_MAX)
	{
	  if (mpz_fits_slong_p (SCM_I_BIG_MPZ (val)))
	    {
	      long n = mpz_get_si (SCM_I_BIG_MPZ (val));
#if SIZEOF_TYPE != 0 && SIZEOF_TYPE > SCM_SIZEOF_LONG
	      return n;
#else
	      if (n >= TYPE_MIN && n <= TYPE_MAX)
		return n;
	      else
		goto out_of_range;
#endif
	    } 
	  else
	    goto out_of_range;
	}
      else
	{
	  scm_t_intmax n;
	  size_t count;

	  if (mpz_sizeinbase (SCM_I_BIG_MPZ (val), 2)
	      > CHAR_BIT*sizeof (scm_t_uintmax))
	    goto out_of_range;
	  
	  mpz_export (&n, &count, 1, sizeof (scm_t_uintmax), 0, 0,
		      SCM_I_BIG_MPZ (val));

	  if (mpz_sgn (SCM_I_BIG_MPZ (val)) >= 0)
	    {
	      if (n < 0)
		goto out_of_range;
	    }
	  else
	    {
	      n = -n;
	      if (n >= 0)
		goto out_of_range;
	    }

	  if (n >= TYPE_MIN && n <= TYPE_MAX)
	    return n;
	  else
	    {
	    out_of_range:
	      scm_i_range_error (val,
				 scm_from_signed_integer (TYPE_MIN),
				 scm_from_signed_integer (TYPE_MAX));
	      return 0;
	    }
	}
    }
  else
    {
      scm_wrong_type_arg_msg (NULL, 0, val, "exact integer");
      return 0;
    }
}
Exemplo n.º 18
0
int scanhash_m7hash(int thr_id, uint32_t *pdata, const uint32_t *ptarget,
    uint64_t max_nonce, unsigned long *hashes_done)
{
    uint32_t data[32] __attribute__((aligned(128)));
    uint32_t *data_p64 = data + (M7_MIDSTATE_LEN / sizeof(data[0]));
    uint32_t hash[8] __attribute__((aligned(32)));
    uint8_t bhash[7][64] __attribute__((aligned(32)));
    uint32_t hashtest[8] __attribute__((aligned(32)));
    uint32_t n = pdata[29] - 1;
    const uint32_t first_nonce = pdata[29];
    char data_str[245], hash_str[65], target_str[65];
    uint8_t *bdata = 0;
    mpz_t bns[7];
    int rc = 0;

    for(int i=0; i < 7; i++){
        mpz_init(bns[i]);
    }

    memcpy(data, pdata, 122);

    sph_sha256_context       ctx_final_sha256;

    sph_sha256_context       ctx_sha256;
    sph_sha512_context       ctx_sha512;
    sph_keccak512_context    ctx_keccak;
    sph_whirlpool_context    ctx_whirlpool;
    sph_haval256_5_context   ctx_haval;
    sph_tiger_context        ctx_tiger;
    sph_ripemd160_context    ctx_ripemd;

    sph_sha256_init(&ctx_sha256);
    sph_sha256 (&ctx_sha256, data, M7_MIDSTATE_LEN);
    
    sph_sha512_init(&ctx_sha512);
    sph_sha512 (&ctx_sha512, data, M7_MIDSTATE_LEN);
    
    sph_keccak512_init(&ctx_keccak);
    sph_keccak512 (&ctx_keccak, data, M7_MIDSTATE_LEN);

    sph_whirlpool_init(&ctx_whirlpool);
    sph_whirlpool (&ctx_whirlpool, data, M7_MIDSTATE_LEN);
    
    sph_haval256_5_init(&ctx_haval);
    sph_haval256_5 (&ctx_haval, data, M7_MIDSTATE_LEN);

    sph_tiger_init(&ctx_tiger);
    sph_tiger (&ctx_tiger, data, M7_MIDSTATE_LEN);

    sph_ripemd160_init(&ctx_ripemd);
    sph_ripemd160 (&ctx_ripemd, data, M7_MIDSTATE_LEN);

    sph_sha256_context       ctx2_sha256;
    sph_sha512_context       ctx2_sha512;
    sph_keccak512_context    ctx2_keccak;
    sph_whirlpool_context    ctx2_whirlpool;
    sph_haval256_5_context   ctx2_haval;
    sph_tiger_context        ctx2_tiger;
    sph_ripemd160_context    ctx2_ripemd;

    do {
        data[29] = ++n;

        memset(bhash, 0, 7 * 64);

        ctx2_sha256 = ctx_sha256;
        sph_sha256 (&ctx2_sha256, data_p64, 122 - M7_MIDSTATE_LEN);
        sph_sha256_close(&ctx2_sha256, (void*)(bhash[0]));

        ctx2_sha512 = ctx_sha512;
        sph_sha512 (&ctx2_sha512, data_p64, 122 - M7_MIDSTATE_LEN);
        sph_sha512_close(&ctx2_sha512, (void*)(bhash[1]));
        
        ctx2_keccak = ctx_keccak;
        sph_keccak512 (&ctx2_keccak, data_p64, 122 - M7_MIDSTATE_LEN);
        sph_keccak512_close(&ctx2_keccak, (void*)(bhash[2]));

        ctx2_whirlpool = ctx_whirlpool;
        sph_whirlpool (&ctx2_whirlpool, data_p64, 122 - M7_MIDSTATE_LEN);
        sph_whirlpool_close(&ctx2_whirlpool, (void*)(bhash[3]));
        
        ctx2_haval = ctx_haval;
        sph_haval256_5 (&ctx2_haval, data_p64, 122 - M7_MIDSTATE_LEN);
        sph_haval256_5_close(&ctx2_haval, (void*)(bhash[4]));

        ctx2_tiger = ctx_tiger;
        sph_tiger (&ctx2_tiger, data_p64, 122 - M7_MIDSTATE_LEN);
        sph_tiger_close(&ctx2_tiger, (void*)(bhash[5]));

        ctx2_ripemd = ctx_ripemd;
        sph_ripemd160 (&ctx2_ripemd, data_p64, 122 - M7_MIDSTATE_LEN);
        sph_ripemd160_close(&ctx2_ripemd, (void*)(bhash[6]));

        for(int i=0; i < 7; i++){
            set_one_if_zero(bhash[i]);
            mpz_set_uint512(bns[i],bhash[i]);
        }
        
        for(int i=6; i > 0; i--){
            mpz_mul(bns[i-1], bns[i-1], bns[i]);
        }

        int bytes = mpz_sizeinbase(bns[0], 256);
        bdata = (uint8_t *)realloc(bdata, bytes);
        mpz_export((void *)bdata, NULL, -1, 1, 0, 0, bns[0]);

        sph_sha256_init(&ctx_final_sha256);
        sph_sha256 (&ctx_final_sha256, bdata, bytes);
        sph_sha256_close(&ctx_final_sha256, (void*)(hash));

        rc = fulltest_m7hash(hash, ptarget);
        if (rc) {
            if (opt_debug) {
                bin2hex(hash_str, (unsigned char *)hash, 32);
                bin2hex(target_str, (unsigned char *)ptarget, 32);
                bin2hex(data_str, (unsigned char *)data, 122);
                applog(LOG_DEBUG, "DEBUG: [%d thread] Found share!\ndata   %s\nhash   %s\ntarget %s", thr_id, 
                    data_str,
                    hash_str,
                    target_str);
            }

            pdata[29] = data[29];

            goto out;
        }
    } while (n < max_nonce && !work_restart[thr_id].restart);

    pdata[29] = n;

out:
    for(int i=0; i < 7; i++){
        mpz_clear(bns[i]);
    }

    *hashes_done = n - first_nonce + 1;
    free(bdata);
    return rc;
}
Exemplo n.º 19
0
void factor_perfect_power(fact_obj_t *fobj, mpz_t b)
{
	// check if (b^1/i)^i == b for i = 2 to bitlen(b)
	uint32 bits = mpz_sizeinbase(b,2);
	uint32 i;
	FILE *flog;
	mpz_t base, ans;

	mpz_init(base);
	mpz_init(ans);

	//open the log file
	flog = fopen(fobj->flogname,"a");
	if (flog == NULL)
	{
		printf("fopen error: %s\n", strerror(errno));
		printf("could not open %s for writing\n",fobj->flogname);
		return;
	}

	for (i=2; i<bits; i++)
	{
		mpz_root(base, b, i);
		mpz_pow_ui(ans, base, i);
		if (mpz_cmp(ans, b) == 0)
		{
			// found a base.  				
			if (is_mpz_prp(base))
			{
				uint32 j;
				//gmp_printf("\nAdding prime base %Zd to factor list...\n", base);
				for (j=0; j<i; j++)
				{
					add_to_factor_list(fobj, base);
					mpz_tdiv_q(b, b, base);
					logprint(flog,"prp%d = %s\n",
						gmp_base10(base),
						mpz_conv2str(&gstr1.s, 10, base));
				}
			}
			else
			{
				// if composite, factor it and then multiply
				// all factors by i (the exponent).
				fact_obj_t *fobj_refactor;
				uint32 j;

				gmp_printf("\nFactoring composite base %Zd...\n", base);

				// load the new fobj with this number
				fobj_refactor = (fact_obj_t *)malloc(sizeof(fact_obj_t));
				init_factobj(fobj_refactor);
				mpz_set(fobj_refactor->N, base);

				// recurse on factor
				factor(fobj_refactor);

				// add all factors found during the refactorization
				for (j=0; j< fobj_refactor->num_factors; j++)
				{
					int k, c;
					//gmp_printf("\nAdding prime base %Zd to factor list...\n", 
					//	fobj_refactor->fobj_factors[j].factor);

					for (k=0; k < fobj_refactor->fobj_factors[j].count; k++)
					{
						// add i copies of it, since this was a perfect power
						for (c = 0; c < i; c++)
						{
							add_to_factor_list(fobj, fobj_refactor->fobj_factors[j].factor);
							mpz_tdiv_q(b, b, fobj_refactor->fobj_factors[j].factor);
							logprint(flog,"prp%d = %s\n",
								gmp_base10(fobj_refactor->fobj_factors[j].factor),
								mpz_conv2str(&gstr1.s, 10, fobj_refactor->fobj_factors[j].factor));
						}
					}
				}

				// free temps
				free_factobj(fobj_refactor);
				free(fobj_refactor);
			}
			break;
		}
	}

	mpz_clear(base);
	mpz_clear(ans);
	fclose(flog);

	return;
}
Exemplo n.º 20
0
unsigned
nettle_mpz_sizeinbase_256_u(const mpz_t x)
{
  return (mpz_sizeinbase(x,2) + 7) / 8;
}
Exemplo n.º 21
0
inline static int mpz_num_bytes(const mpz_t op)
{
	return (mpz_sizeinbase(op, 2) + 7) / 8;
}
Exemplo n.º 22
0
static int count_bits(void *a)
{
   LTC_ARGCHK(a != NULL);
   return mpz_sizeinbase(a, 2);
}
Exemplo n.º 23
0
int
rsa_generate_keypair(struct rsa_public_key *pub,
		     struct rsa_private_key *key,
		     void *random_ctx, nettle_random_func *random,
		     void *progress_ctx, nettle_progress_func *progress,
		     unsigned n_size,
		     unsigned e_size)
{
  mpz_t p1;
  mpz_t q1;
  mpz_t phi;
  mpz_t tmp;

  if (e_size)
    {
      /* We should choose e randomly. Is the size reasonable? */
      if ((e_size < 16) || (e_size >= n_size) )
	return 0;
    }
  else
    {
      /* We have a fixed e. Check that it makes sense */

      /* It must be odd */
      if (!mpz_tstbit(pub->e, 0))
	return 0;

      /* And 3 or larger */
      if (mpz_cmp_ui(pub->e, 3) < 0)
	return 0;

      /* And size less than n */
      if (mpz_sizeinbase(pub->e, 2) >= n_size)
	return 0;
    }

  if (n_size < RSA_MINIMUM_N_BITS)
    return 0;
  
  mpz_init(p1); mpz_init(q1); mpz_init(phi); mpz_init(tmp);

  /* Generate primes */
  for (;;)
    {
      /* Generate p, such that gcd(p-1, e) = 1 */
      for (;;)
	{
	  nettle_random_prime(key->p, (n_size+1)/2, 1,
			      random_ctx, random,
			      progress_ctx, progress);

	  mpz_sub_ui(p1, key->p, 1);
      
	  /* If e was given, we must chose p such that p-1 has no factors in
	   * common with e. */
	  if (e_size)
	    break;
	  
	  mpz_gcd(tmp, pub->e, p1);

	  if (mpz_cmp_ui(tmp, 1) == 0)
	    break;
	  else if (progress) progress(progress_ctx, 'c');
	} 

      if (progress)
	progress(progress_ctx, '\n');
      
      /* Generate q, such that gcd(q-1, e) = 1 */
      for (;;)
	{
	  nettle_random_prime(key->q, n_size/2, 1,
			      random_ctx, random,
			      progress_ctx, progress);

	  /* Very unlikely. */
	  if (mpz_cmp (key->q, key->p) == 0)
	    continue;

	  mpz_sub_ui(q1, key->q, 1);
      
	  /* If e was given, we must chose q such that q-1 has no factors in
	   * common with e. */
	  if (e_size)
	    break;
	  
	  mpz_gcd(tmp, pub->e, q1);

	  if (mpz_cmp_ui(tmp, 1) == 0)
	    break;
	  else if (progress) progress(progress_ctx, 'c');
	}

      /* Now we have the primes. Is the product of the right size? */
      mpz_mul(pub->n, key->p, key->q);

      assert (mpz_sizeinbase(pub->n, 2) == n_size);

      if (progress)
	progress(progress_ctx, '\n');

      /* c = q^{-1} (mod p) */
      if (mpz_invert(key->c, key->q, key->p))
	/* This should succeed everytime. But if it doesn't,
	 * we try again. */
	break;
      else if (progress) progress(progress_ctx, '?');
    }

  mpz_mul(phi, p1, q1);
  
  /* If we didn't have a given e, generate one now. */
  if (e_size)
    {
      int retried = 0;
      for (;;)
	{
	  nettle_mpz_random_size(pub->e,
				 random_ctx, random,
				 e_size);
	
	  /* Make sure it's odd and that the most significant bit is
	   * set */
	  mpz_setbit(pub->e, 0);
	  mpz_setbit(pub->e, e_size - 1);

	  /* Needs gmp-3, or inverse might be negative. */
	  if (mpz_invert(key->d, pub->e, phi))
	    break;

	  if (progress) progress(progress_ctx, 'e');
	  retried = 1;
	}
      if (retried && progress)
	progress(progress_ctx, '\n');	
    }
  else
    {
      /* Must always succeed, as we already that e
       * doesn't have any common factor with p-1 or q-1. */
      int res = mpz_invert(key->d, pub->e, phi);
      assert(res);
    }

  /* Done! Almost, we must compute the auxillary private values. */
  /* a = d % (p-1) */
  mpz_fdiv_r(key->a, key->d, p1);

  /* b = d % (q-1) */
  mpz_fdiv_r(key->b, key->d, q1);

  /* c was computed earlier */

  pub->size = key->size = (n_size + 7) / 8;
  assert(pub->size >= RSA_MINIMUM_N_OCTETS);
  
  mpz_clear(p1); mpz_clear(q1); mpz_clear(phi); mpz_clear(tmp);

  return 1;
}
Exemplo n.º 24
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 = xmalloc (factor_alloc * sizeof (*factor));
  rawfactor = xmalloc (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);
}
Exemplo n.º 25
0
/* If x^y is exactly representable (with maybe a larger precision than z),
   round it in z and return the (mpc) inexact flag in [0, 10].

   If x^y is not exactly representable, return -1.

   If intermediate computations lead to numbers of more than maxprec bits,
   then abort and return -2 (in that case, to avoid loops, mpc_pow_exact
   should be called again with a larger value of maxprec).

   Assume one of Re(x) or Im(x) is non-zero, and y is non-zero (y is real).
*/
static int
mpc_pow_exact (mpc_ptr z, mpc_srcptr x, mpfr_srcptr y, mpc_rnd_t rnd,
               mp_prec_t maxprec)
{
  mp_exp_t ec, ed, ey, emin, emax;
  mpz_t my, a, b, c, d, u;
  unsigned long int t;
  int ret = -2;

  mpz_init (my);
  mpz_init (a);
  mpz_init (b);
  mpz_init (c);
  mpz_init (d);
  mpz_init (u);

  ey = mpfr_get_z_exp (my, y);
  /* normalize so that my is odd */
  t = mpz_scan1 (my, 0);
  ey += t;
  mpz_tdiv_q_2exp (my, my, t);

  if (mpfr_zero_p (MPC_RE(x)))
    {
      mpz_set_ui (c, 0);
      ec = 0;
    }
  else
    ec = mpfr_get_z_exp (c, MPC_RE(x));
  if (mpfr_zero_p (MPC_IM(x)))
    {
      mpz_set_ui (d, 0);
      ed = ec;
    }
  else
    {
      ed = mpfr_get_z_exp (d, MPC_IM(x));
      if (mpfr_zero_p (MPC_RE(x)))
        ec = ed;
    }
  /* x = c*2^ec + I * d*2^ed */
  /* equalize the exponents of x */
  if (ec < ed)
    {
      mpz_mul_2exp (d, d, ed - ec);
      if (mpz_sizeinbase (d, 2) > maxprec)
        goto end;
      ed = ec;
    }
  else if (ed < ec)
    {
      mpz_mul_2exp (c, c, ec - ed);
      if (mpz_sizeinbase (c, 2) > maxprec)
        goto end;
      ec = ed;
    }
  /* now ec=ed and x = (c + I * d) * 2^ec */

  /* divide by two if possible */
  if (mpz_cmp_ui (c, 0) == 0)
    {
      t = mpz_scan1 (d, 0);
      mpz_tdiv_q_2exp (d, d, t);
      ec += t;
    }
  else if (mpz_cmp_ui (d, 0) == 0)
    {
      t = mpz_scan1 (c, 0);
      mpz_tdiv_q_2exp (c, c, t);
      ec += t;
    }
  else /* neither c nor d is zero */
    {
      unsigned long v;
      t = mpz_scan1 (c, 0);
      v = mpz_scan1 (d, 0);
      if (v < t)
        t = v;
      mpz_tdiv_q_2exp (c, c, t);
      mpz_tdiv_q_2exp (d, d, t);
      ec += t;
    }

  /* now either one of c, d is odd */

  while (ey < 0)
    {
      /* check if x is a square */
      if (ec & 1)
        {
          mpz_mul_2exp (c, c, 1);
          mpz_mul_2exp (d, d, 1);
          ec --;
        }
      /* now ec is even */
      if (mpc_perfect_square_p (a, b, c, d) == 0)
        break;
      mpz_swap (a, c);
      mpz_swap (b, d);
      ec /= 2;
      ey ++;
    }

  if (ey < 0)
    {
      ret = -1; /* not representable */
      goto end;
    }

  /* Now ey >= 0, it thus suffices to check that x^my is representable.
     If my > 0, this is always true. If my < 0, we first try to invert
     (c+I*d)*2^ec.
  */
  if (mpz_cmp_ui (my, 0) < 0)
    {
      /* If my < 0, 1 / (c + I*d) = (c - I*d)/(c^2 + d^2), thus a sufficient
         condition is that c^2 + d^2 is a power of two, assuming |c| <> |d|.
         Assume a prime p <> 2 divides c^2 + d^2,
         then if p does not divide c or d, 1 / (c + I*d) cannot be exact.
         If p divides both c and d, then we can write c = p*c', d = p*d',
         and 1 / (c + I*d) = 1/p * 1/(c' + I*d'). This shows that if 1/(c+I*d)
         is exact, then 1/(c' + I*d') is exact too, and we are back to the
         previous case. In conclusion, a necessary and sufficient condition
         is that c^2 + d^2 is a power of two.
      */
      /* FIXME: we could first compute c^2+d^2 mod a limb for example */
      mpz_mul (a, c, c);
      mpz_addmul (a, d, d);
      t = mpz_scan1 (a, 0);
      if (mpz_sizeinbase (a, 2) != 1 + t) /* a is not a power of two */
        {
          ret = -1; /* not representable */
          goto end;
        }
      /* replace (c,d) by (c/(c^2+d^2), -d/(c^2+d^2)) */
      mpz_neg (d, d);
      ec = -ec - t;
      mpz_neg (my, my);
    }

  /* now ey >= 0 and my >= 0, and we want to compute
     [(c + I * d) * 2^ec] ^ (my * 2^ey).

     We first compute [(c + I * d) * 2^ec]^my, then square ey times. */
  t = mpz_sizeinbase (my, 2) - 1;
  mpz_set (a, c);
  mpz_set (b, d);
  ed = ec;
  /* invariant: (a + I*b) * 2^ed = ((c + I*d) * 2^ec)^trunc(my/2^t) */
  while (t-- > 0)
    {
      unsigned long v, w;
      /* square a + I*b */
      mpz_mul (u, a, b);
      mpz_mul (a, a, a);
      mpz_submul (a, b, b);
      mpz_mul_2exp (b, u, 1);
      ed *= 2;
      if (mpz_tstbit (my, t)) /* multiply by c + I*d */
        {
          mpz_mul (u, a, c);
          mpz_submul (u, b, d); /* ac-bd */
          mpz_mul (b, b, c);
          mpz_addmul (b, a, d); /* bc+ad */
          mpz_swap (a, u);
          ed += ec;
        }
      /* remove powers of two in (a,b) */
      if (mpz_cmp_ui (a, 0) == 0)
        {
          w = mpz_scan1 (b, 0);
          mpz_tdiv_q_2exp (b, b, w);
          ed += w;
        }
      else if (mpz_cmp_ui (b, 0) == 0)
        {
          w = mpz_scan1 (a, 0);
          mpz_tdiv_q_2exp (a, a, w);
          ed += w;
        }
      else
        {
          w = mpz_scan1 (a, 0);
          v = mpz_scan1 (b, 0);
          if (v < w)
            w = v;
          mpz_tdiv_q_2exp (a, a, w);
          mpz_tdiv_q_2exp (b, b, w);
          ed += w;
        }
      if (mpz_sizeinbase (a, 2) > maxprec || mpz_sizeinbase (b, 2) > maxprec)
        goto end;
    }
  /* now a+I*b = (c+I*d)^my */

  while (ey-- > 0)
    {
      unsigned long sa, sb;

      /* square a + I*b */
      mpz_mul (u, a, b);
      mpz_mul (a, a, a);
      mpz_submul (a, b, b);
      mpz_mul_2exp (b, u, 1);
      ed *= 2;

      /* divide by largest 2^n possible, to avoid many loops for e.g.,
         (2+2*I)^16777216 */
      sa = mpz_scan1 (a, 0);
      sb = mpz_scan1 (b, 0);
      sa = (sa <= sb) ? sa : sb;
      mpz_tdiv_q_2exp (a, a, sa);
      mpz_tdiv_q_2exp (b, b, sa);
      ed += sa;

      if (mpz_sizeinbase (a, 2) > maxprec || mpz_sizeinbase (b, 2) > maxprec)
        goto end;
    }

  /* save emin, emax */
  emin = mpfr_get_emin ();
  emax = mpfr_get_emax ();
  mpfr_set_emin (mpfr_get_emin_min ());
  mpfr_set_emax (mpfr_get_emax_max ());
  ret = mpfr_set_z (MPC_RE(z), a, MPC_RND_RE(rnd));
  ret = MPC_INEX(ret, mpfr_set_z (MPC_IM(z), b, MPC_RND_IM(rnd)));
  mpfr_mul_2si (MPC_RE(z), MPC_RE(z), ed, MPC_RND_RE(rnd));
  mpfr_mul_2si (MPC_IM(z), MPC_IM(z), ed, MPC_RND_IM(rnd));
  /* restore emin, emax */
  mpfr_set_emin (emin);
  mpfr_set_emax (emax);

 end:
  mpz_clear (my);
  mpz_clear (a);
  mpz_clear (b);
  mpz_clear (c);
  mpz_clear (d);
  mpz_clear (u);

  return ret;
}
Exemplo n.º 26
0
int main() {
	srand(1337);

	// The primes we will perform trial division with on small integers.
	std::vector<uint32_t> primes;

	// Generate the trial division primes using a simple sieve.
	{
		uint32_t max = (uint32_t)ceil(sqrt(TRIAL_BOUND)) + 1;
		char *sieve = new char[max];
		memset(sieve, 1, max);
		for(uint32_t p = 2; p < max; ++p) {
			if(!sieve[p])
				continue;
			primes.push_back(p);
			for(uint32_t i = p; i < max; i += p)
				sieve[i] = 0;
		}
		delete[] sieve;
	}

	mpz_class N;

	// Read numbers to factor from stdin until EOF.
	while(std::cin >> N) {
		// This quadratic sieve implementation is designed to factor numbers no larger than 100 bits.
		if(mpz_sizeinbase(N.get_mpz_t(), 2) > 100) {
			std::cerr << N << " is too large\n" << std::endl;
			continue;
		}

		std::stack<mpz_class> factors;

		factors.push(N);

		while(!factors.empty()) {
			mpz_class factor = factors.top();
			factors.pop();

			// If the factor is prime, print it.
			if(mpz_probab_prime_p(factor.get_mpz_t(), 10)) {
				std::cout << factor << std::endl;
				continue;

			// Run trial division if factor is small.
			} else if(factor < TRIAL_BOUND) {
				uint32_t f = factor.get_ui();
				for(uint32_t p = 0; p < primes.size(); ++p) {
					if(f % primes[p] == 0) {
						factors.push(primes[p]);
						factors.push(factor / primes[p]);
						break;
					}
				}

			} else {
				// Before we run quadratic sieve, check for small factors.
				bool found_factor = false;
				for(uint32_t p = 0; p < primes.size(); ++p) {
					if(mpz_divisible_ui_p(factor.get_mpz_t(), primes[p])) {
						factors.push(primes[p]);
						factors.push(factor / primes[p]);
						found_factor = true;
						break;
					}
				}
				if(found_factor)
					continue;

				// Quadratic sieve doesn't handle perferct powers very well, handle those separately.
				if(mpz_perfect_power_p(factor.get_mpz_t())) {
					mpz_class root, rem;

					// Check root remainders up half of the amount of bits in factor.
					uint32_t max = mpz_sizeinbase(factor.get_mpz_t(), 2) / 2;
					for(uint32_t n = 2; n < max; ++n) {
						mpz_rootrem(root.get_mpz_t(), rem.get_mpz_t(), factor.get_mpz_t(), n);
						if(rem == 0) {
							// Push the n root factors.
							for(uint32_t i = 0; i < n; ++i)
								factors.push(root);
							break;
						}
					}

				} else {
					mpz_class f = quadratic_sieve(factor);

					factors.push(f);
					factors.push(factor / f);
				}
			}
		}

		std::cout << std::endl;
	}

	return 0;
}
Exemplo n.º 27
0
static PyObject *
GMPy_MPZ_is_aprcl_prime(PyObject *self, PyObject *other)
{
  mpz_t N;
  s64_t T, U;
  int i, j, H, I, J, K, P, Q, W, X;
  int IV, InvX, LEVELnow, NP, PK, PL, PM, SW, VK, TestedQs, TestingQs;
  int QQ, T1, T3, U1, U3, V1, V3;
  int break_this = 0;
  MPZ_Object *tempx;

  if (!(tempx = GMPy_MPZ_From_Integer(other, NULL))) {
    TYPE_ERROR("is_aprcl_prime() requires 'mpz' argument");
    return NULL;
  }

  mpz_init(N);
  mpz_set(N, tempx->z);
  Py_DECREF(tempx);

  /* make sure the input is >= 2 and odd */
  if (mpz_cmp_ui(N, 2) < 0)
    Py_RETURN_FALSE;

  if (mpz_divisible_ui_p(N, 2)) {
    if (mpz_cmp_ui(N, 2) == 0)
      Py_RETURN_TRUE;
    else
      Py_RETURN_FALSE;
  }

  /* only three small exceptions for this implementation */
  /* with this set of P and Q primes */
  if (mpz_cmp_ui(N, 3) == 0)
    Py_RETURN_TRUE;
  if (mpz_cmp_ui(N, 7) == 0)
    Py_RETURN_TRUE;
  if (mpz_cmp_ui(N, 11) == 0)
    Py_RETURN_TRUE;

  /* If the input number is larger than 7000 decimal digits
     we will just return whether it is a BPSW (probable) prime */
  NumberLength = mpz_sizeinbase(N, 10);
  if (NumberLength > 7000) {
      VALUE_ERROR("value too large to test");
      return NULL;
  }

  allocate_vars();

  mpz_set(TestNbr, N);
  mpz_set_si(biS, 0);

  j = PK = PL = PM = 0;
  for (J = 0; J < PWmax; J++) {
    /* aiJX[J] = 0; */
    mpz_set_ui(aiJX[J], 0);
  }
  break_this = 0;
/* GetPrimes2Test : */
  for (i = 0; i < LEVELmax; i++) {
    /* biS[0] = 2; */
    mpz_set_ui(biS, 2);

    for (j = 0; j < aiNQ[i]; j++) {
      Q = aiQ[j];
      if (aiT[i]%(Q-1) != 0)
        continue;
      U = aiT[i] * Q;
      do {
        U /= Q;
        /* MultBigNbrByLong(biS, Q, biS, NumberLength); */
        mpz_mul_ui(biS, biS, Q);
      } while (U % Q == 0);

      // Exit loop if S^2 > N.
      if (CompareSquare(biS, TestNbr) > 0) {
        /* break GetPrimes2Test; */
        break_this = 1;
        break;
      }
    } /* End for j */

    if (break_this) break;
  } /* End for i */

  if (i == LEVELmax)
  { /* too big */
    free_vars();
    VALUE_ERROR("value too large to test");
    return NULL;
  }
  LEVELnow = i;
  TestingQs = j;
  T = aiT[LEVELnow];
  NP = aiNP[LEVELnow];

MainStart:
  for (;;)
  {
    for (i = 0; i < NP; i++)
    {
      P = aiP[i];
      if (T%P != 0) continue;

      SW = TestedQs = 0;
      /* Q = W = (int) BigNbrModLong(TestNbr, P * P); */
      Q = W = mpz_fdiv_ui(TestNbr, P * P);
      for (J = P - 2; J > 0; J--)
      {
        W = (W * Q) % (P * P);
      }
      if (P > 2 && W != 1)
      {
        SW = 1;
      }
      for (;;)
      {
        for (j = TestedQs; j <= TestingQs; j++)
        {
          Q = aiQ[j] - 1;
          /* G = aiG[j]; */
          K = 0;
          while (Q % P == 0)
          {
            K++;
            Q /= P;
          }
          Q = aiQ[j];
          if (K == 0)
          {
            continue;
          }

          PM = 1;
          for (I = 1; I < K; I++)
          {
            PM = PM * P;
          }
          PL = (P - 1) * PM;
          PK = P * PM;
          for (I = 0; I < PK; I++)
          {
            /* aiJ0[I] = aiJ1[I] = 0; */
            mpz_set_ui(aiJ0[I], 0);
            mpz_set_ui(aiJ1[I], 0);
          }
          if (P > 2)
          {
            JacobiSum(0, P, PL, Q);
          }
          else
          {
            if (K != 1)
            {
              JacobiSum(0, P, PL, Q);
              for (I = 0; I < PK; I++)
              {
                /* aiJW[I] = 0; */
                mpz_set_ui(aiJW[I], 0);
              }
              if (K != 2)
              {
                for (I = 0; I < PM; I++)
                {
                  /* aiJW[I] = aiJ0[I]; */
                  mpz_set(aiJW[I], aiJ0[I]);
                }
                JacobiSum(1, P, PL, Q);
                for (I = 0; I < PM; I++)
                {
                  /* aiJS[I] = aiJ0[I]; */
                  mpz_set(aiJS[I], aiJ0[I]);
                }
                JS_JW(PK, PL, PM, P);
                for (I = 0; I < PM; I++)
                {
                  /* aiJ1[I] = aiJS[I]; */
                  mpz_set(aiJ1[I], aiJS[I]);
                }
                JacobiSum(2, P, PL, Q);
                for (I = 0; I < PK; I++)
                {
                  /* aiJW[I] = 0; */
                  mpz_set_ui(aiJW[I], 0);
                }
                for (I = 0; I < PM; I++)
                {
                  /* aiJS[I] = aiJ0[I]; */
                  mpz_set(aiJS[I], aiJ0[I]);
                }
                JS_2(PK, PL, PM, P);
                for (I = 0; I < PM; I++)
                {
                  /* aiJ2[I] = aiJS[I]; */
                  mpz_set(aiJ2[I], aiJS[I]);
                }
              }
            }
          }
          /* aiJ00[0] = aiJ01[0] = 1; */
          mpz_set_ui(aiJ00[0], 1);
          mpz_set_ui(aiJ01[0], 1);
          for (I = 1; I < PK; I++)
          {
            /* aiJ00[I] = aiJ01[I] = 0; */
            mpz_set_ui(aiJ00[I], 0);
            mpz_set_ui(aiJ01[I], 0);
          }
          /* VK = (int) BigNbrModLong(TestNbr, PK); */
          VK = mpz_fdiv_ui(TestNbr, PK);
          for (I = 1; I < PK; I++)
          {
            if (I % P != 0)
            {
              U1 = 1;
              U3 = I;
              V1 = 0;
              V3 = PK;
              while (V3 != 0)
              {
                QQ = U3 / V3;
                T1 = U1 - V1 * QQ;
                T3 = U3 - V3 * QQ;
                U1 = V1;
                U3 = V3;
                V1 = T1;
                V3 = T3;
              }
              aiInv[I] = (U1 + PK) % PK;
            }
            else
            {
              aiInv[I] = 0;
            }
          }
          if (P != 2)
          {
            for (IV = 0; IV <= 1; IV++)
            {
              for (X = 1; X < PK; X++)
              {
                for (I = 0; I < PK; I++)
                {
                  /* aiJS[I] = aiJ0[I]; */
                  mpz_set(aiJS[I], aiJ0[I]);
                }
                if (X % P == 0)
                {
                  continue;
                }
                if (IV == 0)
                {
                  /* LongToBigNbr(X, biExp, NumberLength); */
                  mpz_set_ui(biExp, X);
                }
                else
                {
                  /* LongToBigNbr(VK * X / PK, biExp, NumberLength); */
                  mpz_set_ui(biExp, (VK * X) / PK);
                  if ((VK * X) / PK == 0)
                  {
                    continue;
                  }
                }
                JS_E(PK, PL, PM, P);
                for (I = 0; I < PK; I++)
                {
                  /* aiJW[I] = 0; */
                  mpz_set_ui(aiJW[I], 0);
                }
                InvX = aiInv[X];
                for (I = 0; I < PK; I++)
                {
                  J = (I * InvX) % PK;
                  /* AddBigNbrModN(aiJW[J], aiJS[I], aiJW[J], TestNbr, NumberLength); */
                  mpz_add(aiJW[J], aiJW[J], aiJS[I]);
                }
                NormalizeJW(PK, PL, PM, P);
                if (IV == 0)
                {
                  for (I = 0; I < PK; I++)
                  {
                    /* aiJS[I] = aiJ00[I]; */
                    mpz_set(aiJS[I], aiJ00[I]);
                  }
                }
                else
                {
                  for (I = 0; I < PK; I++)
                  {
                    /* aiJS[I] = aiJ01[I]; */
                    mpz_set(aiJS[I], aiJ01[I]);
                  }
                }
                JS_JW(PK, PL, PM, P);
                if (IV == 0)
                {
                  for (I = 0; I < PK; I++)
                  {
                    /* aiJ00[I] = aiJS[I]; */
                    mpz_set(aiJ00[I], aiJS[I]);
                  }
                }
                else
                {
                  for (I = 0; I < PK; I++)
                  {
                    /* aiJ01[I] = aiJS[I]; */
                    mpz_set(aiJ01[I], aiJS[I]);
                  }
                }
              } /* end for X */
            } /* end for IV */
          }
          else
          {
            if (K == 1)
            {
              /* MultBigNbrByLongModN(1, Q, aiJ00[0], TestNbr, NumberLength); */
              mpz_set_ui(aiJ00[0], Q);
              /* aiJ01[0] = 1; */
              mpz_set_ui(aiJ01[0], 1);
            }
            else
            {
              if (K == 2)
              {
                if (VK == 1)
                {
                  /* aiJ01[0] = 1; */
                  mpz_set_ui(aiJ01[0], 1);
                }
                /* aiJS[0] = aiJ0[0]; */
                /* aiJS[1] = aiJ0[1]; */
                mpz_set(aiJS[0], aiJ0[0]);
                mpz_set(aiJS[1], aiJ0[1]);
                JS_2(PK, PL, PM, P);
                if (VK == 3)
                {
                  /* aiJ01[0] = aiJS[0]; */
                  /* aiJ01[1] = aiJS[1]; */
                  mpz_set(aiJ01[0], aiJS[0]);
                  mpz_set(aiJ01[1], aiJS[1]);
                }
                /* MultBigNbrByLongModN(aiJS[0], Q, aiJ00[0], TestNbr, NumberLength); */
                mpz_mul_ui(aiJ00[0], aiJS[0], Q);
                /* MultBigNbrByLongModN(aiJS[1], Q, aiJ00[1], TestNbr, NumberLength); */
                mpz_mul_ui(aiJ00[1], aiJS[1], Q);
              }
              else
              {
                for (IV = 0; IV <= 1; IV++)
                {
                  for (X = 1; X < PK; X += 2)
                  {
                    for (I = 0; I <= PM; I++)
                    {
                      /* aiJS[I] = aiJ1[I]; */
                      mpz_set(aiJS[I], aiJ1[I]);
                    }
                    if (X % 8 == 5 || X % 8 == 7)
                    {
                      continue;
                    }
                    if (IV == 0)
                    {
                      /* LongToBigNbr(X, biExp, NumberLength); */
                      mpz_set_ui(biExp, X);
                    }
                    else
                    {
                      /* LongToBigNbr(VK * X / PK, biExp, NumberLength); */
                      mpz_set_ui(biExp, VK * X / PK);
                      if (VK * X / PK == 0)
                      {
                        continue;
                      }
                    }
                    JS_E(PK, PL, PM, P);
                    for (I = 0; I < PK; I++)
                    {
                      /* aiJW[I] = 0; */
                      mpz_set_ui(aiJW[I], 0);
                    }
                    InvX = aiInv[X];
                    for (I = 0; I < PK; I++)
                    {
                      J = I * InvX % PK;
                      /* AddBigNbrModN(aiJW[J], aiJS[I], aiJW[J], TestNbr, NumberLength); */
                      mpz_add(aiJW[J], aiJW[J], aiJS[I]);
                    }
                    NormalizeJW(PK, PL, PM, P);
                    if (IV == 0)
                    {
                      for (I = 0; I < PK; I++)
                      {
                        /* aiJS[I] = aiJ00[I]; */
                        mpz_set(aiJS[I], aiJ00[I]);
                      }
                    }
                    else
                    {
                      for (I = 0; I < PK; I++)
                      {
                        /* aiJS[I] = aiJ01[I]; */
                        mpz_set(aiJS[I], aiJ01[I]);
                      }
                    }
                    NormalizeJS(PK, PL, PM, P);
                    JS_JW(PK, PL, PM, P);
                    if (IV == 0)
                    {
                      for (I = 0; I < PK; I++)
                      {
                        /* aiJ00[I] = aiJS[I]; */
                        mpz_set(aiJ00[I], aiJS[I]);
                      }
                    }
                    else
                    {
                      for (I = 0; I < PK; I++)
                      {
                        /* aiJ01[I] = aiJS[I]; */
                        mpz_set(aiJ01[I], aiJS[I]);
                      }
                    }
                  } /* end for X */
                  if (IV == 0 || VK % 8 == 1 || VK % 8 == 3)
                  {
                    continue;
                  }
                  for (I = 0; I < PM; I++)
                  {
                    /* aiJW[I] = aiJ2[I]; */
                    /* aiJS[I] = aiJ01[I]; */
                    mpz_set(aiJW[I], aiJ2[I]);
                    mpz_set(aiJS[I], aiJ01[I]);
                  }
                  for (; I < PK; I++)
                  {
                    /* aiJW[I] = aiJS[I] = 0; */
                    mpz_set_ui(aiJW[I], 0);
                    mpz_set_ui(aiJS[I], 0);
                  }
                  JS_JW(PK, PL, PM, P);
                  for (I = 0; I < PM; I++)
                  {
                    /* aiJ01[I] = aiJS[I]; */
                    mpz_set(aiJ01[I], aiJS[I]);
                  }
                } /* end for IV */
              }
            }
          }
          for (I = 0; I < PL; I++)
          {
            /* aiJS[I] = aiJ00[I]; */
            mpz_set(aiJS[I], aiJ00[I]);
          }
          for (; I < PK; I++)
          {
            /* aiJS[I] = 0; */
            mpz_set_ui(aiJS[I], 0);
          }
          /* DivBigNbrByLong(TestNbr, PK, biExp, NumberLength); */
          mpz_fdiv_q_ui(biExp, TestNbr, PK);
          JS_E(PK, PL, PM, P);
          for (I = 0; I < PK; I++)
          {
            /* aiJW[I] = 0; */
            mpz_set_ui(aiJW[I], 0);
          }
          for (I = 0; I < PL; I++)
          {
            for (J = 0; J < PL; J++)
            {
              /* MontgomeryMult(aiJS[I], aiJ01[J], biTmp); */
              /* AddBigNbrModN(biTmp, aiJW[(I + J) % PK], aiJW[(I + J) % PK], TestNbr, NumberLength); */
              mpz_mul(biTmp, aiJS[I], aiJ01[J]);
              mpz_add(aiJW[(I + J) % PK], biTmp, aiJW[(I + J) % PK]);
            }
          }
          NormalizeJW(PK, PL, PM, P);
/* MatchingRoot : */
          do
          {
            H = -1;
            W = 0;
            for (I = 0; I < PL; I++)
            {
              if (mpz_cmp_ui(aiJW[I], 0) != 0)/* (!BigNbrIsZero(aiJW[I])) */
              {
                /* if (H == -1 && BigNbrAreEqual(aiJW[I], 1)) */
                if (H == -1 && (mpz_cmp_ui(aiJW[I], 1) == 0))
                {
                  H = I;
                }
                else
                {
                  H = -2;
                  /* AddBigNbrModN(aiJW[I], MontgomeryMultR1, biTmp, TestNbr, NumberLength); */
                  mpz_add_ui(biTmp, aiJW[I], 1);
                  mpz_mod(biTmp, biTmp, TestNbr);
                  if (mpz_cmp_ui(biTmp, 0) == 0) /* (BigNbrIsZero(biTmp)) */
                  {
                    W++;
                  }
                }
              }
            }
            if (H >= 0)
            {
              /* break MatchingRoot; */
              break;
            }
            if (W != P - 1)
            {
              /* Not prime */
              free_vars();
              Py_RETURN_FALSE;
            }
            for (I = 0; I < PM; I++)
            {
              /* AddBigNbrModN(aiJW[I], 1, biTmp, TestNbr, NumberLength); */
              mpz_add_ui(biTmp, aiJW[I], 1);
              mpz_mod(biTmp, biTmp, TestNbr);
              if (mpz_cmp_ui(biTmp, 0) == 0) /* (BigNbrIsZero(biTmp)) */
              {
                break;
              }
            }
            if (I == PM)
            {
              /* Not prime */
              free_vars();
              Py_RETURN_FALSE;
            }
            for (J = 1; J <= P - 2; J++)
            {
              /* AddBigNbrModN(aiJW[I + J * PM], 1, biTmp, TestNbr, NumberLength); */
              mpz_add_ui(biTmp, aiJW[I + J * PM], 1);
              mpz_mod(biTmp, biTmp, TestNbr);
              if (mpz_cmp_ui(biTmp, 0) != 0)/* (!BigNbrIsZero(biTmp)) */
              {
                /* Not prime */
                free_vars();
                Py_RETURN_FALSE;
              }
            }
            H = I + PL;
          }
          while (0);

          if (SW == 1 || H % P == 0)
          {
            continue;
          }
          if (P != 2)
          {
            SW = 1;
            continue;
          }
          if (K == 1)
          {
            if ((mpz_get_ui(TestNbr) & 3) == 1)
            {
              SW = 1;
            }
            continue;
          }

          // if (Q^((N-1)/2) mod N != N-1), N is not prime.

          /* MultBigNbrByLongModN(1, Q, biTmp, TestNbr, NumberLength); */
          mpz_set_ui(biTmp, Q);
          mpz_mod(biTmp, biTmp, TestNbr);

          mpz_sub_ui(biT, TestNbr, 1); /* biT = n-1 */
          mpz_divexact_ui(biT, biT, 2); /* biT = (n-1)/2 */
          mpz_powm(biR, biTmp, biT, TestNbr); /* biR = Q^((n-1)/2) mod n */
          mpz_add_ui(biTmp, biR, 1);
          mpz_mod(biTmp, biTmp, TestNbr);

          if (mpz_cmp_ui(biTmp, 0) != 0)/* (!BigNbrIsZero(biTmp)) */
          {
            /* Not prime */
            free_vars();
            Py_RETURN_FALSE;
          }
          SW = 1;
        } /* end for j */
        if (SW == 0)
        {
          TestedQs = TestingQs + 1;
          if (TestingQs < aiNQ[LEVELnow] - 1)
          {
            TestingQs++;
            Q = aiQ[TestingQs];
            U = T * Q;
            do
            {
              /* MultBigNbrByLong(biS, Q, biS, NumberLength); */
              mpz_mul_ui(biS, biS, Q);
              U /= Q;
            }
            while (U % Q == 0);

            continue; /* Retry */
          }
          LEVELnow++;
          if (LEVELnow == LEVELmax)
          {
            free_vars();
            // return mpz_bpsw_prp(N); /* Cannot tell */
            VALUE_ERROR("maximum levels reached");
            return NULL;
          }
          T = aiT[LEVELnow];
          NP = aiNP[LEVELnow];
          /* biS = 2; */
          mpz_set_ui(biS, 2);
          for (J = 0; J <= aiNQ[LEVELnow]; J++)
          {
            Q = aiQ[J];
            if (T%(Q-1) != 0) continue;
            U = T * Q;
            do
            {
              /* MultBigNbrByLong(biS, Q, biS, NumberLength); */
              mpz_mul_ui(biS, biS, Q);
              U /= Q;
            }
            while (U % Q == 0);
            if (CompareSquare(biS, TestNbr) > 0)
            {
              TestingQs = J;
              /* continue MainStart; */ /* Retry from the beginning */
              goto MainStart;
            }
          } /* end for J */
          free_vars();
          VALUE_ERROR("internal failure");
          return NULL;
        } /* end if */
        break;
      } /* end for (;;) */
    } /* end for i */

    // Final Test

    /* biR = 1 */
    mpz_set_ui(biR, 1);
    /* biN <- TestNbr mod biS */ /* Compute N mod S */
    mpz_fdiv_r(biN, TestNbr, biS);

    for (U = 1; U <= T; U++)
    {
      /* biR <- (biN * biR) mod biS */
      mpz_mul(biR, biN, biR);
      mpz_mod(biR, biR, biS);
      if (mpz_cmp_ui(biR, 1) == 0) /* biR == 1 */
      {
        /* Number is prime */
        free_vars();
        Py_RETURN_TRUE;
      }
      if (mpz_divisible_p(TestNbr, biR) && mpz_cmp(biR, TestNbr) < 0) /* biR < N and biR | TestNbr */
      {
        /* Number is composite */
        free_vars();
        Py_RETURN_FALSE;
      }
    } /* End for U */
    /* This should never be reached. */
    free_vars();
    SYSTEM_ERROR("Internal error: APR-CL error with final test.");
    return NULL;
  }
}
Exemplo n.º 28
0
// A quadratic sieve implementation for integers up to 100 bits. N must be composite.
mpz_class quadratic_sieve(mpz_class &N) {
	std::vector<uint32_t> factor_base;

	mpz_class sqrt_N = sqrt(N);
	//const unsigned long sqrt_N_long = sqrt_N.get_ui();

	// Set the smoothness bound.
	uint32_t B;
	{
		// Approximation of the natural logarithm of N.
		float log_N = mpz_sizeinbase(N.get_mpz_t(), 2) * log(2);

		// The optimal smoothness bound is exp((0.5 + o(1)) * sqrt(log(n)*log(log(n)))).
		B = (uint32_t)ceil(exp(0.56 * sqrt(log_N * log(log_N)))) + 300;
	}

	// Generate the factor base using a sieve.
	{
		char *sieve = new char[B + 1];
		memset(sieve, 1, B + 1);
		for(unsigned long p = 2; p <= B; ++p) {
			if(!sieve[p])
				continue;

			if(mpz_legendre(N.get_mpz_t(), mpz_class(p).get_mpz_t()) == 1)
				factor_base.push_back(p);

			for(unsigned long i = p; i <= B; i += p)
				sieve[i] = 0;
		}
		delete[] sieve;
	}

	std::vector<uint32_t> X;
	float *Y = new float[SIEVE_CHUNK];

	std::vector<std::vector<uint32_t> > smooth;

	int fails = 0;

	// The sieve boundary.
	uint32_t min_x = 0;
	uint32_t max_x = SIEVE_CHUNK;

	// Calculate sieve index (where to start the sieve) for each factor base number.
	uint32_t **fb_indexes = new uint32_t*[2];
	fb_indexes[0] = new uint32_t[factor_base.size()];
	fb_indexes[1] = new uint32_t[factor_base.size()];
	for(uint32_t p = 0; p < factor_base.size(); ++p) {
		// At what indexes do we start this sieve? Solve the congruence x^2 = n (mod p) to find out.
		// Results in two solutions, so we do two sieve iterations for each prime in the factor base.
		uint32_t idxs[2];
		mpz_class temp = N % mpz_class(factor_base[p]);
		tonelli_shanks(temp.get_ui(), factor_base[p], idxs);

		temp = idxs[0] - sqrt_N;
		temp = ((temp % factor_base[p]) + factor_base[p]) % factor_base[p];
		fb_indexes[0][p] = temp.get_ui();

		temp = idxs[1] - sqrt_N;
		temp = ((temp % factor_base[p]) + factor_base[p]) % factor_base[p];
		fb_indexes[1][p] = temp.get_ui();
	}

	float last_estimate = 0;
	uint32_t next_estimate = 1;

	// Sieve new chunks until we have enough smooth numbers.
	while(smooth.size() < (factor_base.size() + 20)) {
		// Generate our Y vector for the sieve, containing log approximations that fit in machine words.
		for(uint32_t t = 1; t < SIEVE_CHUNK; ++t) {
			// Calculating a log estimate is expensive, so don't do it for every Y[t].
			if(next_estimate <= (t + min_x)) {
				mpz_class y = (sqrt_N + t + min_x) * (sqrt_N + t + min_x) - N;

				// To estimate the 2 logarithm, just count the number of bits that v takes up.
				last_estimate = mpz_sizeinbase(y.get_mpz_t(), 2);

				// The higher t gets, the less the logarithm of Y[t] changes.
				next_estimate = next_estimate * 1.8 + 1;
			}

			Y[t] = last_estimate;
		}

		// Perform the actual sieve.
		for(uint32_t p = 0; p < factor_base.size(); ++p) {
			float lg = log(factor_base[p]) / log(2);

			for(uint32_t t = 0; t < 2; ++t) {
				while(fb_indexes[t][p] < max_x) {
					Y[fb_indexes[t][p] - min_x] -= lg;
					fb_indexes[t][p] += factor_base[p];
				}

				// p = 2 only has one modular root.
				if(factor_base[p] == 2)
					break;
			}
		}

		// Factor all values whose logarithms were reduced to approximately zero using trial division.
		{
			float threshold = log(factor_base.back()) / log(2);
			for(uint32_t i = 0; i < SIEVE_CHUNK; ++i) {
				if(fabs(Y[i]) < threshold) {
					mpz_class y = (sqrt_N + i + min_x) * (sqrt_N + i + min_x) - N;
					smooth.push_back(std::vector<uint32_t>());

					for(uint32_t p = 0; p < factor_base.size(); ++p) {
						while(mpz_divisible_ui_p(y.get_mpz_t(), factor_base[p])) {
							mpz_divexact_ui(y.get_mpz_t(), y.get_mpz_t(), factor_base[p]);
							smooth.back().push_back(p);
						}
					}

					if(y == 1) {
						// This V was indeed B-smooth.
						X.push_back(i + min_x);
						
						// Break out of trial division loop if we've found enou	gh smooth numbers.
						if(smooth.size() >= (factor_base.size() + 20))
							break;
					} else {
						// This V was apparently not B-smooth, remove it.
						smooth.pop_back();
						++fails;
					}
				}
			}
		}

		min_x += SIEVE_CHUNK;
		max_x += SIEVE_CHUNK;
	}

	uint64_t **matrix = new uint64_t*[factor_base.size()];

	// The amount of words needed to accomodate a row in the augmented matrix.
	int row_words = (smooth.size() + sizeof(uint64_t)) / sizeof(uint64_t);

	for(uint32_t i = 0; i < factor_base.size(); ++i) {
		matrix[i] = new uint64_t[row_words];
		memset(matrix[i], 0, row_words * sizeof(uint64_t));
	}

	for(uint32_t s = 0; s < smooth.size(); ++s) {
		// For each factor in the smooth number, add the factor to the corresponding element in the matrix.
		for(uint32_t p = 0; p < smooth[s].size(); ++p)
			toggle_bit(s, matrix[smooth[s][p]]);
	}

	// Gauss elimination. The dimension of the augmented matrix is factor_base.size() x (smooth.size() + 1).
	{
		uint32_t i = 0, j = 0;
		while(i < factor_base.size() && j < (smooth.size() + 1)) {
			uint32_t maxi = i;

			// Find pivot element.
			for(uint32_t k = i + 1; k < factor_base.size(); ++k) {
				if(get_bit(j, matrix[k]) == 1) {
					maxi = k;
					break;
				}
			}
			if(get_bit(j, matrix[maxi]) == 1) {
				std::swap(matrix[i], matrix[maxi]);
				
				for(uint32_t u = i + 1; u < factor_base.size(); ++u) {
					if(get_bit(j, matrix[u]) == 1) {
						for(int32_t w = 0; w < row_words; ++w)
							matrix[u][w] ^= matrix[i][w];
					}
				}
				++i;
			}
			++j;
		}
	}

	mpz_class a;
	mpz_class b;

	// A copy of matrix that we'll perform back-substitution on.
	uint64_t **back_matrix = new uint64_t*[factor_base.size()];
	for(uint32_t i = 0; i < factor_base.size(); ++i)
		back_matrix[i] = new uint64_t[row_words];

	uint32_t *x = new uint32_t[smooth.size()];

	uint32_t *combination = new uint32_t[factor_base.size()];

	// Loop until we've found a non-trivial factor.
	do {
		// Copy the gauss eliminated matrix.
		for(uint32_t i = 0; i < factor_base.size(); ++i)
			memcpy(back_matrix[i], matrix[i], row_words * sizeof(uint64_t));

		// Clear the x vector.
		memset(x, 0, smooth.size() * sizeof(uint32_t));

		// Perform back-substitution on our matrix that's now in row echelon form to get x.
		{
			int32_t i = factor_base.size() - 1;

			while(i >= 0) {
				// Count non-zero elements in current row.
				int32_t count = 0;
				int32_t current = -1;
				for(uint32_t c = 0; c < smooth.size(); ++c) {
					count += get_bit(c, back_matrix[i]);
					current = get_bit(c, back_matrix[i]) ? c : current;
				}

				// Empty row, advance to next.
				if(count == 0) {
					--i;
					continue;
				}

				// The system is underdetermined and we can choose x[current] freely.
				// To avoid the trivial solution we avoid always setting it to 0.
				uint32_t val = count > 1 ? rand() % 2 : get_bit(smooth.size(), back_matrix[i]);

				x[current] = val;

				for(int32_t u = 0; u <= i; ++u) {
					if(get_bit(current, back_matrix[u]) == 1) {
						if(val == 1)
							toggle_bit(smooth.size(), back_matrix[u]);
						unset_bit(current, back_matrix[u]);
					}
				}

				if(count == 1)
					--i;
			}
		}

		a = 1;
		b = 1;

		// The way to combine the factor base to get our square.
		memset(combination, 0, sizeof(uint32_t) * factor_base.size());
		for(uint32_t i = 0; i < smooth.size(); ++i) {
			if(x[i] == 1) {
				for(uint32_t p = 0; p < smooth[i].size(); ++p)
					++combination[smooth[i][p]];
				b *= (X[i] + sqrt_N);
			}
		}

		for(uint32_t p = 0; p < factor_base.size(); ++p) {
			for(uint32_t i = 0; i < (combination[p] / 2); ++i)
				a *= factor_base[p];
		}

		// If a = +/- b (mod N) we found a trivial factor, run the loop again to find a new a and b.
	} while(a % N == b % N || a % N == (- b) % N + N);

	b -= a;

	mpz_class factor;
	mpz_gcd(factor.get_mpz_t(), b.get_mpz_t(), N.get_mpz_t());

	for(uint32_t i = 0; i < factor_base.size(); ++i) {
		delete[] matrix[i];
		delete[] back_matrix[i];
	}

	delete[] combination;
	delete[] Y;
	delete[] fb_indexes[0];
	delete[] fb_indexes[1];
	delete[] fb_indexes;
	delete[] matrix;
	delete[] back_matrix;
	delete[] x;

	return factor;
}
Exemplo n.º 29
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)
    {
      if (mpz_cmpabs_ui (n, 1000000L) <= 0)
	{
	  int is_prime;
	  unsigned long n0;
	  n0 = mpz_get_ui (n);
	  is_prime = n0 & (n0 > 1) ? isprime (n0) : n0 == 2;
	  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_even_p (n))
    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 GMP_LIMB_BITS >= 4
      || r % 5 == 0
#endif
#if GMP_LIMB_BITS >= 8
      || r % 7 == 0
#endif
#if GMP_LIMB_BITS >= 16
      || r % 11 == 0 || r % 13 == 0
#endif
#if GMP_LIMB_BITS >= 32
      || r % 17 == 0 || r % 19 == 0 || r % 23 == 0 || r % 29 == 0
#endif
#if GMP_LIMB_BITS >= 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);
}
Exemplo n.º 30
0
Arquivo: sing.c Projeto: blynn/pbc
static void miller(element_t res, element_t P, element_t Q, element_t R, int n)
{
    //collate divisions
    mp_bitcnt_t m;
    element_t v, vd;
    element_t Z;
    element_t a, b, c;
    element_t e0, e1;
    mpz_t q;
    element_ptr Zx, Zy;
    const element_ptr Px = curve_x_coord(P);
    const element_ptr Py = curve_y_coord(P);
    const element_ptr numx = curve_x_coord(Q);
    const element_ptr numy = curve_y_coord(Q);
    const element_ptr denomx = curve_x_coord(R);
    const element_ptr denomy = curve_y_coord(R);

    #define do_vertical(e, edenom) {         \
        element_sub(e0, numx, Zx);           \
        element_mul((e), (e), e0);           \
                                             \
        element_sub(e0, denomx, Zx);         \
        element_mul((edenom), (edenom), e0); \
    }

    #define do_tangent(e, edenom) {                  \
        /*a = -slope_tangent(A.x, A.y);              \
          b = 1;                                     \
          c = -(A.y + a * A.x);                      \
          but we multiply by 2*A.y to avoid division \
                                                     \
          a = -Ax * (Ax + Ax + Ax + twicea_2) - a_4; \
          This curve is special:                     \
          a = -(3 Ax^2 + 2Ax)                        \
          b = 2 * Ay                                 \
          c = -(2 Ay^2 + a Ax);                   */ \
                                                     \
        if (element_is0(Zy)) {                       \
            do_vertical((e), (edenom));              \
        } else {                                     \
          element_square(a, Zx);                     \
          element_mul_si(a, a, 3);                   \
          element_add(a, a, Zx);                     \
          element_add(a, a, Zx);                     \
          element_neg(a, a);                         \
                                                     \
          element_add(b, Zy, Zy);                    \
                                                     \
          element_mul(e0, b, Zy);                    \
          element_mul(c, a, Zx);                     \
          element_add(c, c, e0);                     \
          element_neg(c, c);                         \
                                                     \
          element_mul(e0, a, numx);                  \
          element_mul(e1, b, numy);                  \
          element_add(e0, e0, e1);                   \
          element_add(e0, e0, c);                    \
          element_mul((e), (e), e0);                 \
                                                     \
          element_mul(e0, a, denomx);                \
          element_mul(e1, b, denomy);                \
          element_add(e0, e0, e1);                   \
          element_add(e0, e0, c);                    \
          element_mul((edenom), (edenom), e0);       \
        }                                            \
    }

    #define do_line(e, edenom) {               \
        if (!element_cmp(Zx, Px)) {            \
            if (!element_cmp(Zy, Py)) {        \
                do_tangent((e), (edenom));     \
            } else {                           \
                do_vertical((e), (edenom));    \
            }                                  \
        } else {                               \
          element_sub(b, Px, Zx);              \
          element_sub(a, Zy, Py);              \
          element_mul(c, Zx, Py);              \
          element_mul(e0, Zy, Px);             \
          element_sub(c, c, e0);               \
                                               \
          element_mul(e0, a, numx);            \
          element_mul(e1, b, numy);            \
          element_add(e0, e0, e1);             \
          element_add(e0, e0, c);              \
          element_mul((e), (e), e0);           \
                                               \
          element_mul(e0, a, denomx);          \
          element_mul(e1, b, denomy);          \
          element_add(e0, e0, e1);             \
          element_add(e0, e0, c);              \
          element_mul((edenom), (edenom), e0); \
       }                                       \
    }

    element_init(a, res->field);
    element_init(b, res->field);
    element_init(c, res->field);
    element_init(e0, res->field);
    element_init(e1, res->field);

    element_init(v, res->field);
    element_init(vd, res->field);
    element_init(Z, P->field);

    element_set(Z, P);
    Zx = curve_x_coord(Z);
    Zy = curve_y_coord(Z);

    element_set1(v);
    element_set1(vd);

    mpz_init(q);
    mpz_set_ui(q, n);
    m = (mp_bitcnt_t)mpz_sizeinbase(q, 2);
    m = (m > 2 ? m - 2 : 0);

    for (;;) {
        element_square(v, v);
        element_square(vd, vd);
        do_tangent(v, vd);
        element_double(Z, Z);
        do_vertical(vd, v);

        if (mpz_tstbit(q, m)) {
            do_line(v, vd);
            element_add(Z, Z, P);
            if (m) {
                do_vertical(vd, v);
            }
        }
        if (!m) break;
        m--;
    }

    mpz_clear(q);

    element_invert(vd, vd);
    element_mul(res, v, vd);

    element_clear(v);
    element_clear(vd);
    element_clear(Z);
    element_clear(a);
    element_clear(b);
    element_clear(c);
    element_clear(e0);
    element_clear(e1);
    #undef do_vertical
    #undef do_tangent
    #undef do_line
}