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