A random number generator for libstd


#21

This is a good point, but not an unsolvable one. 90% of Rand code is no_std compatible; the issues are a few things using Vec and OsRng. So most of the required code could be put in the core lib, and then lang items or similar could be used to specify the entropy source (in std or in a no_std crate).


#22

TIL… Thanks!


#23

Lots of platforms (but by no means all) have CPU intrinsics for random number generation. There are important caveats and variations on these, but they are still useful, especially in embedded case where other entropy sources are problematic. In projects where more comprehensive CSPRNG’s are available, they could/should still at least be used as a mixin entropy source.

I’ve used the rand crate in no_std and it works fine, for the clearly-documented subset of features.

What interests me here is the intersection of the two: so far as I can tell, there isn’t a clear way to get rand to use such an instruction where available – other than perhaps implicitly via OsRng if that happens to use it, and that’s not applicable not in the embedded case.

Is there something that could be put in core to access CPU randomness sources, and used by rand (and probably HashMap too) for benefit where available? It might not be something to recommend for direct consumption by those looking for quick shortcuts, given some of the caveats, but the current alternative seems to be requiring very specific platform knowledge in user code.

(Apologies if there is already such a thing that I missed, it was a while since I went looking).


#24

There’s currently a PR open on the Rand repo about adding hooks for entropy collection on no_std platforms. I won’t link to it because it’s a mess of details (which are entirely solvable) and it’s easy to find. In my opinion the most important part is the big picture.

Currently in Rand:

  • rand::random produces a random value of many possible types, via conversion code on top of thread_rng
  • rand::thread_rng provides a stream of random integers/bytes via a psuedo-random generator over an entropy source
  • rand::rngs::EntropyRng abstracts over external entropy sources, converting to high-quality random data (but is potentially slow)

The goal of Rand is to provide all the above. The goal of rand_core is to expose a standard API for RNGs.

I bring all this up, because it exposes different layers of a random number system which could be introduced into std / core. As mentioned, std already has a copy of thread_rng in order to serve RandomState. Making this no_std compatible requires a little more work (which is the object of the PR mentioned above) but is feasible.

But it begs the question: is the goal of core to be minimal or merely to be portable? And how much functionality should std include? Should std depend on rand or is that the wrong way around?

(Unfortunately making std depend on rand without a cyclic dependency is hard because rand::rngs::OsRng requires file system IO on some platforms.)


#25

I think it’s important to note that it’s significantly more difficult to build, test, and contribute to core and std than to an outside crate. This alone is a strong argument against bringing anything into core/std that doesn’t need to be in there.

I agree with the others who have suggested curated crate recommendations and cargo-fix tie-ins to easily add dependencies to Cargo.toml, in order to further reduce the friction of depending on outside crates.