From: Filippo Valsorda Date: Sun, 25 Aug 2024 12:00:18 +0000 (+0200) Subject: crypto/rand: use runtime.getRandomData on js/wasm X-Git-Tag: go1.24rc1~742 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=ef14ba3e68c166596963bc26187e118cf79375cf;p=gostls13.git crypto/rand: use runtime.getRandomData on js/wasm This mechanism ultimately calls the same JavaScript method, but being consistent between runtime and crypto/rand lets us reuse test coverage across them. Also, no allocations. Cq-Include-Trybots: luci.golang.try:gotip-js-wasm Change-Id: I035da1ed603fbcdad61945f2b57f3fb527a959fe Reviewed-on: https://go-review.googlesource.com/c/go/+/608396 LUCI-TryBot-Result: Go LUCI Reviewed-by: Roland Shoemaker Reviewed-by: Michael Knyszek Reviewed-by: Daniel McCarney --- diff --git a/src/crypto/rand/rand_js.go b/src/crypto/rand/rand_js.go index 82cc75fb4e..d45031a039 100644 --- a/src/crypto/rand/rand_js.go +++ b/src/crypto/rand/rand_js.go @@ -4,41 +4,24 @@ package rand -import "syscall/js" - // The maximum buffer size for crypto.getRandomValues is 65536 bytes. // https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#exceptions const maxGetRandomRead = 64 << 10 -// read implements a pseudorandom generator -// using JavaScript crypto.getRandomValues method. -// See https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues. -var read = batched(getRandom, maxGetRandomRead) - -var jsCrypto = js.Global().Get("crypto") -var uint8Array = js.Global().Get("Uint8Array") - -func getRandom(b []byte) error { - a := uint8Array.New(len(b)) - jsCrypto.Call("getRandomValues", a) - js.CopyBytesToGo(b, a) - return nil -} +//go:wasmimport gojs runtime.getRandomData +//go:noescape +func getRandomValues(r []byte) -// batched returns a function that calls f to populate a []byte by chunking it -// into subslices of, at most, readMax bytes. -func batched(f func([]byte) error, readMax int) func([]byte) error { - return func(out []byte) error { - for len(out) > 0 { - read := len(out) - if read > readMax { - read = readMax - } - if err := f(out[:read]); err != nil { - return err - } - out = out[read:] +// read calls the JavaScript Crypto.getRandomValues() method. +// See https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues. +func read(b []byte) error { + for len(b) > 0 { + size := len(b) + if size > maxGetRandomRead { + size = maxGetRandomRead } - return nil + getRandomValues(b[:size]) + b = b[size:] } + return nil } diff --git a/src/crypto/rand/rand_test.go b/src/crypto/rand/rand_test.go index d3040cbe30..003a8de9ae 100644 --- a/src/crypto/rand/rand_test.go +++ b/src/crypto/rand/rand_test.go @@ -160,9 +160,6 @@ func TestAllocations(t *testing.T) { // Might be fixable with https://go.dev/issue/56378. t.Skip("boringcrypto allocates") } - if runtime.GOOS == "js" { - t.Skip("syscall/js allocates") - } if race.Enabled { t.Skip("urandomRead allocates under -race") }