@@ -7,7 +7,7 @@ use crate::{
77} ;
88use base64:: { engine:: general_purpose:: STANDARD as BASE64 , Engine } ;
99use clap:: Parser ;
10- use ed25519_dalek:: { Signature , Verifier , VerifyingKey } ;
10+ use ed25519_dalek:: { Signature , VerifyingKey } ;
1111use sha2:: { Digest , Sha256 } ;
1212
1313use super :: SEP53_PREFIX ;
@@ -100,7 +100,7 @@ impl Cmd {
100100 let verifying_key = VerifyingKey :: from_bytes ( & public_key. 0 ) ?;
101101
102102 // Verify the signature
103- if verifying_key. verify ( & hash, & signature) . is_ok ( ) {
103+ if verifying_key. verify_strict ( & hash, & signature) . is_ok ( ) {
104104 print. checkln ( "Signature valid" ) ;
105105 Ok ( ( ) )
106106 } else {
@@ -275,6 +275,38 @@ mod tests {
275275 assert ! ( successful. is_err( ) ) ;
276276 }
277277
278+ #[ test]
279+ fn test_verify_rejects_small_order_public_keys ( ) {
280+ // Small-order ed25519 public keys have no secret key. A signature (R, s = 0) with R a
281+ // small-order point passes non-strict verification without any key material.
282+ const IDENTITY_PUBLIC_KEY : & str =
283+ "GAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHV4" ;
284+ const IDENTITY_FORGED_SIGNATURE : & str =
285+ "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" ;
286+ const ZERO_PUBLIC_KEY : & str = "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF" ;
287+ const ZERO_FORGED_SIGNATURE : & str =
288+ "7P///////////////////////////////////////38AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" ;
289+
290+ for ( public_key, signature) in [
291+ ( IDENTITY_PUBLIC_KEY , IDENTITY_FORGED_SIGNATURE ) ,
292+ ( ZERO_PUBLIC_KEY , ZERO_FORGED_SIGNATURE ) ,
293+ ] {
294+ let cmd = super :: Cmd {
295+ message : Some ( "Hello, World!" . to_string ( ) ) ,
296+ base64 : false ,
297+ signature : signature. to_string ( ) ,
298+ public_key : public_key. to_string ( ) ,
299+ hd_path : None ,
300+ locator : setup_locator ( ) ,
301+ } ;
302+ let err = cmd. run ( & global_args ( ) ) . unwrap_err ( ) ;
303+ assert ! (
304+ matches!( err, Error :: VerificationFailed ) ,
305+ "{public_key}: {err:?}"
306+ ) ;
307+ }
308+ }
309+
278310 #[ test]
279311 fn test_verify_rejects_raw_secret_key_as_public_key ( ) {
280312 let secret_key = "SBF5HLRREHMS36XZNTUSKZ6FTXDZGNXOHF4EXKUL5UCWZLPBX3NGJ4BH" ;
0 commit comments