-
Notifications
You must be signed in to change notification settings - Fork 2
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
What common traits should RNG implementations implement? #13
Comments
Note |
I agree that RNGs should definitely not implement PRNGs should also implement |
Also see: I also wonder about removing |
Ah, good links! One of the suggestions in them is to add clone-like functionality, but not implement the actual trait. I wonder if that would still be suggested with the Libz Blitz initiative an API guidelines... Now there is more of a push for interoperability and implementing common traits.
|
Regarding I also imagine they're not trivial to implement correctly. E.g. our recent discussion about whether Also, regarding |
As @dhardy noted in #16 (comment) it might be expected that after let |
I added a summary at the top. I think we're happy with this? |
Good idea to add labels "apparently solved". I would like to think a bit more about |
Can we also recommend Serde support behind a feature gate? See rust-random#189. Note that there are currently two issues likely to prevent |
I am not sure it is such a good idea, for the same reasons RNGs shouldn't implement rust-random#84 (comment) mentions a use case: games want to be able to restore to some specific state, and only knowing the initial seed is not enough. I think we can offer something better, by having seekable RNGs like PCG, ChaCha, and with some effort Xorshift(*). Now only the initial seed is needed and a counter, both which can be recorded with a wrapper. |
There are two problems there: (1) the counter needs to be extracted from somewhere, making implementation harder unless all RNGs now have to count output, and (2) not all RNGs are seekable (or can be made seekable without literally repeating each step). One could compromise and not implement this for CSPRNGs, but really the API shouldn't be responsible for securing details (e.g. a user could simply transmute to a POD struct type mimicking the internal structure if he really wanted to read the contents). |
(sorry for taking your comment apart)
Hm, my idea to work with a wrapper with a counter doesn't work. impl Rng for RngWithCounter {
// RNG outputs 32 bits natively
fn next_u32(&mut self) -> u32 {
self.counter += 1;
self.rng.next_u32()
}
fn next_u64(&mut self) -> u64 {
self.counter += 2;
self.rng.next_u64()
}
/*/
} Or maybe: impl Rng for RngWithCounter {
// RNG outputs 64 bits natively
fn next_u32(&mut self) -> u32 {
self.counter += 1;
self.rng.next_u32()
}
fn next_u64(&mut self) -> u64 {
self.counter += 1;
self.rng.next_u64()
}
/*/
} Or some other, more complex scheme?
Yes, true. But (as far as I know) all common non-cryptographic ones can be (LSFR and LCG families).
Using
Not sure. I don't think we should commit to security too much. But not making it easy for safe Rust code to accidentally reveal an RNGs state seems like a sensible precaution to me. With this post on the PCG blog one could argue not only CSPRNGs should not reveal their state, but normal PRNGs maybe neither. Not sure what to do it. Actually I don't care all that strong about it... |
I'm going to mark this as "apparently solved" again. The serialization stuff has been moved and there seems to be little interest in (partial) |
Added to RFC: rust-lang/rfcs@89ea3a9 |
Do we need to write some documentation / a guide before closing this? Possibly a small addition to the |
Summary
Debug
but such that no internal details are outputClone
if, and only if, the clone will have identical output to the originalCopy
Eq
andPartialEq
All
Rng
implementations should implementDebug
andClone
. For pseudo-random number generators it can also be useful to implementEq
andPartialEq
. Traits that should not be implemented or derived areCopy
,Default
andDisplay
.Debug
Many RNG implementations go through trouble to make the internal state not recoverable from the output, or at least not trivially so. For cryptographic RNGs their security depends on this. Then it seems strange to me if the internal state could show up in debug logs etc.
So for PRNGs we should recomment to add a custom Debug implementation that only displays the struct name, like
IsaacRng
currently does.Wrappers should derive
Debug
normally.Clone, Eq an PartialEq, but not Copy
An older RFC (never accepted, but with good some comments) argued RNG implementations should not implement
Copy
unless the copy generates independent/uncorrelated sequences. SoOsRng
could implement it, but PRNGs should not. It is otherwise to easy to end up with:For consistency I would suggest RNGs to never implement copy. This makes it easy to swap out implementations. For example to replace
OsRng
withChaChaRng
in user code.Clone
can be useful in the rare situations where you need two identical RNGs (I found them useful when testing). Together withEq
it can be useful to store the state of an RNG with clone, and restore or compare an RNG to a previous state.No Default
RNGs should be properly initialized, and not be created with a default fixed value.
I think some guideline like this should be part of the documentation, and possibly of the RFC.
The text was updated successfully, but these errors were encountered: