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