1 /**
2 * Number Theory Functions
3 * 
4 * Copyright:
5 * (C) 1999-2007 Jack Lloyd
6 * (C) 2014-2015 Etienne Cimon
7 *
8 * License:
9 * Botan is released under the Simplified BSD License (see LICENSE.md)
10 */
11 module botan.math.numbertheory.numthry;
12 
13 import botan.constants;
14 static if (BOTAN_HAS_PUBLIC_KEY_CRYPTO):
15 
16 public import botan.math.bigint.bigint;
17 public import botan.math.numbertheory.pow_mod;
18 public import botan.math.numbertheory.primes;
19 public import botan.utils.types;
20 import botan.rng.rng;
21 import botan.hash.hash;
22 import botan.utils.parsing;
23 import std.algorithm;
24 import botan.math.numbertheory.reducer;
25 import botan.utils.bit_ops;
26 import botan.math.mp.mp_core;
27 import botan.utils.rounding;
28 import botan.algo_factory.algo_factory : AlgorithmFactory;
29 import botan.constants;
30 import std.conv : to;
31 import std.traits : isPointer;
32 
33 /**
34 * Fused multiply-add
35 * Params:
36 *  a = an integer
37 *  b = an integer
38 *  c = an integer
39 * Returns: (a*b)+c
40 */
41 /*
42 * Multiply-Add Operation
43 */
44 BigInt mulAdd(const(BigInt)* a, const(BigInt)* b, const(BigInt)* c)
45 {
46     if (c.isNegative() || c.isZero())
47         throw new InvalidArgument("mulAdd: Third argument must be > 0");
48     
49     BigInt.Sign sign = BigInt.Positive;
50     if (a.sign() != b.sign())
51         sign = BigInt.Negative;
52     
53     const size_t a_sw = a.sigWords();
54     const size_t b_sw = b.sigWords();
55     const size_t c_sw = c.sigWords();
56     
57     BigInt r = BigInt(sign, std.algorithm.max(a.length + b.length, c_sw) + 1);
58     SecureVector!word workspace = SecureVector!word(r.length);
59     
60     bigint_mul(r.mutablePtr(), r.length, workspace.ptr, a.ptr, a.length, a_sw, b.ptr, b.length, b_sw);
61     
62     const size_t r_size = std.algorithm.max(r.sigWords(), c_sw);
63     bigint_add2(r.mutablePtr(), r_size, c.ptr, c_sw);
64     return r;
65 }
66 
67 
68 /**
69 * Fused subtract-multiply
70 * Params:
71 *  a = an integer
72 *  b = an integer
73 *  c = an integer
74 * Returns: (a-b)*c
75 */
76 BigInt subMul(const(BigInt)* a, const(BigInt)* b, const(BigInt)* c)
77 {
78     if (a.isNegative() || b.isNegative())
79         throw new InvalidArgument("subMul: First two arguments must be >= 0");
80     
81     BigInt r = a.clone;
82     r -= b;
83     r *= c;
84     return r.move();
85 }
86 
87 /**
88 * Return the absolute value
89 * Params:
90 *  n = an integer
91 * Returns: absolute value of n
92 */
93  BigInt abs(const(BigInt)* n) { return n.abs(); }
94 
95 /**
96 * Compute the greatest common divisor
97 * Params:
98 *  a = positive integer x
99 *  b = positive integer y
100 * Returns: gcd(x,y)
101 */
102 BigInt gcd(const(BigInt)* a, const(BigInt)* b)
103 {
104     if (a.isZero() || b.isZero()) return BigInt(0);
105     if (*a == 1 || *b == 1)         return BigInt(1);
106     
107     BigInt x = a.clone, y = b.clone;
108     x.setSign(BigInt.Positive);
109     y.setSign(BigInt.Positive);
110     size_t shift = std.algorithm.min(lowZeroBits(&x), lowZeroBits(&y));
111     
112     x >>= shift;
113     y >>= shift;
114     
115     while (x.isNonzero())
116     {
117         x >>= lowZeroBits(&x);
118         y >>= lowZeroBits(&y);
119         if (x >= y) { x -= y; x >>= 1; }
120         else         { y -= x; y >>= 1; }
121     }
122     
123     return (y << shift);
124 }
125 
126 /**
127 * Least common multiple
128 * Params:
129 *  a = a positive integer x
130 *  b = a positive integer y
131 * Returns: z, smallest integer such that z % x == 0 and z % y == 0
132 */
133 BigInt lcm(const(BigInt)* a, const(BigInt)* b)
134 {
135 	auto a_b = (*a * b);
136 	auto gcd_a_b = gcd(a, b);
137     return a_b/gcd_a_b;
138 }
139 
140 BigInt lcm(const(BigInt) a, const(BigInt) b)
141 {
142     return (lcm(&a, &b));
143 }
144 /**
145 * Params:
146 *  x = an integer
147 * Returns: (x*x)
148 */
149 BigInt square(const(BigInt)* x)
150 {
151     const size_t x_sw = x.sigWords();
152     
153     BigInt z = BigInt(BigInt.Positive, roundUp!size_t(2*x_sw, 16));
154     SecureVector!word workspace = SecureVector!word(z.length);
155     
156     bigint_sqr(z.mutablePtr(), z.length, workspace.ptr, x.ptr, x.length, x_sw);
157     return z;
158 }
159 
160 /**
161 * Modular inversion
162 * Params:
163 *  n = a positive integer x
164 *  mod = a positive integer modulus
165 * Returns: y st (x*y) % modulus == 1
166 */
167 BigInt inverseMod(const(BigInt)* n, const(BigInt)* mod)
168 {
169     if (mod.isZero())
170         throw new BigInt.DivideByZero();
171     if (mod.isNegative() || n.isNegative())
172         throw new InvalidArgument("inverseMod: arguments must be non-negative");
173     
174     if (n.isZero() || (n.isEven() && mod.isEven()))
175         return BigInt(0); // fast fail checks
176     
177     if (mod.isOdd())
178         return inverseModOddModulus(n, mod);
179     
180     BigInt u = mod.clone, v = n.clone;
181     BigInt A = BigInt(1);
182     BigInt B = BigInt(0);
183     BigInt C = BigInt(0);
184     BigInt D = BigInt(1);
185     
186     while (u.isNonzero())
187     {
188         const size_t u_zero_bits = lowZeroBits(&u);
189         u >>= u_zero_bits;
190         foreach (size_t i; 0 .. u_zero_bits)
191         {
192             if (A.isOdd() || B.isOdd())
193             { A += *n; B -= *mod; }
194             A >>= 1; B >>= 1;
195         }
196         
197         const size_t v_zero_bits = lowZeroBits(&v);
198         v >>= v_zero_bits;
199         foreach (size_t i; 0 .. v_zero_bits)
200         {
201             if (C.isOdd() || D.isOdd())
202             { C += *n; D -= *mod; }
203             C >>= 1; D >>= 1;
204         }
205         
206         if (u >= v) { u -= v; A -= C; B -= D; }
207         else         { v -= u; C -= A; D -= B; }
208     }
209     
210     if (v != 1)
211         return BigInt(0); // no modular inverse
212     
213     while (D.isNegative()) D += *mod;
214     while (D >= *mod) D -= *mod;
215     
216     return D.move();
217 }
218 
219 
220 /**
221 * Compute the Jacobi symbol. If n is prime, this is equivalent
222 * to the Legendre symbol.
223 * @see http://mathworld.wolfram.com/JacobiSymbol.html
224 *
225 * Params:
226 *  a = is a non-negative integer
227 *  n = is an odd integer > 1
228 * Returns: (n / m)
229 */
230 int jacobi(const(BigInt)* a, const(BigInt)* n)
231 {
232     if (a.isNegative())
233         throw new InvalidArgument("jacobi: first argument must be non-negative");
234     if (n.isEven() || (*n) < 2)
235         throw new InvalidArgument("jacobi: second argument must be odd and > 1");
236     
237     BigInt x = (*a).clone, y = (*n).clone;
238     int J = 1;
239     
240     while (y > 1)
241     {
242         x %= y;
243         if (x > y / 2)
244         {
245             x = y - x;
246             if (y % 4 == 3)
247                 J = -J;
248         }
249         if (x.isZero())
250             return 0;
251         
252         size_t shifts = lowZeroBits(&x);
253         x >>= shifts;
254         if (shifts % 2)
255         {
256             word y_mod_8 = y % 8;
257             if (y_mod_8 == 3 || y_mod_8 == 5)
258                 J = -J;
259         }
260         
261         if (x % 4 == 3 && y % 4 == 3)
262             J = -J;
263         std.algorithm.swap(x, y);
264     }
265     return J;
266 }
267 
268 /**
269 * Modular exponentation
270 * Params:
271 *  base = an integer base b
272 *  exp = a positive exponent x
273 *  mod = a positive modulus m
274 * Returns: (b^x) % m
275 */
276 BigInt powerMod(const(BigInt)* base, const(BigInt)* exp, const(BigInt)* mod)
277 {
278 	auto pow_mod = scoped!PowerMod(mod);
279 
280     /*
281     * Calling setBase before setExponent means we end up using a
282     * minimal window. This makes sense given that here we know that any
283     * precomputation is wasted.
284     */
285     pow_mod.setBase(base);
286     pow_mod.setExponent(exp);
287     return pow_mod.execute();
288 }
289 
290 
291 /**
292 * Compute the square root of x modulo a prime using the
293 * Shanks-Tonnelli algorithm
294 *
295 * Params:
296 *  a = the input x
297 *  p = the prime p
298 * Returns: y such that (y*y)%p == x, or -1 if no such integer
299 */
300 
301 /*
302 * Shanks-Tonnelli algorithm
303 */
304 BigInt ressol(const(BigInt)* a, const(BigInt)* p)
305 {
306     if (*a == 0)
307         return BigInt(0);
308 	else if (*a < 0)
309 		throw new InvalidArgument("ressol(): a to solve for must be positive");
310 
311     if (*p == 2)
312         return a.clone;
313 	else if (*p <= 1)
314 		throw new InvalidArgument("ressol(): prime must be > 1");
315 	else if(p.isEven())
316 	   throw new InvalidArgument("ressol(): invalid prime");
317     if (jacobi(a, p) != 1) { // not a quadratic residue
318         auto bi = -BigInt(1);
319         return bi.move();
320     }
321     
322     if ((*p) % 4 == 3) {
323         auto p_mod = (((*p)+1) >> 2);       
324         return powerMod(a, &p_mod, p);
325     }
326     auto s_diff = (*p) - 1;
327     size_t s = lowZeroBits(&s_diff);
328     BigInt q = (*p) >> s;
329     
330     q -= 1;
331     q >>= 1;
332     
333     ModularReducer mod_p = ModularReducer(*p);
334     
335     BigInt r = powerMod(a, &q, p);
336     auto r_1 = mod_p.square(&r);
337     BigInt n = mod_p.multiply(a, &r_1);
338     r = mod_p.multiply(&r, a);
339     
340     if (n == 1)
341         return r.move();
342     
343     // find random non quadratic residue z
344     BigInt z = 2;
345     while (jacobi(&z, p) == 1) // while z quadratic residue
346         ++z;
347     auto c_0 = (q << 1) + 1;
348     BigInt c = powerMod(&z, &c_0, p);
349     
350     while (n > 1)
351     {
352         q = n.clone();
353         
354         size_t i = 0;
355         while (q != 1)
356         {
357             q = mod_p.square(&q);
358 			++i;
359 			if (i >= s) {
360 				auto bi = -BigInt(1);
361 				return bi.move();
362 			}
363         }        
364         auto c_1 = BigInt.powerOf2(s-i-1);
365         c = powerMod(&c, &c_1, p);
366         r = mod_p.multiply(&r, &c);
367         c = mod_p.square(&c);
368         n = mod_p.multiply(&n, &c);
369         s = i;
370     }
371     
372     return r.move();
373 }
374 
375 /*
376 * Compute -input^-1 mod 2^MP_WORD_BITS. Returns zero if input
377 * is even. If input is odd, input and 2^n are relatively prime
378 * and an inverse exists.
379 */
380 word montyInverse(word input)
381 {
382     word b = input;
383     word x2 = 1, x1 = 0, y2 = 0, y1 = 1;
384     
385     // First iteration, a = n+1
386     word q = bigint_divop(1, 0, b);
387     word r = (MP_WORD_MAX - q*b) + 1;
388     word x = x2 - q*x1;
389     word y = y2 - q*y1;
390     
391     word a = b;
392     b = r;
393     x2 = x1;
394     x1 = x;
395     y2 = y1;
396     y1 = y;
397     
398     while (b > 0)
399     {
400         q = a / b;
401         r = a - q*b;
402         x = x2 - q*x1;
403         y = y2 - q*y1;
404         
405         a = b;
406         b = r;
407         x2 = x1;
408         x1 = x;
409         y2 = y1;
410         y1 = y;
411     }
412     
413     // Now invert in addition space
414     y2 = (MP_WORD_MAX - y2) + 1;
415     
416     return y2;
417 }
418 
419 /**
420 * Params:
421 *  n = a positive integer x
422 * Returns: count of the zero bits in x, or, equivalently, the largest
423 *            value of n such that 2^n divides x evenly. Returns zero if
424 *            n is less than or equal to zero.
425 */
426 size_t lowZeroBits(const(BigInt)* n)
427 {
428     size_t low_zero = 0;
429     
430     if (n.isPositive() && n.isNonzero())
431     {
432         for (size_t i = 0; i != n.length; ++i)
433         {
434             const word x = n.wordAt(i);
435             
436             if (x)
437             {
438                 low_zero += ctz(x);
439                 break;
440             }
441             else
442                 low_zero += BOTAN_MP_WORD_BITS;
443         }
444     }
445     
446     return low_zero;
447 }
448 
449 /**
450 * Check for primality using Miller-Rabin
451 * Params:
452 *  n = a positive integer to test for primality
453 *  rng = a random number generator
454 *  prob = chance of false positive is bounded by 1/2**prob
455 *  is_random = true if n was randomly chosen by us
456 * Returns: true if all primality tests passed, otherwise false
457 */
458 bool isPrime(const(BigInt)* n, RandomNumberGenerator rng, size_t prob = 56, bool is_random = false)
459 {
460     import std.range : assumeSorted, SortedRange, empty;
461     if (*n == 2)
462         return true;
463     if (*n <= 1 || n.isEven())
464         return false;
465     
466     // Fast path testing for small numbers (<= 65521)
467     if (*n <= PRIMES[PRIME_TABLE_SIZE-1])
468     {
469         const ushort num = cast(ushort) n.wordAt(0);
470         auto r = assumeSorted(PRIMES[0..$]);
471         return !r.equalRange(num).empty;
472     }
473 
474     const size_t test_iterations = mrTestIterations(n.bits(), prob, is_random);
475     const BigInt n_minus_1 = (*n) - 1;
476     const size_t s = lowZeroBits(&n_minus_1);
477     auto left_shift = n_minus_1 >> s;
478     auto pow_mod = scoped!FixedExponentPowerModImpl(cast(BigInt*)&left_shift, cast(BigInt*)n);
479     ModularReducer reducer = ModularReducer(*n);
480     
481     foreach (size_t i; 0 .. test_iterations)
482     {
483         auto bi = BigInt(2);
484         const BigInt a = BigInt.randomInteger(rng, bi, n_minus_1);
485         BigInt y = cast(BigInt)pow_mod.opCall(cast(BigInt*)&a);
486         if (mrWitness(y, reducer, &n_minus_1, s))
487             return false;
488     }
489     
490     return true;
491 }
492 
493 bool quickCheckPrime(const(BigInt)* n, RandomNumberGenerator rng)
494 { return isPrime(n, rng, 32); }
495 
496 bool checkPrime(const(BigInt)* n, RandomNumberGenerator rng)
497 { return isPrime(n, rng, 56); }
498 
499 bool verifyPrime(const(BigInt)* n, RandomNumberGenerator rng)
500 { return isPrime(n, rng, 80); }
501 
502 /**
503 * Randomly generate a prime
504 * Params:
505 *  rng = a random number generator
506 *  bits = how large the resulting prime should be in bits
507 *  coprime = a positive integer the result should be coprime to
508 *  equiv = a non-negative number that the result should be
509                     equivalent to modulo equiv_mod
510 *  modulo = the modulus equiv should be checked against
511 * Returns: random prime with the specified criteria
512 */
513 BigInt randomPrime(RandomNumberGenerator rng,
514                      size_t bits, const(BigInt)* coprime,
515                      size_t equiv = 1, size_t modulo = 2)
516 {
517     if (bits <= 1)
518         throw new InvalidArgument("randomPrime: Can't make a prime of " ~ to!string(bits) ~ " bits");
519     else if (bits == 2)
520         return ((rng.nextByte() % 2) ? BigInt(2) : BigInt(3));
521     else if (bits == 3)
522         return ((rng.nextByte() % 2) ? BigInt(5) : BigInt(7));
523     else if (bits == 4)
524         return ((rng.nextByte() % 2) ? BigInt(11) : BigInt(13));
525     
526     if (*coprime <= 0)
527         throw new InvalidArgument("randomPrime: coprime must be > 0");
528     if (modulo % 2 == 1 || modulo == 0)
529         throw new InvalidArgument("randomPrime: Invalid modulo value");
530     if (equiv >= modulo || equiv % 2 == 0)
531         throw new InvalidArgument("randomPrime: equiv must be < modulo, and odd");
532     
533     while (true)
534     {
535         BigInt p = BigInt(rng, bits);
536         
537         // Force lowest and two top bits on
538         p.setBit(bits - 1);
539         p.setBit(bits - 2);
540         p.setBit(0);
541         
542         if (p % modulo != equiv)
543             p += (modulo - p % modulo) + equiv;
544         
545         const size_t sieve_size = std.algorithm.min(bits / 2, PRIME_TABLE_SIZE);
546         SecureVector!ushort sieve = SecureVector!ushort(sieve_size);
547         
548         for (size_t j = 0; j != sieve.length; ++j)
549             sieve[j] = cast(ushort)( p % PRIMES[j]);
550         
551         size_t counter = 0;
552         while (true)
553         {
554             if (counter == 4096 || p.bits() > bits)
555                 break;
556             
557             bool passes_sieve = true;
558             ++counter;
559             p += modulo;
560             
561             if (p.bits() > bits)
562                 break;
563             
564             for (size_t j = 0; j != sieve.length; ++j)
565             {
566                 sieve[j] = cast(ushort)((sieve[j] + modulo) % PRIMES[j]);
567                 if (sieve[j] == 0)
568                     passes_sieve = false;
569             }
570 			auto one = BigInt(1);
571 			auto p_1 = p - one;
572 			auto gcd_coprime = gcd(&p_1, coprime);
573             if (!passes_sieve || gcd_coprime != one)
574                 continue;
575             if (isPrime(&p, rng, 64, true))
576                 return p.move;
577         }
578     }
579 }
580 
581 /// ditto
582 BigInt randomPrime(RandomNumberGenerator rng,
583     size_t bits, const BigInt coprime = BigInt(1),
584     size_t equiv = 1, size_t modulo = 2)
585 {
586     return randomPrime(rng, bits, &coprime, equiv, modulo);
587 }
588 
589 /**
590 * Return a random 'safe' prime, of the form p=2*q+1 with q prime
591 * Params:
592 *  rng = a random number generator
593 *  bits = is how long the resulting prime should be
594 * Returns: prime randomly chosen from safe primes of length bits
595 */
596 BigInt randomSafePrime(RandomNumberGenerator rng, size_t bits)
597 {
598     if (bits <= 64)
599         throw new InvalidArgument("randomSafePrime: Can't make a prime of " ~ to!string(bits) ~ " bits");
600     
601     BigInt p;
602     do
603         p = (randomPrime(rng, bits - 1) << 1) + 1;
604     while (!isPrime(&p, rng, 64, true));
605     return p;
606 }
607 
608 /**
609 * Generate DSA parameters using the FIPS 186 kosherizer
610 * Params:
611 *  rng = a random number generator
612 *  af = an algorithm factory
613 *  p_out = where the prime p will be stored
614 *  q_out = where the prime q will be stored
615 *  pbits = how long p will be in bits
616 *  qbits = how long q will be in bits
617 * Returns: random seed used to generate this parameter set
618 */
619 Vector!ubyte generateDsaPrimes(RandomNumberGenerator rng,
620                                AlgorithmFactory af,
621                                ref BigInt p_out, ref BigInt q_out,
622                                size_t pbits, size_t qbits)
623 {
624     while (true)
625     {
626         Vector!ubyte seed = Vector!ubyte(qbits / 8);
627         rng.randomize(seed.ptr, seed.length);
628         
629         if (generateDsaPrimes(rng, af, p_out, q_out, pbits, qbits, seed))
630             return seed;
631     }
632 }
633 
634 
635 /**
636 * Generate DSA parameters using the FIPS 186 kosherizer
637 * Params:
638 *  rng = a random number generator
639 *  af = an algorithm factory
640 *  p_out = where the prime p will be stored
641 *  q_out = where the prime q will be stored
642 *  pbits = how long p will be in bits
643 *  qbits = how long q will be in bits
644 *  seed_c = the seed used to generate the parameters
645 * Returns: true if seed generated a valid DSA parameter set, otherwise
646              false. p_out and q_out are only valid if true was returned.
647 */
648 bool generateDsaPrimes()(RandomNumberGenerator rng,
649                          AlgorithmFactory af,
650                          ref BigInt p_out, ref BigInt q_out,
651                          size_t pbits, size_t qbits,
652                          auto const ref Vector!ubyte seed_c)
653 {
654     if (!fips1863ValidSize(pbits, qbits))
655         throw new InvalidArgument(
656             "FIPS 186-3 does not allow DSA domain parameters of " ~ to!string(pbits) ~ "/" ~ to!string(qbits) ~ " bits long");
657     
658     if (seed_c.length * 8 < qbits)
659         throw new InvalidArgument("Generating a DSA parameter set with a " ~ to!string(qbits) ~ 
660                                    "long q requires a seed at least as many bits long");
661     
662     Unique!HashFunction hash = af.makeHashFunction("SHA-" ~ to!string(qbits));
663     
664     const size_t HASH_SIZE = hash.outputLength;
665     
666     struct Seed
667     {
668     public:
669         this(const(Vector!ubyte)* s) { m_seed = s.clone(); }
670         
671         ref T opCast(T : Vector!ubyte)() { return m_seed; }
672         
673         alias m_seed this;
674         
675         ref Seed opUnary(string op)()
676             if (op == "++")
677         {
678             for (size_t j = m_seed.length; j > 0; --j)
679                 if (++m_seed[j-1])
680                     break;
681             return this;
682         }
683     private:
684         Vector!ubyte m_seed;
685     }
686     
687     Seed seed = Seed(&seed_c);
688     
689     q_out.binaryDecode(hash.process(seed));
690     q_out.setBit(qbits-1);
691     q_out.setBit(0);
692     
693     if (!isPrime(&q_out, rng))
694         return false;
695     
696     const size_t n = (pbits-1) / (HASH_SIZE * 8), b = (pbits-1) % (HASH_SIZE * 8);
697     
698     BigInt X;
699     Vector!ubyte V = Vector!ubyte(HASH_SIZE * (n+1));
700     
701     foreach (size_t j; 0 .. 4096)
702     {
703         for (size_t k = 0; k <= n; ++k)
704         {
705             ++seed;
706             hash.update(seed);
707             hash.flushInto(&V[HASH_SIZE * (n-k)]);
708         }
709         
710         X.binaryDecode(&V[HASH_SIZE - 1 - b/8], V.length - (HASH_SIZE - 1 - b/8));
711         X.setBit(pbits-1);
712         
713         p_out = X - (X % (q_out*2) - 1);
714         
715         if (p_out.bits() == pbits && isPrime(&p_out, rng))
716             return true;
717     }
718     return false;
719 }
720 
721 /*
722 * Check if this size is allowed by FIPS 186-3
723 */
724 bool fips1863ValidSize(size_t pbits, size_t qbits)
725 {
726     if (qbits == 160)
727         return (pbits == 512 || pbits == 768 || pbits == 1024);
728     
729     if (qbits == 224)
730         return (pbits == 2048);
731     
732     if (qbits == 256)
733         return (pbits == 2048 || pbits == 3072);
734     
735     return false;
736 }
737 
738 /*
739 * If the modulus is odd, then we can avoid computing A and C. This is
740 * a critical path algorithm in some instances and an odd modulus is
741 * the common case for crypto, so worth special casing. See note 14.64
742 * in Handbook of Applied Cryptography for more details.
743 */
744 BigInt inverseModOddModulus(const(BigInt)* n, const(BigInt)* mod)
745 {
746     BigInt u = mod.clone;
747     BigInt v = n.clone;
748     BigInt B = BigInt(0);
749     BigInt D = BigInt(1);
750     
751     while (u.isNonzero())
752     {
753         const size_t u_zero_bits = lowZeroBits(&u);
754         u >>= u_zero_bits;
755         foreach (size_t i; 0 .. u_zero_bits)
756         {
757             if (B.isOdd())
758             { B -= *mod; }
759             B >>= 1;
760         }
761         
762         const size_t v_zero_bits = lowZeroBits(&v);
763         v >>= v_zero_bits;
764         foreach (size_t i; 0 .. v_zero_bits)
765         {
766             if (D.isOdd())
767             { D -= *mod; }
768             D >>= 1;
769         }
770         
771         if (u >= v) { u -= v; B -= D; }
772         else        { v -= u; D -= B; }
773     }
774     
775     if (v != 1)
776         return BigInt(0); // no modular inverse
777     
778     while (D.isNegative()) D += *mod;
779     while (D >= *mod) D -= *mod;
780     
781     return D.move();
782 }
783 
784 bool mrWitness(T : ModularReducer)(ref BigInt y,
785                                    auto ref T reducer_n,
786                                    const(BigInt)* n_minus_1, size_t s)
787 {
788     if (y == 1 || y == n_minus_1)
789         return false;
790     
791     foreach (size_t i; 1 .. s)
792     {
793         y = reducer_n.square(&y);
794         
795         if (y == 1) // found a non-trivial square root
796             return true;
797         if (y == n_minus_1) // -1, trivial square root, so give up
798             return false;
799     }
800     
801     return true; // fails Fermat test
802 }
803 
804 size_t mrTestIterations(size_t n_bits, size_t prob, bool random)
805 {
806     const size_t base = (prob + 2) / 2; // worst case 4^-t error rate
807     
808     /*
809     * For randomly chosen numbers we can use the estimates from
810     * http://www.math.dartmouth.edu/~carlp/PDF/paper88.pdf
811     *
812     * These values are derived from the inequality for p(k,t) given on
813     * the second page.
814     */
815     if (random && prob <= 80)
816     {
817         if (n_bits >= 1536)
818             return 2; // < 2^-89
819         if (n_bits >= 1024)
820             return 4; // < 2^-89
821         if (n_bits >= 512)
822             return 5; // < 2^-80
823         if (n_bits >= 256)
824             return 11; // < 2^-80
825     }
826     
827     return base;
828 }