File tree Expand file tree Collapse file tree 2 files changed +36
-2
lines changed Expand file tree Collapse file tree 2 files changed +36
-2
lines changed Original file line number Diff line number Diff line change @@ -49,6 +49,29 @@ fn zeroed_buff_literal(len: usize) -> String {
4949 buff_literal ( & vec ! [ 0u8 ; len] )
5050}
5151
52+ #[ test]
53+ fn test_secp256k1_recover_accepts_high_s_signature ( ) {
54+ let message = "0x7147f89f7ba4980c8628b52c2f0351f018ed31ba593e5ed676ad428c67c23ffb" ;
55+ let signature = "0xe120eaed297a125259ee235a702c3f8dc18f8e65cdb28625061dd9e80197b0e6d29c9b9a200ecffee51033a93c896e9e00907789888eef42f3ede3a81dd7730201" ;
56+ let expected_pubkey = "0x034170a2083dccbc2be253885a8d0e9f7ce859eb370d0c5cae3b6994af4cb9d666" ;
57+ let fallback = zeroed_buff_literal ( 33 ) ;
58+ let program = format ! (
59+ "(is-eq (unwrap! (secp256k1-recover? {message} {signature}) {fallback}) {expected_pubkey})"
60+ ) ;
61+
62+ assert_eq ! (
63+ Value :: Bool ( true ) ,
64+ execute_with_parameters(
65+ program. as_str( ) ,
66+ ClarityVersion :: Clarity1 ,
67+ StacksEpochId :: Epoch20 ,
68+ false
69+ )
70+ . expect( "execution should succeed" )
71+ . expect( "should return a value" )
72+ ) ;
73+ }
74+
5275#[ test]
5376fn test_secp256r1_verify_valid_signature_returns_true ( ) {
5477 let ( message, signature, pubkey) = secp256r1_vectors ( ) ;
Original file line number Diff line number Diff line change @@ -475,14 +475,25 @@ pub fn secp256k1_recover(
475475 return Err ( Secp256k1Error :: InvalidSignature ) ;
476476 }
477477
478- let recovery_id = K256RecoveryId :: from_byte ( serialized_signature_arr[ 64 ] )
478+ let mut recovery_id = K256RecoveryId :: from_byte ( serialized_signature_arr[ 64 ] )
479479 . ok_or ( Secp256k1Error :: InvalidRecoveryId ) ?;
480480
481481 let signature = K256Signature :: from_slice ( & serialized_signature_arr[ ..64 ] )
482482 . map_err ( |_| Secp256k1Error :: InvalidSignature ) ?;
483483
484+ let normalized_signature = signature. normalize_s ( ) ;
485+
486+ let signature_ref: & K256Signature = if let Some ( normalized) = normalized_signature. as_ref ( ) {
487+ let flipped_recovery_id =
488+ K256RecoveryId :: new ( !recovery_id. is_y_odd ( ) , recovery_id. is_x_reduced ( ) ) ;
489+ recovery_id = flipped_recovery_id;
490+ normalized
491+ } else {
492+ & signature
493+ } ;
494+
484495 let recovered_pub =
485- K256VerifyingKey :: recover_from_prehash ( message_arr, & signature , recovery_id)
496+ K256VerifyingKey :: recover_from_prehash ( message_arr, signature_ref , recovery_id)
486497 . map_err ( |_| Secp256k1Error :: RecoveryFailed ) ?;
487498
488499 let public_key = K256PublicKey :: from ( & recovered_pub) ;
You can’t perform that action at this time.
0 commit comments