use crate::fields::models::small_fp::small_fp_backend::{SmallFp, SmallFpConfig};
use crate::{PrimeField, Zero};
use ark_serialize::{
buffer_byte_size, CanonicalDeserialize, CanonicalDeserializeWithFlags, CanonicalSerialize,
CanonicalSerializeWithFlags, Compress, EmptyFlags, Flags, SerializationError, Valid, Validate,
};
impl<P: SmallFpConfig> CanonicalSerializeWithFlags for SmallFp<P> {
fn serialize_with_flags<W: ark_std::io::Write, F: Flags>(
&self,
writer: W,
flags: F,
) -> Result<(), SerializationError> {
if F::BIT_SIZE > 8 {
return Err(SerializationError::NotEnoughSpace);
}
let output_byte_size = buffer_byte_size(Self::MODULUS_BIT_SIZE as usize + F::BIT_SIZE);
let mut w = writer;
let raw: u128 = self.value.into();
let mut bytes = [0u8; 17];
bytes[..16].copy_from_slice(&raw.to_le_bytes());
bytes[output_byte_size - 1] |= flags.u8_bitmask();
w.write_all(&bytes[..output_byte_size])?;
Ok(())
}
fn serialized_size_with_flags<F: Flags>(&self) -> usize {
buffer_byte_size(Self::MODULUS_BIT_SIZE as usize + F::BIT_SIZE)
}
}
impl<P: SmallFpConfig> CanonicalSerialize for SmallFp<P> {
#[inline]
fn serialize_with_mode<W: ark_std::io::Write>(
&self,
writer: W,
_compress: Compress,
) -> Result<(), SerializationError> {
self.serialize_with_flags(writer, EmptyFlags)
}
#[inline]
fn serialized_size(&self, _compress: Compress) -> usize {
self.serialized_size_with_flags::<EmptyFlags>()
}
}
impl<P: SmallFpConfig> CanonicalDeserializeWithFlags for SmallFp<P> {
fn deserialize_with_flags<R: ark_std::io::Read, F: Flags>(
reader: R,
) -> Result<(Self, F), SerializationError> {
if F::BIT_SIZE > 8 {
return Err(SerializationError::NotEnoughSpace);
}
let output_byte_size = Self::zero().serialized_size_with_flags::<F>();
let mut r = reader;
let mut bytes = [0u8; 17];
r.read_exact(&mut bytes[..output_byte_size])?;
let flags = F::from_u8_remove_flags(&mut bytes[output_byte_size - 1])
.ok_or(SerializationError::UnexpectedFlags)?;
let mut le_bytes = [0u8; 16];
le_bytes[..output_byte_size.min(16)].copy_from_slice(&bytes[..output_byte_size.min(16)]);
let raw = u128::from_le_bytes(le_bytes);
if raw >= P::MODULUS_U128 {
return Err(SerializationError::InvalidData);
}
let value = P::T::try_from(raw)
.ok()
.ok_or(SerializationError::InvalidData)?;
Ok((SmallFp::from_raw(value), flags))
}
}
impl<P: SmallFpConfig> Valid for SmallFp<P> {
fn check(&self) -> Result<(), SerializationError> {
Ok(())
}
}
impl<P: SmallFpConfig> CanonicalDeserialize for SmallFp<P> {
fn deserialize_with_mode<R: ark_std::io::Read>(
reader: R,
_compress: Compress,
_validate: Validate,
) -> Result<Self, SerializationError> {
Self::deserialize_with_flags::<R, EmptyFlags>(reader).map(|(r, _)| r)
}
}