Module crypto/random
Cryptographically secure random number generation. Uses OS entropy sources (getrandom on Linux, arc4random_buf on macOS, BCryptGenRandom on Windows, getentropy on WASI).
Example
{ random_u64, uuid_v4 } :: import("std/crypto/random");
id := uuid_v4(exn); // "550e8400-e29b-41d4-a716-446655440000"
Every function here takes an exn : Exception: reading OS entropy can
fail, and a CSPRNG that silently returns a weak value on failure is
worse than one that stops. std/rand is the unseeded-quality
counterpart for simulations and shuffles — it is faster, needs no
exn, and is NOT for keys, tokens or nonces.
Stability
unstable — the correctness work is done (rejection sampling in
random_range, a 53-bit random_f64, and a getrandom loop that no
longer accepts a short read: plans/archive/STD_API_AUDIT.md C5), and
tests/crypto/random.test.yo covers the bounds and the format. What is
not settled is how failure is reported. This module THROWS on an
entropy failure and PANICS on an empty random_range — two failure
modes in one call — while std/rand's rand_u32 / rand_range take
no exn at all, so the same question is answered two ways in std.
uuid_v4 also hands back a String rather than a Uuid type, so a
caller that needs the bytes back has to re-parse its own output; std
has no Uuid. Freezing needs both calls made.
Types
Errors that can occur during cryptographic random operations.
Variants
| Variant | Fields | Description |
|---|---|---|
Unavailable | Platform does not support secure random generation. | |
Other | msg: String | Other platform-specific error. |
Trait Implementations
impl(generic(T : Type), where(T <: ToString), T : (ToString))
impl(generic(T : Type), where(T <: ToString), T : (ToString), Format)
format : fn(self : Self, spec : str) -> StringRender self under spec. An unrecognised spec degrades to the plain
to_string() rendering rather than failing.
Parameters
| Name | Type | Notes |
|---|---|---|
self | Self | |
spec | str |
Returns: String
Methods
to_string : (CryptoError) fn(self : CryptoError) -> Stringsource : (CryptoError) fn(self : CryptoError) -> Option(dyn( + ToString))The error that caused this one, or .None at the root of the chain.
Rust's Error::source. Defaulted to .None, so an error with nothing
underneath it implements the trait by saying only what it is; a wrapper
overrides it to hand back what it wrapped. Walking the chain to the root
cause is not expressible yet — the returned Dyn loses the Error
trait on an erased receiver, so a caller can print one link but cannot
follow it (#521,
issues/self-trait-in-a-return-type-loses-the-trait-on-an-erased-receiver.md).
Parameters
| Name | Type | Notes |
|---|---|---|
self | CryptoError |
Functions
Fill buf with cryptographically secure random bytes from the OS —
Rust's getrandom crate, or OsRng.
The whole slice is filled or the call throws: on Linux the getrandom
syscall is looped until buf.len bytes have arrived (it may return
short above 256 bytes) and EINTR is retried, and on WASI the request
is chunked to the 256-byte random_get limit. macOS uses
arc4random_buf, Windows BCryptGenRandom.
Throws CryptoError.Unavailable when the platform entropy source
refuses. A short fill is never reported as success — the earlier
single-shot getrandom left the tail of the buffer zeroed, which is
predictable material from an apparently successful call.
This blocks only for as long as the OS needs; it is not async, so filling a very large buffer on the event-loop thread stalls it.
Parameters
| Name | Type | Notes |
|---|---|---|
buf | RawSlice(u8) | |
exn | Exception |
Returns: unit
A uniform random u32 — four OS-entropy bytes, assembled
little-endian.
Parameters
| Name | Type | Notes |
|---|---|---|
exn | Exception |
Returns: u32
A uniform random u64.
Two random_u32 draws, so two trips to the OS entropy source: prefer
one random_bytes over a buffer when you need many values.
Parameters
| Name | Type | Notes |
|---|---|---|
exn | Exception |
Returns: u64
A uniform random f64 in the half-open range [0.0, 1.0) — Rust's
Rng::random::<f64>().
Built from the top 53 bits of a u64 draw, the double mantissa width,
so every result is exactly representable and 1.0 is unreachable.
Parameters
| Name | Type | Notes |
|---|---|---|
exn | Exception |
Returns: f64
A uniform random integer in the half-open range r — write it with
..: random_range(i64(10) .. i64(20), exn).
The bound is a Range(i64) rather than two i64 parameters so the
half-open end is visible AT THE CALL SITE, and so this reads the same
as Rng.range in std/rand.
PANICS on an empty range (r.end <= r.start), like Rng.range: a
sampler must return a value FROM the range, and an empty range has
none. It used to return r.start, which invented a value that was
never in the range. (BTreeMap.range may yield an empty ITERATOR for
an inverted window because "no elements" is a real answer there; "no
number" is not.)
Uniform by REJECTION SAMPLING, so the number of entropy draws is not
fixed — a draw above the largest multiple of the span is discarded and
redrawn, with a retry probability below 1/2 even in the worst case.
Plain draw % span would over-weight the low residues whenever the
span does not divide 2^64, which is a real bias in a module advertising
cryptographic security (plans/archive/STD_API_AUDIT.md C5).
Parameters
| Name | Type | Notes |
|---|---|---|
r | Range(i64) | |
exn | Exception |
Returns: i64
A random UUID v4 as the 36-character hyphenated lowercase string
"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx" — RFC 4122 §4.4.
122 bits come from random_bytes; the version nibble (4) and the two
variant bits are set as the RFC requires, so two of the 128 bits are
fixed. Returns a String, not a Uuid value — std has no UUID type —
so a caller that needs the bytes must decode the hex again.
Parameters
| Name | Type | Notes |
|---|---|---|
exn | Exception |
Returns: String