@@ -12,7 +12,7 @@ use crate::{private::Ed25519Keypair, public::Ed25519PublicKey};
1212#[ cfg( feature = "dsa" ) ]
1313use {
1414 crate :: { private:: DsaKeypair , public:: DsaPublicKey } ,
15- sha1:: { Digest , Sha1 } ,
15+ sha1:: Sha1 ,
1616 signature:: { DigestSigner , DigestVerifier , Signature as _} ,
1717} ;
1818
@@ -26,11 +26,19 @@ use crate::{
2626#[ cfg( feature = "rsa" ) ]
2727use {
2828 crate :: { private:: RsaKeypair , public:: RsaPublicKey , HashAlg } ,
29- sha2:: { Sha256 , Sha512 } ,
29+ sha2:: Sha512 ,
3030} ;
3131
32+ #[ cfg( any( feature = "ed25519" , feature = "rsa" ) ) ]
33+ use sha2:: Sha256 ;
34+
35+ #[ cfg( any( feature = "dsa" , feature = "ed25519" ) ) ]
36+ use sha2:: Digest ;
37+
3238const DSA_SIGNATURE_SIZE : usize = 40 ;
3339const ED25519_SIGNATURE_SIZE : usize = 64 ;
40+ const SK_ED25519_SIGNATURE_TRAILER_SIZE : usize = 5 ; // flags(u8), counter(u32)
41+ const SK_ED25519_SIGNATURE_SIZE : usize = ED25519_SIGNATURE_SIZE + SK_ED25519_SIGNATURE_TRAILER_SIZE ;
3442
3543/// Trait for signing keys which produce a [`Signature`].
3644///
@@ -115,6 +123,7 @@ impl Signature {
115123 }
116124 }
117125 Algorithm :: Ed25519 if data. len ( ) == ED25519_SIGNATURE_SIZE => ( ) ,
126+ Algorithm :: SkEd25519 if data. len ( ) == SK_ED25519_SIGNATURE_SIZE => ( ) ,
118127 Algorithm :: Rsa { hash : Some ( _) } => ( ) ,
119128 _ => return Err ( encoding:: Error :: Length . into ( ) ) ,
120129 }
@@ -159,7 +168,16 @@ impl Decode for Signature {
159168
160169 fn decode ( reader : & mut impl Reader ) -> Result < Self > {
161170 let algorithm = Algorithm :: decode ( reader) ?;
162- let data = Vec :: decode ( reader) ?;
171+ let mut data = Vec :: decode ( reader) ?;
172+
173+ if algorithm == Algorithm :: SkEd25519 {
174+ let flags = u8:: decode ( reader) ?;
175+ let counter = u32:: decode ( reader) ?;
176+
177+ data. push ( flags) ;
178+ data. extend ( counter. to_be_bytes ( ) ) ;
179+ }
180+
163181 Self :: new ( algorithm, data)
164182 }
165183}
@@ -181,7 +199,19 @@ impl Encode for Signature {
181199 }
182200
183201 self . algorithm ( ) . encode ( writer) ?;
184- self . as_bytes ( ) . encode ( writer) ?;
202+
203+ if self . algorithm == Algorithm :: SkEd25519 {
204+ let signature_length = self
205+ . as_bytes ( )
206+ . len ( )
207+ . checked_sub ( SK_ED25519_SIGNATURE_TRAILER_SIZE )
208+ . ok_or ( encoding:: Error :: Length ) ?;
209+ self . as_bytes ( ) [ ..signature_length] . encode ( writer) ?;
210+ writer. write ( & self . as_bytes ( ) [ signature_length..] ) ?;
211+ } else {
212+ self . as_bytes ( ) . encode ( writer) ?;
213+ }
214+
185215 Ok ( ( ) )
186216 }
187217}
@@ -268,6 +298,8 @@ impl Verifier<Signature> for public::KeyData {
268298 Self :: Ecdsa ( pk) => pk. verify ( message, signature) ,
269299 #[ cfg( feature = "ed25519" ) ]
270300 Self :: Ed25519 ( pk) => pk. verify ( message, signature) ,
301+ #[ cfg( feature = "ed25519" ) ]
302+ Self :: SkEd25519 ( pk) => pk. verify ( message, signature) ,
271303 #[ cfg( feature = "rsa" ) ]
272304 Self :: Rsa ( pk) => pk. verify ( message, signature) ,
273305 _ => Err ( signature:: Error :: new ( ) ) ,
@@ -324,7 +356,9 @@ impl TryFrom<&Signature> for ed25519_dalek::Signature {
324356
325357 fn try_from ( signature : & Signature ) -> Result < ed25519_dalek:: Signature > {
326358 match signature. algorithm {
327- Algorithm :: Ed25519 => Ok ( ed25519_dalek:: Signature :: try_from ( signature. as_bytes ( ) ) ?) ,
359+ Algorithm :: Ed25519 | Algorithm :: SkEd25519 => {
360+ Ok ( ed25519_dalek:: Signature :: try_from ( signature. as_bytes ( ) ) ?)
361+ }
328362 _ => Err ( Error :: Algorithm ) ,
329363 }
330364 }
@@ -352,6 +386,30 @@ impl Verifier<Signature> for Ed25519PublicKey {
352386 }
353387}
354388
389+ #[ cfg( feature = "ed25519" ) ]
390+ #[ cfg_attr( docsrs, doc( cfg( feature = "ed25519" ) ) ) ]
391+ impl Verifier < Signature > for public:: SkEd25519 {
392+ fn verify ( & self , message : & [ u8 ] , signature : & Signature ) -> signature:: Result < ( ) > {
393+ let signature_len = signature
394+ . as_bytes ( )
395+ . len ( )
396+ . checked_sub ( SK_ED25519_SIGNATURE_TRAILER_SIZE )
397+ . ok_or ( Error :: Encoding ( encoding:: Error :: Length ) ) ?;
398+ let signature_bytes = & signature. as_bytes ( ) [ ..signature_len] ;
399+ let flags_and_counter = & signature. as_bytes ( ) [ signature_len..] ;
400+
401+ #[ allow( clippy:: integer_arithmetic) ]
402+ let mut signed_data =
403+ Vec :: with_capacity ( ( 2 * Sha256 :: output_size ( ) ) + SK_ED25519_SIGNATURE_TRAILER_SIZE ) ;
404+ signed_data. extend ( Sha256 :: digest ( self . application ( ) ) ) ;
405+ signed_data. extend ( flags_and_counter) ;
406+ signed_data. extend ( Sha256 :: digest ( message) ) ;
407+
408+ let signature = ed25519_dalek:: Signature :: try_from ( signature_bytes) ?;
409+ ed25519_dalek:: PublicKey :: try_from ( self . public_key ( ) ) ?. verify ( & signed_data, & signature)
410+ }
411+ }
412+
355413#[ cfg( feature = "p256" ) ]
356414#[ cfg_attr( docsrs, doc( cfg( feature = "p256" ) ) ) ]
357415impl TryFrom < p256:: ecdsa:: Signature > for Signature {
@@ -618,6 +676,7 @@ mod tests {
618676 const DSA_SIGNATURE : & [ u8 ] = & hex ! ( "000000077373682d6473730000002866725bf3c56100e975e21fff28a60f73717534d285ea3e1beefc2891f7189d00bd4d94627e84c55c" ) ;
619677 const ECDSA_SHA2_P256_SIGNATURE : & [ u8 ] = & hex ! ( "0000001365636473612d736861322d6e6973747032353600000048000000201298ab320720a32139cda8a40c97a13dc54ce032ea3c6f09ea9e87501e48fa1d0000002046e4ac697a6424a9870b9ef04ca1182cd741965f989bd1f1f4a26fd83cf70348" ) ;
620678 const ED25519_SIGNATURE : & [ u8 ] = & hex ! ( "0000000b7373682d65643235353139000000403d6b9906b76875aef1e7b2f1e02078a94f439aebb9a4734da1a851a81e22ce0199bbf820387a8de9c834c9c3cc778d9972dcbe70f68d53cc6bc9e26b02b46d04" ) ;
679+ const SK_ED25519_SIGNATURE : & [ u8 ] = & hex ! ( "0000001a736b2d7373682d65643235353139406f70656e7373682e636f6d000000402f5670b6f93465d17423878a74084bf331767031ed240c627c8eb79ab8fa1b935a1fd993f52f5a13fec1797f8a434f943a6096246aea8dd5c8aa922cba3d95060100000009" ) ;
621680 const RSA_SHA512_SIGNATURE : & [ u8 ] = & hex ! ( "0000000c7273612d736861322d3531320000018085a4ad1a91a62c00c85de7bb511f38088ff2bce763d76f4786febbe55d47624f9e2cffce58a680183b9ad162c7f0191ea26cab001ac5f5055743eced58e9981789305c208fc98d2657954e38eb28c7e7f3fbe92393a14324ed77aebb772a41aa7a107b38cb9bd1d9ad79b275135d1d7e019bb1d56d74f2450be6db0771f48f6707d3fcf9789592ca2e55595acc16b6e8d0139b56c5d1360b3a1e060f4151a3d7841df2c2a8c94d6f8a1bf633165ee0bcadac5642763df0dd79d3235ae5506595145f199d8abe8f9980411bf70a16e30f273736324d047043317044c36374d6a5ed34cac251e01c6795e4578393f9090bf4ae3e74a0009275a197315fc9c62f1c9aec1ba3b2d37c3b207e5500df19e090e7097ebc038fb9c9e35aea9161479ba6b5190f48e89e1abe51e8ec0e120ef89776e129687ca52d1892c8e88e6ef062a7d96b8a87682ca6a42ff1df0cdf5815c3645aeed7267ca7093043db0565e0f109b796bf117b9d2bb6d6debc0c67a4c9fb3aae3e29b00c7bd70f6c11cf53c295ff" ) ;
622681
623682 /// Example test vector for signing.
@@ -647,6 +706,12 @@ mod tests {
647706 assert_eq ! ( Algorithm :: Ed25519 , signature. algorithm( ) ) ;
648707 }
649708
709+ #[ test]
710+ fn decode_sk_ed25519 ( ) {
711+ let signature = Signature :: try_from ( SK_ED25519_SIGNATURE ) . unwrap ( ) ;
712+ assert_eq ! ( Algorithm :: SkEd25519 , signature. algorithm( ) ) ;
713+ }
714+
650715 #[ test]
651716 fn decode_rsa ( ) {
652717 let signature = Signature :: try_from ( RSA_SHA512_SIGNATURE ) . unwrap ( ) ;
@@ -685,6 +750,15 @@ mod tests {
685750 assert_eq ! ( ED25519_SIGNATURE , & result) ;
686751 }
687752
753+ #[ test]
754+ fn encode_sk_ed25519 ( ) {
755+ let signature = Signature :: try_from ( SK_ED25519_SIGNATURE ) . unwrap ( ) ;
756+
757+ let mut result = Vec :: new ( ) ;
758+ signature. encode ( & mut result) . unwrap ( ) ;
759+ assert_eq ! ( SK_ED25519_SIGNATURE , & result) ;
760+ }
761+
688762 #[ cfg( feature = "ed25519" ) ]
689763 #[ test]
690764 fn sign_and_verify_ed25519 ( ) {
0 commit comments