10 . "github.com/tendermint/tmlibs/common"
13 var gRandInfo *randInfo
16 gRandInfo = &randInfo{}
17 gRandInfo.MixEntropy(randBytes(32)) // Init
20 // Mix additional bytes of randomness, e.g. from hardware, user-input, etc.
21 // It is OK to call it multiple times. It does not diminish security.
22 func MixEntropy(seedBytes []byte) {
23 gRandInfo.MixEntropy(seedBytes)
26 // This only uses the OS's randomness
27 func randBytes(numBytes int) []byte {
28 b := make([]byte, numBytes)
29 _, err := crand.Read(b)
36 // This uses the OS and the Seed(s).
37 func CRandBytes(numBytes int) []byte {
38 b := make([]byte, numBytes)
39 _, err := gRandInfo.Read(b)
46 //--------------------------------------------------------------------------------
48 type randInfo struct {
51 cipherAES256 cipher.Block
52 streamAES256 cipher.Stream
56 // You can call this as many times as you'd like.
58 func (ri *randInfo) MixEntropy(seedBytes []byte) {
61 // Make new ri.seedBytes
62 hashBytes := Sha256(seedBytes)
63 hashBytes32 := [32]byte{}
64 copy(hashBytes32[:], hashBytes)
65 ri.seedBytes = xorBytes32(ri.seedBytes, hashBytes32)
66 // Create new cipher.Block
68 ri.cipherAES256, err = aes.NewCipher(ri.seedBytes[:])
70 PanicSanity("Error creating AES256 cipher: " + err.Error())
73 ri.streamAES256 = cipher.NewCTR(ri.cipherAES256, randBytes(aes.BlockSize))
75 ri.reader = &cipher.StreamReader{S: ri.streamAES256, R: crand.Reader}
78 func (ri *randInfo) Read(b []byte) (n int, err error) {
81 return ri.reader.Read(b)
84 func xorBytes32(bytesA [32]byte, bytesB [32]byte) (res [32]byte) {
85 for i, b := range bytesA {
86 res[i] = b ^ bytesB[i]