@@ -12,11 +12,14 @@ use core::{fmt, ptr, str};
1212#[ cfg( feature = "recovery" ) ]
1313pub use self :: recovery:: { RecoverableSignature , RecoveryId } ;
1414pub use self :: serialized_signature:: SerializedSignature ;
15+ #[ cfg( feature = "recovery" ) ]
16+ pub use crate :: ecdsa:: recovery:: InvalidRecoveryIdError ;
17+ use crate :: error:: { write_err, SysError } ;
1518use crate :: ffi:: CPtr ;
1619#[ cfg( feature = "global-context" ) ]
1720use crate :: SECP256K1 ;
1821use crate :: {
19- ffi, from_hex, Error , Message , PublicKey , Secp256k1 , SecretKey , Signing , Verification ,
22+ ffi, from_hex, FromHexError , Message , PublicKey , Secp256k1 , SecretKey , Signing , Verification ,
2023} ;
2124
2225/// An ECDSA signature
@@ -36,22 +39,21 @@ impl fmt::Display for Signature {
3639}
3740
3841impl str:: FromStr for Signature {
39- type Err = Error ;
42+ type Err = SignatureFromStrError ;
4043 fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
4144 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- }
45+ let len = from_hex ( s, & mut res) ?;
46+ let sig = Signature :: from_der ( & res[ 0 ..len] ) ?;
47+ Ok ( sig)
4648 }
4749}
4850
4951impl Signature {
5052 #[ inline]
5153 /// Converts a DER-encoded byte slice to a signature
52- pub fn from_der ( data : & [ u8 ] ) -> Result < Signature , Error > {
54+ pub fn from_der ( data : & [ u8 ] ) -> Result < Signature , SignatureError > {
5355 if data. is_empty ( ) {
54- return Err ( Error :: InvalidSignature ) ;
56+ return Err ( SignatureError :: InvalidLength ( 0 ) ) ;
5557 }
5658
5759 unsafe {
@@ -65,15 +67,15 @@ impl Signature {
6567 {
6668 Ok ( Signature ( ret) )
6769 } else {
68- Err ( Error :: InvalidSignature )
70+ Err ( SignatureError :: Sys ( SysError ) )
6971 }
7072 }
7173 }
7274
7375 /// Converts a 64-byte compact-encoded byte slice to a signature
74- pub fn from_compact ( data : & [ u8 ] ) -> Result < Signature , Error > {
76+ pub fn from_compact ( data : & [ u8 ] ) -> Result < Signature , SignatureError > {
7577 if data. len ( ) != 64 {
76- return Err ( Error :: InvalidSignature ) ;
78+ return Err ( SignatureError :: InvalidLength ( data . len ( ) ) ) ;
7779 }
7880
7981 unsafe {
@@ -86,7 +88,7 @@ impl Signature {
8688 {
8789 Ok ( Signature ( ret) )
8890 } else {
89- Err ( Error :: InvalidSignature )
91+ Err ( SignatureError :: Sys ( SysError ) )
9092 }
9193 }
9294 }
@@ -95,9 +97,9 @@ impl Signature {
9597 /// only useful for validating signatures in the Bitcoin blockchain from before
9698 /// 2016. It should never be used in new applications. This library does not
9799 /// support serializing to this "format"
98- pub fn from_der_lax ( data : & [ u8 ] ) -> Result < Signature , Error > {
100+ pub fn from_der_lax ( data : & [ u8 ] ) -> Result < Signature , SignatureError > {
99101 if data. is_empty ( ) {
100- return Err ( Error :: InvalidSignature ) ;
102+ return Err ( SignatureError :: InvalidLength ( 0 ) ) ;
101103 }
102104
103105 unsafe {
@@ -111,7 +113,7 @@ impl Signature {
111113 {
112114 Ok ( Signature ( ret) )
113115 } else {
114- Err ( Error :: InvalidSignature )
116+ Err ( SignatureError :: Sys ( SysError ) )
115117 }
116118 }
117119 }
@@ -194,7 +196,7 @@ impl Signature {
194196 /// The signature must be normalized or verification will fail (see [`Signature::normalize_s`]).
195197 #[ inline]
196198 #[ cfg( feature = "global-context" ) ]
197- pub fn verify ( & self , msg : & Message , pk : & PublicKey ) -> Result < ( ) , Error > {
199+ pub fn verify ( & self , msg : & Message , pk : & PublicKey ) -> Result < ( ) , SysError > {
198200 SECP256K1 . verify_ecdsa ( msg, self , pk)
199201 }
200202}
@@ -366,7 +368,7 @@ impl<C: Verification> Secp256k1<C> {
366368 ///
367369 /// ```rust
368370 /// # #[cfg(feature = "rand-std")] {
369- /// # use secp256k1::{rand, Secp256k1, Message, Error };
371+ /// # use secp256k1::{ecdsa, rand, Secp256k1, Message, SysError };
370372 /// #
371373 /// # let secp = Secp256k1::new();
372374 /// # let (secret_key, public_key) = secp.generate_keypair(&mut rand::thread_rng());
@@ -376,7 +378,7 @@ impl<C: Verification> Secp256k1<C> {
376378 /// assert_eq!(secp.verify_ecdsa(&message, &sig, &public_key), Ok(()));
377379 ///
378380 /// let message = Message::from_slice(&[0xcd; 32]).expect("32 bytes");
379- /// assert_eq!(secp.verify_ecdsa(&message, &sig, &public_key), Err(Error::IncorrectSignature ));
381+ /// assert_eq!(secp.verify_ecdsa(&message, &sig, &public_key), Err(SysError ));
380382 /// # }
381383 /// ```
382384 #[ inline]
@@ -385,7 +387,7 @@ impl<C: Verification> Secp256k1<C> {
385387 msg : & Message ,
386388 sig : & Signature ,
387389 pk : & PublicKey ,
388- ) -> Result < ( ) , Error > {
390+ ) -> Result < ( ) , SysError > {
389391 unsafe {
390392 if ffi:: secp256k1_ecdsa_verify (
391393 self . ctx . as_ptr ( ) ,
@@ -394,7 +396,7 @@ impl<C: Verification> Secp256k1<C> {
394396 pk. as_c_ptr ( ) ,
395397 ) == 0
396398 {
397- Err ( Error :: IncorrectSignature )
399+ Err ( SysError )
398400 } else {
399401 Ok ( ( ) )
400402 }
@@ -429,3 +431,75 @@ pub(crate) fn der_length_check(sig: &ffi::Signature, max_len: usize) -> bool {
429431 }
430432 len <= max_len
431433}
434+
435+ /// Signature is invalid.
436+ #[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
437+ pub enum SignatureError {
438+ /// Invalid signature length.
439+ InvalidLength ( usize ) ,
440+ /// FFI call failed.
441+ Sys ( SysError ) ,
442+ }
443+
444+ impl fmt:: Display for SignatureError {
445+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
446+ use SignatureError :: * ;
447+
448+ match * self {
449+ InvalidLength ( len) => write ! ( f, "invalid signature length: {}" , len) ,
450+ Sys ( ref e) => write_err ! ( f, "sys error" ; e) ,
451+ }
452+ }
453+ }
454+
455+ #[ cfg( feature = "std" ) ]
456+ impl std:: error:: Error for SignatureError {
457+ fn source ( & self ) -> Option < & ( dyn std:: error:: Error + ' static ) > {
458+ use SignatureError :: * ;
459+
460+ match * self {
461+ InvalidLength ( _) => None ,
462+ Sys ( ref e) => Some ( e) ,
463+ }
464+ }
465+ }
466+
467+ /// Signature is invalid.
468+ #[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
469+ pub enum SignatureFromStrError {
470+ /// Invalid hex string.
471+ Hex ( FromHexError ) ,
472+ /// Invalid signature.
473+ Sig ( SignatureError ) ,
474+ }
475+
476+ impl fmt:: Display for SignatureFromStrError {
477+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
478+ use SignatureFromStrError :: * ;
479+
480+ match * self {
481+ Hex ( ref e) => write_err ! ( f, "error decoding hex" ; e) ,
482+ Sig ( ref e) => write_err ! ( f, "invalid signature" ; e) ,
483+ }
484+ }
485+ }
486+
487+ #[ cfg( feature = "std" ) ]
488+ impl std:: error:: Error for SignatureFromStrError {
489+ fn source ( & self ) -> Option < & ( dyn std:: error:: Error + ' static ) > {
490+ use SignatureFromStrError :: * ;
491+
492+ match * self {
493+ Hex ( ref e) => Some ( e) ,
494+ Sig ( ref e) => Some ( e) ,
495+ }
496+ }
497+ }
498+
499+ impl From < FromHexError > for SignatureFromStrError {
500+ fn from ( e : FromHexError ) -> Self { Self :: Hex ( e) }
501+ }
502+
503+ impl From < SignatureError > for SignatureFromStrError {
504+ fn from ( e : SignatureError ) -> Self { Self :: Sig ( e) }
505+ }
0 commit comments