-
Notifications
You must be signed in to change notification settings - Fork 230
kem: Kem trait for the whole algorithm type family
#2243
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
Conversation
Adds a `Kem` trait intended to be impl'd by ZSTs that describe the whole type family, including the decapsulation key, encapsulation key, and the sizes of the ciphertext and shared secret previously defined on the `KemParams` trait (which this subsumes). The remaining traits have been changed to be generic around `K: Kem` and now use it to source their constants or relevant types. `DecapsulationKey<K>` and `EncapsulationKey<K>` type aliases have been added, similar to the ones in `elliptic-curve`, which take care of doing `K as Kem` for you when accessing the associated types. The design of this trait largely matches the bespoke traits that people were defining different but similarly shaped-versions of in individual crates in https://github.com/RustCrypto/KEMs
| /// Often, this will just be a public key. However, it can also be a bundle of public keys, or it | ||
| /// can include a sender's private key for authenticated encapsulation. | ||
| pub trait Encapsulate: KemParams + TryKeyInit + KeyExport { | ||
| pub trait Encapsulate<K: Kem>: TryKeyInit + KeyExport { |
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.
Now that I think about it, these generic parameters are important for binding an impl of Encapsulate/(Try)Decapsulate to a specific KEM algorithm, e.g. if an HSM library wanted to add one.
Unlike signature we can't infer the algorithm from the return type.
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'm also kind of torn using a generic here. There will probably be only one impl per type, so we don't need overlapping bounds.
It means that everyone needs to notate it in the downstream bounds, which is a little annoying, but they'll need to bound on Kem anyway since it's the trait holding everything together.
If we moved it to an associated type it would get out of the way, but then we should probably get rid of the Decapsulator trait so we don't have to worry about both Decapsulator and Decapsulate defining an associated Kem type.
We would, however, still have to worry about both Decapsulate and TryDecapsulate defining associated Kem types, and if we moved encapsulator to those traits they would then have overlapping encapsulator methods (which is the problem Decapsaulator exists to solve in the first place)
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 agree, it's kind of annoying having multiple generics here. A thought: what about putting all methods inside Kem, and just removing all the other traits? Instead of ek.encap(...), you'd call K::encap(ek, ...). Benefits: single generic parameter to manage, one place to define an entire KEM. Downside: it's not clear how to handle TryDecapsulate anymore. For what it's worth, I think it might be fine to make decapsulation always fallible (as of today, the only possible error in any known KEM is ciphertext deserialization). If someone wants to convey it's infallible, they can set Kem::DecapError = Infallible. Thoughts?
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.
What's nice about the current approach is it's flexible to permit a Decapsulate or TryDecapsulate impl on a hardware-backed decapsulation key, where you can still retrieve its associated encapsulation key using a software implementation.
But also: we still need types to hold the state of decoded decapsulation/encapsulation keys. This trait is intended to be impl'd on a ZST.
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.
Ahh, ok. So some simplifications that remain are: absorb Encapsulate into Kem, and merge Decapsulate and TryDecapsulate. I don't feel strongly about either though. Just thoughts
|
I'm going to try this out on https://github.com/RustCrypto/KEMs and if it looks good I'll mark the PR as ready for review |
| pub trait KemParams { | ||
| /// Size of the ciphertext (a.k.a. "encapsulated key") produced by [`Encapsulate::encapsulate`]. | ||
| /// This trait describes the entire type family used by a KEM. | ||
| pub trait Kem: Copy + Clone + Debug + Default + Eq + Ord + Send + Sync + 'static { |
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 are the same bounds as elliptic_curve::Curve. They're important when a type that impls Kem is used as a generic parameter on other types, so custom derive works because it doesn't freak out about the bounds of the ZST it's generic around.
- Bound `DecapsulationKey` on `TryDecapsulate` as it's the supertrait - Remove `From<&Self::DecapsulationKey>` bound - Remove `Decapsulator` trait, replace it with an `AsRef<Self::EncapsulationKey>` bound on `TryDecapsulate`
Companion PR to RustCrypto/traits#2243 This implements a trait which describes a whole KEM type family, with a similar shape to the former `dhkem::DhKem` and `ml_kem::KemCore` traits (both of which have been removed and replaced with `kem::Kem`). As part of this, the `*Params` types in `ml_kem` have been merged with the former type aliases of the `ml_kem::Kem` type (which have also been removed), and now `MlKem512`, `MlKem768`, and `MlKem1024` are the one true ZSTs for describing ML-KEM parameters.
Companion PR to RustCrypto/traits#2243 This implements a trait which describes a whole KEM type family, with a similar shape to the former `dhkem::DhKem` and `ml_kem::KemCore` traits (both of which have been removed and replaced with `kem::Kem`). As part of this, the `*Params` types in `ml_kem` have been merged with the former type aliases of the `ml_kem::Kem` type (which have also been removed), and now `MlKem512`, `MlKem768`, and `MlKem1024` are the one true ZSTs for describing ML-KEM parameters.
Companion PR to RustCrypto/traits#2243 This implements a trait which describes a whole KEM type family, with a similar shape to the former `dhkem::DhKem` and `ml_kem::KemCore` traits (both of which have been removed and replaced with `kem::Kem`). As part of this, the `*Params` types in `ml_kem` have been merged with the former type aliases of the `ml_kem::Kem` type (which have also been removed), and now `MlKem512`, `MlKem768`, and `MlKem1024` are the one true ZSTs for describing ML-KEM parameters.
Companion PR to RustCrypto/traits#2243 This implements a trait which describes a whole KEM type family, with a similar shape to the former `dhkem::DhKem` and `ml_kem::KemCore` traits (both of which have been removed and replaced with `kem::Kem`). As part of this, the `*Params` types in `ml_kem` have been merged with the former type aliases of the `ml_kem::Kem` type (which have also been removed), and now `MlKem512`, `MlKem768`, and `MlKem1024` are the one true ZSTs for describing ML-KEM parameters.
Kem trait for the whole algorithm type familyKem trait for the whole algorithm type family
|
Alright, after a few tweaks I now have RustCrypto/KEMs#223 building against this. Gonna land it and do a crate release, then update the PR. |
Companion PR to RustCrypto/traits#2243 This implements a trait which describes a whole KEM type family, with a similar shape to the former `dhkem::DhKem` and `ml_kem::KemCore` traits (both of which have been removed and replaced with `kem::Kem`). As part of this, the `*Params` types in `ml_kem` have been merged with the former type aliases of the `ml_kem::Kem` type (which have also been removed), and now `MlKem512`, `MlKem768`, and `MlKem1024` are the one true ZSTs for describing ML-KEM parameters.
Companion PR to RustCrypto/traits#2243 This implements a trait which describes a whole KEM type family, with a similar shape to the former `dhkem::DhKem` and `ml_kem::KemCore` traits (both of which have been removed and replaced with `kem::Kem`). As part of this, the `*Params` types in `ml_kem` have been merged with the former type aliases of the `ml_kem::Kem` type (which have also been removed), and now `MlKem512`, `MlKem768`, and `MlKem1024` are the one true ZSTs for describing ML-KEM parameters.
Companion PR to RustCrypto/traits#2243 This implements a trait which describes a whole KEM type family, with a similar shape to the former `dhkem::DhKem` and `ml_kem::KemCore` traits (both of which have been removed and replaced with `kem::Kem`). As part of this, the `*Params` types in `ml_kem` have been merged with the former type aliases of the `ml_kem::Kem` type (which have also been removed), and now `MlKem512`, `MlKem768`, and `MlKem1024` are the one true ZSTs for describing ML-KEM parameters.
Companion PR to RustCrypto/traits#2243 This implements a trait which describes a whole KEM type family, with a similar shape to the former `dhkem::DhKem` and `ml_kem::KemCore` traits (both of which have been removed and replaced with `kem::Kem`). As part of this, the `*Params` types in `ml_kem` have been merged with the former type aliases of the `ml_kem::Kem` type (which have also been removed), and now `MlKem512`, `MlKem768`, and `MlKem1024` are the one true ZSTs for describing ML-KEM parameters.
Companion PR to RustCrypto/traits#2243 This implements a trait which describes a whole KEM type family, with a similar shape to the former `dhkem::DhKem` and `ml_kem::KemCore` traits (both of which have been removed and replaced with `kem::Kem`). As part of this, the `*Params` types in `ml_kem` have been merged with the former type aliases of the `ml_kem::Kem` type (which have also been removed), and now `MlKem512`, `MlKem768`, and `MlKem1024` are the one true ZSTs for describing ML-KEM parameters.
Adds a
Kemtrait intended to be impl'd by ZSTs that describe the whole type family, including the decapsulation key, encapsulation key, and the sizes of the ciphertext and shared secret previously defined on theKemParamstrait (which this subsumes).The remaining traits have been changed to be generic around
K: Kemand now use it to source their constants or relevant types.DecapsulationKey<K>andEncapsulationKey<K>type aliases have been added, similar to the ones inelliptic-curve, which take care of doingK as Kemfor you when accessing the associated types.The design of this trait largely matches the bespoke traits that people were defining different but similarly shaped-versions of in individual crates in https://github.com/RustCrypto/KEMs
cc @rozbb
Edit: companion PR: RustCrypto/KEMs#223