Skip to content

Make RngCore infallible? #1418

@dhardy

Description

@dhardy

Summary

Remove RngCore::try_fill_bytes and recommend that the trait only be implemented for infallible RNGs.

Details

While, in theory, RNGs like ChaCha or even PCG could detect the end of a cycle and report an error, our current RNGs don't do this. BlockRng also does not have any consideration for RNG errors. Meanwhile, OsRng is our only remaining fallible RNG.

A potential external fallible RNG is a hardware RNG token. Plugging one of these into code expecting an RngCore would therefore be more difficult, requiring a fallback, hang or panic-on-error. It is, however, questionable if such a generator should ever implement RngCore.

Users of try_fill_bytes:

  • RngReadAdapter
  • Fill::try_fill; this is only to push error handling up to the caller, and arguably should be replaced with an infallible variant

Hence, for the rand library, the only real loss would be OsRng.

What this doesn't solve

Cryptographic applications requiring a byte RNG with support for error handling. An existing alternative is rustls::crypto::SecureRandom. Another, more application specific trait, is cipher::StreamCipherCore.

There is no reason that a crate can't simultaneously provide impls of more than one of these traits, so impls can be shared.

There is a missing link here: applications which are generic over a SecureRandom no longer have access to rand's functionality (without some error-handling adapter), and so on. This doesn't seem to bad though; in particular (a) adapters are possible (even if they must panic) and (b) as far as I am aware, applications of these different traits usually don't need functionality from multiple of these libraries.

(Note: it is also possible to use a custom trait like SecureRandomRng: SecureRandom + RngCore in case generic code does need to use multiple of these libraries.)

Motivation

Simplicity and focus.

We recently had #1412 in order to improve the situation for infallible code. Ultimately, though, rand is a crate for stochastic algorithms like shuffling, bounded uniform sampling and sampling from a Gaussian. Its generators can be used to generate keys or a book of random data and this won't change aside from the inability to plug in a fallible generator with proper error handling, but arguably when you need this error handling you should already be using another library anyway.

Alternatives

We could encode fallibility into RngCore (#1412 implements one method and mentions another in its comments).

We could also provide a FallibleRng with the try_fill_bytes method, however this begs questions like why not move it up to getrandom or why not use SecureRandom instead?

Final word

The rand library has long been a compromise between many competing demands. The only specific functionality we would lose here is the ability to forward errors from byte-generating RNGs. Fallible RNGs must currently panic (or hang) on error when implementing any of the other three RngCore methods, which is a strong indication that something is wrong with the current design.

CC

@newpavlov @vks @tarcieri @ctz @josephlr

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions