Description
Edit by dhardy: adding a tracker for the planned tasks:
- Replace
SmallRng
algorithm (see Requirements for a small fast RNG dhardy/rand#60 and Shootout: small, fast PRNGs dhardy/rand#52) - Deprecate
XorshiftRng
(required: that the RNG is available in another crate) - Move ISAAC* to new crate
- Publish PCG RNGs somewhere (
rand_rngs
,rand_pcg
or something) - Publish SFC generators somewhere
- Review xoshiro crate by @vks
- Review state of other published RNGs (see linked comment) and fix up if useful
- Document available RNGs (internal and external crates)
Also: we should consider whether we want to rename PRNGs when moving or adding them.
As decided in dhardy#58.
The idea is to only keep the StdRng
and SmallRng
wrappers in Rand, and to not expose PRNG algorithms directly.
The field of PRNG algorithms is not static, it seems like a good idea to cut Rand partly loose from the developements to improve our backward-compatability and usability story. Advantages (from the original issue)
rand
provide easy to reason generator(s) to satisfy the bulk of the usersrand
provides low-friction upgrades and keeps the optimal-ish algorithms readily availablerand
will not accumulate and/or deprecate specific algorithms throughout time- Specific
rand
Rng names won't bleed out to the world, like in forum posts, stackoverflow, etc..
Instead we want to provide an official companion crate, rand_rngs
, with a couple of blessed implementations.
Whether Rand should depend on rand_rngs
or copy the two algorithms used by StdRng
and SmallRng
is not fully decided. It might reduce code size if a crate depends on both StdRng
and its algorithm (currently Hc128Rng
) directly, but that seems rare and not worth much. It has the disadvantage that both implementations should remain in sync. Maybe the CI can check this?
If Rand depends on rand_rngs
, it would restrict rand_rngs
to only depend on rand_core
. But that is what rand_core
is for. I am for having Rand depend on rand_rngs
.
rand_rngs
rand_rngs
should provide a good selection of PRNGs.
Including multiple PRNGs in one crate has the advantage of having a single place to provide guidance, as it helps comparing different algorithms with each other. Also it gives one place to offer consistent benchmarks, to run PRNG test suites, to keep up a common quality level, and possibly to develop functionality that is useful for more than one PRNG (e.g. jumping).
Which PRNGs to include has been the topic of endless discussions. A few are basically decided. I fully expect the number of PRNGs to grow over time. But we also should be careful not to expose too many, as there are hundreds. Every PRNG should have one thing that gives it a clear advantage over others, otherwise it is not worth the inclusion.
Normal PRNGs
dhardy#60 explored normal PRNGs. The following 5 I feel comfortable about for an initial version of rand_rngs
:
- PCG-XSH-RR 64/32 (LCG)
- PCG-XSL-RR 128/64 (MCG)
- SFC (32-bit variant)
- SFC (64-bit variant)
- Xoroshiro128+
The two PCG variants offer good quality and reasonable performance. SFC provides high performance and a chaotic PRNG (not a fixed period). Xoroshiro128+ has acceptable quality but high performance.
An PRNG put together by me, XoroshiroMT, is also good quality and sits between PCG and Xoroshiro128+ qua performance. But now that there is just a new Xoshiro PRNG, it may be worth evaluating that one first, as it is said to also be good quality.
CSPRNGs
For CSPRNGs we currently have two good implementations in Rand
- ChaCha20
- HC-128
ChaCha20 offers reasonably good performance and uses little memory, while HC-128 brings high performance at the cost of using much memory.
I would also like to see some implementation of AES-CTR DRBG eventually, as it is commonly used, and has hardware support on modern desktop processors.
Other / deprecated PRNGs
We currently have the ISAAC, ISAAC-64 and Xorshift128/32 PRNGs in rand. They have no real advantages over the PRNGs metioned before. It is better to use HC-128 instead of ISAAC, and Xoroshiro128+ or PCG instead of Xorshift. We can include them in something like a deprecated
module, but I propose to move them to stand-alone crates outside the Rand repository.
Steps to take
- move the
prngs
module to a seperaterand_rngs
crate in the Rand repository, similar torand_core
. - move
generators
benchmarks over. - lift PRNG implementations from https://github.com/pitdicker/small-rngs (I have updated it to master a while ago, but still have to push the changes)
- lift Xoroshiro128+ from https://github.com/vks/xoroshiro/
Does this sound about right?