@@ -12,11 +12,13 @@ use core::{fmt, ptr, str};
1212#[ cfg( feature = "recovery" ) ]
1313pub use self :: recovery:: { RecoverableSignature , RecoveryId } ;
1414pub use self :: serialized_signature:: SerializedSignature ;
15+ pub use crate :: ecdsa:: recovery:: InvalidRecoveryIdError ;
16+ use crate :: error:: { write_err, SysError } ;
1517use crate :: ffi:: CPtr ;
1618#[ cfg( feature = "global-context" ) ]
1719use crate :: SECP256K1 ;
1820use crate :: {
19- ffi, from_hex, Error , Message , PublicKey , Secp256k1 , SecretKey , Signing , Verification ,
21+ ffi, from_hex, FromHexError , Message , PublicKey , Secp256k1 , SecretKey , Signing , Verification ,
2022} ;
2123
2224/// An ECDSA signature
@@ -36,22 +38,21 @@ impl fmt::Display for Signature {
3638}
3739
3840impl str:: FromStr for Signature {
39- type Err = Error ;
41+ type Err = SignatureFromStrError ;
4042 fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
4143 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- }
44+ let len = from_hex ( s, & mut res) ?;
45+ let sig = Signature :: from_der ( & res[ 0 ..len] ) ?;
46+ Ok ( sig)
4647 }
4748}
4849
4950impl Signature {
5051 #[ inline]
5152 /// Converts a DER-encoded byte slice to a signature
52- pub fn from_der ( data : & [ u8 ] ) -> Result < Signature , Error > {
53+ pub fn from_der ( data : & [ u8 ] ) -> Result < Signature , SignatureError > {
5354 if data. is_empty ( ) {
54- return Err ( Error :: InvalidSignature ) ;
55+ return Err ( SignatureError :: InvalidLength ( 0 ) ) ;
5556 }
5657
5758 unsafe {
@@ -65,15 +66,15 @@ impl Signature {
6566 {
6667 Ok ( Signature ( ret) )
6768 } else {
68- Err ( Error :: InvalidSignature )
69+ Err ( SignatureError :: Sys ( SysError ) )
6970 }
7071 }
7172 }
7273
7374 /// Converts a 64-byte compact-encoded byte slice to a signature
74- pub fn from_compact ( data : & [ u8 ] ) -> Result < Signature , Error > {
75+ pub fn from_compact ( data : & [ u8 ] ) -> Result < Signature , SignatureError > {
7576 if data. len ( ) != 64 {
76- return Err ( Error :: InvalidSignature ) ;
77+ return Err ( SignatureError :: InvalidLength ( data . len ( ) ) ) ;
7778 }
7879
7980 unsafe {
@@ -86,7 +87,7 @@ impl Signature {
8687 {
8788 Ok ( Signature ( ret) )
8889 } else {
89- Err ( Error :: InvalidSignature )
90+ Err ( SignatureError :: Sys ( SysError ) )
9091 }
9192 }
9293 }
@@ -95,9 +96,9 @@ impl Signature {
9596 /// only useful for validating signatures in the Bitcoin blockchain from before
9697 /// 2016. It should never be used in new applications. This library does not
9798 /// support serializing to this "format"
98- pub fn from_der_lax ( data : & [ u8 ] ) -> Result < Signature , Error > {
99+ pub fn from_der_lax ( data : & [ u8 ] ) -> Result < Signature , SignatureError > {
99100 if data. is_empty ( ) {
100- return Err ( Error :: InvalidSignature ) ;
101+ return Err ( SignatureError :: InvalidLength ( 0 ) ) ;
101102 }
102103
103104 unsafe {
@@ -111,7 +112,7 @@ impl Signature {
111112 {
112113 Ok ( Signature ( ret) )
113114 } else {
114- Err ( Error :: InvalidSignature )
115+ Err ( SignatureError :: Sys ( SysError ) )
115116 }
116117 }
117118 }
@@ -194,7 +195,7 @@ impl Signature {
194195 /// The signature must be normalized or verification will fail (see [`Signature::normalize_s`]).
195196 #[ inline]
196197 #[ cfg( feature = "global-context" ) ]
197- pub fn verify ( & self , msg : & Message , pk : & PublicKey ) -> Result < ( ) , Error > {
198+ pub fn verify ( & self , msg : & Message , pk : & PublicKey ) -> Result < ( ) , SysError > {
198199 SECP256K1 . verify_ecdsa ( msg, self , pk)
199200 }
200201}
@@ -366,7 +367,7 @@ impl<C: Verification> Secp256k1<C> {
366367 ///
367368 /// ```rust
368369 /// # #[cfg(feature = "rand-std")] {
369- /// # use secp256k1::{rand, Secp256k1, Message, Error };
370+ /// # use secp256k1::{ecdsa, rand, Secp256k1, Message};
370371 /// #
371372 /// # let secp = Secp256k1::new();
372373 /// # let (secret_key, public_key) = secp.generate_keypair(&mut rand::thread_rng());
@@ -376,7 +377,7 @@ impl<C: Verification> Secp256k1<C> {
376377 /// assert_eq!(secp.verify_ecdsa(&message, &sig, &public_key), Ok(()));
377378 ///
378379 /// let message = Message::from_slice(&[0xcd; 32]).expect("32 bytes");
379- /// assert_eq!(secp.verify_ecdsa(&message, &sig, &public_key), Err(Error::IncorrectSignature ));
380+ /// assert_eq!(secp.verify_ecdsa(&message, &sig, &public_key), Err(ecdsa::SignatureError ));
380381 /// # }
381382 /// ```
382383 #[ inline]
@@ -385,7 +386,7 @@ impl<C: Verification> Secp256k1<C> {
385386 msg : & Message ,
386387 sig : & Signature ,
387388 pk : & PublicKey ,
388- ) -> Result < ( ) , Error > {
389+ ) -> Result < ( ) , SysError > {
389390 unsafe {
390391 if ffi:: secp256k1_ecdsa_verify (
391392 self . ctx . as_ptr ( ) ,
@@ -394,7 +395,7 @@ impl<C: Verification> Secp256k1<C> {
394395 pk. as_c_ptr ( ) ,
395396 ) == 0
396397 {
397- Err ( Error :: IncorrectSignature )
398+ Err ( SysError )
398399 } else {
399400 Ok ( ( ) )
400401 }
@@ -429,3 +430,75 @@ pub(crate) fn der_length_check(sig: &ffi::Signature, max_len: usize) -> bool {
429430 }
430431 len <= max_len
431432}
433+
434+ /// Signature is invalid.
435+ #[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
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( Clone , Copy , Debug , 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