provably-fair-rng
A provably fair RNG based on a stream cipher
Usage
var pfRng = // Key could come from a hash-chainvar key = Buffer// Nonce could be something public, here the bitcoin block hash #611707// Nonces are 24 bytes, hence we use the 24 low order bytesvar nonce = Buffer var rng = console // 8 Random bytesconsole // 8console // Random double. Consumes 7 bytesconsole // Random integer between [0, 1000]. Consumes 7 bytes for each iterationconsole // 8 + 7 + 7 = 22console // 3console // Return 3 integers in [0, 10)console // Permute a, b, c
API
const rng = pfRng(key, nonce)
Create a new RNG from a key
and a nonce
, which must be pfRng.KEYBYTES
and
pfRng.NONCEBYTES
long respectively. Uses chacha20
as the underlying primitive
Other options include:
const rng = pfRng.xchacha(key, nonce)
const rng = pfRng.salsa(key, nonce)
const rng = pfRng.xsalsa(key, nonce)
Each with associated constants on pfRng.*.KEYBYTES
and pfRng.*.NONCEBYTES
const bytes = rng.bytes
How many bytes have been read from the current instance
const trails = rng.trails
How many times was a read call made from the instance
const buf = rng(bytes)
Return a Buffer
of bytes
from the stream
const num = rng.double()
Return a random double in the interval [0, 1)
, which is unbiased, uniform and
equidistant. Consumes 7 bytes
const n = rng.uniform(max)
Read a random integer uniformly and unbiased in the interval [0, max)
.
Consumes 7 bytes for each trail, but may do multiple trails in a single call
due to rejection sampling
const xs = rng.sample(n, p)
Pick n
unique, random integers from the interval [0, p)
which can be used as
indexes into another table. Uses rejection sampling multiple times so the above
note from rng.uniform
applies
const arr = rng.shuffle(arr)
Unbiased shuffle (Fisher-Yates/Knuth) of arr
. Note that this mutates arr
and
returns it (for convenience). Uses rejection sampling multiple times so the
above note from rng.uniform
applies
const idx = rng.weighted(weights)
Samples an index from weights
, which are decimal proportions.
Samples a single double from rng.double
above
const idx = rng.weightedIntegers(weights)
Samples an index from weights
, which are integer proportions.
Uses rejection sampling once so the above note from rng.uniform
applies
Install
npm install provably-fair-rng