Every cryptographic key starts as random bits. If the random number generator is weak or predictable, every key it produces is suspect, however strong the algorithm. NIST covers random bit generation in three documents:
- SP 800-90A Rev. 1 (June 2015): deterministic random bit generators (DRBGs)
- SP 800-90B (January 2018): entropy sources
- SP 800-90C (final, September 2025): how DRBGs and entropy sources are put together into complete random bit generators (RBGs)
This walkthrough covers each document and why randomness matters for post-quantum algorithms.
SP 800-90A: Deterministic Random Bit Generators
SP 800-90A Rev. 1 specifies three DRBG mechanisms:
- Hash_DRBG, built from an approved hash function
- HMAC_DRBG, built from HMAC
- CTR_DRBG, built from a block cipher such as AES in counter mode
A DRBG is deterministic: its output is determined by its internal state, which is seeded from an entropy source. Reseeding refreshes that state with new entropy. Prediction resistance means that an attacker who learns the current state still cannot predict output produced after the next reseed with fresh entropy.
SP 800-90B: Entropy Sources
SP 800-90B covers the design and validation of entropy sources. Its model has three parts:
- Noise source: the physical or non-physical process that produces unpredictable values.
- Health tests: tests that detect when the noise source fails or degrades.
- Conditioning (optional): processing that reduces bias in the raw output.
Validation centres on estimating min-entropy, the worst-case unpredictability of the raw samples, using either an IID track for independent, identically distributed samples or a non-IID track. SP 800-90B requires start-up and continuous health tests and specifies two approved continuous tests: the Repetition Count Test, which catches a source that gets stuck, and the Adaptive Proportion Test, which catches a value that becomes too frequent. NIST publishes an open-source tool for the entropy estimates.
SP 800-90C: RBG Constructions
SP 800-90C, finalised in September 2025, specifies four classes of RBG built from SP 800-90A DRBGs and SP 800-90B entropy sources:
- RBG1: a DRBG instantiated from another RBG. It cannot be reseeded, so it never provides prediction resistance.
- RBG2: a DRBG with access to a validated entropy source. It can provide prediction resistance when reseeding is supported; RBG2(P) uses a physical entropy source and RBG2(NP) a non-physical one.
- RBG3: a construction that provides prediction resistance and full-entropy output, with variants RBG3(XOR) and RBG3(RS).
- RBGC: chains of RBG constructions, forming a tree of DRBGs with a root that is seeded from an RBG2, an RBG3 or a full-entropy source.
RBG1, RBG2 and RBGC outputs have a security strength set by the DRBG instantiation; only RBG3 outputs have full entropy.
Why Randomness Matters for Post-Quantum Algorithms
FIPS 203, 204 and 205 all require randomness from an approved RBG for key generation, with a security strength at least that of the parameter set:
- ML-KEM key generation uses two 32-byte random seeds, and encapsulation uses 32 more random bytes.
- ML-DSA key generation uses a 32-byte seed. Its default "hedged" signing mixes 32 fresh random bytes into each signature, and FIPS 204 also allows a deterministic variant.
- SLH-DSA key generation draws three n-byte seeds, 48 bytes at the 128-bit level and 96 bytes at the 256-bit level, and the whole key follows from them.
Predictable seeds mean predictable keys, so a weak generator undermines the post-quantum algorithms as completely as it undermines RSA or ECDH.
Operating System Generators
Most applications should not build their own RBG. They should use the operating system's:
- Linux: the getrandom(2) system call, or /dev/urandom. Since Linux 5.18 the kernel mixes its entropy inputs into one pool and produces output with a ChaCha20-based generator. After the pool is initialised, /dev/random and /dev/urandom return output of the same quality.
- Windows: the system random number generator, through BCryptGenRandom or ProcessPrng.
- macOS: getentropy(2) or SecRandomCopyBytes.
An operating-system generator is not automatically an SP 800-90 RBG. A validated cryptographic module documents which of its RBGs and entropy sources are validated.
How QNSQY Gets Random Bits
QNSQY's standard build takes its random bits from the operating system's generator through the Rust getrandom library: getrandom(2) on Linux and the system generator on Windows. If the operating system cannot supply randomness, the operation stops instead of falling back to a weaker source. The standard build does not run an SP 800-90 DRBG of its own or use a hardware security module as its random bit generator, and QNSQY is not FIPS 140-3 validated.
Nonces for file encryption are not drawn at random per chunk. QNSQY derives each chunk's nonce from fresh per-file key material and the chunk number, so a nonce is never repeated under the same key.
Common Implementation Mistakes
- Forking after seeding: a user-space generator copied into a child process produces the same output as its parent until it is reseeded.
- Using a non-cryptographic generator, such as the C library's rand(), for keys or nonces.
- Ignoring errors from the system generator and continuing with uninitialised memory.
- Reusing a nonce with the same key in AES-GCM, which breaks confidentiality and authenticity for those messages.
- Shipping test seeds: deterministic test vectors are for testing only.
Frequently Asked Questions
Is SP 800-90C final?
Yes. NIST published the final SP 800-90C, "Recommendation for Random Bit Generator (RBG) Constructions", in September 2025. It specifies the RBG1, RBG2, RBG3 and RBGC constructions.
Is /dev/random better than /dev/urandom?
On current Linux they return output of the same quality once the kernel's pool is initialised; /dev/random only blocks until then. Use getrandom(2), which also waits for initialisation.
How much randomness do the post-quantum algorithms need?
Not much, but it must be good. ML-KEM key generation uses 64 random bytes, ML-DSA's hedged signing uses 32 random bytes per signature, and SLH-DSA key generation uses 48 to 96 bytes depending on the security level.
Does my hardware RNG count as SP 800-90B compliant?
Only if its entropy source has been validated under SP 800-90B. Claims of "true randomness" are not the same as validation.
Should I build my own RBG?
Usually not. Use the operating system's generator or a validated cryptographic module, and leave RBG design and validation to module vendors.
Sources
- NIST SP 800-90A Rev. 1, Recommendation for Random Number Generation Using Deterministic Random Bit Generators, NIST, June 2015
- NIST SP 800-90B, Recommendation for the Entropy Sources Used for Random Bit Generation, NIST, January 2018
- NIST SP 800-90C, Recommendation for Random Bit Generator (RBG) Constructions, NIST, September 2025
- FIPS 203, FIPS 204 and FIPS 205, NIST, August 2024
- Linux getrandom(2) manual page
Related Articles
- What is post-quantum cryptography
- FIPS 203 walkthrough
- FIPS 204 walkthrough
- FIPS 205 walkthrough
- NIST SP 800-57 on key management
Protect Your Data Before Q-Day Arrives
QNSQY's NIST-standardized post-quantum encryption protects files against both current and quantum-era threats.