ark_poly_commit/ipa_pc/
data_structures.rs

1use crate::*;
2use ark_ec::AffineRepr;
3use ark_ff::{UniformRand, Zero};
4use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
5
6/// `UniversalParams` are the universal parameters for the inner product arg scheme.
7#[derive(Derivative, CanonicalSerialize, CanonicalDeserialize)]
8#[derivative(Default(bound = ""), Clone(bound = ""), Debug(bound = ""))]
9pub struct UniversalParams<G: AffineRepr> {
10    /// The key used to commit to polynomials.
11    pub comm_key: Vec<G>,
12
13    /// Some group generator.
14    pub h: G,
15
16    /// Some group generator specifically used for hiding.
17    pub s: G,
18}
19
20impl<G: AffineRepr> PCUniversalParams for UniversalParams<G> {
21    fn max_degree(&self) -> usize {
22        self.comm_key.len() - 1
23    }
24}
25
26/// `CommitterKey` is used to commit to, and create evaluation proofs for, a given
27/// polynomial.
28#[derive(Derivative, CanonicalSerialize, CanonicalDeserialize)]
29#[derivative(
30    Default(bound = ""),
31    Hash(bound = ""),
32    Clone(bound = ""),
33    Debug(bound = "")
34)]
35pub struct CommitterKey<G: AffineRepr> {
36    /// The key used to commit to polynomials.
37    pub comm_key: Vec<G>,
38
39    /// A random group generator.
40    pub h: G,
41
42    /// A random group generator that is to be used to make
43    /// a commitment hiding.
44    pub s: G,
45
46    /// The maximum degree supported by the parameters
47    /// this key was derived from.
48    pub max_degree: usize,
49}
50
51impl<G: AffineRepr> PCCommitterKey for CommitterKey<G> {
52    fn max_degree(&self) -> usize {
53        self.max_degree
54    }
55    fn supported_degree(&self) -> usize {
56        self.comm_key.len() - 1
57    }
58}
59
60/// `VerifierKey` is used to check evaluation proofs for a given commitment.
61pub type VerifierKey<G> = CommitterKey<G>;
62
63impl<G: AffineRepr> PCVerifierKey for VerifierKey<G> {
64    fn max_degree(&self) -> usize {
65        self.max_degree
66    }
67
68    fn supported_degree(&self) -> usize {
69        self.comm_key.len() - 1
70    }
71}
72
73/// Nothing to do to prepare this verifier key (for now).
74pub type PreparedVerifierKey<G> = VerifierKey<G>;
75
76impl<G: AffineRepr> PCPreparedVerifierKey<VerifierKey<G>> for PreparedVerifierKey<G> {
77    /// prepare `PreparedVerifierKey` from `VerifierKey`
78    fn prepare(vk: &VerifierKey<G>) -> Self {
79        vk.clone()
80    }
81}
82
83/// Commitment to a polynomial that optionally enforces a degree bound.
84#[derive(Derivative, CanonicalSerialize, CanonicalDeserialize)]
85#[derivative(
86    Default(bound = ""),
87    Hash(bound = ""),
88    Clone(bound = ""),
89    Copy(bound = ""),
90    Debug(bound = ""),
91    PartialEq(bound = ""),
92    Eq(bound = "")
93)]
94pub struct Commitment<G: AffineRepr> {
95    /// A Pedersen commitment to the polynomial.
96    pub comm: G,
97
98    /// A Pedersen commitment to the shifted polynomial.
99    /// This is `none` if the committed polynomial does not
100    /// enforce a strict degree bound.
101    pub shifted_comm: Option<G>,
102}
103
104impl<G: AffineRepr> PCCommitment for Commitment<G> {
105    #[inline]
106    fn empty() -> Self {
107        Commitment {
108            comm: G::zero(),
109            shifted_comm: None,
110        }
111    }
112
113    fn has_degree_bound(&self) -> bool {
114        false
115    }
116}
117
118/// Nothing to do to prepare this commitment (for now).
119pub type PreparedCommitment<E> = Commitment<E>;
120
121impl<G: AffineRepr> PCPreparedCommitment<Commitment<G>> for PreparedCommitment<G> {
122    /// prepare `PreparedCommitment` from `Commitment`
123    fn prepare(vk: &Commitment<G>) -> Self {
124        vk.clone()
125    }
126}
127
128/// `Randomness` hides the polynomial inside a commitment and is outputted by `InnerProductArg::commit`.
129#[derive(Derivative, CanonicalSerialize, CanonicalDeserialize)]
130#[derivative(
131    Default(bound = ""),
132    Hash(bound = ""),
133    Clone(bound = ""),
134    Debug(bound = ""),
135    PartialEq(bound = ""),
136    Eq(bound = "")
137)]
138pub struct Randomness<G: AffineRepr> {
139    /// Randomness is some scalar field element.
140    pub rand: G::ScalarField,
141
142    /// Randomness applied to the shifted commitment is some scalar field element.
143    pub shifted_rand: Option<G::ScalarField>,
144}
145
146impl<G: AffineRepr> PCCommitmentState for Randomness<G> {
147    type Randomness = Self;
148    fn empty() -> Self {
149        Self {
150            rand: G::ScalarField::zero(),
151            shifted_rand: None,
152        }
153    }
154
155    fn rand<R: RngCore>(_: usize, has_degree_bound: bool, _: Option<usize>, rng: &mut R) -> Self {
156        let rand = G::ScalarField::rand(rng);
157        let shifted_rand = if has_degree_bound {
158            Some(G::ScalarField::rand(rng))
159        } else {
160            None
161        };
162
163        Self { rand, shifted_rand }
164    }
165}
166
167/// `Proof` is an evaluation proof that is output by `InnerProductArg::open`.
168#[derive(Derivative, CanonicalSerialize, CanonicalDeserialize)]
169#[derivative(
170    Default(bound = ""),
171    Hash(bound = ""),
172    Clone(bound = ""),
173    Debug(bound = "")
174)]
175pub struct Proof<G: AffineRepr> {
176    /// Vector of left elements for each of the log_d iterations in `open`
177    pub l_vec: Vec<G>,
178
179    /// Vector of right elements for each of the log_d iterations within `open`
180    pub r_vec: Vec<G>,
181
182    /// Committer key from the last iteration within `open`
183    pub final_comm_key: G,
184
185    /// Coefficient from the last iteration within withinopen`
186    pub c: G::ScalarField,
187
188    /// Commitment to the blinding polynomial.
189    pub hiding_comm: Option<G>,
190
191    /// Linear combination of all the randomness used for commitments
192    /// to the opened polynomials, along with the randomness used for the
193    /// commitment to the hiding polynomial.
194    pub rand: Option<G::ScalarField>,
195}
196
197/// `SuccinctCheckPolynomial` is a succinctly-representated polynomial
198/// generated from the `log_d` random oracle challenges generated in `open`.
199/// It has the special property that can be evaluated in `O(log_d)` time.
200pub struct SuccinctCheckPolynomial<F: Field>(pub Vec<F>);
201
202impl<F: Field> SuccinctCheckPolynomial<F> {
203    /// Computes the coefficients of the underlying degree `d` polynomial.
204    pub fn compute_coeffs(&self) -> Vec<F> {
205        let challenges = &self.0;
206        let log_d = challenges.len();
207
208        let mut coeffs = vec![F::one(); 1 << log_d];
209        for (i, challenge) in challenges.iter().enumerate() {
210            let i = i + 1;
211            let elem_degree = 1 << (log_d - i);
212            for start in (elem_degree..coeffs.len()).step_by(elem_degree * 2) {
213                for offset in 0..elem_degree {
214                    coeffs[start + offset] *= challenge;
215                }
216            }
217        }
218
219        coeffs
220    }
221
222    /// Evaluate `self` at `point` in time `O(log_d)`.
223    pub fn evaluate(&self, point: F) -> F {
224        let challenges = &self.0;
225        let log_d = challenges.len();
226
227        let mut product = F::one();
228        for (i, challenge) in challenges.iter().enumerate() {
229            let i = i + 1;
230            let elem_degree: u64 = (1 << (log_d - i)) as u64;
231            let elem = point.pow([elem_degree]);
232            product *= &(F::one() + &(elem * challenge));
233        }
234
235        product
236    }
237}