Source File
rand_unix.go
Belonging Package
crypto/rand
package rand
import (
)
const urandomDevice = "/dev/urandom"
:= time.AfterFunc(60*time.Second, warnBlocked)
defer .Stop()
}
if altGetRandom != nil && .name == urandomDevice && altGetRandom() {
return len(), nil
}
.mu.Lock()
defer .mu.Unlock()
if .f == nil {
, := os.Open(.name)
if == nil {
return 0,
}
if runtime.GOOS == "plan9" {
.f =
} else {
.f = bufio.NewReader(hideAgainReader{})
}
}
return .f.Read()
}
var isEAGAIN func(error) bool // set by eagain.go on unix systems
func ( io.Reader) io.Reader {
if == nil {
= &devReader{name: "/dev/random"}
}
return &reader{entropy: }
}
type reader struct {
mu sync.Mutex
budget int // number of bytes that can be generated
cipher cipher.Block
entropy io.Reader
time, seed, dst, key [aes.BlockSize]byte
}
func ( *reader) ( []byte) ( int, error) {
.mu.Lock()
defer .mu.Unlock()
= len()
for len() > 0 {
if .budget == 0 {
, := io.ReadFull(.entropy, .seed[0:])
if != nil {
return - len(),
}
_, = io.ReadFull(.entropy, .key[0:])
if != nil {
return - len(),
}
.cipher, = aes.NewCipher(.key[0:])
if != nil {
return - len(),
}
.budget = 1 << 20 // reseed after generating 1MB
}
.budget -= aes.BlockSize
:= time.Now().UnixNano()
binary.BigEndian.PutUint64(.time[:], uint64())
.cipher.Encrypt(.time[0:], .time[0:])
for := 0; < aes.BlockSize; ++ {
.dst[] = .time[] ^ .seed[]
}
.cipher.Encrypt(.dst[0:], .dst[0:])
for := 0; < aes.BlockSize; ++ {
.seed[] = .time[] ^ .dst[]
}
.cipher.Encrypt(.seed[0:], .seed[0:])
:= copy(, .dst[0:])
= [:]
}
return , nil
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |