# Custom RNG

On Unix-based systems and on Windows, Sodium uses the facilities provided by the operating system when generating random numbers is required.

Other operating systems do not support `/dev/urandom` or it might not be suitable for cryptographic applications. These systems might provide a different way to gather random numbers.

And, on embedded operating systems, even if the system may not have such a facility, a hardware-based random number generator might be available.

In addition, reproducible results instead of unpredictable ones may be required in a testing environment.

For all these scenarios, Sodium provides a way to replace the default implementations generating random numbers.

## Usage

```c
typedef struct randombytes_implementation {
    const char *(*implementation_name)(void);
    uint32_t    (*random)(void);
    void        (*stir)(void);
    uint32_t    (*uniform)(const uint32_t upper_bound);
    void        (*buf)(void * const buf, const size_t size);
    int         (*close)(void);
} randombytes_implementation;

int randombytes_set_implementation(randombytes_implementation *impl);
```

The `randombytes_set_implementation()` function defines the set of functions required by the `randombytes_*` interface.

**This function should only be called once, before `sodium_init()`.**

## Example

Sodium ships with a sample alternative `randombytes` implementation based on the ChaCha20 stream cipher in `randombytes_internal_random.c` file.

This implementation only requires access to `/dev/urandom` or `/dev/random` (or to `RtlGenRandom()` on Windows) once, during `sodium_init()`.

It might be used instead of the default implementations in order to avoid system calls when random numbers are required.

It might also be used if a non-blocking random device is not available or not safe, but blocking would only be acceptable at initialization time.

It can be enabled with:

```c
randombytes_set_implementation(&randombytes_internal_implementation);
```

Before calling `sodium_init()`.

It does fast key erasure. However, it is not thread-safe (locks must be added if this is a requirement), and was designed to be just a boilerplate for writing implementations for embedded operating systems. `randombytes_stir()` also has to be called to rekey the generator after fork()ing.

If you are using Windows or a modern Unix-based system, you should stick to the default implementations.

## Notes

Internally, all the functions requiring random numbers use the `randombytes_*` interface.

Replacing the default implementations will affect explicit calls to `randombytes_*` functions as well as functions generating keys and nonces.

Since version 1.0.3, custom RNGs don’t need to provide `randombytes_stir()` nor `randombytes_close()` if they are not required (for example if the data comes from a system call). These can be `NULL` pointers instead. `randombytes_uniform()` doesn’t have to be defined either: a default implementation will be used if a `NULL` pointer is given.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://libsodium.gitbook.io/doc/advanced/custom_rng.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
