1818//! the generic `ml-kem` abstractions into the existing OPAQUE key-exchange
1919//! pipeline.
2020
21- use core:: convert:: TryFrom ;
2221use core:: fmt:: Debug ;
2322use core:: marker:: PhantomData ;
2423use core:: ops:: Add ;
@@ -29,9 +28,11 @@ use digest::{Digest, Output};
2928use generic_array:: sequence:: Concat ;
3029use generic_array:: typenum:: { IsLess , Le , NonZero , Sum , U256 } ;
3130use generic_array:: { ArrayLength , GenericArray } ;
32- use ml_kem:: kem:: { Decapsulate , Encapsulate } ;
33- use ml_kem:: {
34- Ciphertext as MlKemCiphertext , Encoded , EncodedSizeUser , KemCore , SharedKey as MlKemSharedKey ,
31+ #[ allow( deprecated) ]
32+ use ml_kem:: ExpandedKeyEncoding ;
33+ use ml_kem:: kem:: {
34+ Ciphertext as MlKemCiphertext , Decapsulate , Encapsulate , Kem as MlKemTrait , KeyExport ,
35+ KeySizeUser , TryKeyInit ,
3536} ;
3637use rand:: { CryptoRng , RngCore } ;
3738use subtle:: { ConstantTimeEq , CtOption } ;
@@ -44,7 +45,7 @@ use super::{
4445 SerializedIdentifiers ,
4546} ;
4647use crate :: ciphersuite:: { CipherSuite , KeGroup } ;
47- use crate :: errors:: { InternalError , ProtocolError } ;
48+ use crate :: errors:: ProtocolError ;
4849use crate :: hash:: { Hash , OutputSize , ProxyHash } ;
4950use crate :: key_exchange:: group:: Group ;
5051use crate :: keypair:: { PrivateKey , PublicKey } ;
@@ -115,16 +116,42 @@ pub trait KemCoreWrapper {
115116 ) -> Result < GenericArray < u8 , Self :: SharedSecretLen > , ProtocolError > ;
116117}
117118
118- type RcEncapsulationKeyLen < K > = <<K as KemCore >:: EncapsulationKey as EncodedSizeUser >:: EncodedSize ;
119- type RcDecapsulationKeyLen < K > = <<K as KemCore >:: DecapsulationKey as EncodedSizeUser >:: EncodedSize ;
120- type RcCiphertextLen < K > = <K as KemCore >:: CiphertextSize ;
121- type RcSharedSecretLen < K > = <K as KemCore >:: SharedKeySize ;
119+ /// Adapter to bridge `rand 0.8` (`rand_core 0.6`) RNGs to `rand_core 0.10`
120+ /// which is required by `ml-kem 0.3.x`.
121+ struct RngCompat < ' a , R > ( & ' a mut R ) ;
122122
123+ impl < R : RngCore > rand_core_10:: TryRng for RngCompat < ' _ , R > {
124+ type Error = core:: convert:: Infallible ;
125+
126+ fn try_next_u32 ( & mut self ) -> Result < u32 , Self :: Error > {
127+ Ok ( self . 0 . next_u32 ( ) )
128+ }
129+
130+ fn try_next_u64 ( & mut self ) -> Result < u64 , Self :: Error > {
131+ Ok ( self . 0 . next_u64 ( ) )
132+ }
133+
134+ fn try_fill_bytes ( & mut self , dst : & mut [ u8 ] ) -> Result < ( ) , Self :: Error > {
135+ self . 0 . fill_bytes ( dst) ;
136+ Ok ( ( ) )
137+ }
138+ }
139+
140+ impl < R : RngCore + CryptoRng > rand_core_10:: TryCryptoRng for RngCompat < ' _ , R > { }
141+
142+ type RcEncapsulationKeyLen < K > = <<K as MlKemTrait >:: EncapsulationKey as KeySizeUser >:: KeySize ;
143+ #[ allow( deprecated) ]
144+ type RcDecapsulationKeyLen < K > =
145+ <<K as MlKemTrait >:: DecapsulationKey as ExpandedKeyEncoding >:: EncodedSize ;
146+ type RcCiphertextLen < K > = <K as MlKemTrait >:: CiphertextSize ;
147+ type RcSharedSecretLen < K > = <K as MlKemTrait >:: SharedKeySize ;
148+
149+ #[ allow( deprecated) ]
123150impl < K > KemCoreWrapper for K
124151where
125- K : KemCore ,
126- K :: EncapsulationKey : Encapsulate < MlKemCiphertext < K > , MlKemSharedKey < K > > + Clone ,
127- K :: DecapsulationKey : Decapsulate < MlKemCiphertext < K > , MlKemSharedKey < K > > + Clone + ZeroizeOnDrop ,
152+ K : MlKemTrait ,
153+ K :: EncapsulationKey : Encapsulate < Kem = K > + KeyExport + TryKeyInit + Clone ,
154+ K :: DecapsulationKey : Decapsulate < Kem = K > + ExpandedKeyEncoding + Clone + ZeroizeOnDrop ,
128155 RcEncapsulationKeyLen < K > : ArrayLength < u8 > ,
129156 RcDecapsulationKeyLen < K > : ArrayLength < u8 > ,
130157 RcCiphertextLen < K > : ArrayLength < u8 > ,
@@ -140,39 +167,40 @@ where
140167 fn generate < R : RngCore + CryptoRng > (
141168 rng : & mut R ,
142169 ) -> Result < ( Self :: DecapsulationKey , Self :: EncapsulationKey ) , ProtocolError > {
143- Ok ( K :: generate ( rng) )
170+ Ok ( K :: generate_keypair_from_rng ( & mut RngCompat ( rng) ) )
144171 }
145172
146173 fn serialize_encapsulation_key (
147174 key : & Self :: EncapsulationKey ,
148175 ) -> GenericArray < u8 , Self :: EncapsulationKeyLen > {
149- GenericArray :: clone_from_slice ( key. as_bytes ( ) . as_slice ( ) )
176+ GenericArray :: clone_from_slice ( key. to_bytes ( ) . as_slice ( ) )
150177 }
151178
152179 fn deserialize_encapsulation_key (
153180 input : & mut & [ u8 ] ,
154181 ) -> Result < Self :: EncapsulationKey , ProtocolError > {
155182 let bytes: GenericArray < u8 , RcEncapsulationKeyLen < K > > =
156183 input. take_array ( "kem encapsulation key" ) ?;
157- let encoded = Encoded :: < K :: EncapsulationKey > :: try_from ( bytes. as_slice ( ) )
184+ let key = ml_kem :: array :: Array :: try_from ( bytes. as_slice ( ) )
158185 . map_err ( |_| ProtocolError :: SerializationError ) ?;
159- Ok ( K :: EncapsulationKey :: from_bytes ( & encoded ) )
186+ TryKeyInit :: new ( & key ) . map_err ( |_| ProtocolError :: SerializationError )
160187 }
161188
162189 fn serialize_decapsulation_key (
163190 key : & Self :: DecapsulationKey ,
164191 ) -> GenericArray < u8 , Self :: DecapsulationKeyLen > {
165- GenericArray :: clone_from_slice ( key. as_bytes ( ) . as_slice ( ) )
192+ GenericArray :: clone_from_slice ( key. to_expanded_bytes ( ) . as_slice ( ) )
166193 }
167194
168195 fn deserialize_decapsulation_key (
169196 input : & mut & [ u8 ] ,
170197 ) -> Result < Self :: DecapsulationKey , ProtocolError > {
171198 let bytes: GenericArray < u8 , RcDecapsulationKeyLen < K > > =
172199 input. take_array ( "kem decapsulation key" ) ?;
173- let encoded = Encoded :: < K :: DecapsulationKey > :: try_from ( bytes. as_slice ( ) )
200+ let key = ml_kem :: array :: Array :: try_from ( bytes. as_slice ( ) )
174201 . map_err ( |_| ProtocolError :: SerializationError ) ?;
175- Ok ( K :: DecapsulationKey :: from_bytes ( & encoded) )
202+ K :: DecapsulationKey :: from_expanded_bytes ( & key)
203+ . map_err ( |_| ProtocolError :: SerializationError )
176204 }
177205
178206 fn encapsulate < R : RngCore + CryptoRng > (
@@ -185,14 +213,11 @@ where
185213 ) ,
186214 ProtocolError ,
187215 > {
188- key. encapsulate ( rng)
189- . map ( |( ciphertext, shared) | {
190- (
191- GenericArray :: clone_from_slice ( ciphertext. as_slice ( ) ) ,
192- GenericArray :: clone_from_slice ( shared. as_slice ( ) ) ,
193- )
194- } )
195- . map_err ( |_| ProtocolError :: LibraryError ( InternalError :: KemError ) )
216+ let ( ciphertext, shared) = key. encapsulate_with_rng ( & mut RngCompat ( rng) ) ;
217+ Ok ( (
218+ GenericArray :: clone_from_slice ( ciphertext. as_slice ( ) ) ,
219+ GenericArray :: clone_from_slice ( shared. as_slice ( ) ) ,
220+ ) )
196221 }
197222
198223 fn decapsulate (
@@ -201,9 +226,8 @@ where
201226 ) -> Result < GenericArray < u8 , Self :: SharedSecretLen > , ProtocolError > {
202227 let ciphertext = MlKemCiphertext :: < K > :: try_from ( encapsulated_key. as_slice ( ) )
203228 . map_err ( |_| ProtocolError :: SerializationError ) ?;
204- key. decapsulate ( & ciphertext)
205- . map ( |shared| GenericArray :: clone_from_slice ( shared. as_slice ( ) ) )
206- . map_err ( |_| ProtocolError :: LibraryError ( InternalError :: KemError ) )
229+ let shared = key. decapsulate ( & ciphertext) ;
230+ Ok ( GenericArray :: clone_from_slice ( shared. as_slice ( ) ) )
207231 }
208232}
209233/// Triple Diffie-Hellman-style key exchange that offloads the second hop to a
0 commit comments