ark_poly_commit/kzg10/
data_structures.rs

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