ark_poly_commit/sonic_pc/
data_structures.rs

1use crate::{
2    kzg10, BTreeMap, PCCommitterKey, PCPreparedCommitment, PCPreparedVerifierKey, PCVerifierKey,
3};
4use ark_ec::{pairing::Pairing, AdditiveGroup};
5use ark_serialize::{
6    CanonicalDeserialize, CanonicalSerialize, Compress, SerializationError, Valid, Validate,
7};
8use ark_std::io::{Read, Write};
9#[cfg(not(feature = "std"))]
10use ark_std::vec::Vec;
11
12/// `UniversalParams` are the universal parameters for the KZG10 scheme.
13pub type UniversalParams<E> = kzg10::UniversalParams<E>;
14
15/// `Randomness` is the randomness for the KZG10 scheme.
16pub type Randomness<F, P> = kzg10::Randomness<F, P>;
17
18/// `Commitment` is the commitment for the KZG10 scheme.
19pub type Commitment<E> = kzg10::Commitment<E>;
20
21/// `PreparedCommitment` is the prepared commitment for the KZG10 scheme.
22pub type PreparedCommitment<E> = kzg10::PreparedCommitment<E>;
23
24impl<E: Pairing> PCPreparedCommitment<Commitment<E>> for PreparedCommitment<E> {
25    /// prepare `PreparedCommitment` from `Commitment`
26    fn prepare(comm: &Commitment<E>) -> Self {
27        let mut prepared_comm = Vec::<E::G1Affine>::new();
28        let mut cur = E::G1::from(comm.0.clone());
29        for _ in 0..128 {
30            prepared_comm.push(cur.clone().into());
31            cur.double_in_place();
32        }
33
34        Self { 0: prepared_comm }
35    }
36}
37
38/// `ComitterKey` is used to commit to, and create evaluation proofs for, a given
39/// polynomial.
40#[derive(Derivative, CanonicalSerialize, CanonicalDeserialize)]
41#[derivative(
42    Default(bound = ""),
43    Hash(bound = ""),
44    Clone(bound = ""),
45    Debug(bound = "")
46)]
47pub struct CommitterKey<E: Pairing> {
48    /// The key used to commit to polynomials.
49    pub powers_of_g: Vec<E::G1Affine>,
50
51    /// The key used to commit to hiding polynomials.
52    pub powers_of_gamma_g: Vec<E::G1Affine>,
53
54    /// The powers used to commit to shifted polynomials.
55    /// This is `None` if `self` does not support enforcing any degree bounds.
56    pub shifted_powers_of_g: Option<Vec<E::G1Affine>>,
57
58    /// The powers used to commit to shifted hiding polynomials.
59    /// This is `None` if `self` does not support enforcing any degree bounds.
60    pub shifted_powers_of_gamma_g: Option<BTreeMap<usize, Vec<E::G1Affine>>>,
61
62    /// The degree bounds that are supported by `self`.
63    /// Sorted in ascending order from smallest bound to largest bound.
64    /// This is `None` if `self` does not support enforcing any degree bounds.
65    pub enforced_degree_bounds: Option<Vec<usize>>,
66
67    /// The maximum degree supported by the `UniversalParams` from which `self` was derived
68    pub max_degree: usize,
69}
70
71impl<E: Pairing> CommitterKey<E> {
72    /// Obtain powers for the underlying KZG10 construction
73    pub fn powers(&self) -> kzg10::Powers<E> {
74        kzg10::Powers {
75            powers_of_g: self.powers_of_g.as_slice().into(),
76            powers_of_gamma_g: self.powers_of_gamma_g.as_slice().into(),
77        }
78    }
79
80    /// Obtain powers for committing to shifted polynomials.
81    pub fn shifted_powers(
82        &self,
83        degree_bound: impl Into<Option<usize>>,
84    ) -> Option<kzg10::Powers<E>> {
85        match (&self.shifted_powers_of_g, &self.shifted_powers_of_gamma_g) {
86            (Some(shifted_powers_of_g), Some(shifted_powers_of_gamma_g)) => {
87                let max_bound = self
88                    .enforced_degree_bounds
89                    .as_ref()
90                    .unwrap()
91                    .last()
92                    .unwrap();
93                let (bound, powers_range) = if let Some(degree_bound) = degree_bound.into() {
94                    assert!(self
95                        .enforced_degree_bounds
96                        .as_ref()
97                        .unwrap()
98                        .contains(&degree_bound));
99                    (degree_bound, (max_bound - degree_bound)..)
100                } else {
101                    (*max_bound, 0..)
102                };
103
104                let ck = kzg10::Powers {
105                    powers_of_g: shifted_powers_of_g[powers_range.clone()].into(),
106                    powers_of_gamma_g: shifted_powers_of_gamma_g[&bound].clone().into(),
107                };
108
109                Some(ck)
110            }
111
112            (_, _) => None,
113        }
114    }
115}
116
117impl<E: Pairing> PCCommitterKey for CommitterKey<E> {
118    fn max_degree(&self) -> usize {
119        self.max_degree
120    }
121
122    fn supported_degree(&self) -> usize {
123        self.powers_of_g.len() - 1
124    }
125}
126
127/// `VerifierKey` is used to check evaluation proofs for a given commitment.
128#[derive(Derivative)]
129#[derivative(Default(bound = ""), Clone(bound = ""), Debug(bound = ""))]
130pub struct VerifierKey<E: Pairing> {
131    /// The generator of G1.
132    pub g: E::G1Affine,
133
134    /// The generator of G1 that is used for making a commitment hiding.
135    pub gamma_g: E::G1Affine,
136
137    /// The generator of G2.
138    pub h: E::G2Affine,
139
140    /// \beta times the generator of G2.
141    pub beta_h: E::G2Affine,
142
143    /// The generator of G2, prepared for use in pairings.
144    pub prepared_h: E::G2Prepared,
145
146    /// The \beta times the generator of G2, prepared for use in pairings.
147    pub prepared_beta_h: E::G2Prepared,
148
149    /// Pairs a degree_bound with its corresponding G2 element, which has been prepared for use in pairings.
150    /// Each pair is in the form `(degree_bound, \beta^{degree_bound - max_degree} h),` where `h` is the generator of G2 above
151    pub degree_bounds_and_neg_powers_of_h: Option<Vec<(usize, E::G2Affine)>>,
152
153    /// The maximum degree supported by the trimmed parameters that `self` is
154    /// a part of.
155    pub supported_degree: usize,
156
157    /// The maximum degree supported by the `UniversalParams` `self` was derived
158    /// from.
159    pub max_degree: usize,
160}
161
162impl<E: Pairing> VerifierKey<E> {
163    /// Find the appropriate shift for the degree bound.
164    pub fn get_shift_power(&self, degree_bound: usize) -> Option<E::G2Prepared> {
165        self.degree_bounds_and_neg_powers_of_h
166            .as_ref()
167            .and_then(|v| {
168                v.binary_search_by(|(d, _)| d.cmp(&degree_bound))
169                    .ok()
170                    .map(|i| v[i].1.clone().into())
171            })
172    }
173}
174
175impl<E: Pairing> Valid for VerifierKey<E> {
176    fn check(&self) -> Result<(), SerializationError> {
177        self.g.check()?;
178        self.gamma_g.check()?;
179        self.h.check()?;
180        self.beta_h.check()?;
181        self.degree_bounds_and_neg_powers_of_h.check()?;
182        if self.supported_degree > self.max_degree {
183            return Err(SerializationError::InvalidData);
184        }
185        Ok(())
186    }
187}
188
189impl<E: Pairing> CanonicalSerialize for VerifierKey<E> {
190    fn serialize_with_mode<W: Write>(
191        &self,
192        mut writer: W,
193        compress: Compress,
194    ) -> Result<(), SerializationError> {
195        self.g.serialize_with_mode(&mut writer, compress)?;
196        self.gamma_g.serialize_with_mode(&mut writer, compress)?;
197        self.h.serialize_with_mode(&mut writer, compress)?;
198        self.beta_h.serialize_with_mode(&mut writer, compress)?;
199        self.degree_bounds_and_neg_powers_of_h
200            .serialize_with_mode(&mut writer, compress)?;
201        self.supported_degree
202            .serialize_with_mode(&mut writer, compress)?;
203        self.max_degree.serialize_with_mode(&mut writer, compress)
204    }
205
206    fn serialized_size(&self, compress: Compress) -> usize {
207        self.g.serialized_size(compress)
208            + self.gamma_g.serialized_size(compress)
209            + self.h.serialized_size(compress)
210            + self.beta_h.serialized_size(compress)
211            + self
212                .degree_bounds_and_neg_powers_of_h
213                .serialized_size(compress)
214            + self.supported_degree.serialized_size(compress)
215            + self.max_degree.serialized_size(compress)
216    }
217}
218
219impl<E: Pairing> CanonicalDeserialize for VerifierKey<E> {
220    fn deserialize_with_mode<R: Read>(
221        mut reader: R,
222        compress: Compress,
223        validate: Validate,
224    ) -> Result<Self, SerializationError> {
225        let g = E::G1Affine::deserialize_with_mode(&mut reader, compress, Validate::No)?;
226        let gamma_g = E::G1Affine::deserialize_with_mode(&mut reader, compress, Validate::No)?;
227        let h = E::G2Affine::deserialize_with_mode(&mut reader, compress, Validate::No)?;
228        let beta_h = E::G2Affine::deserialize_with_mode(&mut reader, compress, Validate::No)?;
229        let degree_bounds_and_neg_powers_of_h =
230            Option::<Vec<(usize, E::G2Affine)>>::deserialize_with_mode(
231                &mut reader,
232                compress,
233                Validate::No,
234            )?;
235        let supported_degree = usize::deserialize_with_mode(&mut reader, compress, Validate::No)?;
236        let max_degree = usize::deserialize_with_mode(&mut reader, compress, Validate::No)?;
237
238        let prepared_h = E::G2Prepared::from(h.clone());
239        let prepared_beta_h = E::G2Prepared::from(beta_h.clone());
240
241        let result = Self {
242            g,
243            gamma_g,
244            h,
245            beta_h,
246            prepared_h,
247            prepared_beta_h,
248            degree_bounds_and_neg_powers_of_h,
249            supported_degree,
250            max_degree,
251        };
252
253        if let Validate::Yes = validate {
254            result.check()?;
255        }
256
257        Ok(result)
258    }
259}
260
261impl<E: Pairing> PCVerifierKey for VerifierKey<E> {
262    fn max_degree(&self) -> usize {
263        self.max_degree
264    }
265
266    fn supported_degree(&self) -> usize {
267        self.supported_degree
268    }
269}
270
271/// Nothing to do to prepare this verifier key (for now).
272pub type PreparedVerifierKey<E> = VerifierKey<E>;
273
274impl<E: Pairing> PCPreparedVerifierKey<VerifierKey<E>> for PreparedVerifierKey<E> {
275    /// prepare `PreparedVerifierKey` from `VerifierKey`
276    fn prepare(vk: &VerifierKey<E>) -> Self {
277        vk.clone()
278    }
279}
280
281/// Evaluation proof at a query set.
282#[derive(Derivative)]
283#[derivative(
284    Default(bound = ""),
285    Hash(bound = ""),
286    Clone(bound = ""),
287    Debug(bound = ""),
288    PartialEq(bound = ""),
289    Eq(bound = "")
290)]
291pub struct BatchProof<E: Pairing>(pub(crate) Vec<kzg10::Proof<E>>);