libs/common/rand: Update godocs

The godocs fell out of sync with the code here. Additionally we had
warning that these randomness functions weren't for cryptographic
use on every function. However these warnings are confusing, since
there was no implication that they would be secure there, and a
single warning on the actual Rand type would suffice. (This is what
is done in golang's math/rand godoc)

Additionally we indicated that rand.Bytes() was reading OS randomness
but in fact that had been changed.
This commit is contained in:
ValarDragon 2018-07-14 15:31:25 -07:00 committed by Anton Kaliaev
parent dae7dc30e0
commit a3df06d081
1 changed files with 12 additions and 29 deletions

View File

@ -11,9 +11,13 @@ const (
strChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // 62 characters strChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // 62 characters
) )
// pseudo random number generator. // Rand is a prng, that is seeded with OS randomness.
// seeded with OS randomness (crand) // The OS randomness is obtained from crypto/rand, however none of the provided
// methods are suitable for cryptographic usage.
// They all utilize math/rand's prng internally.
//
// All of the methods here are suitable for concurrent use.
// This is achieved by using a mutex lock on all of the provided methods.
type Rand struct { type Rand struct {
sync.Mutex sync.Mutex
rand *mrand.Rand rand *mrand.Rand
@ -150,8 +154,7 @@ func (r *Rand) Seed(seed int64) {
r.Unlock() r.Unlock()
} }
// Constructs an alphanumeric string of given length. // Str constructs a random alphanumeric string of given length.
// It is not safe for cryptographic usage.
func (r *Rand) Str(length int) string { func (r *Rand) Str(length int) string {
chars := []byte{} chars := []byte{}
MAIN_LOOP: MAIN_LOOP:
@ -175,12 +178,10 @@ MAIN_LOOP:
return string(chars) return string(chars)
} }
// It is not safe for cryptographic usage.
func (r *Rand) Uint16() uint16 { func (r *Rand) Uint16() uint16 {
return uint16(r.Uint32() & (1<<16 - 1)) return uint16(r.Uint32() & (1<<16 - 1))
} }
// It is not safe for cryptographic usage.
func (r *Rand) Uint32() uint32 { func (r *Rand) Uint32() uint32 {
r.Lock() r.Lock()
u32 := r.rand.Uint32() u32 := r.rand.Uint32()
@ -188,12 +189,10 @@ func (r *Rand) Uint32() uint32 {
return u32 return u32
} }
// It is not safe for cryptographic usage.
func (r *Rand) Uint64() uint64 { func (r *Rand) Uint64() uint64 {
return uint64(r.Uint32())<<32 + uint64(r.Uint32()) return uint64(r.Uint32())<<32 + uint64(r.Uint32())
} }
// It is not safe for cryptographic usage.
func (r *Rand) Uint() uint { func (r *Rand) Uint() uint {
r.Lock() r.Lock()
i := r.rand.Int() i := r.rand.Int()
@ -201,22 +200,18 @@ func (r *Rand) Uint() uint {
return uint(i) return uint(i)
} }
// It is not safe for cryptographic usage.
func (r *Rand) Int16() int16 { func (r *Rand) Int16() int16 {
return int16(r.Uint32() & (1<<16 - 1)) return int16(r.Uint32() & (1<<16 - 1))
} }
// It is not safe for cryptographic usage.
func (r *Rand) Int32() int32 { func (r *Rand) Int32() int32 {
return int32(r.Uint32()) return int32(r.Uint32())
} }
// It is not safe for cryptographic usage.
func (r *Rand) Int64() int64 { func (r *Rand) Int64() int64 {
return int64(r.Uint64()) return int64(r.Uint64())
} }
// It is not safe for cryptographic usage.
func (r *Rand) Int() int { func (r *Rand) Int() int {
r.Lock() r.Lock()
i := r.rand.Int() i := r.rand.Int()
@ -224,7 +219,6 @@ func (r *Rand) Int() int {
return i return i
} }
// It is not safe for cryptographic usage.
func (r *Rand) Int31() int32 { func (r *Rand) Int31() int32 {
r.Lock() r.Lock()
i31 := r.rand.Int31() i31 := r.rand.Int31()
@ -232,7 +226,6 @@ func (r *Rand) Int31() int32 {
return i31 return i31
} }
// It is not safe for cryptographic usage.
func (r *Rand) Int31n(n int32) int32 { func (r *Rand) Int31n(n int32) int32 {
r.Lock() r.Lock()
i31n := r.rand.Int31n(n) i31n := r.rand.Int31n(n)
@ -240,7 +233,6 @@ func (r *Rand) Int31n(n int32) int32 {
return i31n return i31n
} }
// It is not safe for cryptographic usage.
func (r *Rand) Int63() int64 { func (r *Rand) Int63() int64 {
r.Lock() r.Lock()
i63 := r.rand.Int63() i63 := r.rand.Int63()
@ -248,7 +240,6 @@ func (r *Rand) Int63() int64 {
return i63 return i63
} }
// It is not safe for cryptographic usage.
func (r *Rand) Int63n(n int64) int64 { func (r *Rand) Int63n(n int64) int64 {
r.Lock() r.Lock()
i63n := r.rand.Int63n(n) i63n := r.rand.Int63n(n)
@ -257,7 +248,6 @@ func (r *Rand) Int63n(n int64) int64 {
} }
// Distributed pseudo-exponentially to test for various cases // Distributed pseudo-exponentially to test for various cases
// It is not safe for cryptographic usage.
func (r *Rand) Uint16Exp() uint16 { func (r *Rand) Uint16Exp() uint16 {
bits := r.Uint32() % 16 bits := r.Uint32() % 16
if bits == 0 { if bits == 0 {
@ -269,7 +259,6 @@ func (r *Rand) Uint16Exp() uint16 {
} }
// Distributed pseudo-exponentially to test for various cases // Distributed pseudo-exponentially to test for various cases
// It is not safe for cryptographic usage.
func (r *Rand) Uint32Exp() uint32 { func (r *Rand) Uint32Exp() uint32 {
bits := r.Uint32() % 32 bits := r.Uint32() % 32
if bits == 0 { if bits == 0 {
@ -281,7 +270,6 @@ func (r *Rand) Uint32Exp() uint32 {
} }
// Distributed pseudo-exponentially to test for various cases // Distributed pseudo-exponentially to test for various cases
// It is not safe for cryptographic usage.
func (r *Rand) Uint64Exp() uint64 { func (r *Rand) Uint64Exp() uint64 {
bits := r.Uint32() % 64 bits := r.Uint32() % 64
if bits == 0 { if bits == 0 {
@ -292,7 +280,6 @@ func (r *Rand) Uint64Exp() uint64 {
return n return n
} }
// It is not safe for cryptographic usage.
func (r *Rand) Float32() float32 { func (r *Rand) Float32() float32 {
r.Lock() r.Lock()
f32 := r.rand.Float32() f32 := r.rand.Float32()
@ -300,7 +287,6 @@ func (r *Rand) Float32() float32 {
return f32 return f32
} }
// It is not safe for cryptographic usage.
func (r *Rand) Float64() float64 { func (r *Rand) Float64() float64 {
r.Lock() r.Lock()
f64 := r.rand.Float64() f64 := r.rand.Float64()
@ -308,13 +294,12 @@ func (r *Rand) Float64() float64 {
return f64 return f64
} }
// It is not safe for cryptographic usage.
func (r *Rand) Time() time.Time { func (r *Rand) Time() time.Time {
return time.Unix(int64(r.Uint64Exp()), 0) return time.Unix(int64(r.Uint64Exp()), 0)
} }
// RandBytes returns n random bytes from the OS's source of entropy ie. via crypto/rand. // Bytes returns n random bytes generated from the internal
// It is not safe for cryptographic usage. // prng.
func (r *Rand) Bytes(n int) []byte { func (r *Rand) Bytes(n int) []byte {
// cRandBytes isn't guaranteed to be fast so instead // cRandBytes isn't guaranteed to be fast so instead
// use random bytes generated from the internal PRNG // use random bytes generated from the internal PRNG
@ -325,9 +310,8 @@ func (r *Rand) Bytes(n int) []byte {
return bs return bs
} }
// RandIntn returns, as an int, a non-negative pseudo-random number in [0, n). // Intn returns, as an int, a uniform pseudo-random number in the range [0, n).
// It panics if n <= 0. // It panics if n <= 0.
// It is not safe for cryptographic usage.
func (r *Rand) Intn(n int) int { func (r *Rand) Intn(n int) int {
r.Lock() r.Lock()
i := r.rand.Intn(n) i := r.rand.Intn(n)
@ -335,8 +319,7 @@ func (r *Rand) Intn(n int) int {
return i return i
} }
// RandPerm returns a pseudo-random permutation of n integers in [0, n). // Perm returns a pseudo-random permutation of n integers in [0, n).
// It is not safe for cryptographic usage.
func (r *Rand) Perm(n int) []int { func (r *Rand) Perm(n int) []int {
r.Lock() r.Lock()
perm := r.rand.Perm(n) perm := r.rand.Perm(n)