diff --git a/src/crypto/rand/util.go b/src/crypto/rand/util.go index 4dd1711203..0f143a3830 100644 --- a/src/crypto/rand/util.go +++ b/src/crypto/rand/util.go @@ -10,28 +10,11 @@ import ( "math/big" ) -// smallPrimes is a list of small, prime numbers that allows us to rapidly -// exclude some fraction of composite candidates when searching for a random -// prime. This list is truncated at the point where smallPrimesProduct exceeds -// a uint64. It does not include two because we ensure that the candidates are -// odd by construction. -var smallPrimes = []uint8{ - 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, -} - -// smallPrimesProduct is the product of the values in smallPrimes and allows us -// to reduce a candidate prime by this number and then determine whether it's -// coprime to all the elements of smallPrimes without further big.Int -// operations. -var smallPrimesProduct = new(big.Int).SetUint64(16294579238595022365) - -// Prime returns a number, p, of the given size, such that p is prime -// with high probability. +// Prime returns a number of the given bit length that is prime with high probability. // Prime will return error for any error returned by rand.Read or if bits < 2. -func Prime(rand io.Reader, bits int) (p *big.Int, err error) { +func Prime(rand io.Reader, bits int) (*big.Int, error) { if bits < 2 { - err = errors.New("crypto/rand: prime size must be at least 2-bit") - return + return nil, errors.New("crypto/rand: prime size must be at least 2-bit") } b := uint(bits % 8) @@ -40,13 +23,10 @@ func Prime(rand io.Reader, bits int) (p *big.Int, err error) { } bytes := make([]byte, (bits+7)/8) - p = new(big.Int) - - bigMod := new(big.Int) + p := new(big.Int) for { - _, err = io.ReadFull(rand, bytes) - if err != nil { + if _, err := io.ReadFull(rand, bytes); err != nil { return nil, err } @@ -69,35 +49,8 @@ func Prime(rand io.Reader, bits int) (p *big.Int, err error) { bytes[len(bytes)-1] |= 1 p.SetBytes(bytes) - - // Calculate the value mod the product of smallPrimes. If it's - // a multiple of any of these primes we add two until it isn't. - // The probability of overflowing is minimal and can be ignored - // because we still perform Miller-Rabin tests on the result. - bigMod.Mod(p, smallPrimesProduct) - mod := bigMod.Uint64() - - NextDelta: - for delta := uint64(0); delta < 1<<20; delta += 2 { - m := mod + delta - for _, prime := range smallPrimes { - if m%uint64(prime) == 0 && (bits > 6 || m != uint64(prime)) { - continue NextDelta - } - } - - if delta > 0 { - bigMod.SetUint64(delta) - p.Add(p, bigMod) - } - break - } - - // There is a tiny possibility that, by adding delta, we caused - // the number to be one bit too long. Thus we check BitLen - // here. - if p.ProbablyPrime(20) && p.BitLen() == bits { - return + if p.ProbablyPrime(20) { + return p, nil } } }