1
// nbtheory.cpp - written and placed in the public domain by Wei Dai
5
#ifndef CRYPTOPP_IMPORTS
15
// needed in MSVC 2005 to generate correct manifest
19
NAMESPACE_BEGIN(CryptoPP)
21
const word s_lastSmallPrime = 32719;
25
std::vector<word16> * operator()() const
27
const unsigned int maxPrimeTableSize = 3511;
29
std::auto_ptr<std::vector<word16> > pPrimeTable(new std::vector<word16>);
30
std::vector<word16> &primeTable = *pPrimeTable;
31
primeTable.reserve(maxPrimeTableSize);
33
primeTable.push_back(2);
34
unsigned int testEntriesEnd = 1;
36
for (unsigned int p=3; p<=s_lastSmallPrime; p+=2)
39
for (j=1; j<testEntriesEnd; j++)
40
if (p%primeTable[j] == 0)
42
if (j == testEntriesEnd)
44
primeTable.push_back(p);
45
testEntriesEnd = UnsignedMin(54U, primeTable.size());
49
return pPrimeTable.release();
53
const word16 * GetPrimeTable(unsigned int &size)
55
const std::vector<word16> &primeTable = Singleton<std::vector<word16>, NewPrimeTable>().Ref();
56
size = (unsigned int)primeTable.size();
57
return &primeTable[0];
60
bool IsSmallPrime(const Integer &p)
62
unsigned int primeTableSize;
63
const word16 * primeTable = GetPrimeTable(primeTableSize);
65
if (p.IsPositive() && p <= primeTable[primeTableSize-1])
66
return std::binary_search(primeTable, primeTable+primeTableSize, (word16)p.ConvertToLong());
71
bool TrialDivision(const Integer &p, unsigned bound)
73
unsigned int primeTableSize;
74
const word16 * primeTable = GetPrimeTable(primeTableSize);
76
assert(primeTable[primeTableSize-1] >= bound);
79
for (i = 0; primeTable[i]<bound; i++)
80
if ((p % primeTable[i]) == 0)
83
if (bound == primeTable[i])
84
return (p % bound == 0);
89
bool SmallDivisorsTest(const Integer &p)
91
unsigned int primeTableSize;
92
const word16 * primeTable = GetPrimeTable(primeTableSize);
93
return !TrialDivision(p, primeTable[primeTableSize-1]);
96
bool IsFermatProbablePrime(const Integer &n, const Integer &b)
101
assert(n>3 && b>1 && b<n-1);
102
return a_exp_b_mod_c(b, n-1, n)==1;
105
bool IsStrongProbablePrime(const Integer &n, const Integer &b)
110
assert(n>3 && b>1 && b<n-1);
112
if ((n.IsEven() && n!=2) || GCD(b, n) != 1)
115
Integer nminus1 = (n-1);
118
// calculate a = largest power of 2 that divides (n-1)
120
if (nminus1.GetBit(a))
122
Integer m = nminus1>>a;
124
Integer z = a_exp_b_mod_c(b, m, n);
125
if (z==1 || z==nminus1)
127
for (unsigned j=1; j<a; j++)
138
bool RabinMillerTest(RandomNumberGenerator &rng, const Integer &n, unsigned int rounds)
146
for (unsigned int i=0; i<rounds; i++)
148
b.Randomize(rng, 2, n-2);
149
if (!IsStrongProbablePrime(n, b))
155
bool IsLucasProbablePrime(const Integer &n)
169
while ((j=Jacobi(b.Squared()-4, n)) == 1)
171
if (++i==64 && n.IsSquare()) // avoid infinite loop if n is a square
179
return Lucas(n+1, b, n)==2;
182
bool IsStrongLucasProbablePrime(const Integer &n)
196
while ((j=Jacobi(b.Squared()-4, n)) == 1)
198
if (++i==64 && n.IsSquare()) // avoid infinite loop if n is a square
209
// calculate a = largest power of 2 that divides n1
215
Integer z = Lucas(m, b, n);
220
z = (z.Squared()-2)%n;
229
struct NewLastSmallPrimeSquared
231
Integer * operator()() const
233
return new Integer(Integer(s_lastSmallPrime).Squared());
237
bool IsPrime(const Integer &p)
239
if (p <= s_lastSmallPrime)
240
return IsSmallPrime(p);
241
else if (p <= Singleton<Integer, NewLastSmallPrimeSquared>().Ref())
242
return SmallDivisorsTest(p);
244
return SmallDivisorsTest(p) && IsStrongProbablePrime(p, 3) && IsStrongLucasProbablePrime(p);
247
bool VerifyPrime(RandomNumberGenerator &rng, const Integer &p, unsigned int level)
249
bool pass = IsPrime(p) && RabinMillerTest(rng, p, 1);
251
pass = pass && RabinMillerTest(rng, p, 10);
255
unsigned int PrimeSearchInterval(const Integer &max)
257
return max.BitCount();
260
static inline bool FastProbablePrimeTest(const Integer &n)
262
return IsStrongProbablePrime(n,2);
265
AlgorithmParameters MakeParametersForTwoPrimesOfEqualSize(unsigned int productBitLength)
267
if (productBitLength < 16)
268
throw InvalidArgument("invalid bit length");
272
if (productBitLength%2==0)
274
minP = Integer(182) << (productBitLength/2-8);
275
maxP = Integer::Power2(productBitLength/2)-1;
279
minP = Integer::Power2((productBitLength-1)/2);
280
maxP = Integer(181) << ((productBitLength+1)/2-8);
283
return MakeParameters("RandomNumberType", Integer::PRIME)("Min", minP)("Max", maxP);
289
// delta == 1 or -1 means double sieve with p = 2*q + delta
290
PrimeSieve(const Integer &first, const Integer &last, const Integer &step, signed int delta=0);
291
bool NextCandidate(Integer &c);
294
static void SieveSingle(std::vector<bool> &sieve, word16 p, const Integer &first, const Integer &step, word16 stepInv);
296
Integer m_first, m_last, m_step;
299
std::vector<bool> m_sieve;
302
PrimeSieve::PrimeSieve(const Integer &first, const Integer &last, const Integer &step, signed int delta)
303
: m_first(first), m_last(last), m_step(step), m_delta(delta), m_next(0)
308
bool PrimeSieve::NextCandidate(Integer &c)
310
bool safe = SafeConvert(std::find(m_sieve.begin()+m_next, m_sieve.end(), false) - m_sieve.begin(), m_next);
312
if (m_next == m_sieve.size())
314
m_first += long(m_sieve.size())*m_step;
315
if (m_first > m_last)
321
return NextCandidate(c);
326
c = m_first + long(m_next)*m_step;
332
void PrimeSieve::SieveSingle(std::vector<bool> &sieve, word16 p, const Integer &first, const Integer &step, word16 stepInv)
336
size_t sieveSize = sieve.size();
337
size_t j = (word32(p-(first%p))*stepInv) % p;
338
// if the first multiple of p is p, skip it
339
if (first.WordCount() <= 1 && first + step*long(j) == p)
341
for (; j < sieveSize; j += p)
346
void PrimeSieve::DoSieve()
348
unsigned int primeTableSize;
349
const word16 * primeTable = GetPrimeTable(primeTableSize);
351
const unsigned int maxSieveSize = 32768;
352
unsigned int sieveSize = STDMIN(Integer(maxSieveSize), (m_last-m_first)/m_step+1).ConvertToLong();
355
m_sieve.resize(sieveSize, false);
359
for (unsigned int i = 0; i < primeTableSize; ++i)
360
SieveSingle(m_sieve, primeTable[i], m_first, m_step, (word16)m_step.InverseMod(primeTable[i]));
365
Integer qFirst = (m_first-m_delta) >> 1;
366
Integer halfStep = m_step >> 1;
367
for (unsigned int i = 0; i < primeTableSize; ++i)
369
word16 p = primeTable[i];
370
word16 stepInv = (word16)m_step.InverseMod(p);
371
SieveSingle(m_sieve, p, m_first, m_step, stepInv);
373
word16 halfStepInv = 2*stepInv < p ? 2*stepInv : 2*stepInv-p;
374
SieveSingle(m_sieve, p, qFirst, halfStep, halfStepInv);
379
bool FirstPrime(Integer &p, const Integer &max, const Integer &equiv, const Integer &mod, const PrimeSelector *pSelector)
381
assert(!equiv.IsNegative() && equiv < mod);
383
Integer gcd = GCD(equiv, mod);
384
if (gcd != Integer::One())
386
// the only possible prime p such that p%mod==equiv where GCD(mod,equiv)!=1 is GCD(mod,equiv)
387
if (p <= gcd && gcd <= max && IsPrime(gcd) && (!pSelector || pSelector->IsAcceptable(gcd)))
396
unsigned int primeTableSize;
397
const word16 * primeTable = GetPrimeTable(primeTableSize);
399
if (p <= primeTable[primeTableSize-1])
405
pItr = std::upper_bound(primeTable, primeTable+primeTableSize, (word)p.ConvertToLong());
409
while (pItr < primeTable+primeTableSize && !(*pItr%mod == equiv && (!pSelector || pSelector->IsAcceptable(*pItr))))
412
if (pItr < primeTable+primeTableSize)
418
p = primeTable[primeTableSize-1]+1;
421
assert(p > primeTable[primeTableSize-1]);
424
return FirstPrime(p, max, CRT(equiv, mod, 1, 2, 1), mod<<1, pSelector);
431
PrimeSieve sieve(p, max, mod);
433
while (sieve.NextCandidate(p))
435
if ((!pSelector || pSelector->IsAcceptable(p)) && FastProbablePrimeTest(p) && IsPrime(p))
442
// the following two functions are based on code and comments provided by Preda Mihailescu
443
static bool ProvePrime(const Integer &p, const Integer &q)
448
// this is the Quisquater test. Numbers p having passed the Lucas - Lehmer test
449
// for q and verifying p < q^3 can only be built up of two factors, both = 1 mod q,
450
// or be prime. The next two lines build the discriminant of a quadratic equation
451
// which holds iff p is built up of two factors (excercise ... )
454
if (((r%q).Squared()-4*(r/q)).IsSquare())
457
unsigned int primeTableSize;
458
const word16 * primeTable = GetPrimeTable(primeTableSize);
460
assert(primeTableSize >= 50);
461
for (int i=0; i<50; i++)
463
Integer b = a_exp_b_mod_c(primeTable[i], r, p);
465
return a_exp_b_mod_c(b, q, p) == 1;
470
Integer MihailescuProvablePrime(RandomNumberGenerator &rng, unsigned int pbits)
473
Integer minP = Integer::Power2(pbits-1);
474
Integer maxP = Integer::Power2(pbits) - 1;
476
if (maxP <= Integer(s_lastSmallPrime).Squared())
478
// Randomize() will generate a prime provable by trial division
479
p.Randomize(rng, minP, maxP, Integer::PRIME);
483
unsigned int qbits = (pbits+2)/3 + 1 + rng.GenerateWord32(0, pbits/36);
484
Integer q = MihailescuProvablePrime(rng, qbits);
489
// this initializes the sieve to search in the arithmetic
490
// progression p = p_0 + \lambda * q2 = p_0 + 2 * \lambda * q,
491
// with q the recursively generated prime above. We will be able
492
// to use Lucas tets for proving primality. A trick of Quisquater
493
// allows taking q > cubic_root(p) rather then square_root: this
494
// decreases the recursion.
496
p.Randomize(rng, minP, maxP, Integer::ANY, 1, q2);
497
PrimeSieve sieve(p, STDMIN(p+PrimeSearchInterval(maxP)*q2, maxP), q2);
499
while (sieve.NextCandidate(p))
501
if (FastProbablePrimeTest(p) && ProvePrime(p, q))
510
Integer MaurerProvablePrime(RandomNumberGenerator &rng, unsigned int bits)
512
const unsigned smallPrimeBound = 29, c_opt=10;
515
unsigned int primeTableSize;
516
const word16 * primeTable = GetPrimeTable(primeTableSize);
518
if (bits < smallPrimeBound)
521
p.Randomize(rng, Integer::Power2(bits-1), Integer::Power2(bits)-1, Integer::ANY, 1, 2);
522
while (TrialDivision(p, 1 << ((bits+1)/2)));
526
const unsigned margin = bits > 50 ? 20 : (bits-10)/2;
529
relativeSize = pow(2.0, double(rng.GenerateWord32())/0xffffffff - 1);
530
while (bits * relativeSize >= bits - margin);
533
Integer q = MaurerProvablePrime(rng, unsigned(bits*relativeSize));
534
Integer I = Integer::Power2(bits-2)/q;
536
unsigned int trialDivisorBound = (unsigned int)STDMIN((unsigned long)primeTable[primeTableSize-1], (unsigned long)bits*bits/c_opt);
537
bool success = false;
540
p.Randomize(rng, I, I2, Integer::ANY);
541
p *= q; p <<= 1; ++p;
542
if (!TrialDivision(p, trialDivisorBound))
544
a.Randomize(rng, 2, p-1, Integer::ANY);
545
b = a_exp_b_mod_c(a, (p-1)/q, p);
546
success = (GCD(b-1, p) == 1) && (a_exp_b_mod_c(b, q, p) == 1);
553
Integer CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q, const Integer &u)
555
// isn't operator overloading great?
556
return p * (u * (xq-xp) % q) + xp;
559
cout << hex << t1 << endl;
561
cout << hex << t2 << endl;
563
cout << hex << t3 << endl;
565
cout << hex << t4 << endl;
566
Integer t5 = t4 + xp;
567
cout << hex << t5 << endl;
572
Integer ModularSquareRoot(const Integer &a, const Integer &p)
575
return a_exp_b_mod_c(a, (p+1)/4, p);
586
while (Jacobi(n, p) != -1)
589
Integer y = a_exp_b_mod_c(n, q, p);
590
Integer x = a_exp_b_mod_c(a, (q-1)/2, p);
591
Integer b = (x.Squared()%p)*a%p;
604
return Integer::Zero();
609
for (unsigned i=0; i<r-m-1; i++)
617
assert(x.Squared()%p == a);
621
bool SolveModularQuadraticEquation(Integer &r1, Integer &r2, const Integer &a, const Integer &b, const Integer &c, const Integer &p)
623
Integer D = (b.Squared() - 4*a*c) % p;
624
switch (Jacobi(D, p))
627
assert(false); // not reached
632
r1 = r2 = (-b*(a+a).InverseMod(p)) % p;
633
assert(((r1.Squared()*a + r1*b + c) % p).IsZero());
636
Integer s = ModularSquareRoot(D, p);
637
Integer t = (a+a).InverseMod(p);
640
assert(((r1.Squared()*a + r1*b + c) % p).IsZero());
641
assert(((r2.Squared()*a + r2*b + c) % p).IsZero());
646
Integer ModularRoot(const Integer &a, const Integer &dp, const Integer &dq,
647
const Integer &p, const Integer &q, const Integer &u)
654
p2 = ModularExponentiation((a % p), dp, p);
656
q2 = ModularExponentiation((a % q), dq, q);
658
return CRT(p2, p, q2, q, u);
661
Integer ModularRoot(const Integer &a, const Integer &e,
662
const Integer &p, const Integer &q)
664
Integer dp = EuclideanMultiplicativeInverse(e, p-1);
665
Integer dq = EuclideanMultiplicativeInverse(e, q-1);
666
Integer u = EuclideanMultiplicativeInverse(p, q);
667
assert(!!dp && !!dq && !!u);
668
return ModularRoot(a, dp, dq, p, q, u);
672
Integer GCDI(const Integer &x, const Integer &y)
679
while (a[0]==0 && b[0]==0)
694
switch (a.Compare(b))
717
Integer EuclideanMultiplicativeInverse(const Integer &a, const Integer &b)
719
assert(b.Positive());
722
return EuclideanMultiplicativeInverse(a%b, b);
727
return Integer::Zero(); // no inverse
730
Integer u = EuclideanMultiplicativeInverse(b, a);
732
return Integer::Zero(); // no inverse
734
return (b*(a-u)+1)/a;
737
Integer u=1, d=a, v1=b, v3=b, t1, t3, b2=(b+1)>>1;
741
t1 = Integer::Zero();
781
return Integer::Zero(); // no inverse
785
int Jacobi(const Integer &aIn, const Integer &bIn)
789
Integer b = bIn, a = aIn%bIn;
795
while (a.GetBit(i)==0)
799
if (i%2==1 && (b%8==3 || b%8==5))
802
if (a%4==3 && b%4==3)
809
return (b==1) ? result : 0;
812
Integer Lucas(const Integer &e, const Integer &pIn, const Integer &n)
814
unsigned i = e.BitCount();
816
return Integer::Two();
818
MontgomeryRepresentation m(n);
819
Integer p=m.ConvertIn(pIn%n), two=m.ConvertIn(Integer::Two());
820
Integer v=p, v1=m.Subtract(m.Square(p), two);
827
// v = (v*v1 - p) % m;
828
v = m.Subtract(m.Multiply(v,v1), p);
829
// v1 = (v1*v1 - 2) % m;
830
v1 = m.Subtract(m.Square(v1), two);
834
// v1 = (v*v1 - p) % m;
835
v1 = m.Subtract(m.Multiply(v,v1), p);
836
// v = (v*v - 2) % m;
837
v = m.Subtract(m.Square(v), two);
840
return m.ConvertOut(v);
843
// This is Peter Montgomery's unpublished Lucas sequence evalutation algorithm.
844
// The total number of multiplies and squares used is less than the binary
845
// algorithm (see above). Unfortunately I can't get it to run as fast as
846
// the binary algorithm because of the extra overhead.
848
Integer Lucas(const Integer &n, const Integer &P, const Integer &modulus)
853
#define f(A, B, C) m.Subtract(m.Multiply(A, B), C)
854
#define X2(A) m.Subtract(m.Square(A), two)
855
#define X3(A) m.Multiply(A, m.Subtract(m.Square(A), three))
857
MontgomeryRepresentation m(modulus);
858
Integer two=m.ConvertIn(2), three=m.ConvertIn(3);
859
Integer A=m.ConvertIn(P), B, C, p, d=n, e, r, t, T, U;
864
unsigned int b = WORD_BITS * p.WordCount();
865
Integer alpha = (Integer(5)<<(2*b-2)).SquareRoot() - Integer::Power2(b-1);
880
unsigned int dm2 = d[0], em2 = e[0];
881
unsigned int dm3 = d%3, em3 = e%3;
883
// if ((dm6+em6)%3 == 0 && d <= e + (e>>2))
884
if ((dm3+em3==0 || dm3+em3==3) && (t = e, t >>= 2, t += e, d <= t))
888
// t = d; t += d; t -= e; t /= 3;
890
// e += e; e -= d; e /= 3;
894
t = d; t += e; t /= 3;
905
// if (dm6 == em6 && d <= e + (e>>2))
906
if (dm3 == em3 && dm2 == em2 && (t = e, t >>= 2, t += e, d <= t))
917
if (d <= (t = e, t <<= 2))
951
C = f(T, f(A, B, C), C);
957
if (dm3+em3==0 || dm3+em3==3)
961
d -= e; d -= e; d /= 3;
994
return m.ConvertOut(A);
998
Integer InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q, const Integer &u)
1000
Integer d = (m*m-4);
1002
#pragma omp parallel
1003
#pragma omp sections
1008
p2 = Lucas(EuclideanMultiplicativeInverse(e,p2), m, p);
1013
q2 = Lucas(EuclideanMultiplicativeInverse(e,q2), m, q);
1016
return CRT(p2, p, q2, q, u);
1019
unsigned int FactoringWorkFactor(unsigned int n)
1021
// extrapolated from the table in Odlyzko's "The Future of Integer Factorization"
1022
// updated to reflect the factoring of RSA-130
1024
else return (unsigned int)(2.4 * pow((double)n, 1.0/3.0) * pow(log(double(n)), 2.0/3.0) - 5);
1027
unsigned int DiscreteLogWorkFactor(unsigned int n)
1029
// assuming discrete log takes about the same time as factoring
1031
else return (unsigned int)(2.4 * pow((double)n, 1.0/3.0) * pow(log(double(n)), 2.0/3.0) - 5);
1034
// ********************************************************
1036
void PrimeAndGenerator::Generate(signed int delta, RandomNumberGenerator &rng, unsigned int pbits, unsigned int qbits)
1038
// no prime exists for delta = -1, qbits = 4, and pbits = 5
1040
assert(pbits > qbits);
1042
if (qbits+1 == pbits)
1044
Integer minP = Integer::Power2(pbits-1);
1045
Integer maxP = Integer::Power2(pbits) - 1;
1046
bool success = false;
1050
p.Randomize(rng, minP, maxP, Integer::ANY, 6+5*delta, 12);
1051
PrimeSieve sieve(p, STDMIN(p+PrimeSearchInterval(maxP)*12, maxP), 12, delta);
1053
while (sieve.NextCandidate(p))
1055
assert(IsSmallPrime(p) || SmallDivisorsTest(p));
1057
assert(IsSmallPrime(q) || SmallDivisorsTest(q));
1058
if (FastProbablePrimeTest(q) && FastProbablePrimeTest(p) && IsPrime(q) && IsPrime(p))
1068
// find g such that g is a quadratic residue mod p, then g has order q
1069
// g=4 always works, but this way we get the smallest quadratic residue (other than 1)
1070
for (g=2; Jacobi(g, p) != 1; ++g) {}
1071
// contributed by Walt Tuvell: g should be the following according to the Law of Quadratic Reciprocity
1072
assert((p%8==1 || p%8==7) ? g==2 : (p%12==1 || p%12==11) ? g==3 : g==4);
1076
assert(delta == -1);
1077
// find g such that g*g-4 is a quadratic non-residue,
1078
// and such that g has order q
1080
if (Jacobi(g*g-4, p)==-1 && Lucas(q, g, p)==2)
1086
Integer minQ = Integer::Power2(qbits-1);
1087
Integer maxQ = Integer::Power2(qbits) - 1;
1088
Integer minP = Integer::Power2(pbits-1);
1089
Integer maxP = Integer::Power2(pbits) - 1;
1093
q.Randomize(rng, minQ, maxQ, Integer::PRIME);
1094
} while (!p.Randomize(rng, minP, maxP, Integer::PRIME, delta%q, q));
1096
// find a random g of order q
1101
Integer h(rng, 2, p-2, Integer::ANY);
1102
g = a_exp_b_mod_c(h, (p-1)/q, p);
1104
assert(a_exp_b_mod_c(g, q, p)==1);
1111
Integer h(rng, 3, p-1, Integer::ANY);
1112
if (Jacobi(h*h-4, p)==1)
1114
g = Lucas((p+1)/q, h, p);
1116
assert(Lucas(q, g, p) == 2);