halo2_axiom/poly/
commitment.rs

1use super::{
2    query::{ProverQuery, VerifierQuery},
3    strategy::Guard,
4    Coeff, LagrangeCoeff, Polynomial,
5};
6use crate::poly::Error;
7use crate::transcript::{EncodedChallenge, TranscriptRead, TranscriptWrite};
8use ff::Field;
9use halo2curves::CurveAffine;
10use rand_core::RngCore;
11use std::{
12    fmt::Debug,
13    io::{self},
14    ops::{Add, AddAssign, Mul, MulAssign},
15};
16
17/// Defines components of a commitment scheme.
18pub trait CommitmentScheme {
19    /// Application field of this commitment scheme
20    type Scalar: Field;
21
22    /// Elliptic curve used to commit the application and witnesses
23    type Curve: CurveAffine<ScalarExt = Self::Scalar>;
24
25    /// Constant prover parameters
26    type ParamsProver: for<'params> ParamsProver<
27        'params,
28        Self::Curve,
29        ParamsVerifier = Self::ParamsVerifier,
30    >;
31
32    /// Constant verifier parameters
33    type ParamsVerifier: for<'params> ParamsVerifier<'params, Self::Curve>;
34
35    /// Wrapper for parameter generator
36    fn new_params(k: u32) -> Self::ParamsProver;
37
38    /// Wrapper for parameter reader
39    fn read_params<R: io::Read>(reader: &mut R) -> io::Result<Self::ParamsProver>;
40}
41
42/// Parameters for circuit sysnthesis and prover parameters.
43pub trait Params<'params, C: CurveAffine>: Sized + Clone {
44    /// Multi scalar multiplication engine
45    type MSM: MSM<C> + 'params;
46
47    /// Logaritmic size of the circuit
48    fn k(&self) -> u32;
49
50    /// Size of the circuit
51    fn n(&self) -> u64;
52
53    /// Downsize `Params` with smaller `k`.
54    fn downsize(&mut self, k: u32);
55
56    /// Generates an empty multiscalar multiplication struct using the
57    /// appropriate params.
58    fn empty_msm(&'params self) -> Self::MSM;
59
60    /// This commits to a polynomial using its evaluations over the $2^k$ size
61    /// evaluation domain. The commitment will be blinded by the blinding factor
62    /// `r`.
63    fn commit_lagrange(
64        &self,
65        poly: &Polynomial<C::ScalarExt, LagrangeCoeff>,
66        r: Blind<C::ScalarExt>,
67    ) -> C::CurveExt;
68
69    /// Writes params to a buffer.
70    fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()>;
71
72    /// Reads params from a buffer.
73    fn read<R: io::Read>(reader: &mut R) -> io::Result<Self>;
74}
75
76/// Parameters for circuit sysnthesis and prover parameters.
77pub trait ParamsProver<'params, C: CurveAffine>: Params<'params, C> {
78    /// Constant verifier parameters.
79    type ParamsVerifier: ParamsVerifier<'params, C>;
80
81    /// Returns new instance of parameters
82    fn new(k: u32) -> Self;
83
84    /// This computes a commitment to a polynomial described by the provided
85    /// slice of coefficients. The commitment may be blinded by the blinding
86    /// factor `r`.
87    fn commit(&self, poly: &Polynomial<C::ScalarExt, Coeff>, r: Blind<C::ScalarExt>)
88        -> C::CurveExt;
89
90    /// Getter for g generators
91    fn get_g(&self) -> &[C];
92
93    /// Returns verification parameters.
94    fn verifier_params(&'params self) -> &'params Self::ParamsVerifier;
95}
96
97/// Verifier specific functionality with circuit constaints
98pub trait ParamsVerifier<'params, C: CurveAffine>: Params<'params, C> {}
99
100/// Multi scalar multiplication engine
101pub trait MSM<C: CurveAffine>: Clone + Debug + Send + Sync {
102    /// Add arbitrary term (the scalar and the point)
103    fn append_term(&mut self, scalar: C::Scalar, point: C::Curve);
104
105    /// Add another multiexp into this one
106    fn add_msm(&mut self, other: &Self)
107    where
108        Self: Sized;
109
110    /// Scale all scalars in the MSM by some scaling factor
111    fn scale(&mut self, factor: C::Scalar);
112
113    /// Perform multiexp and check that it results in zero
114    fn check(&self) -> bool;
115
116    /// Perform multiexp and return the result
117    fn eval(&self) -> C::Curve;
118
119    /// Return base points
120    fn bases(&self) -> Vec<C::Curve>;
121
122    /// Scalars
123    fn scalars(&self) -> Vec<C::Scalar>;
124}
125
126/// Common multi-open prover interface for various commitment schemes
127pub trait Prover<'params, Scheme: CommitmentScheme> {
128    /// Query instance or not
129    const QUERY_INSTANCE: bool;
130
131    /// Creates new prover instance
132    fn new(params: &'params Scheme::ParamsProver) -> Self;
133
134    /// Create a multi-opening proof
135    fn create_proof<
136        'com,
137        E: EncodedChallenge<Scheme::Curve>,
138        T: TranscriptWrite<Scheme::Curve, E>,
139        R,
140        I,
141    >(
142        &self,
143        rng: R,
144        transcript: &mut T,
145        queries: I,
146    ) -> io::Result<()>
147    where
148        I: IntoIterator<Item = ProverQuery<'com, Scheme::Curve>> + Clone,
149        R: RngCore;
150}
151
152/// Common multi-open verifier interface for various commitment schemes
153pub trait Verifier<'params, Scheme: CommitmentScheme> {
154    /// Unfinalized verification result. This is returned in verification
155    /// to allow developer to compress or combined verification results
156    type Guard: Guard<Scheme, MSMAccumulator = Self::MSMAccumulator>;
157
158    /// Accumulator fot comressed verification
159    type MSMAccumulator;
160
161    /// Query instance or not
162    const QUERY_INSTANCE: bool;
163
164    /// Creates new verifier instance
165    fn new(params: &'params Scheme::ParamsVerifier) -> Self;
166
167    /// Process the proof and returns unfinished result named `Guard`
168    fn verify_proof<
169        'com,
170        E: EncodedChallenge<Scheme::Curve>,
171        T: TranscriptRead<Scheme::Curve, E>,
172        I,
173    >(
174        &self,
175        transcript: &mut T,
176        queries: I,
177        msm: Self::MSMAccumulator,
178    ) -> Result<Self::Guard, Error>
179    where
180        'params: 'com,
181        I: IntoIterator<
182                Item = VerifierQuery<
183                    'com,
184                    Scheme::Curve,
185                    <Scheme::ParamsVerifier as Params<'params, Scheme::Curve>>::MSM,
186                >,
187            > + Clone;
188}
189
190/// Wrapper type around a blinding factor.
191#[derive(Copy, Clone, Eq, PartialEq, Debug)]
192pub struct Blind<F>(pub F);
193
194impl<F: Field> Default for Blind<F> {
195    fn default() -> Self {
196        Blind(F::ONE)
197    }
198}
199
200impl<F: Field> Blind<F> {
201    /// Given `rng` creates new blinding scalar
202    pub fn new<R: RngCore>(rng: &mut R) -> Self {
203        Blind(F::random(rng))
204    }
205}
206
207impl<F: Field> Add for Blind<F> {
208    type Output = Self;
209
210    fn add(self, rhs: Blind<F>) -> Self {
211        Blind(self.0 + rhs.0)
212    }
213}
214
215impl<F: Field> Mul for Blind<F> {
216    type Output = Self;
217
218    fn mul(self, rhs: Blind<F>) -> Self {
219        Blind(self.0 * rhs.0)
220    }
221}
222
223impl<F: Field> AddAssign for Blind<F> {
224    fn add_assign(&mut self, rhs: Blind<F>) {
225        self.0 += rhs.0;
226    }
227}
228
229impl<F: Field> MulAssign for Blind<F> {
230    fn mul_assign(&mut self, rhs: Blind<F>) {
231        self.0 *= rhs.0;
232    }
233}
234
235impl<F: Field> AddAssign<F> for Blind<F> {
236    fn add_assign(&mut self, rhs: F) {
237        self.0 += rhs;
238    }
239}
240
241impl<F: Field> MulAssign<F> for Blind<F> {
242    fn mul_assign(&mut self, rhs: F) {
243        self.0 *= rhs;
244    }
245}