Browse Source

libs/rand: remove custom seed function (#7473)

pull/7477/head
Sam Kleinman 3 years ago
committed by GitHub
parent
commit
9a0dbdbf13
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 11 additions and 51 deletions
  1. +8
    -5
      libs/bits/bit_array.go
  2. +3
    -3
      libs/events/events_test.go
  3. +0
    -43
      libs/rand/random.go

+ 8
- 5
libs/bits/bit_array.go View File

@ -5,13 +5,12 @@ import (
"errors" "errors"
"fmt" "fmt"
"math" "math"
mrand "math/rand"
"math/rand"
"regexp" "regexp"
"strings" "strings"
"sync" "sync"
tmmath "github.com/tendermint/tendermint/libs/math" tmmath "github.com/tendermint/tendermint/libs/math"
tmrand "github.com/tendermint/tendermint/libs/rand"
tmprotobits "github.com/tendermint/tendermint/proto/tendermint/libs/bits" tmprotobits "github.com/tendermint/tendermint/proto/tendermint/libs/bits"
) )
@ -25,8 +24,6 @@ type BitArray struct {
// NewBitArray returns a new bit array. // NewBitArray returns a new bit array.
// It returns nil if the number of bits is zero. // It returns nil if the number of bits is zero.
func NewBitArray(bits int) *BitArray { func NewBitArray(bits int) *BitArray {
// Reseed non-deterministically.
tmrand.Reseed()
if bits <= 0 { if bits <= 0 {
return nil return nil
} }
@ -270,8 +267,14 @@ func (bA *BitArray) PickRandom() (int, bool) {
if len(trueIndices) == 0 { // no bits set to true if len(trueIndices) == 0 { // no bits set to true
return 0, false return 0, false
} }
// NOTE: using the default math/rand might result in somewhat
// amount of determinism here. It would be possible to use
// rand.New(rand.NewSeed(time.Now().Unix())).Intn() to
// counteract this possibility if it proved to be material.
//
// nolint:gosec // G404: Use of weak random number generator // nolint:gosec // G404: Use of weak random number generator
return trueIndices[mrand.Intn(len(trueIndices))], true
return trueIndices[rand.Intn(len(trueIndices))], true
} }
func (bA *BitArray) getTrueIndices() []int { func (bA *BitArray) getTrueIndices() []int {


+ 3
- 3
libs/events/events_test.go View File

@ -3,6 +3,7 @@ package events
import ( import (
"context" "context"
"fmt" "fmt"
"math/rand"
"testing" "testing"
"time" "time"
@ -10,7 +11,6 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/libs/rand"
) )
// TestAddListenerForEventFireOnce sets up an EventSwitch, subscribes a single // TestAddListenerForEventFireOnce sets up an EventSwitch, subscribes a single
@ -469,7 +469,7 @@ func TestRemoveListenersAsync(t *testing.T) {
// collect received events for event2 // collect received events for event2
go sumReceivedNumbers(numbers2, doneSum2) go sumReceivedNumbers(numbers2, doneSum2)
addListenersStress := func() { addListenersStress := func() {
r1 := rand.NewRand()
r1 := rand.New(rand.NewSource(time.Now().Unix()))
r1.Seed(time.Now().UnixNano()) r1.Seed(time.Now().UnixNano())
for k := uint16(0); k < 400; k++ { for k := uint16(0); k < 400; k++ {
listenerNumber := r1.Intn(100) + 3 listenerNumber := r1.Intn(100) + 3
@ -480,7 +480,7 @@ func TestRemoveListenersAsync(t *testing.T) {
} }
} }
removeListenersStress := func() { removeListenersStress := func() {
r2 := rand.NewRand()
r2 := rand.New(rand.NewSource(time.Now().Unix()))
r2.Seed(time.Now().UnixNano()) r2.Seed(time.Now().UnixNano())
for k := uint16(0); k < 80; k++ { for k := uint16(0); k < 80; k++ {
listenerNumber := r2.Intn(100) + 3 listenerNumber := r2.Intn(100) + 3


+ 0
- 43
libs/rand/random.go View File

@ -1,9 +1,6 @@
package rand package rand
import ( import (
crand "crypto/rand"
"encoding/binary"
"fmt"
mrand "math/rand" mrand "math/rand"
) )
@ -11,37 +8,6 @@ const (
strChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // 62 characters strChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // 62 characters
) )
func init() {
Reseed()
}
// NewRand returns a prng, that is seeded with OS randomness.
// The OS randomness is obtained from crypto/rand, however, like with any math/rand.Rand
// object none of the provided methods are suitable for cryptographic usage.
//
// Note that the returned instance of math/rand's Rand is not
// suitable for concurrent use by multiple goroutines.
//
// For concurrent use, call Reseed to reseed math/rand's default source and
// use math/rand's top-level convenience functions instead.
func NewRand() *mrand.Rand {
seed := crandSeed()
// nolint:gosec // G404: Use of weak random number generator
return mrand.New(mrand.NewSource(seed))
}
// Reseed conveniently re-seeds the default Source of math/rand with
// randomness obtained from crypto/rand.
//
// Note that this does not make math/rand suitable for cryptographic usage.
//
// Use math/rand's top-level convenience functions remain suitable
// for concurrent use by multiple goroutines.
func Reseed() {
seed := crandSeed()
mrand.Seed(seed)
}
// Str constructs a random alphanumeric string of given length // Str constructs a random alphanumeric string of given length
// from math/rand's global default Source. // from math/rand's global default Source.
func Str(length int) string { func Str(length int) string {
@ -78,12 +44,3 @@ func Bytes(n int) []byte {
} }
return bs return bs
} }
func crandSeed() int64 {
var seed int64
err := binary.Read(crand.Reader, binary.BigEndian, &seed)
if err != nil {
panic(fmt.Sprintf("could nor read random seed from crypto/rand: %v", err))
}
return seed
}

Loading…
Cancel
Save