Skip to content

Provide access to the system's random number generator #159

Closed
@joboet

Description

@joboet

Proposal

(an alternative to #393)

Motivation

Nearly all targets that std supports (with the exception of WASM) provide access to a cryptographically secure random number generator. Although this functionality is more widespread than even filesystem access, std does not currently have an abstraction for it, leading users to rely on an external crate like getrandom. While that crate is of high quality, this still leads to the duplication of functionality that std already implements, as HashMap is initialized with seeds generated from the system's RNG by default. Also, this complicates the addition of new targets to the ecosystem, as more libraries need to be changed to support this very common use case.

Unfortunately, the current lack of a common abstraction means there is a widespread pattern of users using File::open("/dev/urandom") for easy access to random data (GitHub search). This is not very portable and can be problematic, as "/dev/urandom" returns low-quality randomness on Linux if the entropy pool is not yet initialized (this is unlikely to be a problem for most usecases, but especially on embedded devices, security will suffer).

Solution sketches

A Readable handle type similar to the Stdin/Stdout handles is added to std::io along with its matching constructor:

// in std::io

pub struct Entropy { .. }

impl Read for Entropy { .. }

pub fn entropy() -> Entropy;

Random bytes are generated by using the Read trait's methods:

use std::io::entropy;

let mut bytes = [0; 128];
entropy().read_exact(&mut bytes)?;

While this represents a departure from getrandom's API, using the Read trait is more idiomatic, enables better interplay with other io functions such as copy and allows for optimizations like using an uninitialized buffer with read_buf. Additionally, it enables the configuration of behaviour like blocking until there is enough entropy available1 through methods on the struct, mirroring API like TcpStream::set_nonblocking.

Links and related work

Footnotes

  1. which should IMHO be the default, but users may want to depart from this behaviour

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-libs-apiapi-change-proposalA proposal to add or alter unstable APIs in the standard libraries

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions