@@ -9,6 +9,7 @@ pub trait Kem {
9
9
const N_PK : usize ;
10
10
const N_SK : usize ;
11
11
const N_SEED : usize ;
12
+ const N_RANDOM : usize ;
12
13
13
14
type EncapsulationKey ;
14
15
type DecapsulationKey ;
@@ -23,21 +24,23 @@ pub trait Kem {
23
24
fn deserialize_private_key ( skXm : & [ u8 ] ) -> Self :: DecapsulationKey ;
24
25
25
26
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 > ) ;
26
28
fn decap ( enc : & [ u8 ] , skR : & Self :: DecapsulationKey ) -> Vec < u8 > ;
27
29
}
28
30
29
31
pub struct KemWithId < K , const ID : u16 > ( core:: marker:: PhantomData < K > ) ;
30
32
31
33
impl < K , const ID : u16 > Kem for KemWithId < K , ID >
32
34
where
33
- K : concrete_hybrid_kem:: Kem ,
35
+ K : concrete_hybrid_kem:: Kem + concrete_hybrid_kem :: EncapsDerand ,
34
36
{
35
37
const ID : [ u8 ; 2 ] = ID . to_be_bytes ( ) ;
36
38
const N_SECRET : usize = K :: SHARED_SECRET_LENGTH ;
37
39
const N_ENC : usize = K :: CIPHERTEXT_LENGTH ;
38
40
const N_PK : usize = K :: ENCAPSULATION_KEY_LENGTH ;
39
41
const N_SK : usize = K :: DECAPSULATION_KEY_LENGTH ;
40
42
const N_SEED : usize = K :: SEED_LENGTH ;
43
+ const N_RANDOM : usize = K :: RANDOMNESS_LENGTH ;
41
44
42
45
type EncapsulationKey = <K as concrete_hybrid_kem:: Kem >:: EncapsulationKey ;
43
46
type DecapsulationKey = <K as concrete_hybrid_kem:: Kem >:: DecapsulationKey ;
78
81
( ss. as_bytes ( ) . to_vec ( ) , ct. as_bytes ( ) . to_vec ( ) )
79
82
}
80
83
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
+
81
90
fn decap ( enc : & [ u8 ] , skR : & Self :: DecapsulationKey ) -> Vec < u8 > {
82
91
use concrete_hybrid_kem:: AsBytes ;
83
92
let enc = K :: Ciphertext :: from ( enc) ;
@@ -92,14 +101,15 @@ pub struct MlKemWithId<K, const ID: u16>(core::marker::PhantomData<K>);
92
101
93
102
impl < K , const ID : u16 > Kem for MlKemWithId < K , ID >
94
103
where
95
- K : concrete_hybrid_kem:: Kem ,
104
+ K : concrete_hybrid_kem:: Kem + concrete_hybrid_kem :: EncapsDerand ,
96
105
{
97
106
const ID : [ u8 ; 2 ] = ID . to_be_bytes ( ) ;
98
107
const N_SECRET : usize = K :: SHARED_SECRET_LENGTH ;
99
108
const N_ENC : usize = K :: CIPHERTEXT_LENGTH ;
100
109
const N_PK : usize = K :: ENCAPSULATION_KEY_LENGTH ;
101
110
const N_SK : usize = K :: SEED_LENGTH ; // Use seed length for ML-KEM per spec
102
111
const N_SEED : usize = K :: SEED_LENGTH ;
112
+ const N_RANDOM : usize = K :: RANDOMNESS_LENGTH ;
103
113
104
114
type EncapsulationKey = <K as concrete_hybrid_kem:: Kem >:: EncapsulationKey ;
105
115
type DecapsulationKey = <K as concrete_hybrid_kem:: Kem >:: DecapsulationKey ;
@@ -140,6 +150,12 @@ where
140
150
( ss. as_bytes ( ) . to_vec ( ) , ct. as_bytes ( ) . to_vec ( ) )
141
151
}
142
152
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
+
143
159
fn decap ( enc : & [ u8 ] , skR : & Self :: DecapsulationKey ) -> Vec < u8 > {
144
160
use concrete_hybrid_kem:: AsBytes ;
145
161
let enc = K :: Ciphertext :: from ( enc) ;
@@ -513,6 +529,7 @@ where
513
529
const N_PK : usize = C :: POINT_SIZE ;
514
530
const N_SK : usize = C :: SCALAR_SIZE ;
515
531
const N_SEED : usize = C :: SCALAR_SIZE ;
532
+ const N_RANDOM : usize = C :: SCALAR_SIZE ;
516
533
517
534
type EncapsulationKey = C :: Point ;
518
535
type DecapsulationKey = C :: Scalar ;
@@ -557,6 +574,20 @@ where
557
574
( shared_secret, enc)
558
575
}
559
576
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
+
560
591
fn decap ( enc : & [ u8 ] , skR : & Self :: DecapsulationKey ) -> Vec < u8 > {
561
592
use crate :: concat;
562
593
0 commit comments