#![cfg_attr(not(feature = "std"), no_std)]
#![warn(unused, future_incompatible, nonstandard_style, rust_2018_idioms)]
#![forbid(unsafe_code)]
mod error;
mod flags;
pub use ark_std::io::{Read, Write};
use ark_std::{
borrow::{Cow, ToOwned},
collections::{BTreeMap, BTreeSet},
convert::TryFrom,
rc::Rc,
string::String,
vec::Vec,
};
pub use error::*;
pub use flags::*;
#[cfg(feature = "derive")]
#[doc(hidden)]
pub use ark_serialize_derive::*;
pub trait CanonicalSerializeWithFlags: CanonicalSerialize {
fn serialize_with_flags<W: Write, F: Flags>(
&self,
writer: W,
flags: F,
) -> Result<(), SerializationError>;
fn serialized_size_with_flags<F: Flags>(&self) -> usize;
}
pub trait CanonicalSerialize {
fn serialize<W: Write>(&self, writer: W) -> Result<(), SerializationError>;
fn serialized_size(&self) -> usize;
#[inline]
fn serialize_uncompressed<W: Write>(&self, writer: W) -> Result<(), SerializationError> {
self.serialize(writer)
}
#[inline]
fn serialize_unchecked<W: Write>(&self, writer: W) -> Result<(), SerializationError> {
self.serialize_uncompressed(writer)
}
#[inline]
fn uncompressed_size(&self) -> usize {
self.serialized_size()
}
}
pub trait CanonicalDeserializeWithFlags: Sized {
fn deserialize_with_flags<R: Read, F: Flags>(
reader: R,
) -> Result<(Self, F), SerializationError>;
}
pub trait CanonicalDeserialize: Sized {
fn deserialize<R: Read>(reader: R) -> Result<Self, SerializationError>;
#[inline]
fn deserialize_uncompressed<R: Read>(reader: R) -> Result<Self, SerializationError> {
Self::deserialize(reader)
}
#[inline]
fn deserialize_unchecked<R: Read>(reader: R) -> Result<Self, SerializationError> {
Self::deserialize_uncompressed(reader)
}
}
macro_rules! impl_uint {
($ty: ident) => {
impl CanonicalSerialize for $ty {
#[inline]
fn serialize<W: Write>(&self, mut writer: W) -> Result<(), SerializationError> {
Ok(writer.write_all(&self.to_le_bytes())?)
}
#[inline]
fn serialized_size(&self) -> usize {
core::mem::size_of::<$ty>()
}
}
impl CanonicalDeserialize for $ty {
#[inline]
fn deserialize<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
let mut bytes = [0u8; core::mem::size_of::<$ty>()];
reader.read_exact(&mut bytes)?;
Ok($ty::from_le_bytes(bytes))
}
}
};
}
impl_uint!(u8);
impl_uint!(u16);
impl_uint!(u32);
impl_uint!(u64);
impl CanonicalSerialize for usize {
#[inline]
fn serialize<W: Write>(&self, mut writer: W) -> Result<(), SerializationError> {
Ok(writer.write_all(&(*self as u64).to_le_bytes())?)
}
#[inline]
fn serialized_size(&self) -> usize {
core::mem::size_of::<u64>()
}
}
impl CanonicalDeserialize for usize {
#[inline]
fn deserialize<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
let mut bytes = [0u8; core::mem::size_of::<u64>()];
reader.read_exact(&mut bytes)?;
usize::try_from(u64::from_le_bytes(bytes)).map_err(|_| SerializationError::InvalidData)
}
}
impl CanonicalSerialize for String {
#[inline]
fn serialize<W: Write>(&self, mut writer: W) -> Result<(), SerializationError> {
self.clone().into_bytes().serialize(&mut writer)
}
#[inline]
fn serialized_size(&self) -> usize {
self.clone().into_bytes().serialized_size()
}
}
impl CanonicalDeserialize for String {
#[inline]
fn deserialize<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
String::from_utf8(Vec::<u8>::deserialize(&mut reader)?)
.map_err(|_| SerializationError::InvalidData)
}
}
impl<T: CanonicalSerialize> CanonicalSerialize for [T] {
#[inline]
fn serialize<W: Write>(&self, mut writer: W) -> Result<(), SerializationError> {
let len = self.len() as u64;
len.serialize(&mut writer)?;
for item in self.iter() {
item.serialize(&mut writer)?;
}
Ok(())
}
#[inline]
fn serialized_size(&self) -> usize {
8 + self
.iter()
.map(|item| item.serialized_size())
.sum::<usize>()
}
#[inline]
fn serialize_uncompressed<W: Write>(&self, mut writer: W) -> Result<(), SerializationError> {
let len = self.len() as u64;
len.serialize(&mut writer)?;
for item in self.iter() {
item.serialize_uncompressed(&mut writer)?;
}
Ok(())
}
#[inline]
fn serialize_unchecked<W: Write>(&self, mut writer: W) -> Result<(), SerializationError> {
let len = self.len() as u64;
len.serialize(&mut writer)?;
for item in self.iter() {
item.serialize_unchecked(&mut writer)?;
}
Ok(())
}
#[inline]
fn uncompressed_size(&self) -> usize {
8 + self
.iter()
.map(|item| item.uncompressed_size())
.sum::<usize>()
}
}
impl<T: CanonicalSerialize> CanonicalSerialize for Vec<T> {
#[inline]
fn serialize<W: Write>(&self, writer: W) -> Result<(), SerializationError> {
self.as_slice().serialize(writer)
}
#[inline]
fn serialized_size(&self) -> usize {
self.as_slice().serialized_size()
}
#[inline]
fn serialize_uncompressed<W: Write>(&self, writer: W) -> Result<(), SerializationError> {
self.as_slice().serialize_uncompressed(writer)
}
#[inline]
fn serialize_unchecked<W: Write>(&self, writer: W) -> Result<(), SerializationError> {
self.as_slice().serialize_unchecked(writer)
}
#[inline]
fn uncompressed_size(&self) -> usize {
self.as_slice().uncompressed_size()
}
}
impl<T: CanonicalDeserialize> CanonicalDeserialize for Vec<T> {
#[inline]
fn deserialize<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
let len = u64::deserialize(&mut reader)?;
let mut values = Vec::new();
for _ in 0..len {
values.push(T::deserialize(&mut reader)?);
}
Ok(values)
}
#[inline]
fn deserialize_uncompressed<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
let len = u64::deserialize(&mut reader)?;
let mut values = Vec::new();
for _ in 0..len {
values.push(T::deserialize_uncompressed(&mut reader)?);
}
Ok(values)
}
#[inline]
fn deserialize_unchecked<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
let len = u64::deserialize(&mut reader)?;
let mut values = Vec::new();
for _ in 0..len {
values.push(T::deserialize_unchecked(&mut reader)?);
}
Ok(values)
}
}
#[inline]
pub fn buffer_bit_byte_size(modulus_bits: usize) -> (usize, usize) {
let byte_size = buffer_byte_size(modulus_bits);
((byte_size * 8), byte_size)
}
#[inline]
pub const fn buffer_byte_size(modulus_bits: usize) -> usize {
(modulus_bits + 7) / 8
}
macro_rules! impl_tuple {
($( $ty: ident : $no: tt, )*) => {
impl<$($ty, )*> CanonicalSerialize for ($($ty,)*) where
$($ty: CanonicalSerialize,)*
{
#[inline]
fn serialize<W: Write>(&self, mut _writer: W) -> Result<(), SerializationError> {
$(self.$no.serialize(&mut _writer)?;)*
Ok(())
}
#[inline]
fn serialized_size(&self) -> usize {
[$(
self.$no.serialized_size(),
)*].iter().sum()
}
#[inline]
fn serialize_uncompressed<W: Write>(&self, mut _writer: W) -> Result<(), SerializationError> {
$(self.$no.serialize_uncompressed(&mut _writer)?;)*
Ok(())
}
#[inline]
fn serialize_unchecked<W: Write>(&self, mut _writer: W) -> Result<(), SerializationError> {
$(self.$no.serialize_unchecked(&mut _writer)?;)*
Ok(())
}
#[inline]
fn uncompressed_size(&self) -> usize {
[$(
self.$no.uncompressed_size(),
)*].iter().sum()
}
}
impl<$($ty, )*> CanonicalDeserialize for ($($ty,)*) where
$($ty: CanonicalDeserialize,)*
{
#[inline]
fn deserialize<R: Read>(mut _reader: R) -> Result<Self, SerializationError> {
Ok(($(
$ty::deserialize(&mut _reader)?,
)*))
}
#[inline]
fn deserialize_uncompressed<R: Read>(mut _reader: R) -> Result<Self, SerializationError> {
Ok(($(
$ty::deserialize_uncompressed(&mut _reader)?,
)*))
}
#[inline]
fn deserialize_unchecked<R: Read>(mut _reader: R) -> Result<Self, SerializationError> {
Ok(($(
$ty::deserialize_unchecked(&mut _reader)?,
)*))
}
}
}
}
impl_tuple!();
impl_tuple!(A:0, B:1,);
impl_tuple!(A:0, B:1, C:2,);
impl_tuple!(A:0, B:1, C:2, D:3,);
impl<T> CanonicalSerialize for core::marker::PhantomData<T> {
#[inline]
fn serialize<W: Write>(&self, _writer: W) -> Result<(), SerializationError> {
Ok(())
}
#[inline]
fn serialized_size(&self) -> usize {
0
}
}
impl<T> CanonicalDeserialize for core::marker::PhantomData<T> {
#[inline]
fn deserialize<R: Read>(_reader: R) -> Result<Self, SerializationError> {
Ok(core::marker::PhantomData)
}
}
impl<'a, T: CanonicalSerialize + ToOwned> CanonicalSerialize for Cow<'a, T> {
#[inline]
fn serialize<W: Write>(&self, writer: W) -> Result<(), SerializationError> {
self.as_ref().serialize(writer)
}
#[inline]
fn serialized_size(&self) -> usize {
self.as_ref().serialized_size()
}
#[inline]
fn serialize_uncompressed<W: Write>(&self, writer: W) -> Result<(), SerializationError> {
self.as_ref().serialize_uncompressed(writer)
}
#[inline]
fn serialize_unchecked<W: Write>(&self, writer: W) -> Result<(), SerializationError> {
self.as_ref().serialize_unchecked(writer)
}
fn uncompressed_size(&self) -> usize {
self.as_ref().uncompressed_size()
}
}
impl<'a, T> CanonicalDeserialize for Cow<'a, T>
where
T: ToOwned,
<T as ToOwned>::Owned: CanonicalDeserialize,
{
#[inline]
fn deserialize<R: Read>(reader: R) -> Result<Self, SerializationError> {
Ok(Cow::Owned(<T as ToOwned>::Owned::deserialize(reader)?))
}
#[inline]
fn deserialize_uncompressed<R: Read>(reader: R) -> Result<Self, SerializationError> {
Ok(Cow::Owned(<T as ToOwned>::Owned::deserialize_uncompressed(
reader,
)?))
}
#[inline]
fn deserialize_unchecked<R: Read>(reader: R) -> Result<Self, SerializationError> {
Ok(Cow::Owned(<T as ToOwned>::Owned::deserialize_unchecked(
reader,
)?))
}
}
impl<T: CanonicalSerialize> CanonicalSerialize for Option<T> {
#[inline]
fn serialize<W: Write>(&self, mut writer: W) -> Result<(), SerializationError> {
self.is_some().serialize(&mut writer)?;
if let Some(item) = self {
item.serialize(&mut writer)?;
}
Ok(())
}
#[inline]
fn serialized_size(&self) -> usize {
self.is_some().serialized_size()
+ if let Some(item) = self {
item.serialized_size()
} else {
0
}
}
#[inline]
fn serialize_uncompressed<W: Write>(&self, mut writer: W) -> Result<(), SerializationError> {
self.is_some().serialize_uncompressed(&mut writer)?;
if let Some(item) = self {
item.serialize_uncompressed(&mut writer)?;
}
Ok(())
}
#[inline]
fn uncompressed_size(&self) -> usize {
self.is_some().uncompressed_size()
+ if let Some(item) = self {
item.uncompressed_size()
} else {
0
}
}
#[inline]
fn serialize_unchecked<W: Write>(&self, mut writer: W) -> Result<(), SerializationError> {
self.is_some().serialize_unchecked(&mut writer)?;
if let Some(item) = self {
item.serialize_unchecked(&mut writer)?;
}
Ok(())
}
}
impl<T: CanonicalDeserialize> CanonicalDeserialize for Option<T> {
#[inline]
fn deserialize<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
let is_some = bool::deserialize(&mut reader)?;
let data = if is_some {
Some(T::deserialize(&mut reader)?)
} else {
None
};
Ok(data)
}
#[inline]
fn deserialize_uncompressed<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
let is_some = bool::deserialize_uncompressed(&mut reader)?;
let data = if is_some {
Some(T::deserialize_uncompressed(&mut reader)?)
} else {
None
};
Ok(data)
}
#[inline]
fn deserialize_unchecked<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
let is_some = bool::deserialize_unchecked(&mut reader)?;
let data = if is_some {
Some(T::deserialize_unchecked(&mut reader)?)
} else {
None
};
Ok(data)
}
}
impl<T: CanonicalSerialize> CanonicalSerialize for Rc<T> {
#[inline]
fn serialize<W: Write>(&self, mut writer: W) -> Result<(), SerializationError> {
self.as_ref().serialize(&mut writer)
}
#[inline]
fn serialized_size(&self) -> usize {
self.as_ref().serialized_size()
}
#[inline]
fn serialize_uncompressed<W: Write>(&self, mut writer: W) -> Result<(), SerializationError> {
self.as_ref().serialize_uncompressed(&mut writer)
}
#[inline]
fn uncompressed_size(&self) -> usize {
self.as_ref().uncompressed_size()
}
#[inline]
fn serialize_unchecked<W: Write>(&self, mut writer: W) -> Result<(), SerializationError> {
self.as_ref().serialize_unchecked(&mut writer)
}
}
impl<T: CanonicalDeserialize> CanonicalDeserialize for Rc<T> {
#[inline]
fn deserialize<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
Ok(Rc::new(T::deserialize(&mut reader)?))
}
#[inline]
fn deserialize_uncompressed<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
Ok(Rc::new(T::deserialize_uncompressed(&mut reader)?))
}
#[inline]
fn deserialize_unchecked<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
Ok(Rc::new(T::deserialize_unchecked(&mut reader)?))
}
}
impl CanonicalSerialize for bool {
#[inline]
fn serialize<W: Write>(&self, writer: W) -> Result<(), SerializationError> {
Ok((*self as u8).serialize(writer)?)
}
#[inline]
fn serialized_size(&self) -> usize {
1
}
}
impl CanonicalDeserialize for bool {
#[inline]
fn deserialize<R: Read>(reader: R) -> Result<Self, SerializationError> {
let val = u8::deserialize(reader)?;
if val == 0 {
return Ok(false);
} else if val == 1 {
return Ok(true);
}
Err(SerializationError::InvalidData)
}
#[inline]
fn deserialize_unchecked<R: Read>(reader: R) -> Result<Self, SerializationError> {
Ok(u8::deserialize(reader)? == 1)
}
}
impl<K, V> CanonicalSerialize for BTreeMap<K, V>
where
K: CanonicalSerialize,
V: CanonicalSerialize,
{
fn serialize<W: Write>(&self, mut writer: W) -> Result<(), SerializationError> {
let len = self.len() as u64;
len.serialize(&mut writer)?;
for (k, v) in self.iter() {
k.serialize(&mut writer)?;
v.serialize(&mut writer)?;
}
Ok(())
}
fn serialized_size(&self) -> usize {
8 + self
.iter()
.map(|(k, v)| k.serialized_size() + v.serialized_size())
.sum::<usize>()
}
fn serialize_uncompressed<W: Write>(&self, mut writer: W) -> Result<(), SerializationError> {
let len = self.len() as u64;
len.serialize_uncompressed(&mut writer)?;
for (k, v) in self.iter() {
k.serialize_uncompressed(&mut writer)?;
v.serialize_uncompressed(&mut writer)?;
}
Ok(())
}
fn serialize_unchecked<W: Write>(&self, mut writer: W) -> Result<(), SerializationError> {
let len = self.len() as u64;
len.serialize_unchecked(&mut writer)?;
for (k, v) in self.iter() {
k.serialize_unchecked(&mut writer)?;
v.serialize_unchecked(&mut writer)?;
}
Ok(())
}
fn uncompressed_size(&self) -> usize {
8 + self
.iter()
.map(|(k, v)| k.uncompressed_size() + v.uncompressed_size())
.sum::<usize>()
}
}
impl<K, V> CanonicalDeserialize for BTreeMap<K, V>
where
K: Ord + CanonicalDeserialize,
V: CanonicalDeserialize,
{
fn deserialize<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
let len = u64::deserialize(&mut reader)?;
let mut map = BTreeMap::new();
for _ in 0..len {
map.insert(K::deserialize(&mut reader)?, V::deserialize(&mut reader)?);
}
Ok(map)
}
fn deserialize_uncompressed<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
let len = u64::deserialize_uncompressed(&mut reader)?;
let mut map = BTreeMap::new();
for _ in 0..len {
map.insert(
K::deserialize_uncompressed(&mut reader)?,
V::deserialize_uncompressed(&mut reader)?,
);
}
Ok(map)
}
fn deserialize_unchecked<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
let len = u64::deserialize_unchecked(&mut reader)?;
let mut map = BTreeMap::new();
for _ in 0..len {
map.insert(
K::deserialize_unchecked(&mut reader)?,
V::deserialize_unchecked(&mut reader)?,
);
}
Ok(map)
}
}
impl<T: CanonicalSerialize> CanonicalSerialize for BTreeSet<T> {
fn serialize<W: Write>(&self, mut writer: W) -> Result<(), SerializationError> {
let len = self.len() as u64;
len.serialize(&mut writer)?;
for elem in self.iter() {
elem.serialize(&mut writer)?;
}
Ok(())
}
fn serialized_size(&self) -> usize {
8 + self
.iter()
.map(|elem| elem.serialized_size())
.sum::<usize>()
}
fn serialize_uncompressed<W: Write>(&self, mut writer: W) -> Result<(), SerializationError> {
let len = self.len() as u64;
len.serialize_uncompressed(&mut writer)?;
for elem in self.iter() {
elem.serialize_uncompressed(&mut writer)?;
}
Ok(())
}
fn serialize_unchecked<W: Write>(&self, mut writer: W) -> Result<(), SerializationError> {
let len = self.len() as u64;
len.serialize_unchecked(&mut writer)?;
for elem in self.iter() {
elem.serialize_unchecked(&mut writer)?;
}
Ok(())
}
fn uncompressed_size(&self) -> usize {
8 + self
.iter()
.map(|elem| elem.uncompressed_size())
.sum::<usize>()
}
}
impl<T: CanonicalDeserialize + Ord> CanonicalDeserialize for BTreeSet<T> {
fn deserialize<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
let len = u64::deserialize(&mut reader)?;
let mut set = BTreeSet::new();
for _ in 0..len {
set.insert(T::deserialize(&mut reader)?);
}
Ok(set)
}
fn deserialize_uncompressed<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
let len = u64::deserialize_uncompressed(&mut reader)?;
let mut set = BTreeSet::new();
for _ in 0..len {
set.insert(T::deserialize_uncompressed(&mut reader)?);
}
Ok(set)
}
fn deserialize_unchecked<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
let len = u64::deserialize_unchecked(&mut reader)?;
let mut set = BTreeSet::new();
for _ in 0..len {
set.insert(T::deserialize_unchecked(&mut reader)?);
}
Ok(set)
}
}
#[cfg(test)]
mod test {
use super::*;
use ark_std::rand::RngCore;
use ark_std::vec;
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
struct Dummy;
impl CanonicalSerialize for Dummy {
#[inline]
fn serialize<W: Write>(&self, mut writer: W) -> Result<(), SerializationError> {
100u8.serialize(&mut writer)
}
#[inline]
fn serialized_size(&self) -> usize {
100u8.serialized_size()
}
#[inline]
fn serialize_uncompressed<W: Write>(
&self,
mut writer: W,
) -> Result<(), SerializationError> {
(&[100u8, 200u8]).serialize_uncompressed(&mut writer)
}
#[inline]
fn uncompressed_size(&self) -> usize {
(&[100u8, 200u8]).uncompressed_size()
}
#[inline]
fn serialize_unchecked<W: Write>(&self, mut writer: W) -> Result<(), SerializationError> {
(&[100u8, 200u8]).serialize_unchecked(&mut writer)
}
}
impl CanonicalDeserialize for Dummy {
#[inline]
fn deserialize<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
let result = u8::deserialize(&mut reader)?;
assert_eq!(result, 100u8);
Ok(Dummy)
}
#[inline]
fn deserialize_uncompressed<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
let result = Vec::<u8>::deserialize_uncompressed(&mut reader)?;
assert_eq!(result.as_slice(), &[100u8, 200u8]);
Ok(Dummy)
}
#[inline]
fn deserialize_unchecked<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
let result = Vec::<u8>::deserialize_unchecked(&mut reader)?;
assert_eq!(result.as_slice(), &[100u8, 200u8]);
Ok(Dummy)
}
}
fn test_serialize<
T: PartialEq + core::fmt::Debug + CanonicalSerialize + CanonicalDeserialize,
>(
data: T,
) {
let mut serialized = vec![0; data.serialized_size()];
data.serialize(&mut serialized[..]).unwrap();
let de = T::deserialize(&serialized[..]).unwrap();
assert_eq!(data, de);
let mut serialized = vec![0; data.uncompressed_size()];
data.serialize_uncompressed(&mut serialized[..]).unwrap();
let de = T::deserialize_uncompressed(&serialized[..]).unwrap();
assert_eq!(data, de);
let mut serialized = vec![0; data.uncompressed_size()];
data.serialize_unchecked(&mut serialized[..]).unwrap();
let de = T::deserialize_unchecked(&serialized[..]).unwrap();
assert_eq!(data, de);
}
fn ensure_non_malleable_encoding<
T: PartialEq + core::fmt::Debug + CanonicalSerialize + CanonicalDeserialize,
>(
data: T,
valid_mutation: fn(&[u8]) -> bool,
) {
let mut r = ark_std::test_rng();
let mut serialized = vec![0; data.serialized_size()];
r.fill_bytes(&mut serialized);
while !valid_mutation(&serialized) {
r.fill_bytes(&mut serialized);
}
let de = T::deserialize(&serialized[..]);
assert!(de.is_err());
let mut serialized = vec![0; data.uncompressed_size()];
r.fill_bytes(&mut serialized);
while !valid_mutation(&serialized) {
r.fill_bytes(&mut serialized);
}
let de = T::deserialize_uncompressed(&serialized[..]);
assert!(de.is_err());
}
#[test]
fn test_vec() {
test_serialize(vec![1u64, 2, 3, 4, 5]);
test_serialize(Vec::<u64>::new());
}
#[test]
fn test_uint() {
test_serialize(192830918usize);
test_serialize(192830918u64);
test_serialize(192830918u32);
test_serialize(22313u16);
test_serialize(123u8);
}
#[test]
fn test_string() {
test_serialize(String::from("arkworks"));
}
#[test]
fn test_tuple() {
test_serialize(());
test_serialize((123u64, Dummy));
test_serialize((123u64, 234u32, Dummy));
}
#[test]
fn test_tuple_vec() {
test_serialize(vec![
(Dummy, Dummy, Dummy),
(Dummy, Dummy, Dummy),
(Dummy, Dummy, Dummy),
]);
test_serialize(vec![
(86u8, 98u64, Dummy),
(86u8, 98u64, Dummy),
(86u8, 98u64, Dummy),
]);
}
#[test]
fn test_option() {
test_serialize(Some(Dummy));
test_serialize(None::<Dummy>);
test_serialize(Some(10u64));
test_serialize(None::<u64>);
}
#[test]
fn test_rc() {
test_serialize(Rc::new(Dummy));
}
#[test]
fn test_bool() {
test_serialize(true);
test_serialize(false);
let valid_mutation = |data: &[u8]| -> bool {
return data.len() == 1 && data[0] > 1;
};
for _ in 0..10 {
ensure_non_malleable_encoding(true, valid_mutation);
ensure_non_malleable_encoding(false, valid_mutation);
}
}
#[test]
fn test_btreemap() {
let mut map = BTreeMap::new();
map.insert(0u64, Dummy);
map.insert(5u64, Dummy);
test_serialize(map);
let mut map = BTreeMap::new();
map.insert(10u64, vec![1u8, 2u8, 3u8]);
map.insert(50u64, vec![4u8, 5u8, 6u8]);
test_serialize(map);
}
#[test]
fn test_btreeset() {
let mut set = BTreeSet::new();
set.insert(Dummy);
set.insert(Dummy);
test_serialize(set);
let mut set = BTreeSet::new();
set.insert(vec![1u8, 2u8, 3u8]);
set.insert(vec![4u8, 5u8, 6u8]);
test_serialize(set);
}
#[test]
fn test_phantomdata() {
test_serialize(core::marker::PhantomData::<Dummy>);
}
}