References ========== Sources by generator family ---------------------------- Each generator family in simdrng is implemented from a single canonical source (plus, for ChaCha, an independent oracle used only to cross-check the tests). This is the map from family to paper: **Xoshiro256++ & SplitMix64** - D. Blackman and S. Vigna, *Scrambled Linear Pseudorandom Number Generators*, ACM Transactions on Mathematical Software (2021). https://vigna.di.unimi.it/papers.php#BlVSLPNG — the design and analysis of the scrambled-linear family and the ``++`` scrambler. - S. Vigna, *xoshiro / xoroshiro generators and the PRNG shootout*. https://prng.di.unimi.it/ — the shootout, the SplitMix64 **seeding** recommendation, and the ``uniform()`` conversion rationale. **ChaCha 8 / 12 / 20** - D. J. Bernstein, *ChaCha, a variant of Salsa20*. https://cr.yp.to/chacha.html — the cipher core simdrng uses as a CSPRNG. - `Monocypher `_ — an independent ChaCha20 implementation used as a test oracle (cross-check only; not a dependency). **Philox (2×32, 4×32, 2×64, 4×64)** - J. K. Salmon, M. A. Moraes, R. O. Dror, D. E. Shaw, *Parallel Random Numbers: As Easy as 1, 2, 3* (Philox), SC '11 — the counter-based design behind the stateless, trivially parallel Philox family. The annotated period, scrambling, seeding and conversion details below are the authoritative statement of each fact; the per-family **Guides** link here rather than restating the numbers. .. _choosing-a-generator: Choosing a generator -------------------- The all-purpose-versus-special-purpose framing below is Vigna's (https://prng.di.unimi.it/), extended here to the two counter-based families he does not cover: - **xoshiro256++ is the all-purpose default.** Vigna's recommended general 64-bit generator: large state, passes all known statistical tests, very fast — but *not* cryptographically secure. Reach for it unless you have a specific reason not to. - **Seed with SplitMix64.** Vigna's explicit recommendation (quoted under :ref:`seeding`); SplitMix is a *seeding helper only*, not a general-purpose engine. - **Philox** (Salmon et al.) when you need **stateless, seekable, trivially-parallel** streams — GPU-style kernels and embarrassingly parallel Monte Carlo, where each work item derives its own sub-stream from ``(seed, counter)`` with no coordination. - **ChaCha** (Bernstein) when you want **cryptographic-grade** statistical quality or a CSPRNG-style stream; pick the round count (8 / 12 / 20) to trade margin against speed. .. _gen-properties: Generator properties -------------------- .. list-table:: :header-rows: 1 :widths: 26 18 56 * - Generator - Period - Notes * - xoshiro256++ - 2\ :sup:`256` − 1 - All-purpose 64-bit generator; ``jump()`` / ``long_jump()`` carve out 2\ :sup:`128` / 2\ :sup:`192`-spaced non-overlapping subsequences for parallel streams. * - SplitMix64 - 2\ :sup:`64` - Seeding only. Per Vigna: *"We suggest to use SplitMix64 to initialize the state of our generators starting from a 64-bit seed."* simdrng uses it to expand a scalar seed into the xoshiro state. * - ChaCha (8 / 12 / 20) - 2\ :sup:`64` per (key, nonce) - Counter-based stream cipher used as a CSPRNG; the 64-bit block counter sets the period within a (key, nonce) pair. * - Philox (2×32, 4×32, 2×64, 4×64) - 2\ :sup:`W·N` - Counter-based; stateless and trivially parallel — distinct counters give independent streams with no coordination. .. _scrambling: Scrambling and equidistribution -------------------------------- xoshiro256++ is a **scrambled-linear** generator: a fast linear engine over GF(2) (the ``xoshiro`` state transition) supplies excellent equidistribution and a known period, while a non-linear *scrambler* applied to the output hides the linear artifacts that batteries like BigCrush detect. The ``++`` scrambler — ``rotl(s0 + s3, 23) + s0`` — is a sum-and-rotate that, per Blackman & Vigna, makes the output pass the full test suites while keeping the per-call cost to a couple of instructions. The underlying linear engine is **equidistributed**, i.e. over a full period every output value appears the same number of times (minus the all-zero state), which is what gives the family its strong low-dimensional uniformity. .. _seeding: Seeding ------- Vigna recommends never seeding a scrambled-linear generator directly from a small integer, because a low-entropy state propagates slowly through the linear map. simdrng follows the recommendation from https://prng.di.unimi.it/ and expands every 64-bit seed through **SplitMix64** before filling engine state: *"We suggest to use a SplitMix64 generator … to fill the state of our generators starting from a 64-bit seed, as research has shown that initialization must be performed with a generator radically different in nature from the one initialized."* This is why ``0`` and ``1`` are perfectly good seeds in simdrng. The same SplitMix64 expansion derives the Philox key from its seed. .. _uniform-doubles: Uniform doubles in ``[0, 1)`` ----------------------------- ``uniform()`` converts a 64-bit output ``x`` to a double with .. code-block:: cpp static_cast(x >> 11) * 0x1.0p-53; // (x >> 11) · 2⁻⁵³ following the rationale on https://prng.di.unimi.it/#remarks: *"This conversion guarantees that all dyadic rationals of the form k / 2⁻⁵³ will be equally likely."* The right shift takes the top 53 bits, because the conversion *"prefers the high bits of x (usually, a good idea)"* — the high bits of xoshiro-class generators have the best statistical quality. .. _reference-impls: Reference implementations ------------------------- The test suite validates simdrng against the authors' own reference code: - ``splitmix64.c`` and ``xoshiro256plusplus.c`` are downloaded from https://prng.di.unimi.it/ and are released to the **public domain (CC0)** by David Blackman and Sebastiano Vigna. - ChaCha20 is cross-checked against `Monocypher `_. These files are used only by the tests/benchmarks as a ground-truth oracle and are not part of the installed library.