alloy_primitives/signature/
sig.rs1#![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
11const SECP256K1N_ORDER: U256 =
13 uint!(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141_U256);
14
15#[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 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 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 pub const fn new(r: U256, s: U256, v: Parity) -> Self {
119 Self { r, s, v }
120 }
121
122 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 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 #[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 pub fn with_parity_bool(self) -> Self {
283 self.with_parity(self.v.to_parity_bool())
284 }
285
286 #[inline]
288 pub const fn r(&self) -> U256 {
289 self.r
290 }
291
292 #[inline]
294 pub const fn s(&self) -> U256 {
295 self.s
296 }
297
298 #[inline]
300 pub const fn v(&self) -> Parity {
301 self.v
302 }
303
304 pub const fn chain_id(&self) -> Option<u64> {
309 self.v.chain_id()
310 }
311
312 #[inline]
319 pub const fn has_eip155_value(&self) -> bool {
320 self.v().has_eip155_value()
321 }
322
323 #[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 #[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 #[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 pub fn rlp_vrs_len(&self) -> usize {
351 self.rlp_rs_len() + alloy_rlp::Encodable::length(&self.v)
352 }
353
354 #[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 #[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 #[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 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 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 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 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 let bytes = crate::hex!("f84301a048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a010002cef538bc0c8e21c46080634a93e082408b0ad93f4a7207e63ec5463793d");
764
765 let result = Signature::decode(&mut &bytes[..]).unwrap();
767
768 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 let sig = Signature::from_str("48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c8041b").unwrap();
780
781 let mut buf = vec![];
783
784 sig.encode(&mut buf);
786
787 let expected = "f8431ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804";
789
790 assert_eq!(hex::encode(&buf), expected);
792 }
793
794 #[cfg(feature = "rlp")]
795 #[test]
796 fn signature_rlp_length() {
797 let sig = Signature::from_str("48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c8041b").unwrap();
799
800 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}