Skip to main content

alloy_primitives/signature/
sig.rs

1#![allow(clippy::missing_const_for_fn)] // On purpose for forward compatibility.
2
3use crate::{B256, U256, hex, normalize_v, signature::SignatureError, uint};
4use alloc::vec::Vec;
5use core::{fmt::Display, str::FromStr};
6
7#[cfg(any(feature = "k256", feature = "secp256k1"))]
8use crate::Address;
9
10/// The order of the [Secp256k1](https://en.bitcoin.it/wiki/Secp256k1) curve.
11const SECP256K1N_ORDER: U256 =
12    uint!(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141_U256);
13
14/// An Ethereum ECDSA signature.
15#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
16#[cfg_attr(feature = "diesel", derive(diesel::AsExpression, diesel::FromSqlRow))]
17#[cfg_attr(feature = "diesel", diesel(sql_type = diesel::sql_types::Binary))]
18pub struct Signature {
19    y_parity: bool,
20    r: U256,
21    s: U256,
22}
23
24impl Display for Signature {
25    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
26        write!(f, "0x{}", hex::encode(self.as_bytes()))
27    }
28}
29
30impl TryFrom<&[u8]> for Signature {
31    type Error = SignatureError;
32
33    /// Parses a 65-byte long raw signature.
34    ///
35    /// See [`from_raw`](Self::from_raw).
36    fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
37        Self::from_raw(bytes)
38    }
39}
40
41impl FromStr for Signature {
42    type Err = SignatureError;
43
44    fn from_str(s: &str) -> Result<Self, Self::Err> {
45        Self::from_raw_array(&hex::decode_to_array(s)?)
46    }
47}
48
49impl From<&Signature> for [u8; 65] {
50    #[inline]
51    fn from(value: &Signature) -> [u8; 65] {
52        value.as_bytes()
53    }
54}
55
56impl From<Signature> for [u8; 65] {
57    #[inline]
58    fn from(value: Signature) -> [u8; 65] {
59        value.as_bytes()
60    }
61}
62
63impl From<&Signature> for Vec<u8> {
64    #[inline]
65    fn from(value: &Signature) -> Self {
66        value.as_bytes().to_vec()
67    }
68}
69
70impl From<Signature> for Vec<u8> {
71    #[inline]
72    fn from(value: Signature) -> Self {
73        value.as_bytes().to_vec()
74    }
75}
76
77#[cfg(feature = "k256")]
78impl From<(k256::ecdsa::Signature, k256::ecdsa::RecoveryId)> for Signature {
79    fn from(value: (k256::ecdsa::Signature, k256::ecdsa::RecoveryId)) -> Self {
80        Self::from_signature_and_parity(value.0, value.1.is_y_odd())
81    }
82}
83
84#[cfg(feature = "secp256k1")]
85impl From<secp256k1::ecdsa::RecoverableSignature> for Signature {
86    fn from(value: secp256k1::ecdsa::RecoverableSignature) -> Self {
87        let (recid, bytes) = value.serialize_compact();
88        let r = U256::from_be_slice(&bytes[..32]);
89        let s = U256::from_be_slice(&bytes[32..]);
90        let v = matches!(
91            recid,
92            secp256k1::ecdsa::RecoveryId::One | secp256k1::ecdsa::RecoveryId::Three
93        );
94        Self { y_parity: v, r, s }
95    }
96}
97
98#[cfg(feature = "k256")]
99impl TryFrom<Signature> for k256::ecdsa::Signature {
100    type Error = k256::ecdsa::Error;
101
102    fn try_from(value: Signature) -> Result<Self, Self::Error> {
103        value.to_k256()
104    }
105}
106
107#[cfg(feature = "rlp")]
108impl Signature {
109    /// Decode an RLP-encoded VRS signature. Accepts `decode_parity` closure which allows to
110    /// customize parity decoding and possibly extract additional data from it (e.g chain_id for
111    /// legacy signature).
112    pub fn decode_rlp_vrs(
113        buf: &mut &[u8],
114        decode_parity: impl FnOnce(&mut &[u8]) -> alloy_rlp::Result<bool>,
115    ) -> Result<Self, alloy_rlp::Error> {
116        use alloy_rlp::Decodable;
117
118        let parity = decode_parity(buf)?;
119        let r = Decodable::decode(buf)?;
120        let s = Decodable::decode(buf)?;
121
122        Ok(Self::new(r, s, parity))
123    }
124}
125
126impl Signature {
127    /// Instantiate a new signature from `r`, `s`, and `v` values.
128    #[inline]
129    pub const fn new(r: U256, s: U256, y_parity: bool) -> Self {
130        Self { r, s, y_parity }
131    }
132
133    /// Parses a 65-byte long raw signature.
134    ///
135    /// The first 32 bytes is the `r` value, the second 32 bytes the `s` value, and the final byte
136    /// is the `v` value in 'Electrum' notation.
137    #[inline]
138    pub fn from_raw(bytes: &[u8]) -> Result<Self, SignatureError> {
139        Self::from_raw_array(
140            bytes.try_into().map_err(|_| SignatureError::FromBytes("expected exactly 65 bytes"))?,
141        )
142    }
143
144    /// Parses a 65-byte long raw signature.
145    ///
146    /// See [`from_raw`](Self::from_raw).
147    #[inline]
148    pub fn from_raw_array(bytes: &[u8; 65]) -> Result<Self, SignatureError> {
149        let [bytes @ .., v] = bytes;
150        let v = *v as u64;
151        let Some(parity) = normalize_v(v) else { return Err(SignatureError::InvalidParity(v)) };
152        Ok(Self::from_bytes_and_parity(bytes, parity))
153    }
154
155    /// Parses a signature from a byte slice, with a v value
156    ///
157    /// # Panics
158    ///
159    /// If the slice is not at least 64 bytes long.
160    #[inline]
161    #[track_caller]
162    pub fn from_bytes_and_parity(bytes: &[u8], parity: bool) -> Self {
163        let (r_bytes, s_bytes) = bytes[..64].split_at(32);
164        let r = U256::from_be_slice(r_bytes);
165        let s = U256::from_be_slice(s_bytes);
166        Self::new(r, s, parity)
167    }
168
169    /// Returns the byte-array representation of this signature.
170    ///
171    /// The first 32 bytes are the `r` value, the second 32 bytes the `s` value
172    /// and the final byte is the `v` value in 'Electrum' notation.
173    #[inline]
174    pub fn as_bytes(&self) -> [u8; 65] {
175        let mut sig = [0u8; 65];
176        sig[..32].copy_from_slice(&self.r.to_be_bytes::<32>());
177        sig[32..64].copy_from_slice(&self.s.to_be_bytes::<32>());
178        sig[64] = self.v_byte();
179        sig
180    }
181
182    /// Returns the byte-array representation of this signature as (r, s, y_parity).
183    ///
184    /// The first 32 bytes are the `r` value, the second 32 bytes the `s` value,
185    /// and the final byte is the `y_parity` value as-is (0 or 1).
186    ///
187    /// See [`as_erc2098`](Self::as_erc2098) for the compact ERC-2098 representation.
188    #[inline]
189    pub fn as_rsy(&self) -> [u8; 65] {
190        let mut sig = [0u8; 65];
191        sig[..32].copy_from_slice(&self.r.to_be_bytes::<32>());
192        sig[32..64].copy_from_slice(&self.s.to_be_bytes::<32>());
193        sig[64] = self.y_parity as u8;
194        sig
195    }
196
197    /// Decode the signature from the ERC-2098 compact representation.
198    ///
199    /// The first 32 bytes are the `r` value, and the next 32 bytes are the `s` value with `yParity`
200    /// in the top bit of the `s` value, as described in ERC-2098.
201    ///
202    /// See <https://eips.ethereum.org/EIPS/eip-2098>
203    ///
204    /// # Panics
205    ///
206    /// If the slice is not at least 64 bytes long.
207    pub fn from_erc2098(bytes: &[u8]) -> Self {
208        let (r_bytes, y_and_s_bytes) = bytes[..64].split_at(32);
209        let r = U256::from_be_slice(r_bytes);
210        let y_and_s = U256::from_be_slice(y_and_s_bytes);
211        let y_parity = y_and_s.bit(255);
212        let mut s = y_and_s;
213        s.set_bit(255, false);
214        Self { y_parity, r, s }
215    }
216
217    /// Returns the ERC-2098 compact representation of this signature.
218    ///
219    /// The first 32 bytes are the `r` value, and the next 32 bytes are the `s` value with `yParity`
220    /// in the top bit of the `s` value, as described in ERC-2098.
221    ///
222    /// See <https://eips.ethereum.org/EIPS/eip-2098>
223    pub fn as_erc2098(&self) -> [u8; 64] {
224        let normalized = self.normalized_s();
225        // The top bit of the `s` parameters is always 0, due to the use of canonical
226        // signatures which flip the solution parity to prevent negative values, which was
227        // introduced as a constraint in Homestead.
228        let mut sig = [0u8; 64];
229        sig[..32].copy_from_slice(&normalized.r().to_be_bytes::<32>());
230        sig[32..64].copy_from_slice(&normalized.s().to_be_bytes::<32>());
231        debug_assert_eq!(sig[32] >> 7, 0, "top bit of s should be 0");
232        sig[32] |= (normalized.y_parity as u8) << 7;
233        sig
234    }
235
236    /// Sets the recovery ID by normalizing a `v` value.
237    #[inline]
238    pub fn with_parity(mut self, v: bool) -> Self {
239        self.y_parity = v;
240        self
241    }
242
243    /// Returns the inner ECDSA signature.
244    #[cfg(feature = "k256")]
245    #[inline]
246    pub fn to_k256(self) -> Result<k256::ecdsa::Signature, k256::ecdsa::Error> {
247        k256::ecdsa::Signature::from_scalars(self.r.to_be_bytes(), self.s.to_be_bytes())
248    }
249
250    /// Returns the inner ECDSA recoverable signature using the `secp256k1` backend.
251    #[cfg(feature = "secp256k1")]
252    #[inline]
253    pub fn to_secp256k1(&self) -> Result<secp256k1::ecdsa::RecoverableSignature, secp256k1::Error> {
254        let mut bytes = [0u8; 64];
255        bytes[..32].copy_from_slice(&self.r.to_be_bytes::<32>());
256        bytes[32..].copy_from_slice(&self.s.to_be_bytes::<32>());
257        secp256k1::ecdsa::RecoverableSignature::from_compact(&bytes, self.secp256k1_recid())
258    }
259
260    /// Instantiate from a signature and recovery id
261    #[cfg(feature = "k256")]
262    pub fn from_signature_and_parity(sig: k256::ecdsa::Signature, v: bool) -> Self {
263        let r = U256::from_be_slice(sig.r().to_bytes().as_ref());
264        let s = U256::from_be_slice(sig.s().to_bytes().as_ref());
265        Self { y_parity: v, r, s }
266    }
267
268    /// Creates a [`Signature`] from the serialized `r` and `s` scalar values, which
269    /// comprise the ECDSA signature, alongside a `v` value, used to determine the recovery ID.
270    #[inline]
271    pub fn from_scalars_and_parity(r: B256, s: B256, parity: bool) -> Self {
272        Self::new(U256::from_be_bytes(r.0), U256::from_be_bytes(s.0), parity)
273    }
274
275    /// Normalizes the signature into "low S" form as described in
276    /// [BIP 0062: Dealing with Malleability][1].
277    ///
278    /// If `s` is already normalized, returns `None`.
279    ///
280    /// [1]: https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki
281    #[inline]
282    pub fn normalize_s(&self) -> Option<Self> {
283        let s = self.s();
284        if s > SECP256K1N_ORDER >> 1 {
285            Some(Self { y_parity: !self.y_parity, r: self.r, s: SECP256K1N_ORDER - s })
286        } else {
287            None
288        }
289    }
290
291    /// Normalizes the signature into "low S" form as described in
292    /// [BIP 0062: Dealing with Malleability][1].
293    ///
294    /// If `s` is already normalized, returns `self`.
295    ///
296    /// [1]: https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki
297    #[inline]
298    pub fn normalized_s(self) -> Self {
299        self.normalize_s().unwrap_or(self)
300    }
301
302    /// Returns the recovery ID.
303    #[cfg(feature = "k256")]
304    #[inline]
305    pub fn recid(&self) -> k256::ecdsa::RecoveryId {
306        k256::ecdsa::RecoveryId::new(self.y_parity, false)
307    }
308
309    /// Returns the recovery ID as a [`secp256k1::ecdsa::RecoveryId`].
310    #[cfg(feature = "secp256k1")]
311    #[inline]
312    pub fn secp256k1_recid(&self) -> secp256k1::ecdsa::RecoveryId {
313        if self.y_parity {
314            secp256k1::ecdsa::RecoveryId::One
315        } else {
316            secp256k1::ecdsa::RecoveryId::Zero
317        }
318    }
319
320    /// Recovers an [`Address`] from this signature and the given message by first prefixing and
321    /// hashing the message according to [EIP-191](crate::eip191_hash_message).
322    #[cfg(any(feature = "k256", feature = "secp256k1"))]
323    #[inline]
324    pub fn recover_address_from_msg<T: AsRef<[u8]>>(
325        &self,
326        msg: T,
327    ) -> Result<Address, SignatureError> {
328        self.recover_address_from_prehash(&crate::eip191_hash_message(msg))
329    }
330
331    /// Recovers an [`Address`] from this signature and the given prehashed message.
332    #[cfg(any(feature = "k256", feature = "secp256k1"))]
333    #[inline]
334    pub fn recover_address_from_prehash(&self, prehash: &B256) -> Result<Address, SignatureError> {
335        cfg_if::cfg_if! {
336            if #[cfg(feature = "secp256k1")] {
337                let pubkey = self.recover_from_prehash_secp256k1(prehash)?;
338                Ok(Address::from_raw_public_key(&pubkey.serialize_uncompressed()[1..]))
339            } else {
340                let vk = self.recover_from_prehash_k256(prehash)?;
341                Ok(Address::from_public_key(&vk))
342            }
343        }
344    }
345
346    /// Recovers a [`VerifyingKey`] from this signature and the given message by first prefixing and
347    /// hashing the message according to [EIP-191](crate::eip191_hash_message).
348    ///
349    /// [`VerifyingKey`]: k256::ecdsa::VerifyingKey
350    #[cfg(feature = "k256")]
351    #[inline]
352    pub fn recover_from_msg<T: AsRef<[u8]>>(
353        &self,
354        msg: T,
355    ) -> Result<k256::ecdsa::VerifyingKey, SignatureError> {
356        self.recover_from_prehash(&crate::eip191_hash_message(msg))
357    }
358
359    /// Recovers a [`VerifyingKey`] from this signature and the given prehashed message.
360    ///
361    /// [`VerifyingKey`]: k256::ecdsa::VerifyingKey
362    #[cfg(feature = "k256")]
363    #[inline]
364    pub fn recover_from_prehash(
365        &self,
366        prehash: &B256,
367    ) -> Result<k256::ecdsa::VerifyingKey, SignatureError> {
368        self.recover_from_prehash_k256(prehash)
369    }
370
371    /// Recovers a [`VerifyingKey`] using the `k256` backend.
372    ///
373    /// [`VerifyingKey`]: k256::ecdsa::VerifyingKey
374    #[cfg(feature = "k256")]
375    #[inline]
376    fn recover_from_prehash_k256(
377        &self,
378        prehash: &B256,
379    ) -> Result<k256::ecdsa::VerifyingKey, SignatureError> {
380        let this = self.normalized_s();
381        k256::ecdsa::VerifyingKey::recover_from_prehash(
382            prehash.as_slice(),
383            &this.to_k256()?,
384            this.recid(),
385        )
386        .map_err(Into::into)
387    }
388
389    /// Recovers a [`secp256k1::PublicKey`] from this signature and the given message by first
390    /// prefixing and hashing the message according to [EIP-191](crate::eip191_hash_message).
391    #[cfg(feature = "secp256k1")]
392    #[inline]
393    pub fn recover_from_msg_secp256k1<T: AsRef<[u8]>>(
394        &self,
395        msg: T,
396    ) -> Result<secp256k1::PublicKey, SignatureError> {
397        self.recover_from_prehash_secp256k1(&crate::eip191_hash_message(msg))
398    }
399
400    /// Recovers a [`secp256k1::PublicKey`] from this signature and the given prehashed message.
401    #[cfg(feature = "secp256k1")]
402    #[inline]
403    pub fn recover_from_prehash_secp256k1(
404        &self,
405        prehash: &B256,
406    ) -> Result<secp256k1::PublicKey, SignatureError> {
407        let this = self.normalized_s();
408        let sig = this.to_secp256k1()?;
409        let msg = secp256k1::Message::from_digest(prehash.0);
410        #[cfg(feature = "std")]
411        {
412            secp256k1::SECP256K1.recover_ecdsa(msg, &sig).map_err(Into::into)
413        }
414        #[cfg(not(feature = "std"))]
415        {
416            let secp = secp256k1::Secp256k1::verification_only();
417            secp.recover_ecdsa(msg, &sig).map_err(Into::into)
418        }
419    }
420
421    /// Returns the `r` component of this signature.
422    #[inline]
423    pub fn r(&self) -> U256 {
424        self.r
425    }
426
427    /// Returns the `s` component of this signature.
428    #[inline]
429    pub fn s(&self) -> U256 {
430        self.s
431    }
432
433    /// Returns the recovery ID as a `bool`.
434    #[inline]
435    pub fn v(&self) -> bool {
436        self.y_parity
437    }
438
439    /// Returns the recovery ID in 'Electrum' notation (`27 + y_parity`).
440    #[inline]
441    pub const fn v_byte(&self) -> u8 {
442        27 + self.y_parity as u8
443    }
444
445    /// Length of RLP RS field encoding
446    #[cfg(feature = "rlp")]
447    pub fn rlp_rs_len(&self) -> usize {
448        alloy_rlp::Encodable::length(&self.r) + alloy_rlp::Encodable::length(&self.s)
449    }
450
451    /// Write R and S to an RLP buffer in progress.
452    #[cfg(feature = "rlp")]
453    pub fn write_rlp_rs(&self, out: &mut dyn alloy_rlp::BufMut) {
454        alloy_rlp::Encodable::encode(&self.r, out);
455        alloy_rlp::Encodable::encode(&self.s, out);
456    }
457
458    /// Write the VRS to the output.
459    #[cfg(feature = "rlp")]
460    pub fn write_rlp_vrs(&self, out: &mut dyn alloy_rlp::BufMut, v: impl alloy_rlp::Encodable) {
461        v.encode(out);
462        self.write_rlp_rs(out);
463    }
464
465    #[doc(hidden)]
466    #[inline(always)]
467    pub fn test_signature() -> Self {
468        Self::from_scalars_and_parity(
469            b256!("0x840cfc572845f5786e702984c2a582528cad4b49b2a10b9db1be7fca90058565"),
470            b256!("0x25e7109ceb98168d95b09b18bbf6b685130e0562f233877d492b94eee0c5b6d1"),
471            false,
472        )
473    }
474}
475
476#[cfg(feature = "arbitrary")]
477impl<'a> arbitrary::Arbitrary<'a> for Signature {
478    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
479        Ok(Self::new(u.arbitrary()?, u.arbitrary()?, u.arbitrary()?))
480    }
481}
482
483#[cfg(feature = "arbitrary")]
484impl proptest::arbitrary::Arbitrary for Signature {
485    type Parameters = ();
486    type Strategy = proptest::strategy::Map<
487        <(U256, U256, bool) as proptest::arbitrary::Arbitrary>::Strategy,
488        fn((U256, U256, bool)) -> Self,
489    >;
490
491    fn arbitrary_with((): Self::Parameters) -> Self::Strategy {
492        use proptest::strategy::Strategy;
493        proptest::arbitrary::any::<(U256, U256, bool)>()
494            .prop_map(|(r, s, y_parity)| Self::new(r, s, y_parity))
495    }
496}
497
498#[cfg(feature = "serde")]
499mod signature_serde {
500    use super::Signature;
501    use crate::{U64, U256, normalize_v};
502    use serde::{Deserialize, Deserializer, Serialize};
503
504    #[derive(Serialize, Deserialize)]
505    struct HumanReadableRepr {
506        r: U256,
507        s: U256,
508        #[serde(rename = "yParity")]
509        y_parity: Option<U64>,
510        #[serde(default, skip_serializing_if = "Option::is_none")]
511        v: Option<U64>,
512    }
513
514    type NonHumanReadableRepr = (U256, U256, U64);
515
516    impl Serialize for Signature {
517        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
518        where
519            S: serde::Serializer,
520        {
521            // if the serializer is human readable, serialize as a map, otherwise as a tuple
522            if serializer.is_human_readable() {
523                HumanReadableRepr {
524                    y_parity: Some(U64::from(self.y_parity as u64)),
525                    v: Some(U64::from(self.y_parity as u64)),
526                    r: self.r,
527                    s: self.s,
528                }
529                .serialize(serializer)
530            } else {
531                let repr: NonHumanReadableRepr = (self.r, self.s, U64::from(self.y_parity as u64));
532                repr.serialize(serializer)
533            }
534        }
535    }
536
537    impl<'de> Deserialize<'de> for Signature {
538        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
539        where
540            D: Deserializer<'de>,
541        {
542            let (y_parity, v, r, s) = if deserializer.is_human_readable() {
543                let HumanReadableRepr { y_parity, v, r, s } = <_>::deserialize(deserializer)?;
544                (y_parity, v, r, s)
545            } else {
546                let (r, s, y_parity) = NonHumanReadableRepr::deserialize(deserializer)?;
547                (Some(y_parity), None, r, s)
548            };
549
550            // Attempt to extract `y_parity` bit from either `yParity` key or `v` value.
551            let y_parity = if let Some(y_parity) = y_parity {
552                match y_parity.to::<u64>() {
553                    0 => false,
554                    1 => true,
555                    _ => return Err(serde::de::Error::custom("invalid yParity")),
556                }
557            } else if let Some(v) = v {
558                normalize_v(v.to()).ok_or(serde::de::Error::custom("invalid v"))?
559            } else {
560                return Err(serde::de::Error::custom("missing `yParity` or `v`"));
561            };
562
563            Ok(Self::new(r, s, y_parity))
564        }
565    }
566}
567
568#[cfg(test)]
569mod tests {
570    use super::*;
571    use core::str::FromStr;
572
573    #[cfg(feature = "rlp")]
574    use alloy_rlp::{Decodable, Encodable};
575
576    #[test]
577    #[cfg(feature = "k256")]
578    #[cfg_attr(miri, ignore = "k256 is too slow under Miri")]
579    fn can_recover_tx_sender_not_normalized() {
580        let sig = Signature::from_str("48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c8041b").unwrap();
581        let hash = b256!("0x5eb4f5a33c621f32a8622d5f943b6b102994dfe4e5aebbefe69bb1b2aa0fc93e");
582        let expected = address!("0x0f65fe9276bc9a24ae7083ae28e2660ef72df99e");
583        assert_eq!(sig.recover_address_from_prehash(&hash).unwrap(), expected);
584    }
585
586    #[test]
587    #[cfg(feature = "k256")]
588    #[cfg_attr(miri, ignore = "k256 is too slow under Miri")]
589    fn recover_web3_signature() {
590        // test vector taken from:
591        // https://web3js.readthedocs.io/en/v1.2.2/web3-eth-accounts.html#sign
592        let sig = Signature::from_str(
593            "b91467e570a6466aa9e9876cbcd013baba02900b8979d43fe208a4a4f339f5fd6007e74cd82e037b800186422fc2da167c747ef045e5d18a5f5d4300f8e1a0291c"
594        ).expect("could not parse signature");
595        let expected = address!("0x2c7536E3605D9C16a7a3D7b1898e529396a65c23");
596        assert_eq!(sig.recover_address_from_msg("Some data").unwrap(), expected);
597    }
598
599    #[test]
600    fn signature_from_str() {
601        let s1 = Signature::from_str(
602            "0xaa231fbe0ed2b5418e6ba7c19bee2522852955ec50996c02a2fe3e71d30ddaf1645baf4823fea7cb4fcc7150842493847cfb6a6d63ab93e8ee928ee3f61f503500"
603        ).expect("could not parse 0x-prefixed signature");
604
605        let s2 = Signature::from_str(
606            "aa231fbe0ed2b5418e6ba7c19bee2522852955ec50996c02a2fe3e71d30ddaf1645baf4823fea7cb4fcc7150842493847cfb6a6d63ab93e8ee928ee3f61f503500"
607        ).expect("could not parse non-prefixed signature");
608
609        assert_eq!(s1, s2);
610    }
611
612    #[cfg(feature = "serde")]
613    #[test]
614    fn deserialize_with_parity() {
615        let raw_signature_with_y_parity = serde_json::json!({
616            "r": "0xc569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0",
617            "s": "0x1a891b566d369e79b7a66eecab1e008831e22daa15f91a0a0cf4f9f28f47ee05",
618            "v": "0x1",
619            "yParity": "0x1"
620        });
621
622        let signature: Signature = serde_json::from_value(raw_signature_with_y_parity).unwrap();
623
624        let expected = Signature::new(
625            U256::from_str("0xc569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0")
626                .unwrap(),
627            U256::from_str("0x1a891b566d369e79b7a66eecab1e008831e22daa15f91a0a0cf4f9f28f47ee05")
628                .unwrap(),
629            true,
630        );
631
632        assert_eq!(signature, expected);
633    }
634
635    #[cfg(feature = "serde")]
636    #[test]
637    fn serialize_both_parity() {
638        // this test should be removed if the struct moves to an enum based on tx type
639        let signature = Signature::new(
640            U256::from_str("0xc569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0")
641                .unwrap(),
642            U256::from_str("0x1a891b566d369e79b7a66eecab1e008831e22daa15f91a0a0cf4f9f28f47ee05")
643                .unwrap(),
644            true,
645        );
646
647        let serialized = serde_json::to_string(&signature).unwrap();
648        assert_eq!(
649            serialized,
650            r#"{"r":"0xc569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0","s":"0x1a891b566d369e79b7a66eecab1e008831e22daa15f91a0a0cf4f9f28f47ee05","yParity":"0x1","v":"0x1"}"#
651        );
652    }
653
654    #[cfg(feature = "serde")]
655    #[test]
656    fn serialize_v_only() {
657        // this test should be removed if the struct moves to an enum based on tx type
658        let signature = Signature::new(
659            U256::from_str("0xc569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0")
660                .unwrap(),
661            U256::from_str("0x1a891b566d369e79b7a66eecab1e008831e22daa15f91a0a0cf4f9f28f47ee05")
662                .unwrap(),
663            true,
664        );
665
666        let expected = r#"{"r":"0xc569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0","s":"0x1a891b566d369e79b7a66eecab1e008831e22daa15f91a0a0cf4f9f28f47ee05","yParity":"0x1","v":"0x1"}"#;
667
668        let serialized = serde_json::to_string(&signature).unwrap();
669        assert_eq!(serialized, expected);
670    }
671
672    #[cfg(feature = "serde")]
673    #[test]
674    fn bincode_roundtrip() {
675        let signature = Signature::new(
676            U256::from_str("0xc569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0")
677                .unwrap(),
678            U256::from_str("0x1a891b566d369e79b7a66eecab1e008831e22daa15f91a0a0cf4f9f28f47ee05")
679                .unwrap(),
680            true,
681        );
682
683        let bin = bincode::serialize(&signature).unwrap();
684        assert_eq!(bincode::deserialize::<Signature>(&bin).unwrap(), signature);
685    }
686
687    #[cfg(feature = "rlp")]
688    #[test]
689    fn signature_rlp_encode() {
690        // Given a Signature instance
691        let sig = Signature::from_str("48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c8041b").unwrap();
692
693        // Initialize an empty buffer
694        let mut buf = vec![];
695
696        // Encode the Signature into the buffer
697        sig.write_rlp_vrs(&mut buf, sig.v());
698
699        // Define the expected hex-encoded string
700        let expected = "80a048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804";
701
702        // Assert that the encoded buffer matches the expected hex-encoded string
703        assert_eq!(hex::encode(&buf), expected);
704    }
705
706    #[cfg(feature = "rlp")]
707    #[test]
708    fn signature_rlp_length() {
709        // Given a Signature instance
710        let sig = Signature::from_str("48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c8041b").unwrap();
711
712        // Assert that the length of the Signature matches the expected length
713        assert_eq!(sig.rlp_rs_len() + sig.v().length(), 67);
714    }
715
716    #[cfg(feature = "rlp")]
717    #[test]
718    fn rlp_vrs_len() {
719        let signature = Signature::test_signature();
720        assert_eq!(67, signature.rlp_rs_len() + 1);
721    }
722
723    #[cfg(feature = "rlp")]
724    #[test]
725    fn encode_and_decode() {
726        let signature = Signature::test_signature();
727
728        let mut encoded = Vec::new();
729        signature.write_rlp_vrs(&mut encoded, signature.v());
730        assert_eq!(encoded.len(), signature.rlp_rs_len() + signature.v().length());
731        let decoded = Signature::decode_rlp_vrs(&mut &*encoded, bool::decode).unwrap();
732        assert_eq!(signature, decoded);
733    }
734
735    #[test]
736    fn as_bytes() {
737        let signature = Signature::new(
738            U256::from_str(
739                "18515461264373351373200002665853028612451056578545711640558177340181847433846",
740            )
741            .unwrap(),
742            U256::from_str(
743                "46948507304638947509940763649030358759909902576025900602547168820602576006531",
744            )
745            .unwrap(),
746            false,
747        );
748
749        let expected = hex!(
750            "0x28ef61340bd939bc2195fe537567866003e1a15d3c71ff63e1590620aa63627667cbe9d8997f761aecb703304b3800ccf555c9f3dc64214b297fb1966a3b6d831b"
751        );
752        assert_eq!(signature.as_bytes(), expected);
753    }
754
755    #[test]
756    fn as_rsy() {
757        let signature = Signature::new(
758            U256::from_str(
759                "18515461264373351373200002665853028612451056578545711640558177340181847433846",
760            )
761            .unwrap(),
762            U256::from_str(
763                "46948507304638947509940763649030358759909902576025900602547168820602576006531",
764            )
765            .unwrap(),
766            false,
767        );
768
769        let expected = hex!(
770            "0x28ef61340bd939bc2195fe537567866003e1a15d3c71ff63e1590620aa63627667cbe9d8997f761aecb703304b3800ccf555c9f3dc64214b297fb1966a3b6d8300"
771        );
772        assert_eq!(signature.as_rsy(), expected);
773    }
774
775    #[test]
776    fn as_rsy_y_parity_true() {
777        let signature = Signature::new(
778            U256::from_str(
779                "18515461264373351373200002665853028612451056578545711640558177340181847433846",
780            )
781            .unwrap(),
782            U256::from_str(
783                "46948507304638947509940763649030358759909902576025900602547168820602576006531",
784            )
785            .unwrap(),
786            true,
787        );
788
789        let expected = hex!(
790            "0x28ef61340bd939bc2195fe537567866003e1a15d3c71ff63e1590620aa63627667cbe9d8997f761aecb703304b3800ccf555c9f3dc64214b297fb1966a3b6d8301"
791        );
792        assert_eq!(signature.as_rsy(), expected);
793    }
794
795    #[test]
796    fn v_byte() {
797        let signature = Signature::new(U256::ZERO, U256::ZERO, false);
798        assert_eq!(signature.v_byte(), 27);
799
800        let signature = signature.with_parity(true);
801        assert_eq!(signature.v_byte(), 28);
802    }
803
804    #[test]
805    fn as_erc2098_y_false() {
806        let signature = Signature::new(
807            U256::from_str(
808                "47323457007453657207889730243826965761922296599680473886588287015755652701072",
809            )
810            .unwrap(),
811            U256::from_str(
812                "57228803202727131502949358313456071280488184270258293674242124340113824882788",
813            )
814            .unwrap(),
815            false,
816        );
817
818        let expected = hex!(
819            "0x68a020a209d3d56c46f38cc50a33f704f4a9a10a59377f8dd762ac66910e9b907e865ad05c4035ab5792787d4a0297a43617ae897930a6fe4d822b8faea52064"
820        );
821        assert_eq!(signature.as_erc2098(), expected);
822    }
823
824    #[test]
825    fn as_erc2098_y_true() {
826        let signature = Signature::new(
827            U256::from_str("0x9328da16089fcba9bececa81663203989f2df5fe1faa6291a45381c81bd17f76")
828                .unwrap(),
829            U256::from_str("0x139c6d6b623b42da56557e5e734a43dc83345ddfadec52cbe24d0cc64f550793")
830                .unwrap(),
831            true,
832        );
833
834        let expected = hex!(
835            "0x9328da16089fcba9bececa81663203989f2df5fe1faa6291a45381c81bd17f76939c6d6b623b42da56557e5e734a43dc83345ddfadec52cbe24d0cc64f550793"
836        );
837        assert_eq!(signature.as_erc2098(), expected);
838    }
839
840    #[test]
841    fn from_erc2098_y_false() {
842        let expected = Signature::new(
843            U256::from_str(
844                "47323457007453657207889730243826965761922296599680473886588287015755652701072",
845            )
846            .unwrap(),
847            U256::from_str(
848                "57228803202727131502949358313456071280488184270258293674242124340113824882788",
849            )
850            .unwrap(),
851            false,
852        );
853
854        assert_eq!(
855            Signature::from_erc2098(&hex!(
856                "0x68a020a209d3d56c46f38cc50a33f704f4a9a10a59377f8dd762ac66910e9b907e865ad05c4035ab5792787d4a0297a43617ae897930a6fe4d822b8faea52064"
857            )),
858            expected
859        );
860    }
861
862    #[test]
863    fn from_erc2098_y_true() {
864        let expected = Signature::new(
865            U256::from_str("0x9328da16089fcba9bececa81663203989f2df5fe1faa6291a45381c81bd17f76")
866                .unwrap(),
867            U256::from_str("0x139c6d6b623b42da56557e5e734a43dc83345ddfadec52cbe24d0cc64f550793")
868                .unwrap(),
869            true,
870        );
871
872        assert_eq!(
873            Signature::from_erc2098(&hex!(
874                "0x9328da16089fcba9bececa81663203989f2df5fe1faa6291a45381c81bd17f76939c6d6b623b42da56557e5e734a43dc83345ddfadec52cbe24d0cc64f550793"
875            )),
876            expected
877        );
878    }
879
880    #[test]
881    fn display_impl() {
882        let sig = Signature::new(
883            U256::from_str("0x9328da16089fcba9bececa81663203989f2df5fe1faa6291a45381c81bd17f76")
884                .unwrap(),
885            U256::from_str("0x139c6d6b623b42da56557e5e734a43dc83345ddfadec52cbe24d0cc64f550793")
886                .unwrap(),
887            true,
888        );
889
890        assert_eq!(
891            format!("{sig}"),
892            "0x9328da16089fcba9bececa81663203989f2df5fe1faa6291a45381c81bd17f76139c6d6b623b42da56557e5e734a43dc83345ddfadec52cbe24d0cc64f5507931c"
893        );
894    }
895}