std1.0.0-beta-7 SafeC docs

Source crypto/rng.h

View in the repository

// SafeC Standard Library — Cryptographic RNG
// A ChaCha20 keystream generator, seeded from the OS's random source
// (BCryptGenRandom on Windows, getentropy on macOS, getrandom on Linux),
// else rdrand (x86-64) or /dev/urandom, or from a caller-supplied 32-byte
// seed.
// Freestanding-safe with RngCtx::init_seed() or rdrand.
// Usage: struct RngCtx rng; rng.init(); rng.fill(buf, n);
#pragma once
#include <std/crypto/buf.h>

#define RNG_BLOCK_SIZE 64   // ChaCha20 output block (bytes)

namespace std {

struct RngCtx {
    unsigned int  state[16];  // ChaCha20 key + nonce + counter
    unsigned char buf[RNG_BLOCK_SIZE];
    unsigned long buf_pos;    // next byte to consume from buf

    // Initialise in place with automatic seeding (the OS's random source,
    // else rdrand on x86-64, else /dev/urandom). Returns 1; aborts with a
    // diagnostic if no entropy source is available (use init_seed() with
    // your own entropy source on such targets).
    int init();

    // Initialise in place with a user-provided 32-byte seed (deterministic;
    // useful for tests).
    void init_seed(const unsigned char seed[32]);

    // Fill `out[0..len-1]` with cryptographically strong random bytes.
    void fill([]unsigned char out);
    // internal: the (reference, length) core of fill()
    void fill_n_(&unsigned char out, unsigned long len);

    // Return a random 32-bit unsigned integer.
    unsigned int  rand32();

    // Return a random 64-bit unsigned integer.
    unsigned long long rand64();

    // Return a uniform random integer in [0, bound).
    unsigned long rand_range(unsigned long bound);
};

} // namespace std