From: Filippo Valsorda Date: Thu, 10 Mar 2022 16:43:43 +0000 (-0500) Subject: crypto/rand: make Prime not deterministic for a fixed input stream X-Git-Tag: go1.19beta1~766 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=c18f398f32c45afe2e9a81a6d885a4e0183cd649;p=gostls13.git crypto/rand: make Prime not deterministic for a fixed input stream rand.Prime does not guarantee the precise prime selection algorithm as part of its contract. For example, it changed slightly in CL 387554. We want to ensure that no tests come to rely on it staying the same, so just like other cryptographic functions that use randomness in an unspecified way (ECDSA signing, RSA PKCS #1 v1.5 encryption, RSA key generation), make it randomly read an extra byte or not. Change-Id: Ib9079c03360812d412b7c21d5a06caadabb4a8bf Reviewed-on: https://go-review.googlesource.com/c/go/+/391554 Run-TryBot: Filippo Valsorda Auto-Submit: Filippo Valsorda Trust: Filippo Valsorda TryBot-Result: Gopher Robot Reviewed-by: Roland Shoemaker --- diff --git a/src/crypto/rand/util.go b/src/crypto/rand/util.go index 0f143a3830..11b1a28ec5 100644 --- a/src/crypto/rand/util.go +++ b/src/crypto/rand/util.go @@ -5,6 +5,7 @@ package rand import ( + "crypto/internal/randutil" "errors" "io" "math/big" @@ -17,6 +18,8 @@ func Prime(rand io.Reader, bits int) (*big.Int, error) { return nil, errors.New("crypto/rand: prime size must be at least 2-bit") } + randutil.MaybeReadByte(rand) + b := uint(bits % 8) if b == 0 { b = 8 diff --git a/src/crypto/rand/util_test.go b/src/crypto/rand/util_test.go index e76ce2018a..9caf8e91cc 100644 --- a/src/crypto/rand/util_test.go +++ b/src/crypto/rand/util_test.go @@ -38,6 +38,25 @@ func TestPrimeBitsLt2(t *testing.T) { } } +func TestPrimeNondeterministic(t *testing.T) { + r := mathrand.New(mathrand.NewSource(42)) + p0, err := rand.Prime(r, 32) + if err != nil { + t.Fatal(err) + } + for i := 0; i < 128; i++ { + r.Seed(42) + p, err := rand.Prime(r, 32) + if err != nil { + t.Fatal(err) + } + if p.Cmp(p0) != 0 { + return + } + } + t.Error("Prime always generated the same prime given the same input") +} + func TestInt(t *testing.T) { // start at 128 so the case of (max.BitLen() % 8) == 0 is covered for n := 128; n < 140; n++ { diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go index c4fb2fe0b4..052e7ad9c0 100644 --- a/src/go/build/deps_test.go +++ b/src/go/build/deps_test.go @@ -416,8 +416,8 @@ var depsRules = ` # CRYPTO-MATH is core bignum-based crypto - no cgo, net; fmt now ok. CRYPTO, FMT, math/big, embed - < crypto/rand < crypto/internal/randutil + < crypto/rand < crypto/ed25519 < encoding/asn1 < golang.org/x/crypto/cryptobyte/asn1