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