librandombytes: Intro

librandombytes

librandombytes provides a simple API for applications generating fresh randomness: include `<randombytes.h>`, call `randombytes(x,xbytes)` whenever desired to generate fresh random bytes `x[0]`, `x[1]`, ..., `x[xbytes-1]`, and link with `-lrandombytes`.

Random bytes are often used directly in applications. Random bytes are also the foundation of more complicated random objects, such as random integers in a limited interval, random floating-point numbers from a (nearly) normal distribution, and random keys used in public-key cryptosystems. librandombytes is dedicated to obtaining fresh random bytes in the first place, and leaves it to higher-level libraries to convert those bytes into other types of random objects.

librandombytes aims for the following stringent randomness goal: no feasible computation will ever be able to tell the difference between the output bytes and true randomness (independent uniformly distributed random bytes). This makes the `randombytes()` output suitable for use in applications ranging from simulations to cryptography.

Most alternative sources of randomness (such as `rand()` and `random()` in C, and `mt19937_64` in C++) consider detectable deviations from true randomness to be acceptable as long as most applications do not notice the deviations. These sources are not permitted inside librandombytes; the `randombytes()` caller is entitled to expect that the output comes from sources that are designed for the right goal.

Internally, librandombytes is an abstraction layer for a choice of two libraries, where each library provides the same `randombytes` interface but the libraries choose two different sources of randomness:

- `librandombytes-kernel` reads random bytes provided by the OS kernel via mechanisms such as `getrandom()`. These mechanisms are typically advertised as providing RNG security features that are harder to provide in user space, such as hypervisor integration.

- `librandombytes-openssl` uses OpenSSL's `RAND_bytes` to generate random bytes. This mechanism is typically advertised as providing speed that is difficult to achieve without a per-process RNG.

The idea is that the OS can install `librandombytes-kernel` by default, but the sysadmin can install `librandombytes-openssl` to transparently switch all of the `randombytes()` applications to `RAND_bytes` (for example, via Debian's `/etc/alternatives` mechanism) if profiling shows that this switch is important for overall system performance.

Making this choice centrally means that applications are free to simply call `randombytes()`

- without worrying about evaluating performance,

- without worrying about how to balance performance concerns with competing concerns, and

- without worrying that these performance evaluations will be rendered obsolete by speed improvements: for example, by ongoing work to accelerate `getrandom()`, or by the increasing deployment of fast-key-erasure RNGs.

Another virtue of having a `randombytes()` abstraction layer is that test frameworks can substitute a deterministic seeded `randombytes()` providing known pseudorandom bytes for reproducible tests. Of course, the `randombytes()` provided by these test frameworks must be kept separate from the fresh `randombytes()` used for deployment.

Version: This is version 2023.09.04 of the "Intro" web page.