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 }