1#![cfg_attr(not(feature = "std"), no_std)]
2#![warn(
3 unused,
4 future_incompatible,
5 nonstandard_style,
6 rust_2018_idioms,
7 rust_2021_compatibility
8)]
9#![forbid(unsafe_code)]
10#![doc = include_str!("../README.md")]
11mod error;
12mod flags;
13mod impls;
14
15pub use ark_std::io::{Read, Write};
16
17pub use error::*;
18pub use flags::*;
19
20#[cfg(test)]
21mod test;
22
23#[cfg(feature = "derive")]
24#[doc(hidden)]
25pub use ark_serialize_derive::*;
26
27use digest::{generic_array::GenericArray, Digest, OutputSizeUser};
28
29#[macro_export]
32macro_rules! serialize_to_vec {
33 ($($x:expr),*) => ({
34 let mut buf = ::ark_std::vec![];
35 {$crate::serialize_to_vec!(@inner buf, $($x),*)}.map(|_| buf)
36 });
37
38 (@inner $buf:expr, $y:expr, $($x:expr),*) => ({
39 {
40 $crate::CanonicalSerialize::serialize_uncompressed(&$y, &mut $buf)
41 }.and({$crate::serialize_to_vec!(@inner $buf, $($x),*)})
42 });
43
44 (@inner $buf:expr, $x:expr) => ({
45 $crate::CanonicalSerialize::serialize_uncompressed(&$x, &mut $buf)
46 });
47}
48
49#[derive(Copy, Clone, PartialEq, Eq)]
52pub enum Compress {
53 Yes,
54 No,
55}
56
57#[derive(Copy, Clone, PartialEq, Eq)]
60pub enum Validate {
61 Yes,
62 No,
63}
64
65pub trait Valid: Sized + Sync {
66 fn check(&self) -> Result<(), SerializationError>;
67
68 fn batch_check<'a>(
69 batch: impl Iterator<Item = &'a Self> + Send,
70 ) -> Result<(), SerializationError>
71 where
72 Self: 'a,
73 {
74 #[cfg(feature = "parallel")]
75 {
76 use rayon::{iter::ParallelBridge, prelude::ParallelIterator};
77 batch.par_bridge().try_for_each(|e| e.check())?;
78 }
79 #[cfg(not(feature = "parallel"))]
80 {
81 for item in batch {
82 item.check()?;
83 }
84 }
85 Ok(())
86 }
87}
88
89pub trait CanonicalSerialize {
106 fn serialize_with_mode<W: Write>(
108 &self,
109 writer: W,
110 compress: Compress,
111 ) -> Result<(), SerializationError>;
112
113 fn serialized_size(&self, compress: Compress) -> usize;
114
115 fn serialize_compressed<W: Write>(&self, writer: W) -> Result<(), SerializationError> {
116 self.serialize_with_mode(writer, Compress::Yes)
117 }
118
119 fn compressed_size(&self) -> usize {
120 self.serialized_size(Compress::Yes)
121 }
122
123 fn serialize_uncompressed<W: Write>(&self, writer: W) -> Result<(), SerializationError> {
124 self.serialize_with_mode(writer, Compress::No)
125 }
126
127 fn uncompressed_size(&self) -> usize {
128 self.serialized_size(Compress::No)
129 }
130}
131
132pub trait CanonicalDeserialize: Valid {
149 fn deserialize_with_mode<R: Read>(
151 reader: R,
152 compress: Compress,
153 validate: Validate,
154 ) -> Result<Self, SerializationError>;
155
156 fn deserialize_compressed<R: Read>(reader: R) -> Result<Self, SerializationError> {
157 Self::deserialize_with_mode(reader, Compress::Yes, Validate::Yes)
158 }
159
160 fn deserialize_compressed_unchecked<R: Read>(reader: R) -> Result<Self, SerializationError> {
161 Self::deserialize_with_mode(reader, Compress::Yes, Validate::No)
162 }
163
164 fn deserialize_uncompressed<R: Read>(reader: R) -> Result<Self, SerializationError> {
165 Self::deserialize_with_mode(reader, Compress::No, Validate::Yes)
166 }
167
168 fn deserialize_uncompressed_unchecked<R: Read>(reader: R) -> Result<Self, SerializationError> {
169 Self::deserialize_with_mode(reader, Compress::No, Validate::No)
170 }
171}
172
173pub trait CanonicalSerializeWithFlags: CanonicalSerialize {
175 fn serialize_with_flags<W: Write, F: Flags>(
177 &self,
178 writer: W,
179 flags: F,
180 ) -> Result<(), SerializationError>;
181
182 fn serialized_size_with_flags<F: Flags>(&self) -> usize;
184}
185
186pub trait CanonicalDeserializeWithFlags: Sized {
188 fn deserialize_with_flags<R: Read, F: Flags>(
191 reader: R,
192 ) -> Result<(Self, F), SerializationError>;
193}
194
195struct HashMarshaller<'a, H: Digest>(&'a mut H);
198
199impl<'a, H: Digest> ark_std::io::Write for HashMarshaller<'a, H> {
200 #[inline]
201 fn write(&mut self, buf: &[u8]) -> ark_std::io::Result<usize> {
202 Digest::update(self.0, buf);
203 Ok(buf.len())
204 }
205
206 #[inline]
207 fn flush(&mut self) -> ark_std::io::Result<()> {
208 Ok(())
209 }
210}
211
212pub trait CanonicalSerializeHashExt: CanonicalSerialize {
215 fn hash<H: Digest>(&self) -> GenericArray<u8, <H as OutputSizeUser>::OutputSize> {
216 let mut hasher = H::new();
217 self.serialize_compressed(HashMarshaller(&mut hasher))
218 .expect("HashMarshaller::flush should be infaillible!");
219 hasher.finalize()
220 }
221
222 fn hash_uncompressed<H: Digest>(&self) -> GenericArray<u8, <H as OutputSizeUser>::OutputSize> {
223 let mut hasher = H::new();
224 self.serialize_uncompressed(HashMarshaller(&mut hasher))
225 .expect("HashMarshaller::flush should be infaillible!");
226 hasher.finalize()
227 }
228}
229
230impl<T: CanonicalSerialize> CanonicalSerializeHashExt for T {}
233
234#[inline]
235pub fn buffer_bit_byte_size(modulus_bits: usize) -> (usize, usize) {
236 let byte_size = buffer_byte_size(modulus_bits);
237 ((byte_size * 8), byte_size)
238}
239
240#[inline]
243pub const fn buffer_byte_size(modulus_bits: usize) -> usize {
244 (modulus_bits + 7) / 8
245}