Description
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 Read
able 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
- @matklad advocating for RNG access in
std
- Use getrandom for generating HashMap seed rust#80149 will remove
std
's random number generation in favour ofgetrandom
Footnotes
-
which should IMHO be the default, but users may want to depart from this behaviour ↩