alloy_primitives/signature/
sig.rs

1#![allow(unknown_lints, unnameable_types)]
2
3use crate::{
4    hex,
5    signature::{Parity, SignatureError},
6    uint, U256,
7};
8use alloc::vec::Vec;
9use core::str::FromStr;
10
11/// The order of the secp256k1 curve
12const SECP256K1N_ORDER: U256 =
13    uint!(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141_U256);
14
15/// An Ethereum ECDSA signature.
16#[deprecated(since = "0.8.15", note = "use PrimitiveSignature instead")]
17#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
18pub struct Signature {
19    v: Parity,
20    r: U256,
21    s: U256,
22}
23
24impl<'a> TryFrom<&'a [u8]> for Signature {
25    type Error = SignatureError;
26
27    /// Parses a raw signature which is expected to be 65 bytes long where
28    /// the first 32 bytes is the `r` value, the second 32 bytes the `s` value
29    /// and the final byte is the `v` value in 'Electrum' notation.
30    fn try_from(bytes: &'a [u8]) -> Result<Self, Self::Error> {
31        if bytes.len() != 65 {
32            return Err(SignatureError::FromBytes("expected exactly 65 bytes"));
33        }
34        Self::from_bytes_and_parity(&bytes[..64], bytes[64] as u64)
35    }
36}
37
38impl FromStr for Signature {
39    type Err = SignatureError;
40
41    fn from_str(s: &str) -> Result<Self, Self::Err> {
42        let bytes = hex::decode(s)?;
43        Self::try_from(&bytes[..])
44    }
45}
46
47impl From<&Signature> for [u8; 65] {
48    #[inline]
49    fn from(value: &Signature) -> [u8; 65] {
50        value.as_bytes()
51    }
52}
53
54impl From<Signature> for [u8; 65] {
55    #[inline]
56    fn from(value: Signature) -> [u8; 65] {
57        value.as_bytes()
58    }
59}
60
61impl From<&Signature> for Vec<u8> {
62    #[inline]
63    fn from(value: &Signature) -> Self {
64        value.as_bytes().to_vec()
65    }
66}
67
68impl From<Signature> for Vec<u8> {
69    #[inline]
70    fn from(value: Signature) -> Self {
71        value.as_bytes().to_vec()
72    }
73}
74
75#[cfg(feature = "k256")]
76impl From<(k256::ecdsa::Signature, k256::ecdsa::RecoveryId)> for Signature {
77    fn from(value: (k256::ecdsa::Signature, k256::ecdsa::RecoveryId)) -> Self {
78        Self::from_signature_and_parity(value.0, value.1).unwrap()
79    }
80}
81
82#[cfg(feature = "k256")]
83impl TryFrom<Signature> for k256::ecdsa::Signature {
84    type Error = k256::ecdsa::Error;
85
86    fn try_from(value: Signature) -> Result<Self, Self::Error> {
87        value.to_k256()
88    }
89}
90
91#[cfg(feature = "rlp")]
92impl Signature {
93    /// Decode an RLP-encoded VRS signature.
94    pub fn decode_rlp_vrs(buf: &mut &[u8]) -> Result<Self, alloy_rlp::Error> {
95        use alloy_rlp::Decodable;
96
97        let parity: Parity = Decodable::decode(buf)?;
98        let r = Decodable::decode(buf)?;
99        let s = Decodable::decode(buf)?;
100
101        Self::from_rs_and_parity(r, s, parity)
102            .map_err(|_| alloy_rlp::Error::Custom("attempted to decode invalid field element"))
103    }
104}
105
106impl Signature {
107    #[doc(hidden)]
108    pub fn test_signature() -> Self {
109        Self::from_scalars_and_parity(
110            b256!("0x840cfc572845f5786e702984c2a582528cad4b49b2a10b9db1be7fca90058565"),
111            b256!("0x25e7109ceb98168d95b09b18bbf6b685130e0562f233877d492b94eee0c5b6d1"),
112            false,
113        )
114        .unwrap()
115    }
116
117    /// Instantiate a new signature from `r`, `s`, and `v` values.
118    pub const fn new(r: U256, s: U256, v: Parity) -> Self {
119        Self { r, s, v }
120    }
121
122    /// Returns the inner ECDSA signature.
123    #[cfg(feature = "k256")]
124    #[deprecated(note = "use `Signature::to_k256` instead")]
125    #[inline]
126    pub fn into_inner(self) -> k256::ecdsa::Signature {
127        self.try_into().expect("signature conversion failed")
128    }
129
130    /// Returns the inner ECDSA signature.
131    #[cfg(feature = "k256")]
132    #[inline]
133    pub fn to_k256(self) -> Result<k256::ecdsa::Signature, k256::ecdsa::Error> {
134        k256::ecdsa::Signature::from_scalars(self.r.to_be_bytes(), self.s.to_be_bytes())
135    }
136
137    /// Instantiate from a signature and recovery id
138    #[cfg(feature = "k256")]
139    pub fn from_signature_and_parity<T: TryInto<Parity, Error = E>, E: Into<SignatureError>>(
140        sig: k256::ecdsa::Signature,
141        parity: T,
142    ) -> Result<Self, SignatureError> {
143        let r = U256::from_be_slice(sig.r().to_bytes().as_ref());
144        let s = U256::from_be_slice(sig.s().to_bytes().as_ref());
145        Ok(Self { v: parity.try_into().map_err(Into::into)?, r, s })
146    }
147
148    /// Creates a [`Signature`] from the serialized `r` and `s` scalar values, which comprise the
149    /// ECDSA signature, alongside a `v` value, used to determine the recovery ID.
150    #[inline]
151    pub fn from_scalars_and_parity<T: TryInto<Parity, Error = E>, E: Into<SignatureError>>(
152        r: crate::B256,
153        s: crate::B256,
154        parity: T,
155    ) -> Result<Self, SignatureError> {
156        Self::from_rs_and_parity(
157            U256::from_be_slice(r.as_ref()),
158            U256::from_be_slice(s.as_ref()),
159            parity,
160        )
161    }
162
163    /// Normalizes the signature into "low S" form as described in
164    /// [BIP 0062: Dealing with Malleability][1].
165    ///
166    /// [1]: https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki
167    #[inline]
168    pub fn normalize_s(&self) -> Option<Self> {
169        let s = self.s();
170
171        if s > SECP256K1N_ORDER >> 1 {
172            Some(Self { v: self.v.inverted(), r: self.r, s: SECP256K1N_ORDER - s })
173        } else {
174            None
175        }
176    }
177
178    /// Returns the recovery ID.
179    #[cfg(feature = "k256")]
180    #[inline]
181    pub const fn recid(&self) -> k256::ecdsa::RecoveryId {
182        self.v.recid()
183    }
184
185    #[cfg(feature = "k256")]
186    #[doc(hidden)]
187    #[deprecated(note = "use `Signature::recid` instead")]
188    pub const fn recovery_id(&self) -> k256::ecdsa::RecoveryId {
189        self.recid()
190    }
191
192    /// Recovers an [`Address`] from this signature and the given message by first prefixing and
193    /// hashing the message according to [EIP-191](crate::eip191_hash_message).
194    ///
195    /// [`Address`]: crate::Address
196    #[cfg(feature = "k256")]
197    #[inline]
198    pub fn recover_address_from_msg<T: AsRef<[u8]>>(
199        &self,
200        msg: T,
201    ) -> Result<crate::Address, SignatureError> {
202        self.recover_from_msg(msg).map(|vk| crate::Address::from_public_key(&vk))
203    }
204
205    /// Recovers an [`Address`] from this signature and the given prehashed message.
206    ///
207    /// [`Address`]: crate::Address
208    #[cfg(feature = "k256")]
209    #[inline]
210    pub fn recover_address_from_prehash(
211        &self,
212        prehash: &crate::B256,
213    ) -> Result<crate::Address, SignatureError> {
214        self.recover_from_prehash(prehash).map(|vk| crate::Address::from_public_key(&vk))
215    }
216
217    /// Recovers a [`VerifyingKey`] from this signature and the given message by first prefixing and
218    /// hashing the message according to [EIP-191](crate::eip191_hash_message).
219    ///
220    /// [`VerifyingKey`]: k256::ecdsa::VerifyingKey
221    #[cfg(feature = "k256")]
222    #[inline]
223    pub fn recover_from_msg<T: AsRef<[u8]>>(
224        &self,
225        msg: T,
226    ) -> Result<k256::ecdsa::VerifyingKey, SignatureError> {
227        self.recover_from_prehash(&crate::eip191_hash_message(msg))
228    }
229
230    /// Recovers a [`VerifyingKey`] from this signature and the given prehashed message.
231    ///
232    /// [`VerifyingKey`]: k256::ecdsa::VerifyingKey
233    #[cfg(feature = "k256")]
234    #[inline]
235    pub fn recover_from_prehash(
236        &self,
237        prehash: &crate::B256,
238    ) -> Result<k256::ecdsa::VerifyingKey, SignatureError> {
239        let this = self.normalize_s().unwrap_or(*self);
240        k256::ecdsa::VerifyingKey::recover_from_prehash(
241            prehash.as_slice(),
242            &this.to_k256()?,
243            this.recid(),
244        )
245        .map_err(Into::into)
246    }
247
248    /// Parses a signature from a byte slice, with a v value
249    ///
250    /// # Panics
251    ///
252    /// If the slice is not at least 64 bytes long.
253    #[inline]
254    pub fn from_bytes_and_parity<T: TryInto<Parity, Error = E>, E: Into<SignatureError>>(
255        bytes: &[u8],
256        parity: T,
257    ) -> Result<Self, SignatureError> {
258        let r = U256::from_be_slice(&bytes[..32]);
259        let s = U256::from_be_slice(&bytes[32..64]);
260        Self::from_rs_and_parity(r, s, parity)
261    }
262
263    /// Instantiate from v, r, s.
264    pub fn from_rs_and_parity<T: TryInto<Parity, Error = E>, E: Into<SignatureError>>(
265        r: U256,
266        s: U256,
267        parity: T,
268    ) -> Result<Self, SignatureError> {
269        Ok(Self { v: parity.try_into().map_err(Into::into)?, r, s })
270    }
271
272    /// Modifies the recovery ID by applying [EIP-155] to a `v` value.
273    ///
274    /// [EIP-155]: https://eips.ethereum.org/EIPS/eip-155
275    #[inline]
276    pub fn with_chain_id(self, chain_id: u64) -> Self {
277        self.with_parity(self.v.with_chain_id(chain_id))
278    }
279
280    /// Modifies the recovery ID by dropping any [EIP-155] v value, converting
281    /// to a simple parity bool.
282    pub fn with_parity_bool(self) -> Self {
283        self.with_parity(self.v.to_parity_bool())
284    }
285
286    /// Returns the `r` component of this signature.
287    #[inline]
288    pub const fn r(&self) -> U256 {
289        self.r
290    }
291
292    /// Returns the `s` component of this signature.
293    #[inline]
294    pub const fn s(&self) -> U256 {
295        self.s
296    }
297
298    /// Returns the recovery ID as a `u8`.
299    #[inline]
300    pub const fn v(&self) -> Parity {
301        self.v
302    }
303
304    /// Returns the chain ID associated with the V value, if this signature is
305    /// replay-protected by [EIP-155].
306    ///
307    /// [EIP-155]: https://eips.ethereum.org/EIPS/eip-155
308    pub const fn chain_id(&self) -> Option<u64> {
309        self.v.chain_id()
310    }
311
312    /// Returns true if the signature is replay-protected by [EIP-155].
313    ///
314    /// This is true if the V value is 35 or greater. Values less than 35 are
315    /// either not replay protected (27/28), or are invalid.
316    ///
317    /// [EIP-155]: https://eips.ethereum.org/EIPS/eip-155
318    #[inline]
319    pub const fn has_eip155_value(&self) -> bool {
320        self.v().has_eip155_value()
321    }
322
323    /// Returns the byte-array representation of this signature.
324    ///
325    /// The first 32 bytes are the `r` value, the second 32 bytes the `s` value
326    /// and the final byte is the `v` value in 'Electrum' notation.
327    #[inline]
328    pub fn as_bytes(&self) -> [u8; 65] {
329        let mut sig = [0u8; 65];
330        sig[..32].copy_from_slice(&self.r.to_be_bytes::<32>());
331        sig[32..64].copy_from_slice(&self.s.to_be_bytes::<32>());
332        sig[64] = self.v.y_parity_byte_non_eip155().unwrap_or(self.v.y_parity_byte());
333        sig
334    }
335
336    /// Sets the recovery ID by normalizing a `v` value.
337    #[inline]
338    pub fn with_parity<T: Into<Parity>>(self, parity: T) -> Self {
339        Self { v: parity.into(), r: self.r, s: self.s }
340    }
341
342    /// Length of RLP RS field encoding
343    #[cfg(feature = "rlp")]
344    pub fn rlp_rs_len(&self) -> usize {
345        alloy_rlp::Encodable::length(&self.r) + alloy_rlp::Encodable::length(&self.s)
346    }
347
348    #[cfg(feature = "rlp")]
349    /// Length of RLP V field encoding
350    pub fn rlp_vrs_len(&self) -> usize {
351        self.rlp_rs_len() + alloy_rlp::Encodable::length(&self.v)
352    }
353
354    /// Write R and S to an RLP buffer in progress.
355    #[cfg(feature = "rlp")]
356    pub fn write_rlp_rs(&self, out: &mut dyn alloy_rlp::BufMut) {
357        alloy_rlp::Encodable::encode(&self.r, out);
358        alloy_rlp::Encodable::encode(&self.s, out);
359    }
360
361    /// Write the V to an RLP buffer without using EIP-155.
362    #[cfg(feature = "rlp")]
363    pub fn write_rlp_v(&self, out: &mut dyn alloy_rlp::BufMut) {
364        alloy_rlp::Encodable::encode(&self.v, out);
365    }
366
367    /// Write the VRS to the output. The V will always be 27 or 28.
368    #[cfg(feature = "rlp")]
369    pub fn write_rlp_vrs(&self, out: &mut dyn alloy_rlp::BufMut) {
370        self.write_rlp_v(out);
371        self.write_rlp_rs(out);
372    }
373}
374
375#[cfg(feature = "rlp")]
376impl alloy_rlp::Encodable for Signature {
377    fn encode(&self, out: &mut dyn alloy_rlp::BufMut) {
378        alloy_rlp::Header { list: true, payload_length: self.rlp_vrs_len() }.encode(out);
379        self.write_rlp_vrs(out);
380    }
381
382    fn length(&self) -> usize {
383        let payload_length = self.rlp_vrs_len();
384        payload_length + alloy_rlp::length_of_length(payload_length)
385    }
386}
387
388#[cfg(feature = "rlp")]
389impl alloy_rlp::Decodable for Signature {
390    fn decode(buf: &mut &[u8]) -> Result<Self, alloy_rlp::Error> {
391        let header = alloy_rlp::Header::decode(buf)?;
392        let pre_len = buf.len();
393        let decoded = Self::decode_rlp_vrs(buf)?;
394        let consumed = pre_len - buf.len();
395        if consumed != header.payload_length {
396            return Err(alloy_rlp::Error::Custom("consumed incorrect number of bytes"));
397        }
398
399        Ok(decoded)
400    }
401}
402
403#[cfg(feature = "serde")]
404impl serde::Serialize for Signature {
405    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
406    where
407        S: serde::Serializer,
408    {
409        // if the serializer is human readable, serialize as a map, otherwise as a tuple
410        if serializer.is_human_readable() {
411            use serde::ser::SerializeMap;
412
413            let mut map = serializer.serialize_map(Some(3))?;
414
415            map.serialize_entry("r", &self.r)?;
416            map.serialize_entry("s", &self.s)?;
417
418            match self.v {
419                Parity::Eip155(v) => map.serialize_entry("v", &crate::U64::from(v))?,
420                Parity::NonEip155(b) => {
421                    map.serialize_entry("v", &crate::U64::from(b as u8 + 27))?
422                }
423                Parity::Parity(true) => map.serialize_entry("yParity", "0x1")?,
424                Parity::Parity(false) => map.serialize_entry("yParity", "0x0")?,
425            }
426            map.end()
427        } else {
428            use serde::ser::SerializeTuple;
429
430            let mut tuple = serializer.serialize_tuple(3)?;
431            tuple.serialize_element(&self.r)?;
432            tuple.serialize_element(&self.s)?;
433            tuple.serialize_element(&crate::U64::from(self.v.to_u64()))?;
434            tuple.end()
435        }
436    }
437}
438
439#[cfg(feature = "serde")]
440impl<'de> serde::Deserialize<'de> for Signature {
441    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
442    where
443        D: serde::Deserializer<'de>,
444    {
445        use serde::de::MapAccess;
446
447        enum Field {
448            R,
449            S,
450            V,
451            YParity,
452            Unknown,
453        }
454
455        impl<'de> serde::Deserialize<'de> for Field {
456            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
457            where
458                D: serde::Deserializer<'de>,
459            {
460                struct FieldVisitor;
461
462                impl serde::de::Visitor<'_> for FieldVisitor {
463                    type Value = Field;
464
465                    fn expecting(
466                        &self,
467                        formatter: &mut core::fmt::Formatter<'_>,
468                    ) -> core::fmt::Result {
469                        formatter.write_str("v, r, s, or yParity")
470                    }
471
472                    fn visit_str<E>(self, value: &str) -> Result<Field, E>
473                    where
474                        E: serde::de::Error,
475                    {
476                        match value {
477                            "r" => Ok(Field::R),
478                            "s" => Ok(Field::S),
479                            "v" => Ok(Field::V),
480                            "yParity" => Ok(Field::YParity),
481                            _ => Ok(Field::Unknown),
482                        }
483                    }
484                }
485                deserializer.deserialize_identifier(FieldVisitor)
486            }
487        }
488
489        struct MapVisitor;
490        impl<'de> serde::de::Visitor<'de> for MapVisitor {
491            type Value = Signature;
492
493            fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
494                formatter.write_str("a JSON signature object containing r, s, and v or yParity")
495            }
496
497            fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
498            where
499                A: MapAccess<'de>,
500            {
501                let mut v: Option<Parity> = None;
502                let mut r = None;
503                let mut s = None;
504
505                while let Some(key) = map.next_key()? {
506                    match key {
507                        Field::V => {
508                            let value: crate::U64 = map.next_value()?;
509                            let parity = value.try_into().map_err(|_| {
510                                serde::de::Error::invalid_value(
511                                    serde::de::Unexpected::Unsigned(value.as_limbs()[0]),
512                                    &"a valid v value matching the range 0 | 1 | 27 | 28 | 35..",
513                                )
514                            })?;
515                            v = Some(parity);
516                        }
517                        Field::YParity => {
518                            let value: crate::Uint<1, 1> = map.next_value()?;
519                            if v.is_none() {
520                                v = Some(value.into());
521                            }
522                        }
523                        Field::R => {
524                            let value: U256 = map.next_value()?;
525                            r = Some(value);
526                        }
527                        Field::S => {
528                            let value: U256 = map.next_value()?;
529                            s = Some(value);
530                        }
531                        _ => {}
532                    }
533                }
534
535                let v = v.ok_or_else(|| serde::de::Error::missing_field("v"))?;
536                let r = r.ok_or_else(|| serde::de::Error::missing_field("r"))?;
537                let s = s.ok_or_else(|| serde::de::Error::missing_field("s"))?;
538
539                Signature::from_rs_and_parity(r, s, v).map_err(serde::de::Error::custom)
540            }
541        }
542
543        struct TupleVisitor;
544        impl<'de> serde::de::Visitor<'de> for TupleVisitor {
545            type Value = Signature;
546
547            fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
548                formatter.write_str("a tuple containing r, s, and v")
549            }
550
551            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
552            where
553                A: serde::de::SeqAccess<'de>,
554            {
555                let r = seq
556                    .next_element()?
557                    .ok_or_else(|| serde::de::Error::invalid_length(0, &self))?;
558                let s = seq
559                    .next_element()?
560                    .ok_or_else(|| serde::de::Error::invalid_length(1, &self))?;
561                let v: crate::U64 = seq
562                    .next_element()?
563                    .ok_or_else(|| serde::de::Error::invalid_length(2, &self))?;
564
565                Signature::from_rs_and_parity(r, s, v).map_err(serde::de::Error::custom)
566            }
567        }
568
569        if deserializer.is_human_readable() {
570            deserializer.deserialize_map(MapVisitor)
571        } else {
572            deserializer.deserialize_tuple(3, TupleVisitor)
573        }
574    }
575}
576
577#[cfg(feature = "arbitrary")]
578impl<'a> arbitrary::Arbitrary<'a> for Signature {
579    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
580        Self::from_rs_and_parity(u.arbitrary()?, u.arbitrary()?, u.arbitrary::<Parity>()?)
581            .map_err(|_| arbitrary::Error::IncorrectFormat)
582    }
583}
584
585#[cfg(feature = "arbitrary")]
586impl proptest::arbitrary::Arbitrary for Signature {
587    type Parameters = ();
588    type Strategy = proptest::strategy::FilterMap<
589        <(U256, U256, Parity) as proptest::arbitrary::Arbitrary>::Strategy,
590        fn((U256, U256, Parity)) -> Option<Self>,
591    >;
592
593    fn arbitrary_with((): Self::Parameters) -> Self::Strategy {
594        use proptest::strategy::Strategy;
595        proptest::arbitrary::any::<(U256, U256, Parity)>()
596            .prop_filter_map("invalid signature", |(r, s, parity)| {
597                Self::from_rs_and_parity(r, s, parity).ok()
598            })
599    }
600}
601
602#[cfg(test)]
603#[allow(unused_imports)]
604mod tests {
605    use super::*;
606    use crate::Bytes;
607    use core::str::FromStr;
608    use hex::FromHex;
609
610    #[cfg(feature = "rlp")]
611    use alloy_rlp::{Decodable, Encodable};
612
613    #[test]
614    #[cfg(feature = "k256")]
615    fn can_recover_tx_sender_not_normalized() {
616        let sig = Signature::from_str("48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c8041b").unwrap();
617        let hash = b256!("0x5eb4f5a33c621f32a8622d5f943b6b102994dfe4e5aebbefe69bb1b2aa0fc93e");
618        let expected = address!("0x0f65fe9276bc9a24ae7083ae28e2660ef72df99e");
619        assert_eq!(sig.recover_address_from_prehash(&hash).unwrap(), expected);
620    }
621
622    #[test]
623    #[cfg(feature = "k256")]
624    fn recover_web3_signature() {
625        // test vector taken from:
626        // https://web3js.readthedocs.io/en/v1.2.2/web3-eth-accounts.html#sign
627        let sig = Signature::from_str(
628            "b91467e570a6466aa9e9876cbcd013baba02900b8979d43fe208a4a4f339f5fd6007e74cd82e037b800186422fc2da167c747ef045e5d18a5f5d4300f8e1a0291c"
629        ).expect("could not parse signature");
630        let expected = address!("0x2c7536E3605D9C16a7a3D7b1898e529396a65c23");
631        assert_eq!(sig.recover_address_from_msg("Some data").unwrap(), expected);
632    }
633
634    #[test]
635    fn signature_from_str() {
636        let s1 = Signature::from_str(
637            "0xaa231fbe0ed2b5418e6ba7c19bee2522852955ec50996c02a2fe3e71d30ddaf1645baf4823fea7cb4fcc7150842493847cfb6a6d63ab93e8ee928ee3f61f503500"
638        ).expect("could not parse 0x-prefixed signature");
639
640        let s2 = Signature::from_str(
641            "aa231fbe0ed2b5418e6ba7c19bee2522852955ec50996c02a2fe3e71d30ddaf1645baf4823fea7cb4fcc7150842493847cfb6a6d63ab93e8ee928ee3f61f503500"
642        ).expect("could not parse non-prefixed signature");
643
644        assert_eq!(s1, s2);
645    }
646
647    #[cfg(feature = "serde")]
648    #[test]
649    fn deserialize_without_parity() {
650        let raw_signature_without_y_parity = r#"{
651            "r":"0xc569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0",
652            "s":"0x1a891b566d369e79b7a66eecab1e008831e22daa15f91a0a0cf4f9f28f47ee05",
653            "v":"0x1"
654        }"#;
655
656        let signature: Signature = serde_json::from_str(raw_signature_without_y_parity).unwrap();
657
658        let expected = Signature::from_rs_and_parity(
659            U256::from_str("0xc569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0")
660                .unwrap(),
661            U256::from_str("0x1a891b566d369e79b7a66eecab1e008831e22daa15f91a0a0cf4f9f28f47ee05")
662                .unwrap(),
663            1,
664        )
665        .unwrap();
666
667        assert_eq!(signature, expected);
668    }
669
670    #[cfg(feature = "serde")]
671    #[test]
672    fn deserialize_with_parity() {
673        let raw_signature_with_y_parity = serde_json::json!({
674            "r": "0xc569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0",
675            "s": "0x1a891b566d369e79b7a66eecab1e008831e22daa15f91a0a0cf4f9f28f47ee05",
676            "v": "0x1",
677            "yParity": "0x1"
678        });
679
680        let signature: Signature = serde_json::from_value(raw_signature_with_y_parity).unwrap();
681
682        let expected = Signature::from_rs_and_parity(
683            U256::from_str("0xc569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0")
684                .unwrap(),
685            U256::from_str("0x1a891b566d369e79b7a66eecab1e008831e22daa15f91a0a0cf4f9f28f47ee05")
686                .unwrap(),
687            1,
688        )
689        .unwrap();
690
691        assert_eq!(signature, expected);
692    }
693
694    #[cfg(feature = "serde")]
695    #[test]
696    fn serialize_both_parity() {
697        // this test should be removed if the struct moves to an enum based on tx type
698        let signature = Signature::from_rs_and_parity(
699            U256::from_str("0xc569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0")
700                .unwrap(),
701            U256::from_str("0x1a891b566d369e79b7a66eecab1e008831e22daa15f91a0a0cf4f9f28f47ee05")
702                .unwrap(),
703            1,
704        )
705        .unwrap();
706
707        let serialized = serde_json::to_string(&signature).unwrap();
708        assert_eq!(
709            serialized,
710            r#"{"r":"0xc569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0","s":"0x1a891b566d369e79b7a66eecab1e008831e22daa15f91a0a0cf4f9f28f47ee05","yParity":"0x1"}"#
711        );
712    }
713
714    #[cfg(feature = "serde")]
715    #[test]
716    fn serialize_v_only() {
717        // this test should be removed if the struct moves to an enum based on tx type
718        let signature = Signature::from_rs_and_parity(
719            U256::from_str("0xc569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0")
720                .unwrap(),
721            U256::from_str("0x1a891b566d369e79b7a66eecab1e008831e22daa15f91a0a0cf4f9f28f47ee05")
722                .unwrap(),
723            1,
724        )
725        .unwrap();
726
727        let expected = r#"{"r":"0xc569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0","s":"0x1a891b566d369e79b7a66eecab1e008831e22daa15f91a0a0cf4f9f28f47ee05","yParity":"0x1"}"#;
728
729        let serialized = serde_json::to_string(&signature).unwrap();
730        assert_eq!(serialized, expected);
731    }
732
733    #[cfg(feature = "serde")]
734    #[test]
735    fn serialize_v_hex() {
736        let s = r#"{"r":"0x3d43270611ffb1a10fcab841e636e355a787151969b920cf10fef48d3a61aac3","s":"0x11336489e3050e3ec017079dfe16582ce3d167559bcaa8383b665b3fda4eb963","v":"0x1b"}"#;
737
738        let sig = serde_json::from_str::<Signature>(s).unwrap();
739        let serialized = serde_json::to_string(&sig).unwrap();
740        assert_eq!(serialized, s);
741    }
742
743    #[cfg(feature = "serde")]
744    #[test]
745    fn test_bincode_roundtrip() {
746        let signature = Signature::from_rs_and_parity(
747            U256::from_str("0xc569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0")
748                .unwrap(),
749            U256::from_str("0x1a891b566d369e79b7a66eecab1e008831e22daa15f91a0a0cf4f9f28f47ee05")
750                .unwrap(),
751            1,
752        )
753        .unwrap();
754
755        let bin = bincode::serialize(&signature).unwrap();
756        assert_eq!(bincode::deserialize::<Signature>(&bin).unwrap(), signature);
757    }
758
759    #[cfg(feature = "rlp")]
760    #[test]
761    fn signature_rlp_decode() {
762        // Given a hex-encoded byte sequence
763        let bytes = crate::hex!("f84301a048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a010002cef538bc0c8e21c46080634a93e082408b0ad93f4a7207e63ec5463793d");
764
765        // Decode the byte sequence into a Signature instance
766        let result = Signature::decode(&mut &bytes[..]).unwrap();
767
768        // Assert that the decoded Signature matches the expected Signature
769        assert_eq!(
770            result,
771            Signature::from_str("48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a3664935310002cef538bc0c8e21c46080634a93e082408b0ad93f4a7207e63ec5463793d01").unwrap()
772        );
773    }
774
775    #[cfg(feature = "rlp")]
776    #[test]
777    fn signature_rlp_encode() {
778        // Given a Signature instance
779        let sig = Signature::from_str("48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c8041b").unwrap();
780
781        // Initialize an empty buffer
782        let mut buf = vec![];
783
784        // Encode the Signature into the buffer
785        sig.encode(&mut buf);
786
787        // Define the expected hex-encoded string
788        let expected = "f8431ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804";
789
790        // Assert that the encoded buffer matches the expected hex-encoded string
791        assert_eq!(hex::encode(&buf), expected);
792    }
793
794    #[cfg(feature = "rlp")]
795    #[test]
796    fn signature_rlp_length() {
797        // Given a Signature instance
798        let sig = Signature::from_str("48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c8041b").unwrap();
799
800        // Assert that the length of the Signature matches the expected length
801        assert_eq!(sig.length(), 69);
802    }
803
804    #[cfg(feature = "rlp")]
805    #[test]
806    fn test_rlp_vrs_len() {
807        let signature = Signature::test_signature();
808        assert_eq!(67, signature.rlp_vrs_len());
809    }
810
811    #[cfg(feature = "rlp")]
812    #[test]
813    fn test_encode_and_decode() {
814        let signature = Signature::test_signature();
815
816        let mut encoded = Vec::new();
817        signature.encode(&mut encoded);
818        assert_eq!(encoded.len(), signature.length());
819        let decoded = Signature::decode(&mut &*encoded).unwrap();
820        assert_eq!(signature, decoded);
821    }
822
823    #[test]
824    fn test_as_bytes() {
825        let signature = Signature::new(
826            U256::from_str(
827                "18515461264373351373200002665853028612451056578545711640558177340181847433846",
828            )
829            .unwrap(),
830            U256::from_str(
831                "46948507304638947509940763649030358759909902576025900602547168820602576006531",
832            )
833            .unwrap(),
834            Parity::Parity(false),
835        );
836
837        let expected = Bytes::from_hex("0x28ef61340bd939bc2195fe537567866003e1a15d3c71ff63e1590620aa63627667cbe9d8997f761aecb703304b3800ccf555c9f3dc64214b297fb1966a3b6d831b").unwrap();
838        assert_eq!(signature.as_bytes(), **expected);
839    }
840}