ark_poly_commit/marlin/marlin_pst13_pc/
data_structures.rs

1use crate::{
2    BTreeMap, PCCommitmentState, PCCommitterKey, PCPreparedVerifierKey, PCUniversalParams,
3    PCVerifierKey,
4};
5use ark_ec::pairing::Pairing;
6use ark_poly::DenseMVPolynomial;
7use ark_serialize::{
8    CanonicalDeserialize, CanonicalSerialize, Compress, SerializationError, Valid, Validate,
9};
10#[cfg(not(feature = "std"))]
11use ark_std::vec::Vec;
12use ark_std::{
13    io::{Read, Write},
14    marker::PhantomData,
15    ops::{Add, AddAssign, Index},
16    rand::RngCore,
17};
18
19/// `UniversalParams` are the universal parameters for the MarlinPST13 scheme.
20#[derive(Derivative)]
21#[derivative(Default(bound = ""), Clone(bound = ""), Debug(bound = ""))]
22pub struct UniversalParams<E, P>
23where
24    E: Pairing,
25    P: DenseMVPolynomial<E::ScalarField>,
26    P::Point: Index<usize, Output = E::ScalarField>,
27{
28    /// Contains group elements corresponding to all possible monomials with
29    /// `num_vars` and maximum degree `max_degree` evaluated at `\beta`
30    pub powers_of_g: BTreeMap<P::Term, E::G1Affine>,
31    /// `\gamma` times the generater of G1
32    pub gamma_g: E::G1Affine,
33    /// Group elements of the form `{ \beta_i^j \gamma G }`, where `i` ranges
34    /// from 0 to `num_vars-1` and `j` ranges from `1` to `max_degree+1`.
35    pub powers_of_gamma_g: Vec<Vec<E::G1Affine>>,
36    /// The generator of G2.
37    pub h: E::G2Affine,
38    /// Group elements of the form `{ \beta_i H }`, where `i` ranges from 0 to `num_vars-1`
39    pub beta_h: Vec<E::G2Affine>,
40    /// The generator of G2, prepared for use in pairings.
41    #[derivative(Debug = "ignore")]
42    pub prepared_h: E::G2Prepared,
43    /// Group elements of the form `{ \beta_i H }`, where `i` ranges from 0 to `num_vars-1`,
44    /// prepared for use in pairings
45    #[derivative(Debug = "ignore")]
46    pub prepared_beta_h: Vec<E::G2Prepared>,
47    /// The number of variables `self` is initialized for
48    pub num_vars: usize,
49    /// The maximum degree supported by `self`
50    pub max_degree: usize,
51}
52
53impl<E, P> Valid for UniversalParams<E, P>
54where
55    E: Pairing,
56    P: DenseMVPolynomial<E::ScalarField>,
57    P::Point: Index<usize, Output = E::ScalarField>,
58{
59    fn check(&self) -> Result<(), SerializationError> {
60        self.powers_of_g.check()?;
61        self.gamma_g.check()?;
62        self.powers_of_gamma_g.check()?;
63        self.h.check()?;
64        self.beta_h.check()?;
65        self.num_vars.check()?;
66        self.max_degree.check()?;
67        Ok(())
68    }
69}
70
71impl<E, P> CanonicalSerialize for UniversalParams<E, P>
72where
73    E: Pairing,
74    P: DenseMVPolynomial<E::ScalarField>,
75    P::Point: Index<usize, Output = E::ScalarField>,
76{
77    fn serialize_with_mode<W: Write>(
78        &self,
79        mut writer: W,
80        compress: Compress,
81    ) -> Result<(), SerializationError> {
82        self.powers_of_g
83            .serialize_with_mode(&mut writer, compress)?;
84        self.gamma_g.serialize_with_mode(&mut writer, compress)?;
85        self.powers_of_gamma_g
86            .serialize_with_mode(&mut writer, compress)?;
87        self.h.serialize_with_mode(&mut writer, compress)?;
88        self.beta_h.serialize_with_mode(&mut writer, compress)?;
89        self.num_vars.serialize_with_mode(&mut writer, compress)?;
90        self.max_degree.serialize_with_mode(&mut writer, compress)
91    }
92
93    fn serialized_size(&self, compress: Compress) -> usize {
94        self.powers_of_g.serialized_size(compress)
95            + self.gamma_g.serialized_size(compress)
96            + self.powers_of_gamma_g.serialized_size(compress)
97            + self.h.serialized_size(compress)
98            + self.beta_h.serialized_size(compress)
99            + self.num_vars.serialized_size(compress)
100            + self.max_degree.serialized_size(compress)
101    }
102}
103
104impl<E, P> CanonicalDeserialize for UniversalParams<E, P>
105where
106    E: Pairing,
107    P: DenseMVPolynomial<E::ScalarField>,
108    P::Point: Index<usize, Output = E::ScalarField>,
109{
110    fn deserialize_with_mode<R: Read>(
111        mut reader: R,
112        compress: Compress,
113        validate: Validate,
114    ) -> Result<Self, SerializationError> {
115        let powers_of_g = BTreeMap::deserialize_with_mode(&mut reader, compress, Validate::No)?;
116        let gamma_g = E::G1Affine::deserialize_with_mode(&mut reader, compress, Validate::No)?;
117        let powers_of_gamma_g = Vec::deserialize_with_mode(&mut reader, compress, Validate::No)?;
118        let h = E::G2Affine::deserialize_with_mode(&mut reader, compress, Validate::No)?;
119        let beta_h =
120            Vec::<E::G2Affine>::deserialize_with_mode(&mut reader, compress, Validate::No)?;
121        let num_vars = usize::deserialize_with_mode(&mut reader, compress, Validate::No)?;
122        let max_degree = usize::deserialize_with_mode(&mut reader, compress, Validate::No)?;
123
124        let prepared_beta_h = beta_h.iter().map(|x| x.clone().into()).collect();
125        let result = Self {
126            powers_of_g,
127            gamma_g,
128            powers_of_gamma_g,
129            h,
130            beta_h,
131            prepared_h: h.into(),
132            prepared_beta_h,
133            num_vars,
134            max_degree,
135        };
136        if let Validate::Yes = validate {
137            result.check()?;
138        }
139        Ok(result)
140    }
141}
142
143impl<E, P> PCUniversalParams for UniversalParams<E, P>
144where
145    E: Pairing,
146    P: DenseMVPolynomial<E::ScalarField>,
147    P::Point: Index<usize, Output = E::ScalarField>,
148{
149    fn max_degree(&self) -> usize {
150        self.max_degree
151    }
152}
153
154/// `CommitterKey` is used to commit to and create evaluation proofs for a given
155/// polynomial.
156#[derive(Derivative, CanonicalSerialize, CanonicalDeserialize)]
157#[derivative(Hash(bound = ""), Clone(bound = ""), Debug(bound = ""))]
158pub struct CommitterKey<E, P>
159where
160    E: Pairing,
161    P: DenseMVPolynomial<E::ScalarField>,
162    P::Point: Index<usize, Output = E::ScalarField>,
163{
164    /// Contains group elements corresponding to all possible monomials with
165    /// `num_vars` and maximum degree `supported_degree` evaluated at `\beta`
166    pub powers_of_g: BTreeMap<P::Term, E::G1Affine>,
167    /// `\gamma` times the generater of G1
168    pub gamma_g: E::G1Affine,
169    /// Group elements of the form `{ \beta_i^j \gamma G }`, where `i` ranges
170    /// from 0 to `num_vars-1` and `j` ranges from `1` to `supported_degree+1`.
171    pub powers_of_gamma_g: Vec<Vec<E::G1Affine>>,
172    /// The number of variables `self` is initialized for
173    pub num_vars: usize,
174    /// The maximum degree supported by the trimmed parameters that `self` is
175    /// a part of
176    pub supported_degree: usize,
177    /// The maximum degree supported by the `UniversalParams` `self` was derived
178    /// from.
179    pub max_degree: usize,
180}
181
182impl<E, P> PCCommitterKey for CommitterKey<E, P>
183where
184    E: Pairing,
185    P: DenseMVPolynomial<E::ScalarField>,
186    P::Point: Index<usize, Output = E::ScalarField>,
187{
188    fn max_degree(&self) -> usize {
189        self.max_degree
190    }
191
192    fn supported_degree(&self) -> usize {
193        self.supported_degree
194    }
195}
196
197/// `VerifierKey` is used to check evaluation proofs for a given commitment.
198#[derive(Derivative)]
199#[derivative(Default(bound = ""), Clone(bound = ""), Debug(bound = ""))]
200pub struct VerifierKey<E: Pairing> {
201    /// The generator of G1.
202    pub g: E::G1Affine,
203    /// The generator of G1 that is used for making a commitment hiding.
204    pub gamma_g: E::G1Affine,
205    /// The generator of G2.
206    pub h: E::G2Affine,
207    /// `\beta_i` times the above generator of G2 where `i` ranges from 0 to `num_vars-1`
208    pub beta_h: Vec<E::G2Affine>,
209    /// The generator of G2, prepared for use in pairings.
210    #[derivative(Debug = "ignore")]
211    pub prepared_h: E::G2Prepared,
212    /// `\beta_i` times the above generator of G2 where `i` ranges from 0 to `num_vars-1`,
213    /// prepared for use in pairings
214    #[derivative(Debug = "ignore")]
215    pub prepared_beta_h: Vec<E::G2Prepared>,
216    /// The number of variables `self` is initialized for
217    pub num_vars: usize,
218    /// The maximum degree supported by the trimmed parameters that `self` is
219    /// a part of.
220    pub supported_degree: usize,
221    /// The maximum degree supported by the `UniversalParams` `self` was derived
222    /// from.
223    pub max_degree: usize,
224}
225impl<E: Pairing> Valid for VerifierKey<E> {
226    fn check(&self) -> Result<(), SerializationError> {
227        self.g.check()?;
228        self.gamma_g.check()?;
229        self.h.check()?;
230        self.beta_h.check()?;
231
232        if self.num_vars == 0 {
233            return Err(SerializationError::InvalidData);
234        }
235        if self.supported_degree == 0 {
236            return Err(SerializationError::InvalidData);
237        }
238        if self.max_degree == 0 || self.max_degree < self.supported_degree {
239            return Err(SerializationError::InvalidData);
240        }
241
242        Ok(())
243    }
244}
245impl<E: Pairing> CanonicalSerialize for VerifierKey<E> {
246    fn serialize_with_mode<W: Write>(
247        &self,
248        mut writer: W,
249        compress: Compress,
250    ) -> Result<(), SerializationError> {
251        self.g.serialize_with_mode(&mut writer, compress)?;
252        self.gamma_g.serialize_with_mode(&mut writer, compress)?;
253        self.h.serialize_with_mode(&mut writer, compress)?;
254        self.beta_h.serialize_with_mode(&mut writer, compress)?;
255        self.num_vars.serialize_with_mode(&mut writer, compress)?;
256        self.supported_degree
257            .serialize_with_mode(&mut writer, compress)?;
258        self.max_degree.serialize_with_mode(&mut writer, compress)
259    }
260
261    fn serialized_size(&self, compress: Compress) -> usize {
262        self.g.serialized_size(compress)
263            + self.gamma_g.serialized_size(compress)
264            + self.h.serialized_size(compress)
265            + self.beta_h.serialized_size(compress)
266            + self.num_vars.serialized_size(compress)
267            + self.supported_degree.serialized_size(compress)
268            + self.max_degree.serialized_size(compress)
269    }
270}
271
272impl<E: Pairing> CanonicalDeserialize for VerifierKey<E> {
273    fn deserialize_with_mode<R: Read>(
274        mut reader: R,
275        compress: Compress,
276        validate: Validate,
277    ) -> Result<Self, SerializationError> {
278        let g = E::G1Affine::deserialize_with_mode(&mut reader, compress, Validate::No)?;
279        let gamma_g = E::G1Affine::deserialize_with_mode(&mut reader, compress, Validate::No)?;
280        let h = E::G2Affine::deserialize_with_mode(&mut reader, compress, Validate::No)?;
281        let beta_h =
282            Vec::<E::G2Affine>::deserialize_with_mode(&mut reader, compress, Validate::No)?;
283        let num_vars = usize::deserialize_with_mode(&mut reader, compress, Validate::No)?;
284        let supported_degree = usize::deserialize_with_mode(&mut reader, compress, Validate::No)?;
285        let max_degree = usize::deserialize_with_mode(&mut reader, compress, Validate::No)?;
286
287        let prepared_beta_h = beta_h.iter().map(|x| x.clone().into()).collect();
288        let result = Self {
289            g,
290            gamma_g,
291            h,
292            beta_h,
293            prepared_h: h.into(),
294            prepared_beta_h,
295            num_vars,
296            supported_degree,
297            max_degree,
298        };
299        if let Validate::Yes = validate {
300            result.check()?;
301        }
302        Ok(result)
303    }
304}
305
306impl<E: Pairing> PCVerifierKey for VerifierKey<E> {
307    fn max_degree(&self) -> usize {
308        self.max_degree
309    }
310
311    fn supported_degree(&self) -> usize {
312        self.supported_degree
313    }
314}
315
316/// Nothing to do to prepare this verifier key (for now).
317pub type PreparedVerifierKey<E> = VerifierKey<E>;
318
319impl<E: Pairing> PCPreparedVerifierKey<VerifierKey<E>> for PreparedVerifierKey<E> {
320    /// prepare `PreparedVerifierKey` from `VerifierKey`
321    fn prepare(vk: &VerifierKey<E>) -> Self {
322        vk.clone()
323    }
324}
325
326/// `Randomness` hides the polynomial inside a commitment`.
327#[derive(Derivative, CanonicalSerialize, CanonicalDeserialize)]
328#[derivative(
329    Hash(bound = ""),
330    Clone(bound = ""),
331    Debug(bound = ""),
332    PartialEq(bound = ""),
333    Eq(bound = "")
334)]
335pub struct Randomness<E, P>
336where
337    E: Pairing,
338    P: DenseMVPolynomial<E::ScalarField>,
339    P::Point: Index<usize, Output = E::ScalarField>,
340{
341    /// A multivariate polynomial where each monomial is univariate with random coefficient
342    pub blinding_polynomial: P,
343    _engine: PhantomData<E>,
344}
345
346impl<E, P> Randomness<E, P>
347where
348    E: Pairing,
349    P: DenseMVPolynomial<E::ScalarField>,
350    P::Point: Index<usize, Output = E::ScalarField>,
351{
352    /// Does `self` provide any hiding properties to the corresponding commitment?
353    /// `self.is_hiding() == true` only if the underlying polynomial is non-zero.
354    #[inline]
355    pub fn is_hiding(&self) -> bool {
356        !self.blinding_polynomial.is_zero()
357    }
358
359    /// What is the degree of the hiding polynomial for a given hiding bound?
360    #[inline]
361    pub fn calculate_hiding_polynomial_degree(hiding_bound: usize) -> usize {
362        hiding_bound + 1
363    }
364}
365
366impl<E, P> PCCommitmentState for Randomness<E, P>
367where
368    E: Pairing,
369    P: DenseMVPolynomial<E::ScalarField>,
370    P::Point: Index<usize, Output = E::ScalarField>,
371{
372    type Randomness = Self;
373    fn empty() -> Self {
374        Self {
375            blinding_polynomial: P::zero(),
376            _engine: PhantomData,
377        }
378    }
379
380    fn rand<R: RngCore>(
381        hiding_bound: usize,
382        _: bool,
383        num_vars: Option<usize>,
384        rng: &mut R,
385    ) -> Self {
386        let hiding_poly_degree = Self::calculate_hiding_polynomial_degree(hiding_bound);
387        Randomness {
388            blinding_polynomial: P::rand(hiding_poly_degree, num_vars.unwrap(), rng),
389            _engine: PhantomData,
390        }
391    }
392}
393
394impl<'a, E: Pairing, P: DenseMVPolynomial<E::ScalarField>> Add<&'a Randomness<E, P>>
395    for Randomness<E, P>
396where
397    E: Pairing,
398    P: DenseMVPolynomial<E::ScalarField>,
399    P::Point: Index<usize, Output = E::ScalarField>,
400{
401    type Output = Self;
402
403    #[inline]
404    fn add(mut self, other: &'a Self) -> Self {
405        self.blinding_polynomial += &other.blinding_polynomial;
406        self
407    }
408}
409
410impl<'a, E, P> Add<(E::ScalarField, &'a Randomness<E, P>)> for Randomness<E, P>
411where
412    E: Pairing,
413    P: DenseMVPolynomial<E::ScalarField>,
414    P::Point: Index<usize, Output = E::ScalarField>,
415{
416    type Output = Self;
417
418    #[inline]
419    fn add(mut self, other: (E::ScalarField, &'a Randomness<E, P>)) -> Self {
420        self += other;
421        self
422    }
423}
424
425impl<'a, E, P> AddAssign<&'a Randomness<E, P>> for Randomness<E, P>
426where
427    E: Pairing,
428    P: DenseMVPolynomial<E::ScalarField>,
429    P::Point: Index<usize, Output = E::ScalarField>,
430{
431    #[inline]
432    fn add_assign(&mut self, other: &'a Self) {
433        self.blinding_polynomial += &other.blinding_polynomial;
434    }
435}
436
437impl<'a, E, P> AddAssign<(E::ScalarField, &'a Randomness<E, P>)> for Randomness<E, P>
438where
439    E: Pairing,
440    P: DenseMVPolynomial<E::ScalarField>,
441    P::Point: Index<usize, Output = E::ScalarField>,
442{
443    #[inline]
444    fn add_assign(&mut self, (f, other): (E::ScalarField, &'a Randomness<E, P>)) {
445        self.blinding_polynomial += (f, &other.blinding_polynomial);
446    }
447}
448
449/// `Proof` is an evaluation proof that is output by `KZG10::open`.
450#[derive(Derivative, CanonicalSerialize, CanonicalDeserialize)]
451#[derivative(
452    Default(bound = ""),
453    Hash(bound = ""),
454    Clone(bound = ""),
455    Debug(bound = ""),
456    PartialEq(bound = ""),
457    Eq(bound = "")
458)]
459pub struct Proof<E: Pairing> {
460    /// Commitments to the witness polynomials
461    pub w: Vec<E::G1Affine>,
462    /// Evaluation of the random polynomial at the point for which
463    /// the evaluation proof was produced.
464    pub random_v: Option<E::ScalarField>,
465}