@@ -10,13 +10,14 @@ pub mod serialized_signature;
1010use core:: { fmt, ptr, str} ;
1111
1212#[ cfg( feature = "recovery" ) ]
13- pub use self :: recovery:: { RecoverableSignature , RecoveryId } ;
13+ pub use self :: recovery:: { InvalidRecoveryIdError , RecoverableSignature , RecoveryId } ;
1414pub use self :: serialized_signature:: SerializedSignature ;
15+ use crate :: error:: { write_err, SysError } ;
1516use crate :: ffi:: CPtr ;
1617#[ cfg( feature = "global-context" ) ]
1718use crate :: SECP256K1 ;
1819use crate :: {
19- ffi, from_hex, Error , Message , PublicKey , Secp256k1 , SecretKey , Signing , Verification ,
20+ ffi, from_hex, FromHexError , Message , PublicKey , Secp256k1 , SecretKey , Signing , Verification ,
2021} ;
2122
2223/// An ECDSA signature
@@ -36,22 +37,21 @@ impl fmt::Display for Signature {
3637}
3738
3839impl str:: FromStr for Signature {
39- type Err = Error ;
40+ type Err = SignatureFromStrError ;
4041 fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
4142 let mut res = [ 0u8 ; 72 ] ;
42- match from_hex ( s, & mut res) {
43- Ok ( x) => Signature :: from_der ( & res[ 0 ..x] ) ,
44- _ => Err ( Error :: InvalidSignature ) ,
45- }
43+ let len = from_hex ( s, & mut res) ?;
44+ let sig = Signature :: from_der ( & res[ 0 ..len] ) ?;
45+ Ok ( sig)
4646 }
4747}
4848
4949impl Signature {
5050 #[ inline]
5151 /// Converts a DER-encoded byte slice to a signature
52- pub fn from_der ( data : & [ u8 ] ) -> Result < Signature , Error > {
52+ pub fn from_der ( data : & [ u8 ] ) -> Result < Signature , SignatureError > {
5353 if data. is_empty ( ) {
54- return Err ( Error :: InvalidSignature ) ;
54+ return Err ( SignatureError :: InvalidLength ( 0 ) ) ;
5555 }
5656
5757 unsafe {
@@ -65,15 +65,15 @@ impl Signature {
6565 {
6666 Ok ( Signature ( ret) )
6767 } else {
68- Err ( Error :: InvalidSignature )
68+ Err ( SignatureError :: Sys ( SysError ) )
6969 }
7070 }
7171 }
7272
7373 /// Converts a 64-byte compact-encoded byte slice to a signature
74- pub fn from_compact ( data : & [ u8 ] ) -> Result < Signature , Error > {
74+ pub fn from_compact ( data : & [ u8 ] ) -> Result < Signature , SignatureError > {
7575 if data. len ( ) != 64 {
76- return Err ( Error :: InvalidSignature ) ;
76+ return Err ( SignatureError :: InvalidLength ( data . len ( ) ) ) ;
7777 }
7878
7979 unsafe {
@@ -86,7 +86,7 @@ impl Signature {
8686 {
8787 Ok ( Signature ( ret) )
8888 } else {
89- Err ( Error :: InvalidSignature )
89+ Err ( SignatureError :: Sys ( SysError ) )
9090 }
9191 }
9292 }
@@ -95,9 +95,9 @@ impl Signature {
9595 /// only useful for validating signatures in the Bitcoin blockchain from before
9696 /// 2016. It should never be used in new applications. This library does not
9797 /// support serializing to this "format"
98- pub fn from_der_lax ( data : & [ u8 ] ) -> Result < Signature , Error > {
98+ pub fn from_der_lax ( data : & [ u8 ] ) -> Result < Signature , SignatureError > {
9999 if data. is_empty ( ) {
100- return Err ( Error :: InvalidSignature ) ;
100+ return Err ( SignatureError :: InvalidLength ( 0 ) ) ;
101101 }
102102
103103 unsafe {
@@ -111,7 +111,7 @@ impl Signature {
111111 {
112112 Ok ( Signature ( ret) )
113113 } else {
114- Err ( Error :: InvalidSignature )
114+ Err ( SignatureError :: Sys ( SysError ) )
115115 }
116116 }
117117 }
@@ -194,7 +194,7 @@ impl Signature {
194194 /// The signature must be normalized or verification will fail (see [`Signature::normalize_s`]).
195195 #[ inline]
196196 #[ cfg( feature = "global-context" ) ]
197- pub fn verify ( & self , msg : & Message , pk : & PublicKey ) -> Result < ( ) , Error > {
197+ pub fn verify ( & self , msg : & Message , pk : & PublicKey ) -> Result < ( ) , SysError > {
198198 SECP256K1 . verify_ecdsa ( msg, self , pk)
199199 }
200200}
@@ -366,7 +366,7 @@ impl<C: Verification> Secp256k1<C> {
366366 ///
367367 /// ```rust
368368 /// # #[cfg(feature = "rand-std")] {
369- /// # use secp256k1::{rand, Secp256k1, Message, Error };
369+ /// # use secp256k1::{ecdsa, rand, Secp256k1, Message, SysError };
370370 /// #
371371 /// # let secp = Secp256k1::new();
372372 /// # let (secret_key, public_key) = secp.generate_keypair(&mut rand::thread_rng());
@@ -376,7 +376,7 @@ impl<C: Verification> Secp256k1<C> {
376376 /// assert_eq!(secp.verify_ecdsa(&message, &sig, &public_key), Ok(()));
377377 ///
378378 /// let message = Message::from_digest_slice(&[0xcd; 32]).expect("32 bytes");
379- /// assert_eq!(secp.verify_ecdsa(&message, &sig, &public_key), Err(Error::IncorrectSignature ));
379+ /// assert_eq!(secp.verify_ecdsa(&message, &sig, &public_key), Err(SysError ));
380380 /// # }
381381 /// ```
382382 #[ inline]
@@ -385,7 +385,7 @@ impl<C: Verification> Secp256k1<C> {
385385 msg : & Message ,
386386 sig : & Signature ,
387387 pk : & PublicKey ,
388- ) -> Result < ( ) , Error > {
388+ ) -> Result < ( ) , SysError > {
389389 unsafe {
390390 if ffi:: secp256k1_ecdsa_verify (
391391 self . ctx . as_ptr ( ) ,
@@ -394,7 +394,7 @@ impl<C: Verification> Secp256k1<C> {
394394 pk. as_c_ptr ( ) ,
395395 ) == 0
396396 {
397- Err ( Error :: IncorrectSignature )
397+ Err ( SysError )
398398 } else {
399399 Ok ( ( ) )
400400 }
@@ -429,3 +429,76 @@ pub(crate) fn der_length_check(sig: &ffi::Signature, max_len: usize) -> bool {
429429 }
430430 len <= max_len
431431}
432+
433+ /// Signature is invalid.
434+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
435+ #[ non_exhaustive]
436+ pub enum SignatureError {
437+ /// Invalid signature length.
438+ InvalidLength ( usize ) ,
439+ /// FFI call failed.
440+ Sys ( SysError ) ,
441+ }
442+
443+ impl fmt:: Display for SignatureError {
444+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
445+ use SignatureError :: * ;
446+
447+ match * self {
448+ InvalidLength ( len) => write ! ( f, "invalid signature length: {}" , len) ,
449+ Sys ( ref e) => write_err ! ( f, "sys error" ; e) ,
450+ }
451+ }
452+ }
453+
454+ #[ cfg( feature = "std" ) ]
455+ impl std:: error:: Error for SignatureError {
456+ fn source ( & self ) -> Option < & ( dyn std:: error:: Error + ' static ) > {
457+ use SignatureError :: * ;
458+
459+ match * self {
460+ InvalidLength ( _) => None ,
461+ Sys ( ref e) => Some ( e) ,
462+ }
463+ }
464+ }
465+
466+ /// Signature is invalid.
467+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
468+ pub enum SignatureFromStrError {
469+ /// Invalid hex string.
470+ Hex ( FromHexError ) ,
471+ /// Invalid signature.
472+ Sig ( SignatureError ) ,
473+ }
474+
475+ impl fmt:: Display for SignatureFromStrError {
476+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
477+ use SignatureFromStrError :: * ;
478+
479+ match * self {
480+ Hex ( ref e) => write_err ! ( f, "error decoding hex" ; e) ,
481+ Sig ( ref e) => write_err ! ( f, "invalid signature" ; e) ,
482+ }
483+ }
484+ }
485+
486+ #[ cfg( feature = "std" ) ]
487+ impl std:: error:: Error for SignatureFromStrError {
488+ fn source ( & self ) -> Option < & ( dyn std:: error:: Error + ' static ) > {
489+ use SignatureFromStrError :: * ;
490+
491+ match * self {
492+ Hex ( ref e) => Some ( e) ,
493+ Sig ( ref e) => Some ( e) ,
494+ }
495+ }
496+ }
497+
498+ impl From < FromHexError > for SignatureFromStrError {
499+ fn from ( e : FromHexError ) -> Self { Self :: Hex ( e) }
500+ }
501+
502+ impl From < SignatureError > for SignatureFromStrError {
503+ fn from ( e : SignatureError ) -> Self { Self :: Sig ( e) }
504+ }
0 commit comments