@@ -804,6 +804,26 @@ impl Builder {
804804 }
805805 }
806806
807+ /// Create a new [Multikey] from a seed.
808+ ///
809+ /// Currently only supports [Codec::Ed25519Priv] seeds.
810+ pub fn new_from_seed ( codec : Codec , seed : & [ u8 ] ) -> Result < Self , Error > {
811+ match codec {
812+ Codec :: Ed25519Priv => {
813+ let keypair =
814+ ssh_key:: private:: Ed25519Keypair :: from_seed ( seed. try_into ( ) . map_err ( |_| {
815+ ConversionsError :: UnsupportedAlgorithm (
816+ "Ed25519 seed must be 32 bytes long" . to_string ( ) ,
817+ )
818+ } ) ?) ;
819+ let private_key = PrivateKey :: try_from ( KeypairData :: Ed25519 ( keypair) )
820+ . map_err ( |e| ConversionsError :: Ssh ( e. into ( ) ) ) ?;
821+ Self :: new_from_ssh_private_key ( & private_key)
822+ }
823+ _ => Err ( ConversionsError :: UnsupportedCodec ( codec) . into ( ) ) ,
824+ }
825+ }
826+
807827 /// add an encoding
808828 pub fn with_base_encoding ( mut self , base : Base ) -> Self {
809829 self . base_encoding = Some ( base) ;
@@ -1365,4 +1385,24 @@ mod tests {
13651385 assert_eq ! ( mk1, mk2) ;
13661386 assert ! ( mk2. is_null( ) ) ;
13671387 }
1388+
1389+ #[ test]
1390+ fn test_from_seed ( ) {
1391+ let seed = hex:: decode ( "f9ddcd5118319cc69e6985ef3f4ee3b6c591d46255e1ae5569c8662111b7d3c2" )
1392+ . unwrap ( ) ;
1393+ let mk = Builder :: new_from_seed ( Codec :: Ed25519Priv , seed. as_slice ( ) )
1394+ . unwrap ( )
1395+ . with_comment ( "test key" )
1396+ . try_build ( )
1397+ . unwrap ( ) ;
1398+ let attr = mk. attr_view ( ) . unwrap ( ) ;
1399+ assert_eq ! ( mk. codec( ) , Codec :: Ed25519Priv ) ;
1400+ assert_eq ! ( mk. comment, "test key" . to_string( ) ) ;
1401+ assert ! ( !attr. is_encrypted( ) ) ;
1402+ assert ! ( !attr. is_public_key( ) ) ;
1403+ assert ! ( attr. is_secret_key( ) ) ;
1404+ let kd = mk. data_view ( ) . unwrap ( ) ;
1405+ assert ! ( kd. key_bytes( ) . is_ok( ) ) ;
1406+ assert ! ( kd. secret_bytes( ) . is_ok( ) ) ;
1407+ }
13681408}
0 commit comments