poly_commitment/lib.rs
1mod combine;
2pub mod commitment;
3pub mod error;
4pub mod hash_map_cache;
5pub mod ipa;
6pub mod kzg;
7pub mod lagrange_basis;
8pub mod precomputed_srs;
9pub mod utils;
10
11// Exposing property based tests for the SRS trait
12pub mod pbt_srs;
13
14pub use commitment::PolyComm;
15
16use crate::{
17 commitment::{BatchEvaluationProof, BlindedCommitment, CommitmentCurve},
18 error::CommitmentError,
19 utils::DensePolynomialOrEvaluations,
20};
21use ark_ec::AffineRepr;
22use ark_ff::UniformRand;
23use ark_poly::{
24 univariate::DensePolynomial, EvaluationDomain, Evaluations, Radix2EvaluationDomain as D,
25};
26use mina_poseidon::FqSponge;
27use rand_core::{CryptoRng, RngCore};
28
29pub trait SRS<G: CommitmentCurve>: Clone + Sized + Sync + Send {
30 /// The maximum polynomial degree that can be committed to
31 fn max_poly_size(&self) -> usize;
32
33 /// Get the group element used for blinding commitments
34 fn blinding_commitment(&self) -> G;
35
36 /// Same as [SRS::mask] except that you can pass the blinders manually.
37 /// A [BlindedCommitment] object is returned instead of a PolyComm object to
38 /// keep the blinding factors and the commitment together. The blinded
39 /// commitment is saved in the commitment field of the output.
40 /// The output is wrapped into a [Result] to handle the case the blinders
41 /// are not the same length than the number of chunks commitments have.
42 fn mask_custom(
43 &self,
44 com: PolyComm<G>,
45 blinders: &PolyComm<G::ScalarField>,
46 ) -> Result<BlindedCommitment<G>, CommitmentError>;
47
48 /// Turns a non-hiding polynomial commitment into a hidding polynomial
49 /// commitment. Transforms each given `<a, G>` into `(<a, G> + wH, w)` with
50 /// a random `w` per commitment.
51 /// A [BlindedCommitment] object is returned instead of a PolyComm object to
52 /// keep the blinding factors and the commitment together. The blinded
53 /// commitment is saved in the commitment field of the output.
54 fn mask(
55 &self,
56 comm: PolyComm<G>,
57 rng: &mut (impl RngCore + CryptoRng),
58 ) -> BlindedCommitment<G> {
59 let blinders = comm.map(|_| G::ScalarField::rand(rng));
60 self.mask_custom(comm, &blinders).unwrap()
61 }
62
63 /// This function commits a polynomial using the SRS' basis of size `n`.
64 /// - `plnm`: polynomial to commit to. The polynomial can be of any degree,
65 /// including higher than `n`.
66 /// - `num_chunks`: the minimal number of commitments to be included in the
67 /// output polynomial commitment.
68 ///
69 /// The function returns the commitments to the chunks (of size at most `n`) of
70 /// the polynomials.
71 ///
72 /// The function will also pad with zeroes if the polynomial has a degree
73 /// smaller than `n * num_chunks`.
74 ///
75 /// Note that if the polynomial has a degree higher than `n * num_chunks`,
76 /// the output will contain more than `num_chunks` commitments as it will
77 /// also contain the additional chunks.
78 ///
79 /// See the test
80 /// [crate::pbt_srs::test_regression_commit_non_hiding_expected_number_of_chunks]
81 /// for an example of the number of chunks returned.
82 fn commit_non_hiding(
83 &self,
84 plnm: &DensePolynomial<G::ScalarField>,
85 num_chunks: usize,
86 ) -> PolyComm<G>;
87
88 /// Commits a polynomial, potentially splitting the result in multiple
89 /// commitments.
90 /// It is analogous to [SRS::commit_evaluations] but for polynomials.
91 /// A [BlindedCommitment] object is returned instead of a PolyComm object to
92 /// keep the blinding factors and the commitment together. The blinded
93 /// commitment is saved in the commitment field of the output.
94 fn commit(
95 &self,
96 plnm: &DensePolynomial<G::ScalarField>,
97 num_chunks: usize,
98 rng: &mut (impl RngCore + CryptoRng),
99 ) -> BlindedCommitment<G>;
100
101 /// Commit to a polynomial, with custom blinding factors.
102 /// It is a combination of [SRS::commit] and [SRS::mask_custom].
103 /// It is analogous to [SRS::commit_evaluations_custom] but for polynomials.
104 /// A [BlindedCommitment] object is returned instead of a PolyComm object to
105 /// keep the blinding factors and the commitment together. The blinded
106 /// commitment is saved in the commitment field of the output.
107 /// The output is wrapped into a [Result] to handle the case the blinders
108 /// are not the same length than the number of chunks commitments have.
109 fn commit_custom(
110 &self,
111 plnm: &DensePolynomial<G::ScalarField>,
112 num_chunks: usize,
113 blinders: &PolyComm<G::ScalarField>,
114 ) -> Result<BlindedCommitment<G>, CommitmentError>;
115
116 /// Commit to evaluations, without blinding factors.
117 /// It is analogous to [SRS::commit_non_hiding] but for evaluations.
118 fn commit_evaluations_non_hiding(
119 &self,
120 domain: D<G::ScalarField>,
121 plnm: &Evaluations<G::ScalarField, D<G::ScalarField>>,
122 ) -> PolyComm<G>;
123
124 /// Commit to evaluations with blinding factors, generated using the random
125 /// number generator `rng`.
126 /// It is analogous to [SRS::commit] but for evaluations.
127 /// A [BlindedCommitment] object is returned instead of a PolyComm object to
128 /// keep the blinding factors and the commitment together. The blinded
129 /// commitment is saved in the commitment field of the output.
130 fn commit_evaluations(
131 &self,
132 domain: D<G::ScalarField>,
133 plnm: &Evaluations<G::ScalarField, D<G::ScalarField>>,
134 rng: &mut (impl RngCore + CryptoRng),
135 ) -> BlindedCommitment<G>;
136
137 /// Commit to evaluations with custom blinding factors.
138 /// It is a combination of [SRS::commit_evaluations] and [SRS::mask_custom].
139 /// It is analogous to [SRS::commit_custom] but for evaluations.
140 /// A [BlindedCommitment] object is returned instead of a PolyComm object to
141 /// keep the blinding factors and the commitment together. The blinded
142 /// commitment is saved in the commitment field of the output.
143 /// The output is wrapped into a [Result] to handle the case the blinders
144 /// are not the same length than the number of chunks commitments have.
145 fn commit_evaluations_custom(
146 &self,
147 domain: D<G::ScalarField>,
148 plnm: &Evaluations<G::ScalarField, D<G::ScalarField>>,
149 blinders: &PolyComm<G::ScalarField>,
150 ) -> Result<BlindedCommitment<G>, CommitmentError>;
151
152 /// Create an SRS of size `depth`.
153 ///
154 /// Warning: in the case of a trusted setup, as it is required for a
155 /// polynomial commitment scheme like KZG, a toxic waste is generated using
156 /// `rand::thread_rng()`. This is not the behavior you would expect in a
157 /// production environment.
158 /// However, we do accept this behavior for the sake of simplicity in the
159 /// interface, and this method will only be supposed to be used in tests in
160 /// this case.
161 fn create(depth: usize) -> Self;
162
163 /// Compute commitments to the lagrange basis corresponding to the given domain and
164 /// cache them in the SRS
165 fn get_lagrange_basis(&self, domain: D<G::ScalarField>) -> &Vec<PolyComm<G>>;
166
167 /// Same as `get_lagrange_basis` but only using the domain size.
168 fn get_lagrange_basis_from_domain_size(&self, domain_size: usize) -> &Vec<PolyComm<G>>;
169
170 fn size(&self) -> usize;
171}
172
173#[allow(type_alias_bounds)]
174/// An alias to represent a polynomial (in either coefficient or
175/// evaluation form), with a set of *scalar field* elements that
176/// represent the exponent of its blinder.
177// TODO: add a string to name the polynomial
178type PolynomialsToCombine<'a, G: CommitmentCurve, D: EvaluationDomain<G::ScalarField>> = &'a [(
179 DensePolynomialOrEvaluations<'a, G::ScalarField, D>,
180 PolyComm<G::ScalarField>,
181)];
182
183pub trait OpenProof<G: CommitmentCurve>: Sized + Clone {
184 type SRS: SRS<G> + std::fmt::Debug;
185
186 /// Create an opening proof for a batch of polynomials. The parameters are
187 /// the following:
188 /// - `srs`: the structured reference string used to commit
189 /// to the polynomials
190 /// - `group_map`: the group map
191 /// - `plnms`: the list of polynomials to open, with possible blinders.
192 /// The type is simply an alias to handle the polynomials in evaluations or
193 /// coefficients forms.
194 /// - `elm`: the evaluation points
195 /// - `polyscale`: a challenge to bacth the polynomials.
196 /// - `evalscale`: a challenge to bacth the evaluation points
197 /// - `sponge`: Sponge used to coin and absorb values and simulate
198 /// non-interactivity using the Fiat-Shamir transformation.
199 /// - `rng`: a pseudo random number generator used for zero-knowledge
200 #[allow(clippy::too_many_arguments)]
201 fn open<EFqSponge, RNG, D: EvaluationDomain<<G as AffineRepr>::ScalarField>>(
202 srs: &Self::SRS,
203 group_map: &<G as CommitmentCurve>::Map,
204 plnms: PolynomialsToCombine<G, D>,
205 elm: &[<G as AffineRepr>::ScalarField],
206 polyscale: <G as AffineRepr>::ScalarField,
207 evalscale: <G as AffineRepr>::ScalarField,
208 sponge: EFqSponge,
209 rng: &mut RNG,
210 ) -> Self
211 where
212 EFqSponge:
213 Clone + FqSponge<<G as AffineRepr>::BaseField, G, <G as AffineRepr>::ScalarField>,
214 RNG: RngCore + CryptoRng;
215
216 /// Verify the opening proof
217 fn verify<EFqSponge, RNG>(
218 srs: &Self::SRS,
219 group_map: &G::Map,
220 batch: &mut [BatchEvaluationProof<G, EFqSponge, Self>],
221 rng: &mut RNG,
222 ) -> bool
223 where
224 EFqSponge: FqSponge<G::BaseField, G, G::ScalarField>,
225 RNG: RngCore + CryptoRng;
226}