2
2
3
3
use crate :: {
4
4
hex,
5
- signature:: { sig:: Signature , Parity , SignatureError } ,
5
+ signature:: {
6
+ sig:: Signature ,
7
+ super_sig:: { ArbitrarySuperSig , K256SuperSig , RlpSuperSig , SerdeSuperSig } ,
8
+ Parity , SignatureError ,
9
+ } ,
6
10
uint, U256 ,
7
11
} ;
8
12
use alloc:: vec:: Vec ;
9
13
use core:: str:: FromStr ;
10
- use crate :: signature:: super_signature:: { ArbitrarySuperSig , K256SuperSig , RlpSuperSig , SerdeSuperSig } ;
11
14
12
15
/// The order of the secp256k1 curve
13
16
const SECP256K1N_ORDER : U256 =
@@ -21,63 +24,20 @@ pub struct EcdsaSignature {
21
24
s : U256 ,
22
25
}
23
26
27
+ #[ cfg( test) ]
24
28
impl EcdsaSignature {
25
- /// Returns the recovery ID.
26
- #[ cfg( feature = "k256" ) ]
27
- #[ inline]
28
- const fn recid ( & self ) -> k256:: ecdsa:: RecoveryId {
29
- self . v . recid ( )
30
- }
31
-
32
- #[ cfg( feature = "k256" ) ]
33
- #[ doc( hidden) ]
34
- #[ deprecated( note = "use `Signature::recid` instead" ) ]
35
- pub const fn recovery_id ( & self ) -> k256:: ecdsa:: RecoveryId {
36
- self . recid ( )
37
- }
38
-
39
29
#[ doc( hidden) ]
40
30
fn test_signature ( ) -> Self {
41
31
Self :: from_scalars_and_parity (
42
32
b256 ! ( "840cfc572845f5786e702984c2a582528cad4b49b2a10b9db1be7fca90058565" ) ,
43
33
b256 ! ( "25e7109ceb98168d95b09b18bbf6b685130e0562f233877d492b94eee0c5b6d1" ) ,
44
34
false ,
45
35
)
46
- . unwrap ( )
36
+ . unwrap ( )
47
37
}
48
38
}
49
39
50
- impl RlpSuperSig for EcdsaSignature { }
51
-
52
- impl K256SuperSig for EcdsaSignature { }
53
-
54
- impl SerdeSuperSig for EcdsaSignature { }
55
-
56
- impl ArbitrarySuperSig for EcdsaSignature { }
57
-
58
- impl Signature for EcdsaSignature {
59
- /// Instantiate a new signature from `r`, `s`, and `v` values.
60
- fn new ( r : U256 , s : U256 , v : Parity ) -> Self {
61
- Self { r, s, v }
62
- }
63
-
64
- /// Returns the `r` component of this signature.
65
- #[ inline]
66
- fn r ( & self ) -> U256 {
67
- self . r
68
- }
69
-
70
- /// Returns the `s` component of this signature.
71
- #[ inline]
72
- fn s ( & self ) -> U256 {
73
- self . s
74
- }
75
-
76
- /// Returns the recovery ID as a `u8`.
77
- #[ inline]
78
- fn v ( & self ) -> Parity {
79
- self . v
80
- }
40
+ impl RlpSuperSig for EcdsaSignature {
81
41
#[ cfg( feature = "rlp" ) ]
82
42
fn decode_rlp_vrs ( buf : & mut & [ u8 ] ) -> Result < Self , alloy_rlp:: Error > {
83
43
use alloy_rlp:: Decodable ;
@@ -90,34 +50,40 @@ impl Signature for EcdsaSignature {
90
50
. map_err ( |_| alloy_rlp:: Error :: Custom ( "attempted to decode invalid field element" ) )
91
51
}
92
52
93
- /// Returns the byte-array representation of this signature.
94
- ///
95
- /// The first 32 bytes are the `r` value, the second 32 bytes the `s` value
96
- /// and the final byte is the `v` value in 'Electrum' notation.
97
- #[ inline]
98
- fn as_bytes ( & self ) -> [ u8 ; 65 ] {
99
- let mut sig = [ 0u8 ; 65 ] ;
100
- sig[ ..32 ] . copy_from_slice ( & self . r . to_be_bytes :: < 32 > ( ) ) ;
101
- sig[ 32 ..64 ] . copy_from_slice ( & self . s . to_be_bytes :: < 32 > ( ) ) ;
102
- sig[ 64 ] = self . v . y_parity_byte_non_eip155 ( ) . unwrap_or ( self . v . y_parity_byte ( ) ) ;
103
- sig
53
+ /// Length of RLP RS field encoding
54
+ #[ cfg( feature = "rlp" ) ]
55
+ fn rlp_rs_len ( & self ) -> usize {
56
+ alloy_rlp:: Encodable :: length ( & self . r ) + alloy_rlp:: Encodable :: length ( & self . s )
104
57
}
105
58
106
- /// Normalizes the signature into "low S" form as described in
107
- /// [BIP 0062: Dealing with Malleability][1].
108
- ///
109
- /// [1]: https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki
110
- #[ inline]
111
- fn normalize_s ( & self ) -> Option < Self > {
112
- let s = self . s ( ) ;
59
+ #[ cfg( feature = "rlp" ) ]
60
+ /// Length of RLP V field encoding
61
+ fn rlp_vrs_len ( & self ) -> usize {
62
+ self . rlp_rs_len ( ) + alloy_rlp:: Encodable :: length ( & self . v )
63
+ }
113
64
114
- if s > SECP256K1N_ORDER >> 1 {
115
- Some ( Self { v : self . v . inverted ( ) , r : self . r , s : SECP256K1N_ORDER - s } )
116
- } else {
117
- None
118
- }
65
+ /// Write R and S to an RLP buffer in progress.
66
+ #[ cfg( feature = "rlp" ) ]
67
+ fn write_rlp_rs ( & self , out : & mut dyn alloy_rlp:: BufMut ) {
68
+ alloy_rlp:: Encodable :: encode ( & self . r , out) ;
69
+ alloy_rlp:: Encodable :: encode ( & self . s , out) ;
70
+ }
71
+
72
+ /// Write the V to an RLP buffer without using EIP-155.
73
+ #[ cfg( feature = "rlp" ) ]
74
+ fn write_rlp_v ( & self , out : & mut dyn alloy_rlp:: BufMut ) {
75
+ alloy_rlp:: Encodable :: encode ( & self . v , out) ;
76
+ }
77
+
78
+ /// Write the VRS to the output. The V will always be 27 or 28.
79
+ #[ cfg( feature = "rlp" ) ]
80
+ fn write_rlp_vrs ( & self , out : & mut dyn alloy_rlp:: BufMut ) {
81
+ self . write_rlp_v ( out) ;
82
+ self . write_rlp_rs ( out) ;
119
83
}
84
+ }
120
85
86
+ impl K256SuperSig for EcdsaSignature {
121
87
/// Recovers an [`Address`] from this signature and the given message by first prefixing and
122
88
/// hashing the message according to [EIP-191](crate::eip191_hash_message).
123
89
///
@@ -174,6 +140,102 @@ impl Signature for EcdsaSignature {
174
140
. map_err ( Into :: into)
175
141
}
176
142
143
+ /// Returns the inner ECDSA signature.
144
+ #[ cfg( feature = "k256" ) ]
145
+ #[ inline]
146
+ fn into_inner ( self ) -> k256:: ecdsa:: Signature {
147
+ self . try_into ( ) . expect ( "signature conversion failed" )
148
+ }
149
+
150
+ /// Returns the inner ECDSA signature.
151
+ #[ cfg( feature = "k256" ) ]
152
+ #[ inline]
153
+ fn to_k256 ( & self ) -> Result < k256:: ecdsa:: Signature , k256:: ecdsa:: Error > {
154
+ k256:: ecdsa:: Signature :: from_scalars ( self . r . to_be_bytes ( ) , self . s . to_be_bytes ( ) )
155
+ }
156
+
157
+ /// Instantiate from a signature and recovery id
158
+ #[ cfg( feature = "k256" ) ]
159
+ fn from_signature_and_parity < T : TryInto < Parity , Error = E > , E : Into < SignatureError > > (
160
+ sig : k256:: ecdsa:: Signature ,
161
+ parity : T ,
162
+ ) -> Result < Self , SignatureError > {
163
+ let r = U256 :: from_be_slice ( sig. r ( ) . to_bytes ( ) . as_ref ( ) ) ;
164
+ let s = U256 :: from_be_slice ( sig. s ( ) . to_bytes ( ) . as_ref ( ) ) ;
165
+ Ok ( Self { v : parity. try_into ( ) . map_err ( Into :: into) ?, r, s } )
166
+ }
167
+
168
+ /// Returns the recovery ID.
169
+ #[ cfg( feature = "k256" ) ]
170
+ #[ inline]
171
+ fn recid ( & self ) -> k256:: ecdsa:: RecoveryId {
172
+ self . v . recid ( )
173
+ }
174
+
175
+ /// Deprecated - use `Signature::recid` instead
176
+ #[ cfg( feature = "k256" ) ]
177
+ #[ doc( hidden) ]
178
+ fn recovery_id ( & self ) -> k256:: ecdsa:: RecoveryId {
179
+ self . recid ( )
180
+ }
181
+ }
182
+
183
+ impl SerdeSuperSig for EcdsaSignature { }
184
+
185
+ impl ArbitrarySuperSig for EcdsaSignature { }
186
+
187
+ impl Signature for EcdsaSignature {
188
+ /// Instantiate a new signature from `r`, `s`, and `v` values.
189
+ fn new ( r : U256 , s : U256 , v : Parity ) -> Self {
190
+ Self { r, s, v }
191
+ }
192
+
193
+ /// Returns the `r` component of this signature.
194
+ #[ inline]
195
+ fn r ( & self ) -> U256 {
196
+ self . r
197
+ }
198
+
199
+ /// Returns the `s` component of this signature.
200
+ #[ inline]
201
+ fn s ( & self ) -> U256 {
202
+ self . s
203
+ }
204
+
205
+ /// Returns the recovery ID as a `u8`.
206
+ #[ inline]
207
+ fn v ( & self ) -> Parity {
208
+ self . v
209
+ }
210
+
211
+ /// Returns the byte-array representation of this signature.
212
+ ///
213
+ /// The first 32 bytes are the `r` value, the second 32 bytes the `s` value
214
+ /// and the final byte is the `v` value in 'Electrum' notation.
215
+ #[ inline]
216
+ fn as_bytes ( & self ) -> [ u8 ; 65 ] {
217
+ let mut sig = [ 0u8 ; 65 ] ;
218
+ sig[ ..32 ] . copy_from_slice ( & self . r . to_be_bytes :: < 32 > ( ) ) ;
219
+ sig[ 32 ..64 ] . copy_from_slice ( & self . s . to_be_bytes :: < 32 > ( ) ) ;
220
+ sig[ 64 ] = self . v . y_parity_byte_non_eip155 ( ) . unwrap_or ( self . v . y_parity_byte ( ) ) ;
221
+ sig
222
+ }
223
+
224
+ /// Normalizes the signature into "low S" form as described in
225
+ /// [BIP 0062: Dealing with Malleability][1].
226
+ ///
227
+ /// [1]: https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki
228
+ #[ inline]
229
+ fn normalize_s ( & self ) -> Option < Self > {
230
+ let s = self . s ( ) ;
231
+
232
+ if s > SECP256K1N_ORDER >> 1 {
233
+ Some ( Self { v : self . v . inverted ( ) , r : self . r , s : SECP256K1N_ORDER - s } )
234
+ } else {
235
+ None
236
+ }
237
+ }
238
+
177
239
/// Modifies the recovery ID by applying [EIP-155] to a `v` value.
178
240
///
179
241
/// [EIP-155]: https://eips.ethereum.org/EIPS/eip-155
@@ -232,63 +294,6 @@ impl Signature for EcdsaSignature {
232
294
) -> Result < Self , SignatureError > {
233
295
Ok ( Self { v : parity. try_into ( ) . map_err ( Into :: into) ?, r, s } )
234
296
}
235
-
236
- /// Length of RLP RS field encoding
237
- #[ cfg( feature = "rlp" ) ]
238
- fn rlp_rs_len ( & self ) -> usize {
239
- alloy_rlp:: Encodable :: length ( & self . r ) + alloy_rlp:: Encodable :: length ( & self . s )
240
- }
241
-
242
- #[ cfg( feature = "rlp" ) ]
243
- /// Length of RLP V field encoding
244
- fn rlp_vrs_len ( & self ) -> usize {
245
- self . rlp_rs_len ( ) + alloy_rlp:: Encodable :: length ( & self . v )
246
- }
247
-
248
- /// Write R and S to an RLP buffer in progress.
249
- #[ cfg( feature = "rlp" ) ]
250
- fn write_rlp_rs ( & self , out : & mut dyn alloy_rlp:: BufMut ) {
251
- alloy_rlp:: Encodable :: encode ( & self . r , out) ;
252
- alloy_rlp:: Encodable :: encode ( & self . s , out) ;
253
- }
254
-
255
- /// Write the V to an RLP buffer without using EIP-155.
256
- #[ cfg( feature = "rlp" ) ]
257
- fn write_rlp_v ( & self , out : & mut dyn alloy_rlp:: BufMut ) {
258
- alloy_rlp:: Encodable :: encode ( & self . v , out) ;
259
- }
260
-
261
- /// Write the VRS to the output. The V will always be 27 or 28.
262
- #[ cfg( feature = "rlp" ) ]
263
- fn write_rlp_vrs ( & self , out : & mut dyn alloy_rlp:: BufMut ) {
264
- self . write_rlp_v ( out) ;
265
- self . write_rlp_rs ( out) ;
266
- }
267
-
268
- /// Returns the inner ECDSA signature.
269
- #[ cfg( feature = "k256" ) ]
270
- #[ inline]
271
- fn into_inner ( self ) -> k256:: ecdsa:: Signature {
272
- self . try_into ( ) . expect ( "signature conversion failed" )
273
- }
274
-
275
- /// Returns the inner ECDSA signature.
276
- #[ cfg( feature = "k256" ) ]
277
- #[ inline]
278
- fn to_k256 ( & self ) -> Result < k256:: ecdsa:: Signature , k256:: ecdsa:: Error > {
279
- k256:: ecdsa:: Signature :: from_scalars ( self . r . to_be_bytes ( ) , self . s . to_be_bytes ( ) )
280
- }
281
-
282
- /// Instantiate from a signature and recovery id
283
- #[ cfg( feature = "k256" ) ]
284
- fn from_signature_and_parity < T : TryInto < Parity , Error = E > , E : Into < SignatureError > > (
285
- sig : k256:: ecdsa:: Signature ,
286
- parity : T ,
287
- ) -> Result < Self , SignatureError > {
288
- let r = U256 :: from_be_slice ( sig. r ( ) . to_bytes ( ) . as_ref ( ) ) ;
289
- let s = U256 :: from_be_slice ( sig. s ( ) . to_bytes ( ) . as_ref ( ) ) ;
290
- Ok ( Self { v : parity. try_into ( ) . map_err ( Into :: into) ?, r, s } )
291
- }
292
297
}
293
298
294
299
impl TryFrom < & [ u8 ] > for EcdsaSignature {
0 commit comments