@@ -13,74 +13,82 @@ pub use common::{
1313} ;
1414
1515use common:: array:: { self , ArraySize } ;
16+ use core:: fmt:: Debug ;
1617use core:: { array:: TryFromSliceError , convert:: Infallible } ;
1718use rand_core:: CryptoRng ;
1819
1920#[ cfg( feature = "getrandom" ) ]
2021use common:: getrandom:: { SysRng , rand_core:: UnwrapErr } ;
2122
23+ /// KEM decryption key (i.e. private key) which can decrypt encrypted shared secret ciphertexts
24+ /// which were encrypted by [`EncapsulationKey<K>`].
25+ pub type DecapsulationKey < K > = <K as Kem >:: DecapsulationKey ;
26+
27+ /// KEM encryption key (i.e. public key) which encrypts shared secrets into ciphertexts which
28+ /// can be decrypted by [`DecapsulationKey<K>`].
29+ pub type EncapsulationKey < K > = <K as Kem >:: EncapsulationKey ;
30+
31+ /// Shared key: plaintext produced after decapsulation by [`Decapsulate::decapsulate`] which is
32+ /// also returned by [`Encapsulate::encapsulate`], which is the shared secret resulting from the
33+ /// key encapsulation algorithm.
34+ pub type SharedKey < K > = array:: Array < u8 , <K as Kem >:: SharedKeySize > ;
35+
2236/// Ciphertext message (a.k.a. "encapsulated key") produced by [`Encapsulate::encapsulate`] which is
23- /// an encrypted [`SharedSecret`] that can be decrypted using [`Decapsulate::decapsulate`].
24- ///
25- /// `K` is expected to be a type that impls [`KemParams`], such as an encapsulator or decapsulator.
26- pub type Ciphertext < K > = array:: Array < u8 , <K as KemParams >:: CiphertextSize > ;
37+ /// an encrypted [`SharedKey`] that can be decrypted using [`Decapsulate::decapsulate`].
38+ pub type Ciphertext < K > = array:: Array < u8 , <K as Kem >:: CiphertextSize > ;
2739
28- /// Shared secret: plaintext produced after decapsulation by [`Decapsulate::decapsulate`] which is
29- /// also returned by [`Encapsulate::encapsulate`].
40+ /// Key encapsulation mechanism.
3041///
31- /// `K` is expected to be a type that impls [`KemParams`], such as an encapsulator or decapsulator.
32- pub type SharedSecret < K > = array:: Array < u8 , <K as KemParams >:: SharedSecretSize > ;
42+ /// This trait describes the entire type family used by a KEM.
43+ pub trait Kem : Copy + Clone + Debug + Default + Eq + Ord + Send + Sync + ' static {
44+ /// KEM decryption key (i.e. private key) which can decrypt encrypted shared secret ciphertexts
45+ /// which were encrypted by [`Kem::EncapsulationKey`].
46+ type DecapsulationKey : TryDecapsulate < Self > + Generate ;
3347
34- /// Key encapsulation mechanism parameters: sizes of the ciphertext and decrypted plaintext.
35- ///
36- /// This trait is impl'd by types that impl either [`Encapsulate`] or [`Decapsulate`] and defines
37- /// the sizes of the encapsulated key and shared secret.
38- pub trait KemParams {
39- /// Size of the ciphertext (a.k.a. "encapsulated key") produced by [`Encapsulate::encapsulate`].
48+ /// KEM encryption key (i.e. public key) which encrypts shared secrets into ciphertexts which
49+ /// can be decrypted by [`Kem::DecapsulationKey`].
50+ type EncapsulationKey : Encapsulate < Self > + Clone + Debug + Eq ;
51+
52+ /// Size of the shared key/secret returned by both encapsulation and decapsulation.
53+ type SharedKeySize : ArraySize ;
54+
55+ /// Size of the ciphertext (a.k.a. "encapsulated key") produced by [`Self::EncapsulationKey`].
4056 type CiphertextSize : ArraySize ;
4157
42- /// Size of the shared secret after decapsulation by [`Decapsulate::decapsulate`].
43- type SharedSecretSize : ArraySize ;
58+ /// Generate a random KEM keypair using the provided random number generator.
59+ fn generate_keypair_from_rng < R : CryptoRng > (
60+ rng : & mut R ,
61+ ) -> ( Self :: DecapsulationKey , Self :: EncapsulationKey ) {
62+ let dk = Self :: DecapsulationKey :: generate_from_rng ( rng) ;
63+ let ek = dk. as_ref ( ) . clone ( ) ;
64+ ( dk, ek)
65+ }
66+
67+ /// Generate a random KEM keypair using the system's secure RNG.
68+ #[ cfg( feature = "getrandom" ) ]
69+ fn generate_keypair ( ) -> ( Self :: DecapsulationKey , Self :: EncapsulationKey ) {
70+ Self :: generate_keypair_from_rng ( & mut UnwrapErr ( SysRng ) )
71+ }
4472}
4573
4674/// Encapsulator for shared secrets.
4775///
4876/// Often, this will just be a public key. However, it can also be a bundle of public keys, or it
4977/// can include a sender's private key for authenticated encapsulation.
50- pub trait Encapsulate : KemParams + TryKeyInit + KeyExport {
51- /// Encapsulates a fresh [`SharedSecret `] generated using the supplied random number
78+ pub trait Encapsulate < K : Kem > : TryKeyInit + KeyExport {
79+ /// Encapsulates a fresh [`SharedKey `] generated using the supplied random number
5280 /// generator `R`.
53- fn encapsulate_with_rng < R > ( & self , rng : & mut R ) -> ( Ciphertext < Self > , SharedSecret < Self > )
81+ fn encapsulate_with_rng < R > ( & self , rng : & mut R ) -> ( Ciphertext < K > , SharedKey < K > )
5482 where
5583 R : CryptoRng + ?Sized ;
5684
5785 /// Encapsulate a fresh shared secret generated using the system's secure RNG.
5886 #[ cfg( feature = "getrandom" ) ]
59- fn encapsulate ( & self ) -> ( Ciphertext < Self > , SharedSecret < Self > ) {
87+ fn encapsulate ( & self ) -> ( Ciphertext < K > , SharedKey < K > ) {
6088 self . encapsulate_with_rng ( & mut UnwrapErr ( SysRng ) )
6189 }
6290}
6391
64- /// Trait for decapsulators, which is a supertrait bound of both [`Decapsulate`] and
65- /// [`TryDecapsulate`].
66- pub trait Decapsulator :
67- KemParams <
68- CiphertextSize = <Self :: Encapsulator as KemParams >:: CiphertextSize ,
69- SharedSecretSize = <Self :: Encapsulator as KemParams >:: SharedSecretSize ,
70- >
71- {
72- /// Encapsulator which corresponds to this decapsulator.
73- type Encapsulator : Encapsulate + Clone + KemParams ;
74-
75- /// Retrieve the encapsulator associated with this decapsulator.
76- fn encapsulator ( & self ) -> & Self :: Encapsulator ;
77- }
78-
79- impl < K : Decapsulator > KemParams for K {
80- type CiphertextSize = <K :: Encapsulator as KemParams >:: CiphertextSize ;
81- type SharedSecretSize = <K :: Encapsulator as KemParams >:: SharedSecretSize ;
82- }
83-
8492/// Decapsulator for encapsulated keys, with an associated `Encapsulator` bounded by the
8593/// [`Encapsulate`] trait.
8694///
@@ -90,15 +98,15 @@ impl<K: Decapsulator> KemParams for K {
9098///
9199/// When possible (i.e. for software / non-HSM implementations) types which impl this trait should
92100/// also impl the [`Generate`] trait to support key generation.
93- pub trait Decapsulate : Decapsulator + TryDecapsulate < Error = Infallible > {
101+ pub trait Decapsulate < K : Kem > : TryDecapsulate < K , Error = Infallible > {
94102 /// Decapsulates the given [`Ciphertext`] a.k.a. "encapsulated key".
95- fn decapsulate ( & self , ct : & Ciphertext < Self > ) -> SharedSecret < Self > ;
103+ fn decapsulate ( & self , ct : & Ciphertext < K > ) -> SharedKey < K > ;
96104
97105 /// Decapsulate the given byte slice containing a [`Ciphertext`] a.k.a. "encapsulated key".
98106 ///
99107 /// # Errors
100108 /// - If the length of `ct` is not equal to `<Self as Kem>::CiphertextSize`.
101- fn decapsulate_slice ( & self , ct : & [ u8 ] ) -> Result < SharedSecret < Self > , TryFromSliceError > {
109+ fn decapsulate_slice ( & self , ct : & [ u8 ] ) -> Result < SharedKey < K > , TryFromSliceError > {
102110 ct. try_into ( ) . map ( |ct| self . decapsulate ( & ct) )
103111 }
104112}
@@ -108,32 +116,33 @@ pub trait Decapsulate: Decapsulator + TryDecapsulate<Error = Infallible> {
108116///
109117/// Prefer to implement the [`Decapsulate`] trait if possible. See that trait's documentation for
110118/// more information.
111- pub trait TryDecapsulate : Decapsulator {
119+ pub trait TryDecapsulate < K : Kem > : AsRef < K :: EncapsulationKey > {
112120 /// Decapsulation error
113121 type Error : core:: error:: Error ;
114122
115123 /// Decapsulates the given [`Ciphertext`] a.k.a. "encapsulated key".
116- fn try_decapsulate ( & self , ct : & Ciphertext < Self > ) -> Result < SharedSecret < Self > , Self :: Error > ;
124+ fn try_decapsulate ( & self , ct : & Ciphertext < K > ) -> Result < SharedKey < K > , Self :: Error > ;
117125
118126 /// Decapsulate the given byte slice containing a [`Ciphertext`] a.k.a. "encapsulated key".
119127 ///
120128 /// # Errors
121129 /// - If the length of `ct` is not equal to `<Self as Kem>::CiphertextSize`.
122- fn try_decapsulate_slice ( & self , ct : & [ u8 ] ) -> Result < SharedSecret < Self > , Self :: Error >
130+ fn try_decapsulate_slice ( & self , ct : & [ u8 ] ) -> Result < SharedKey < K > , Self :: Error >
123131 where
124132 Self :: Error : From < TryFromSliceError > ,
125133 {
126134 self . try_decapsulate ( ct. try_into ( ) ?)
127135 }
128136}
129137
130- impl < D > TryDecapsulate for D
138+ impl < D , K > TryDecapsulate < K > for D
131139where
132- D : Decapsulate ,
140+ D : Decapsulate < K > ,
141+ K : Kem ,
133142{
134143 type Error = Infallible ;
135144
136- fn try_decapsulate ( & self , ct : & Ciphertext < Self > ) -> Result < SharedSecret < Self > , Infallible > {
145+ fn try_decapsulate ( & self , ct : & Ciphertext < K > ) -> Result < SharedKey < K > , Infallible > {
137146 Ok ( self . decapsulate ( ct) )
138147 }
139148}
0 commit comments