Browse code

Prefer crypto rand seed for pkg/rand

Crypto rand is a much better seed for math/rand than
time. In the event we use math/rand where we should not,
this will make it a safer source of random numbers.

Although potentially dangerous, this will still fallback
to time should crypto/rand for any reason fail.

Signed-off-by: Eric Windisch <eric@windisch.us>

Eric Windisch authored on 2015/07/30 00:38:09
Showing 1 changed files
... ...
@@ -1,7 +1,10 @@
1 1
 package random
2 2
 
3 3
 import (
4
+	cryptorand "crypto/rand"
4 5
 	"io"
6
+	"math"
7
+	"math/big"
5 8
 	"math/rand"
6 9
 	"sync"
7 10
 	"time"
... ...
@@ -36,8 +39,15 @@ func (r *lockedSource) Seed(seed int64) {
36 36
 // NewSource returns math/rand.Source safe for concurrent use and initialized
37 37
 // with current unix-nano timestamp
38 38
 func NewSource() rand.Source {
39
+	var seed int64
40
+	if cryptoseed, err := cryptorand.Int(cryptorand.Reader, big.NewInt(math.MaxInt64)); err != nil {
41
+		// This should not happen, but worst-case fallback to time-based seed.
42
+		seed = time.Now().UnixNano()
43
+	} else {
44
+		seed = cryptoseed.Int64()
45
+	}
39 46
 	return &lockedSource{
40
-		src: rand.NewSource(time.Now().UnixNano()),
47
+		src: rand.NewSource(seed),
41 48
 	}
42 49
 }
43 50