+++ /dev/null
-package crypto
-
-import (
- "crypto/aes"
- "crypto/cipher"
- crand "crypto/rand"
- "io"
- "sync"
-
- . "github.com/tendermint/tmlibs/common"
-)
-
-var gRandInfo *randInfo
-
-func init() {
- gRandInfo = &randInfo{}
- gRandInfo.MixEntropy(randBytes(32)) // Init
-}
-
-// Mix additional bytes of randomness, e.g. from hardware, user-input, etc.
-// It is OK to call it multiple times. It does not diminish security.
-func MixEntropy(seedBytes []byte) {
- gRandInfo.MixEntropy(seedBytes)
-}
-
-// This only uses the OS's randomness
-func randBytes(numBytes int) []byte {
- b := make([]byte, numBytes)
- _, err := crand.Read(b)
- if err != nil {
- PanicCrisis(err)
- }
- return b
-}
-
-// This uses the OS and the Seed(s).
-func CRandBytes(numBytes int) []byte {
- b := make([]byte, numBytes)
- _, err := gRandInfo.Read(b)
- if err != nil {
- PanicCrisis(err)
- }
- return b
-}
-
-//--------------------------------------------------------------------------------
-
-type randInfo struct {
- mtx sync.Mutex
- seedBytes [32]byte
- cipherAES256 cipher.Block
- streamAES256 cipher.Stream
- reader io.Reader
-}
-
-// You can call this as many times as you'd like.
-// XXX TODO review
-func (ri *randInfo) MixEntropy(seedBytes []byte) {
- ri.mtx.Lock()
- defer ri.mtx.Unlock()
- // Make new ri.seedBytes
- hashBytes := Sha256(seedBytes)
- hashBytes32 := [32]byte{}
- copy(hashBytes32[:], hashBytes)
- ri.seedBytes = xorBytes32(ri.seedBytes, hashBytes32)
- // Create new cipher.Block
- var err error
- ri.cipherAES256, err = aes.NewCipher(ri.seedBytes[:])
- if err != nil {
- PanicSanity("Error creating AES256 cipher: " + err.Error())
- }
- // Create new stream
- ri.streamAES256 = cipher.NewCTR(ri.cipherAES256, randBytes(aes.BlockSize))
- // Create new reader
- ri.reader = &cipher.StreamReader{S: ri.streamAES256, R: crand.Reader}
-}
-
-func (ri *randInfo) Read(b []byte) (n int, err error) {
- ri.mtx.Lock()
- defer ri.mtx.Unlock()
- return ri.reader.Read(b)
-}
-
-func xorBytes32(bytesA [32]byte, bytesB [32]byte) (res [32]byte) {
- for i, b := range bytesA {
- res[i] = b ^ bytesB[i]
- }
- return res
-}