From 01f865c4ca1e16281e7c713d82fd4dff2437cfc6 Mon Sep 17 00:00:00 2001 From: Wawwior <45405580+Wawwior@users.noreply.github.com> Date: Sun, 9 Mar 2025 16:56:01 +0100 Subject: [PATCH 1/4] Implement serde for BoxedUint Adapted from #587 --- Cargo.lock | 5 ++- Cargo.toml | 1 + src/uint/boxed/encoding.rs | 3 ++ src/uint/boxed/encoding/serde.rs | 72 ++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 src/uint/boxed/encoding/serde.rs diff --git a/Cargo.lock b/Cargo.lock index ea2da98b..89348b5b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -231,6 +231,7 @@ dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.2", "rlp", + "serde_json", "serdect", "subtle", "zeroize", @@ -714,9 +715,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.138" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", "memchr", diff --git a/Cargo.toml b/Cargo.toml index 48a91f76..c03701dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,7 @@ num-modular = { version = "0.6", features = ["num-bigint", "num-integer", "num-t proptest = "1.5" rand_core = { version = "0.9", features = ["std", "os_rng"] } rand_chacha = "0.9" +serde_json = { version = "1.0.140", features = ["alloc"] } [features] diff --git a/src/uint/boxed/encoding.rs b/src/uint/boxed/encoding.rs index 85d7b0e9..357372a8 100644 --- a/src/uint/boxed/encoding.rs +++ b/src/uint/boxed/encoding.rs @@ -5,6 +5,9 @@ use crate::{DecodeError, Limb, Word, uint::encoding}; use alloc::{boxed::Box, string::String, vec::Vec}; use subtle::{Choice, CtOption}; +#[cfg(feature = "serde")] +mod serde; + impl BoxedUint { /// Create a new [`BoxedUint`] from the provided big endian bytes. /// diff --git a/src/uint/boxed/encoding/serde.rs b/src/uint/boxed/encoding/serde.rs new file mode 100644 index 00000000..4e641d11 --- /dev/null +++ b/src/uint/boxed/encoding/serde.rs @@ -0,0 +1,72 @@ +use serdect::serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error}; + +use crate::BoxedUint; + +impl<'de> Deserialize<'de> for BoxedUint { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let slice = serdect::slice::deserialize_hex_or_bin_vec(deserializer)?; + Self::from_le_slice(&slice, slice.len() as u32 * 8).map_err(Error::custom) + } +} + +impl Serialize for BoxedUint { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serdect::slice::serialize_hex_lower_or_bin(&self.to_le_bytes(), serializer) + } +} + +#[cfg(test)] +mod tests { + use super::BoxedUint; + + #[test] + fn serde_roundabout() { + let n = BoxedUint::from(11223344u64); + let ser = serde_json::to_string(&n).unwrap(); + let de: BoxedUint = serde_json::from_str(&ser).unwrap(); + assert_eq!(n, de); + } + + #[test] + #[cfg(target_pointer_width = "64")] + fn serde() { + let test: BoxedUint = BoxedUint::from_be_hex("7711223344556600", 64).unwrap(); + + let serialized = bincode::serialize(&test).unwrap(); + let deserialized: BoxedUint = bincode::deserialize(&serialized).unwrap(); + + assert_eq!(test, deserialized); + } + + #[test] + #[cfg(target_pointer_width = "64")] + fn serde_owned() { + let test: BoxedUint = BoxedUint::from_be_hex("7711223344556600", 64).unwrap(); + + let serialized = bincode::serialize(&test).unwrap(); + let deserialized: BoxedUint = bincode::deserialize_from(serialized.as_slice()).unwrap(); + + assert_eq!(test, deserialized); + } + + #[test] + #[cfg(target_pointer_width = "32")] + fn from_le_slice_eq_test() { + let bytes = hex!("7766554433221100"); + let box_uint = BoxedUint::from_le_slice(&bytes, 64).unwrap(); + + let serialized = bincode::serialize(&box_uint).unwrap(); + let deserialized: BoxedUint = bincode::deserialize_from(serialized.as_slice()).unwrap(); + + assert_eq!( + deserialized.as_limbs(), + &[Limb(0x44556677), Limb(0x00112233)] + ); + } +} From 4aa29c3b2d16155e6a3b776a73d9d52112e6c4fb Mon Sep 17 00:00:00 2001 From: Wawwior <45405580+Wawwior@users.noreply.github.com> Date: Sun, 9 Mar 2025 17:07:40 +0100 Subject: [PATCH 2/4] Fix: add missing use statements --- src/uint/boxed/encoding/serde.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/uint/boxed/encoding/serde.rs b/src/uint/boxed/encoding/serde.rs index 4e641d11..14ff7546 100644 --- a/src/uint/boxed/encoding/serde.rs +++ b/src/uint/boxed/encoding/serde.rs @@ -24,6 +24,10 @@ impl Serialize for BoxedUint { #[cfg(test)] mod tests { use super::BoxedUint; + #[cfg(target_pointer_width = "32")] + use crate::Limb; + #[cfg(target_pointer_width = "32")] + use hex_literal::hex; #[test] fn serde_roundabout() { From a04893067de4d4a2b0f19c17489051a7bebff63b Mon Sep 17 00:00:00 2001 From: wawwior <45405580+wawwior@users.noreply.github.com> Date: Sun, 9 Mar 2025 17:54:28 +0100 Subject: [PATCH 3/4] add: overflow error --- src/uint/boxed/encoding/serde.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/uint/boxed/encoding/serde.rs b/src/uint/boxed/encoding/serde.rs index 14ff7546..2488a0b4 100644 --- a/src/uint/boxed/encoding/serde.rs +++ b/src/uint/boxed/encoding/serde.rs @@ -8,7 +8,10 @@ impl<'de> Deserialize<'de> for BoxedUint { D: Deserializer<'de>, { let slice = serdect::slice::deserialize_hex_or_bin_vec(deserializer)?; - Self::from_le_slice(&slice, slice.len() as u32 * 8).map_err(Error::custom) + let bit_precision = (slice.len() as u32).checked_mul(8).ok_or(Error::custom( + "Deserialized value overflows u32 bit precision!", + ))?; + Self::from_le_slice(&slice, bit_precision).map_err(Error::custom) } } From 53bb7bacde4eab74e0e11d9fa563a76b59d74b29 Mon Sep 17 00:00:00 2001 From: wawwior <45405580+wawwior@users.noreply.github.com> Date: Thu, 20 Mar 2025 19:34:44 +0100 Subject: [PATCH 4/4] remove: serde_json dev dependency --- Cargo.lock | 1 - Cargo.toml | 2 -- src/uint/boxed/encoding/serde.rs | 8 -------- 3 files changed, 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 89348b5b..4e545cd6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -231,7 +231,6 @@ dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.2", "rlp", - "serde_json", "serdect", "subtle", "zeroize", diff --git a/Cargo.toml b/Cargo.toml index c03701dd..d28092f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,8 +38,6 @@ num-modular = { version = "0.6", features = ["num-bigint", "num-integer", "num-t proptest = "1.5" rand_core = { version = "0.9", features = ["std", "os_rng"] } rand_chacha = "0.9" -serde_json = { version = "1.0.140", features = ["alloc"] } - [features] default = ["rand"] diff --git a/src/uint/boxed/encoding/serde.rs b/src/uint/boxed/encoding/serde.rs index 2488a0b4..845579ee 100644 --- a/src/uint/boxed/encoding/serde.rs +++ b/src/uint/boxed/encoding/serde.rs @@ -32,14 +32,6 @@ mod tests { #[cfg(target_pointer_width = "32")] use hex_literal::hex; - #[test] - fn serde_roundabout() { - let n = BoxedUint::from(11223344u64); - let ser = serde_json::to_string(&n).unwrap(); - let de: BoxedUint = serde_json::from_str(&ser).unwrap(); - assert_eq!(n, de); - } - #[test] #[cfg(target_pointer_width = "64")] fn serde() {