Example #1
0
int solovay_strassen(mpz_t n, int k)
{
	int i;
	for (i = 0; i < primes_count && mpz_cmp_si(n, primes[i]*primes[i]) >= 0; i++)
		if (mpz_divisible_ui_p(n, primes[i])) // Check if current prime divides n
			return 0;

	if (mpz_cmp_si(n, 2) < 0)
		return 0;
	if (mpz_cmp_si(n, 2) == 0)
		return 1;
	if (mpz_divisible_ui_p(n, 2))
		return 0;

	gmp_randstate_t RAND;
	gmp_randinit_default(RAND);

	mpz_t a, jac, mod, exp, n1;
	mpz_init(a);
	mpz_init(jac);
	mpz_init(mod);
	mpz_init(exp);
	mpz_init(n1);
	mpz_sub_ui(n1, n, 1);
	while (k > 0) {
		k--;
		mpz_urandomm(a, RAND, n1);
		mpz_add_ui(a, a, 1);

		int j = jacobi(a, n);
		if (j == -1) { // jac = n + jac(a,n)
			mpz_sub_ui(jac, n, 1);
		} else if (j == 1)
			mpz_set_si(jac, j);

		mpz_divexact_ui(exp, n1, 2); // exp = (n-1)/2
		mpz_powm(mod, a, exp, n); // mod = a^((n-1)/2) % n
		if (mpz_cmp_ui(jac, 0) == 0 || mpz_cmp(mod, jac) != 0) { // Is it a liar?
			mpz_clear(a);
			mpz_clear(jac);
			mpz_clear(mod);
			mpz_clear(exp);
			mpz_clear(n1);

			return 0;
		}
	}

	mpz_clear(a);
	mpz_clear(jac);
	mpz_clear(mod);
	mpz_clear(exp);
	mpz_clear(n1);

	return 1;
}
static int has_small_prime_factor(mpz_t n)
{
	for (unsigned i = 0; i < len(prime_list); i++)
		if (mpz_divisible_ui_p(n, prime_list[i]))
			return 1;
	return 0;
}
Example #3
0
void pollard(mpz_t x_1, mpz_t x_2, mpz_t d, mpz_t n, int init, int c, int counter)
{
    if(mpz_divisible_ui_p(n, 2)) {
        mpz_set_ui(d, 2);
        return;
    }

    mpz_set_ui(x_1, init);
    NEXT_VALUE(x_1, x_1, n, c);
    NEXT_VALUE(x_2, x_1, n, c);

    mpz_set_ui(d, 1);
    while (mpz_cmp_ui(d, 1) == 0) {
        NEXT_VALUE(x_1, x_1, n, c);
        NEXT_VALUE(x_2, x_2, n, c);
        NEXT_VALUE(x_2, x_2, n, c);

        mpz_sub(d, x_2, x_1);
        mpz_abs(d, d);
        mpz_gcd(d, d, n);

        if (counter < 0) {
            mpz_set_ui(d, 0);
            return;
        } else {
            --counter;
        }
    }

    if(mpz_cmp(d, n) == 0) {
        return pollard(x_1, x_2, d, n, primes[RAND], primes[RAND], counter);
    }
}
Example #4
0
void
check_one (mpz_srcptr a, mpz_srcptr d, int want)
{
  int   got;

  if (mpz_fits_ulong_p (d))
    {
      unsigned long  u = mpz_get_ui (d);
      got = (mpz_divisible_ui_p (a, u) != 0);
      if (want != got)
        {
          printf ("mpz_divisible_ui_p wrong\n");
          printf ("   expected %d got %d\n", want, got);
          mpz_trace ("   a", a);
          printf ("   d=%lu\n", u);
          mp_trace_base = -16;
          mpz_trace ("   a", a);
          printf ("   d=0x%lX\n", u);
          abort ();
        }
    }

  got = (mpz_divisible_p (a, d) != 0);
  if (want != got)
    {
      printf ("mpz_divisible_p wrong\n");
      printf ("   expected %d got %d\n", want, got);
      mpz_trace ("   a", a);
      mpz_trace ("   d", d);
      mp_trace_base = -16;
      mpz_trace ("   a", a);
      mpz_trace ("   d", d);
      abort ();
    }
}
Example #5
0
static PyObject *
GMPy_MPZ_Method_IsDivisible(PyObject *self, PyObject *other)
{
    unsigned long temp;
    int error, res;
    MPZ_Object *tempd;

    temp = GMPy_Integer_AsUnsignedLongAndError(other, &error);
    if (!error) {
        res = mpz_divisible_ui_p(MPZ(self), temp);
        if (res)
            Py_RETURN_TRUE;
        else
            Py_RETURN_FALSE;
    }

    if (!(tempd = GMPy_MPZ_From_Integer(other, NULL))) {
        TYPE_ERROR("is_divisible() requires integer argument");
        return NULL;
    }

    res = mpz_divisible_p(MPZ(self), tempd->z);
    Py_DECREF((PyObject*)tempd);
    if (res)
        Py_RETURN_TRUE;
    else
        Py_RETURN_FALSE;
}
int main() {


	unsigned long long a,b;
	mpz_t a2, b3, v, sum;

	mpz_init(a2);
	mpz_init(b3);
	mpz_init(v);
	mpz_init_set_ui(sum, 0);

	for (b = 1; b < sqrt(MAX); b++) {
		mpz_ui_pow_ui(b3, b, 3);			
		for (a = 1; a < b	; a++) {
			mpz_ui_pow_ui(a2, a, 2);		
			mpz_add(v, a2, b3);
      if (!mpz_divisible_ui_p(v, a)) {
				continue;
      }
			mpz_div_ui(v, v, a);
			if (mpz_perfect_square_p(v)) {
				mpz_add(sum, sum, v);
				printf("%s %llu %llu\n",  mpz_get_str(NULL, 10, v), a, b);
			}


    }

  }



 	
	return(0);
}
Example #7
0
/* *************************************************************************
 * mpz_euler_prp: (also called a Solovay-Strassen pseudoprime)
 * An "Euler pseudoprime" to the base a is an odd composite number n with,
 * (a,n)=1 such that a^((n-1)/2)=(a/n) mod n [(a/n) is the Jacobi symbol]
 * *************************************************************************/
int mpz_euler_prp(mpz_t n, mpz_t a)
{
  mpz_t res;
  mpz_t exp;
  int ret = 0;

  if (mpz_cmp_ui(a, 2) < 0)
    return PRP_ERROR;

  if (mpz_cmp_ui(n, 2) < 0)
    return PRP_COMPOSITE;

  if (mpz_divisible_ui_p(n, 2))
  {
    if (mpz_cmp_ui(n, 2) == 0)
      return PRP_PRIME;
    else
      return PRP_COMPOSITE;
  }

  mpz_init_set_ui(res, 0);
  mpz_gcd(res, n, a);

  if (mpz_cmp_ui(res, 1) > 0)
  {
    mpz_clear(res);
    return PRP_COMPOSITE;
  }

  mpz_init_set(exp, n);

  mpz_sub_ui(exp, exp, 1); /* exp = n-1 */
  mpz_divexact_ui(exp, exp, 2); /* exp = (n-1)/2 */
  mpz_powm(res, a, exp, n);

  /* reuse exp to calculate jacobi(a,n) mod n */
  ret = mpz_jacobi(a,n);
  mpz_set(exp, n);
  if (ret == -1)
    mpz_sub_ui(exp, exp, 1);
  else if (ret == 1)
    mpz_add_ui(exp, exp, 1);
  mpz_mod(exp, exp, n);

  if (mpz_cmp(res, exp) == 0)
  {
    mpz_clear(res);
    mpz_clear(exp);
    return PRP_PRP;
  }
  else
  {
    mpz_clear(res);
    mpz_clear(exp);
    return PRP_COMPOSITE;
  }

}/* method mpz_euler_prp */
Example #8
0
int jacobi(mpz_t aa, mpz_t nn) // Generalization of Legendre's symbol.
{
	mpz_t a, n, n2;
	mpz_init_set(a, aa);
	mpz_init_set(n, nn);
	mpz_init(n2);

	if (mpz_divisible_p(a, n))
		return 0; // (0/n) = 0

	int ans = 1;
	if (mpz_cmp_ui(a, 0) < 0) {
		mpz_neg(a, a); // (a/n) = (-a/n)*(-1/n)
		if (mpz_congruent_ui_p(n, 3, 4)) // if n%4 == 3
			ans = -ans; // (-1/n) = -1 if n = 3 (mod 4)
	}

	if (mpz_cmp_ui(a, 1) == 0) {
		mpz_clear(a);
		mpz_clear(n);
		mpz_clear(n2);

		return ans; // (1/n) = 1
	}

	while (mpz_cmp_ui(a, 0) != 0) {
		if (mpz_cmp_ui(a, 0) < 0) {
			mpz_neg(a, a); // (a/n) = (-a/n)*(-1/n)
			if (mpz_congruent_ui_p(n, 3, 4)) // if n%4 == 3
				ans = -ans; // (-1/n) = -1 if n = 3 ( mod 4 )
		}

		while (mpz_divisible_ui_p(a, 2)) {
			mpz_divexact_ui(a, a, 2); // a = a/2
			if (mpz_congruent_ui_p(n, 3, 8) || mpz_congruent_ui_p(n, 5, 8)) // n%8==3 || n%8==5
				ans = -ans;
		}

		mpz_swap(a, n); // (a,n) = (n,a)
		if (mpz_congruent_ui_p(a, 3, 4) && mpz_congruent_ui_p(n, 3, 4)) // a%4==3 && n%4==3
			ans = -ans;

		mpz_mod(a, a, n); // because (a/p) = (a%p / p ) and a%pi = (a%n)%pi if n % pi = 0
		mpz_cdiv_q_ui(n2, n, 2);
		if (mpz_cmp(a, n2) > 0) // a > n/2
			mpz_sub(a, a, n); // a = a-n
	}

	int cmp = mpz_cmp_ui(n, 1);
	mpz_clear(a);
	mpz_clear(n);
	mpz_clear(n2);

	if (cmp == 0)
		return ans;
	return 0;
}
int aks_is_prime(mpz_t n) {

  // Peform simple checks before running the AKS algorithm
  if (mpz_cmp_ui(n, 2) == 0) {
    return PRIME;
  }

  if (mpz_cmp_ui(n, 1) <= 0 || mpz_divisible_ui_p(n, 2)) {
    return COMPOSITE;
  }

  // Step 1: Check if n is a perfect power, meaning n = a ^ b where a is a natural number and b > 1
  if (mpz_perfect_power_p(n)) {
    return COMPOSITE;
  }

  // Step 2: Find the smallest r such that or(n) > log(n) ^ 2
  mpz_t r;
  mpz_init(r);
  find_smallest_r(r, n);

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

  // Step 3: Check if there exists an a <= r such that 1 < (a,n) < n
  if (check_a_exists(n, r)) {
    mpz_clear(r);
    return COMPOSITE;
  }

  if (aks_debug) gmp_printf("a does not exist\n");

  // Step 4: Check if n <= r
  if (mpz_cmp(n, r) <= 0) {
    mpz_clear(r);
    return PRIME;
  }

  if (aks_debug) gmp_printf("checking polynomial equation\n");

  // Step 5
  if (check_polys(r, n)) {
    mpz_clear(r);
    return COMPOSITE;
  }

  mpz_clear(r);

  // Step 6
  return PRIME;
}
Example #10
0
/* Search the index to start sieving for one number */
uint64_t search_index_to_start_sieving(smooth_number_t** smooth_array, uint64_t size_base, uint64_t prime_number, mpz_t root){

  uint64_t i;
  smooth_number_t* smooth;
  mpz_t remainder;
  mpz_init(remainder);

  for( i = 0; i < size_base; i++){
    smooth = smooth_array[i];
//    mpz_mod_ui(remainder, smooth->f_x, prime_number);
    if(mpz_divisible_ui_p(smooth->f_x, prime_number)){
      return i;
    }
  }

  return -1;
}
Example #11
0
/* ******************************************************************
 * mpz_prp: (also called a Fermat pseudoprime)
 * A "pseudoprime" to the base a is a composite number n such that,
 * (a,n)=1 and a^(n-1) = 1 mod n
 * ******************************************************************/
int mpz_prp(mpz_t n, mpz_t a)
{
  mpz_t res;
  mpz_t nm1;

  if (mpz_cmp_ui(a, 2) < 0)
    return PRP_ERROR;

  if (mpz_cmp_ui(n, 2) < 0)
    return PRP_COMPOSITE;

  if (mpz_divisible_ui_p(n, 2))
  {
    if (mpz_cmp_ui(n, 2) == 0)
      return PRP_PRIME;
    else
      return PRP_COMPOSITE;
  }

  mpz_init_set_ui(res, 0);
  mpz_gcd(res, n, a);

  if (mpz_cmp_ui(res, 1) > 0)
  {
    mpz_clear(res);
    return PRP_COMPOSITE;
  }

  mpz_init_set(nm1, n);
  mpz_sub_ui(nm1, nm1, 1);
  mpz_powm(res, a, nm1, n);

  if (mpz_cmp_ui(res, 1) == 0)
  {
    mpz_clear(res);
    mpz_clear(nm1);
    return PRP_PRP;
  }
  else
  {
    mpz_clear(res);
    mpz_clear(nm1);
    return PRP_COMPOSITE;
  }

}/* method mpz_prp */
Example #12
0
void pollard_brent(mpz_t x_1, mpz_t x_2, mpz_t d, mpz_t n, int init, int c, int counter)
{
    int i;
    for(i = 0; i < 10000; ++i) {
        if(mpz_divisible_ui_p(n, primes[i])) {
            mpz_set_ui(d, primes[i]);
            return;
        }
    }

    unsigned long power = 1;
    unsigned long lam = 1;

    mpz_set_ui(x_1, init);

    mpz_set_ui(d, 1);
    while(mpz_cmp_ui(d, 1) == 0) {
        if (power == lam) {
            mpz_set(x_2, x_1);
            power *= 2;
            lam = 0;
        }

        mpz_mul(x_1, x_1, x_1);
        mpz_add_ui(x_1, x_1, c);
        mpz_mod(x_1, x_1, n);

        mpz_sub(d, x_2, x_1);
        mpz_abs(d, d);
        mpz_gcd(d, d, n);

        lam++;

        if (counter < 0) {
            mpz_set_ui(d, 0);
            return;
        } else {
            --counter;
        }
    }

    if(mpz_cmp(d, n) == 0) {
        return pollard_brent(x_1, x_2, d, n, rand(), rand(), counter);
    }
}
Example #13
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 );
}
// Check Fermat probable primality test (2-PRP): 2 ** (n-1) = 1 (mod n)
// true: n is probable prime
// false: n is composite; set fractional length in the nLength output
static bool FermatProbablePrimalityTestFast(const mpz_class& n, unsigned int& nLength, CPrimalityTestParams& testParams, bool fFastDiv = false)
{
    // Faster GMP version
    mpz_t& mpzN = testParams.mpzN;
    mpz_t& mpzE = testParams.mpzE;
    mpz_t& mpzR = testParams.mpzR;
    const unsigned int nPrimorialSeq = testParams.nPrimorialSeq;

    mpz_set(mpzN, n.get_mpz_t());
    if (fFastDiv)
    {
        // Fast divisibility tests
        // Starting from the first prime not included in the round primorial
        const unsigned int nBeginSeq = nPrimorialSeq + 1;
        const unsigned int nEndSeq = nBeginSeq + nFastDivPrimes;
        for (unsigned int nPrimeSeq = nBeginSeq; nPrimeSeq < nEndSeq; nPrimeSeq++) {
            if (mpz_divisible_ui_p(mpzN, vPrimes[nPrimeSeq])) {
               return false;
            }
        }
    }

	++fermats;
    mpz_sub_ui(mpzE, mpzN, 1);
    mpz_powm(mpzR, mpzTwo.get_mpz_t(), mpzE, mpzN);
    if (mpz_cmp_ui(mpzR, 1) == 0)
    {
        return true;
    }
    // Failed Fermat test, calculate fractional length
    mpz_sub(mpzE, mpzN, mpzR);
    mpz_mul_2exp(mpzR, mpzE, nFractionalBits);
    mpz_tdiv_q(mpzE, mpzR, mpzN);
    unsigned int nFractionalLength = mpz_get_ui(mpzE);

    if (nFractionalLength >= (1 << nFractionalBits))
	{
		cout << "FermatProbablePrimalityTest() : fractional assert" << endl;
        return false;
	}
    nLength = (nLength & TARGET_LENGTH_MASK) | nFractionalLength;
    return false;
}
Example #15
0
static PyObject *
GMPy_MPZ_Function_IsDivisible(PyObject *self, PyObject *args)
{
    unsigned long temp;
    int error, res;
    MPZ_Object *tempx, *tempd;

    if (PyTuple_GET_SIZE(args) != 2) {
        TYPE_ERROR("is_divisible() requires 2 integer arguments");
        return NULL;
    }

    if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) {
        return NULL;
    }

    temp = GMPy_Integer_AsUnsignedLongAndError(PyTuple_GET_ITEM(args, 1), &error);
    if (!error) {
        res = mpz_divisible_ui_p(tempx->z, temp);
        Py_DECREF((PyObject*)tempx);
        if (res)
            Py_RETURN_TRUE;
        else
            Py_RETURN_FALSE;
    }

    if (!(tempd = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL))) {
        TYPE_ERROR("is_divisible() requires 2 integer arguments");
        Py_DECREF((PyObject*)tempx);
        return NULL;
    }

    res = mpz_divisible_p(tempx->z, tempd->z);
    Py_DECREF((PyObject*)tempx);
    Py_DECREF((PyObject*)tempd);
    if (res)
        Py_RETURN_TRUE;
    else
        Py_RETURN_FALSE;
}
Example #16
0
static PyObject *
GMPY_mpz_is_strong_prp(PyObject *self, PyObject *args)
{
    MPZ_Object *a, *n;
    PyObject *result = 0;
    mpz_t s, nm1, mpz_test;
    mp_bitcnt_t r = 0;

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

    n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL);
    a = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL);
    if (!a || !n) {
        TYPE_ERROR("is_strong_prp() requires 2 integer arguments");
        goto cleanup;
    }

    mpz_init(s);
    mpz_init(nm1);
    mpz_init(mpz_test);

    /* Require a >= 2. */
    if (mpz_cmp_ui(a->z, 2) < 0) {
        VALUE_ERROR("is_strong_prp() requires 'a' greater than or equal to 2");
        goto cleanup;
    }

    /* Require n > 0. */
    if (mpz_sgn(n->z) <= 0) {
        VALUE_ERROR("is_strong_prp() requires 'n' be greater than 0");
        goto cleanup;
    }

    /* Check for n == 1 */
    if (mpz_cmp_ui(n->z, 1) == 0) {
        result = Py_False;
        goto cleanup;
    }

    /* Handle n even. */
    if (mpz_divisible_ui_p(n->z, 2)) {
        if (mpz_cmp_ui(n->z, 2) == 0)
            result = Py_True;
        else
            result = Py_False;
        goto cleanup;
    }

    /* Check gcd(a,b) */
    mpz_gcd(s, n->z, a->z);
    if (mpz_cmp_ui(s, 1) > 0) {
        VALUE_ERROR("is_strong_prp() requires gcd(n,a) == 1");
        goto cleanup;
    }

    mpz_set(nm1, n->z);
    mpz_sub_ui(nm1, nm1, 1);

    /* Find s and r satisfying: n-1=(2^r)*s, s odd */
    r = mpz_scan1(nm1, 0);
    mpz_fdiv_q_2exp(s, nm1, r);


    /* Check a^((2^t)*s) mod n for 0 <= t < r */
    mpz_powm(mpz_test, a->z, s, n->z);
    if ((mpz_cmp_ui(mpz_test, 1) == 0) || (mpz_cmp(mpz_test, nm1) == 0)) {
        result = Py_True;
        goto cleanup;
    }

    while (--r) {
        /* mpz_test = mpz_test^2%n */
        mpz_mul(mpz_test, mpz_test, mpz_test);
        mpz_mod(mpz_test, mpz_test, n->z);

        if (mpz_cmp(mpz_test, nm1) == 0) {
            result = Py_True;
            goto cleanup;
        }
    }

    result = Py_False;
  cleanup:
    Py_XINCREF(result);
    mpz_clear(s);
    mpz_clear(nm1);
    mpz_clear(mpz_test);
    Py_XDECREF((PyObject*)a);
    Py_XDECREF((PyObject*)n);
    return result;
}
Example #17
0
/* *******************************************************************************
 * mpz_lucas_prp:
 * A "Lucas pseudoprime" with parameters (P,Q) is a composite n with D=P^2-4Q,
 * (n,2QD)=1 such that U_(n-(D/n)) == 0 mod n [(D/n) is the Jacobi symbol]
 * *******************************************************************************/
int mpz_lucas_prp(mpz_t n, long int p, long int q)
{
  mpz_t zD;
  mpz_t res;
  mpz_t index;
  mpz_t uh, vl, vh, ql, qh, tmp; /* used for calculating the Lucas U sequence */
  int s = 0, j = 0;
  int ret = 0;
  long int d = p*p - 4*q;

  if (d == 0) /* Does not produce a proper Lucas sequence */
    return PRP_ERROR;

  if (mpz_cmp_ui(n, 2) < 0)
    return PRP_COMPOSITE;

  if (mpz_divisible_ui_p(n, 2))
  {
    if (mpz_cmp_ui(n, 2) == 0)
      return PRP_PRIME;
    else
      return PRP_COMPOSITE;
  }

  mpz_init(index);
  mpz_init_set_si(zD, d);
  mpz_init(res);

  mpz_mul_si(res, zD, q);
  mpz_mul_ui(res, res, 2);
  mpz_gcd(res, res, n);
  if ((mpz_cmp(res, n) != 0) && (mpz_cmp_ui(res, 1) > 0))
  {
    mpz_clear(zD);
    mpz_clear(res);
    mpz_clear(index);
    return PRP_COMPOSITE;
  }

  /* index = n-(D/n), where (D/n) is the Jacobi symbol */
  mpz_set(index, n);
  ret = mpz_jacobi(zD, n);
  if (ret == -1)
    mpz_add_ui(index, index, 1);
  else if (ret == 1)
    mpz_sub_ui(index, index, 1);

  /* mpz_lucasumod(res, p, q, index, n); */
  mpz_init_set_si(uh, 1);
  mpz_init_set_si(vl, 2);
  mpz_init_set_si(vh, p);
  mpz_init_set_si(ql, 1);
  mpz_init_set_si(qh, 1);
  mpz_init_set_si(tmp,0);

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

      /* uh = uh*vh (mod n) */
      mpz_mul(uh, uh, vh);
      mpz_mod(uh, uh, n);

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

      /* 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);
    }
    else
    {
      /* qh = ql */
      mpz_set(qh, ql);

      /* uh = uh*vl - ql (mod n) */
      mpz_mul(uh, uh, vl);
      mpz_sub(uh, uh, ql);
      mpz_mod(uh, uh, n);

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

      /* 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);
    }
  }
  /* ql = ql*qh */
  mpz_mul(ql, ql, qh);

  /* qh = ql*q */
  mpz_mul_si(qh, ql, q);

  /* uh = uh*vl - ql */
  mpz_mul(uh, uh, vl);
  mpz_sub(uh, uh, ql);

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

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

  for (j = 1; j <= s; j++)
  {
    /* uh = uh*vl (mod n) */
    mpz_mul(uh, uh, vl);
    mpz_mod(uh, uh, n);

    /* 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);

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

  mpz_mod(res, uh, n); /* uh contains our return value */

  mpz_clear(zD);
  mpz_clear(index);
  mpz_clear(uh);
  mpz_clear(vl);
  mpz_clear(vh);
  mpz_clear(ql);
  mpz_clear(qh);
  mpz_clear(tmp);

  if (mpz_cmp_ui(res, 0) == 0)
  {
    mpz_clear(res);
    return PRP_PRP;
  }
  else
  {
    mpz_clear(res);
    return PRP_COMPOSITE;
  }

}/* method mpz_lucas_prp */
Example #18
0
/* *************************************************************************
 * mpz_fibonacci_prp:
 * A "Fibonacci pseudoprime" with parameters (P,Q), P > 0, Q=+/-1, is a
 * composite n for which V_n == P mod n
 * [V is the Lucas V sequence with parameters P,Q]
 * *************************************************************************/
int mpz_fibonacci_prp(mpz_t n, long int p, long int q)
{
  mpz_t pmodn, zP;
  mpz_t vl, vh, ql, qh, tmp; /* used for calculating the Lucas V sequence */
  int s = 0, j = 0;

  if (p*p-4*q == 0)
    return PRP_ERROR;

  if (((q != 1) && (q != -1)) || (p <= 0))
    return PRP_ERROR;

  if (mpz_cmp_ui(n, 2) < 0)
    return PRP_COMPOSITE;

  if (mpz_divisible_ui_p(n, 2))
  {
    if (mpz_cmp_ui(n, 2) == 0)
      return PRP_PRIME;
    else
      return PRP_COMPOSITE;
  }

  mpz_init_set_ui(zP, p);
  mpz_init(pmodn);
  mpz_mod(pmodn, zP, n);

  /* mpz_lucasvmod(res, p, q, n, n); */
  mpz_init_set_si(vl, 2);
  mpz_init_set_si(vh, p);
  mpz_init_set_si(ql, 1);
  mpz_init_set_si(qh, 1);
  mpz_init_set_si(tmp,0);

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

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

      /* 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);
    }
    else
    {
      /* qh = ql */
      mpz_set(qh, ql);

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

      /* 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);
    }
  }
  /* ql = ql*qh */
  mpz_mul(ql, ql, qh);

  /* qh = ql*q */
  mpz_mul_si(qh, ql, q);

  /* vl = vh*vl - p*ql */
  mpz_mul(vl, vh, vl);
  mpz_mul_si(tmp, ql, p);
  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);

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

  mpz_mod(vl, vl, n); /* vl contains our return value */

  if (mpz_cmp(vl, pmodn) == 0)
  {
    mpz_clear(zP);
    mpz_clear(pmodn);
    mpz_clear(vl);
    mpz_clear(vh);
    mpz_clear(ql);
    mpz_clear(qh);
    mpz_clear(tmp);
    return PRP_PRP;
  }
  mpz_clear(zP);
  mpz_clear(pmodn);
  mpz_clear(vl);
  mpz_clear(vh);
  mpz_clear(ql);
  mpz_clear(qh);
  mpz_clear(tmp);
  return PRP_COMPOSITE;

}/* method mpz_fibonacci_prp */
Example #19
0
/* *********************************************************************************************
 * mpz_sprp: (also called a Miller-Rabin pseudoprime)
 * A "strong pseudoprime" to the base a is an odd composite n = (2^r)*s+1 with s odd such that
 * either a^s == 1 mod n, or a^((2^t)*s) == -1 mod n, for some integer t, with 0 <= t < r.
 * *********************************************************************************************/
int mpz_sprp(mpz_t n, mpz_t a)
{
  mpz_t s;
  mpz_t nm1;
  mpz_t mpz_test;
  unsigned long int r = 0;

  if (mpz_cmp_ui(a, 2) < 0)
    return PRP_ERROR;

  if (mpz_cmp_ui(n, 2) < 0)
    return PRP_COMPOSITE;

  if (mpz_divisible_ui_p(n, 2))
  {
    if (mpz_cmp_ui(n, 2) == 0)
      return PRP_PRIME;
    else
      return PRP_COMPOSITE;
  }

  mpz_init_set_ui(mpz_test, 0);
  mpz_init_set_ui(s, 0);
  mpz_init_set(nm1, n);
  mpz_sub_ui(nm1, nm1, 1);

  /***********************************************/
  /* Find s and r satisfying: n-1=(2^r)*s, s odd */
  r = mpz_scan1(nm1, 0);
  mpz_fdiv_q_2exp(s, nm1, r);


  /******************************************/
  /* Check a^((2^t)*s) mod n for 0 <= t < r */
  mpz_powm(mpz_test, a, s, n);
  if ( (mpz_cmp_ui(mpz_test, 1) == 0) || (mpz_cmp(mpz_test, nm1) == 0) )
  {
    mpz_clear(s);
    mpz_clear(nm1);
    mpz_clear(mpz_test);
    return PRP_PRP;
  }

  while ( --r )
  {
    /* mpz_test = mpz_test^2%n */
    mpz_mul(mpz_test, mpz_test, mpz_test);
    mpz_mod(mpz_test, mpz_test, n);

    if (mpz_cmp(mpz_test, nm1) == 0)
    {
      mpz_clear(s);
      mpz_clear(nm1);
      mpz_clear(mpz_test);
      return PRP_PRP;
    }
  }

  mpz_clear(s);
  mpz_clear(nm1);
  mpz_clear(mpz_test);
  return PRP_COMPOSITE;

}/* method mpz_sprp */
Example #20
0
/*
 * isprime : is this number prime ?
 * this use the Miller-Rabin method. The algorithm can be found at Wikipedia
 * return 1 (yes) and 0 (no)
 */
int
isprime(mpz_t p)
{
    gmp_randstate_t st;         /* random init stat */
    mpz_t           a,
                    d,
                    tmp,
                    x;
    int             i,
                    ret,
                    j;
    unsigned long   s;

    ret = 1;

    /*
     * ensure that p is odd and greater than 3 
     */
    if (mpz_cmp_ui(p, 3) <= 0 || !mpz_tstbit(p, 0))
        return 0;

    /*
     * put p in the 2^s.d form
     */
    mpz_init(d);
    mpz_sub_ui(d, p, 1);        /* d = p-1 */
    s = 0;

    do {
        s++;
        mpz_divexact_ui(d, d, 2);
    } while (mpz_divisible_ui_p(d, 2));
    /*
     * now we have p as 2^s.d
     */

    gmp_randinit_default(st);
    gmp_randseed_ui(st, time(NULL));
    mpz_init(a);
    mpz_init(x);
    mpz_init(tmp);
    mpz_sub_ui(tmp, p, 1);      /* tmp = p - 1 */

    for (i = 0; i < ACCURACY; i++) {
        /*
         * generate a as 2 <= a <= n-2 
         */
        do {
            mpz_urandomm(a, st, tmp);   /* a will be between 0 and * tmp-1 
                                         * inclusive */
        } while (mpz_cmp_ui(a, 2) < 0);

        mpz_powm(x, a, d, p);   /* do x = a^d mod p */

        /*
         * if x == 1 or x == p-1 
         */
        if (!mpz_cmp_ui(x, 1) || !mpz_cmp(x, tmp))
            continue;

        for (j = 1; j < s; j++) {
            mpz_powm_ui(x, x, 2, p);    /* do x = x^2 mod p */
            if (!mpz_cmp_ui(x, 1)
                || !mpz_cmp(x, tmp))    /* x == 1 */
                break;
        }

        if (mpz_cmp(x, tmp) || !mpz_cmp_ui(x, 1)) {     /* x != p-1 */
            ret = 0;
            break;
        }
    }

    /*
     * Free Ressources
     */
    gmp_randclear(st);
    mpz_clear(a);
    mpz_clear(d);
    mpz_clear(tmp);

    return ret;
}
Example #21
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;
}
Example #22
0
static PyObject *
GMPY_mpz_is_extrastronglucas_prp(PyObject *self, PyObject *args)
{
    MPZ_Object *n, *p;
    PyObject *result = 0;
    mpz_t zD, s, nmj, nm2, res;
    /* these are needed for the LucasU and LucasV part of this function */
    mpz_t uh, vl, vh, ql, qh, tmp;
    mp_bitcnt_t r = 0, j = 0;
    int ret = 0;

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

    mpz_init(zD);
    mpz_init(s);
    mpz_init(nmj);
    mpz_init(nm2);
    mpz_init(res);
    mpz_init(uh);
    mpz_init(vl);
    mpz_init(vh);
    mpz_init(ql);
    mpz_init(qh);
    mpz_init(tmp);

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

    /* Check if p*p - 4 == 0. */
    mpz_mul(zD, p->z, p->z);
    mpz_sub_ui(zD, zD, 4);
    if (mpz_sgn(zD) == 0) {
        VALUE_ERROR("invalid value for p in is_extra_strong_lucas_prp()");
        goto cleanup;
    }

    /* Require n > 0. */
    if (mpz_sgn(n->z) <= 0) {
        VALUE_ERROR("is_extra_strong_lucas_prp() requires 'n' be greater than 0");
        goto cleanup;
    }

    /* Check for n == 1 */
    if (mpz_cmp_ui(n->z, 1) == 0) {
        result = Py_False;
        goto cleanup;
    }

    /* Handle n even. */
    if (mpz_divisible_ui_p(n->z, 2)) {
        if (mpz_cmp_ui(n->z, 2) == 0)
            result = Py_True;
        else
            result = Py_False;
        goto cleanup;
    }

    /* Check GCD */
    mpz_mul_ui(res, zD, 2);
    mpz_gcd(res, res, n->z);
    if ((mpz_cmp(res, n->z) != 0) && (mpz_cmp_ui(res, 1) > 0)) {
        VALUE_ERROR("is_extra_strong_lucas_prp() requires gcd(n,2*D) == 1");
        goto cleanup;
    }

    /* nmj = n - (D/n), where (D/n) is the Jacobi symbol */
    mpz_set(nmj, n->z);
    ret = mpz_jacobi(zD, n->z);
    if (ret == -1)
        mpz_add_ui(nmj, nmj, 1);
    else if (ret == 1)
        mpz_sub_ui(nmj, nmj, 1);

    r = mpz_scan1(nmj, 0);
    mpz_fdiv_q_2exp(s, nmj, r);

    mpz_set(nm2, n->z);
    mpz_sub_ui(nm2, nm2, 2);

    /* make sure that either U_s == 0 mod n or V_s == +/-2 mod n, or */
    /* V_((2^t)*s) == 0 mod n for some t with 0 <= t < r-1           */
    mpz_set_si(uh, 1);
    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);

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

            /* uh = uh*vh (mod n) */
            mpz_mul(uh, uh, vh);
            mpz_mod(uh, uh, n->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);

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

            /* 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_set(qh, ql);

    /* uh = uh*vl - ql */
    mpz_mul(uh, uh, vl);
    mpz_sub(uh, uh, ql);

    /* 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);

    mpz_mod(uh, uh, n->z);
    mpz_mod(vl, vl, n->z);

    /* uh contains LucasU_s and vl contains LucasV_s */
    if ((mpz_cmp_ui(uh, 0) == 0) || (mpz_cmp_ui(vl, 0) == 0) ||
        (mpz_cmp(vl, nm2) == 0) || (mpz_cmp_si(vl, 2) == 0)) {
        result = Py_True;
        goto cleanup;
    }

    for (j = 1; j < r-1; 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 (mpz_cmp_ui(vl, 0) == 0) {
            result = Py_True;
            goto cleanup;
        }
    }

    result = Py_False;
  cleanup:
    Py_XINCREF(result);
    mpz_clear(zD);
    mpz_clear(s);
    mpz_clear(nmj);
    mpz_clear(nm2);
    mpz_clear(res);
    mpz_clear(uh);
    mpz_clear(vl);
    mpz_clear(vh);
    mpz_clear(ql);
    mpz_clear(qh);
    mpz_clear(tmp);
    Py_XDECREF((PyObject*)p);
    Py_XDECREF((PyObject*)n);
    return result;
}
Example #23
0
File: cal.c Project: hotaru2k3/cal
int main(int argc, char **argv) {
    mpz_t year, tmp1, tmp2, tmp3, tmp4;
    unsigned long day_of_week = 0;
    uintmax_t month_min = 1, month_max = 12;
    int_fast8_t month_days = 0;
    const int_fast8_t months_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,
                                          30, 31
                                        };
    time_t t = time(NULL);
    char weekday[13] = {0}, weekdays[92] = {0}, month_name[13] = {0};
    struct tm *time_struct = localtime(&t);
    setlocale(LC_ALL, "");
    mpz_init(year);
    switch(argc) {
    case 1:
        mpz_set_ui(year, time_struct->tm_year + 1900);
        month_min = month_max = time_struct->tm_mon + 1;
        break;
    case 2:
        mpz_set_str(year, argv[1], 10);
        break;
    default:
        month_min = month_max = strtoumax(argv[1], NULL, 10);
        mpz_set_str(year, argv[2], 10);
    }
    if(mpz_sgn(year) < 1 || !month_min || month_min > 12) {
        fputs("http://opengroup.org/onlinepubs/9699919799/utilities/cal.html\n",
              stderr);
        exit(1);
    }
    for(int_fast8_t i = 0; i < 7; ++i) {
        time_struct->tm_wday = i;
        strftime(weekday, 13, "%a", time_struct);
        strcat(weekdays, weekday);
        strcat(weekdays, " ");
    }
    strcat(weekdays, "\n");
    for(uintmax_t month = month_min; month <= month_max; ++month) {
        time_struct->tm_mon = month - 1;
        strftime(month_name, 13, "%b", time_struct);
        if(month > month_min) putchar('\n');
        for(int_fast8_t i = (23 - strlen(mpz_get_str(NULL, 10, year))) / 2; i > 0; --i)
            putchar(' ');
        fputs(month_name, stdout);
        putchar(' ');
        printf("%s\n", mpz_get_str(NULL, 10, year));
        fputs(weekdays, stdout);
        if(!mpz_cmp_ui(year, 1752) && month == 9) {
            fputs("         1   2  14  15  16", stdout);
            fputs("17  18  19  20  21  22  23", stdout);
            fputs("24  25  26  27  28  29  30", stdout);
        } else {
            month_days = months_days[month - 1];
            mpz_init(tmp1);
            mpz_init(tmp2);
            mpz_init(tmp3);
            mpz_init(tmp4);
            if(mpz_cmp_ui(year, 1752) > 0 || (!mpz_cmp_ui(year, 1752) && month > 9)) {
                /* Gregorian */
                if(month == 2 && mpz_divisible_ui_p(year, 4) && (!mpz_divisible_ui_p(year,
                        100) || mpz_divisible_ui_p(year, 400))) month_days = 29;
                mpz_add_ui(tmp4, year, 4800 - (14 - month) / 12);
                mpz_tdiv_q_ui(tmp1, tmp4, 4);
                mpz_tdiv_q_ui(tmp2, tmp4, 100);
                mpz_tdiv_q_ui(tmp3, tmp4, 400);
                mpz_mul_ui(tmp4, tmp4, 365);
                mpz_add(tmp4, tmp4, tmp1);
                mpz_sub(tmp4, tmp4, tmp2);
                mpz_add(tmp4, tmp4, tmp3);
                mpz_add_ui(tmp4, tmp4, (153 * (month + 12 * ((14 - month) / 12) - 3) + 2) /
                           5);
                mpz_sub_ui(tmp4, tmp4, 32043);
                day_of_week = mpz_tdiv_ui(tmp4, 7);
            } else {
                /* Julian */
                if(month == 2 && mpz_divisible_ui_p(year, 4))
                    month_days = 29;
                mpz_add_ui(tmp2, year, 4800 - (14 - month) / 12);
                mpz_tdiv_q_ui(tmp1, tmp2, 4);
                mpz_mul_ui(tmp2, tmp2, 365);
                mpz_add(tmp2, tmp2, tmp1);
                mpz_add_ui(tmp2, tmp2, (153 * (month + 12 * ((14 - month) / 12) - 3) + 2) /
                           5);
                mpz_sub_ui(tmp2, tmp2, 32081);
                day_of_week = mpz_tdiv_ui(tmp2, 7);
            }
            mpz_clear(tmp1);
            mpz_clear(tmp2);
            mpz_clear(tmp3);
            mpz_clear(tmp4);
            for(uint_fast8_t i = 0; i < day_of_week; ++i) fputs("    ", stdout);
            for(int_fast8_t i = 1; i <= month_days; ++i) {
                printf("%2u", i);
                ++day_of_week;
                if(i < month_days)
                    fputs((day_of_week %= 7) ? "  " : "\n", stdout);
            }
        }
        putchar('\n');
    }
    mpz_clear(year);
    return 0;
}
Example #24
0
static PyObject *
GMPY_mpz_is_lucas_prp(PyObject *self, PyObject *args)
{
    MPZ_Object *n, *p, *q;
    PyObject *result = 0;
    mpz_t zD, res, index;
    /* used for calculating the Lucas U sequence */
    mpz_t uh, vl, vh, ql, qh, tmp;
    mp_bitcnt_t s = 0, j = 0;
    int ret;

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

    mpz_init(zD);
    mpz_init(res);
    mpz_init(index);
    mpz_init(uh);
    mpz_init(vl);
    mpz_init(vh);
    mpz_init(ql);
    mpz_init(qh);
    mpz_init(tmp);

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

    /* Check if p*p - 4*q == 0. */
    mpz_mul(zD, p->z, p->z);
    mpz_mul_ui(tmp, q->z, 4);
    mpz_sub(zD, zD, tmp);
    if (mpz_sgn(zD) == 0) {
        VALUE_ERROR("invalid values for p,q in is_lucas_prp()");
        goto cleanup;
    }

    /* Require n > 0. */
    if (mpz_sgn(n->z) <= 0) {
        VALUE_ERROR("is_lucas_prp() requires 'n' be greater than 0");
        goto cleanup;
    }

    /* Check for n == 1 */
    if (mpz_cmp_ui(n->z, 1) == 0) {
        result = Py_False;
        goto cleanup;
    }

    /* Handle n even. */
    if (mpz_divisible_ui_p(n->z, 2)) {
        if (mpz_cmp_ui(n->z, 2) == 0)
            result = Py_True;
        else
            result = Py_False;
        goto cleanup;
    }

    /* Check GCD */
    mpz_mul(res, zD, q->z);
    mpz_mul_ui(res, res, 2);
    mpz_gcd(res, res, n->z);
    if ((mpz_cmp(res, n->z) != 0) && (mpz_cmp_ui(res, 1) > 0)) {
        VALUE_ERROR("is_lucas_prp() requires gcd(n,2*q*D) == 1");
        goto cleanup;
    }

    /* index = n-(D/n), where (D/n) is the Jacobi symbol */
    mpz_set(index, n->z);
    ret = mpz_jacobi(zD, n->z);
    if (ret == -1)
        mpz_add_ui(index, index, 1);
    else if (ret == 1)
        mpz_sub_ui(index, index, 1);

    /* mpz_lucasumod(res, p, q, index, n); */
    mpz_set_si(uh, 1);
    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(index, 0);
    for (j = mpz_sizeinbase(index,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(index,j) == 1) {
            /* qh = ql*q */
            mpz_mul(qh, ql, q->z);

            /* uh = uh*vh (mod n) */
            mpz_mul(uh, uh, vh);
            mpz_mod(uh, uh, n->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);

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

            /* 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);

    /* uh = uh*vl - ql */
    mpz_mul(uh, uh, vl);
    mpz_sub(uh, uh, ql);

    /* 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++) {
        /* uh = uh*vl (mod n) */
        mpz_mul(uh, uh, vl);
        mpz_mod(uh, uh, 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*ql (mod n) */
        mpz_mul(ql, ql, ql);
        mpz_mod(ql, ql, n->z);
    }

    /* uh contains our return value */
    mpz_mod(res, uh, n->z);
    if (mpz_cmp_ui(res, 0) == 0)
        result = Py_True;
    else
        result = Py_False;

  cleanup:
    Py_XINCREF(result);
    mpz_clear(zD);
    mpz_clear(res);
    mpz_clear(index);
    mpz_clear(uh);
    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*)n);
    return result;
}
Example #25
0
static PyObject *
GMPY_mpz_is_fermat_prp(PyObject *self, PyObject *args)
{
    MPZ_Object *a, *n;
    PyObject *result = 0;
    mpz_t res, nm1;

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

    n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL);
    a = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL);
    if (!a || !n) {
        TYPE_ERROR("is_fermat_prp() requires 2 integer arguments");
        goto cleanup;
    }

    mpz_init(res);
    mpz_init(nm1);

    /* Require a >= 2. */
    if (mpz_cmp_ui(a->z, 2) < 0) {
        VALUE_ERROR("is_fermat_prp() requires 'a' greater than or equal to 2");
        goto cleanup;
    }

    /* Require n > 0. */
    if (mpz_sgn(n->z) <= 0) {
        VALUE_ERROR("is_fermat_prp() requires 'n' be greater than 0");
        goto cleanup;
    }

    /* Check for n == 1 */
    if (mpz_cmp_ui(n->z, 1) == 0) {
        result = Py_False;
        goto cleanup;
    }

    /* Handle n even. */
    /* Should n even raise an exception? */
    if (mpz_divisible_ui_p(n->z, 2)) {
        if (mpz_cmp_ui(n->z, 2) == 0)
            result = Py_True;
        else
            result = Py_False;
        goto cleanup;
    }

    /* Check gcd(a,n) */
    mpz_gcd(res, n->z, a->z);
    if (mpz_cmp_ui(res, 1) > 0) {
        VALUE_ERROR("is_fermat_prp() requires gcd(n,a) == 1");
        goto cleanup;
    }

    mpz_set(nm1, n->z);
    mpz_sub_ui(nm1, nm1, 1);
    mpz_powm(res, a->z, nm1, n->z);

    if (mpz_cmp_ui(res, 1) == 0)
        result = Py_True;
    else
        result = Py_False;

  cleanup:
    Py_XINCREF(result);
    mpz_clear(res);
    mpz_clear(nm1);
    Py_XDECREF((PyObject*)a);
    Py_XDECREF((PyObject*)n);
    return result;
}
Example #26
0
static PyObject *
GMPY_mpz_is_euler_prp(PyObject *self, PyObject *args)
{
    MPZ_Object *a, *n;
    PyObject *result = 0;
    mpz_t res, exp;
    int ret;

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

    n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL);
    a = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL);
    if (!a || !n) {
        TYPE_ERROR("is_euler_prp() requires 2 integer arguments");
        goto cleanup;
    }

    mpz_init(res);
    mpz_init(exp);

    /* Require a >= 2. */
    if (mpz_cmp_ui(a->z, 2) < 0) {
        VALUE_ERROR("is_euler_prp() requires 'a' greater than or equal to 2");
        goto cleanup;
    }

    /* Require n > 0. */
    if (mpz_sgn(n->z) <= 0) {
        VALUE_ERROR("is_euler_prp() requires 'n' be greater than 0");
        goto cleanup;
    }

    /* Check for n == 1 */
    if (mpz_cmp_ui(n->z, 1) == 0) {
        result = Py_False;
        goto cleanup;
    }

    /* Handle n even. */
    if (mpz_divisible_ui_p(n->z, 2)) {
        if (mpz_cmp_ui(n->z, 2) == 0)
            result = Py_True;
        else
            result = Py_False;
        goto cleanup;
    }

    /* Check gcd(a,b) */
    mpz_gcd(res, n->z, a->z);
    if (mpz_cmp_ui(res, 1) > 0) {
        VALUE_ERROR("is_euler_prp() requires gcd(n,a) == 1");
        goto cleanup;
    }

    mpz_set(exp, n->z);
    mpz_sub_ui(exp, exp, 1);
    mpz_divexact_ui(exp, exp, 2);
    mpz_powm(res, a->z, exp, n->z);

    /* reuse exp to calculate jacobi(a,n) mod n */
    ret = mpz_jacobi(a->z,n->z);
    mpz_set(exp, n->z);
    if (ret == -1)
        mpz_sub_ui(exp, exp, 1);
    else if (ret == 1)
        mpz_add_ui(exp, exp, 1);
    mpz_mod(exp, exp, n->z);

    if (mpz_cmp(res, exp) == 0)
        result = Py_True;
    else
        result = Py_False;

  cleanup:
    Py_XINCREF(result);
    mpz_clear(res);
    mpz_clear(exp);
    Py_XDECREF((PyObject*)a);
    Py_XDECREF((PyObject*)n);
    return result;
}
Example #27
0
/* *******************************************************************************************
 * mpz_extrastronglucas_prp:
 * Let U_n = LucasU(p,1), V_n = LucasV(p,1), and D=p^2-4.
 * An "extra strong Lucas pseudoprime" to the base p is a composite n = (2^r)*s+(D/n), where
 * s is odd and (n,2D)=1, such that either U_s == 0 mod n and V_s == +/-2 mod n, or
 * V_((2^t)*s) == 0 mod n for some t with 0 <= t < r-1 [(D/n) is the Jacobi symbol]
 * *******************************************************************************************/
int mpz_extrastronglucas_prp(mpz_t n, long int p)
{
  mpz_t zD;
  mpz_t s;
  mpz_t nmj; /* n minus jacobi(D/n) */
  mpz_t res;
  mpz_t uh, vl, vh, ql, qh, tmp; /* these are needed for the LucasU and LucasV part of this function */
  long int d = p*p - 4;
  long int q = 1;
  unsigned long int r = 0;
  int ret = 0;
  int j = 0;

  if (d == 0) /* Does not produce a proper Lucas sequence */
    return PRP_ERROR;

  if (mpz_cmp_ui(n, 2) < 0)
    return PRP_COMPOSITE;

  if (mpz_divisible_ui_p(n, 2))
  {
    if (mpz_cmp_ui(n, 2) == 0)
      return PRP_PRIME;
    else
      return PRP_COMPOSITE;
  }

  mpz_init_set_si(zD, d);
  mpz_init(res);

  mpz_mul_ui(res, zD, 2);
  mpz_gcd(res, res, n);
  if ((mpz_cmp(res, n) != 0) && (mpz_cmp_ui(res, 1) > 0))
  {
    mpz_clear(zD);
    mpz_clear(res);
    return PRP_COMPOSITE;
  }

  mpz_init(s);
  mpz_init(nmj);

  /* nmj = n - (D/n), where (D/n) is the Jacobi symbol */
  mpz_set(nmj, n);
  ret = mpz_jacobi(zD, n);
  if (ret == -1)
    mpz_add_ui(nmj, nmj, 1);
  else if (ret == 1)
    mpz_sub_ui(nmj, nmj, 1);

  r = mpz_scan1(nmj, 0);
  mpz_fdiv_q_2exp(s, nmj, r);

  /* make sure that either (U_s == 0 mod n and V_s == +/-2 mod n), or */
  /* V_((2^t)*s) == 0 mod n for some t with 0 <= t < r-1              */
  mpz_init_set_si(uh, 1);
  mpz_init_set_si(vl, 2);
  mpz_init_set_si(vh, p);
  mpz_init_set_si(ql, 1);
  mpz_init_set_si(qh, 1);
  mpz_init_set_si(tmp,0);

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

      /* uh = uh*vh (mod n) */
      mpz_mul(uh, uh, vh);
      mpz_mod(uh, uh, n);

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

      /* 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);
    }
    else
    {
      /* qh = ql */
      mpz_set(qh, ql);

      /* uh = uh*vl - ql (mod n) */
      mpz_mul(uh, uh, vl);
      mpz_sub(uh, uh, ql);
      mpz_mod(uh, uh, n);

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

      /* 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);
    }
  }
  /* ql = ql*qh */
  mpz_mul(ql, ql, qh);

  /* qh = ql*q */
  mpz_mul_si(qh, ql, q);

  /* uh = uh*vl - ql */
  mpz_mul(uh, uh, vl);
  mpz_sub(uh, uh, ql);

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

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

  mpz_mod(uh, uh, n);
  mpz_mod(vl, vl, n);

  /* tmp = n-2, for the following comparison */
  mpz_sub_ui(tmp, n, 2);

  /* uh contains LucasU_s and vl contains LucasV_s */
  if (((mpz_cmp_ui(uh, 0) == 0) && ((mpz_cmp(vl, tmp) == 0) || (mpz_cmp_si(vl, 2) == 0)))
    || (mpz_cmp_ui(vl, 0) == 0))
  {
    mpz_clear(zD);
    mpz_clear(s);
    mpz_clear(nmj);
    mpz_clear(res);
    mpz_clear(uh);
    mpz_clear(vl);
    mpz_clear(vh);
    mpz_clear(ql);
    mpz_clear(qh);
    mpz_clear(tmp);
    return PRP_PRP;
  }

  for (j = 1; j < r-1; 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);

    /* ql = ql*ql (mod n) */
    mpz_mul(ql, ql, ql);
    mpz_mod(ql, ql, n);

    if (mpz_cmp_ui(vl, 0) == 0)
    {
      mpz_clear(zD);
      mpz_clear(s);
      mpz_clear(nmj);
      mpz_clear(res);
      mpz_clear(uh);
      mpz_clear(vl);
      mpz_clear(vh);
      mpz_clear(ql);
      mpz_clear(qh);
      mpz_clear(tmp);
      return PRP_PRP;
    }
  }

  mpz_clear(zD);
  mpz_clear(s);
  mpz_clear(nmj);
  mpz_clear(res);
  mpz_clear(uh);
  mpz_clear(vl);
  mpz_clear(vh);
  mpz_clear(ql);
  mpz_clear(qh);
  mpz_clear(tmp);
  return PRP_COMPOSITE;

}/* method mpz_extrastronglucas_prp */
Example #28
0
static PyObject *
GMPY_mpz_is_strongbpsw_prp(PyObject *self, PyObject *args)
{
    MPZ_Object *n;
    PyObject *result = 0, *temp = 0;

    if (PyTuple_Size(args) != 1) {
        TYPE_ERROR("is_strong_bpsw_prp() requires 1 integer argument");
        return NULL;
    }

    n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL);
    if (!n) {
        TYPE_ERROR("is_strong_bpsw_prp() requires 1 integer argument");
        goto cleanup;
    }

    /* Require n > 0. */
    if (mpz_sgn(n->z) <= 0) {
        VALUE_ERROR("is_strong_bpsw_prp() requires 'n' be greater than 0");
        goto cleanup;
    }

    /* Check for n == 1 */
    if (mpz_cmp_ui(n->z, 1) == 0) {
        result = Py_False;
        goto cleanup;
    }

    /* Handle n even. */
    if (mpz_divisible_ui_p(n->z, 2)) {
        if (mpz_cmp_ui(n->z, 2) == 0)
            result = Py_True;
        else
            result = Py_False;
        goto cleanup;
    }

    /* "O" is used to increment the reference to n so deleting temp won't
     * delete n.
     */
    temp = Py_BuildValue("Oi", n, 2);
    if (!temp)
        goto cleanup;
    result = GMPY_mpz_is_strong_prp(NULL, temp);
    Py_DECREF(temp);
    if (result == Py_False)
        goto return_result;
    /* Remember to ignore the preceding result */
    Py_DECREF(result);

    temp = Py_BuildValue("O", n);
    if (!temp)
        goto cleanup;
    result = GMPY_mpz_is_selfridge_prp(NULL, temp);
    Py_DECREF(temp);
    goto return_result;

  cleanup:
    Py_XINCREF(result);
  return_result:
    Py_DECREF((PyObject*)n);
    return result;
}
Example #29
0
/* ***********************************************************************************************
 * mpz_selfridge_prp:
 * A "Lucas-Selfridge pseudoprime" n is a "Lucas pseudoprime" using Selfridge parameters of:
 * Find the first element D in the sequence {5, -7, 9, -11, 13, ...} such that Jacobi(D,n) = -1
 * Then use P=1 and Q=(1-D)/4 in the Lucas pseudoprime test.
 * Make sure n is not a perfect square, otherwise the search for D will only stop when D=n.
 * ***********************************************************************************************/
int mpz_selfridge_prp(mpz_t n)
{
  long int d = 5, p = 1, q = 0;
  int max_d = 1000000;
  int jacobi = 0;
  mpz_t zD;

  if (mpz_cmp_ui(n, 2) < 0)
    return PRP_COMPOSITE;

  if (mpz_divisible_ui_p(n, 2))
  {
    if (mpz_cmp_ui(n, 2) == 0)
      return PRP_PRIME;
    else
      return PRP_COMPOSITE;
  }

  mpz_init_set_ui(zD, d);

  while (1)
  {
    jacobi = mpz_jacobi(zD, n);

    /* if jacobi == 0, d is a factor of n, therefore n is composite... */
    /* if d == n, then either n is either prime or 9... */
    if (jacobi == 0)
    {
      if ((mpz_cmpabs(zD, n) == 0) && (mpz_cmp_ui(zD, 9) != 0))
      {
        mpz_clear(zD);
        return PRP_PRIME;
      }
      else
      {
        mpz_clear(zD);
        return PRP_COMPOSITE;
      }
    }
    if (jacobi == -1)
      break;

    /* if we get to the 5th d, make sure we aren't dealing with a square... */
    if (d == 13)
    {
      if (mpz_perfect_square_p(n))
      {
        mpz_clear(zD);
        return PRP_COMPOSITE;
      }
    }

    if (d < 0)
    {
      d *= -1;
      d += 2;
    }
    else
    {
      d += 2;
      d *= -1;
    }

    /* make sure we don't search forever */
    if (d >= max_d)
    {
      mpz_clear(zD);
      return PRP_ERROR;
    }

    mpz_set_si(zD, d);
  }
  mpz_clear(zD);

  q = (1-d)/4;

  return mpz_lucas_prp(n, p, q);

}/* method mpz_selfridge_prp */
Example #30
0
static PyObject *
GMPY_mpz_is_fibonacci_prp(PyObject *self, PyObject *args)
{
    MPZ_Object *n, *p, *q;
    PyObject *result = 0;
    mpz_t pmodn, zP;
    /* used for calculating the Lucas V sequence */
    mpz_t vl, vh, ql, qh, tmp;
    mp_bitcnt_t s = 0, j = 0;

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

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

    n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL);
    p = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL);
    q = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 2), NULL);
    if (!n || !p || !q) {
        TYPE_ERROR("is_fibonacci_prp() requires 3 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 is_fibonacci_prp()");
        goto cleanup;
    }

    /* Verify q = +/-1 */

    if ((mpz_cmp_si(q->z, 1) && mpz_cmp_si(q->z, -1)) || (mpz_sgn(p->z) <= 0)) {
        VALUE_ERROR("invalid values for p,q in is_fibonacci_prp()");
        goto cleanup;
    }

    /* Require n > 0. */
    if (mpz_sgn(n->z) <= 0) {
        VALUE_ERROR("is_fibonacci_prp() requires 'n' be greater than 0");
        goto cleanup;
    }

    /* Check for n == 1 */
    if (mpz_cmp_ui(n->z, 1) == 0) {
        result = Py_False;
        goto cleanup;
    }

    /* Handle n even. */
    if (mpz_divisible_ui_p(n->z, 2)) {
        if (mpz_cmp_ui(n->z, 2) == 0)
            result = Py_True;
        else
            result = Py_False;
        goto cleanup;
    }

    mpz_set(zP, p->z);
    mpz_mod(pmodn, zP, n->z);

    /* mpz_lucasvmod(res, p, q, n, n); */
    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(n->z, 0);
    for (j = mpz_sizeinbase(n->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(n->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);
    }

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

    if (mpz_cmp(vl, pmodn) == 0)
        result = Py_True;
    else
        result = Py_False;

  cleanup:
    Py_XINCREF(result);
    mpz_clear(pmodn);
    mpz_clear(zP);
    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*)n);
    return result;
}