2020-09-29 00:23:41 -07:00
|
|
|
use super::super::{
|
2020-12-01 14:34:18 -08:00
|
|
|
commitment::{self, Blind, Params},
|
2020-12-21 14:59:41 -08:00
|
|
|
Coeff, Polynomial,
|
2020-09-29 00:23:41 -07:00
|
|
|
};
|
2020-12-01 14:34:18 -08:00
|
|
|
use super::{
|
2020-12-21 14:59:41 -08:00
|
|
|
construct_intermediate_sets, ChallengeX1, ChallengeX2, ChallengeX3, ChallengeX4, ProverQuery,
|
|
|
|
Query,
|
2020-12-01 14:34:18 -08:00
|
|
|
};
|
2020-09-29 00:23:41 -07:00
|
|
|
|
2022-09-09 10:43:43 -07:00
|
|
|
use crate::arithmetic::{eval_polynomial, kate_division, CurveAffine};
|
2021-04-30 18:28:50 -07:00
|
|
|
use crate::transcript::{EncodedChallenge, TranscriptWrite};
|
2020-11-12 16:08:08 -08:00
|
|
|
|
|
|
|
use ff::Field;
|
2021-02-22 11:02:53 -08:00
|
|
|
use group::Curve;
|
2022-01-20 08:16:48 -08:00
|
|
|
use rand_core::RngCore;
|
2020-12-23 15:20:27 -08:00
|
|
|
use std::io;
|
2020-10-07 09:13:06 -07:00
|
|
|
use std::marker::PhantomData;
|
2020-09-29 00:23:41 -07:00
|
|
|
|
2020-12-21 14:59:41 -08:00
|
|
|
/// Create a multi-opening proof
|
2021-12-25 05:36:41 -08:00
|
|
|
pub fn create_proof<
|
|
|
|
'a,
|
|
|
|
I,
|
|
|
|
C: CurveAffine,
|
|
|
|
E: EncodedChallenge<C>,
|
|
|
|
R: RngCore,
|
|
|
|
T: TranscriptWrite<C, E>,
|
|
|
|
>(
|
2020-12-21 14:59:41 -08:00
|
|
|
params: &Params<C>,
|
2021-12-25 05:36:41 -08:00
|
|
|
mut rng: R,
|
2020-12-21 14:59:41 -08:00
|
|
|
transcript: &mut T,
|
|
|
|
queries: I,
|
|
|
|
) -> io::Result<()>
|
|
|
|
where
|
|
|
|
I: IntoIterator<Item = ProverQuery<'a, C>> + Clone,
|
|
|
|
{
|
2021-05-01 04:36:09 -07:00
|
|
|
let x_1: ChallengeX1<_> = transcript.squeeze_challenge_scalar();
|
|
|
|
let x_2: ChallengeX2<_> = transcript.squeeze_challenge_scalar();
|
2020-12-21 14:59:41 -08:00
|
|
|
|
|
|
|
let (poly_map, point_sets) = construct_intermediate_sets(queries);
|
|
|
|
|
|
|
|
// Collapse openings at same point sets together into single openings using
|
|
|
|
// x_1 challenge.
|
|
|
|
let mut q_polys: Vec<Option<Polynomial<C::Scalar, Coeff>>> = vec![None; point_sets.len()];
|
2022-11-29 21:05:37 -08:00
|
|
|
let mut q_blinds = vec![Blind(C::Scalar::ZERO); point_sets.len()];
|
2020-12-21 14:59:41 -08:00
|
|
|
|
|
|
|
{
|
2021-01-13 16:22:32 -08:00
|
|
|
let mut accumulate =
|
|
|
|
|set_idx: usize, new_poly: &Polynomial<C::Scalar, Coeff>, blind: Blind<C::Scalar>| {
|
|
|
|
if let Some(poly) = &q_polys[set_idx] {
|
|
|
|
q_polys[set_idx] = Some(poly.clone() * *x_1 + new_poly);
|
|
|
|
} else {
|
|
|
|
q_polys[set_idx] = Some(new_poly.clone());
|
|
|
|
}
|
|
|
|
q_blinds[set_idx] *= *x_1;
|
|
|
|
q_blinds[set_idx] += blind;
|
|
|
|
};
|
2020-10-13 10:08:03 -07:00
|
|
|
|
2020-12-21 14:59:41 -08:00
|
|
|
for commitment_data in poly_map.into_iter() {
|
|
|
|
accumulate(
|
|
|
|
commitment_data.set_index, // set_idx,
|
|
|
|
commitment_data.commitment.poly, // poly,
|
|
|
|
commitment_data.commitment.blind, // blind,
|
|
|
|
);
|
2020-10-07 09:13:06 -07:00
|
|
|
}
|
2020-12-21 14:59:41 -08:00
|
|
|
}
|
2020-10-07 09:13:06 -07:00
|
|
|
|
2022-02-09 12:36:49 -08:00
|
|
|
let q_prime_poly = point_sets
|
2020-12-21 14:59:41 -08:00
|
|
|
.iter()
|
|
|
|
.zip(q_polys.iter())
|
2022-02-09 12:36:49 -08:00
|
|
|
.fold(None, |q_prime_poly, (points, poly)| {
|
2020-12-21 14:59:41 -08:00
|
|
|
let mut poly = points
|
2020-10-07 21:48:40 -07:00
|
|
|
.iter()
|
2021-01-13 16:22:32 -08:00
|
|
|
.fold(poly.clone().unwrap().values, |poly, point| {
|
|
|
|
kate_division(&poly, *point)
|
|
|
|
});
|
2022-11-29 21:05:37 -08:00
|
|
|
poly.resize(params.n as usize, C::Scalar::ZERO);
|
2020-12-21 14:59:41 -08:00
|
|
|
let poly = Polynomial {
|
|
|
|
values: poly,
|
|
|
|
_marker: PhantomData,
|
|
|
|
};
|
2020-09-29 00:23:41 -07:00
|
|
|
|
2022-02-09 12:36:49 -08:00
|
|
|
if q_prime_poly.is_none() {
|
2020-12-21 14:59:41 -08:00
|
|
|
Some(poly)
|
|
|
|
} else {
|
2022-02-09 12:36:49 -08:00
|
|
|
q_prime_poly.map(|q_prime_poly| q_prime_poly * *x_2 + &poly)
|
2020-09-29 00:23:41 -07:00
|
|
|
}
|
2020-12-21 14:59:41 -08:00
|
|
|
})
|
|
|
|
.unwrap();
|
2020-09-29 00:23:41 -07:00
|
|
|
|
2022-02-09 12:36:49 -08:00
|
|
|
let q_prime_blind = Blind(C::Scalar::random(&mut rng));
|
|
|
|
let q_prime_commitment = params.commit(&q_prime_poly, q_prime_blind).to_affine();
|
2020-09-29 00:23:41 -07:00
|
|
|
|
2022-02-09 12:36:49 -08:00
|
|
|
transcript.write_point(q_prime_commitment)?;
|
2020-09-29 00:23:41 -07:00
|
|
|
|
2021-05-01 04:36:09 -07:00
|
|
|
let x_3: ChallengeX3<_> = transcript.squeeze_challenge_scalar();
|
2020-09-29 00:23:41 -07:00
|
|
|
|
2022-02-09 12:36:49 -08:00
|
|
|
// Prover sends u_i for all i, which correspond to the evaluation
|
|
|
|
// of each Q polynomial commitment at x_3.
|
|
|
|
for q_i_poly in &q_polys {
|
|
|
|
transcript.write_scalar(eval_polynomial(q_i_poly.as_ref().unwrap(), *x_3))?;
|
2020-09-29 00:23:41 -07:00
|
|
|
}
|
2020-12-21 14:59:41 -08:00
|
|
|
|
2021-05-01 04:36:09 -07:00
|
|
|
let x_4: ChallengeX4<_> = transcript.squeeze_challenge_scalar();
|
2020-12-21 14:59:41 -08:00
|
|
|
|
2022-02-09 12:36:49 -08:00
|
|
|
let (p_poly, p_poly_blind) = q_polys.into_iter().zip(q_blinds.into_iter()).fold(
|
|
|
|
(q_prime_poly, q_prime_blind),
|
|
|
|
|(q_prime_poly, q_prime_blind), (poly, blind)| {
|
2020-12-21 14:59:41 -08:00
|
|
|
(
|
2022-02-09 12:36:49 -08:00
|
|
|
q_prime_poly * *x_4 + &poly.unwrap(),
|
|
|
|
Blind((q_prime_blind.0 * &(*x_4)) + &blind.0),
|
2020-12-21 14:59:41 -08:00
|
|
|
)
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
2022-02-09 12:36:49 -08:00
|
|
|
commitment::create_proof(params, rng, transcript, &p_poly, p_poly_blind, *x_3)
|
2020-09-29 00:23:41 -07:00
|
|
|
}
|
2020-10-07 06:59:55 -07:00
|
|
|
|
2020-10-15 16:01:30 -07:00
|
|
|
#[doc(hidden)]
|
|
|
|
#[derive(Copy, Clone)]
|
|
|
|
pub struct PolynomialPointer<'a, C: CurveAffine> {
|
|
|
|
poly: &'a Polynomial<C::Scalar, Coeff>,
|
|
|
|
blind: commitment::Blind<C::Scalar>,
|
|
|
|
}
|
2020-10-07 06:59:55 -07:00
|
|
|
|
2020-10-15 16:01:30 -07:00
|
|
|
impl<'a, C: CurveAffine> PartialEq for PolynomialPointer<'a, C> {
|
|
|
|
fn eq(&self, other: &Self) -> bool {
|
|
|
|
std::ptr::eq(self.poly, other.poly)
|
2020-10-07 06:59:55 -07:00
|
|
|
}
|
2020-10-15 16:01:30 -07:00
|
|
|
}
|
2020-10-07 06:59:55 -07:00
|
|
|
|
2020-10-15 16:01:30 -07:00
|
|
|
impl<'a, C: CurveAffine> Query<C::Scalar> for ProverQuery<'a, C> {
|
|
|
|
type Commitment = PolynomialPointer<'a, C>;
|
2021-01-13 16:22:32 -08:00
|
|
|
type Eval = ();
|
2020-10-07 06:59:55 -07:00
|
|
|
|
2020-10-15 16:01:30 -07:00
|
|
|
fn get_point(&self) -> C::Scalar {
|
|
|
|
self.point
|
2020-10-07 06:59:55 -07:00
|
|
|
}
|
2021-01-14 07:53:19 -08:00
|
|
|
fn get_eval(&self) {}
|
2020-10-15 16:01:30 -07:00
|
|
|
fn get_commitment(&self) -> Self::Commitment {
|
|
|
|
PolynomialPointer {
|
|
|
|
poly: self.poly,
|
|
|
|
blind: self.blind,
|
2020-10-07 06:59:55 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|