1+ use crate :: FixedSeedRNG ;
12use bouncycastle_core:: errors:: KEMError ;
2- use bouncycastle_core:: traits:: { KEMDecapsulator , KEMEncapsulator , KEMPrivateKey , KEMPublicKey } ;
3+ use bouncycastle_core:: traits:: {
4+ KEMDecapsulator , KEMEncapsulator , KEMPrivateKey , KEMPublicKey , RNG , SecurityStrength ,
5+ } ;
36
47pub struct TestFrameworkKEM {
58 // Put any config options here
@@ -24,8 +27,7 @@ impl TestFrameworkKEM {
2427 pub fn test_kem <
2528 PK : KEMPublicKey < PK_LEN > ,
2629 SK : KEMPrivateKey < SK_LEN > ,
27- ENCAPSULATOR : KEMEncapsulator < PK , PK_LEN , CT_LEN , SS_LEN > ,
28- DECAPSULATOR : KEMDecapsulator < SK , SK_LEN , CT_LEN , SS_LEN > ,
30+ KEMAlg : KEMEncapsulator < PK , PK_LEN , CT_LEN , SS_LEN > + KEMDecapsulator < SK , SK_LEN , CT_LEN , SS_LEN > ,
2931 const PK_LEN : usize ,
3032 const SK_LEN : usize ,
3133 const CT_LEN : usize ,
@@ -37,27 +39,45 @@ impl TestFrameworkKEM {
3739 ) {
3840 // Basic test
3941 let ( pk, sk) = keygen ( ) . unwrap ( ) ;
40- let ( ss, ct) = ENCAPSULATOR :: encaps ( & pk) . unwrap ( ) ;
41- let ss1 = DECAPSULATOR :: decaps ( & sk, & ct) . unwrap ( ) ;
42+ let ( ss, ct) = KEMAlg :: encaps ( & pk) . unwrap ( ) ;
43+ let ss1 = KEMAlg :: decaps ( & sk, & ct) . unwrap ( ) ;
4244 assert_eq ! ( ss, ss1) ;
4345
46+ // Test that encaps_rng is deterministic in its RNG input: two encapsulations against the
47+ // same public key, each fed an RNG that emits identical bytes, must produce the same
48+ // shared secret and ciphertext.
49+ {
50+ let mut rng_a = FixedSeedRNG :: new ( [ 0x5A ; 64 ] ) ;
51+ let mut rng_b = FixedSeedRNG :: new ( [ 0x5A ; 64 ] ) ;
52+ let ( ss_a, ct_a) = KEMAlg :: encaps_rng ( & pk, & mut rng_a) . unwrap ( ) ;
53+ let ( ss_b, ct_b) = KEMAlg :: encaps_rng ( & pk, & mut rng_b) . unwrap ( ) ;
54+ assert_eq ! (
55+ ss_a, ss_b,
56+ "encaps_rng shared secret must be deterministic given fixed RNG output"
57+ ) ;
58+ assert_eq ! (
59+ ct_a, ct_b,
60+ "encaps_rng ciphertext must be deterministic given fixed RNG output"
61+ ) ;
62+ }
63+
4464 // Test non-determinism
4565 if !self . alg_is_deterministic {
46- let ( ss1, ct1) = ENCAPSULATOR :: encaps ( & pk) . unwrap ( ) ;
47- let ( ss2, ct2) = ENCAPSULATOR :: encaps ( & pk) . unwrap ( ) ;
66+ let ( ss1, ct1) = KEMAlg :: encaps ( & pk) . unwrap ( ) ;
67+ let ( ss2, ct2) = KEMAlg :: encaps ( & pk) . unwrap ( ) ;
4868 assert_ne ! ( ss1, ss2) ;
4969 assert_ne ! ( ct1, ct2) ;
5070 }
5171
5272 // Test that decaps fails for broken ct value
5373 let ( pk, sk) = keygen ( ) . unwrap ( ) ;
54- let ( ss, mut ct) = ENCAPSULATOR :: encaps ( & pk) . unwrap ( ) ;
74+ let ( ss, mut ct) = KEMAlg :: encaps ( & pk) . unwrap ( ) ;
5575 ct[ 17 ] ^= 0xFF ;
5676 if self . is_implicitly_rejecting {
57- let ss2 = DECAPSULATOR :: decaps ( & sk, & ct) . unwrap ( ) ;
77+ let ss2 = KEMAlg :: decaps ( & sk, & ct) . unwrap ( ) ;
5878 assert_ne ! ( ss, ss2) ;
5979 } else {
60- match DECAPSULATOR :: decaps ( & sk, & ct) {
80+ match KEMAlg :: decaps ( & sk, & ct) {
6181 Err ( KEMError :: DecapsulationFailed ) =>
6282 /* good */
6383 {
@@ -76,10 +96,10 @@ impl TestFrameworkKEM {
7696
7797 // should throw an Err
7898 if self . is_implicitly_rejecting {
79- let ss2 = DECAPSULATOR :: decaps ( & sk, & ct_copy) . unwrap ( ) ;
99+ let ss2 = KEMAlg :: decaps ( & sk, & ct_copy) . unwrap ( ) ;
80100 assert_ne ! ( ss, ss2) ;
81101 } else {
82- match DECAPSULATOR :: decaps ( & sk, & ct) {
102+ match KEMAlg :: decaps ( & sk, & ct) {
83103 Err ( KEMError :: DecapsulationFailed ) =>
84104 /* good */
85105 {
@@ -94,20 +114,29 @@ impl TestFrameworkKEM {
94114
95115 // test ct the wrong length
96116 let ( pk, sk) = keygen ( ) . unwrap ( ) ;
97- let ( _ss, ct) = ENCAPSULATOR :: encaps ( & pk) . unwrap ( ) ;
117+ let ( _ss, ct) = KEMAlg :: encaps ( & pk) . unwrap ( ) ;
98118 // too short
99- match DECAPSULATOR :: decaps ( & sk, & ct[ ..CT_LEN - 1 ] ) {
119+ match KEMAlg :: decaps ( & sk, & ct[ ..CT_LEN - 1 ] ) {
100120 Err ( KEMError :: LengthError ( _) ) => { /* good */ }
101121 _ => panic ! ( "This should have thrown an error but it didn't." ) ,
102122 } ;
103123
104124 // too long
105125 let mut long_ct = vec ! [ 1u8 ; CT_LEN + 2 ] ;
106126 long_ct. as_mut_slice ( ) [ ..CT_LEN ] . copy_from_slice ( & ct) ;
107- match DECAPSULATOR :: decaps ( & sk, & long_ct) {
127+ match KEMAlg :: decaps ( & sk, & long_ct) {
108128 Err ( KEMError :: LengthError ( _) ) => { /* good */ }
109129 _ => panic ! ( "This should have thrown an error but it didn't." ) ,
110130 } ;
131+
132+ // encaps_rng should reject an RNG at a lower security level than the KEM
133+ let mut no_security_rng = FixedSeedRNG :: new ( [ 0x00 ; 64 ] ) ;
134+ no_security_rng. set_security_strength ( SecurityStrength :: None ) ;
135+ assert_eq ! ( no_security_rng. security_strength( ) , SecurityStrength :: None ) ;
136+ match KEMAlg :: encaps_rng ( & pk, & mut no_security_rng) {
137+ Err ( KEMError :: RNGError ( _) ) => { /* good */ }
138+ _ => panic ! ( "This should have thrown an error but it didn't." ) ,
139+ }
111140 }
112141}
113142
0 commit comments