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