package rand_test
-import (
- "bytes"
- "crypto/rand"
- "fmt"
-)
+import "crypto/rand"
-// This example reads 10 cryptographically secure pseudorandom numbers from
-// rand.Reader and writes them to a byte slice.
func ExampleRead() {
- c := 10
- b := make([]byte, c)
- _, err := rand.Read(b)
- if err != nil {
- fmt.Println("error:", err)
- return
- }
- // The slice should now contain random bytes instead of only zeroes.
- fmt.Println(bytes.Equal(b, make([]byte, c)))
-
- // Output:
- // false
+ // Note that no error handling is necessary, as Read always succeeds.
+ key := make([]byte, 32)
+ rand.Read(key)
}
"io"
"sync/atomic"
"time"
+ _ "unsafe"
)
// Reader is a global, shared instance of a cryptographically
// - On Windows, Reader uses the ProcessPrng API.
// - On js/wasm, Reader uses the Web Crypto API.
// - On wasip1/wasm, Reader uses random_get.
+//
+// All the platform APIs above are documented to never return an error
+// when used as they are in this package.
var Reader io.Reader
func init() {
return len(b), nil
}
-// Read is a helper function that calls Reader.Read using io.ReadFull.
-// On return, n == len(b) if and only if err == nil.
+// fatal is [runtime.fatal], pushed via linkname.
+//
+//go:linkname fatal
+func fatal(string)
+
+// Read fills b with cryptographically secure random bytes. It never returns an
+// error, and always fills b entirely.
+//
+// If [Reader] is set to a non-default value, Read calls [io.ReadFull] on
+// [Reader] and crashes the program irrecoverably if an error is returned.
func Read(b []byte) (n int, err error) {
- return io.ReadFull(Reader, b)
+ _, err = io.ReadFull(Reader, b)
+ if err != nil {
+ fatal("crypto/rand: failed to read random data (see https://go.dev/issue/66821): " + err.Error())
+ panic("unreachable") // To be sure.
+ }
+ return len(b), nil
}
// batched returns a function that calls f to populate a []byte by chunking it
)
// Prime returns a number of the given bit length that is prime with high probability.
-// Prime will return error for any error returned by [rand.Read] or if bits < 2.
+// Prime will return error for any error returned by rand.Read or if bits < 2.
func Prime(rand io.Reader, bits int) (*big.Int, error) {
if bits < 2 {
return nil, errors.New("crypto/rand: prime size must be at least 2-bit")
}
}
-// Int returns a uniform random value in [0, max). It panics if max <= 0.
+// Int returns a uniform random value in [0, max). It panics if max <= 0, and
+// returns an error if rand.Read returns one.
func Int(rand io.Reader, max *big.Int) (n *big.Int, err error) {
if max.Sign() <= 0 {
panic("crypto/rand: argument to Int is <= 0")
fatal(s)
}
+//go:linkname rand_fatal crypto/rand.fatal
+func rand_fatal(s string) {
+ fatal(s)
+}
+
// throw triggers a fatal error that dumps a stack trace and exits.
//
// throw should be used for runtime-internal fatal errors where Go itself,