Crypto++  8.9
Free C++ class library of cryptographic schemes
nbtheory.cpp
1 // nbtheory.cpp - originally written and placed in the public domain by Wei Dai
2 
3 #include "pch.h"
4 
5 #ifndef CRYPTOPP_IMPORTS
6 
7 #include "nbtheory.h"
8 #include "integer.h"
9 #include "modarith.h"
10 #include "algparam.h"
11 #include "smartptr.h"
12 #include "misc.h"
13 #include "stdcpp.h"
14 #include "trap.h"
15 
16 #ifdef _OPENMP
17 # include <omp.h>
18 #endif
19 
20 NAMESPACE_BEGIN(CryptoPP)
21 
22 // Keep sync'd with primetab.cpp
23 const unsigned int maxPrimeTableSize = 3511;
24 const word s_lastSmallPrime = 32719;
25 
26 const word16 * GetPrimeTable(unsigned int &size)
27 {
28  extern const word16 precomputedPrimeTable[maxPrimeTableSize];
29  size = maxPrimeTableSize;
30  return precomputedPrimeTable;
31 }
32 
33 bool IsSmallPrime(const Integer &p)
34 {
35  unsigned int primeTableSize;
36  const word16 * primeTable = GetPrimeTable(primeTableSize);
37 
38  if (p.IsPositive() && p <= primeTable[primeTableSize-1])
39  return std::binary_search(primeTable, primeTable+primeTableSize, (word16)p.ConvertToLong());
40  else
41  return false;
42 }
43 
44 bool TrialDivision(const Integer &p, unsigned bound)
45 {
46  unsigned int primeTableSize;
47  const word16 * primeTable = GetPrimeTable(primeTableSize);
48 
49  CRYPTOPP_ASSERT(primeTable[primeTableSize-1] >= bound);
50 
51  unsigned int i;
52  for (i = 0; primeTable[i]<bound; i++)
53  if ((p % primeTable[i]) == 0)
54  return true;
55 
56  if (bound == primeTable[i])
57  return (p % bound == 0);
58  else
59  return false;
60 }
61 
62 bool SmallDivisorsTest(const Integer &p)
63 {
64  unsigned int primeTableSize;
65  const word16 * primeTable = GetPrimeTable(primeTableSize);
66  return !TrialDivision(p, primeTable[primeTableSize-1]);
67 }
68 
69 bool IsFermatProbablePrime(const Integer &n, const Integer &b)
70 {
71  if (n <= 3)
72  return n==2 || n==3;
73 
74  CRYPTOPP_ASSERT(n>3 && b>1 && b<n-1);
75  return a_exp_b_mod_c(b, n-1, n)==1;
76 }
77 
78 bool IsStrongProbablePrime(const Integer &n, const Integer &b)
79 {
80  if (n <= 3)
81  return n==2 || n==3;
82 
83  CRYPTOPP_ASSERT(n>3 && b>1 && b<n-1);
84 
85  if ((n.IsEven() && n!=2) || GCD(b, n) != 1)
86  return false;
87 
88  Integer nminus1 = (n-1);
89  unsigned int a;
90 
91  // calculate a = largest power of 2 that divides (n-1)
92  for (a=0; ; a++)
93  if (nminus1.GetBit(a))
94  break;
95  Integer m = nminus1>>a;
96 
97  Integer z = a_exp_b_mod_c(b, m, n);
98  if (z==1 || z==nminus1)
99  return true;
100  for (unsigned j=1; j<a; j++)
101  {
102  z = z.Squared()%n;
103  if (z==nminus1)
104  return true;
105  if (z==1)
106  return false;
107  }
108  return false;
109 }
110 
111 bool RabinMillerTest(RandomNumberGenerator &rng, const Integer &n, unsigned int rounds)
112 {
113  if (n <= 3)
114  return n==2 || n==3;
115 
116  CRYPTOPP_ASSERT(n>3);
117 
118  Integer b;
119  for (unsigned int i=0; i<rounds; i++)
120  {
121  b.Randomize(rng, 2, n-2);
122  if (!IsStrongProbablePrime(n, b))
123  return false;
124  }
125  return true;
126 }
127 
128 bool IsLucasProbablePrime(const Integer &n)
129 {
130  if (n <= 1)
131  return false;
132 
133  if (n.IsEven())
134  return n==2;
135 
136  CRYPTOPP_ASSERT(n>2);
137 
138  Integer b=3;
139  unsigned int i=0;
140  int j;
141 
142  while ((j=Jacobi(b.Squared()-4, n)) == 1)
143  {
144  if (++i==64 && n.IsSquare()) // avoid infinite loop if n is a square
145  return false;
146  ++b; ++b;
147  }
148 
149  if (j==0)
150  return false;
151  else
152  return Lucas(n+1, b, n)==2;
153 }
154 
155 bool IsStrongLucasProbablePrime(const Integer &n)
156 {
157  if (n <= 1)
158  return false;
159 
160  if (n.IsEven())
161  return n==2;
162 
163  CRYPTOPP_ASSERT(n>2);
164 
165  Integer b=3;
166  unsigned int i=0;
167  int j;
168 
169  while ((j=Jacobi(b.Squared()-4, n)) == 1)
170  {
171  if (++i==64 && n.IsSquare()) // avoid infinite loop if n is a square
172  return false;
173  ++b; ++b;
174  }
175 
176  if (j==0)
177  return false;
178 
179  Integer n1 = n+1;
180  unsigned int a;
181 
182  // calculate a = largest power of 2 that divides n1
183  for (a=0; ; a++)
184  if (n1.GetBit(a))
185  break;
186  Integer m = n1>>a;
187 
188  Integer z = Lucas(m, b, n);
189  if (z==2 || z==n-2)
190  return true;
191  for (i=1; i<a; i++)
192  {
193  z = (z.Squared()-2)%n;
194  if (z==n-2)
195  return true;
196  if (z==2)
197  return false;
198  }
199  return false;
200 }
201 
202 struct NewLastSmallPrimeSquared
203 {
204  Integer * operator()() const
205  {
206  return new Integer(Integer(s_lastSmallPrime).Squared());
207  }
208 };
209 
210 bool IsPrime(const Integer &p)
211 {
212  if (p <= s_lastSmallPrime)
213  return IsSmallPrime(p);
214  else if (p <= Singleton<Integer, NewLastSmallPrimeSquared>().Ref())
215  return SmallDivisorsTest(p);
216  else
218 }
219 
220 bool VerifyPrime(RandomNumberGenerator &rng, const Integer &p, unsigned int level)
221 {
222  bool pass = IsPrime(p) && RabinMillerTest(rng, p, 1);
223  if (level >= 1)
224  pass = pass && RabinMillerTest(rng, p, 10);
225  return pass;
226 }
227 
228 unsigned int PrimeSearchInterval(const Integer &max)
229 {
230  return max.BitCount();
231 }
232 
233 static inline bool FastProbablePrimeTest(const Integer &n)
234 {
235  return IsStrongProbablePrime(n,2);
236 }
237 
238 AlgorithmParameters MakeParametersForTwoPrimesOfEqualSize(unsigned int productBitLength)
239 {
240  if (productBitLength < 16)
241  throw InvalidArgument("invalid bit length");
242 
243  Integer minP, maxP;
244 
245  if (productBitLength%2==0)
246  {
247  minP = Integer(182) << (productBitLength/2-8);
248  maxP = Integer::Power2(productBitLength/2)-1;
249  }
250  else
251  {
252  minP = Integer::Power2((productBitLength-1)/2);
253  maxP = Integer(181) << ((productBitLength+1)/2-8);
254  }
255 
256  return MakeParameters("RandomNumberType", Integer::PRIME)("Min", minP)("Max", maxP);
257 }
258 
259 class PrimeSieve
260 {
261 public:
262  // delta == 1 or -1 means double sieve with p = 2*q + delta
263  PrimeSieve(const Integer &first, const Integer &last, const Integer &step, signed int delta=0);
264  bool NextCandidate(Integer &c);
265 
266  void DoSieve();
267  static void SieveSingle(std::vector<bool> &sieve, word16 p, const Integer &first, const Integer &step, word16 stepInv);
268 
269  Integer m_first, m_last, m_step;
270  signed int m_delta;
271  word m_next;
272  std::vector<bool> m_sieve;
273 };
274 
275 PrimeSieve::PrimeSieve(const Integer &first, const Integer &last, const Integer &step, signed int delta)
276  : m_first(first), m_last(last), m_step(step), m_delta(delta), m_next(0)
277 {
278  DoSieve();
279 }
280 
281 bool PrimeSieve::NextCandidate(Integer &c)
282 {
283  bool safe = SafeConvert(std::find(m_sieve.begin()+m_next, m_sieve.end(), false) - m_sieve.begin(), m_next);
284  CRYPTOPP_UNUSED(safe); CRYPTOPP_ASSERT(safe);
285  if (m_next == m_sieve.size())
286  {
287  m_first += long(m_sieve.size())*m_step;
288  if (m_first > m_last)
289  return false;
290  else
291  {
292  m_next = 0;
293  DoSieve();
294  return NextCandidate(c);
295  }
296  }
297  else
298  {
299  c = m_first + long(m_next)*m_step;
300  ++m_next;
301  return true;
302  }
303 }
304 
305 void PrimeSieve::SieveSingle(std::vector<bool> &sieve, word16 p, const Integer &first, const Integer &step, word16 stepInv)
306 {
307  if (stepInv)
308  {
309  size_t sieveSize = sieve.size();
310  size_t j = (word32(p-(first%p))*stepInv) % p;
311  // if the first multiple of p is p, skip it
312  if (first.WordCount() <= 1 && first + step*long(j) == p)
313  j += p;
314  for (; j < sieveSize; j += p)
315  sieve[j] = true;
316  }
317 }
318 
319 void PrimeSieve::DoSieve()
320 {
321  unsigned int primeTableSize;
322  const word16 * primeTable = GetPrimeTable(primeTableSize);
323 
324  const unsigned int maxSieveSize = 32768;
325  unsigned int sieveSize = STDMIN(Integer(maxSieveSize), (m_last-m_first)/m_step+1).ConvertToLong();
326 
327  m_sieve.clear();
328  m_sieve.resize(sieveSize, false);
329 
330  if (m_delta == 0)
331  {
332  for (unsigned int i = 0; i < primeTableSize; ++i)
333  SieveSingle(m_sieve, primeTable[i], m_first, m_step, (word16)m_step.InverseMod(primeTable[i]));
334  }
335  else
336  {
337  CRYPTOPP_ASSERT(m_step%2==0);
338  Integer qFirst = (m_first-m_delta) >> 1;
339  Integer halfStep = m_step >> 1;
340  for (unsigned int i = 0; i < primeTableSize; ++i)
341  {
342  word16 p = primeTable[i];
343  word16 stepInv = (word16)m_step.InverseMod(p);
344  SieveSingle(m_sieve, p, m_first, m_step, stepInv);
345 
346  word16 halfStepInv = 2*stepInv < p ? 2*stepInv : 2*stepInv-p;
347  SieveSingle(m_sieve, p, qFirst, halfStep, halfStepInv);
348  }
349  }
350 }
351 
352 bool FirstPrime(Integer &p, const Integer &max, const Integer &equiv, const Integer &mod, const PrimeSelector *pSelector)
353 {
354  CRYPTOPP_ASSERT(!equiv.IsNegative() && equiv < mod);
355 
356  Integer gcd = GCD(equiv, mod);
357  if (gcd != Integer::One())
358  {
359  // the only possible prime p such that p%mod==equiv where GCD(mod,equiv)!=1 is GCD(mod,equiv)
360  if (p <= gcd && gcd <= max && IsPrime(gcd) && (!pSelector || pSelector->IsAcceptable(gcd)))
361  {
362  p = gcd;
363  return true;
364  }
365  else
366  return false;
367  }
368 
369  unsigned int primeTableSize;
370  const word16 * primeTable = GetPrimeTable(primeTableSize);
371 
372  if (p <= primeTable[primeTableSize-1])
373  {
374  const word16 *pItr;
375 
376  --p;
377  if (p.IsPositive())
378  pItr = std::upper_bound(primeTable, primeTable+primeTableSize, (word)p.ConvertToLong());
379  else
380  pItr = primeTable;
381 
382  while (pItr < primeTable+primeTableSize && !(*pItr%mod == equiv && (!pSelector || pSelector->IsAcceptable(*pItr))))
383  ++pItr;
384 
385  if (pItr < primeTable+primeTableSize)
386  {
387  p = *pItr;
388  return p <= max;
389  }
390 
391  p = primeTable[primeTableSize-1]+1;
392  }
393 
394  CRYPTOPP_ASSERT(p > primeTable[primeTableSize-1]);
395 
396  if (mod.IsOdd())
397  return FirstPrime(p, max, CRT(equiv, mod, 1, 2, 1), mod<<1, pSelector);
398 
399  p += (equiv-p)%mod;
400 
401  if (p>max)
402  return false;
403 
404  PrimeSieve sieve(p, max, mod);
405 
406  while (sieve.NextCandidate(p))
407  {
408  if ((!pSelector || pSelector->IsAcceptable(p)) && FastProbablePrimeTest(p) && IsPrime(p))
409  return true;
410  }
411 
412  return false;
413 }
414 
415 // the following two functions are based on code and comments provided by Preda Mihailescu
416 static bool ProvePrime(const Integer &p, const Integer &q)
417 {
418  CRYPTOPP_ASSERT(p < q*q*q);
419  CRYPTOPP_ASSERT(p % q == 1);
420 
421 // this is the Quisquater test. Numbers p having passed the Lucas - Lehmer test
422 // for q and verifying p < q^3 can only be built up of two factors, both = 1 mod q,
423 // or be prime. The next two lines build the discriminant of a quadratic equation
424 // which holds iff p is built up of two factors (exercise ... )
425 
426  Integer r = (p-1)/q;
427  if (((r%q).Squared()-4*(r/q)).IsSquare())
428  return false;
429 
430  unsigned int primeTableSize;
431  const word16 * primeTable = GetPrimeTable(primeTableSize);
432 
433  CRYPTOPP_ASSERT(primeTableSize >= 50);
434  for (int i=0; i<50; i++)
435  {
436  Integer b = a_exp_b_mod_c(primeTable[i], r, p);
437  if (b != 1)
438  return a_exp_b_mod_c(b, q, p) == 1;
439  }
440  return false;
441 }
442 
443 Integer MihailescuProvablePrime(RandomNumberGenerator &rng, unsigned int pbits)
444 {
445  Integer p;
446  Integer minP = Integer::Power2(pbits-1);
447  Integer maxP = Integer::Power2(pbits) - 1;
448 
449  if (maxP <= Integer(s_lastSmallPrime).Squared())
450  {
451  // Randomize() will generate a prime provable by trial division
452  p.Randomize(rng, minP, maxP, Integer::PRIME);
453  return p;
454  }
455 
456  unsigned int qbits = (pbits+2)/3 + 1 + rng.GenerateWord32(0, pbits/36);
457  Integer q = MihailescuProvablePrime(rng, qbits);
458  Integer q2 = q<<1;
459 
460  while (true)
461  {
462  // this initializes the sieve to search in the arithmetic
463  // progression p = p_0 + \lambda * q2 = p_0 + 2 * \lambda * q,
464  // with q the recursively generated prime above. We will be able
465  // to use Lucas tets for proving primality. A trick of Quisquater
466  // allows taking q > cubic_root(p) rather than square_root: this
467  // decreases the recursion.
468 
469  p.Randomize(rng, minP, maxP, Integer::ANY, 1, q2);
470  PrimeSieve sieve(p, STDMIN(p+PrimeSearchInterval(maxP)*q2, maxP), q2);
471 
472  while (sieve.NextCandidate(p))
473  {
474  if (FastProbablePrimeTest(p) && ProvePrime(p, q))
475  return p;
476  }
477  }
478 
479  // not reached
480  return p;
481 }
482 
483 Integer MaurerProvablePrime(RandomNumberGenerator &rng, unsigned int bits)
484 {
485  const unsigned smallPrimeBound = 29, c_opt=10;
486  Integer p;
487 
488  unsigned int primeTableSize;
489  const word16 * primeTable = GetPrimeTable(primeTableSize);
490 
491  if (bits < smallPrimeBound)
492  {
493  do
494  p.Randomize(rng, Integer::Power2(bits-1), Integer::Power2(bits)-1, Integer::ANY, 1, 2);
495  while (TrialDivision(p, 1 << ((bits+1)/2)));
496  }
497  else
498  {
499  const unsigned margin = bits > 50 ? 20 : (bits-10)/2;
500  double relativeSize;
501  do
502  relativeSize = std::pow(2.0, double(rng.GenerateWord32())/0xffffffff - 1);
503  while (bits * relativeSize >= bits - margin);
504 
505  Integer a,b;
506  Integer q = MaurerProvablePrime(rng, unsigned(bits*relativeSize));
507  Integer I = Integer::Power2(bits-2)/q;
508  Integer I2 = I << 1;
509  unsigned int trialDivisorBound = (unsigned int)STDMIN((unsigned long)primeTable[primeTableSize-1], (unsigned long)bits*bits/c_opt);
510  bool success = false;
511  while (!success)
512  {
513  p.Randomize(rng, I, I2, Integer::ANY);
514  p *= q; p <<= 1; ++p;
515  if (!TrialDivision(p, trialDivisorBound))
516  {
517  a.Randomize(rng, 2, p-1, Integer::ANY);
518  b = a_exp_b_mod_c(a, (p-1)/q, p);
519  success = (GCD(b-1, p) == 1) && (a_exp_b_mod_c(b, q, p) == 1);
520  }
521  }
522  }
523  return p;
524 }
525 
526 Integer CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q, const Integer &u)
527 {
528  // Callers must ensure p and q are prime, GH #1249
529  CRYPTOPP_ASSERT(IsPrime(p) && IsPrime(q));
530 
531  // isn't operator overloading great?
532  return p * (u * (xq-xp) % q) + xp;
533 /*
534  Integer t1 = xq-xp;
535  cout << hex << t1 << endl;
536  Integer t2 = u * t1;
537  cout << hex << t2 << endl;
538  Integer t3 = t2 % q;
539  cout << hex << t3 << endl;
540  Integer t4 = p * t3;
541  cout << hex << t4 << endl;
542  Integer t5 = t4 + xp;
543  cout << hex << t5 << endl;
544  return t5;
545 */
546 }
547 
548 Integer ModularSquareRoot(const Integer &a, const Integer &p)
549 {
550  // Callers must ensure p is prime, GH #1249
552 
553  if (p%4 == 3)
554  return a_exp_b_mod_c(a, (p+1)/4, p);
555 
556  Integer q=p-1;
557  unsigned int r=0;
558  while (q.IsEven())
559  {
560  r++;
561  q >>= 1;
562  }
563 
564  Integer n=2;
565  while (Jacobi(n, p) != -1)
566  ++n;
567 
568  Integer y = a_exp_b_mod_c(n, q, p);
569  Integer x = a_exp_b_mod_c(a, (q-1)/2, p);
570  Integer b = (x.Squared()%p)*a%p;
571  x = a*x%p;
572  Integer tempb, t;
573 
574  while (b != 1)
575  {
576  unsigned m=0;
577  tempb = b;
578  do
579  {
580  m++;
581  b = b.Squared()%p;
582  if (m==r)
583  return Integer::Zero();
584  }
585  while (b != 1);
586 
587  t = y;
588  for (unsigned i=0; i<r-m-1; i++)
589  t = t.Squared()%p;
590  y = t.Squared()%p;
591  r = m;
592  x = x*t%p;
593  b = tempb*y%p;
594  }
595 
596  CRYPTOPP_ASSERT(x.Squared()%p == a);
597  return x;
598 }
599 
600 bool SolveModularQuadraticEquation(Integer &r1, Integer &r2, const Integer &a, const Integer &b, const Integer &c, const Integer &p)
601 {
602  // Callers must ensure p is prime, GH #1249
604 
605  Integer D = (b.Squared() - 4*a*c) % p;
606  switch (Jacobi(D, p))
607  {
608  default:
609  CRYPTOPP_ASSERT(false); // not reached
610  return false;
611  case -1:
612  return false;
613  case 0:
614  r1 = r2 = (-b*(a+a).InverseMod(p)) % p;
615  CRYPTOPP_ASSERT(((r1.Squared()*a + r1*b + c) % p).IsZero());
616  return true;
617  case 1:
618  Integer s = ModularSquareRoot(D, p);
619  Integer t = (a+a).InverseMod(p);
620  r1 = (s-b)*t % p;
621  r2 = (-s-b)*t % p;
622  CRYPTOPP_ASSERT(((r1.Squared()*a + r1*b + c) % p).IsZero());
623  CRYPTOPP_ASSERT(((r2.Squared()*a + r2*b + c) % p).IsZero());
624  return true;
625  }
626 }
627 
628 Integer ModularRoot(const Integer &a, const Integer &dp, const Integer &dq,
629  const Integer &p, const Integer &q, const Integer &u)
630 {
631  // Callers must ensure p and q are prime, GH #1249
632  CRYPTOPP_ASSERT(IsPrime(p) && IsPrime(q));
633 
634  // GCC warning bug, https://stackoverflow.com/q/12842306/608639
635 #ifdef _OPENMP
636  Integer p2, q2;
637  #pragma omp parallel
638  #pragma omp sections
639  {
640  #pragma omp section
641  p2 = ModularExponentiation((a % p), dp, p);
642  #pragma omp section
643  q2 = ModularExponentiation((a % q), dq, q);
644  }
645 #else
646  const Integer p2 = ModularExponentiation((a % p), dp, p);
647  const Integer q2 = ModularExponentiation((a % q), dq, q);
648 #endif
649 
650  return CRT(p2, p, q2, q, u);
651 }
652 
653 Integer ModularRoot(const Integer &a, const Integer &e,
654  const Integer &p, const Integer &q)
655 {
656  // Callers must ensure p and q are prime, GH #1249
657  CRYPTOPP_ASSERT(IsPrime(p) && IsPrime(q));
658 
662  CRYPTOPP_ASSERT(!!dp && !!dq && !!u);
663  return ModularRoot(a, dp, dq, p, q, u);
664 }
665 
666 /*
667 Integer GCDI(const Integer &x, const Integer &y)
668 {
669  Integer a=x, b=y;
670  unsigned k=0;
671 
672  CRYPTOPP_ASSERT(!!a && !!b);
673 
674  while (a[0]==0 && b[0]==0)
675  {
676  a >>= 1;
677  b >>= 1;
678  k++;
679  }
680 
681  while (a[0]==0)
682  a >>= 1;
683 
684  while (b[0]==0)
685  b >>= 1;
686 
687  while (1)
688  {
689  switch (a.Compare(b))
690  {
691  case -1:
692  b -= a;
693  while (b[0]==0)
694  b >>= 1;
695  break;
696 
697  case 0:
698  return (a <<= k);
699 
700  case 1:
701  a -= b;
702  while (a[0]==0)
703  a >>= 1;
704  break;
705 
706  default:
707  CRYPTOPP_ASSERT(false);
708  }
709  }
710 }
711 
712 Integer EuclideanMultiplicativeInverse(const Integer &a, const Integer &b)
713 {
714  CRYPTOPP_ASSERT(b.Positive());
715 
716  if (a.Negative())
717  return EuclideanMultiplicativeInverse(a%b, b);
718 
719  if (b[0]==0)
720  {
721  if (!b || a[0]==0)
722  return Integer::Zero(); // no inverse
723  if (a==1)
724  return 1;
725  Integer u = EuclideanMultiplicativeInverse(b, a);
726  if (!u)
727  return Integer::Zero(); // no inverse
728  else
729  return (b*(a-u)+1)/a;
730  }
731 
732  Integer u=1, d=a, v1=b, v3=b, t1, t3, b2=(b+1)>>1;
733 
734  if (a[0])
735  {
736  t1 = Integer::Zero();
737  t3 = -b;
738  }
739  else
740  {
741  t1 = b2;
742  t3 = a>>1;
743  }
744 
745  while (!!t3)
746  {
747  while (t3[0]==0)
748  {
749  t3 >>= 1;
750  if (t1[0]==0)
751  t1 >>= 1;
752  else
753  {
754  t1 >>= 1;
755  t1 += b2;
756  }
757  }
758  if (t3.Positive())
759  {
760  u = t1;
761  d = t3;
762  }
763  else
764  {
765  v1 = b-t1;
766  v3 = -t3;
767  }
768  t1 = u-v1;
769  t3 = d-v3;
770  if (t1.Negative())
771  t1 += b;
772  }
773  if (d==1)
774  return u;
775  else
776  return Integer::Zero(); // no inverse
777 }
778 */
779 
780 int Jacobi(const Integer &aIn, const Integer &bIn)
781 {
782  CRYPTOPP_ASSERT(bIn.IsOdd());
783 
784  Integer b = bIn, a = aIn%bIn;
785  int result = 1;
786 
787  while (!!a)
788  {
789  unsigned i=0;
790  while (a.GetBit(i)==0)
791  i++;
792  a>>=i;
793 
794  if (i%2==1 && (b%8==3 || b%8==5))
795  result = -result;
796 
797  if (a%4==3 && b%4==3)
798  result = -result;
799 
800  std::swap(a, b);
801  a %= b;
802  }
803 
804  return (b==1) ? result : 0;
805 }
806 
807 Integer Lucas(const Integer &e, const Integer &pIn, const Integer &n)
808 {
809  unsigned i = e.BitCount();
810  if (i==0)
811  return Integer::Two();
812 
814  Integer p=m.ConvertIn(pIn%n), two=m.ConvertIn(Integer::Two());
815  Integer v=p, v1=m.Subtract(m.Square(p), two);
816 
817  i--;
818  while (i--)
819  {
820  if (e.GetBit(i))
821  {
822  // v = (v*v1 - p) % m;
823  v = m.Subtract(m.Multiply(v,v1), p);
824  // v1 = (v1*v1 - 2) % m;
825  v1 = m.Subtract(m.Square(v1), two);
826  }
827  else
828  {
829  // v1 = (v*v1 - p) % m;
830  v1 = m.Subtract(m.Multiply(v,v1), p);
831  // v = (v*v - 2) % m;
832  v = m.Subtract(m.Square(v), two);
833  }
834  }
835  return m.ConvertOut(v);
836 }
837 
838 // This is Peter Montgomery's unpublished Lucas sequence evaluation algorithm.
839 // The total number of multiplies and squares used is less than the binary
840 // algorithm (see above). Unfortunately I can't get it to run as fast as
841 // the binary algorithm because of the extra overhead.
842 /*
843 Integer Lucas(const Integer &n, const Integer &P, const Integer &modulus)
844 {
845  if (!n)
846  return 2;
847 
848 #define f(A, B, C) m.Subtract(m.Multiply(A, B), C)
849 #define X2(A) m.Subtract(m.Square(A), two)
850 #define X3(A) m.Multiply(A, m.Subtract(m.Square(A), three))
851 
852  MontgomeryRepresentation m(modulus);
853  Integer two=m.ConvertIn(2), three=m.ConvertIn(3);
854  Integer A=m.ConvertIn(P), B, C, p, d=n, e, r, t, T, U;
855 
856  while (d!=1)
857  {
858  p = d;
859  unsigned int b = WORD_BITS * p.WordCount();
860  Integer alpha = (Integer(5)<<(2*b-2)).SquareRoot() - Integer::Power2(b-1);
861  r = (p*alpha)>>b;
862  e = d-r;
863  B = A;
864  C = two;
865  d = r;
866 
867  while (d!=e)
868  {
869  if (d<e)
870  {
871  swap(d, e);
872  swap(A, B);
873  }
874 
875  unsigned int dm2 = d[0], em2 = e[0];
876  unsigned int dm3 = d%3, em3 = e%3;
877 
878 // if ((dm6+em6)%3 == 0 && d <= e + (e>>2))
879  if ((dm3+em3==0 || dm3+em3==3) && (t = e, t >>= 2, t += e, d <= t))
880  {
881  // #1
882 // t = (d+d-e)/3;
883 // t = d; t += d; t -= e; t /= 3;
884 // e = (e+e-d)/3;
885 // e += e; e -= d; e /= 3;
886 // d = t;
887 
888 // t = (d+e)/3
889  t = d; t += e; t /= 3;
890  e -= t;
891  d -= t;
892 
893  T = f(A, B, C);
894  U = f(T, A, B);
895  B = f(T, B, A);
896  A = U;
897  continue;
898  }
899 
900 // if (dm6 == em6 && d <= e + (e>>2))
901  if (dm3 == em3 && dm2 == em2 && (t = e, t >>= 2, t += e, d <= t))
902  {
903  // #2
904 // d = (d-e)>>1;
905  d -= e; d >>= 1;
906  B = f(A, B, C);
907  A = X2(A);
908  continue;
909  }
910 
911 // if (d <= (e<<2))
912  if (d <= (t = e, t <<= 2))
913  {
914  // #3
915  d -= e;
916  C = f(A, B, C);
917  swap(B, C);
918  continue;
919  }
920 
921  if (dm2 == em2)
922  {
923  // #4
924 // d = (d-e)>>1;
925  d -= e; d >>= 1;
926  B = f(A, B, C);
927  A = X2(A);
928  continue;
929  }
930 
931  if (dm2 == 0)
932  {
933  // #5
934  d >>= 1;
935  C = f(A, C, B);
936  A = X2(A);
937  continue;
938  }
939 
940  if (dm3 == 0)
941  {
942  // #6
943 // d = d/3 - e;
944  d /= 3; d -= e;
945  T = X2(A);
946  C = f(T, f(A, B, C), C);
947  swap(B, C);
948  A = f(T, A, A);
949  continue;
950  }
951 
952  if (dm3+em3==0 || dm3+em3==3)
953  {
954  // #7
955 // d = (d-e-e)/3;
956  d -= e; d -= e; d /= 3;
957  T = f(A, B, C);
958  B = f(T, A, B);
959  A = X3(A);
960  continue;
961  }
962 
963  if (dm3 == em3)
964  {
965  // #8
966 // d = (d-e)/3;
967  d -= e; d /= 3;
968  T = f(A, B, C);
969  C = f(A, C, B);
970  B = T;
971  A = X3(A);
972  continue;
973  }
974 
975  CRYPTOPP_ASSERT(em2 == 0);
976  // #9
977  e >>= 1;
978  C = f(C, B, A);
979  B = X2(B);
980  }
981 
982  A = f(A, B, C);
983  }
984 
985 #undef f
986 #undef X2
987 #undef X3
988 
989  return m.ConvertOut(A);
990 }
991 */
992 
993 Integer InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q, const Integer &u)
994 {
995  // Callers must ensure p and q are prime, GH #1249
996  CRYPTOPP_ASSERT(IsPrime(p) && IsPrime(q));
997 
998  // GCC warning bug, https://stackoverflow.com/q/12842306/608639
999 #ifdef _OPENMP
1000  Integer d = (m*m-4), p2, q2;
1001  #pragma omp parallel
1002  #pragma omp sections
1003  {
1004  #pragma omp section
1005  {
1006  p2 = p-Jacobi(d,p);
1007  p2 = Lucas(EuclideanMultiplicativeInverse(e,p2), m, p);
1008  }
1009  #pragma omp section
1010  {
1011  q2 = q-Jacobi(d,q);
1012  q2 = Lucas(EuclideanMultiplicativeInverse(e,q2), m, q);
1013  }
1014  }
1015 #else
1016  const Integer d = (m*m-4);
1017  const Integer t1 = p-Jacobi(d,p);
1018  const Integer p2 = Lucas(EuclideanMultiplicativeInverse(e,t1), m, p);
1019 
1020  const Integer t2 = q-Jacobi(d,q);
1021  const Integer q2 = Lucas(EuclideanMultiplicativeInverse(e,t2), m, q);
1022 #endif
1023 
1024  return CRT(p2, p, q2, q, u);
1025 }
1026 
1027 unsigned int FactoringWorkFactor(unsigned int n)
1028 {
1029  // extrapolated from the table in Odlyzko's "The Future of Integer Factorization"
1030  // updated to reflect the factoring of RSA-130
1031  if (n<5) return 0;
1032  else return (unsigned int)(2.4 * std::pow((double)n, 1.0/3.0) * std::pow(log(double(n)), 2.0/3.0) - 5);
1033 }
1034 
1035 unsigned int DiscreteLogWorkFactor(unsigned int n)
1036 {
1037  // assuming discrete log takes about the same time as factoring
1038  if (n<5) return 0;
1039  else return (unsigned int)(2.4 * std::pow((double)n, 1.0/3.0) * std::pow(log(double(n)), 2.0/3.0) - 5);
1040 }
1041 
1042 // ********************************************************
1043 
1044 void PrimeAndGenerator::Generate(signed int delta, RandomNumberGenerator &rng, unsigned int pbits, unsigned int qbits)
1045 {
1046  // no prime exists for delta = -1, qbits = 4, and pbits = 5
1047  CRYPTOPP_ASSERT(qbits > 4);
1048  CRYPTOPP_ASSERT(pbits > qbits);
1049 
1050  if (qbits+1 == pbits)
1051  {
1052  Integer minP = Integer::Power2(pbits-1);
1053  Integer maxP = Integer::Power2(pbits) - 1;
1054  bool success = false;
1055 
1056  while (!success)
1057  {
1058  p.Randomize(rng, minP, maxP, Integer::ANY, 6+5*delta, 12);
1059  PrimeSieve sieve(p, STDMIN(p+PrimeSearchInterval(maxP)*12, maxP), 12, delta);
1060 
1061  while (sieve.NextCandidate(p))
1062  {
1064  q = (p-delta) >> 1;
1066  if (FastProbablePrimeTest(q) && FastProbablePrimeTest(p) && IsPrime(q) && IsPrime(p))
1067  {
1068  success = true;
1069  break;
1070  }
1071  }
1072  }
1073 
1074  if (delta == 1)
1075  {
1076  // find g such that g is a quadratic residue mod p, then g has order q
1077  // g=4 always works, but this way we get the smallest quadratic residue (other than 1)
1078  for (g=2; Jacobi(g, p) != 1; ++g) {}
1079  // contributed by Walt Tuvell: g should be the following according to the Law of Quadratic Reciprocity
1080  CRYPTOPP_ASSERT((p%8==1 || p%8==7) ? g==2 : (p%12==1 || p%12==11) ? g==3 : g==4);
1081  }
1082  else
1083  {
1084  CRYPTOPP_ASSERT(delta == -1);
1085  // find g such that g*g-4 is a quadratic non-residue,
1086  // and such that g has order q
1087  for (g=3; ; ++g)
1088  if (Jacobi(g*g-4, p)==-1 && Lucas(q, g, p)==2)
1089  break;
1090  }
1091  }
1092  else
1093  {
1094  Integer minQ = Integer::Power2(qbits-1);
1095  Integer maxQ = Integer::Power2(qbits) - 1;
1096  Integer minP = Integer::Power2(pbits-1);
1097  Integer maxP = Integer::Power2(pbits) - 1;
1098 
1099  do
1100  {
1101  q.Randomize(rng, minQ, maxQ, Integer::PRIME);
1102  } while (!p.Randomize(rng, minP, maxP, Integer::PRIME, delta%q, q));
1103 
1104  // find a random g of order q
1105  if (delta==1)
1106  {
1107  do
1108  {
1109  Integer h(rng, 2, p-2, Integer::ANY);
1110  g = a_exp_b_mod_c(h, (p-1)/q, p);
1111  } while (g <= 1);
1112  CRYPTOPP_ASSERT(a_exp_b_mod_c(g, q, p)==1);
1113  }
1114  else
1115  {
1116  CRYPTOPP_ASSERT(delta==-1);
1117  do
1118  {
1119  Integer h(rng, 3, p-1, Integer::ANY);
1120  if (Jacobi(h*h-4, p)==1)
1121  continue;
1122  g = Lucas((p+1)/q, h, p);
1123  } while (g <= 2);
1124  CRYPTOPP_ASSERT(Lucas(q, g, p) == 2);
1125  }
1126  }
1127 }
1128 
1129 NAMESPACE_END
1130 
1131 #endif
Classes for working with NameValuePairs.
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed=true)
Create an object that implements NameValuePairs.
Definition: algparam.h:508
An object that implements NameValuePairs.
Definition: algparam.h:426
Multiple precision integer with arithmetic operations.
Definition: integer.h:50
bool GetBit(size_t i) const
Provides the i-th bit of the Integer.
bool IsPositive() const
Determines if the Integer is positive.
Definition: integer.h:347
signed long ConvertToLong() const
Convert the Integer to Long.
bool IsSquare() const
Determine whether this integer is a perfect square.
void Randomize(RandomNumberGenerator &rng, size_t bitCount)
Set this Integer to random integer.
static Integer Power2(size_t e)
Exponentiates to a power of 2.
Integer Squared() const
Multiply this integer by itself.
Definition: integer.h:634
static const Integer & One()
Integer representing 1.
unsigned int BitCount() const
Determines the number of bits required to represent the Integer.
unsigned int WordCount() const
Determines the number of words required to represent the Integer.
@ ANY
a number with no special properties
Definition: integer.h:93
@ PRIME
a number which is probabilistically prime
Definition: integer.h:95
static const Integer & Zero()
Integer representing 0.
bool IsNegative() const
Determines if the Integer is negative.
Definition: integer.h:341
static const Integer & Two()
Integer representing 2.
bool IsOdd() const
Determines if the Integer is odd parity.
Definition: integer.h:356
Integer InverseMod(const Integer &n) const
Calculate multiplicative inverse.
bool IsEven() const
Determines if the Integer is even parity.
Definition: integer.h:353
An invalid argument was detected.
Definition: cryptlib.h:208
Performs modular arithmetic in Montgomery representation for increased speed.
Definition: modarith.h:296
void Generate(signed int delta, RandomNumberGenerator &rng, unsigned int pbits, unsigned qbits)
Generate a Prime and Generator.
Application callback to signal suitability of a cabdidate prime.
Definition: nbtheory.h:117
Interface for random number generators.
Definition: cryptlib.h:1440
virtual word32 GenerateWord32(word32 min=0, word32 max=0xffffffffUL)
Generate a random 32 bit word in the range min to max, inclusive.
Restricts the instantiation of a class to one static object without locks.
Definition: misc.h:309
word64 word
Full word used for multiprecision integer arithmetic.
Definition: config_int.h:192
unsigned int word32
32-bit unsigned datatype
Definition: config_int.h:72
unsigned short word16
16-bit unsigned datatype
Definition: config_int.h:69
Multiple precision integer with arithmetic operations.
Utility functions for the Crypto++ library.
bool SafeConvert(T1 from, T2 &to)
Perform a conversion from from to to.
Definition: misc.h:718
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:657
Class file for performing modular arithmetic.
Crypto++ library namespace.
Classes and functions for number theoretic operations.
CRYPTOPP_DLL int Jacobi(const Integer &a, const Integer &b)
Calculate the Jacobi symbol.
CRYPTOPP_DLL bool IsPrime(const Integer &p)
Verifies a number is probably prime.
CRYPTOPP_DLL Integer MihailescuProvablePrime(RandomNumberGenerator &rng, unsigned int bits)
Generates a provable prime.
CRYPTOPP_DLL bool IsStrongLucasProbablePrime(const Integer &n)
Determine if a number is probably prime.
CRYPTOPP_DLL unsigned int DiscreteLogWorkFactor(unsigned int bitlength)
Estimate work factor.
Integer ModularExponentiation(const Integer &x, const Integer &e, const Integer &m)
Modular exponentiation.
Definition: nbtheory.h:219
CRYPTOPP_DLL Integer ModularSquareRoot(const Integer &a, const Integer &p)
Extract a modular square root.
CRYPTOPP_DLL const word16 * GetPrimeTable(unsigned int &size)
The Small Prime table.
CRYPTOPP_DLL bool IsSmallPrime(const Integer &p)
Tests whether a number is a small prime.
CRYPTOPP_DLL bool SolveModularQuadraticEquation(Integer &r1, Integer &r2, const Integer &a, const Integer &b, const Integer &c, const Integer &p)
Solve a Modular Quadratic Equation.
CRYPTOPP_DLL bool RabinMillerTest(RandomNumberGenerator &rng, const Integer &n, unsigned int rounds)
Determine if a number is probably prime.
CRYPTOPP_DLL Integer MaurerProvablePrime(RandomNumberGenerator &rng, unsigned int bits)
Generates a provable prime.
CRYPTOPP_DLL Integer Lucas(const Integer &e, const Integer &p, const Integer &n)
Calculate the Lucas value.
CRYPTOPP_DLL Integer InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q, const Integer &u)
Calculate the inverse Lucas value.
CRYPTOPP_DLL bool VerifyPrime(RandomNumberGenerator &rng, const Integer &p, unsigned int level=1)
Verifies a number is probably prime.
CRYPTOPP_DLL Integer ModularRoot(const Integer &a, const Integer &dp, const Integer &dq, const Integer &p, const Integer &q, const Integer &u)
Extract a modular root.
Integer EuclideanMultiplicativeInverse(const Integer &a, const Integer &b)
Calculate multiplicative inverse.
Definition: nbtheory.h:169
CRYPTOPP_DLL bool SmallDivisorsTest(const Integer &p)
Tests whether a number is divisible by a small prime.
CRYPTOPP_DLL bool IsLucasProbablePrime(const Integer &n)
Determine if a number is probably prime.
Integer GCD(const Integer &a, const Integer &b)
Calculate the greatest common divisor.
Definition: nbtheory.h:146
CRYPTOPP_DLL bool TrialDivision(const Integer &p, unsigned bound)
Tests whether a number is divisible by a small prime.
CRYPTOPP_DLL unsigned int FactoringWorkFactor(unsigned int bitlength)
Estimate work factor.
CRYPTOPP_DLL bool IsFermatProbablePrime(const Integer &n, const Integer &b)
Determine if a number is probably prime.
CRYPTOPP_DLL Integer CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q, const Integer &u)
Chinese Remainder Theorem.
CRYPTOPP_DLL bool IsStrongProbablePrime(const Integer &n, const Integer &b)
Determine if a number is probably prime.
CRYPTOPP_DLL bool FirstPrime(Integer &p, const Integer &max, const Integer &equiv, const Integer &mod, const PrimeSelector *pSelector)
Finds a random prime of special form.
Precompiled header file.
void swap(::SecBlock< T, A > &a, ::SecBlock< T, A > &b)
Swap two SecBlocks.
Definition: secblock.h:1289
Classes for automatic resource management.
Common C++ header files.
Debugging and diagnostic assertions.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68