@@ -10,12 +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, InvalidSliceLengthError , SysError } ;
15
16
use crate :: ffi:: CPtr ;
17
+ use crate :: hex:: { self , FromHexError } ;
16
18
#[ cfg( feature = "global-context" ) ]
17
19
use crate :: SECP256K1 ;
18
- use crate :: { ffi, hex , Error , Message , PublicKey , Secp256k1 , SecretKey , Signing , Verification } ;
20
+ use crate :: { ffi, Message , PublicKey , Secp256k1 , SecretKey , Signing , Verification } ;
19
21
20
22
/// An ECDSA signature
21
23
#[ derive( Copy , Clone , PartialOrd , Ord , PartialEq , Eq , Hash ) ]
@@ -34,22 +36,21 @@ impl fmt::Display for Signature {
34
36
}
35
37
36
38
impl str:: FromStr for Signature {
37
- type Err = Error ;
39
+ type Err = SignatureParseError ;
38
40
fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
39
41
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)
44
45
}
45
46
}
46
47
47
48
impl Signature {
48
49
#[ inline]
49
50
/// 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 > {
51
52
if data. is_empty ( ) {
52
- return Err ( Error :: InvalidSignature ) ;
53
+ return Err ( SignatureError :: EmptySlice ) ;
53
54
}
54
55
55
56
unsafe {
@@ -63,15 +64,15 @@ impl Signature {
63
64
{
64
65
Ok ( Signature ( ret) )
65
66
} else {
66
- Err ( Error :: InvalidSignature )
67
+ Err ( SignatureError :: Sys ( SysError { } ) )
67
68
}
68
69
}
69
70
}
70
71
71
72
/// 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 > {
73
74
if data. len ( ) != 64 {
74
- return Err ( Error :: InvalidSignature ) ;
75
+ return Err ( SignatureError :: invalid_length ( data . len ( ) ) ) ;
75
76
}
76
77
77
78
unsafe {
@@ -84,7 +85,7 @@ impl Signature {
84
85
{
85
86
Ok ( Signature ( ret) )
86
87
} else {
87
- Err ( Error :: InvalidSignature )
88
+ Err ( SignatureError :: Sys ( SysError { } ) )
88
89
}
89
90
}
90
91
}
@@ -93,9 +94,9 @@ impl Signature {
93
94
/// only useful for validating signatures in the Bitcoin blockchain from before
94
95
/// 2016. It should never be used in new applications. This library does not
95
96
/// 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 > {
97
98
if data. is_empty ( ) {
98
- return Err ( Error :: InvalidSignature ) ;
99
+ return Err ( SignatureError :: EmptySlice ) ;
99
100
}
100
101
101
102
unsafe {
@@ -109,7 +110,7 @@ impl Signature {
109
110
{
110
111
Ok ( Signature ( ret) )
111
112
} else {
112
- Err ( Error :: InvalidSignature )
113
+ Err ( SignatureError :: Sys ( SysError { } ) )
113
114
}
114
115
}
115
116
}
@@ -192,7 +193,7 @@ impl Signature {
192
193
/// The signature must be normalized or verification will fail (see [`Signature::normalize_s`]).
193
194
#[ inline]
194
195
#[ 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 > {
196
197
SECP256K1 . verify_ecdsa ( msg, self , pk)
197
198
}
198
199
}
@@ -364,7 +365,7 @@ impl<C: Verification> Secp256k1<C> {
364
365
///
365
366
/// ```rust
366
367
/// # #[cfg(feature = "rand-std")] {
367
- /// # use secp256k1::{rand, Secp256k1, Message, Error };
368
+ /// # use secp256k1::{ecdsa, rand, Secp256k1, Message, SysError };
368
369
/// #
369
370
/// # let secp = Secp256k1::new();
370
371
/// # let (secret_key, public_key) = secp.generate_keypair(&mut rand::thread_rng());
@@ -374,7 +375,7 @@ impl<C: Verification> Secp256k1<C> {
374
375
/// assert_eq!(secp.verify_ecdsa(&message, &sig, &public_key), Ok(()));
375
376
///
376
377
/// 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) ));
378
379
/// # }
379
380
/// ```
380
381
#[ inline]
@@ -383,7 +384,7 @@ impl<C: Verification> Secp256k1<C> {
383
384
msg : & Message ,
384
385
sig : & Signature ,
385
386
pk : & PublicKey ,
386
- ) -> Result < ( ) , Error > {
387
+ ) -> Result < ( ) , SysError > {
387
388
unsafe {
388
389
if ffi:: secp256k1_ecdsa_verify (
389
390
self . ctx . as_ptr ( ) ,
@@ -392,7 +393,7 @@ impl<C: Verification> Secp256k1<C> {
392
393
pk. as_c_ptr ( ) ,
393
394
) == 0
394
395
{
395
- Err ( Error :: IncorrectSignature )
396
+ Err ( SysError { } )
396
397
} else {
397
398
Ok ( ( ) )
398
399
}
@@ -427,3 +428,91 @@ pub(crate) fn der_length_check(sig: &ffi::Signature, max_len: usize) -> bool {
427
428
}
428
429
len <= max_len
429
430
}
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