AES-CTR Random Pool (also known as randp
) is a C library, designed for modern Linux systems, with functions that give pseudorandom numbers. It was inspired by arc4random, and it mimics its functionality.
The API is designed to be compatible with the arc4random family of functions.
| Description | arc4random family | randp family |
|---|---|---|
| Fill a buffer with n random bytes | void arc4random_buf(void* buf, size_t n) |
void randp_bytes(void* buf, size_t n) |
| Return a uniform random unsigned integer | uint32_t arc4random() |
uint8_t randp_u8()uint16_t randp_u16()uint32_t randp_u32()uint64_t randp_u64() |
| Return a uniform random unsigned integer less than upper_bound | uint32_t arc4random_uniform(uint32_t upper_bound) |
uint32_t randp_lt_u32(uint32_t upper_bound) |
The randp structure stores random bytes in a pool that can be retrieved later by the functions listed above.
The static thread_local randp structure is mmapd with flags MAP_PRIVATE | MAP_ANONYMOUS and then madvised with MADV_DONTDUMP and MADV_WIPEONFORK. Its size is at most one page (4096 B), and it's not allocated until immediately before first use. See src/allocate.h for details.
Description of mmap flags
MAP_PRIVATE
Create a private copy-on-write mapping. Updates to the
mapping are not visible to other processes mapping the
same file, and are not carried through to the underlying
file. It is unspecified whether changes made to the file
after the mmap() call are visible in the mapped region.
MAP_ANONYMOUS
The mapping is not backed by any file; its contents are
initialized to zero. The fd argument is ignored; however,
some implementations require fd to be -1 if MAP_ANONYMOUS
(or MAP_ANON) is specified, and portable applications
should ensure this. The offset argument should be zero.
Support for MAP_ANONYMOUS in conjunction with MAP_SHARED
was added in Linux 2.4.
Description of madvise flags
MADV_DONTDUMP (since Linux 3.4)
Exclude from a core dump those pages in the range
specified by addr and length. This is useful in
applications that have large areas of memory that are
known not to be useful in a core dump. The effect of
MADV_DONTDUMP takes precedence over the bit mask that is
set via the /proc/pid/coredump_filter file (see core(5)).
MADV_WIPEONFORK (since Linux 4.14)
Present the child process with zero-filled memory in this
range after a fork(2). This is useful in forking servers
in order to ensure that sensitive per-process data (for
example, PRNG seeds, cryptographic secrets, and so on) is
not handed to child processes.
The MADV_WIPEONFORK operation can be applied only to
private anonymous pages (see mmap(2)).
Within the child created by fork(2), the MADV_WIPEONFORK
setting remains in place on the specified address range.
This setting is cleared during execve(2).
Upon first use, the pseudorandom number generator (PRNG) is initialized/seeded by getentropy. See src/aes_ctr_128_prng.h for details. Then the pool is filled with random bytes generated by the PRNG.
As bytes are retrieved from the pool, they are zeroized. After a certain number of bytes has been read, the PRNG is reseeded, and the pool is filled again with random bytes. See src/randp.c for details.
- A processor with AES instructions
- Linux 4.14 or newer
MADV_WIPEONFORKwas added in Linux 4.14
- GCC 14 or newer
- C23 support was added in GCC 14. randp uses the
thread_localkeyword. - clang and clang++ are not supported
- C23 support was added in GCC 14. randp uses the
- Glibc 2.25 or newer
getentropywas added in glibc 2.25. 1 2
Run make randp-single.h to generate a header-only file of randp.
Is randp a cryptographically secure pseudorandom number generator (CSPRNG)?
No claims are made that randp is a CSPRNG, but the random numbers it produces are practically unpredictable (i.e. computationally infeasible to predict). Of the following critera of a CSPRNG, it hasn't satisfied numbers 6, 7, or 8.
To prove that a random number generator (RNG) is cryptographically secure, it must meet several stringent criteria and undergo rigorous testing. Here's an overview of the key aspects involved in proving cryptographic security for an RNG:
Unpredictability
- Next-bit unpredictability: Given the first k bits of a random sequence, it should be computationally infeasible to predict the k+1-th bit with any significant advantage over random guessing (which would be 50% for a single bit).
- Forward and backward security: Even if part of the state or some outputs are compromised, the RNG should still be secure. This means that past outputs can't be reconstructed (backward security) and future outputs can't be predicted (forward security).
Statistical Randomness Tests
- The output of the RNG must pass a battery of statistical tests that measure the randomness of the sequence. Common tests include the NIST Statistical Test Suite, Diehard tests, and TestU01.
- While these tests don't prove cryptographic security, they help ensure the output appears random, which is a necessary condition.
Entropy Source
- A cryptographically secure RNG must be based on a source of true entropy. This could be physical processes (like thermal noise or radioactive decay) or carefully designed algorithms that maintain high entropy.
- The entropy must be unpredictable and cannot be influenced or predicted by an attacker.
Resilience to Attacks
- Mathematical Proofs: The design of the RNG should ideally be accompanied by mathematical proofs demonstrating that it is resistant to known cryptographic attacks, such as linear or differential cryptanalysis.
- Seed Security: The seed used to initialize the RNG must be secure. If the seed is predictable, the entire RNG is compromised.
Cryptographic Algorithms
- The RNG should utilize cryptographic primitives like block ciphers (e.g., AES), cryptographic hash functions (e.g., SHA-2), or stream ciphers that are proven secure under standard assumptions (e.g., security of AES against known attacks).
- The design should avoid known weaknesses such as bias in output or correlations between bits.
Security Proofs
- A formal security proof can provide strong evidence of cryptographic security. This proof would typically show that breaking the RNG's security is as hard as solving a known difficult problem (e.g., factoring large integers or solving discrete logarithms), which is assumed to be infeasible within polynomial time for large instances.
Independent Verification
- The RNG should undergo independent security analysis and audits by third parties. This is to ensure that there are no hidden flaws or vulnerabilities that were overlooked by the original designers.
Compliance with Standards
- The RNG should comply with established cryptographic standards like those provided by NIST (e.g., NIST SP 800-90A/B/C) or other recognized bodies. These standards provide guidelines for the design, testing, and validation of cryptographically secure RNGs.
Summary
Proving that an RNG is cryptographically secure involves demonstrating that it is unpredictable, passes statistical tests, has a high-entropy source, is resilient to attacks, and follows cryptographic principles backed by security proofs. It should also undergo independent verification and comply with relevant standards.
— ChatGPT (GPT-4o). How Can a Random Number Generator Be Proven to Be Cryptographically Secure?
OpenAI, 2024-08-28.
The Open Software License 3.0 (OSL-3.0)