Description
The rand
crate currently has:
weak_rng()
— seeds a newXorShiftRng
fromOsRng
on each callthread_rng()
— initialises a per-thread ISAAC generator fromOsRng
on first call and returns a referencerandom()
— convenience wrapper aroundthread_rng()
OsRng::new()
— unlike other generators, can be created directly since it uses external entropy
But what do we want to provide? In terms of entropy:
- Strong entropy for direct usage or seeding crypto generators:
OsRng
- "Good" entropy via
OsRng
or a fallback for cases where entropy is still important but not critical (stuff likeHashMap
which might possibly be open to a DoS attack or randomised algorithms) - Weak entropy? For things which want some entropy (e.g. randomised algorithms and games) but aren't vulnerable to attacks or where it really doesn't matter. (It may be that the previous category covers this one too sufficiently anyway.)
- Deterministic (seeded) generators: no entropy
In terms of convenient random numbers it gets more complicated, because we potentially have a matrix of entropy vs speed and memory requirements, via a thread-local generator or a fresh generator. But most importantly:
- Direct access to strong entropy (
OsRng
) - Direct access to reliable entropy (
OsRng
or fallback) - (Possibly) direct access to fast entropy (
ClockRng
or some such) - A generator which provides a good trade-off between strength and performance without necessarily having true cryptographic strength:
thread_rng
- Some recommended PRNGs providing various trade-offs between performance, memory usage and quality, which can be easily seeded from either fresh entropy or a fixed seed
The existing weak_rng()
really satisfies only one variant of the last case, and personally I see little justification for keeping it over something like SmallFastRng::from_rng(reliable_entropy())
. On the other hand, one shouldn't use SmallFastRng
directly for deterministic generation (since the underlying generator may change), so SmallFastRng::from_rng(reliable_entropy())
appears to be the only use-case.
The existing StdRng
is in a similar position: it shouldn't be used for reproducibility, hence its only real use is the current thread_rng()
.
To do:
- Implement a good fallback generator
- Do we also want a fast, weak clock-based generator?
- Is
weak_rng
+thread_rng
+ direct access to entropy generators sufficient? - Is usage sufficiently clear (e.g. that
thread_rng
is not for cryptography)?