Example #1
0
static PyObject *
GMPy_MPZ_Function_Isqrt(PyObject *self, PyObject *other)
{
    MPZ_Object *result;

    if (CHECK_MPZANY(other)) {
        if (mpz_sgn(MPZ(other)) < 0) {
            VALUE_ERROR("isqrt() of negative number");
            return NULL;
        }
        if ((result = GMPy_MPZ_New(NULL))) {
            mpz_sqrt(result->z, MPZ(other));
        }
    }
    else {
        if (!(result = GMPy_MPZ_From_Integer(other, NULL))) {
            TYPE_ERROR("isqrt() requires 'mpz' argument");
            return NULL;
        }
        if (mpz_sgn(result->z) < 0) {
            VALUE_ERROR("isqrt() of negative number");
            Py_DECREF((PyObject*)result);
            return NULL;
        }
        mpz_sqrt(result->z, result->z);
    }
    return (PyObject*)result;
}
Example #2
0
/* See Cohen 1.5.3 */
int modified_cornacchia(mpz_t x, mpz_t y, mpz_t D, mpz_t p)
{
    int result = 0;
    mpz_t a, b, c, d;

    if (mpz_cmp_ui(p, 2) == 0) {
        mpz_add_ui(x, D, 8);
        if (mpz_perfect_square_p(x)) {
            mpz_sqrt(x, x);
            mpz_set_ui(y, 1);
            result = 1;
        }
        return result;
    }
    if (mpz_jacobi(D, p) == -1)     /* No solution */
        return 0;

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

    sqrtmod(x, D, p, a, b, c, d);
    if ( (mpz_even_p(D) && mpz_odd_p(x)) || (mpz_odd_p(D) && mpz_even_p(x)) )
        mpz_sub(x, p, x);

    mpz_mul_ui(a, p, 2);
    mpz_set(b, x);
    mpz_sqrt(c, p);
    mpz_mul_ui(c, c, 2);

    /* Euclidean algorithm */
    while (mpz_cmp(b, c) > 0) {
        mpz_set(d, a);
        mpz_set(a, b);
        mpz_mod(b, d, b);
    }

    mpz_mul_ui(c, p, 4);
    mpz_mul(a, b, b);
    mpz_sub(a, c, a);   /* a = 4p - b^2 */
    mpz_abs(d, D);      /* d = |D| */

    if (mpz_divisible_p(a, d)) {
        mpz_divexact(c, a, d);
        if (mpz_perfect_square_p(c)) {
            mpz_set(x, b);
            mpz_sqrt(y, c);
            result = 1;
        }
    }

    mpz_clear(a);
    mpz_clear(b);
    mpz_clear(c);
    mpz_clear(d);

    return result;
}
Example #3
0
bool PrGlib::PrG_prime_test(const ZZZ& n,unsigned int len)
{
    /*kiem tra gia nguyen to fermat co so */
    ZZZ tmp;
    mpz_powm(tmp.get_mpz_t(), ZZZ(2).get_mpz_t(),ZZZ((n - 1)).get_mpz_t(), n.get_mpz_t());
    if (tmp != 1) return false;
    /**************************************/
    /*let k and m such that: n-1=m*2^k*/
    ZZZ m = n^1;                    //sub(m, n, 1); because n is odd
	long k;					// MakeOdd(m);
	k = 0;
	do{
		m >>= 1;				//= > m = m / 2;
		//y = m & 1;				//check m is even number
		k++;
	} while ((m & 1) == 0);
    /*check prime number with the first 20 prime numbers*/
    gmp_randclass r(gmp_randinit_default);
    ZZZ x;
	for (int i = 0; i < 20; i++) {
		x = PrG_prime_sample[i];
		if (PrG_rabin_miller_test(n, x, k, m))return false;
	}
	/*check prime number with the random 44 numbers <= sqrt(n)*/
	ZZZ qk;
	mpz_sqrt(qk.get_mpz_t(),n.get_mpz_t());
	for (int i = 0; i < len; i++)
	{
		do {
            x= r.get_z_range(qk); //RandomBnd(x, n);
		} while (x <= 73);
		if (PrG_rabin_miller_test(n, x, k, m))return false;
	}
	return true;
}
Example #4
0
File: yn.c Project: Kirija/XPIR
/* compute in s an approximation of S1 = sum((n-k)!/k!*y^k,k=0..n)
   return e >= 0 the exponent difference between the maximal value of |s|
   during the for loop and the final value of |s|.
*/
static mpfr_exp_t
mpfr_yn_s1 (mpfr_ptr s, mpfr_srcptr y, unsigned long n)
{
  unsigned long k;
  mpz_t f;
  mpfr_exp_t e, emax;

  mpz_init_set_ui (f, 1);
  /* we compute n!*S1 = sum(a[k]*y^k,k=0..n) where a[k] = n!*(n-k)!/k!,
     a[0] = (n!)^2, a[1] = n!*(n-1)!, ..., a[n-1] = n, a[n] = 1 */
  mpfr_set_ui (s, 1, MPFR_RNDN); /* a[n] */
  emax = MPFR_EXP(s);
  for (k = n; k-- > 0;)
    {
      /* a[k]/a[k+1] = (n-k)!/k!/(n-(k+1))!*(k+1)! = (k+1)*(n-k) */
      mpfr_mul (s, s, y, MPFR_RNDN);
      mpz_mul_ui (f, f, n - k);
      mpz_mul_ui (f, f, k + 1);
      /* invariant: f = a[k] */
      mpfr_add_z (s, s, f, MPFR_RNDN);
      e = MPFR_EXP(s);
      if (e > emax)
        emax = e;
    }
  /* now we have f = (n!)^2 */
  mpz_sqrt (f, f);
  mpfr_div_z (s, s, f, MPFR_RNDN);
  mpz_clear (f);
  return emax - MPFR_EXP(s);
}
Example #5
0
static void generator_inverse_pi(Generator *gen, mpz_t pi1, mpz_t pi2, mpz_t seed) {
        int res;

        /*
         * Inverse pairing function that takes @seed as input and returns the
         * inverse-pair as @pi1 and @pi2. We use storage on @gen as temporary
         * variables, to avoid dynamic allocation on each call.
         */

        /* CAREFUL: pi1/pi2/seed may *overlap*! */

        mpz_sqrt(gen->root, seed);
        mpz_pow_ui(gen->root_squared, gen->root, 2);
        mpz_sub(gen->index, seed, gen->root_squared);

        res = mpz_cmp(gen->index, gen->root);
        if (res < 0) {
                mpz_sub(pi1, seed, gen->root_squared);
                mpz_set(pi2, gen->root);
        } else {
                mpz_sub(gen->index, seed, gen->root_squared);
                mpz_sub(pi2, gen->index, gen->root);
                mpz_set(pi1, gen->root);
        }
}
Example #6
0
File: pi.cpp Project: wxv/PiCalc
mpz_class chudnovsky(int digits)
{
    digits += EXTRA_DIGITS;

    const double digits_per_term = log10(151931373056000ll); // log(C_cubed_over_24 / 72);
    int N = int(digits / digits_per_term) + 1;

    std::cout << "Binary splitting max: " << N << std::endl;

    mpz_class P, Q, T;
    bs(0, N, P, Q, T);


    mpz_class one;
    mpz_ui_pow_ui(one.get_mpz_t(), 10, digits);
    mpz_class sqrt_10005 = one * 10005;
    mpz_sqrt(sqrt_10005.get_mpz_t(), sqrt_10005.get_mpz_t());

    mpz_class pi = (Q * 426880 * sqrt_10005) / T;

    //int bin_digits = int(digits * log2(10));
    //int precision = bin_digits + EXTRA_DIGITS;
    //std::cout << "Precision: " << precision << std::endl;
    //mpf_set_default_prec(precision);

    //mpf_class Q_float(Q);
    //mpf_class T_float(T);

    //mpf_class sqrt_10005;
    //mpf_sqrt_ui(sqrt_10005.get_mpf_t(), 10005);
    //std::cout << sqrt_10005 << std::endl; // Correct precision

    //mpf_class pi = (Q_float * 426880 * sqrt_10005) / T_float;
    return pi;
}
Example #7
0
/* See Cohen 1.5.2 */
int cornacchia(mpz_t x, mpz_t y, mpz_t D, mpz_t p)
{
    int result = 0;
    mpz_t a, b, c, d;

    if (mpz_jacobi(D, p) < 0)     /* No solution */
        return 0;

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

    sqrtmod(x, D, p, a, b, c, d);
    mpz_set(a, p);
    mpz_set(b, x);
    mpz_sqrt(c, p);

    while (mpz_cmp(b,c) > 0) {
        mpz_set(d, a);
        mpz_set(a, b);
        mpz_mod(b, d, b);
    }

    mpz_mul(a, b, b);
    mpz_sub(a, p, a);   /* a = p - b^2 */
    mpz_abs(d, D);      /* d = |D| */

    if (mpz_divisible_p(a, d)) {
        mpz_divexact(c, a, d);
        if (mpz_perfect_square_p(c)) {
            mpz_set(x, b);
            mpz_sqrt(y, c);
            result = 1;
        }
    }

    mpz_clear(a);
    mpz_clear(b);
    mpz_clear(c);
    mpz_clear(d);

    return result;
}
Example #8
0
int
main(int argc, char **argv)
{
	char line[INTEGER_LIMIT];
	if (argc > 1)
		strncpy(&line[0], argv[1], INTEGER_LIMIT);
	else if (scanf("%s\n", &line[0]) != 1) {
		fprintf(stderr, "factor: unable to read number from stdin\n");
		return 1;
	}

	mpz_t n;
	mpz_init(n);

	if (mpz_set_str(n, &line[0], 0) == -1 || mpz_cmp_ui(n, 1) < 0) {
		fprintf(stderr, "factor: input must be a positive integer\n");
		mpz_clear(n);
		return 1;
	}

	if (mpz_cmp_ui(n, 1) == 0 || mpz_probab_prime_p(n, MILLERRABIN_REPEATS) > 0) {
		gmp_printf("%Zd: %Zd\n", n, n);
		mpz_clear(n);
		return 0;
	}

	mpz_t t;
	mpz_init(t);
	mpz_sqrt(t, n);

	struct factors *f = factors_create();
	struct prime_sieve *ps = prime_sieve_create(MIN(TRIALDIVISION_LIMIT, mpz_get_ui(t)));

	if (mpz_perfect_square_p(n)) {
		factors_push(f, t);
		factors_push(f, t);
	} else {
		mpz_set(t, n);
		factors_push(f, t);
	}

	/* run trial division to find find small factors */
	while (factors_remove_composite(f, t) && trial_division(t, f, ps));
	prime_sieve_destroy(ps);

	/* run quadratic sieve until factorized into only prime numbers */
	while (factors_remove_composite(f, t) && quadratic_sieve(t, f, QUADRATIC_SIEVE_SIZE));

	factors_sort(f);
	print_result(n, f);

	mpz_clears(n, t, NULL);
	factors_destroy(f);

	return 0;
}
Example #9
0
// Factor using lehman method.
int _factor_lehman_method(mpz_class &rop, const mpz_class &n)
{
    if (n < 21)
        throw std::runtime_error("Require n >= 21 to use lehman method");

    int ret_val = 0;
    mpz_class u_bound;

    mpz_root(u_bound.get_mpz_t(), n.get_mpz_t(), 3);
    u_bound = u_bound + 1;

    Sieve::iterator pi(u_bound.get_ui());
    unsigned p;
    while ((p = pi.next_prime()) <= u_bound.get_ui()) {
        if (n % p == 0) {
            rop = n / p;
            ret_val = 1;
            break;
        }
    }

    if (!ret_val) {

        mpz_class k, a, b, l;
        mpf_class t;

        k = 1;

        while (k <= u_bound) {
            t = 2 * sqrt(k * n);
            mpz_set_f(a.get_mpz_t(), t.get_mpf_t());
            mpz_root(b.get_mpz_t(), n.get_mpz_t(), 6);
            mpz_root(l.get_mpz_t(), k.get_mpz_t(), 2);
            b = b / (4 * l);
            b = b + a;

            while (a <= b) {
                l = a * a - 4 * k * n;
                if (mpz_perfect_square_p(l.get_mpz_t())) {
                    mpz_sqrt(b.get_mpz_t(), l.get_mpz_t());
                    b = a + b;
                    mpz_gcd(rop.get_mpz_t(), n.get_mpz_t(), b.get_mpz_t());
                    ret_val = 1;
                    break;
                }
                a = a + 1;
            }
            if (ret_val)
                break;
            k = k + 1;
        }
    }

    return ret_val;
}
Example #10
0
File: pow.c Project: tomi500/MPC
/* Return non-zero iff c+i*d is an exact square (a+i*b)^2,
   with a, b both of the form m*2^e with m, e integers.
   If so, returns in a+i*b the corresponding square root, with a >= 0.
   The variables a, b must not overlap with c, d.

   We have c = a^2 - b^2 and d = 2*a*b.

   If one of a, b is exact, then both are (see algorithms.tex).

   Case 1: a <> 0 and b <> 0.
   Let a = m*2^e and b = n*2^f with m, e, n, f integers, m and n odd
   (we will treat apart the case a = 0 or b = 0).
   Then 2*a*b = m*n*2^(e+f+1), thus necessarily e+f >= -1.
   Assume e < 0, then f >= 0, then a^2 - b^2 = m^2*2^(2e) - n^2*2^(2f) cannot
   be an integer, since n^2*2^(2f) is an integer, and m^2*2^(2e) is not.
   Similarly when f < 0 (and thus e >= 0).
   Thus we have e, f >= 0, and a, b are both integers.
   Let A = 2a^2, then eliminating b between c = a^2 - b^2 and d = 2*a*b
   gives A^2 - 2c*A - d^2 = 0, which has solutions c +/- sqrt(c^2+d^2).
   We thus need c^2+d^2 to be a square, and c + sqrt(c^2+d^2) --- the solution
   we are interested in --- to be two times a square. Then b = d/(2a) is
   necessarily an integer.

   Case 2: a = 0. Then d is necessarily zero, thus it suffices to check
   whether c = -b^2, i.e., if -c is a square.

   Case 3: b = 0. Then d is necessarily zero, thus it suffices to check
   whether c = a^2, i.e., if c is a square.
*/
static int
mpc_perfect_square_p (mpz_t a, mpz_t b, mpz_t c, mpz_t d)
{
  if (mpz_cmp_ui (d, 0) == 0) /* case a = 0 or b = 0 */
    {
      /* necessarily c < 0 here, since we have already considered the case
         where x is real non-negative and y is real */
      MPC_ASSERT (mpz_cmp_ui (c, 0) < 0);
      mpz_neg (b, c);
      if (mpz_perfect_square_p (b)) /* case 2 above */
        {
          mpz_sqrt (b, b);
          mpz_set_ui (a, 0);
          return 1; /* c + i*d = (0 + i*b)^2 */
        }
    }
  else /* both a and b are non-zero */
    {
      if (mpz_divisible_2exp_p (d, 1) == 0)
        return 0; /* d must be even */
      mpz_mul (a, c, c);
      mpz_addmul (a, d, d); /* c^2 + d^2 */
      if (mpz_perfect_square_p (a))
        {
          mpz_sqrt (a, a);
          mpz_add (a, c, a); /* c + sqrt(c^2+d^2) */
          if (mpz_divisible_2exp_p (a, 1))
            {
              mpz_tdiv_q_2exp (a, a, 1);
              if (mpz_perfect_square_p (a))
                {
                  mpz_sqrt (a, a);
                  mpz_tdiv_q_2exp (b, d, 1); /* d/2 */
                  mpz_divexact (b, b, a); /* d/(2a) */
                  return 1;
                }
            }
        }
    }
  return 0; /* not a square */
}
Example #11
0
File: pow.c Project: mahdiz/mpclib
/* return non zero iff x^y is exact.
   Assumes x and y are ordinary numbers (neither NaN nor Inf),
   and y is not zero.
*/
int
mpfr_pow_is_exact (mpfr_srcptr x, mpfr_srcptr y)
{
  mp_exp_t d;
  unsigned long i, c;
  mp_limb_t *yp;
  
  if ((mpfr_sgn (x) < 0) && (mpfr_isinteger (y) == 0))
      return 0;

  if (mpfr_sgn (y) < 0)
    return mpfr_cmp_si_2exp (x, MPFR_SIGN(x), MPFR_EXP(x) - 1) == 0;

  /* compute d such that y = c*2^d with c odd integer */
  d = MPFR_EXP(y) - MPFR_PREC(y);
  /* since y is not zero, necessarily one of the mantissa limbs is not zero,
     thus we can simply loop until we find a non zero limb */
  yp = MPFR_MANT(y);
  for (i = 0; yp[i] == 0; i++, d += BITS_PER_MP_LIMB);
  /* now yp[i] is not zero */
  count_trailing_zeros (c, yp[i]);
  d += c;
  
  if (d < 0)
    {
      mpz_t a;
      mp_exp_t b;

      mpz_init (a);
      b = mpfr_get_z_exp (a, x); /* x = a * 2^b */
      c = mpz_scan1 (a, 0);
      mpz_div_2exp (a, a, c);
      b += c;
      /* now a is odd */
      while (d != 0)
        {
          if (mpz_perfect_square_p (a))
            {
              d++;
              mpz_sqrt (a, a);
            }
          else
            {
              mpz_clear (a);
              return 0;
            }
        }
      mpz_clear (a);
    }

    return 1;
}
Example #12
0
RCP<const Integer> isqrt(const Integer &n)
{
    mpz_class m;
    mpz_t m_t;

    mpz_init(m_t);
    mpz_sqrt(m_t, n.as_mpz().get_mpz_t());
    m = mpz_class(m_t);

    mpz_clear(m_t);

    return integer(m);
}
/**
 * Returns sqrt(totient(r)) * log(n) which is used by step 5.
 */
void compute_upper_limit(mpz_t rop, mpz_t r, mpz_t n) {
  mpz_t tot, logn;
  mpz_init(tot);
  mpz_init(logn);

  totient(tot, r);
  if (aks_debug) gmp_printf("tot=%Zd\n", tot);
  mpz_sqrt(tot, tot);

  compute_logn(logn, n);
  mpz_mul(rop, tot, logn);

  mpz_clear(tot);
  mpz_clear(logn);
}
Example #14
0
/* Exercise mpz_perfect_square_p compared to what mpz_sqrt says. */
void
check_sqrt (int reps)
{
  mpz_t x2, x2t, x;
  mp_size_t x2n;
  int res;
  int i;
  /* int cnt = 0; */
  gmp_randstate_ptr rands = RANDS;
  mpz_t bs;

  mpz_init (bs);

  mpz_init (x2);
  mpz_init (x);
  mpz_init (x2t);

  for (i = 0; i < reps; i++)
    {
      mpz_urandomb (bs, rands, 9);
      x2n = mpz_get_ui (bs);
      mpz_rrandomb (x2, rands, x2n);
      /* mpz_out_str (stdout, -16, x2); puts (""); */

      res = mpz_perfect_square_p (x2);
      mpz_sqrt (x, x2);
      mpz_mul (x2t, x, x);

      if (res != (mpz_cmp (x2, x2t) == 0))
        {
          printf    ("mpz_perfect_square_p and mpz_sqrt differ\n");
          mpz_trace ("   x  ", x);
          mpz_trace ("   x2 ", x2);
          mpz_trace ("   x2t", x2t);
          printf    ("   mpz_perfect_square_p %d\n", res);
          printf    ("   mpz_sqrt             %d\n", mpz_cmp (x2, x2t) == 0);
          abort ();
        }

      /* cnt += res != 0; */
    }
  /* printf ("%d/%d perfect squares\n", cnt, reps); */

  mpz_clear (bs);
  mpz_clear (x2);
  mpz_clear (x);
  mpz_clear (x2t);
}
Example #15
0
int main(){

    printf("ciao pippo1 \n");

	mpz_t n;
	mpz_init(n);
	mpz_set_ui(n,4);

    printf("ciao pippo2 \n");

    unsigned int p = 17;

    printf("ciao pippo3 \n");
    
    mpz_t s;
    mpz_init(s);
    mpz_sqrt(s,n);

    printf("ciao pippo4 \n");

    pair solution;

    printf("ciao pippo5 \n"); 

    inizializza_pair(&solution);

    printf("ciao pippo6 \n");

    unsigned int pippo=-3;

    printf("ciao pippo7 \n");

    pippo = legendre(n,p);

    printf("ciao pippo8 \n");

    printf("%d\n",pippo);

    pippo = legendre_sol(n,p,&solution);

    printf("ciao pippo9 \n");

    printf("%d\n",pippo);

    printf("%d\n",solution.sol1);
    printf("%d\n",solution.sol2);    

}
Example #16
0
//------------------------------------------------------------------------------
// Name: sqrt
//------------------------------------------------------------------------------
knumber_base *knumber_integer::sqrt() {

	if(sign() < 0) {
		delete this;
		return new knumber_error(knumber_error::ERROR_UNDEFINED);
	}

	if(mpz_perfect_square_p(mpz_)) {
		mpz_sqrt(mpz_, mpz_);
		return this;
	} else {
		knumber_float *f = new knumber_float(this);
		delete this;
		return f->sqrt();
	}
}
Example #17
0
int isprime( mpz_t n )
{
    mpz_t i, n2, tmp;
    int d, ret;

    /*  1は素数ではない */
    if( mpz_cmp_ui( n, 1 ) == 0 )
        return( 0 );

    /*  2,3は素数 */
    if( mpz_cmp_ui( n, 2 ) == 0 || mpz_cmp_ui( n, 3 ) == 0 )
        return( 1 );

    /*  2,3で割り切れたら合成数    */
    if( mpz_even_p( n ) || mpz_divisible_ui_p( n, 3 ) )
        return( 0 );

    mpz_init( i );
    mpz_init( n2 );
    mpz_init( tmp );

    /*  sqrt(n)+1を求める */
    mpz_sqrt( n2, n );

    /*  n2以下の2,3の倍数以外での剰余が0かどうか調べる   */
    d = 2;
    mpz_set_ui( i, 5 );
    ret = 1;
    while( mpz_cmp( i, n2 ) <= 0 ) {
        if( mpz_divisible_p( n, i ) ) {
            ret = 0;
            break;
        }
        mpz_add_ui( tmp, i, d );
        mpz_set( i, tmp );
        d = ( d == 2 ? 4 : 2 );
    }

    mpz_clear( i );
    mpz_clear( n2 );
    mpz_clear( tmp );

    return( ret );
}
Example #18
0
unsigned int factorCount(mpz_t number)
{
    mpz_t maxNumber;
    mpz_t counter;
    mpz_t q;
    mpz_t r;
    unsigned int result = 0;
    
    //if (mpz_cmp_ui(number, 1) == 0)
    //    return 1;
    mpz_init_set(maxNumber, number);
    mpz_init(r);
    mpz_init(q);
    mpz_sqrt(maxNumber, number);
    for (mpz_init_set_ui(counter, 1); mpz_cmp(counter, maxNumber) <= 0; mpz_add_ui(counter, counter, 1))
        if (mpz_divisible_p(number, counter))
            result += 2;
    return result;
}
Example #19
0
File: prime.c Project: pbos/optimus
void sieve_factor(mpz_t num)
{
	mpz_t gmp_root;
	mpz_init(gmp_root);
	mpz_sqrt(gmp_root, num);

	if(mpz_root(gmp_root, num, 2) != 0)
	{
		mpz_set(factors[num_factors++], gmp_root);
		mpz_set(factors[num_factors++], gmp_root);
		mpz_clear(gmp_root);
		return;
	}

	fail = true;

	find_candidates(num, gmp_root);

	mpz_clear(gmp_root);
}
inline vector<mpz_class> sieve_of_eratosthenes_factorization(const mpz_class& n)
{
  mpz_class remaining = n;
  vector<mpz_class> factors;

  unsigned int limit = pow(2, 26);
  mpz_class tmp;
  mpz_sqrt(tmp.get_mpz_t(), n.get_mpz_t());
  tmp++;
  if (tmp.fits_uint_p() && tmp < limit)
  {
    limit = tmp.get_ui();
  }

  vector<bool> is_prime (limit, true);
  
  is_prime[0] = false;
  is_prime[1] = false;
  for (int i = 2; i < limit; i++)
  {
    if (is_prime[i])
    {
      while (remaining % i == 0)
      {
        remaining /= i;
        factors.push_back(i);
      }

      for (int j = i*i; j < limit; j += i)
      {
        is_prime[j] = false;
      }
    }
  }

  // Don't forget the last factor if one exists.
  if (remaining > 1) factors.push_back(remaining);

  return factors;
}
Example #21
0
File: rw.c Project: agl/rwb0fuz1024
// -----------------------------------------------------------------------------
// Calculate a compressed Rabin signature (see Compressing Rabin Signatures,
// Daniel Bleichenbacher)
//
// zsig: (output) the resulting signature
// s: the Rabin signature
// n: the composite group order
// -----------------------------------------------------------------------------
static void
signature_compress(mpz_t zsig, mpz_t s, mpz_t n) {
  mpz_t vs[4];
  mpz_init_set_ui(vs[0], 0);
  mpz_init_set_ui(vs[1], 1);
  mpz_init(vs[2]);
  mpz_init(vs[3]);

  mpz_t root;
  mpz_init(root);
  mpz_sqrt(root, n);

  mpz_t cf;
  mpz_init(cf);

  unsigned i = 1;

  do {
    i = (i + 1) & 3;

    if (i & 1) {
      mpz_fdiv_qr(cf, s, s, n);
    } else {
      mpz_fdiv_qr(cf, n, n, s);
    }
    mpz_mul(vs[i], vs[(i-1)&3], cf);
    mpz_add(vs[i], vs[i], vs[(i-2)&3]);
  } while (mpz_cmp(vs[i], root) < 0);

  mpz_init(zsig);
  mpz_set(zsig, vs[(i-1) & 3]);

  mpz_clear(root);
  mpz_clear(cf);
  mpz_clear(vs[0]);
  mpz_clear(vs[1]);
  mpz_clear(vs[2]);
  mpz_clear(vs[3]);
}
Example #22
0
/* Compute log(2)/log(b) as a fixnum. */
void
mp_2logb (mpz_t r, int bi, int prec)
{
  mpz_t t, t2, two, b;
  int i;

  mpz_init_set_ui (t, 1);
  mpz_mul_2exp (t, t, prec+EXTRA);

  mpz_init (t2);

  mpz_init_set_ui (two, 2);
  mpz_mul_2exp (two, two, prec+EXTRA);

  mpz_set_ui (r, 0);

  mpz_init_set_ui (b, bi);
  mpz_mul_2exp (b, b, prec+EXTRA);

  for (i = prec-1; i >= 0; i--)
    {
      mpz_mul_2exp (b, b, prec+EXTRA);
      mpz_sqrt (b, b);

      mpz_mul (t2, t, b);
      mpz_tdiv_q_2exp (t2, t2, prec+EXTRA);

      if (mpz_cmp (t2, two) < 0)	/* not too large? */
	{
	  mpz_setbit (r, i);		/* set next less significant bit */
	  mpz_swap (t, t2);		/* new value acceptable */
	}
    }

  mpz_clear (t);
  mpz_clear (t2);
  mpz_clear (two);
  mpz_clear (b);
}
Example #23
0
int isPrime(mpz_t n)
{
    mpz_t iterator;
    mpz_t maxIterator;
    mpz_t remainder;

    if (mpz_cmp_ui(n, 1) <= 0) // negatives, zero, 1 : not prime
        return 0;
    if (mpz_cmp_ui(n, 2) == 0) // 2 : prime
        return 1;
    mpz_init(remainder);
    mpz_init(iterator);
    mpz_init(maxIterator);
    mpz_sqrt(maxIterator, n);
    mpz_add_ui(maxIterator, maxIterator, 1); // round up
    for (mpz_set_ui(iterator, 2); mpz_cmp(iterator, maxIterator) <= 0; mpz_add_ui(iterator, iterator, 1))
    {
        mpz_cdiv_r(remainder, n, iterator);
        if (mpz_cmp_ui(remainder, 0) == 0)
            return 0;
    }
    return 1;
}
Example #24
0
static Variant HHVM_FUNCTION(gmp_sqrt,
                             const Variant& data) {
  mpz_t gmpReturn, gmpData;

  if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_SQRT, gmpData, data)) {
    return false;
  }

  if (mpz_sgn(gmpData) < 0) {
    raise_warning(cs_GMP_INVALID_NUMBER_IS_NEGATIVE, cs_GMP_FUNC_NAME_GMP_SQRT);
    return false;
  }

  mpz_init(gmpReturn);
  mpz_sqrt(gmpReturn, gmpData);

  Variant ret = NEWOBJ(GMPResource)(gmpReturn);

  mpz_clear(gmpData);
  mpz_clear(gmpReturn);

  return ret;
}
int shankSquares(mpz_t *n)
{
	mpz_t myN, constA, constB, tmp, tmp2;
	mpz_t Pi, Qi, Plast, Qlast, Qnext, bi;
	long counter = 1;
	int status = FAIL;
	
	printf("[INFO ] Trying shank squares\n");


	mpz_init_set(myN, *n);

	mpz_init(tmp);	mpz_init(tmp2);
	mpz_init(bi);	mpz_init(Qnext);
	mpz_init(Pi);

	mpz_mul_ui(tmp, myN, SHANKQUAREK); // constA = k*N
	mpz_init_set(constA, tmp);

	mpz_sqrt(tmp, constA);	// constB = floor(sqrt(constA))
	mpz_init_set(constB, tmp);

	mpz_init_set(Plast, constB);


	mpz_pow_ui(tmp, Plast, 2);	// Qi = (constA) - (Pi**2)
	mpz_sub(tmp, constA, tmp);
	mpz_init_set(Qi, tmp);

	
	mpz_init_set_ui(Qlast, 1);


	while (counter < SHANKQUAREMAX)
	{

		mpz_add(tmp, constB, Plast);	//bi = floor( (constB) + (Plast) / Qi )
		mpz_fdiv_q(bi, tmp, Qi);

		mpz_mul(tmp, bi, Qi);			//Pi = (bi * Qi) - (Plast)
		mpz_sub(Pi, tmp, Plast);

		mpz_sub(tmp, Plast, Pi);		//Qnext = Qlast + (bi * (Plast - Pi))
		mpz_mul(tmp, tmp, bi);
		mpz_add(Qnext, Qlast, tmp);

		if (mpz_perfect_square_p(Qi) != 0 && counter % 2 == 0)
		{
			break;
		}
		else
		{
			mpz_set(Plast, Pi);
			mpz_set(Qlast, Qi);
			mpz_set(Qi, Qnext);	
		}

		counter += 1;
	}


	mpz_sub(tmp, constB, Plast);	//bi = floor( ( constB - Plast ) / sqrt(Qi) )
	mpz_sqrt(tmp2, Qi);
	mpz_fdiv_q(bi, tmp, tmp2);

	mpz_sqrt(tmp, Qi);				//Plast = (bi * sqrt(Qi)) + Plast
	mpz_mul(tmp, tmp, bi);
	mpz_add(Plast, tmp, Plast);

	mpz_sqrt(Qlast, Qi);

	mpz_pow_ui(tmp2, Plast, 2);		//Qnext = ((constA) - Plast**2) / Qlast
	mpz_sub(tmp, constA, tmp2);
	mpz_div(Qnext, tmp, Qlast);

	mpz_set(Qi, Qnext);

	counter = 0;

	while (counter < SHANKQUAREMAX)
	{
		mpz_add(tmp, constB, Plast);	//bi = floor( ( constB + Plast ) / Qi )
		mpz_fdiv_q(bi, tmp, Qi);

		mpz_mul(tmp, bi, Qi);			//Pi = (bi*Qi) - Plast
		mpz_sub(Pi, tmp, Plast);

		mpz_sub(tmp, Plast, Pi);		//Qnext = Qlast + (bi * (Plast - Pi))
		mpz_mul(tmp, tmp, bi);
		mpz_add(Qnext, Qlast, tmp);

		if (mpz_cmp(Pi, Plast) == 0)
		{
			break;
		}

		mpz_set(Plast, Pi);
		mpz_set(Qlast, Qi);
		mpz_set(Qi, Qnext);

		counter += 1;
	}

	mpz_gcd(tmp, myN, Pi);

	if (mpz_cmp_ui(tmp, 1) != 0 && mpz_cmp(tmp, myN) != 0)
	{
		printWin(&tmp, "Shanks squares");
		status = WIN;
	}

	mpz_clear(myN);		mpz_clear(constA);
	mpz_clear(constB);	mpz_clear(tmp);		mpz_clear(tmp2);
	mpz_clear(Pi);		mpz_clear(Qi);		mpz_clear(Plast);
	mpz_clear(Qlast);	mpz_clear(Qnext);	mpz_clear(bi);

	return status;

}
Example #26
0
//----------------------- NFS ENTRY POINT ------------------------------------//
void nfs(fact_obj_t *fobj)
{
	//expect the input in fobj->nfs_obj.gmp_n
	char *input;
	msieve_obj *obj = NULL;
	char *nfs_args = NULL; // unused as yet
	enum cpu_type cpu = yafu_get_cpu_type();
	mp_t mpN;
	factor_list_t factor_list;
	uint32 flags = 0;
	nfs_job_t job;
	uint32 relations_needed = 1;
	uint32 last_specialq = 0;
	struct timeval stop;	// stop time of this job
	struct timeval start;	// start time of this job
	struct timeval bstop;	// stop time of sieving batch
	struct timeval bstart;	// start time of sieving batch
	TIME_DIFF *	difference;
	double t_time;
	uint32 pre_batch_rels = 0;
	char tmpstr[GSTR_MAXSIZE];
	int process_done;
	enum nfs_state_e nfs_state;

	// initialize some job parameters
	memset(&job, 0, sizeof(nfs_job_t));

	obj_ptr = NULL;

	//below a certain amount, revert to SIQS
	if (gmp_base10(fobj->nfs_obj.gmp_n) < fobj->nfs_obj.min_digits)
	{
		mpz_set(fobj->qs_obj.gmp_n, fobj->nfs_obj.gmp_n);
		SIQS(fobj);
		mpz_set(fobj->nfs_obj.gmp_n, fobj->qs_obj.gmp_n);
		return;
	}

	if (mpz_probab_prime_p(fobj->nfs_obj.gmp_n, NUM_WITNESSES))
	{
		add_to_factor_list(fobj, fobj->nfs_obj.gmp_n);
		
		if (VFLAG >= 0)
			gmp_printf("PRP%d = %Zd\n", gmp_base10(fobj->nfs_obj.gmp_n),
				fobj->nfs_obj.gmp_n);
		
		logprint_oc(fobj->flogname, "a", "PRP%d = %s\n",
			gmp_base10(fobj->nfs_obj.gmp_n),
			mpz_conv2str(&gstr1.s, 10, fobj->nfs_obj.gmp_n));	

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

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

		add_to_factor_list(fobj, fobj->nfs_obj.gmp_n);
		logprint_oc(fobj->flogname, "a", "prp%d = %s\n",
			gmp_base10(fobj->nfs_obj.gmp_n),
			mpz_conv2str(&gstr1.s, 10, fobj->nfs_obj.gmp_n));

		add_to_factor_list(fobj, fobj->nfs_obj.gmp_n);
		logprint_oc(fobj->flogname, "a", "prp%d = %s\n",
			gmp_base10(fobj->nfs_obj.gmp_n),
			mpz_conv2str(&gstr1.s, 10, fobj->nfs_obj.gmp_n));

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

	if (mpz_perfect_power_p(fobj->nfs_obj.gmp_n))
	{
		FILE *flog;
		uint32 j;

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

		flog = fopen(fobj->flogname, "a");
		if (flog == NULL)
		{
			printf("fopen error: %s\n", strerror(errno));
			printf("could not open %s for appending\n", fobj->flogname);
			exit(1);
		}

		logprint(flog,"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(flog,"prp%d = %s\n",gmp_base10(fobj->fobj_factors[j].factor), 
					mpz_conv2str(&gstr1.s, 10, fobj->fobj_factors[j].factor));
			}
		}

		fclose(flog);
		return;
	}

	if (fobj->nfs_obj.filearg[0] != '\0')
	{
		if (VFLAG > 0) printf("test: starting trial sieving\n");
		trial_sieve(fobj);
		return;
	}

	//initialize the flag to watch for interrupts, and set the
	//pointer to the function to call if we see a user interrupt
	NFS_ABORT = 0;
	signal(SIGINT,nfsexit);

	//start a counter for the whole job
	gettimeofday(&start, NULL);

	//nfs state machine:
	input = (char *)malloc(GSTR_MAXSIZE * sizeof(char));
	nfs_state = NFS_STATE_INIT;
	process_done = 0;
	while (!process_done)
	{
		switch (nfs_state)
		{
		case NFS_STATE_INIT:
			// write the input bigint as a string
			input = mpz_conv2str(&input, 10, fobj->nfs_obj.gmp_n);

			// create an msieve_obj
			// this will initialize the savefile to the outputfile name provided
			obj = msieve_obj_new(input, flags, fobj->nfs_obj.outputfile, fobj->nfs_obj.logfile,
				fobj->nfs_obj.fbfile, g_rand.low, g_rand.hi, (uint32)0, cpu,
				(uint32)L1CACHE, (uint32)L2CACHE, (uint32)THREADS, (uint32)0, nfs_args);
			fobj->nfs_obj.mobj = obj;

			// initialize these before checking existing files.  If poly
			// select is resumed they will be changed by check_existing_files.
			job.last_leading_coeff = 0;
			job.poly_time = 0;
			job.use_max_rels = 0;
			job.snfs = NULL;

			// determine what to do next based on the state of various files.
			// this will set job.current_rels if it finds any
			nfs_state = check_existing_files(fobj, &last_specialq, &job);

			// before we get started, check to make sure we can find ggnfs sievers
			// if we are going to be doing sieving
			if (check_for_sievers(fobj, 1) == 1)
				nfs_state = NFS_STATE_DONE;

			if (VFLAG >= 0 && nfs_state != NFS_STATE_DONE)
				gmp_printf("nfs: commencing nfs on c%d: %Zd\n",
					gmp_base10(fobj->nfs_obj.gmp_n), fobj->nfs_obj.gmp_n);

			if (nfs_state != NFS_STATE_DONE)
				logprint_oc(fobj->flogname, "a", "nfs: commencing nfs on c%d: %s\n",
					gmp_base10(fobj->nfs_obj.gmp_n),
					mpz_conv2str(&gstr1.s, 10, fobj->nfs_obj.gmp_n));

			// convert input to msieve bigint notation and initialize a list of factors
			gmp2mp_t(fobj->nfs_obj.gmp_n,&mpN);
			factor_list_init(&factor_list);

			if (fobj->nfs_obj.rangeq > 0)
				job.qrange = ceil((double)fobj->nfs_obj.rangeq / (double)THREADS);

			break;

		case NFS_STATE_POLY:

			if ((fobj->nfs_obj.nfs_phases == NFS_DEFAULT_PHASES) ||
				(fobj->nfs_obj.nfs_phases & NFS_PHASE_POLY))
			{
				// always check snfs forms (it is fast)
				snfs_choose_poly(fobj, &job);

				if( job.snfs == NULL )
				{ 
					// either we never were doing snfs, or snfs form detect failed.
					// if the latter then bail with an error because the user 
					// explicitly wants to run snfs...
					if (fobj->nfs_obj.snfs)
					{
						printf("nfs: failed to find snfs polynomial!\n");
						exit(-1);
					}

					// init job.poly for gnfs
					job.poly = (mpz_polys_t*)malloc(sizeof(mpz_polys_t));
					if (job.poly == NULL)
					{
						printf("nfs: couldn't allocate memory!\n");
						exit(-1);
					}
					mpz_polys_init(job.poly);
					job.poly->rat.degree = 1; // maybe way off in the future this isn't true
					// assume gnfs for now
					job.poly->side = ALGEBRAIC_SPQ;

					do_msieve_polyselect(fobj, obj, &job, &mpN, &factor_list);
				}
				else
				{
					fobj->nfs_obj.snfs = 1;
					mpz_set(fobj->nfs_obj.gmp_n, job.snfs->n);
				}
			}

			nfs_state = NFS_STATE_SIEVE;
			break;

		case NFS_STATE_SIEVE:

			pre_batch_rels = job.current_rels;
			gettimeofday(&bstart, NULL);

			// sieve if the user has requested to (or by default).  else,
			// set the done sieving flag.  this will prevent some infinite loops,
			// for instance if we only want to post-process, but filtering 
			// doesn't produce a matrix.  if we don't want to sieve in that case,
			// then we're done.
			if (((fobj->nfs_obj.nfs_phases == NFS_DEFAULT_PHASES) ||
				(fobj->nfs_obj.nfs_phases & NFS_PHASE_SIEVE)) &&
				!(fobj->nfs_obj.nfs_phases & NFS_DONE_SIEVING))
				do_sieving(fobj, &job);
			else
				fobj->nfs_obj.nfs_phases |= NFS_DONE_SIEVING;

			// if this has been previously marked, then go ahead and exit.
			if (fobj->nfs_obj.nfs_phases & NFS_DONE_SIEVING)
				process_done = 1;
			
			// if user specified -ns with a fixed start and range,
			// then mark that we're done sieving.  
			if (fobj->nfs_obj.rangeq > 0)
			{
				// we're done sieving the requested range, but there may be
				// more phases to check, so don't exit yet
				fobj->nfs_obj.nfs_phases |= NFS_DONE_SIEVING;
			}
				
			// then move on to the next phase
			nfs_state = NFS_STATE_FILTCHECK;

			break;

		case NFS_STATE_FILTER:

			// if we've flagged not to do filtering, then assume we have
			// enough relations and move on to linear algebra
			if ((fobj->nfs_obj.nfs_phases == NFS_DEFAULT_PHASES) ||
				(fobj->nfs_obj.nfs_phases & NFS_PHASE_FILTER))
				relations_needed = do_msieve_filtering(fobj, obj, &job);
			else
				relations_needed = 0;

			if (relations_needed == 0)
				nfs_state = NFS_STATE_LINALG;
			else
			{
				// if we filtered, but didn't produce a matrix, raise the target
				// min rels by a few percent.  this will prevent too frequent
				// filtering attempts while allowing the q_batch size to remain small.
				if (job.current_rels > job.min_rels)
					job.min_rels = job.current_rels * fobj->nfs_obj.filter_min_rels_nudge;
				else
					job.min_rels *= fobj->nfs_obj.filter_min_rels_nudge;

				if (VFLAG > 0)
					printf("nfs: raising min_rels by %1.2f percent to %u\n", 
					100*(fobj->nfs_obj.filter_min_rels_nudge-1), job.min_rels);

				nfs_state = NFS_STATE_SIEVE;
			}

			break;

		case NFS_STATE_LINALG:

			if ((fobj->nfs_obj.nfs_phases == NFS_DEFAULT_PHASES) ||
				(fobj->nfs_obj.nfs_phases & NFS_PHASE_LA) ||
				(fobj->nfs_obj.nfs_phases & NFS_PHASE_LA_RESUME))
			{
				// msieve: build matrix
				flags = 0;
				flags = flags | MSIEVE_FLAG_USE_LOGFILE;
				if (VFLAG > 0)
					flags = flags | MSIEVE_FLAG_LOG_TO_STDOUT;
				flags = flags | MSIEVE_FLAG_NFS_LA;

				// add restart flag if requested
				if (fobj->nfs_obj.nfs_phases & NFS_PHASE_LA_RESUME)
					flags |= MSIEVE_FLAG_NFS_LA_RESTART;

				obj->flags = flags;

				if (VFLAG >= 0)
					printf("nfs: commencing msieve linear algebra\n");

				logprint_oc(fobj->flogname, "a", "nfs: commencing msieve linear algebra\n");

				// use a different number of threads for the LA, if requested
				if (LATHREADS > 0)
				{
					msieve_obj_free(obj);
					obj = msieve_obj_new(input, flags, fobj->nfs_obj.outputfile, fobj->nfs_obj.logfile,
						fobj->nfs_obj.fbfile, g_rand.low, g_rand.hi, (uint32)0, cpu,
						(uint32)L1CACHE, (uint32)L2CACHE, (uint32)LATHREADS, (uint32)0, nfs_args);
				}

				// try this hack - store a pointer to the msieve obj so that
				// we can change a flag on abort in order to interrupt the LA.
				obj_ptr = obj;
				nfs_solve_linear_system(obj, fobj->nfs_obj.gmp_n);
				if (obj_ptr->flags & MSIEVE_FLAG_STOP_SIEVING)
					nfs_state = NFS_STATE_DONE;
				else
				{
					// check for a .dat.deps file.  if we don't have one, assume
					// its because the job was way oversieved and only trivial
					// dependencies were found.  try again from filtering with
					// 20% less relations.
					FILE *t;
					sprintf(tmpstr, "%s.dep", fobj->nfs_obj.outputfile);
					if ((t = fopen(tmpstr, "r")) == NULL)
					{
						if (job.use_max_rels > 0)
						{
							// we've already tried again with an attempted fix to the trivial
							// dependencies problem, so either that wasn't the problem or
							// it didn't work.  either way, give up.
							printf("nfs: no dependency file retry failed\n");
							fobj->flags |= FACTOR_INTERRUPT;
							nfs_state = NFS_STATE_DONE;
						}
						else
						{
							// this should be sufficient to produce a matrix, but not too much
							// to trigger the assumed failure mode.							
							if (job.min_rels == 0)
							{
								// if min_rels is not set, then we need to parse the .job file to compute it.
								parse_job_file(fobj, &job);
								nfs_set_min_rels(&job);
							}
							job.use_max_rels = job.min_rels * 1.5;
							printf("nfs: no dependency file found - trying again with %u relations\n",
								job.use_max_rels);
							nfs_state = NFS_STATE_FILTER;
						}
					}
					else
					{
						fclose(t);
						nfs_state = NFS_STATE_SQRT;
					}
				}

				// set the msieve threads back to where it was if we used
				// a different amount for linalg
				if (LATHREADS > 0)
				{
					msieve_obj_free(obj);
					obj = msieve_obj_new(input, flags, fobj->nfs_obj.outputfile, fobj->nfs_obj.logfile,
						fobj->nfs_obj.fbfile, g_rand.low, g_rand.hi, (uint32)0, cpu,
						(uint32)L1CACHE, (uint32)L2CACHE, (uint32)THREADS, (uint32)0, nfs_args);
				}

				obj_ptr = NULL;
			}
			else // not doing linalg
				nfs_state = NFS_STATE_SQRT;

			break;

		case NFS_STATE_SQRT:

			if ((fobj->nfs_obj.nfs_phases == NFS_DEFAULT_PHASES) ||
				(fobj->nfs_obj.nfs_phases & NFS_PHASE_SQRT))
			{
				uint32 retcode;

				// msieve: find factors
				flags = 0;
				flags = flags | MSIEVE_FLAG_USE_LOGFILE;
				if (VFLAG > 0)
					flags = flags | MSIEVE_FLAG_LOG_TO_STDOUT;
				flags = flags | MSIEVE_FLAG_NFS_SQRT;
				obj->flags = flags;

				if (VFLAG >= 0)
					printf("nfs: commencing msieve sqrt\n");

				logprint_oc(fobj->flogname, "a", "nfs: commencing msieve sqrt\n");

				// try this hack - store a pointer to the msieve obj so that
				// we can change a flag on abort in order to interrupt the sqrt.
				obj_ptr = obj;

				retcode = nfs_find_factors(obj, fobj->nfs_obj.gmp_n, &factor_list);

				obj_ptr = NULL;

				if (retcode)
				{
					extract_factors(&factor_list,fobj);

					if (mpz_cmp_ui(fobj->nfs_obj.gmp_n, 1) == 0)
						nfs_state = NFS_STATE_CLEANUP;		//completely factored, clean up everything
					else
						nfs_state = NFS_STATE_DONE;		//not factored completely, keep files and stop
				}
				else
				{
					if (VFLAG >= 0)
					{
						printf("nfs: failed to find factors... possibly no dependencies found\n");
						printf("nfs: continuing with sieving\n");
					}

					logprint_oc(fobj->flogname, "a", "nfs: failed to find factors... "
						"possibly no dependencies found\n"
						"nfs: continuing with sieving\n");

					nfs_state = NFS_STATE_SIEVE;
				}				
			}
			else
				nfs_state = NFS_STATE_DONE;		//not factored completely, keep files and stop

			break;

		case NFS_STATE_CLEANUP:
			
			remove(fobj->nfs_obj.outputfile);
			remove(fobj->nfs_obj.fbfile);
			sprintf(tmpstr, "%s.p",fobj->nfs_obj.outputfile);	remove(tmpstr);			
			sprintf(tmpstr, "%s.br",fobj->nfs_obj.outputfile);	remove(tmpstr);
			sprintf(tmpstr, "%s.cyc",fobj->nfs_obj.outputfile);	remove(tmpstr);
			sprintf(tmpstr, "%s.dep",fobj->nfs_obj.outputfile);	remove(tmpstr);
			sprintf(tmpstr, "%s.hc",fobj->nfs_obj.outputfile);	remove(tmpstr);
			sprintf(tmpstr, "%s.mat",fobj->nfs_obj.outputfile);	remove(tmpstr);	
			sprintf(tmpstr, "%s.lp",fobj->nfs_obj.outputfile);	remove(tmpstr);
			sprintf(tmpstr, "%s.d",fobj->nfs_obj.outputfile);	remove(tmpstr);
			sprintf(tmpstr, "%s.mat.chk",fobj->nfs_obj.outputfile);	remove(tmpstr);

			gettimeofday(&stop, NULL);

			difference = my_difftime (&start, &stop);

			t_time = ((double)difference->secs + (double)difference->usecs / 1000000);
			free(difference);	

			if (VFLAG >= 0)
				printf("NFS elapsed time = %6.4f seconds.\n",t_time);

			logprint_oc(fobj->flogname, "a", "NFS elapsed time = %6.4f seconds.\n",t_time);
			logprint_oc(fobj->flogname, "a", "\n");
			logprint_oc(fobj->flogname, "a", "\n");

			// free stuff			
			nfs_state = NFS_STATE_DONE;
			break;

		case NFS_STATE_DONE:
			process_done = 1;
			break;

		case NFS_STATE_FILTCHECK:
			if (job.current_rels >= job.min_rels)
			{
				if (VFLAG > 0)
					printf("nfs: found %u relations, need at least %u, proceeding with filtering ...\n",
					job.current_rels, job.min_rels);
				
				nfs_state = NFS_STATE_FILTER;
			}
			else
			{
				// compute eta by dividing how many rels we have left to find
				// by the average time per relation.  we have average time
				// per relation because we've saved the time it took to do 
				// the last batch of sieving and we know how many relations we
				// found in that batch.
				uint32 est_time;

				gettimeofday(&bstop, NULL);
				difference = my_difftime (&bstart, &bstop);
				t_time = ((double)difference->secs + (double)difference->usecs / 1000000);
				free(difference);

				est_time = (uint32)((job.min_rels - job.current_rels) * 
					(t_time / (job.current_rels - pre_batch_rels)));				

				// if the user doesn't want to sieve, then we can't make progress.
				if ((fobj->nfs_obj.nfs_phases == NFS_DEFAULT_PHASES) ||
					(fobj->nfs_obj.nfs_phases & NFS_PHASE_SIEVE))
				{
					if (VFLAG > 0)
						printf("nfs: found %u relations, need at least %u "
							"(filtering ETA: %uh %um), continuing with sieving ...\n", // uh... um... hmm... idk *shrug*
							job.current_rels, job.min_rels, est_time / 3600, 
							(est_time % 3600) / 60);

					nfs_state = NFS_STATE_SIEVE;
				}
				else
				{
					if (VFLAG > 0)
						printf("nfs: found %u relations, need at least %u "
							"(filtering ETA: %uh %um), sieving not selected, finishing ...\n",
							job.current_rels, job.min_rels, est_time / 3600, 
							(est_time % 3600) / 60);

					nfs_state = NFS_STATE_DONE;
				}
			}
			break;

		case NFS_STATE_STARTNEW:

			nfs_state = NFS_STATE_POLY;		

			// create a new directory for this job 
//#ifdef _WIN32
//			sprintf(tmpstr, "%s\%s", fobj->nfs_obj.ggnfs_dir, 
//				mpz_conv2str(&gstr1.s, 10, fobj->nfs_obj.gmp_n));
//			mkdir(tmpstr);
//#else
//			sprintf(tmpstr, "%s/%s", fobj->nfs_obj.ggnfs_dir, 
//				mpz_conv2str(&gstr1.s, 10, fobj->nfs_obj.gmp_n));
//			mkdir(tmpstr, S_IRWXU);
//#endif
			
			// point msieve and ggnfs to the new directory
//#ifdef _WIN32
//			sprintf(fobj->nfs_obj.outputfile, "%s\%s", 
//				tmpstr, fobj->nfs_obj.outputfile);
//			sprintf(fobj->nfs_obj.logfile, "%s\%s", 
//				tmpstr, fobj->nfs_obj.logfile);
//			sprintf(fobj->nfs_obj.fbfile, "%s\%s", 
//				tmpstr, fobj->nfs_obj.fbfile);
//#else
//			sprintf(fobj->nfs_obj.outputfile, "%s%s", 
//				tmpstr, fobj->nfs_obj.outputfile);
//			sprintf(fobj->nfs_obj.logfile, "%s%s", 
//				tmpstr, fobj->nfs_obj.logfile);
//			sprintf(fobj->nfs_obj.fbfile, "%s%s", 
//				tmpstr, fobj->nfs_obj.fbfile);
//
//#endif
//
//			msieve_obj_free(fobj->nfs_obj.mobj);
//			obj = msieve_obj_new(input, flags, fobj->nfs_obj.outputfile, fobj->nfs_obj.logfile, 
//				fobj->nfs_obj.fbfile, g_rand.low, g_rand.hi, (uint32)0, nfs_lower, nfs_upper, cpu, 
//				(uint32)L1CACHE, (uint32)L2CACHE, (uint32)THREADS, (uint32)0, (uint32)0, 0.0);
//			fobj->nfs_obj.mobj = obj;
//
//			printf("output: %s\n", fobj->nfs_obj.mobj->savefile.name);
//			printf("log: %s\n", fobj->nfs_obj.mobj->logfile_name);
//			printf("fb: %s\n", fobj->nfs_obj.mobj->nfs_fbfile_name);

			break;

			// should really be "resume_job", since we do more than just resume sieving...
		case NFS_STATE_RESUMESIEVE:

			// last_specialq == 0 if:
			// 1) user specifies -R and -ns with params
			// 2) user specifies post processing steps only
			// 3) user wants to resume sieving (either with a solo -ns or no arguements)
			//		but no data file or special-q was found
			// 4) -R was not specified (but then we won't be in this state, we'll be in DONE)
			// last_specialq > 1 if:
			// 5) user wants to resume sieving (either with a solo -ns or no arguements)
			//		and a data file and special-q was found
			// 6) it contains poly->time info (in which case we'll be in NFS_STATE_RESUMEPOLY)

			strcpy(tmpstr, "");
			if ((last_specialq == 0) &&
				((fobj->nfs_obj.nfs_phases == NFS_DEFAULT_PHASES) ||
				(fobj->nfs_obj.nfs_phases & NFS_PHASE_SIEVE)))
 			{								
				// this if-block catches cases 1 and 3 from above
				uint32 missing_params = parse_job_file(fobj, &job);
				
				// set min_rels.  
				get_ggnfs_params(fobj, &job);
				
				fill_job_file(fobj, &job, missing_params);
				// if any ggnfs params are missing, fill them
				// this means the user can provide an SNFS poly or external GNFS poly, 
				// but let YAFU choose the other params
				// this won't override any params in the file.
			
				if (fobj->nfs_obj.startq > 0)
				{
					job.startq = fobj->nfs_obj.startq;

					sprintf(tmpstr, "nfs: resuming with sieving at user specified special-q %u\n",
						job.startq);
				}
				else
				{
					// this is a guess, may be completely wrong
					job.startq = (job.poly->side == RATIONAL_SPQ ? job.rlim : job.alim) / 2;

					sprintf(tmpstr, "nfs: continuing with sieving - could not determine "
						"last special q; using default startq\n");
				}

				// next step is sieving
				nfs_state = NFS_STATE_SIEVE;
			}
			else if ((last_specialq == 0) &&
				((fobj->nfs_obj.nfs_phases & NFS_PHASE_FILTER) ||
				(fobj->nfs_obj.nfs_phases & NFS_PHASE_LA) ||
				(fobj->nfs_obj.nfs_phases & NFS_PHASE_LA_RESUME) ||
				(fobj->nfs_obj.nfs_phases & NFS_PHASE_SQRT)))
			{
				// this if-block catches case 2 from above
				// with these options we don't check for the last special-q, so this isn't
				// really a new factorization
				if ((fobj->nfs_obj.nfs_phases & NFS_PHASE_FILTER))
				{
					nfs_state = NFS_STATE_FILTCHECK;
					sprintf(tmpstr, "nfs: resuming with filtering\n");
				}
				else if ((fobj->nfs_obj.nfs_phases & NFS_PHASE_LA) ||
					(fobj->nfs_obj.nfs_phases & NFS_PHASE_LA_RESUME))
				{
					nfs_state = NFS_STATE_LINALG;
					sprintf(tmpstr, "nfs: resuming with linear algebra\n");
				}
				else if (fobj->nfs_obj.nfs_phases & NFS_PHASE_SQRT)
				{
					nfs_state = NFS_STATE_SQRT;
					sprintf(tmpstr, "nfs: resuming with sqrt\n");
				}

			}
			else // data file already exists
			{				
				// this if-block catches case 5 from above
				(void) parse_job_file(fobj, &job);
				
				// set min_rels.  
				get_ggnfs_params(fobj, &job);

				if (fobj->nfs_obj.startq > 0)
				{
					// user wants to resume sieving.
					// i don't believe this case is ever executed... 
					// because if startq is > 0, then last_specialq will be 0...
					job.startq = fobj->nfs_obj.startq;
					nfs_state = NFS_STATE_SIEVE;
				}
				else
				{
					job.startq = last_specialq;

					// we found some relations - find the appropriate state
					// given user input
					if ((fobj->nfs_obj.nfs_phases == NFS_DEFAULT_PHASES) ||
						(fobj->nfs_obj.nfs_phases & NFS_PHASE_FILTER))
					{
						nfs_state = NFS_STATE_FILTCHECK;
						sprintf(tmpstr, "nfs: resuming with filtering\n");
					}
					else if (fobj->nfs_obj.nfs_phases & NFS_PHASE_SIEVE)
					{
						nfs_state = NFS_STATE_SIEVE;
						sprintf(tmpstr, "nfs: resuming with sieving at special-q = %u\n",
							last_specialq);
					}
					else if ((fobj->nfs_obj.nfs_phases & NFS_PHASE_LA) ||
						(fobj->nfs_obj.nfs_phases & NFS_PHASE_LA_RESUME))
					{
						nfs_state = NFS_STATE_LINALG;
						sprintf(tmpstr, "nfs: resuming with linear algebra\n");
					}
					else if (fobj->nfs_obj.nfs_phases & NFS_PHASE_SQRT)
					{
						nfs_state = NFS_STATE_SQRT;
						sprintf(tmpstr, "nfs: resuming with sqrt\n");
					}

				}				
			}

			if (VFLAG >= 0)
				printf("%s", tmpstr);

			logprint_oc(fobj->flogname, "a", "%s", tmpstr);

			// if there is a job file and the user has specified -np, print
			// this warning.
			if (fobj->nfs_obj.nfs_phases & NFS_PHASE_POLY)
			{
				printf("WARNING: .job file exists!  If you really want to redo poly selection,"
					" delete the .job file.\n");
				// non ideal solution to infinite loop in factor() if we return without factors
				// (should return error code instead)
				NFS_ABORT = 1;
				process_done = 1;
			}

			break;

		case NFS_STATE_RESUMEPOLY:
			if (VFLAG > 1) printf("nfs: resuming poly select\n");
			fobj->nfs_obj.polystart = job.last_leading_coeff;

			nfs_state = NFS_STATE_POLY;

			break;

		default:
			printf("unknown state, bailing\n");
			// non ideal solution to infinite loop in factor() if we return without factors
			// (should return error code instead)
			NFS_ABORT = 1;
			break;

		}

		//after every state, check elasped time against a specified timeout value
		gettimeofday(&stop, NULL);
		difference = my_difftime (&start, &stop);

		t_time = ((double)difference->secs + (double)difference->usecs / 1000000);
		free(difference);	
		if ((fobj->nfs_obj.timeout > 0) && (t_time > (double)fobj->nfs_obj.timeout))
		{
			if (VFLAG >= 0)
				printf("NFS timeout after %6.4f seconds.\n",t_time);

			logprint_oc(fobj->flogname, "a", "NFS timeout after %6.4f seconds.\n",t_time);
			process_done = 1;
		}

		if (NFS_ABORT)
		{
			print_factors(fobj);
			exit(1);
		}
	}

	//reset signal handler to default (no handler).
	signal(SIGINT,NULL);

	if (obj != NULL)
		msieve_obj_free(obj);
	free(input);
	
	if( job.snfs )
	{
		snfs_clear(job.snfs);
		free(job.snfs);
	} 
	else if( job.poly )
	{
		mpz_polys_free(job.poly);
		free(job.poly);
	}

	return;
}
Example #27
0
int main(int argc, char **argv) {
	gettimeofday(&start_global, NULL);
	print_lib_version();

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

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

	uint64_t i, j;

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

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

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

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

	OPEN_LOG_FILE("freq");

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

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

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

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

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

	printf("\nN-Quadratic primes found %" PRId64 "\n", nb_qr_primes);
	STOP_TIMER_PRINT_TIME("\tQuadratic prime filtering done");

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

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

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

	/*for(i=0; i<nb_qr_primes; i++)
	 {
	 printf("[%10" PRId64 "-> roots: %10u - %10u]\n", primes[i], modular_roots[i].root1, modular_roots[i].root2);
	 }*/

//--------------------------------------------------------
//         ***** initialize the matrix *****
//--------------------------------------------------------
	START_TIMER();
	init_matrix(&matrix, nb_qr_primes + NB_VECTORS_OFFSET, nb_qr_primes);
	mpz_init2(tmp_matrix_row, nb_qr_primes);
	STOP_TIMER_PRINT_TIME("\nMatrix initialized");

//--------------------------------------------------------
// [Sieving]
//--------------------------------------------------------
	START_TIMER();

	mpz_t x, sieving_index, next_sieving_index;
	unsigned long ui_index, SIEVING_STEP = 50000; /* we sieve for 50000 elements at each loop */
	uint64_t p_pow;
	smooth_number_t *x_squared;

	x_squared = calloc(SIEVING_STEP, sizeof(smooth_number_t));
	smooth_numbers = calloc(nb_qr_primes + NB_VECTORS_OFFSET,
			sizeof(smooth_number_t));

	mpz_init_set(x, sqrtN);
	mpz_init_set(sieving_index, x);
	mpz_init_set(next_sieving_index, x);

	mpz_t p;
	mpz_init(p);
	mpz_t str;
	mpz_init_set(str, sieving_index);
	printf("\nSieving ...\n");

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

		/* the factors_exp array is used to keep track of exponents */
		//x_squared[i].factors_exp = calloc(nb_qr_primes, sizeof(uint64_t));
		/* we use directly the exponents vector modulo 2 to preserve space */mpz_init2(
				x_squared[i].factors_vect, nb_qr_primes);
		mpz_add_ui(x, x, 1);
	}

	int nb_smooth_per_round = 0;
	char s[512];

//--------------------------------------------------------
// WHILE smooth numbers found less than the primes in the smooth base + NB_VECTORS_OFFSET
//--------------------------------------------------------
	while (nb_smooth_numbers_found < nb_qr_primes + NB_VECTORS_OFFSET) {
		nb_smooth_per_round = 0;
		mpz_set(x, next_sieving_index); /* sieve numbers from sieving_index to sieving_index + sieving_step */
		mpz_set(sieving_index, next_sieving_index);

		printf("\r");
		printf(
				"\t\tSieving at: %s30 <--> Smooth numbers found: %" PRId64 "/%" PRId64 "",
				mpz_get_str(NULL, 10, sieving_index), nb_smooth_numbers_found,
				nb_qr_primes);
		fflush(stdout);

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

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

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

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

//--------------------------------------------------------
// eliminate factors in the x_squared array, those who are 'destructed' to 1 are smooth
//--------------------------------------------------------

		for (i = 0; i < nb_qr_primes; i++) {
			mpz_set_ui(p, (unsigned long) primes[i]);
			mpz_set(x, sieving_index);

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

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

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

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

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

			mpz_set(x, sieving_index);

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

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

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

				if (mpz_cmp_ui(x_squared[j].value_x_squared, 1) == 0) {
					save_smooth_number(x_squared[j]);
					nb_smooth_per_round++;
				}
			}
		}
		//printf("\tSmooth numbers found %" PRId64 "\n", nb_smooth_numbers_found);
		/*sprintf(s, "[start: %s - end: %s - step: %" PRId64 "] nb_smooth_per_round: %d",
		 mpz_get_str(NULL, 10, sieving_index),
		 mpz_get_str(NULL, 10, next_sieving_index),
		 SIEVING_STEP,
		 nb_smooth_per_round);
		 APPEND_TO_LOG_FILE(s);*/
	}

	STOP_TIMER_PRINT_TIME("\nSieving DONE");

	uint64_t t = 0;

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

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

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

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

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

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

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

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

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

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

		mpz_sub(solution_X, solution_X, solution_Y);

		mpz_gcd(solution_X, solution_X, N);

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

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

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

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

	STOP_TIMER_PRINT_TIME("\nFactorizing done");

	printf("Cleaning memory..\n");

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

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

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

	free_matrix(&matrix);

	gettimeofday(&end_global, NULL);
	timersub(&end_global, &start_global, &elapsed);
	printf("****** TOTAL TIME: %.3f ms\n",
			elapsed.tv_sec * 1000 + elapsed.tv_usec / (double) 1000);
	show_mem_usage();
	return 0;
}
Example #28
0
void poly_init(QS_t * qs_inf, poly_t * poly_inf, mpz_t N)
{
   unsigned long num_primes = qs_inf->num_primes;
   unsigned long s = (qs_inf->bits-1)/28+1;
   if (s <= 2) s = 3;
	prime_t * factor_base = qs_inf->factor_base;
   unsigned long fact_approx, fact, span;
   unsigned long sieve_size = qs_inf->sieve_size;
   unsigned long small_primes = qs_inf->small_primes;
   long min; 
   
   poly_inf->s = s;
     
   poly_inf->B = (unsigned long*) flint_stack_alloc(qs_inf->prec+1);  
   poly_inf->B_terms = (unsigned long*) flint_stack_alloc(s*(qs_inf->prec+1));  
   poly_inf->A = (unsigned long*) flint_stack_alloc(qs_inf->prec+1);  
   poly_inf->target_A = (unsigned long*) flint_stack_alloc(qs_inf->prec+1);  
   
   poly_inf->A_ind = (unsigned long*) flint_stack_alloc(s);  
   poly_inf->A_modp = (unsigned long*) flint_stack_alloc(s);  
   poly_inf->A_inv2B = (uint32_t**) flint_stack_alloc(s); 
   poly_inf->inv_p2 = (double*) flint_stack_alloc_bytes(s*sizeof(double));  
   poly_inf->A_inv = (uint32_t *) flint_stack_alloc_bytes(num_primes*sizeof(uint32_t));  
   poly_inf->soln1 = (uint32_t *) flint_stack_alloc_bytes(num_primes*sizeof(uint32_t)); 
   poly_inf->soln2 = (uint32_t *) flint_stack_alloc_bytes(num_primes*sizeof(uint32_t)); 
   poly_inf->posn1 = (uint32_t *) flint_stack_alloc_bytes(num_primes*sizeof(uint32_t)); 
   poly_inf->posn2 = (uint32_t *) flint_stack_alloc_bytes(num_primes*sizeof(uint32_t)); 
   
   uint32_t ** A_inv2B = poly_inf->A_inv2B;
   
   A_inv2B[0] = (uint32_t *) flint_stack_alloc_bytes(num_primes*s*sizeof(uint32_t));
   
   mpz_init(poly_inf->A_mpz);
   mpz_init(poly_inf->B_mpz);
   mpz_init(poly_inf->C);
   
   for (unsigned long i = 1; i < s; i++)
   {
      A_inv2B[i] = A_inv2B[i-1] + num_primes;
   } 
 
   mpz_t temp;
   mpz_init(temp); 
   
   mpz_mul_ui(temp, N, 2*qs_inf->k);
   mpz_sqrt(temp, temp);
   
   mpz_div_ui(temp, temp, 47*sieve_size/100);
   mpz_to_fmpz(poly_inf->target_A, temp);
   
   mpz_root(temp, temp, s);
   fact_approx = mpz_get_ui(temp);
   
   for (fact = 0; fact_approx >= factor_base[fact].p; fact++); 
   
   span = num_primes/s/s/2;
   if (span < 6*s) span = 6*s;
   min = fact - span/2;
   if (min < (long) small_primes) min = small_primes;
   if (min + span >= qs_inf->num_primes - 1) span = num_primes - min - 1;
   fact = min + span/2;

#if POLY_PARAMS   
   printf("min = FB[%ld], span = %ld, number of factors = %ld\n", min, span, s);
#endif
   
   poly_inf->min = min;
   poly_inf->fact = fact;
   poly_inf->span = span;
          
   mpz_clear(temp); 
}
Example #29
0
extern void _jl_mpz_sqrt(mpz_t* rop, mpz_t* op) {
    mpz_sqrt(*rop, *op);
}
Example #30
0
unsigned int sieve(
	mpz_t n,
	unsigned int* factor_base,
	unsigned int base_dim,
	pair* solutions,
	unsigned int** exponents,
	mpz_t* As,
	unsigned int poly_val_num,
	unsigned int max_fact,
	unsigned int intervals
	) {

	unsigned int i;

	unsigned int** expo2;
	init_matrix(&expo2, intervals, base_dim);
	word** is_used_expo2;
	init_matrix_l(&is_used_expo2, 1, (intervals / N_BITS) + 1);
	for(i = 0; i < ((intervals / N_BITS) + 1); ++i) {
		set_matrix_l(is_used_expo2, 0, i, 0);
	}

	mpz_t n_root;
	mpz_t intermed;
	mpz_init(n_root);
	mpz_init(intermed);
	mpz_sqrt(n_root, n);

	unsigned char go_on = 1;

	unsigned int fact_count = 0;
	unsigned int j, k;
	mpz_t* evaluated_poly;

	init_vector_mpz(&evaluated_poly, poly_val_num);

	word** is_used;
	init_matrix_l(&is_used, 1, (poly_val_num / N_BITS) + 1);
	for(i = 0; i < ((poly_val_num / N_BITS) + 1); ++i) {
		set_matrix_l(is_used, 0, i, 0);
	}

	max_fact += base_dim;

	// Trovo poly_val_num valori del polinomio (A + s)^2 - n, variando A
	for(i = 0; i < poly_val_num; ++i) {
		mpz_add_ui(intermed, n_root, i);
		mpz_mul(intermed, intermed, intermed);
		mpz_sub(evaluated_poly[i], intermed, n);
		
		mpz_add_ui(As[i], n_root, i);
	}

	// Per ogni primo nella base di fattori
	for(i = 0; i < base_dim && go_on; ++i) {

		// Provo tutte le possibili fattorizzazioni nella base di fattori
		for(j = solutions[i].sol1; j < poly_val_num && go_on; j += factor_base[i]) {

			// Divido e salvo l'esponente va bene
			while(mpz_divisible_ui_p(evaluated_poly[j], factor_base[i])) {
				
				// Se non sono mai stati usati gli esponenti
				if(get_k_i(is_used, 0, j) == 0) {
					for(k = 0; k < base_dim; ++k)
						set_matrix(exponents, j, k, 0);
					set_k_i(is_used, 0, j, 1);
				}
				
				set_matrix(exponents, j, i, get_matrix(exponents, j, i) + 1); // ++exponents[j][i];
				mpz_divexact_ui(evaluated_poly[j], evaluated_poly[j], factor_base[i]);	
			}
			
			if(mpz_cmp_ui(evaluated_poly[j], 1) == 0) {
				++fact_count;
				if(fact_count >= max_fact) {
					go_on = 0;
				}
			}
		}

		// Faccio la stessa cosa con entrambe le soluzioni, a meno che non stia usando 2
		if(factor_base[i] != 2) {
			for(j = solutions[i].sol2; j < poly_val_num && go_on; j += factor_base[i]) {

				while(mpz_divisible_ui_p(evaluated_poly[j], factor_base[i])) {
					
					// Se non sono mai stati usati gli esponenti
					if(get_k_i(is_used, 0, j) == 0) {
						for(k = 0; k < base_dim; ++k)
							set_matrix(exponents, j, k, 0);
						set_k_i(is_used, 0, j, 1);
					}

					set_matrix(exponents, j, i, get_matrix(exponents, j, i) + 1); // ++exponents[j][i];
					mpz_divexact_ui(evaluated_poly[j], evaluated_poly[j], factor_base[i]);
				}

				if(mpz_cmp_ui(evaluated_poly[j], 1) == 0) {
					++fact_count;
					if(fact_count >= max_fact) {
						go_on = 0;
					}
				}
			}
		}
	}

	mpz_clear(n_root);
	mpz_clear(intermed);

	remove_not_factorized(exponents, evaluated_poly, As, poly_val_num, base_dim);

	// finalize_vector_mpz(&evaluated_poly, poly_val_num);
	// Si noti che questa istruzione apparentemente innocua porta all'uscita di demoni dal naso del programmatore

	return fact_count;
}