package cryptorand import ( "crypto/rand" "encoding/binary" insecurerand "math/rand" ) type cryptoSource struct { err error } func (*cryptoSource) Seed(_ int64) { // Intentionally disregard seed } func (c *cryptoSource) Int63() int64 { var n int64 err := binary.Read(rand.Reader, binary.BigEndian, &n) if err != nil { c.err = err } // The sign bit must be cleared to ensure the final value is non-negative. n &= 0x7fffffffffffffff return n } func (c *cryptoSource) Uint64() uint64 { var n uint64 err := binary.Read(rand.Reader, binary.BigEndian, &n) if err != nil { c.err = err } return n } // secureRand returns a cryptographically secure random number generator. func secureRand() (*insecurerand.Rand, *cryptoSource) { var cs cryptoSource //nolint:gosec return insecurerand.New(&cs), &cs } // Int64 returns a non-negative random 63-bit integer as a int64. func Int63() (int64, error) { rng, cs := secureRand() return rng.Int63(), cs.err } // Intn returns a non-negative integer in [0,max) as an int. func Intn(max int) (int, error) { rng, cs := secureRand() return rng.Intn(max), cs.err } // Float64 returns a random number in [0.0,1.0) as a float64. func Float64() (float64, error) { rng, cs := secureRand() return rng.Float64(), cs.err }