Skip to content

Auto-seeded randomness: thread_rng, weak_rng, random() #23

Closed
@dhardy

Description

@dhardy

The rand crate currently has:

  • weak_rng() — seeds a new XorShiftRng from OsRng on each call
  • thread_rng() — initialises a per-thread ISAAC generator from OsRng on first call and returns a reference
  • random() — convenience wrapper around thread_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:

  1. Strong entropy for direct usage or seeding crypto generators: OsRng
  2. "Good" entropy via OsRng or a fallback for cases where entropy is still important but not critical (stuff like HashMap which might possibly be open to a DoS attack or randomised algorithms)
  3. 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.)
  4. 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:

  1. Direct access to strong entropy (OsRng)
  2. Direct access to reliable entropy (OsRng or fallback)
  3. (Possibly) direct access to fast entropy (ClockRng or some such)
  4. A generator which provides a good trade-off between strength and performance without necessarily having true cryptographic strength: thread_rng
  5. 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)?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions