Conversation
# Conflicts: # QUALITY_AND_STYLE.md # crypto/core/src/traits.rs
…ms consume randomness
romen
left a comment
There was a problem hiding this comment.
Is passing &mut dyn RNG really necessary?
Rather than
fn keygen_from_rng<R: RNG>(rng: R) -> Result<(PK, SK), KEMError> { ... }Committing to dynamic dispatch is not necessarily always evil, but does prevent the compiler to optimize as much, and does have some runtime performance penalty due to vtable indirection to resolve the dispatching.
On the other hand, if you intentionally want to support RNG implementations that are known only at runtime and not at compile time, a dyn RNG ref is the way to go.
| behaviours and error conditions that are comment to all implementations of that trait. | ||
|
|
||
| All crypto algorithms must have tests against the bc-test-data repo and against wycheproof. | ||
| behaviours and error conditions that are comment to all implementations of that trait.All crypto algorithms must have tests against the bc-test-data repo and against wycheproof. |
There was a problem hiding this comment.
I am not sure this whitespace change is intentional!
Also s/comment/common/
There was a problem hiding this comment.
See https://doc.rust-lang.org/std/keyword.dyn.html for a terse review of the tradeoffs
|
The choice of
That said, if we really want to leave room for static dispatch, a common idiomatic compromise is to keep the public methods generic over Conclusion: There is no need to revert |
|
Thanks @romen . I am still very much wrapping my head around how dyn works. This discussion is helpful. I hadn't really considered that these two versions are alternate ways to achieve the same behaviour, but with some different tradeoffs fn keygen_from_rng(rng: &mut dyn RNG) -> Result<(PK, SK), KEMError> {
let mut seed = KeyMaterial::<64>::new();
rng.fill_keymaterial_out(&mut seed)?;
Self::keygen_from_seed(&seed)
}vs fn keygen_from_rng<R: RNG>(rng: R) -> Result<(PK, SK), KEMError> {
let mut seed = KeyMaterial::<64>::new();
rng.fill_keymaterial_out(&mut seed)?;
Self::keygen_from_seed(&seed)
}My feeling is that Dyn is correct here; especially if we expect this to be highly dynamic at runtime -- for example if the calling application wakes up, looks around, decides what kinds of OS or HW RNGs are present on its system, and then chooses an RNG impl to provide to the alg. I also think that Dyn will play nicer with RNGFactory, which again is an attempt to abstract away the concrete type But this is great. Please continue educating me on the tradeoffs! |
|
@Quant-TheodoreFelix I have to ask, are all your comments AI-generated? I find this comment very odd:
That is referring to a TODO comment that I added in this PR, that is completely unrelated to this discussion, so why would you "recommend" that? |
This change set makes the RNG trait dyn-compatible and also leverages it within ML-DSA and ML-KEM so that keygen() and encaps() have versions that can accept a
&dyn RNGand source their randomness from that.This change brings bc-rust a bit closer to bc-java.