-
Notifications
You must be signed in to change notification settings - Fork 216
aead: generate_nonce accept an immutable rng #1087
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
Comments
The It's leveraging a blanket impl of The purpose of using this was to make the type signature a bit cleaner than @newpavlov it seems people get really confused by these type signatures because they don't immediately realize they need to pass |
In addition to cleaner signatures the current approach also allows us to write I am open to changing it in the next breaking releases (together with |
Being able to directly pass I’d be down to change it back to a named parameter in the next release, though. I think it’s just too confusing as is. |
I see, I was so entrenched in seeing and using function signature like Future reference for myself: trait RngCore {}
#[derive(Default)]
struct OsRng;
impl RngCore for OsRng {}
// blanket implementation, mimicking rand_core: https://docs.rs/rand_core/latest/rand_core/trait.RngCore.html#impl-RngCore-for-%26%27a%20mut%20R
impl<'a, R: RngCore> RngCore for &'a mut R {}
// same as `fn encrypt(_rng: &mut impl RngCore)`, but generic over R looks better.
// passing in an immutable binding of mutable reference: can't change what `rng` points to, can change the value/state that `rng` points to.
fn encrypt<R: RngCore>(_rng: &mut R) {}
// what RustCrypto and Halo2 uses. Cleaner-looking API than `encrypt()`
fn encrypt2(mut _rng: impl RngCore) {}
fn main() {
let mut rng = OsRng::default();
// encrypt(rng); // will give clear error: "expected `&mut _`, consider mutably borrowing here: `&mut rng`"
encrypt(&mut rng); // only this will works! obvious from function signature
// encrypt2(&rng); // the trait `RngCore` is not implemented for `&OsRng`
// // will be troublesome if we can pass in `&rng`, because that means inside `encrypt()`, they can mutate the reference and point
// // to some other Rng, which is obviously undesirable. Thankfully, the blanket implementation is only for `&mut R`, not `&R`, not `&R`
encrypt2(&mut rng); // works! becasue of the blanket impl
encrypt2(rng); // works! but note that we move `rng` into this function, useful when you only want to use some Rng once without the redundant &mut
} |
Something else I think is a bit annoying is the need to declare the binding pub fn some_fn(mut rng: &mut Rng) -> (Key, Nonce) {
let key = MyAead::generate_key(&mut rng);
let nonce = MyAead::generate_nonce(&mut rng);
(key, nonce)
} ...whereas with pub fn some_fn(rng: &mut Rng) -> (Key, Nonce) {
let key = MyAead::generate_key(rng);
let nonce = MyAead::generate_nonce(rng);
(key, nonce)
} |
yeah, that's true. Guess no clear winner between the two options then, and a matter of taste. |
another tangential question, why are we marking didn't |
Using |
TIL: https://docs.rs/rand_core/latest/rand_core/trait.CryptoRngCore.html Given that, I think we could move to (though for whatever reason |
`rand_core` v0.6.4 added an auto-impl'd `CryptoRngCore` marker trait for types which impl `CryptoRng + RngCore` which is slightly more convenient and less verbose. This commit changes to using `&mut impl CryptoRngCore` as proposed in #1087. This hopefully strikes a balance between least surprise and minimal required syntax, namely &mut references are reusable and don't require knowledge of the blanket impl of `RngCore` for `&mut R: RngCore`
`rand_core` v0.6.4 added an auto-impl'd `CryptoRngCore` marker trait for types which impl `CryptoRng + RngCore` which is slightly more convenient and less verbose. This commit changes to using `&mut impl CryptoRngCore` as proposed in #1087. This hopefully strikes a balance between least surprise and minimal required syntax, namely &mut references are reusable and don't require knowledge of the blanket impl of `RngCore` for `&mut R: RngCore`
I think this issue is "solved", and opened #1148 for further discussion. |
I'm a little confused by the latest
AeadCore::generate_nonce()
API:in code, it seems to be
however in rustdoc (latest/v0.5.1), it seem to be accepting an immutable
rng
:fn generate_nonce(rng: impl CryptoRng + RngCore) -> Nonce<Self>
that's the first confusion.
The second confusion is, why does it accept
mut rng
instead of&mut rng
?The text was updated successfully, but these errors were encountered: