package gmath import ( "crypto/rand" "math/big" "xdx.jelly/xgcl/grand" ) const MRConst = 10 // IsPrimeMR tests if n is prime by the Miller-Rabin prime testing method. func IsPrimeMR(n *big.Int) bool { return n.ProbablyPrime(MRConst) } // MillerRabin tests if n is prime by the Miller-Rabin prime testing method. func MillerRabin(n *big.Int) bool { // n = 2^s * r n1 := new(big.Int) n1.Sub(n, BigInt1) r := new(big.Int).Set(n1) s := 0 for r.Bit(0) == 0 { s++ r = r.Rsh(r, 1) } for i := 0; i < MRConst; i++ { a, _ := rand.Int(grand.Reader, n1) //a = a^r mod n a.Exp(a, r, n) if a.Cmp(BigInt1) != 0 && a.Cmp(n1) != 0 { for j := 1; j < s && a.Cmp(n1) != 0; j++ { a.Mul(a, a) a.Mod(a, n) if a.Cmp(BigInt1) == 0 { return false } } if a.Cmp(n1) != 0 { return false } } } return true }