Source File
prime.go
Belonging Package
math/big
// Copyright 2016 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package bigimport// ProbablyPrime reports whether x is probably prime,// applying the Miller-Rabin test with n pseudorandomly chosen bases// as well as a Baillie-PSW test.//// If x is prime, ProbablyPrime returns true.// If x is chosen randomly and not prime, ProbablyPrime probably returns false.// The probability of returning true for a randomly chosen non-prime is at most ¼ⁿ.//// ProbablyPrime is 100% accurate for inputs less than 2⁶⁴.// See Menezes et al., Handbook of Applied Cryptography, 1997, pp. 145-149,// and FIPS 186-4 Appendix F for further discussion of the error probabilities.//// ProbablyPrime is not suitable for judging primes that an adversary may// have crafted to fool the test.//// As of Go 1.8, ProbablyPrime(0) is allowed and applies only a Baillie-PSW test.// Before Go 1.8, ProbablyPrime applied only the Miller-Rabin tests, and ProbablyPrime(0) panicked.func ( *Int) ( int) bool {// Note regarding the doc comment above:// It would be more precise to say that the Baillie-PSW test uses the// extra strong Lucas test as its Lucas test, but since no one knows// how to tell any of the Lucas tests apart inside a Baillie-PSW test// (they all work equally well empirically), that detail need not be// documented or implicitly guaranteed.// The comment does avoid saying "the" Baillie-PSW test// because of this general ambiguity.if < 0 {panic("negative n for ProbablyPrime")}if .neg || len(.abs) == 0 {return false}// primeBitMask records the primes < 64.const uint64 = 1<<2 | 1<<3 | 1<<5 | 1<<7 |1<<11 | 1<<13 | 1<<17 | 1<<19 | 1<<23 | 1<<29 | 1<<31 |1<<37 | 1<<41 | 1<<43 | 1<<47 | 1<<53 | 1<<59 | 1<<61:= .abs[0]if len(.abs) == 1 && < 64 {return &(1<<) != 0}if &1 == 0 {return false // x is even}const = 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23 * 37const = 29 * 31 * 41 * 43 * 47 * 53var , uint32switch _W {case 32:= uint32(.abs.modW())= uint32(.abs.modW())case 64::= .abs.modW(( * ) & _M)= uint32( % )= uint32( % )default:panic("math/big: invalid word size")}if %3 == 0 || %5 == 0 || %7 == 0 || %11 == 0 || %13 == 0 || %17 == 0 || %19 == 0 || %23 == 0 || %37 == 0 ||%29 == 0 || %31 == 0 || %41 == 0 || %43 == 0 || %47 == 0 || %53 == 0 {return false}return .abs.probablyPrimeMillerRabin(+1, true) && .abs.probablyPrimeLucas()}// probablyPrimeMillerRabin reports whether n passes reps rounds of the// Miller-Rabin primality test, using pseudo-randomly chosen bases.// If force2 is true, one of the rounds is forced to use base 2.// See Handbook of Applied Cryptography, p. 139, Algorithm 4.24.// The number n is known to be non-zero.func ( nat) ( int, bool) bool {:= nat(nil).sub(, natOne)// determine q, k such that nm1 = q << k:= .trailingZeroBits():= nat(nil).shr(, ):= nat(nil).sub(, natTwo):= rand.New(rand.NewSource(int64([0])))var , , nat:= .bitLen():for := 0; < ; ++ {if == -1 && {= .set(natTwo)} else {= .random(, , )= .add(, natTwo)}= .expNN(, , )if .cmp(natOne) == 0 || .cmp() == 0 {continue}for := uint(1); < ; ++ {= .sqr(), = .div(, , )if .cmp() == 0 {continue}if .cmp(natOne) == 0 {return false}}return false}return true}// probablyPrimeLucas reports whether n passes the "almost extra strong" Lucas probable prime test,// using Baillie-OEIS parameter selection. This corresponds to "AESLPSP" on Jacobsen's tables (link below).// The combination of this test and a Miller-Rabin/Fermat test with base 2 gives a Baillie-PSW test.//// References://// Baillie and Wagstaff, "Lucas Pseudoprimes", Mathematics of Computation 35(152),// October 1980, pp. 1391-1417, especially page 1401.// https://www.ams.org/journals/mcom/1980-35-152/S0025-5718-1980-0583518-6/S0025-5718-1980-0583518-6.pdf//// Grantham, "Frobenius Pseudoprimes", Mathematics of Computation 70(234),// March 2000, pp. 873-891.// https://www.ams.org/journals/mcom/2001-70-234/S0025-5718-00-01197-2/S0025-5718-00-01197-2.pdf//// Baillie, "Extra strong Lucas pseudoprimes", OEIS A217719, https://oeis.org/A217719.//// Jacobsen, "Pseudoprime Statistics, Tables, and Data", http://ntheory.org/pseudoprimes.html.//// Nicely, "The Baillie-PSW Primality Test", http://www.trnicely.net/misc/bpsw.html.// (Note that Nicely's definition of the "extra strong" test gives the wrong Jacobi condition,// as pointed out by Jacobsen.)//// Crandall and Pomerance, Prime Numbers: A Computational Perspective, 2nd ed.// Springer, 2005.func ( nat) () bool {// Discard 0, 1.if len() == 0 || .cmp(natOne) == 0 {return false}// Two is the only even prime.// Already checked by caller, but here to allow testing in isolation.if [0]&1 == 0 {return .cmp(natTwo) == 0}// Baillie-OEIS "method C" for choosing D, P, Q,// as in https://oeis.org/A217719/a217719.txt:// try increasing P ≥ 3 such that D = P² - 4 (so Q = 1)// until Jacobi(D, n) = -1.// The search is expected to succeed for non-square n after just a few trials.// After more than expected failures, check whether n is square// (which would cause Jacobi(D, n) = 1 for all D not dividing n).:= Word(3):= nat{1}:= nat(nil) // temp:= &Int{abs: }:= &Int{abs: }for ; ; ++ {if > 10000 {// This is widely believed to be impossible.// If we get a report, we'll want the exact number n.panic("math/big: internal error: cannot find (D/n) = -1 for " + .String())}[0] = * - 4:= Jacobi(, )if == -1 {break}if == 0 {// d = p²-4 = (p-2)(p+2).// If (d/n) == 0 then d shares a prime factor with n.// Since the loop proceeds in increasing p and starts with p-2==1,// the shared prime factor must be p+2.// If p+2 == n, then n is prime; otherwise p+2 is a proper factor of n.return len() == 1 && [0] == +2}if == 40 {// We'll never find (d/n) = -1 if n is a square.// If n is a non-square we expect to find a d in just a few attempts on average.// After 40 attempts, take a moment to check if n is indeed a square.= .sqrt()= .sqr()if .cmp() == 0 {return false}}}// Grantham definition of "extra strong Lucas pseudoprime", after Thm 2.3 on p. 876// (D, P, Q above have become Δ, b, 1)://// Let U_n = U_n(b, 1), V_n = V_n(b, 1), and Δ = b²-4.// An extra strong Lucas pseudoprime to base b is a composite n = 2^r s + Jacobi(Δ, n),// where s is odd and gcd(n, 2*Δ) = 1, such that either (i) U_s ≡ 0 mod n and V_s ≡ ±2 mod n,// or (ii) V_{2^t s} ≡ 0 mod n for some 0 ≤ t < r-1.//// We know gcd(n, Δ) = 1 or else we'd have found Jacobi(d, n) == 0 above.// We know gcd(n, 2) = 1 because n is odd.//// Arrange s = (n - Jacobi(Δ, n)) / 2^r = (n+1) / 2^r.:= nat(nil).add(, natOne):= int(.trailingZeroBits())= .shr(, uint()):= nat(nil).sub(, natTwo) // n-2// We apply the "almost extra strong" test, which checks the above conditions// except for U_s ≡ 0 mod n, which allows us to avoid computing any U_k values.// Jacobsen points out that maybe we should just do the full extra strong test:// "It is also possible to recover U_n using Crandall and Pomerance equation 3.13:// U_n = D^-1 (2V_{n+1} - PV_n) allowing us to run the full extra-strong test// at the cost of a single modular inversion. This computation is easy and fast in GMP,// so we can get the full extra-strong test at essentially the same performance as the// almost extra strong test."// Compute Lucas sequence V_s(b, 1), where://// V(0) = 2// V(1) = P// V(k) = P V(k-1) - Q V(k-2).//// (Remember that due to method C above, P = b, Q = 1.)//// In general V(k) = α^k + β^k, where α and β are roots of x² - Px + Q.// Crandall and Pomerance (p.147) observe that for 0 ≤ j ≤ k,//// V(j+k) = V(j)V(k) - V(k-j).//// So in particular, to quickly double the subscript://// V(2k) = V(k)² - 2// V(2k+1) = V(k) V(k+1) - P//// We can therefore start with k=0 and build up to k=s in log₂(s) steps.:= nat(nil).setWord():= nat(nil).setWord(2):= nat(nil).setWord():= nat(nil) // tempfor := int(.bitLen()); >= 0; -- {if .bit(uint()) != 0 {// k' = 2k+1// V(k') = V(2k+1) = V(k) V(k+1) - P.= .mul(, )= .add(, )= .sub(, ), = .div(, , )// V(k'+1) = V(2k+2) = V(k+1)² - 2.= .sqr()= .add(, ), = .div(, , )} else {// k' = 2k// V(k'+1) = V(2k+1) = V(k) V(k+1) - P.= .mul(, )= .add(, )= .sub(, ), = .div(, , )// V(k') = V(2k) = V(k)² - 2= .sqr()= .add(, ), = .div(, , )}}// Now k=s, so vk = V(s). Check V(s) ≡ ±2 (mod n).if .cmp(natTwo) == 0 || .cmp() == 0 {// Check U(s) ≡ 0.// As suggested by Jacobsen, apply Crandall and Pomerance equation 3.13://// U(k) = D⁻¹ (2 V(k+1) - P V(k))//// Since we are checking for U(k) == 0 it suffices to check 2 V(k+1) == P V(k) mod n,// or P V(k) - 2 V(k+1) == 0 mod n.:= .mul(, ):= .shl(, 1)if .cmp() < 0 {, = ,}= .sub(, ):= // steal vk1, no longer needed below= nil_ =, = .div(, , )if len() == 0 {return true}}// Check V(2^t s) ≡ 0 mod n for some 0 ≤ t < r-1.for := 0; < -1; ++ {if len() == 0 { // vk == 0return true}// Optimization: V(k) = 2 is a fixed point for V(k') = V(k)² - 2,// so if V(k) = 2, we can stop: we will never find a future V(k) == 0.if len() == 1 && [0] == 2 { // vk == 2return false}// k' = 2k// V(k') = V(2k) = V(k)² - 2= .sqr()= .sub(, natTwo), = .div(, , )}return false}