Secure random bytes, drawn without bias.
You supply the source; it fills the buffer. No generator, no state, and no quiet fallback to a seeded one — when there are no bytes to be had, the call stops with Unavailable.
This tile was drawn from the bytes this page took, through below — by this library, compiled to wasm. Press it and the net breaks.
One method, fills the buffer. Who fills it is the caller's business.
The crate is one contract: give me bytes. @system.source is the platform's — crypto.getRandomValues on JavaScript, WASI's random_get on wasm, the runtime on native.
Replay hands back the bytes it was given, in order, until it runs out — that is how the test vectors are replayed. Your own implementation can be a device, a service, a file. Three kinds of source, one method.
There is no fallback. That is not a promise in the prose, it is in the type: the call raises, the signature says so, and the caller cannot miss it.
Three lines. No init, no global state, no generator to construct first.
moon run src/examples/tour walks the whole API once, so you can watch it ask for bytes.
Rejection, not modulo. Modulo favours the small values; not doing that is why this function exists.
below(bound) reads its bound as a big-endian number: draw exactly as many bytes as bound−1 needs, clear the unused high bits of the first, and draw again while the value is at or above bound. Every value is equally likely.
scalar(order) gives you something in [1, order) — a private key, a nonce. Draw as wide as order, draw again while the value is zero or not below order: FIPS 186-5 A.2.2, the same draw Go's ECDSA makes. A P-521 scalar is 66 bytes with the top bits clear, which is why this cannot be "ask for 32 bytes".
Both are checked against Go: fixed byte streams go into crypto/rand.Int and ecdsa.GenerateKey, and the tests replay those same bytes and expect the same values, every byte used.
below(1 << k) never redraws — the mask already fits. Only a bound that is not a power of two pays for the loop.
Every public item, package by package. Nothing left out.
It is not a generator, and does not pretend to be one.
No seed, no stream, no "same seed gives the same numbers". For a reproducible stream, use moonrand. Keeping these apart is what stops either from deciding for you.
The root package touches no platform. Linking system links the platform's one call. A wasm host without WASI uses the root package and a source of its own.
One call, one answer; whether to retry is the caller's policy. It moves entropy, it does not stretch it — 32 bytes do not become a 64-byte secret.
It takes bytes from a source and hands them over. The buffer is yours to wipe or not; this crate does not allocate a cache or keep a copy.
The rejection loop leaves a timing trace. Constant time is the caller's problem: bound the retries, or sample differently.
@system.source reports what the platform says. It does not judge whether the platform is compromised. That trust sits in the OS, not here.