crypto_bigint/uint/encoding/
rlp.rs1use crate::{Encoding, Uint};
4use rlp::{DecoderError, Rlp, RlpStream};
5
6impl<const LIMBS: usize> rlp::Encodable for Uint<LIMBS>
7where
8 Self: Encoding,
9{
10 fn rlp_append(&self, stream: &mut RlpStream) {
11 let bytes = self.to_be_bytes();
12 let mut bytes_stripped = bytes.as_ref();
13
14 while bytes_stripped.first().cloned() == Some(0) {
15 bytes_stripped = &bytes_stripped[1..];
16 }
17
18 stream.encoder().encode_value(bytes_stripped);
19 }
20}
21
22impl<const LIMBS: usize> rlp::Decodable for Uint<LIMBS>
23where
24 Self: Encoding,
25 <Self as Encoding>::Repr: Default,
26{
27 fn decode(rlp: &Rlp<'_>) -> Result<Self, DecoderError> {
28 rlp.decoder().decode_value(|bytes| {
29 if bytes.first().cloned() == Some(0) {
30 Err(DecoderError::RlpInvalidIndirection)
31 } else {
32 let mut repr = <Self as Encoding>::Repr::default();
33 let offset = repr
34 .as_ref()
35 .len()
36 .checked_sub(bytes.len())
37 .ok_or(DecoderError::RlpIsTooBig)?;
38
39 repr.as_mut()[offset..].copy_from_slice(bytes);
40 Ok(Self::from_be_bytes(repr))
41 }
42 })
43 }
44}
45
46#[cfg(test)]
47#[allow(clippy::unwrap_used)]
48mod tests {
49 use crate::U256;
50 use hex_literal::hex;
51
52 const U256_VECTORS: &[(U256, &[u8])] = &[
56 (U256::ZERO, &hex!("80")),
57 (
58 U256::from_be_hex("0000000000000000000000000000000000000000000000000000000001000000"),
59 &hex!("8401000000"),
60 ),
61 (
62 U256::from_be_hex("00000000000000000000000000000000000000000000000000000000ffffffff"),
63 &hex!("84ffffffff"),
64 ),
65 (
66 U256::from_be_hex("8090a0b0c0d0e0f00910203040506077000000000000000100000000000012f0"),
67 &hex!("a08090a0b0c0d0e0f00910203040506077000000000000000100000000000012f0"),
68 ),
69 ];
70
71 #[test]
72 fn round_trip() {
73 for &(uint, expected_bytes) in U256_VECTORS {
74 assert_eq!(rlp::encode(&uint), expected_bytes);
75 assert_eq!(rlp::decode::<U256>(expected_bytes).unwrap(), uint);
76 }
77 }
78}