From 8db763f46dddd5827b54f5fa7c161097a83e8f69 Mon Sep 17 00:00:00 2001 From: Sudhi Herle Date: Sat, 1 Jun 2019 22:49:43 -0700 Subject: [PATCH] use rand.Prime instead of local copy. --- prime.go | 104 +++---------------------------------------------------- 1 file changed, 4 insertions(+), 100 deletions(-) diff --git a/prime.go b/prime.go index 947c7c6..9d658da 100644 --- a/prime.go +++ b/prime.go @@ -1,40 +1,20 @@ // prime.go - Generate safe primes // // Copyright 2013-2017 Sudhi Herle -// -// This code is largely simplified copy of crypto/rand/util.go; and thus, this file is licensed -// under the same terms as golang. - +// License: MIT package srp import ( "crypto/rand" - "errors" - "io" "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) - // safePrime generates a safe prime; i.e., a prime 'p' such that 2p+1 is also prime. func safePrime(bits int) (*big.Int, error) { a := new(big.Int) for { - p, err := prime(bits) + p, err := rand.Prime(rand.Reader, bits) if err != nil { return nil, err } @@ -51,84 +31,6 @@ func safePrime(bits int) (*big.Int, error) { return nil, nil } -// Prime returns a number, p, of the given size, such that p is prime -// with high probability. -// Prime will return error for any error returned by rand.Read or if bits < 2. -func prime(bits int) (p *big.Int, err error) { - if bits < 2 { - err = errors.New("srp: prime size must be at least 2-bit") - return - } - - b := uint(bits % 8) - if b == 0 { - b = 8 - } - - bytes := make([]byte, (bits+7)/8) - p = new(big.Int) - - bigMod := new(big.Int) - - for { - _, err = io.ReadFull(rand.Reader, bytes) - if err != nil { - return nil, err - } - - // Clear bits in the first byte to make sure the candidate has a size <= bits. - bytes[0] &= uint8(int(1<= 2 { - bytes[0] |= 3 << (b - 2) - } else { - // Here b==1, because b cannot be zero. - bytes[0] |= 1 - if len(bytes) > 1 { - bytes[1] |= 0x80 - } - } - - // Set the first two bits since we will be looking for safe primes. - // * if p is prime, we want (p-1)/2 to also be prime. - // * (p-1)/2 is p >> 1 - // * and setting bit 1 guarantees that (p-1)/2 will be odd. - bytes[len(bytes)-1] |= 3 - 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 - } - - if p.ProbablyPrime(20) && p.BitLen() == bits { - return - } - } -} - // Return true if g is a generator for safe prime p // // From Cryptography Theory & Practive, Stinson and Paterson (Th. 6.8 pp 196): @@ -184,3 +86,5 @@ func ok(g, x *big.Int, p *big.Int) bool { } return false } + +// vim: noexpandtab:sw=8:ts=8:tw=92: