@@ -10,13 +10,14 @@ pub mod serialized_signature;
10
10
use core:: { fmt, ptr, str} ;
11
11
12
12
#[ cfg( feature = "recovery" ) ]
13
- pub use self :: recovery:: { RecoverableSignature , RecoveryId } ;
13
+ pub use self :: recovery:: { InvalidRecoveryIdError , RecoverableSignature , RecoveryId } ;
14
14
pub use self :: serialized_signature:: SerializedSignature ;
15
+ use crate :: error:: { write_err, SysError } ;
15
16
use crate :: ffi:: CPtr ;
16
17
#[ cfg( feature = "global-context" ) ]
17
18
use crate :: SECP256K1 ;
18
19
use crate :: {
19
- ffi, from_hex, Error , Message , PublicKey , Secp256k1 , SecretKey , Signing , Verification ,
20
+ ffi, from_hex, FromHexError , Message , PublicKey , Secp256k1 , SecretKey , Signing , Verification ,
20
21
} ;
21
22
22
23
/// An ECDSA signature
@@ -36,22 +37,21 @@ impl fmt::Display for Signature {
36
37
}
37
38
38
39
impl str:: FromStr for Signature {
39
- type Err = Error ;
40
+ type Err = SignatureFromStrError ;
40
41
fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
41
42
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)
46
46
}
47
47
}
48
48
49
49
impl Signature {
50
50
#[ inline]
51
51
/// 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 > {
53
53
if data. is_empty ( ) {
54
- return Err ( Error :: InvalidSignature ) ;
54
+ return Err ( SignatureError :: InvalidLength ( 0 ) ) ;
55
55
}
56
56
57
57
unsafe {
@@ -65,15 +65,15 @@ impl Signature {
65
65
{
66
66
Ok ( Signature ( ret) )
67
67
} else {
68
- Err ( Error :: InvalidSignature )
68
+ Err ( SignatureError :: Sys ( SysError ) )
69
69
}
70
70
}
71
71
}
72
72
73
73
/// 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 > {
75
75
if data. len ( ) != 64 {
76
- return Err ( Error :: InvalidSignature ) ;
76
+ return Err ( SignatureError :: InvalidLength ( data . len ( ) ) ) ;
77
77
}
78
78
79
79
unsafe {
@@ -86,7 +86,7 @@ impl Signature {
86
86
{
87
87
Ok ( Signature ( ret) )
88
88
} else {
89
- Err ( Error :: InvalidSignature )
89
+ Err ( SignatureError :: Sys ( SysError ) )
90
90
}
91
91
}
92
92
}
@@ -95,9 +95,9 @@ impl Signature {
95
95
/// only useful for validating signatures in the Bitcoin blockchain from before
96
96
/// 2016. It should never be used in new applications. This library does not
97
97
/// 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 > {
99
99
if data. is_empty ( ) {
100
- return Err ( Error :: InvalidSignature ) ;
100
+ return Err ( SignatureError :: InvalidLength ( 0 ) ) ;
101
101
}
102
102
103
103
unsafe {
@@ -111,7 +111,7 @@ impl Signature {
111
111
{
112
112
Ok ( Signature ( ret) )
113
113
} else {
114
- Err ( Error :: InvalidSignature )
114
+ Err ( SignatureError :: Sys ( SysError ) )
115
115
}
116
116
}
117
117
}
@@ -194,7 +194,7 @@ impl Signature {
194
194
/// The signature must be normalized or verification will fail (see [`Signature::normalize_s`]).
195
195
#[ inline]
196
196
#[ 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 > {
198
198
SECP256K1 . verify_ecdsa ( msg, self , pk)
199
199
}
200
200
}
@@ -366,7 +366,7 @@ impl<C: Verification> Secp256k1<C> {
366
366
///
367
367
/// ```rust
368
368
/// # #[cfg(feature = "rand-std")] {
369
- /// # use secp256k1::{rand, Secp256k1, Message, Error };
369
+ /// # use secp256k1::{ecdsa, rand, Secp256k1, Message, SysError };
370
370
/// #
371
371
/// # let secp = Secp256k1::new();
372
372
/// # let (secret_key, public_key) = secp.generate_keypair(&mut rand::thread_rng());
@@ -376,7 +376,7 @@ impl<C: Verification> Secp256k1<C> {
376
376
/// assert_eq!(secp.verify_ecdsa(&message, &sig, &public_key), Ok(()));
377
377
///
378
378
/// 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 ));
380
380
/// # }
381
381
/// ```
382
382
#[ inline]
@@ -385,7 +385,7 @@ impl<C: Verification> Secp256k1<C> {
385
385
msg : & Message ,
386
386
sig : & Signature ,
387
387
pk : & PublicKey ,
388
- ) -> Result < ( ) , Error > {
388
+ ) -> Result < ( ) , SysError > {
389
389
unsafe {
390
390
if ffi:: secp256k1_ecdsa_verify (
391
391
self . ctx . as_ptr ( ) ,
@@ -394,7 +394,7 @@ impl<C: Verification> Secp256k1<C> {
394
394
pk. as_c_ptr ( ) ,
395
395
) == 0
396
396
{
397
- Err ( Error :: IncorrectSignature )
397
+ Err ( SysError )
398
398
} else {
399
399
Ok ( ( ) )
400
400
}
@@ -429,3 +429,76 @@ pub(crate) fn der_length_check(sig: &ffi::Signature, max_len: usize) -> bool {
429
429
}
430
430
len <= max_len
431
431
}
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