prysm-pulse/shared/rand/rand.go
Preston Van Loon 7cc32c4dda
Various code inspection resolutions (#7438)
* remove unused code

* remove defer use in loop

* Remove unused methods and constants

* gofmt and gaz

* nilness check

* remove unused args

* Add TODO for refactoring subscribeWithBase to remove unused arg. It seems too involved to include in this sweeping PR. https://github.com/prysmaticlabs/prysm/issues/7437

* replace empty slice declaration

* Remove unnecessary type conversions

* remove redundant type declaration

* rename receivers to be consistent

* Remove bootnode query tool. It is now obsolete by discv5

* Remove relay node. It is no longer used or supported

* Revert "Remove relay node. It is no longer used or supported"

This reverts commit 4bd7717334dad85ef4766ed9bc4da711fb5fa810.

* Delete unused test directory

* Delete unsupported gcp startup script

* Delete old k8s script

* build fixes

* fix build

* go mod tidy

* revert slasher/db/kv/block_header.go

* fix build

* remove redundant nil check

* combine func args

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Victor Farazdagi <simple.square@gmail.com>
2020-10-12 08:11:05 +00:00

81 lines
3.1 KiB
Go

/*
Package rand defines methods of obtaining cryptographically secure random number generators.
One is expected to use randomness from this package only, without introducing any other packages.
This limits the scope of code that needs to be hardened.
There are two modes, one for deterministic and another non-deterministic randomness:
1. If deterministic pseudo-random generator is enough, use:
import "github.com/prysmaticlabs/prysm/shared/rand"
randGen := rand.NewDeterministicGenerator()
randGen.Intn(32) // or any other func defined in math.rand API
In this mode, only seed is generated using cryptographically secure source (crypto/rand). So,
once seed is obtained, and generator is seeded, the next generations are deterministic, thus fast.
This method is still better than using unix time for source of randomness - since time is not a
good source of seed randomness, when you have many concurrent servers using it (and they have
coinciding random generators' start times).
2. For cryptographically secure non-deterministic mode (CSPRNG), use:
import "github.com/prysmaticlabs/prysm/shared/rand"
randGen := rand.NewGenerator()
randGen.Intn(32) // or any other func defined in math.rand API
Again, any of the functions from `math/rand` can be used, however, they all use custom source
of randomness (crypto/rand), on every step. This makes randomness non-deterministic. However,
you take a performance hit -- as it is an order of magnitude slower.
*/
package rand
import (
"crypto/rand"
"encoding/binary"
mrand "math/rand"
)
type source struct{}
var _ mrand.Source64 = (*source)(nil)
// Seed does nothing when crypto/rand is used as source.
func (s *source) Seed(_ int64) {}
// Int63 returns uniformly-distributed random (as in CSPRNG) int64 value within [0, 1<<63) range.
// Panics if random generator reader cannot return data.
func (s *source) Int63() int64 {
return int64(s.Uint64() & ^uint64(1<<63))
}
// Uint64 returns uniformly-distributed random (as in CSPRNG) uint64 value within [0, 1<<64) range.
// Panics if random generator reader cannot return data.
func (s *source) Uint64() (val uint64) {
if err := binary.Read(rand.Reader, binary.BigEndian, &val); err != nil {
panic(err)
}
return
}
// Rand is alias for underlying random generator.
type Rand = mrand.Rand
// NewGenerator returns a new generator that uses random values from crypto/rand as a source
// (cryptographically secure random number generator).
// Panics if crypto/rand input cannot be read.
// Use it for everything where crypto secure non-deterministic randomness is required. Performance
// takes a hit, so use sparingly.
func NewGenerator() *Rand {
return mrand.New(&source{})
}
// NewDeterministicGenerator returns a random generator which is only seeded with crypto/rand,
// but is deterministic otherwise (given seed, produces given results, deterministically).
// Panics if crypto/rand input cannot be read.
// Use this method for performance, where deterministic pseudo-random behaviour is enough.
// Otherwise, rely on NewGenerator().
func NewDeterministicGenerator() *Rand {
randGen := NewGenerator()
return mrand.New(mrand.NewSource(randGen.Int63()))
}