-
Notifications
You must be signed in to change notification settings - Fork 230
Description
The current definition of kem::Encapsulate is
pub trait Encapsulate<EK, SS> {
/// Encapsulation error
type Error: core::error::Error;
/// Encapsulates a fresh shared secret
fn encapsulate_with_rng<R: TryCryptoRng + ?Sized>(
&self,
rng: &mut R,
) -> Result<(EK, SS), Self::Error>;
// ...
}Note that Error is an associated type, but encapsulate_with_rng takes a fallible RNG, whose error type can be anything (as long as it's Debug + Display). So an implementer who wants to faithfully return an RNG error needs to either 1) define Encapsulate::Error to store a Box<dyn Debug + Display> in case the RNG fails, or 2) not store the RNG error at all, and just return a unit type RngError. Both of these options aren't great. (1) is particularly odd because usually you only care about fallible RNGs in embedded settings, where you might not have an allocator anyway.
One solution I like is to remove TryCryptoRng from the kem API entirely, and just accept CryptoRng.
I'll strengthen it further, actually: I am not convinced that ANY low-level cryptography crate should accept a TryCryptoRng in its API. imo there is no reason that an IO error should show up in a public key encryption, or a polynomial secret sharing operation. I think it only serves to clutter the API, and frustrate error handling (like we see above). If a user has a fallible RNG and wants to use a low-level cryptography library, I think the correct path is to use that RNG to make a 32 byte seed, and then instantiate an infallible seedable RNG with it.