1// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5//go:build js && wasm
6
7package rand
8
9import "syscall/js"
10
11// The maximum buffer size for crypto.getRandomValues is 65536 bytes.
12// https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#exceptions
13const maxGetRandomRead = 64 << 10
14
15var batchedGetRandom func([]byte) error
16
17func init() {
18	Reader = &reader{}
19	batchedGetRandom = batched(getRandom, maxGetRandomRead)
20}
21
22var jsCrypto = js.Global().Get("crypto")
23var uint8Array = js.Global().Get("Uint8Array")
24
25// reader implements a pseudorandom generator
26// using JavaScript crypto.getRandomValues method.
27// See https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues.
28type reader struct{}
29
30func (r *reader) Read(b []byte) (int, error) {
31	if err := batchedGetRandom(b); err != nil {
32		return 0, err
33	}
34	return len(b), nil
35}
36
37func getRandom(b []byte) error {
38	a := uint8Array.New(len(b))
39	jsCrypto.Call("getRandomValues", a)
40	js.CopyBytesToGo(b, a)
41	return nil
42}
43