Skip to main content

dory_pcs/backends/arkworks/
ark_serde.rs

1//! Manual implementations of Dory serialization traits for arkworks wrapper types
2use crate::backends::arkworks::{ArkFr, ArkG1, ArkG2, ArkGT};
3use crate::primitives::serialization::{Compress, SerializationError, Valid, Validate};
4use crate::primitives::{DoryDeserialize, DorySerialize};
5use ark_serialize::{
6    CanonicalDeserialize, CanonicalSerialize, Compress as ArkCompress,
7    SerializationError as ArkSerializationError, Valid as ArkValid, Validate as ArkValidate,
8};
9use std::io::{Read, Write};
10
11use super::BN254;
12use crate::messages::{FirstReduceMessage, ScalarProductMessage, SecondReduceMessage, VMVMessage};
13use crate::setup::{ProverSetup, VerifierSetup};
14
15impl Valid for ArkFr {
16    fn check(&self) -> Result<(), SerializationError> {
17        self.0
18            .check()
19            .map_err(|e| SerializationError::InvalidData(format!("{e:?}")))
20    }
21}
22
23impl DorySerialize for ArkFr {
24    fn serialize_with_mode<W: Write>(
25        &self,
26        writer: W,
27        compress: Compress,
28    ) -> Result<(), SerializationError> {
29        match compress {
30            Compress::Yes => self
31                .0
32                .serialize_compressed(writer)
33                .map_err(|e| SerializationError::InvalidData(format!("{e}"))),
34            Compress::No => self
35                .0
36                .serialize_uncompressed(writer)
37                .map_err(|e| SerializationError::InvalidData(format!("{e}"))),
38        }
39    }
40
41    fn serialized_size(&self, compress: Compress) -> usize {
42        match compress {
43            Compress::Yes => self.0.compressed_size(),
44            Compress::No => self.0.uncompressed_size(),
45        }
46    }
47}
48
49impl DoryDeserialize for ArkFr {
50    fn deserialize_with_mode<R: Read>(
51        reader: R,
52        compress: Compress,
53        validate: Validate,
54    ) -> Result<Self, SerializationError> {
55        let inner = match compress {
56            Compress::Yes => ark_bn254::Fr::deserialize_compressed(reader)
57                .map_err(|e| SerializationError::InvalidData(format!("{e}")))?,
58            Compress::No => ark_bn254::Fr::deserialize_uncompressed(reader)
59                .map_err(|e| SerializationError::InvalidData(format!("{e}")))?,
60        };
61
62        if matches!(validate, Validate::Yes) {
63            inner
64                .check()
65                .map_err(|e| SerializationError::InvalidData(format!("{e:?}")))?;
66        }
67
68        Ok(ArkFr(inner))
69    }
70}
71
72impl Valid for ArkG1 {
73    fn check(&self) -> Result<(), SerializationError> {
74        self.0
75            .check()
76            .map_err(|e| SerializationError::InvalidData(format!("{e:?}")))
77    }
78}
79
80impl DorySerialize for ArkG1 {
81    fn serialize_with_mode<W: Write>(
82        &self,
83        writer: W,
84        compress: Compress,
85    ) -> Result<(), SerializationError> {
86        match compress {
87            Compress::Yes => self
88                .0
89                .serialize_compressed(writer)
90                .map_err(|e| SerializationError::InvalidData(format!("{e}"))),
91            Compress::No => self
92                .0
93                .serialize_uncompressed(writer)
94                .map_err(|e| SerializationError::InvalidData(format!("{e}"))),
95        }
96    }
97
98    fn serialized_size(&self, compress: Compress) -> usize {
99        match compress {
100            Compress::Yes => self.0.compressed_size(),
101            Compress::No => self.0.uncompressed_size(),
102        }
103    }
104}
105
106impl DoryDeserialize for ArkG1 {
107    fn deserialize_with_mode<R: Read>(
108        reader: R,
109        compress: Compress,
110        validate: Validate,
111    ) -> Result<Self, SerializationError> {
112        let inner = match compress {
113            Compress::Yes => ark_bn254::G1Projective::deserialize_compressed(reader)
114                .map_err(|e| SerializationError::InvalidData(format!("{e}")))?,
115            Compress::No => ark_bn254::G1Projective::deserialize_uncompressed(reader)
116                .map_err(|e| SerializationError::InvalidData(format!("{e}")))?,
117        };
118
119        if matches!(validate, Validate::Yes) {
120            inner
121                .check()
122                .map_err(|e| SerializationError::InvalidData(format!("{e:?}")))?;
123        }
124
125        Ok(ArkG1(inner))
126    }
127}
128
129impl Valid for ArkG2 {
130    fn check(&self) -> Result<(), SerializationError> {
131        self.0
132            .check()
133            .map_err(|e| SerializationError::InvalidData(format!("{e:?}")))
134    }
135}
136
137impl DorySerialize for ArkG2 {
138    fn serialize_with_mode<W: Write>(
139        &self,
140        writer: W,
141        compress: Compress,
142    ) -> Result<(), SerializationError> {
143        match compress {
144            Compress::Yes => self
145                .0
146                .serialize_compressed(writer)
147                .map_err(|e| SerializationError::InvalidData(format!("{e}"))),
148            Compress::No => self
149                .0
150                .serialize_uncompressed(writer)
151                .map_err(|e| SerializationError::InvalidData(format!("{e}"))),
152        }
153    }
154
155    fn serialized_size(&self, compress: Compress) -> usize {
156        match compress {
157            Compress::Yes => self.0.compressed_size(),
158            Compress::No => self.0.uncompressed_size(),
159        }
160    }
161}
162
163impl DoryDeserialize for ArkG2 {
164    fn deserialize_with_mode<R: Read>(
165        reader: R,
166        compress: Compress,
167        validate: Validate,
168    ) -> Result<Self, SerializationError> {
169        let inner = match compress {
170            Compress::Yes => ark_bn254::G2Projective::deserialize_compressed(reader)
171                .map_err(|e| SerializationError::InvalidData(format!("{e}")))?,
172            Compress::No => ark_bn254::G2Projective::deserialize_uncompressed(reader)
173                .map_err(|e| SerializationError::InvalidData(format!("{e}")))?,
174        };
175
176        if matches!(validate, Validate::Yes) {
177            inner
178                .check()
179                .map_err(|e| SerializationError::InvalidData(format!("{e:?}")))?;
180        }
181
182        Ok(ArkG2(inner))
183    }
184}
185
186impl Valid for ArkGT {
187    fn check(&self) -> Result<(), SerializationError> {
188        self.0
189            .check()
190            .map_err(|e| SerializationError::InvalidData(format!("{e:?}")))
191    }
192}
193
194impl DorySerialize for ArkGT {
195    fn serialize_with_mode<W: Write>(
196        &self,
197        writer: W,
198        compress: Compress,
199    ) -> Result<(), SerializationError> {
200        match compress {
201            Compress::Yes => self
202                .0
203                .serialize_compressed(writer)
204                .map_err(|e| SerializationError::InvalidData(format!("{e}"))),
205            Compress::No => self
206                .0
207                .serialize_uncompressed(writer)
208                .map_err(|e| SerializationError::InvalidData(format!("{e}"))),
209        }
210    }
211
212    fn serialized_size(&self, compress: Compress) -> usize {
213        match compress {
214            Compress::Yes => self.0.compressed_size(),
215            Compress::No => self.0.uncompressed_size(),
216        }
217    }
218}
219
220impl DoryDeserialize for ArkGT {
221    fn deserialize_with_mode<R: Read>(
222        reader: R,
223        compress: Compress,
224        validate: Validate,
225    ) -> Result<Self, SerializationError> {
226        let inner = match compress {
227            Compress::Yes => ark_bn254::Fq12::deserialize_compressed(reader)
228                .map_err(|e| SerializationError::InvalidData(format!("{e}")))?,
229            Compress::No => ark_bn254::Fq12::deserialize_uncompressed(reader)
230                .map_err(|e| SerializationError::InvalidData(format!("{e}")))?,
231        };
232
233        if matches!(validate, Validate::Yes) {
234            inner
235                .check()
236                .map_err(|e| SerializationError::InvalidData(format!("{e:?}")))?;
237        }
238
239        Ok(ArkGT(inner))
240    }
241}
242
243// Arkworks-specific Dory proof type
244use super::ArkDoryProof;
245
246#[cfg(feature = "zk")]
247mod zk_serde {
248    use ark_serialize::{
249        CanonicalDeserialize as De, CanonicalSerialize as Ser, Compress, SerializationError, Valid,
250        Validate,
251    };
252    use std::io::{Read, Write};
253
254    pub(super) fn ser_opt<W: Write, T: Ser>(
255        v: &Option<T>,
256        w: &mut W,
257        c: Compress,
258    ) -> Result<(), SerializationError> {
259        match v {
260            Some(val) => {
261                Ser::serialize_with_mode(&1u8, &mut *w, c)?;
262                Ser::serialize_with_mode(val, w, c)
263            }
264            None => Ser::serialize_with_mode(&0u8, w, c),
265        }
266    }
267
268    pub(super) fn de_opt<R: Read, T: De>(
269        r: &mut R,
270        c: Compress,
271        v: Validate,
272    ) -> Result<Option<T>, SerializationError> {
273        match <u8 as De>::deserialize_with_mode(&mut *r, c, v)? {
274            0 => Ok(None),
275            1 => Ok(Some(T::deserialize_with_mode(r, c, v)?)),
276            _ => Err(SerializationError::InvalidData),
277        }
278    }
279
280    pub(super) fn size_opt<T: Ser>(v: &Option<T>, c: Compress) -> usize {
281        1 + v.as_ref().map_or(0, |val| Ser::serialized_size(val, c))
282    }
283
284    macro_rules! impl_serde {
285        ($ty:ty, [$($field:ident),+]) => {
286            impl Valid for $ty { fn check(&self) -> Result<(), SerializationError> { Ok(()) } }
287            impl Ser for $ty {
288                fn serialize_with_mode<W: Write>(&self, mut w: W, c: Compress) -> Result<(), SerializationError> {
289                    $(Ser::serialize_with_mode(&self.$field, &mut w, c)?;)+
290                    Ok(())
291                }
292                fn serialized_size(&self, c: Compress) -> usize {
293                    0 $(+ Ser::serialized_size(&self.$field, c))+
294                }
295            }
296            impl De for $ty {
297                fn deserialize_with_mode<R: Read>(mut r: R, c: Compress, v: Validate) -> Result<Self, SerializationError> {
298                    Ok(Self { $($field: De::deserialize_with_mode(&mut r, c, v)?),+ })
299                }
300            }
301        };
302    }
303
304    use super::{ArkFr, ArkG1, ArkG2, ArkGT};
305    use crate::messages::{ScalarProductProof, Sigma1Proof, Sigma2Proof};
306
307    impl_serde!(Sigma1Proof<ArkG1, ArkG2, ArkFr>, [a1, a2, z1, z2, z3]);
308    impl_serde!(Sigma2Proof<ArkFr, ArkGT>, [a, z1, z2]);
309    impl_serde!(ScalarProductProof<ArkG1, ArkG2, ArkFr, ArkGT>, [p1, p2, q, r, e1, e2, r1, r2, r3]);
310}
311
312impl ArkValid for ArkDoryProof {
313    fn check(&self) -> Result<(), ArkSerializationError> {
314        Ok(())
315    }
316}
317
318impl CanonicalSerialize for ArkDoryProof {
319    fn serialize_with_mode<W: Write>(
320        &self,
321        mut writer: W,
322        compress: ArkCompress,
323    ) -> Result<(), ArkSerializationError> {
324        // Serialize VMV message
325        CanonicalSerialize::serialize_with_mode(&self.vmv_message.c, &mut writer, compress)?;
326        CanonicalSerialize::serialize_with_mode(&self.vmv_message.d2, &mut writer, compress)?;
327        CanonicalSerialize::serialize_with_mode(&self.vmv_message.e1, &mut writer, compress)?;
328
329        // Serialize number of rounds
330        let num_rounds = self.first_messages.len() as u32;
331        CanonicalSerialize::serialize_with_mode(&num_rounds, &mut writer, compress)?;
332
333        // Serialize first messages
334        for msg in &self.first_messages {
335            CanonicalSerialize::serialize_with_mode(&msg.d1_left, &mut writer, compress)?;
336            CanonicalSerialize::serialize_with_mode(&msg.d1_right, &mut writer, compress)?;
337            CanonicalSerialize::serialize_with_mode(&msg.d2_left, &mut writer, compress)?;
338            CanonicalSerialize::serialize_with_mode(&msg.d2_right, &mut writer, compress)?;
339            CanonicalSerialize::serialize_with_mode(&msg.e1_beta, &mut writer, compress)?;
340            CanonicalSerialize::serialize_with_mode(&msg.e2_beta, &mut writer, compress)?;
341        }
342
343        // Serialize second messages
344        for msg in &self.second_messages {
345            CanonicalSerialize::serialize_with_mode(&msg.c_plus, &mut writer, compress)?;
346            CanonicalSerialize::serialize_with_mode(&msg.c_minus, &mut writer, compress)?;
347            CanonicalSerialize::serialize_with_mode(&msg.e1_plus, &mut writer, compress)?;
348            CanonicalSerialize::serialize_with_mode(&msg.e1_minus, &mut writer, compress)?;
349            CanonicalSerialize::serialize_with_mode(&msg.e2_plus, &mut writer, compress)?;
350            CanonicalSerialize::serialize_with_mode(&msg.e2_minus, &mut writer, compress)?;
351        }
352
353        // Serialize final message
354        CanonicalSerialize::serialize_with_mode(&self.final_message.e1, &mut writer, compress)?;
355        CanonicalSerialize::serialize_with_mode(&self.final_message.e2, &mut writer, compress)?;
356
357        // Serialize nu and sigma
358        CanonicalSerialize::serialize_with_mode(&(self.nu as u32), &mut writer, compress)?;
359        CanonicalSerialize::serialize_with_mode(&(self.sigma as u32), &mut writer, compress)?;
360
361        #[cfg(feature = "zk")]
362        {
363            zk_serde::ser_opt(&self.e2, &mut writer, compress)?;
364            zk_serde::ser_opt(&self.y_com, &mut writer, compress)?;
365            zk_serde::ser_opt(&self.sigma1_proof, &mut writer, compress)?;
366            zk_serde::ser_opt(&self.sigma2_proof, &mut writer, compress)?;
367            zk_serde::ser_opt(&self.scalar_product_proof, &mut writer, compress)?;
368        }
369
370        Ok(())
371    }
372
373    fn serialized_size(&self, compress: ArkCompress) -> usize {
374        let mut size = 0;
375
376        // VMV message
377        size += CanonicalSerialize::serialized_size(&self.vmv_message.c, compress);
378        size += CanonicalSerialize::serialized_size(&self.vmv_message.d2, compress);
379        size += CanonicalSerialize::serialized_size(&self.vmv_message.e1, compress);
380
381        // Number of rounds
382        size += 4; // u32
383
384        // First messages
385        for msg in &self.first_messages {
386            size += CanonicalSerialize::serialized_size(&msg.d1_left, compress);
387            size += CanonicalSerialize::serialized_size(&msg.d1_right, compress);
388            size += CanonicalSerialize::serialized_size(&msg.d2_left, compress);
389            size += CanonicalSerialize::serialized_size(&msg.d2_right, compress);
390            size += CanonicalSerialize::serialized_size(&msg.e1_beta, compress);
391            size += CanonicalSerialize::serialized_size(&msg.e2_beta, compress);
392        }
393
394        // Second messages
395        for msg in &self.second_messages {
396            size += CanonicalSerialize::serialized_size(&msg.c_plus, compress);
397            size += CanonicalSerialize::serialized_size(&msg.c_minus, compress);
398            size += CanonicalSerialize::serialized_size(&msg.e1_plus, compress);
399            size += CanonicalSerialize::serialized_size(&msg.e1_minus, compress);
400            size += CanonicalSerialize::serialized_size(&msg.e2_plus, compress);
401            size += CanonicalSerialize::serialized_size(&msg.e2_minus, compress);
402        }
403
404        // Final message
405        size += CanonicalSerialize::serialized_size(&self.final_message.e1, compress);
406        size += CanonicalSerialize::serialized_size(&self.final_message.e2, compress);
407
408        // nu and sigma
409        size += 8; // 2 * u32
410
411        #[cfg(feature = "zk")]
412        {
413            size += zk_serde::size_opt(&self.e2, compress);
414            size += zk_serde::size_opt(&self.y_com, compress);
415            size += zk_serde::size_opt(&self.sigma1_proof, compress);
416            size += zk_serde::size_opt(&self.sigma2_proof, compress);
417            size += zk_serde::size_opt(&self.scalar_product_proof, compress);
418        }
419
420        size
421    }
422}
423
424impl CanonicalDeserialize for ArkDoryProof {
425    fn deserialize_with_mode<R: Read>(
426        mut reader: R,
427        compress: ArkCompress,
428        validate: ArkValidate,
429    ) -> Result<Self, ArkSerializationError> {
430        // Deserialize VMV message
431        let c = CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
432        let d2 = CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
433        let e1 = CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
434        let vmv_message = VMVMessage { c, d2, e1 };
435
436        // Deserialize number of rounds
437        let num_rounds =
438            <u32 as CanonicalDeserialize>::deserialize_with_mode(&mut reader, compress, validate)?
439                as usize;
440
441        // Deserialize first messages
442        let mut first_messages = Vec::with_capacity(num_rounds);
443        for _ in 0..num_rounds {
444            let d1_left =
445                CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
446            let d1_right =
447                CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
448            let d2_left =
449                CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
450            let d2_right =
451                CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
452            let e1_beta =
453                CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
454            let e2_beta =
455                CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
456            first_messages.push(FirstReduceMessage {
457                d1_left,
458                d1_right,
459                d2_left,
460                d2_right,
461                e1_beta,
462                e2_beta,
463            });
464        }
465
466        // Deserialize second messages
467        let mut second_messages = Vec::with_capacity(num_rounds);
468        for _ in 0..num_rounds {
469            let c_plus =
470                CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
471            let c_minus =
472                CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
473            let e1_plus =
474                CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
475            let e1_minus =
476                CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
477            let e2_plus =
478                CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
479            let e2_minus =
480                CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
481            second_messages.push(SecondReduceMessage {
482                c_plus,
483                c_minus,
484                e1_plus,
485                e1_minus,
486                e2_plus,
487                e2_minus,
488            });
489        }
490
491        // Deserialize final message
492        let e1 = CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
493        let e2 = CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
494        let final_message = ScalarProductMessage { e1, e2 };
495
496        // Deserialize nu and sigma
497        let nu =
498            <u32 as CanonicalDeserialize>::deserialize_with_mode(&mut reader, compress, validate)?
499                as usize;
500        let sigma =
501            <u32 as CanonicalDeserialize>::deserialize_with_mode(&mut reader, compress, validate)?
502                as usize;
503
504        Ok(ArkDoryProof {
505            vmv_message,
506            first_messages,
507            second_messages,
508            final_message,
509            nu,
510            sigma,
511            #[cfg(feature = "zk")]
512            e2: zk_serde::de_opt(&mut reader, compress, validate)?,
513            #[cfg(feature = "zk")]
514            y_com: zk_serde::de_opt(&mut reader, compress, validate)?,
515            #[cfg(feature = "zk")]
516            sigma1_proof: zk_serde::de_opt(&mut reader, compress, validate)?,
517            #[cfg(feature = "zk")]
518            sigma2_proof: zk_serde::de_opt(&mut reader, compress, validate)?,
519            #[cfg(feature = "zk")]
520            scalar_product_proof: zk_serde::de_opt(&mut reader, compress, validate)?,
521        })
522    }
523}
524
525// Setup wrapper types (declared in ark_setup.rs, serialization impls here)
526use super::{ArkworksProverSetup, ArkworksVerifierSetup};
527
528impl ArkValid for ArkworksProverSetup {
529    fn check(&self) -> Result<(), ArkSerializationError> {
530        Ok(())
531    }
532}
533
534impl CanonicalSerialize for ArkworksProverSetup {
535    fn serialize_with_mode<W: Write>(
536        &self,
537        mut writer: W,
538        compress: ArkCompress,
539    ) -> Result<(), ArkSerializationError> {
540        let dory_compress = match compress {
541            ArkCompress::Yes => Compress::Yes,
542            ArkCompress::No => Compress::No,
543        };
544
545        DorySerialize::serialize_with_mode(&self.0, &mut writer, dory_compress)
546            .map_err(|_| ArkSerializationError::InvalidData)
547    }
548
549    fn serialized_size(&self, compress: ArkCompress) -> usize {
550        let dory_compress = match compress {
551            ArkCompress::Yes => Compress::Yes,
552            ArkCompress::No => Compress::No,
553        };
554        DorySerialize::serialized_size(&self.0, dory_compress)
555    }
556}
557
558impl CanonicalDeserialize for ArkworksProverSetup {
559    fn deserialize_with_mode<R: Read>(
560        mut reader: R,
561        compress: ArkCompress,
562        validate: ArkValidate,
563    ) -> Result<Self, ArkSerializationError> {
564        let dory_compress = match compress {
565            ArkCompress::Yes => Compress::Yes,
566            ArkCompress::No => Compress::No,
567        };
568
569        let dory_validate = match validate {
570            ArkValidate::Yes => Validate::Yes,
571            ArkValidate::No => Validate::No,
572        };
573
574        let setup =
575            ProverSetup::<BN254>::deserialize_with_mode(&mut reader, dory_compress, dory_validate)
576                .map_err(|_| ArkSerializationError::InvalidData)?;
577
578        Ok(Self(setup))
579    }
580}
581
582impl ArkValid for ArkworksVerifierSetup {
583    fn check(&self) -> Result<(), ArkSerializationError> {
584        Ok(())
585    }
586}
587
588impl CanonicalSerialize for ArkworksVerifierSetup {
589    fn serialize_with_mode<W: Write>(
590        &self,
591        mut writer: W,
592        compress: ArkCompress,
593    ) -> Result<(), ArkSerializationError> {
594        let dory_compress = match compress {
595            ArkCompress::Yes => Compress::Yes,
596            ArkCompress::No => Compress::No,
597        };
598
599        DorySerialize::serialize_with_mode(&self.0, &mut writer, dory_compress)
600            .map_err(|_| ArkSerializationError::InvalidData)
601    }
602
603    fn serialized_size(&self, compress: ArkCompress) -> usize {
604        let dory_compress = match compress {
605            ArkCompress::Yes => Compress::Yes,
606            ArkCompress::No => Compress::No,
607        };
608        DorySerialize::serialized_size(&self.0, dory_compress)
609    }
610}
611
612impl CanonicalDeserialize for ArkworksVerifierSetup {
613    fn deserialize_with_mode<R: Read>(
614        mut reader: R,
615        compress: ArkCompress,
616        validate: ArkValidate,
617    ) -> Result<Self, ArkSerializationError> {
618        let dory_compress = match compress {
619            ArkCompress::Yes => Compress::Yes,
620            ArkCompress::No => Compress::No,
621        };
622
623        let dory_validate = match validate {
624            ArkValidate::Yes => Validate::Yes,
625            ArkValidate::No => Validate::No,
626        };
627
628        let setup = VerifierSetup::<BN254>::deserialize_with_mode(
629            &mut reader,
630            dory_compress,
631            dory_validate,
632        )
633        .map_err(|_| ArkSerializationError::InvalidData)?;
634
635        Ok(Self(setup))
636    }
637}