-
Notifications
You must be signed in to change notification settings - Fork 238
Add OsRng to getrandom #751
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
base: master
Are you sure you want to change the base?
Conversation
|
@newpavlov your opinion on this please? There is an alternative: the |
|
As I wrote previously, personally, I have a slight preference for a separate crate. But I would be fine with this PR as well, if others prefer it. P.S.: Note that |
josephlr
left a comment
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.
As I wrote previously, personally, I have a slight preference for a separate crate. But I would be fine with this PR as well, if others prefer it.
I think I would slightly lean towards having this as part of getrandom. A non-default additive feature seems like a good fit. I think the only complexity is figuring out what (if anything) this crate should re-export from rand_core.
.github/workflows/tests.yml
Outdated
| - run: cargo test | ||
| # Make sure enabling the std feature doesn't break anything | ||
| - run: cargo test --features=std | ||
| - run: cargo test --features=std,rng |
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.
Should we have a test somewhere that rng works without the std feature? Maybe here we could have:
| - run: cargo test --features=std,rng | |
| - run: cargo test --features=std | |
| - run: cargo test --features=rng | |
| - run: cargo test --features=std,rng |
I agree that having most of the testing use --features=std,rng is correct.
Cargo.toml
Outdated
| ] | ||
|
|
||
| [package.metadata.docs.rs] | ||
| features = ["std"] |
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.
This should be updated to include "rng" so that users can see the generated docs for stuff gated behind rng
| /// An RNG over the operating-system's random data source | ||
| /// | ||
| /// This is a zero-sized struct. It can be freely constructed with just `OsRng`. | ||
| /// | ||
| /// This struct is also available as [`rand::rngs::OsRng`] when using [rand]. | ||
| /// | ||
| /// # Usage example | ||
| /// ``` | ||
| /// use getrandom::{rand_core::{TryRngCore, RngCore}, OsRng}; | ||
| /// | ||
| /// let mut key = [0u8; 32]; | ||
| /// OsRng.try_fill_bytes(&mut key).unwrap(); | ||
| /// | ||
| /// let mut rng = OsRng.unwrap_err(); | ||
| /// let random_u64 = rng.next_u64(); | ||
| /// ``` | ||
| /// | ||
| /// [rand]: https://crates.io/crates/rand | ||
| /// [`rand::rngs::OsRng`]: https://docs.rs/rand/latest/rand/rngs/struct.OsRng.html |
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.
Similar to the docs for getrandom::Error, we should mention that this will require a crate to enable the rng feature. We should also mention here if the rng feature will have different MSRV or stability guarantees going forward. Are we allowed to increase the minor version of rand_core (from say 0.10 to 0.11) when moving from getrandom 0.4.0 to getrandom 0.4.1?
Not sure what our policy should be, but we should document it.
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.
doc-auto-cfg was stabilised so docs will note that OsRng requires feature rng, if that's what you mean.
Are we allowed to increase the minor version of
rand_core(from say0.10to0.11) when moving fromgetrandom 0.4.0togetrandom 0.4.1?
That would break semver since rand_core_0_10::TryRngCore and rand_core_0_11::TryRngCore are considered separate traits, so it should be clear that we cannot do that.
We should also mention here if the
rngfeature will have different MSRV or stability guarantees going forward.
I don't see why it would.
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.
doc-auto-cfg was stabilised
Are you sure? I thought it was just merged into doc_cfg. In RustCrypto we still use #![cfg_attr(docsrs, feature(doc_cfg))].
src/rng.rs
Outdated
| #[test] | ||
| fn test_os_rng() { | ||
| let x = OsRng.try_next_u64().unwrap(); | ||
| let y = OsRng.try_next_u64().unwrap(); | ||
| assert!(x != 0); | ||
| assert!(x != y); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_construction() { | ||
| assert!(OsRng.try_next_u64().unwrap() != 0); | ||
| } |
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.
These should be in a mod test with #[cfg(test)]
src/lib.rs
Outdated
| #[cfg(feature = "rng")] | ||
| mod rng; | ||
| #[cfg(feature = "rng")] | ||
| pub extern crate rand_core; |
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.
| pub extern crate rand_core; | |
| pub use rand_core; |
This is necessary for rustdoc to correctly:
- Render descriptions for all the other items
- Mark this re-export as gated behind the
rngfeature.
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.
- Mark this re-export as gated behind the
rngfeature.
It's not, but it does appear to cause render issues (all following text is fixed width / code). Weird.
src/rng.rs
Outdated
| /// # Usage example | ||
| /// ``` | ||
| /// use getrandom::{rand_core::{TryRngCore, RngCore}, 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.
| /// # Usage example | |
| /// ``` | |
| /// use getrandom::{rand_core::{TryRngCore, RngCore}, OsRng}; | |
| /// # Usage example | |
| /// | |
| /// The functionality of this struct is only accessible though its | |
| /// [`TryRngCore`] implementation: | |
| /// ``` | |
| /// use getrandom::{OsRng, rand_core::TryRngCore}; |
We should make it clear that the only way to use OsRng is via TryRngCore.
src/lib.rs
Outdated
| #[cfg(feature = "rng")] | ||
| pub extern crate rand_core; |
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.
Is there a reason to re-export all of rand_core? Would it make more sense to only re-export TryRngCore as that's the only non-marker trait OsRng implements?
We could then also add additional documentation explaining the re-export:
| #[cfg(feature = "rng")] | |
| pub extern crate rand_core; | |
| #[cfg(feature = "rng")] | |
| /// Re-exported base RNG trait from [`rand_core`] | |
| /// | |
| pub use rand_core::TryRngCore; |
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.
@newpavlov convinced me in the past that this is a good general policy, and I agree:
- It allows downstream crates to access
rand_corefunctionality without explicitly depending on that - It does not pretend that
TryRngCoreis part ofgetrandom - It reduces the chance of people hitting "multiple versions of
rand_core" errors
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.
IMO re-exporting rand_core is a must have and should be done by all RNG implementation crates.
654872c to
5b2ab43
Compare
|
Thanks for moving this forward @josephlr. I think I addressed your concerns (except as commented). |
5b2ab43 to
1e873b4
Compare
| /// [`rand::rngs::OsRng`]: https://docs.rs/rand/latest/rand/rngs/struct.OsRng.html | ||
| /// [`RngCore`]: rand_core::RngCore | ||
| #[derive(Clone, Copy, Debug, Default)] | ||
| pub struct 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.
I would prefer for it to be named as SysRng, since OsRng can be a confusing name on no_std targets. To make migration easier we could add type OsRng = SysRng; alias in rand (with or without #[deprecated] attribute).
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.
Makes some sense... some backends like RDRAND are not OS features.
| wasm_js = ["dep:wasm-bindgen", "dep:js-sys"] | ||
|
|
||
| # Provide OsRng over rand_core | ||
| rng = ["dep:rand_core"] |
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.
How about naming the feature os_rng (or sys_rng if the type will be renamed)?
| impl TryCryptoRng for OsRng {} | ||
|
|
||
| #[cfg(test)] | ||
| mod test { |
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 it's better to define these tests in tests/rng.rs or integrate them into the doctest.
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.
Motivation? Having tests close to the feature definition is slightly preferable in my opinion (where tests are not too extensive at least).
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.
My general preference is to keep public API tests in integration tests (i.e. in the tests folder) and/or doctest, while using test modules (i.e. unit tests) only for private API testing.
Since these tests are quite small, I think they can be simply merged into the OsRng doctest, potentially with # used to hide asserts.
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 the motivation is to improve visibility of integration tests, then moving to tests makes sense.
I'm disinclined to push these into a doc-test since (a) it hides it, (b) I would normally assume that doc-tests are only for documentation purposes and (c) failure reporting for doc tests is worse (slower and worse messages) than for other types of test.
So I don't understand why you prefer both integration tests and doc tests over a local test module.
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.
It's just a matter of not duplicating tests which are already covered by doctests. I am fine with keeping the example as-is and moving the test module into the tests/ folder.
This was mentioned elsewhere: rust-random/rand#1675
Adds
rand_coreas a dependency, which is one small crate.This attempts to enable testing of
rngin all CI tests.