示例#1
0
/* In the _vast_ majority of cases this simply checks that your chosen random
 * number is >= KLastSmallPrimeSquared and return EFalse and lets the normal
 * prime generation routines handle the situation.  In the case where it is
 * smaller, it generates a provable prime and returns ETrue.  The algorithm for
 * finding a provable prime < KLastPrimeSquared is not the most efficient in the
 * world, but two points come to mind
 * 1) The two if statements hardly _ever_ evaluate to ETrue in real life.
 * 2) Even when it is, the distribution of primes < KLastPrimeSquared is pretty
 * dense, so you aren't going to have check many.
 * This function is essentially here for two reasons:
 * 1) Ensures that it is possible to generate primes < KLastPrimeSquared (the
 * test code does this)
 * 2) Ensures that if you request a prime of a large bit size that there is an
 * even probability distribution across all integers < 2^aBits
 */
TBool TInteger::SmallPrimeRandomizeL(void)
	{
	TBool foundPrime = EFalse;
	//If the random number we've chosen is less than KLastSmallPrime,
	//testing for primality is easy.
	if(*this <= KLastSmallPrime)
		{
		//If Zero or One, or two, next prime number is two
		if(IsZero() || *this == One() || *this == Two())
			{
			CopyL(TInteger::Two());
			foundPrime = ETrue;
			}
		else
			{
			//Make sure any number we bother testing is at least odd
			SetBit(0);
			//Binary search the small primes.
			while(!IsSmallPrime(ConvertToUnsignedLong()))
				{
				//If not prime, add two and try the next odd number.

				//will never carry as the minimum size of an RInteger is 2
				//words.  Much bigger than KLastSmallPrime on 32bit
				//architectures.
				IncrementNoCarry(Ptr(), Size(), 2);
				}
			assert(IsSmallPrime(ConvertToUnsignedLong()));
			foundPrime = ETrue;
			}
		}
	else if(*this <= KLastSmallPrimeSquared)
		{
		//Make sure any number we bother testing is at least odd
		SetBit(0);

		while(HasSmallDivisorL(*this) && *this <= KLastSmallPrimeSquared)
			{
			//If not prime, add two and try the next odd number.

			//will never carry as the minimum size of an RInteger is 2
			//words.  Much bigger than KLastSmallPrime on 32bit
			//architectures.
			IncrementNoCarry(Ptr(), Size(), 2);
			}
		//If we exited while loop because it had no small divisor then it is
		//prime.  Otherwise, we've exceeded the limit of what we can provably
		//generate.  Therefore the normal prime gen routines will be run on it
		//now.
		if(*this < KLastSmallPrimeSquared)
			{
			foundPrime = ETrue;
			}
		}
	//This doesn't mean there is no such prime, simply means that the number
	//wasn't less than KSmallPrimeSquared and needs to be handled by the normal
	//prime generation routines.
	return foundPrime;
	}
示例#2
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;
		}
	}
示例#3
0
bool IsPrime(const Integer &p)
{
	if (p <= s_lastSmallPrime)
		return IsSmallPrime(p);
	else if (p <= Singleton<Integer, NewLastSmallPrimeSquared>().Ref())
		return SmallDivisorsTest(p);
	else
		return SmallDivisorsTest(p) && IsStrongProbablePrime(p, 3) && IsStrongLucasProbablePrime(p);
}
示例#4
0
文件: nbtheory.cpp 项目: vgck/opendr2
bool IsPrime(const Integer &p)
{
	static const Integer lastSmallPrimeSquared = Integer(lastSmallPrime).Squared();

	if (p <= lastSmallPrime)
		return IsSmallPrime(p);
	else if (p <= lastSmallPrimeSquared)
		return SmallDivisorsTest(p);
	else
		return SmallDivisorsTest(p) && IsStrongProbablePrime(p, 3) && IsStrongLucasProbablePrime(p);
}
示例#5
0
TBool TInteger::IsPrimeL(void) const
	{
	if( NotPositive() )
		{
		return EFalse;
		}
	else if( IsEven() )
		{
		return *this == Two();
		}
	else if( *this <= KLastSmallPrime )
		{
		assert(KLastSmallPrime < KMaxTUint);
		return IsSmallPrime(this->ConvertToUnsignedLong());
		}
	else if( *this <= KLastSmallPrimeSquared )
		{
		return !HasSmallDivisorL(*this);
		}
	else 
		{
		return !HasSmallDivisorL(*this) && IsStrongProbablePrimeL(*this);
		}
	}