Ejemplo n.º 1
0
void PrimeAndGenerator::Generate(signed int delta, RandomNumberGenerator &rng, unsigned int pbits, unsigned int qbits)
{
	// no prime exists for delta = -1, qbits = 4, and pbits = 5
	assert(qbits > 4);
	assert(pbits > qbits);

	if (qbits+1 == pbits)
	{
		Integer minP = Integer::Power2(pbits-1);
		Integer maxP = Integer::Power2(pbits) - 1;
		bool success = false;

		while (!success)
		{
			p.Randomize(rng, minP, maxP, Integer::ANY, 6+5*delta, 12);
			PrimeSieve sieve(p, STDMIN(p+PrimeSearchInterval(maxP)*12, maxP), 12, delta);

			while (sieve.NextCandidate(p))
			{
				assert(IsSmallPrime(p) || SmallDivisorsTest(p));
				q = (p-delta) >> 1;
				assert(IsSmallPrime(q) || SmallDivisorsTest(q));
				if (FastProbablePrimeTest(q) && FastProbablePrimeTest(p) && IsPrime(q) && IsPrime(p))
				{
					success = true;
					break;
				}
			}
		}

		if (delta == 1)
		{
			// find g such that g is a quadratic residue mod p, then g has order q
			// g=4 always works, but this way we get the smallest quadratic residue (other than 1)
			for (g=2; Jacobi(g, p) != 1; ++g) {}
			// contributed by Walt Tuvell: g should be the following according to the Law of Quadratic Reciprocity
			assert((p%8==1 || p%8==7) ? g==2 : (p%12==1 || p%12==11) ? g==3 : g==4);
		}
		else
		{
			assert(delta == -1);
			// find g such that g*g-4 is a quadratic non-residue, 
			// and such that g has order q
			for (g=3; ; ++g)
				if (Jacobi(g*g-4, p)==-1 && Lucas(q, g, p)==2)
					break;
		}
	}
Ejemplo n.º 2
0
Integer MihailescuProvablePrime(RandomNumberGenerator &rng, unsigned int pbits)
{
	Integer p;
	Integer minP = Integer::Power2(pbits-1);
	Integer maxP = Integer::Power2(pbits) - 1;

	if (maxP <= Integer(s_lastSmallPrime).Squared())
	{
		// Randomize() will generate a prime provable by trial division
		p.Randomize(rng, minP, maxP, Integer::PRIME);
		return p;
	}

	unsigned int qbits = (pbits+2)/3 + 1 + rng.GenerateWord32(0, pbits/36);
	Integer q = MihailescuProvablePrime(rng, qbits);
	Integer q2 = q<<1;

	while (true)
	{
		// this initializes the sieve to search in the arithmetic
		// progression p = p_0 + \lambda * q2 = p_0 + 2 * \lambda * q,
		// with q the recursively generated prime above. We will be able
		// to use Lucas tets for proving primality. A trick of Quisquater
		// allows taking q > cubic_root(p) rather then square_root: this
		// decreases the recursion.

		p.Randomize(rng, minP, maxP, Integer::ANY, 1, q2);
		PrimeSieve sieve(p, STDMIN(p+PrimeSearchInterval(maxP)*q2, maxP), q2);

		while (sieve.NextCandidate(p))
		{
			if (FastProbablePrimeTest(p) && ProvePrime(p, q))
				return p;
		}
	}

	// not reached
	return p;
}
Ejemplo n.º 3
0
bool FirstPrime(Integer &p, const Integer &max, const Integer &equiv, const Integer &mod)
{
	assert(!equiv.IsNegative() && equiv < mod);

	Integer gcd = GCD(equiv, mod);
	if (gcd != Integer::One())
	{
		// the only possible prime p such that p%mod==equiv where GCD(mod,equiv)!=1 is GCD(mod,equiv)
		if (p <= gcd && gcd <= max && IsPrime(gcd))
		{
			p = gcd;
			return true;
		}
		else
			return false;
	}

	BuildPrimeTable();

	if (p <= primeTable[primeTableSize-1])
	{
		word *pItr;

		--p;
		if (p.IsPositive())
			pItr = std::upper_bound(primeTable, primeTable+primeTableSize, p.ConvertToLong());
		else
			pItr = primeTable;

		while (pItr < primeTable+primeTableSize && *pItr%mod != equiv)
			++pItr;

		if (pItr < primeTable+primeTableSize)
		{
			p = *pItr;
			return p <= max;
		}

		p = primeTable[primeTableSize-1]+1;
	}

	assert(p > primeTable[primeTableSize-1]);

	if (mod.IsOdd())
		return FirstPrime(p, max, CRT(equiv, mod, 1, 2, 1), mod<<1);

	p += (equiv-p)%mod;

	if (p>max)
		return false;

	PrimeSieve sieve(p, max, mod);

	while (sieve.NextCandidate(p))
	{
		if (FastProbablePrimeTest(p) && IsPrime(p))
			return true;
	}

	return false;
}
Ejemplo n.º 4
0
bool FirstPrime(Integer &p, const Integer &max, const Integer &equiv, const Integer &mod, const PrimeSelector *pSelector)
{
	assert(!equiv.IsNegative() && equiv < mod);

	Integer gcd = GCD(equiv, mod);
	if (gcd != Integer::One())
	{
		// the only possible prime p such that p%mod==equiv where GCD(mod,equiv)!=1 is GCD(mod,equiv)
		if (p <= gcd && gcd <= max && IsPrime(gcd) && (!pSelector || pSelector->IsAcceptable(gcd)))
		{
			p = gcd;
			return true;
		}
		else
			return false;
	}

	unsigned int primeTableSize;
	const word16 * primeTable = GetPrimeTable(primeTableSize);

	if (p <= primeTable[primeTableSize-1])
	{
		const word16 *pItr;

		--p;
		if (p.IsPositive())
			pItr = std::upper_bound(primeTable, primeTable+primeTableSize, (word)p.ConvertToLong());
		else
			pItr = primeTable;

		while (pItr < primeTable+primeTableSize && !(*pItr%mod == equiv && (!pSelector || pSelector->IsAcceptable(*pItr))))
			++pItr;

		if (pItr < primeTable+primeTableSize)
		{
			p = *pItr;
			return p <= max;
		}

		p = primeTable[primeTableSize-1]+1;
	}

	assert(p > primeTable[primeTableSize-1]);

	if (mod.IsOdd())
		return FirstPrime(p, max, CRT(equiv, mod, 1, 2, 1), mod<<1, pSelector);

	p += (equiv-p)%mod;

	if (p>max)
		return false;

	PrimeSieve sieve(p, max, mod);

	while (sieve.NextCandidate(p))
	{
		if ((!pSelector || pSelector->IsAcceptable(p)) && FastProbablePrimeTest(p) && IsPrime(p))
			return true;
	}

	return false;
}