-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Crypto / rand trait & crate split #2118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
|
||
| ```rust | ||
| pub enum Error { | ||
| pub Unspecified, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pub here is invalid syntax
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good work! Some comments and suggestions.
UPD: Also what about SeedableRng? I think we need crypto counterpart, either fully copied SeedableCsrng (plus errors for incorrect seed length) or something like trait Csprng: Csrng { .. }, otherwise CSPRNG crates will have to import rand or not use traits for relevant functionality.
|
|
||
| Create a new crate, `crypto-rand`, with only the following contents: | ||
|
|
||
| ```rust |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You forgot to add #![no_std] here.
| ```rust | ||
| pub enum Error { | ||
| pub Unspecified, | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if we need enum here. Can't we just use pub struct Error; ? @briansmith can you provide motivation for using enum? I think it's quite unlikely we'll need to expand this error in the future.
Also what about implementing Error trait (btw conflict of the names) and deriving/implementing others, e.g. Copy, Clone, Debug, Display, Read, etc.? For Error we'll need to introduce std feature gate.
|
|
||
| pub trait Generator { | ||
| fn try_fill(&self, dest: &mut [u8]) -> Result<(), Error>; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think Generator is a bit too long, how about Csrng? (you propose something similar in alternatives) It's a bit more cryptic, but will be in a good alignment with my further proposal regarding crate names. Also I don't fully agree with Brian regarding the need to remove "r" from "rng" just because crate name is based on "random".
text/0000-rand-crypto.md
Outdated
| ``` | ||
|
|
||
| Associated with this, create another crate called `crypto-rng-os` which defines | ||
| a struct `OsGen`, implementing `Generator` via OS functionality (using code from |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we want to use a prefix for crate names, I think something like csrng-* will fit better. Although I like suffixes like os-csrng a bit more, to me they feel more natural for this use-case. Also if we use rng in the crate name, then it's logical to use OsRng instead (plus it will be familiar to users).
| // possibly also next_u128 | ||
|
|
||
| // possibly also the following (no Result unlike try_fill above): | ||
| fn fill(&mut self, dest: &mut [u8]) { /* default impl here */ } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to specify what will happen here in case of an error, will it panic? Ideally directly provide default implementation for this method. Something like:
fn fill(&mut self, dest: &mut [u8]) {
self.try_fill(dest).except("...");
}
Note that some games have the additional requirement of determinism: that for a given seed, you are guaranteed to get some specific value. This means that you can't use floats for computation, and you can't store stuff into For example, take a minecraft/minetest clone which stores the map by storing the difference to the generated terrain. Here you want perfect reproducability, especially if client and server have different platforms (server x86 based, client ARM based). Most use cases in games are of the "fast, no need for determinism" kind, but for the use cases outlined above, determinism is very important. Probably this use case is very niche and doesn't deserve its own trait, but instead implementations of the trait can signify whether they are 100% deterministic in their documentation, but I think its great to be aware. |
|
Actually, @est31, I think determinism is very useful for a bunch of stuff (e.g. see this comment of mine). Luckily for us all PRNG algorithms are deterministic (the 'P' means pseudo — algorithms can never generate real randomness). Maybe that comment should be a little clearer then... |
|
@dhardy Interesting point was raised in the parent RFC. Should we use error which will be associated type in the Regarding |
|
|
||
| The `CryptoRng` trait and `Error` enum are specified above. We should make it | ||
| clear that although `Error::Unspecified` is directly accessible, `Error` could | ||
| be extended in the future (is formal specification of this possible?). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#[non_exhaustive]? #2008
| } | ||
|
|
||
| impl OsRng { | ||
| pub fn new() -> OsRng { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible to move the fallibility into the constructor? So the trait method would be infallible, but you'd use OsRng::try_new() to get an instance, which might fail with something like Err(Error::NotYetSecurelySeeded) or Err(Error::NotAvailableOnPlatform). (My recollection from the previous threads and sponge papers is that once the CSPRNG has sufficient entropy to start producing values, it will no longer fail.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, some errors can be detected on creation, but the interfaces used by most or all OSes have some potential to fail later. Whether or not they fail in practice I have no idea.
great to hear!
If you use floats you are likely not deterministic (as floats are strange beasts where order of operations matter but compilers don't care and reorder happily, and many more things). And if you use So its not a trivially fulfilled property. Surely, its easy to make most PRNG algorithms deterministic, but we should have some consensus on what to do about non deterministic/platform dependent ones... Fix them? Mark them somehow? Are docs enough? |
|
@est31 if you're talking specifically about PRNG algorithms, nearly all algorithms are integer based, and we pretty-much agreed to remove the Of course, a complex application using floating-point operations may end up producing different results on different platforms (OS/CPU/compiler) even if the PRNG generates the same numbers; I've had that problem before (even totally different results due to decisions based on randomised FP numbers) but it's not a PRNG problem. |
Noise-rs uses usize for seeding: https://docs.rs/noise/0.4.1/noise/struct.Perlin.html |
|
@est31 Perlin Noise is not a general purpose random number generator: sampled values are deliberately not independent. That said, if you think it should be cross-platform reproducible, by all means ask the author not to use |
|
Just as an observation, if you care about determinism and/or reproducibility of your RNG, you need to pin both the seed and the algorithm. It's important, I think, to give the people who need those things what they want - but it is also important to make sure that the "default" RNG isn't tied down to either determinism or any particular algorithm. Basically what I'm saying is that the seedable API should require you to specify the algorithm as well as the seed, and APIs that don't specify the algorithm should not be manually seedable. |
|
I'm going to close this RFC; it's not up-to-date with the main one and having a separate discussion channel for the split didn't work out. There are some good points about reproducibility here; not quite sure how we got to that subject though! |
Rendered
Background
This RFC is an offshoot of the Rand revision RFC, on the subject of:
Rngtrait into a crypto-oriented trait andnumerical-application-oriented trait