]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/rand: use runtime.getRandomData on js/wasm
authorFilippo Valsorda <filippo@golang.org>
Sun, 25 Aug 2024 12:00:18 +0000 (14:00 +0200)
committerFilippo Valsorda <filippo@golang.org>
Mon, 7 Oct 2024 15:34:27 +0000 (15:34 +0000)
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 <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
src/crypto/rand/rand_js.go
src/crypto/rand/rand_test.go

index 82cc75fb4e7cde79288d3e7d24c3444387cd1f08..d45031a039e3c67806fee1d6b154313265926e9a 100644 (file)
@@ -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
 }
index d3040cbe307642d25fd4983661c9af01abdf1e69..003a8de9aeee2fb84fae82cf818edbde6c44d7a1 100644 (file)
@@ -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")
        }