# randomBytes _(no submodules)_ ## Purpose Produce cryptographically-secure random bytes. Every `@suaveplan/crypto-*` package routes entropy through this single helper so there is exactly one callsite of `globalThis.crypto.getRandomValues` to audit, and callers that need deterministic entropy in tests (or a hardware-RNG adapter in production) can swap it with dependency injection rather than monkey-patching `globalThis`. ## Features - Wraps `globalThis.crypto.getRandomValues` (Web Crypto) — works in Node 20+, Bun, browsers, Deno, Cloudflare Workers. - Dependency-injectable `ByteSource` for tests and hardware RNG adapters. - Explicit `n` range check; throws stable `CRYPTO.UTILS.RNG.INVALID_LENGTH` on bad input. - Returns a fresh `Uint8Array` every call. ## Usage: Basic Example ```ts import { randomBytes } from "@suaveplan/crypto-utils/random"; const nonce = randomBytes(12); ``` ## Usage: Advanced Example ```ts import { randomBytes, type ByteSource } from "@suaveplan/crypto-utils/random"; // Deterministic source for tests — feeds a known sequence. function fixedSequence(bytes: Uint8Array): ByteSource { let pos = 0; return (n) => { const out = bytes.slice(pos, pos + n); pos += n; return out; }; } function generateKey(opts?: { byteSource?: ByteSource }): Uint8Array { return randomBytes(32, opts); } const testKey = generateKey({ byteSource: fixedSequence(new Uint8Array(32).fill(0xaa)), }); ``` ## API Reference - `randomBytes(n: number, options?: { byteSource?: ByteSource }): Uint8Array` — returns `n` random bytes. Throws `CryptoUtilsError(CRYPTO.UTILS.RNG.INVALID_LENGTH)` if `n` is not a non-negative integer. - `defaultByteSource: ByteSource` — the `getRandomValues`-backed source. Exported for adapters that want to delegate to it. - `type ByteSource = (n: number) => Uint8Array` — the injection surface. ## Implementation Notes `globalThis.crypto` is a WHATWG Web Crypto `Crypto` instance on every supported runtime. In Node we rely on the polyfill injected at test-setup time (`node:crypto` `webcrypto`). The test-only `byteSource` option is deliberately on the call, not a module-level setter, so there is never a case where a test leaks a deterministic source into production code. The length check rejects `NaN`, non-integers, and negatives — all would previously have been forwarded to `getRandomValues`, which throws a less-precise `RangeError`.