@@ -9,6 +9,7 @@ pub trait Kem {
99 const N_PK : usize ;
1010 const N_SK : usize ;
1111 const N_SEED : usize ;
12+ const N_RANDOM : usize ;
1213
1314 type EncapsulationKey ;
1415 type DecapsulationKey ;
@@ -23,21 +24,23 @@ pub trait Kem {
2324 fn deserialize_private_key ( skXm : & [ u8 ] ) -> Self :: DecapsulationKey ;
2425
2526 fn encap ( rng : & mut impl rand:: CryptoRng , pkR : & Self :: EncapsulationKey ) -> ( Vec < u8 > , Vec < u8 > ) ;
27+ fn encap_derand ( pkR : & Self :: EncapsulationKey , randomness : & [ u8 ] ) -> ( Vec < u8 > , Vec < u8 > ) ;
2628 fn decap ( enc : & [ u8 ] , skR : & Self :: DecapsulationKey ) -> Vec < u8 > ;
2729}
2830
2931pub struct KemWithId < K , const ID : u16 > ( core:: marker:: PhantomData < K > ) ;
3032
3133impl < K , const ID : u16 > Kem for KemWithId < K , ID >
3234where
33- K : concrete_hybrid_kem:: Kem ,
35+ K : concrete_hybrid_kem:: Kem + concrete_hybrid_kem :: EncapsDerand ,
3436{
3537 const ID : [ u8 ; 2 ] = ID . to_be_bytes ( ) ;
3638 const N_SECRET : usize = K :: SHARED_SECRET_LENGTH ;
3739 const N_ENC : usize = K :: CIPHERTEXT_LENGTH ;
3840 const N_PK : usize = K :: ENCAPSULATION_KEY_LENGTH ;
3941 const N_SK : usize = K :: DECAPSULATION_KEY_LENGTH ;
4042 const N_SEED : usize = K :: SEED_LENGTH ;
43+ const N_RANDOM : usize = K :: RANDOMNESS_LENGTH ;
4144
4245 type EncapsulationKey = <K as concrete_hybrid_kem:: Kem >:: EncapsulationKey ;
4346 type DecapsulationKey = <K as concrete_hybrid_kem:: Kem >:: DecapsulationKey ;
7881 ( ss. as_bytes ( ) . to_vec ( ) , ct. as_bytes ( ) . to_vec ( ) )
7982 }
8083
84+ fn encap_derand ( pkR : & Self :: EncapsulationKey , randomness : & [ u8 ] ) -> ( Vec < u8 > , Vec < u8 > ) {
85+ use concrete_hybrid_kem:: AsBytes ;
86+ let ( ct, ss) = <K as concrete_hybrid_kem:: EncapsDerand >:: encaps_derand ( pkR, randomness) . unwrap ( ) ;
87+ ( ss. as_bytes ( ) . to_vec ( ) , ct. as_bytes ( ) . to_vec ( ) )
88+ }
89+
8190 fn decap ( enc : & [ u8 ] , skR : & Self :: DecapsulationKey ) -> Vec < u8 > {
8291 use concrete_hybrid_kem:: AsBytes ;
8392 let enc = K :: Ciphertext :: from ( enc) ;
@@ -92,14 +101,15 @@ pub struct MlKemWithId<K, const ID: u16>(core::marker::PhantomData<K>);
92101
93102impl < K , const ID : u16 > Kem for MlKemWithId < K , ID >
94103where
95- K : concrete_hybrid_kem:: Kem ,
104+ K : concrete_hybrid_kem:: Kem + concrete_hybrid_kem :: EncapsDerand ,
96105{
97106 const ID : [ u8 ; 2 ] = ID . to_be_bytes ( ) ;
98107 const N_SECRET : usize = K :: SHARED_SECRET_LENGTH ;
99108 const N_ENC : usize = K :: CIPHERTEXT_LENGTH ;
100109 const N_PK : usize = K :: ENCAPSULATION_KEY_LENGTH ;
101110 const N_SK : usize = K :: SEED_LENGTH ; // Use seed length for ML-KEM per spec
102111 const N_SEED : usize = K :: SEED_LENGTH ;
112+ const N_RANDOM : usize = K :: RANDOMNESS_LENGTH ;
103113
104114 type EncapsulationKey = <K as concrete_hybrid_kem:: Kem >:: EncapsulationKey ;
105115 type DecapsulationKey = <K as concrete_hybrid_kem:: Kem >:: DecapsulationKey ;
@@ -140,6 +150,12 @@ where
140150 ( ss. as_bytes ( ) . to_vec ( ) , ct. as_bytes ( ) . to_vec ( ) )
141151 }
142152
153+ fn encap_derand ( pkR : & Self :: EncapsulationKey , randomness : & [ u8 ] ) -> ( Vec < u8 > , Vec < u8 > ) {
154+ use concrete_hybrid_kem:: AsBytes ;
155+ let ( ct, ss) = <K as concrete_hybrid_kem:: EncapsDerand >:: encaps_derand ( pkR, randomness) . unwrap ( ) ;
156+ ( ss. as_bytes ( ) . to_vec ( ) , ct. as_bytes ( ) . to_vec ( ) )
157+ }
158+
143159 fn decap ( enc : & [ u8 ] , skR : & Self :: DecapsulationKey ) -> Vec < u8 > {
144160 use concrete_hybrid_kem:: AsBytes ;
145161 let enc = K :: Ciphertext :: from ( enc) ;
@@ -513,6 +529,7 @@ where
513529 const N_PK : usize = C :: POINT_SIZE ;
514530 const N_SK : usize = C :: SCALAR_SIZE ;
515531 const N_SEED : usize = C :: SCALAR_SIZE ;
532+ const N_RANDOM : usize = C :: SCALAR_SIZE ;
516533
517534 type EncapsulationKey = C :: Point ;
518535 type DecapsulationKey = C :: Scalar ;
@@ -557,6 +574,20 @@ where
557574 ( shared_secret, enc)
558575 }
559576
577+ fn encap_derand ( pkR : & Self :: EncapsulationKey , randomness : & [ u8 ] ) -> ( Vec < u8 > , Vec < u8 > ) {
578+ use crate :: concat;
579+
580+ let ( skE, pkE) = Self :: derive_key_pair ( randomness) ;
581+ let dh = C :: dh ( & skE, pkR) ;
582+ let enc = Self :: serialize_public_key ( & pkE) ;
583+
584+ let pkRm = Self :: serialize_public_key ( pkR) ;
585+ let kem_context = concat ( & [ & enc, & pkRm] ) ;
586+
587+ let shared_secret = K :: extract_and_expand ( C :: SUITE_ID , & dh, & kem_context, Self :: N_SECRET ) ;
588+ ( shared_secret, enc)
589+ }
590+
560591 fn decap ( enc : & [ u8 ] , skR : & Self :: DecapsulationKey ) -> Vec < u8 > {
561592 use crate :: concat;
562593
0 commit comments