@@ -10,12 +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, InvalidSliceLengthError , SysError } ;
1516use crate :: ffi:: CPtr ;
17+ use crate :: hex:: { self , FromHexError } ;
1618#[ cfg( feature = "global-context" ) ]
1719use crate :: SECP256K1 ;
18- use crate :: { ffi, hex , Error , Message , PublicKey , Secp256k1 , SecretKey , Signing , Verification } ;
20+ use crate :: { ffi, Message , PublicKey , Secp256k1 , SecretKey , Signing , Verification } ;
1921
2022/// An ECDSA signature
2123#[ derive( Copy , Clone , PartialOrd , Ord , PartialEq , Eq , Hash ) ]
@@ -34,22 +36,21 @@ impl fmt::Display for Signature {
3436}
3537
3638impl str:: FromStr for Signature {
37- type Err = Error ;
39+ type Err = SignatureParseError ;
3840 fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
3941 let mut res = [ 0u8 ; 72 ] ;
40- match hex:: from_hex ( s, & mut res) {
41- Ok ( x) => Signature :: from_der ( & res[ 0 ..x] ) ,
42- _ => Err ( Error :: InvalidSignature ) ,
43- }
42+ let len = hex:: from_hex ( s, & mut res) ?;
43+ let sig = Signature :: from_der ( & res[ 0 ..len] ) ?;
44+ Ok ( sig)
4445 }
4546}
4647
4748impl Signature {
4849 #[ inline]
4950 /// Converts a DER-encoded byte slice to a signature
50- pub fn from_der ( data : & [ u8 ] ) -> Result < Signature , Error > {
51+ pub fn from_der ( data : & [ u8 ] ) -> Result < Signature , SignatureError > {
5152 if data. is_empty ( ) {
52- return Err ( Error :: InvalidSignature ) ;
53+ return Err ( SignatureError :: EmptySlice ) ;
5354 }
5455
5556 unsafe {
@@ -63,15 +64,15 @@ impl Signature {
6364 {
6465 Ok ( Signature ( ret) )
6566 } else {
66- Err ( Error :: InvalidSignature )
67+ Err ( SignatureError :: Sys ( SysError { } ) )
6768 }
6869 }
6970 }
7071
7172 /// Converts a 64-byte compact-encoded byte slice to a signature
72- pub fn from_compact ( data : & [ u8 ] ) -> Result < Signature , Error > {
73+ pub fn from_compact ( data : & [ u8 ] ) -> Result < Signature , SignatureError > {
7374 if data. len ( ) != 64 {
74- return Err ( Error :: InvalidSignature ) ;
75+ return Err ( SignatureError :: invalid_length ( data . len ( ) ) ) ;
7576 }
7677
7778 unsafe {
@@ -84,7 +85,7 @@ impl Signature {
8485 {
8586 Ok ( Signature ( ret) )
8687 } else {
87- Err ( Error :: InvalidSignature )
88+ Err ( SignatureError :: Sys ( SysError { } ) )
8889 }
8990 }
9091 }
@@ -93,9 +94,9 @@ impl Signature {
9394 /// only useful for validating signatures in the Bitcoin blockchain from before
9495 /// 2016. It should never be used in new applications. This library does not
9596 /// support serializing to this "format"
96- pub fn from_der_lax ( data : & [ u8 ] ) -> Result < Signature , Error > {
97+ pub fn from_der_lax ( data : & [ u8 ] ) -> Result < Signature , SignatureError > {
9798 if data. is_empty ( ) {
98- return Err ( Error :: InvalidSignature ) ;
99+ return Err ( SignatureError :: EmptySlice ) ;
99100 }
100101
101102 unsafe {
@@ -109,7 +110,7 @@ impl Signature {
109110 {
110111 Ok ( Signature ( ret) )
111112 } else {
112- Err ( Error :: InvalidSignature )
113+ Err ( SignatureError :: Sys ( SysError { } ) )
113114 }
114115 }
115116 }
@@ -192,7 +193,7 @@ impl Signature {
192193 /// The signature must be normalized or verification will fail (see [`Signature::normalize_s`]).
193194 #[ inline]
194195 #[ cfg( feature = "global-context" ) ]
195- pub fn verify ( & self , msg : & Message , pk : & PublicKey ) -> Result < ( ) , Error > {
196+ pub fn verify ( & self , msg : & Message , pk : & PublicKey ) -> Result < ( ) , SysError > {
196197 SECP256K1 . verify_ecdsa ( msg, self , pk)
197198 }
198199}
@@ -364,7 +365,7 @@ impl<C: Verification> Secp256k1<C> {
364365 ///
365366 /// ```rust
366367 /// # #[cfg(feature = "rand-std")] {
367- /// # use secp256k1::{rand, Secp256k1, Message, Error };
368+ /// # use secp256k1::{ecdsa, rand, Secp256k1, Message, SysError };
368369 /// #
369370 /// # let secp = Secp256k1::new();
370371 /// # let (secret_key, public_key) = secp.generate_keypair(&mut rand::thread_rng());
@@ -374,7 +375,7 @@ impl<C: Verification> Secp256k1<C> {
374375 /// assert_eq!(secp.verify_ecdsa(&message, &sig, &public_key), Ok(()));
375376 ///
376377 /// let message = Message::from_digest_slice(&[0xcd; 32]).expect("32 bytes");
377- /// assert_eq!( secp.verify_ecdsa(&message, &sig, &public_key), Err(Error::IncorrectSignature ));
378+ /// assert!(matches!( secp.verify_ecdsa(&message, &sig, &public_key), Err(SysError) ));
378379 /// # }
379380 /// ```
380381 #[ inline]
@@ -383,7 +384,7 @@ impl<C: Verification> Secp256k1<C> {
383384 msg : & Message ,
384385 sig : & Signature ,
385386 pk : & PublicKey ,
386- ) -> Result < ( ) , Error > {
387+ ) -> Result < ( ) , SysError > {
387388 unsafe {
388389 if ffi:: secp256k1_ecdsa_verify (
389390 self . ctx . as_ptr ( ) ,
@@ -392,7 +393,7 @@ impl<C: Verification> Secp256k1<C> {
392393 pk. as_c_ptr ( ) ,
393394 ) == 0
394395 {
395- Err ( Error :: IncorrectSignature )
396+ Err ( SysError { } )
396397 } else {
397398 Ok ( ( ) )
398399 }
@@ -427,3 +428,91 @@ pub(crate) fn der_length_check(sig: &ffi::Signature, max_len: usize) -> bool {
427428 }
428429 len <= max_len
429430}
431+
432+ /// Signature is invalid.
433+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
434+ #[ non_exhaustive]
435+ pub enum SignatureError {
436+ /// Tried to create signature from an empty slice.
437+ EmptySlice ,
438+ /// Tried to create signature from an invalid length slice.
439+ InvalidSliceLength ( InvalidSliceLengthError ) ,
440+ /// FFI call failed.
441+ Sys ( SysError ) ,
442+ }
443+
444+ impl SignatureError {
445+ fn invalid_length ( len : usize ) -> Self {
446+ InvalidSliceLengthError { got : len, expected : 64 } . into ( )
447+ }
448+ }
449+
450+ impl fmt:: Display for SignatureError {
451+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
452+ use SignatureError :: * ;
453+
454+ match * self {
455+ EmptySlice => write ! ( f, "tried to create signature from an empty slice" ) ,
456+ InvalidSliceLength ( ref e) =>
457+ write_err ! ( f, "tried to create signature from an invalid length slice" ; e) ,
458+ Sys ( ref e) => write_err ! ( f, "sys error" ; e) ,
459+ }
460+ }
461+ }
462+
463+ #[ cfg( feature = "std" ) ]
464+ impl std:: error:: Error for SignatureError {
465+ fn source ( & self ) -> Option < & ( dyn std:: error:: Error + ' static ) > {
466+ use SignatureError :: * ;
467+
468+ match * self {
469+ EmptySlice => None ,
470+ InvalidSliceLength ( ref e) => Some ( e) ,
471+ Sys ( ref e) => Some ( e) ,
472+ }
473+ }
474+ }
475+
476+ impl From < InvalidSliceLengthError > for SignatureError {
477+ fn from ( e : InvalidSliceLengthError ) -> Self { Self :: InvalidSliceLength ( e) }
478+ }
479+
480+ /// Signature is invalid.
481+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
482+ pub enum SignatureParseError {
483+ /// Invalid hex string.
484+ Hex ( FromHexError ) ,
485+ /// Invalid signature.
486+ Sig ( SignatureError ) ,
487+ }
488+
489+ impl fmt:: Display for SignatureParseError {
490+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
491+ use SignatureParseError :: * ;
492+
493+ match * self {
494+ Hex ( ref e) => write_err ! ( f, "error decoding hex" ; e) ,
495+ Sig ( ref e) => write_err ! ( f, "invalid signature" ; e) ,
496+ }
497+ }
498+ }
499+
500+ #[ cfg( feature = "std" ) ]
501+ impl std:: error:: Error for SignatureParseError {
502+ fn source ( & self ) -> Option < & ( dyn std:: error:: Error + ' static ) > {
503+ use SignatureParseError :: * ;
504+
505+ match * self {
506+ Hex ( ref e) => Some ( e) ,
507+ Sig ( ref e) => Some ( e) ,
508+ }
509+ }
510+ }
511+
512+ impl From < FromHexError > for SignatureParseError {
513+ fn from ( e : FromHexError ) -> Self { Self :: Hex ( e) }
514+ }
515+
516+ impl From < SignatureError > for SignatureParseError {
517+ fn from ( e : SignatureError ) -> Self { Self :: Sig ( e) }
518+ }
0 commit comments