Skip to main content

ark_ff/fields/models/small_fp/
serialize.rs

1use crate::fields::models::small_fp::small_fp_backend::{SmallFp, SmallFpConfig};
2use crate::{PrimeField, Zero};
3use ark_serialize::{
4    buffer_byte_size, CanonicalDeserialize, CanonicalDeserializeWithFlags, CanonicalSerialize,
5    CanonicalSerializeWithFlags, Compress, EmptyFlags, Flags, SerializationError, Valid, Validate,
6};
7
8impl<P: SmallFpConfig> CanonicalSerializeWithFlags for SmallFp<P> {
9    fn serialize_with_flags<W: ark_std::io::Write, F: Flags>(
10        &self,
11        writer: W,
12        flags: F,
13    ) -> Result<(), SerializationError> {
14        // All reasonable `Flags` should be less than 8 bits in size
15        // (256 values are enough for anyone!)
16        if F::BIT_SIZE > 8 {
17            return Err(SerializationError::NotEnoughSpace);
18        }
19
20        // Calculate the number of bytes required to represent a field element
21        // serialized with `flags`. If `F::BIT_SIZE < 8`,
22        // this is at most `N * 8 + 1`
23        let output_byte_size = buffer_byte_size(Self::MODULUS_BIT_SIZE as usize + F::BIT_SIZE);
24        let mut w = writer;
25
26        // Serialize the Montgomery representation directly
27        let raw: u128 = self.value.into();
28        let mut bytes = [0u8; 17];
29        bytes[..16].copy_from_slice(&raw.to_le_bytes());
30        bytes[output_byte_size - 1] |= flags.u8_bitmask();
31        w.write_all(&bytes[..output_byte_size])?;
32        Ok(())
33    }
34
35    // Let `m = 8 * n` for some `n` be the smallest multiple of 8 greater
36    // than `P::MODULUS_BIT_SIZE`.
37    // If `(m - P::MODULUS_BIT_SIZE) >= F::BIT_SIZE` , then this method returns `n`;
38    // otherwise, it returns `n + 1`.
39    fn serialized_size_with_flags<F: Flags>(&self) -> usize {
40        buffer_byte_size(Self::MODULUS_BIT_SIZE as usize + F::BIT_SIZE)
41    }
42}
43
44impl<P: SmallFpConfig> CanonicalSerialize for SmallFp<P> {
45    #[inline]
46    fn serialize_with_mode<W: ark_std::io::Write>(
47        &self,
48        writer: W,
49        _compress: Compress,
50    ) -> Result<(), SerializationError> {
51        self.serialize_with_flags(writer, EmptyFlags)
52    }
53
54    #[inline]
55    fn serialized_size(&self, _compress: Compress) -> usize {
56        self.serialized_size_with_flags::<EmptyFlags>()
57    }
58}
59
60impl<P: SmallFpConfig> CanonicalDeserializeWithFlags for SmallFp<P> {
61    fn deserialize_with_flags<R: ark_std::io::Read, F: Flags>(
62        reader: R,
63    ) -> Result<(Self, F), SerializationError> {
64        // All reasonable `Flags` should be less than 8 bits in size
65        // (256 values are enough for anyone!)
66        if F::BIT_SIZE > 8 {
67            return Err(SerializationError::NotEnoughSpace);
68        }
69        // Calculate the number of bytes required to represent a field element
70        // serialized with `flags`.
71        let output_byte_size = Self::zero().serialized_size_with_flags::<F>();
72        let mut r = reader;
73
74        // Deserialize directly into the Montgomery representation,
75        let mut bytes = [0u8; 17];
76        r.read_exact(&mut bytes[..output_byte_size])?;
77        let flags = F::from_u8_remove_flags(&mut bytes[output_byte_size - 1])
78            .ok_or(SerializationError::UnexpectedFlags)?;
79
80        let mut le_bytes = [0u8; 16];
81        le_bytes[..output_byte_size.min(16)].copy_from_slice(&bytes[..output_byte_size.min(16)]);
82        let raw = u128::from_le_bytes(le_bytes);
83
84        if raw >= P::MODULUS_U128 {
85            return Err(SerializationError::InvalidData);
86        }
87
88        let value = P::T::try_from(raw)
89            .ok()
90            .ok_or(SerializationError::InvalidData)?;
91        Ok((SmallFp::from_raw(value), flags))
92    }
93}
94
95impl<P: SmallFpConfig> Valid for SmallFp<P> {
96    fn check(&self) -> Result<(), SerializationError> {
97        Ok(())
98    }
99}
100
101impl<P: SmallFpConfig> CanonicalDeserialize for SmallFp<P> {
102    fn deserialize_with_mode<R: ark_std::io::Read>(
103        reader: R,
104        _compress: Compress,
105        _validate: Validate,
106    ) -> Result<Self, SerializationError> {
107        Self::deserialize_with_flags::<R, EmptyFlags>(reader).map(|(r, _)| r)
108    }
109}