Skip to content

Commit a353cf6

Browse files
committed
- rename super_sign
- add methods to feature-traits
1 parent ea15d09 commit a353cf6

File tree

7 files changed

+268
-249
lines changed

7 files changed

+268
-249
lines changed

crates/primitives/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,10 @@ mod signed;
5454
pub use signed::{BigIntConversionError, ParseSignedError, Sign, Signed};
5555

5656
mod signature;
57-
pub use signature::{normalize_v, to_eip155_v, Parity, PrimitiveSignature, EcdsaSignature, Signature, SignatureError};
57+
pub use signature::{
58+
normalize_v, to_eip155_v, ArbitrarySuperSig, EcdsaSignature, K256SuperSig, Parity,
59+
PrimitiveSignature, RlpSuperSig, SerdeSuperSig, Signature, SignatureError,
60+
};
5861

5962
pub mod utils;
6063
pub use utils::{eip191_hash_message, keccak256, Keccak256};

crates/primitives/src/signature/ecdsa_sig.rs

Lines changed: 133 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22

33
use crate::{
44
hex,
5-
signature::{sig::Signature, Parity, SignatureError},
5+
signature::{
6+
sig::Signature,
7+
super_sig::{ArbitrarySuperSig, K256SuperSig, RlpSuperSig, SerdeSuperSig},
8+
Parity, SignatureError,
9+
},
610
uint, U256,
711
};
812
use alloc::vec::Vec;
913
use core::str::FromStr;
10-
use crate::signature::super_signature::{ArbitrarySuperSig, K256SuperSig, RlpSuperSig, SerdeSuperSig};
1114

1215
/// The order of the secp256k1 curve
1316
const SECP256K1N_ORDER: U256 =
@@ -21,63 +24,20 @@ pub struct EcdsaSignature {
2124
s: U256,
2225
}
2326

27+
#[cfg(test)]
2428
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-
3929
#[doc(hidden)]
4030
fn test_signature() -> Self {
4131
Self::from_scalars_and_parity(
4232
b256!("840cfc572845f5786e702984c2a582528cad4b49b2a10b9db1be7fca90058565"),
4333
b256!("25e7109ceb98168d95b09b18bbf6b685130e0562f233877d492b94eee0c5b6d1"),
4434
false,
4535
)
46-
.unwrap()
36+
.unwrap()
4737
}
4838
}
4939

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 {
8141
#[cfg(feature = "rlp")]
8242
fn decode_rlp_vrs(buf: &mut &[u8]) -> Result<Self, alloy_rlp::Error> {
8343
use alloy_rlp::Decodable;
@@ -90,34 +50,40 @@ impl Signature for EcdsaSignature {
9050
.map_err(|_| alloy_rlp::Error::Custom("attempted to decode invalid field element"))
9151
}
9252

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)
10457
}
10558

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+
}
11364

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);
11983
}
84+
}
12085

86+
impl K256SuperSig for EcdsaSignature {
12187
/// Recovers an [`Address`] from this signature and the given message by first prefixing and
12288
/// hashing the message according to [EIP-191](crate::eip191_hash_message).
12389
///
@@ -174,6 +140,102 @@ impl Signature for EcdsaSignature {
174140
.map_err(Into::into)
175141
}
176142

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+
177239
/// Modifies the recovery ID by applying [EIP-155] to a `v` value.
178240
///
179241
/// [EIP-155]: https://eips.ethereum.org/EIPS/eip-155
@@ -232,63 +294,6 @@ impl Signature for EcdsaSignature {
232294
) -> Result<Self, SignatureError> {
233295
Ok(Self { v: parity.try_into().map_err(Into::into)?, r, s })
234296
}
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-
}
292297
}
293298

294299
impl TryFrom<&[u8]> for EcdsaSignature {

crates/primitives/src/signature/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ pub use ecdsa_sig::EcdsaSignature;
99

1010
mod utils;
1111

12-
mod sig;
13-
mod super_signature;
12+
mod super_sig;
13+
pub use super_sig::{ArbitrarySuperSig, K256SuperSig, RlpSuperSig, SerdeSuperSig};
1414

15+
mod sig;
1516
pub use sig::Signature;
1617

1718
pub use utils::{normalize_v, to_eip155_v};

crates/primitives/src/signature/primitive_sig.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ impl TryFrom<PrimitiveSignature> for k256::ecdsa::Signature {
8888
#[cfg(feature = "rlp")]
8989
impl PrimitiveSignature {
9090
/// Decode an RLP-encoded VRS signature. Accepts `decode_parity` closure which allows to
91-
/// customize parity decoding and possibly extract additional data from it (e.g chain_id for
91+
/// customize parity decoding and possibly extract additional data from it (e.g. chain_id for
9292
/// legacy signature).
9393
pub fn decode_rlp_vrs(
9494
buf: &mut &[u8],

0 commit comments

Comments
 (0)