crypto/rand: switch to arc4random_buf
This doesn't have the potential blocking issue of the getentropy call (which calls WASI random_get when using wasi-libc) and should therefore be a lot faster. For context, this is what the random_get documentation says: > Write high-quality random data into a buffer. This function blocks > when the implementation is unable to immediately provide sufficient > high-quality random data. This function may execute slowly, so when > large mounts of random data are required, it's advisable to use this > function to seed a pseudo-random number generator, rather than to > provide the random data directly.
Этот коммит содержится в:
родитель
4f7b23c2b7
коммит
d05103668f
2 изменённых файлов: 30 добавлений и 38 удалений
30
src/crypto/rand/rand_arc4random.go
Обычный файл
30
src/crypto/rand/rand_arc4random.go
Обычный файл
|
@ -0,0 +1,30 @@
|
||||||
|
// +build darwin freebsd tinygo.wasm
|
||||||
|
|
||||||
|
// This implementation of crypto/rand uses the arc4random_buf function
|
||||||
|
// (available on both MacOS and WASI) to generate random numbers.
|
||||||
|
//
|
||||||
|
// Note: arc4random_buf (unlike what the name suggets) does not use the insecure
|
||||||
|
// RC4 cipher. Instead, it uses a high-quality cipher, varying by the libc
|
||||||
|
// implementation.
|
||||||
|
|
||||||
|
package rand
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Reader = &reader{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type reader struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *reader) Read(b []byte) (n int, err error) {
|
||||||
|
if len(b) != 0 {
|
||||||
|
libc_arc4random_buf(unsafe.Pointer(&b[0]), uint(len(b)))
|
||||||
|
}
|
||||||
|
return len(b), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// void arc4random_buf(void *buf, size_t buflen);
|
||||||
|
//export arc4random_buf
|
||||||
|
func libc_arc4random_buf(buf unsafe.Pointer, buflen uint)
|
|
@ -1,38 +0,0 @@
|
||||||
// +build darwin freebsd tinygo.wasm
|
|
||||||
|
|
||||||
// This implementation of crypto/rand uses the getentropy system call (available
|
|
||||||
// on both MacOS and WASI) to generate random numbers.
|
|
||||||
|
|
||||||
package rand
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
var errReadFailed = errors.New("rand: could not read random bytes")
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
Reader = &reader{}
|
|
||||||
}
|
|
||||||
|
|
||||||
type reader struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *reader) Read(b []byte) (n int, err error) {
|
|
||||||
if len(b) != 0 {
|
|
||||||
if len(b) > 256 {
|
|
||||||
b = b[:256]
|
|
||||||
}
|
|
||||||
result := libc_getentropy(unsafe.Pointer(&b[0]), len(b))
|
|
||||||
if result < 0 {
|
|
||||||
// Maybe we should return a syscall.Errno here?
|
|
||||||
return 0, errReadFailed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return len(b), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// int getentropy(void *buf, size_t buflen);
|
|
||||||
//export getentropy
|
|
||||||
func libc_getentropy(buf unsafe.Pointer, buflen int) int
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче