package pringo

  1. Overview
  2. Docs

This library provides pseudo-random number generators (PRNGs) comparable to that of the Random module from OCaml's standard library, but with two extensions:

  • Generators are "splittable": they support a split operation that returns a new generator that is statistically independent from the current generator. Both generators can be used in parallel, and can be further splitted, without introducing statistical bias. This splitting operation is particularly useful to implement the lazy generation of pseudo-random infinite data structures such as functions or streams.
  • In addition to a stateful, imperative interface resembling that of the Random.State standard library module, another, purely functional interface is provided. In the functional interface, the current state of the PRNG appears as parameter but also as result of the number generation functions. This interface can be used directly within a state monad.

The stateful interface

module type STATE = sig ... end

The purely-functional, monadic interface

In this alternate interface, number-generating functions do not update the current state of the generator in-place. Instead, they return the updated generator as a second result. It is the programmer's responsibility to correctly thread the generators through the program, typically by using a state monad.

All operations of the STATE interface are provided except bytes (too imperative) and copy, reseed and remake (pointless).

module type PURE = sig ... end

The Splitmix implementation

module Splitmix : sig ... end

This is an implementation of the STATE and PURE interfaces based on the Splitmix design by Guy L. Steele Jr., Doug Lea, and Christine H. Flood.

For seeding, 64 bits of entropy is recommended. Seeds of 8 characters or less are used as a 64-bit integer. Longer seeds are hashed using Digest.string before being used.

Reseeding is recommended after 232 numbers have been generated.

The Chacha-20 implementation

module Chacha : sig ... end

This is an implementation of the STATE and PURE interfaces based on the Chacha 20 stream cipher by D. J. Bernstein.

For seeding, 128 bits of entropy is recommended. Seeds of up to 32 characters are used as keys to the Chacha 20 cipher. Characters beyond the first 32 are ignored.

Reseeding is recommended after 264 numbers have been generated.

The LXM implementation

module LXM : sig ... end

This is an implementation of the STATE and PURE interfaces based on the LXM design by Guy L. Steele Jr, and Sebastiano Vigna. We use the L64X128 variant from Fig. 1 of their OOPSLA 2021 paper.

For seeding, 128 bits of entropy is recommended. The last 32 bytes of the seed are used to initialize the PRNG state.

This PRNG has a large internal state (192 bits) and a period of 2192 - 264. Therefore, reseeding should not be necessary in practice.