@@ -22,6 +22,7 @@ newtype_buffer!(PublicKey, PublicKeyRef);
2222newtype_buffer ! ( SecretKey , SecretKeyRef ) ;
2323newtype_buffer ! ( Ciphertext , CiphertextRef ) ;
2424newtype_buffer ! ( SharedSecret , SharedSecretRef ) ;
25+ newtype_buffer ! ( KeypairSeed , KeypairSeedRef ) ;
2526
2627macro_rules! implement_kems {
2728 { $( ( $feat: literal) $kem: ident: $oqs_id: ident) ,* $( , ) ? } => (
@@ -69,6 +70,36 @@ macro_rules! implement_kems {
6970 Ok ( ( ) )
7071 }
7172
73+ #[ test]
74+ #[ cfg( feature = $feat) ]
75+ fn test_encaps_decaps_derand( ) -> Result <( ) > {
76+ use crate :: ffi:: rand:: OQS_randombytes ;
77+ crate :: init( ) ;
78+
79+ let alg = Algorithm :: $kem;
80+ let kem = Kem :: new( alg) ?;
81+ let mut seed = KeypairSeed {
82+ bytes: Vec :: with_capacity( kem. length_keypair_seed( ) ) ,
83+ } ;
84+ unsafe {
85+ // On some systems, getentropy fails if given a zero-length array
86+ if ( kem. length_keypair_seed( ) > 0 ) {
87+ OQS_randombytes ( seed. bytes. as_mut_ptr( ) , kem. length_keypair_seed( ) ) ;
88+ }
89+ seed. bytes. set_len( kem. length_keypair_seed( ) ) ;
90+ }
91+ let result = kem. keypair_derand( & seed) ;
92+ // expect Error::Error for KEMs with this API disabled
93+ if ( kem. length_keypair_seed( ) == 0 ) {
94+ return result. map_or_else( |e| { match e { Error :: Error => Ok ( ( ) ) , _ => Err ( Error :: Error ) } } , |_| Err ( Error :: Error ) ) ;
95+ }
96+ let ( pk, sk) = result?;
97+ let ( ct, ss1) = kem. encapsulate( & pk) ?;
98+ let ss2 = kem. decapsulate( & sk, & ct) ?;
99+ assert_eq!( ss1, ss2, "shared secret not equal!" ) ;
100+ Ok ( ( ) )
101+ }
102+
72103 #[ test]
73104 fn test_enabled( ) {
74105 crate :: init( ) ;
@@ -270,6 +301,12 @@ impl Kem {
270301 kem. length_shared_secret
271302 }
272303
304+ /// Get the length of a keypair seed
305+ pub fn length_keypair_seed ( & self ) -> usize {
306+ let kem = unsafe { self . kem . as_ref ( ) } ;
307+ kem. length_keypair_seed
308+ }
309+
273310 /// Obtain a secret key objects from bytes
274311 ///
275312 /// Returns None if the secret key is not the correct length.
@@ -314,6 +351,17 @@ impl Kem {
314351 }
315352 }
316353
354+ /// Obtain a keypair seed from bytes
355+ ///
356+ /// Returns None if the shared secret is not the correct length.
357+ pub fn keypair_seed_from_bytes < ' a > ( & self , buf : & ' a [ u8 ] ) -> Option < KeypairSeedRef < ' a > > {
358+ if self . length_keypair_seed ( ) != buf. len ( ) {
359+ None
360+ } else {
361+ Some ( KeypairSeedRef :: new ( buf) )
362+ }
363+ }
364+
317365 /// Generate a new keypair
318366 pub fn keypair ( & self ) -> Result < ( PublicKey , SecretKey ) > {
319367 let kem = unsafe { self . kem . as_ref ( ) } ;
@@ -335,6 +383,40 @@ impl Kem {
335383 Ok ( ( pk, sk) )
336384 }
337385
386+ /// Generate a new keypair from a seed
387+ pub fn keypair_derand < ' a , S : Into < KeypairSeedRef < ' a > > > (
388+ & self ,
389+ seed : S ,
390+ ) -> Result < ( PublicKey , SecretKey ) > {
391+ let seed = seed. into ( ) ;
392+ if seed. bytes . len ( ) != self . length_keypair_seed ( ) {
393+ return Err ( Error :: InvalidLength ) ;
394+ }
395+ let kem = unsafe { self . kem . as_ref ( ) } ;
396+ let func = kem. keypair_derand . unwrap ( ) ;
397+ let mut pk = PublicKey {
398+ bytes : Vec :: with_capacity ( kem. length_public_key ) ,
399+ } ;
400+ let mut sk = SecretKey {
401+ bytes : Vec :: with_capacity ( kem. length_secret_key ) ,
402+ } ;
403+ let status = unsafe {
404+ func (
405+ pk. bytes . as_mut_ptr ( ) ,
406+ sk. bytes . as_mut_ptr ( ) ,
407+ seed. bytes . as_ptr ( ) ,
408+ )
409+ } ;
410+ status_to_result ( status) ?;
411+ // update the lengths of the vecs
412+ // this is safe to do, as we have initialised them now.
413+ unsafe {
414+ pk. bytes . set_len ( kem. length_public_key ) ;
415+ sk. bytes . set_len ( kem. length_secret_key ) ;
416+ }
417+ Ok ( ( pk, sk) )
418+ }
419+
338420 /// Encapsulate to the provided public key
339421 pub fn encapsulate < ' a , P : Into < PublicKeyRef < ' a > > > (
340422 & self ,
0 commit comments