diff --git a/src/arithmetic/big_gmp.rs b/src/arithmetic/big_gmp.rs index 35df3e2d..b5e0c42e 100644 --- a/src/arithmetic/big_gmp.rs +++ b/src/arithmetic/big_gmp.rs @@ -21,7 +21,6 @@ use std::{fmt, ops, ptr}; use gmp::mpz::Mpz; use gmp::sign::Sign; use num_traits::{One, Zero}; -use serde::{Deserialize, Serialize}; use zeroize::Zeroize; use super::errors::*; @@ -35,8 +34,7 @@ type BN = Mpz; /// very limited API that allows easily switching between implementations. /// /// Set of traits implemented on BigInt remains the same regardless of underlying implementation. -#[derive(PartialOrd, PartialEq, Ord, Eq, Clone, Serialize, Deserialize)] -#[serde(transparent)] +#[derive(PartialOrd, PartialEq, Ord, Eq, Clone)] pub struct BigInt { gmp: Mpz, } diff --git a/src/arithmetic/big_native.rs b/src/arithmetic/big_native.rs index 3793414d..0345d97c 100644 --- a/src/arithmetic/big_native.rs +++ b/src/arithmetic/big_native.rs @@ -2,7 +2,6 @@ use std::convert::{TryFrom, TryInto}; use std::{fmt, ops}; use num_traits::Signed; -use serde::{Deserialize, Serialize}; use super::errors::*; use super::traits::*; @@ -19,8 +18,7 @@ mod ring_algorithms; /// very limited API that allows easily switching between implementations. /// /// Set of traits implemented on BigInt remains the same regardless of underlying implementation. -#[derive(PartialOrd, PartialEq, Ord, Eq, Clone, Serialize, Deserialize)] -#[serde(transparent)] +#[derive(PartialOrd, PartialEq, Ord, Eq, Clone)] pub struct BigInt { num: BN, } diff --git a/src/arithmetic/mod.rs b/src/arithmetic/mod.rs index 3840b670..aff7aa5f 100644 --- a/src/arithmetic/mod.rs +++ b/src/arithmetic/mod.rs @@ -17,6 +17,7 @@ mod errors; mod macros; mod samplable; +mod serde_support; pub mod traits; #[cfg(not(any(feature = "rust-gmp-kzen", feature = "num-bigint")))] @@ -31,6 +32,7 @@ pub use big_gmp::BigInt; #[cfg(feature = "num-bigint")] mod big_native; + #[cfg(feature = "num-bigint")] pub use big_native::BigInt; @@ -45,6 +47,16 @@ mod test { use super::*; + #[test] + fn serde() { + use serde_test::{assert_tokens, Token::*}; + for bigint in [BigInt::zero(), BigInt::sample(1024)] { + let bytes = bigint.to_bytes(); + let tokens = vec![Bytes(bytes.leak())]; + assert_tokens(&bigint, &tokens) + } + } + #[test] fn serializing_to_hex() { let n = BigInt::from(1_000_000_u32); diff --git a/src/arithmetic/serde_support.rs b/src/arithmetic/serde_support.rs new file mode 100644 index 00000000..fc6040aa --- /dev/null +++ b/src/arithmetic/serde_support.rs @@ -0,0 +1,43 @@ +use std::fmt; + +use serde::de::Visitor; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +use super::traits::Converter; +use super::BigInt; + +impl Serialize for BigInt { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let bytes = self.to_bytes(); + serializer.serialize_bytes(&bytes) + } +} + +impl<'de> Deserialize<'de> for BigInt { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct BigintVisitor; + + impl<'de> Visitor<'de> for BigintVisitor { + type Value = BigInt; + + fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "bigint") + } + + fn visit_bytes(self, v: &[u8]) -> Result + where + E: serde::de::Error, + { + Ok(BigInt::from_bytes(v)) + } + } + + deserializer.deserialize_bytes(BigintVisitor) + } +}