mirror of
https://github.com/saymrwulf/pasta_curves-source.git
synced 2026-09-06 20:20:34 +00:00
Improve naming of offsets/indexes and mappings.
This commit is contained in:
parent
378c56b952
commit
35c4bd4dd9
4 changed files with 139 additions and 129 deletions
|
|
@ -5,6 +5,7 @@ use std::collections::HashMap;
|
||||||
use super::Error;
|
use super::Error;
|
||||||
use crate::arithmetic::Field;
|
use crate::arithmetic::Field;
|
||||||
|
|
||||||
|
use super::domain::Rotation;
|
||||||
/// This represents a wire which has a fixed (permanent) value
|
/// This represents a wire which has a fixed (permanent) value
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
pub struct FixedWire(pub usize);
|
pub struct FixedWire(pub usize);
|
||||||
|
|
@ -135,6 +136,11 @@ impl<F> Mul<F> for Polynomial<F> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents an index into a vector where each entry corresponds to a distinct
|
||||||
|
/// point that polynomials are queried at.
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub struct PointIndex(pub usize);
|
||||||
|
|
||||||
/// This is a description of the circuit environment, such as the gate, wire and
|
/// This is a description of the circuit environment, such as the gate, wire and
|
||||||
/// permutation arrangements.
|
/// permutation arrangements.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
@ -143,15 +149,17 @@ pub struct MetaCircuit<F> {
|
||||||
pub(crate) num_advice_wires: usize,
|
pub(crate) num_advice_wires: usize,
|
||||||
// permutations: Vec<Vec<Wire>>,
|
// permutations: Vec<Vec<Wire>>,
|
||||||
pub(crate) gates: Vec<Polynomial<F>>,
|
pub(crate) gates: Vec<Polynomial<F>>,
|
||||||
pub(crate) advice_queries: Vec<(AdviceWire, i32)>,
|
pub(crate) advice_queries: Vec<(AdviceWire, Rotation)>,
|
||||||
pub(crate) fixed_queries: Vec<(FixedWire, i32)>,
|
pub(crate) fixed_queries: Vec<(FixedWire, Rotation)>,
|
||||||
pub(crate) query_rows: HashMap<i32, usize>,
|
|
||||||
|
// Mapping from a witness vector rotation to the index in the point vector.
|
||||||
|
pub(crate) rotations: HashMap<Rotation, PointIndex>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Field> Default for MetaCircuit<F> {
|
impl<F: Field> Default for MetaCircuit<F> {
|
||||||
fn default() -> MetaCircuit<F> {
|
fn default() -> MetaCircuit<F> {
|
||||||
let mut query_rows = HashMap::new();
|
let mut rotations = HashMap::new();
|
||||||
query_rows.insert(0, 0);
|
rotations.insert(Rotation::default(), PointIndex(0));
|
||||||
|
|
||||||
MetaCircuit {
|
MetaCircuit {
|
||||||
num_fixed_wires: 0,
|
num_fixed_wires: 0,
|
||||||
|
|
@ -159,7 +167,7 @@ impl<F: Field> Default for MetaCircuit<F> {
|
||||||
gates: vec![],
|
gates: vec![],
|
||||||
fixed_queries: Vec::new(),
|
fixed_queries: Vec::new(),
|
||||||
advice_queries: Vec::new(),
|
advice_queries: Vec::new(),
|
||||||
query_rows,
|
rotations,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -167,9 +175,10 @@ impl<F: Field> Default for MetaCircuit<F> {
|
||||||
impl<F: Field> MetaCircuit<F> {
|
impl<F: Field> MetaCircuit<F> {
|
||||||
/// Query a fixed wire at a relative position
|
/// Query a fixed wire at a relative position
|
||||||
pub fn query_fixed(&mut self, wire: FixedWire, at: i32) -> Polynomial<F> {
|
pub fn query_fixed(&mut self, wire: FixedWire, at: i32) -> Polynomial<F> {
|
||||||
|
let at = Rotation(at);
|
||||||
{
|
{
|
||||||
let len = self.query_rows.len();
|
let len = self.rotations.len();
|
||||||
self.query_rows.entry(at).or_insert(len);
|
self.rotations.entry(at).or_insert(PointIndex(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check for existing query so we don't make redundant queries
|
// TODO: check for existing query so we don't make redundant queries
|
||||||
|
|
@ -181,9 +190,10 @@ impl<F: Field> MetaCircuit<F> {
|
||||||
|
|
||||||
/// Query an advice wire at a relative position
|
/// Query an advice wire at a relative position
|
||||||
pub fn query_advice(&mut self, wire: AdviceWire, at: i32) -> Polynomial<F> {
|
pub fn query_advice(&mut self, wire: AdviceWire, at: i32) -> Polynomial<F> {
|
||||||
|
let at = Rotation(at);
|
||||||
{
|
{
|
||||||
let len = self.query_rows.len();
|
let len = self.rotations.len();
|
||||||
self.query_rows.entry(at).or_insert(len);
|
self.rotations.entry(at).or_insert(PointIndex(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check for existing query so we don't make redundant queries
|
// TODO: check for existing query so we don't make redundant queries
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,16 @@
|
||||||
use crate::arithmetic::{best_fft, parallelize, Field, Group};
|
use crate::arithmetic::{best_fft, parallelize, Field, Group};
|
||||||
|
|
||||||
|
/// Describes a relative location in the evaluation domain; applying a rotation
|
||||||
|
/// by i will rotate the vector in the evaluation domain by i.
|
||||||
|
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
|
||||||
|
pub struct Rotation(pub i32);
|
||||||
|
|
||||||
|
impl Default for Rotation {
|
||||||
|
fn default() -> Rotation {
|
||||||
|
Rotation(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This structure contains precomputed constants and other details needed for
|
/// This structure contains precomputed constants and other details needed for
|
||||||
/// performing operations on an evaluation domain of size $2^k$ in the context
|
/// performing operations on an evaluation domain of size $2^k$ in the context
|
||||||
/// of PLONK.
|
/// of PLONK.
|
||||||
|
|
@ -119,22 +130,26 @@ impl<G: Group> EvaluationDomain<G> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This takes us from an n-length coefficient vector into the coset
|
/// This takes us from an n-length coefficient vector into the coset
|
||||||
/// evaluation domain.
|
/// evaluation domain, rotating by `rotation` if desired.
|
||||||
///
|
///
|
||||||
/// This function will panic if the provided vector is not the correct
|
/// This function will panic if the provided vector is not the correct
|
||||||
/// length.
|
/// length.
|
||||||
pub fn obtain_coset(&self, mut a: Vec<G>, index: i32) -> Vec<G> {
|
pub fn obtain_coset(&self, mut a: Vec<G>, rotation: Rotation) -> Vec<G> {
|
||||||
assert_eq!(a.len(), 1 << self.k);
|
assert_eq!(a.len(), 1 << self.k);
|
||||||
|
|
||||||
assert!(index != i32::MIN);
|
assert!(rotation.0 != i32::MIN);
|
||||||
if index == 0 {
|
if rotation.0 == 0 {
|
||||||
|
// In this special case, the powers of zeta repeat so we do not need
|
||||||
|
// to compute them.
|
||||||
Self::distribute_powers_zeta(&mut a, self.g_coset);
|
Self::distribute_powers_zeta(&mut a, self.g_coset);
|
||||||
} else {
|
} else {
|
||||||
let mut g = G::Scalar::ZETA;
|
let mut g = G::Scalar::ZETA;
|
||||||
if index > 0 {
|
if rotation.0 > 0 {
|
||||||
g *= &self.omega.pow_vartime(&[index as u64, 0, 0, 0]);
|
g *= &self.omega.pow_vartime(&[rotation.0 as u64, 0, 0, 0]);
|
||||||
} else {
|
} else {
|
||||||
g *= &self.omega_inv.pow_vartime(&[index.abs() as u64, 0, 0, 0]);
|
g *= &self
|
||||||
|
.omega_inv
|
||||||
|
.pow_vartime(&[rotation.0.abs() as u64, 0, 0, 0]);
|
||||||
}
|
}
|
||||||
Self::distribute_powers(&mut a, g);
|
Self::distribute_powers(&mut a, g);
|
||||||
}
|
}
|
||||||
|
|
@ -233,4 +248,16 @@ impl<G: Group> EvaluationDomain<G> {
|
||||||
pub fn get_omega_inv(&self) -> G::Scalar {
|
pub fn get_omega_inv(&self) -> G::Scalar {
|
||||||
self.omega_inv
|
self.omega_inv
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn rotate_omega(&self, constant: G::Scalar, rotation: Rotation) -> G::Scalar {
|
||||||
|
let mut point = constant;
|
||||||
|
if rotation.0 >= 0 {
|
||||||
|
point *= &self.get_omega().pow(&[rotation.0 as u64, 0, 0, 0]);
|
||||||
|
} else {
|
||||||
|
point *= &self
|
||||||
|
.get_omega_inv()
|
||||||
|
.pow(&[rotation.0.abs() as u64, 0, 0, 0]);
|
||||||
|
}
|
||||||
|
point
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use super::{
|
use super::{
|
||||||
circuit::{AdviceWire, Circuit, ConstraintSystem, FixedWire, MetaCircuit},
|
circuit::{AdviceWire, Circuit, ConstraintSystem, FixedWire, MetaCircuit},
|
||||||
|
domain::Rotation,
|
||||||
hash_point, Error, Proof, SRS,
|
hash_point, Error, Proof, SRS,
|
||||||
};
|
};
|
||||||
use crate::arithmetic::{
|
use crate::arithmetic::{
|
||||||
|
|
@ -181,31 +182,13 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
let advice_evals: Vec<_> = meta
|
let advice_evals: Vec<_> = meta
|
||||||
.advice_queries
|
.advice_queries
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&(wire, at)| {
|
.map(|&(wire, at)| eval_polynomial(&advice_polys[wire.0], domain.rotate_omega(x_3, at)))
|
||||||
let mut point = x_3;
|
|
||||||
if at >= 0 {
|
|
||||||
point *= &domain.get_omega().pow(&[at as u64, 0, 0, 0]);
|
|
||||||
} else {
|
|
||||||
point *= &domain.get_omega_inv().pow(&[at.abs() as u64, 0, 0, 0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
eval_polynomial(&advice_polys[wire.0], point)
|
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let fixed_evals: Vec<_> = meta
|
let fixed_evals: Vec<_> = meta
|
||||||
.fixed_queries
|
.fixed_queries
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&(wire, at)| {
|
.map(|&(wire, at)| eval_polynomial(&srs.fixed_polys[wire.0], domain.rotate_omega(x_3, at)))
|
||||||
let mut point = x_3;
|
|
||||||
if at >= 0 {
|
|
||||||
point *= &domain.get_omega().pow(&[at as u64, 0, 0, 0]);
|
|
||||||
} else {
|
|
||||||
point *= &domain.get_omega_inv().pow(&[at.abs() as u64, 0, 0, 0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
eval_polynomial(&srs.fixed_polys[wire.0], point)
|
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let h_evals: Vec<_> = h_pieces
|
let h_evals: Vec<_> = h_pieces
|
||||||
|
|
@ -240,49 +223,49 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
|
|
||||||
// Collapse openings at same points together into single openings using
|
// Collapse openings at same points together into single openings using
|
||||||
// x_4 challenge.
|
// x_4 challenge.
|
||||||
let mut q_polys: Vec<Option<Vec<_>>> = vec![None; meta.query_rows.len()];
|
let mut q_polys: Vec<Option<Vec<_>>> = vec![None; meta.rotations.len()];
|
||||||
let mut q_blinds = vec![C::Scalar::zero(); meta.query_rows.len()];
|
let mut q_blinds = vec![C::Scalar::zero(); meta.rotations.len()];
|
||||||
let mut q_evals: Vec<_> = vec![C::Scalar::zero(); meta.query_rows.len()];
|
let mut q_evals: Vec<_> = vec![C::Scalar::zero(); meta.rotations.len()];
|
||||||
{
|
{
|
||||||
for (i, &(wire, ref at)) in meta.advice_queries.iter().enumerate() {
|
for (query_index, &(wire, ref at)) in meta.advice_queries.iter().enumerate() {
|
||||||
let query_row = *meta.query_rows.get(at).unwrap();
|
let point_index = (*meta.rotations.get(at).unwrap()).0;
|
||||||
|
|
||||||
if q_polys[query_row].is_none() {
|
if q_polys[point_index].is_none() {
|
||||||
q_polys[query_row] = Some(advice_polys[wire.0].clone());
|
q_polys[point_index] = Some(advice_polys[wire.0].clone());
|
||||||
q_blinds[query_row] = advice_blinds[wire.0];
|
q_blinds[point_index] = advice_blinds[wire.0];
|
||||||
q_evals[query_row] = advice_evals[i];
|
q_evals[point_index] = advice_evals[query_index];
|
||||||
} else {
|
} else {
|
||||||
parallelize(q_polys[query_row].as_mut().unwrap(), |q, start| {
|
parallelize(q_polys[point_index].as_mut().unwrap(), |q, start| {
|
||||||
for (q, a) in q.iter_mut().zip(advice_polys[wire.0][start..].iter()) {
|
for (q, a) in q.iter_mut().zip(advice_polys[wire.0][start..].iter()) {
|
||||||
*q *= &x_4;
|
*q *= &x_4;
|
||||||
*q += a;
|
*q += a;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
q_blinds[query_row] *= &x_4;
|
q_blinds[point_index] *= &x_4;
|
||||||
q_blinds[query_row] += &advice_blinds[wire.0];
|
q_blinds[point_index] += &advice_blinds[wire.0];
|
||||||
q_evals[query_row] *= &x_4;
|
q_evals[point_index] *= &x_4;
|
||||||
q_evals[query_row] += &advice_evals[i];
|
q_evals[point_index] += &advice_evals[query_index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i, &(wire, ref at)) in meta.fixed_queries.iter().enumerate() {
|
for (query_index, &(wire, ref at)) in meta.fixed_queries.iter().enumerate() {
|
||||||
let query_row = *meta.query_rows.get(at).unwrap();
|
let point_index = (*meta.rotations.get(at).unwrap()).0;
|
||||||
|
|
||||||
if q_polys[query_row].is_none() {
|
if q_polys[point_index].is_none() {
|
||||||
q_polys[query_row] = Some(srs.fixed_polys[wire.0].clone());
|
q_polys[point_index] = Some(srs.fixed_polys[wire.0].clone());
|
||||||
q_blinds[query_row] = C::Scalar::one();
|
q_blinds[point_index] = C::Scalar::one();
|
||||||
q_evals[query_row] = fixed_evals[i];
|
q_evals[point_index] = fixed_evals[query_index];
|
||||||
} else {
|
} else {
|
||||||
parallelize(q_polys[query_row].as_mut().unwrap(), |q, start| {
|
parallelize(q_polys[point_index].as_mut().unwrap(), |q, start| {
|
||||||
for (q, a) in q.iter_mut().zip(srs.fixed_polys[wire.0][start..].iter()) {
|
for (q, a) in q.iter_mut().zip(srs.fixed_polys[wire.0][start..].iter()) {
|
||||||
*q *= &x_4;
|
*q *= &x_4;
|
||||||
*q += a;
|
*q += a;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
q_blinds[query_row] *= &x_4;
|
q_blinds[point_index] *= &x_4;
|
||||||
q_blinds[query_row] += &C::Scalar::one();
|
q_blinds[point_index] += &C::Scalar::one();
|
||||||
q_evals[query_row] *= &x_4;
|
q_evals[point_index] *= &x_4;
|
||||||
q_evals[query_row] += &fixed_evals[i];
|
q_evals[point_index] += &fixed_evals[query_index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -292,23 +275,23 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
.zip(h_evals.iter())
|
.zip(h_evals.iter())
|
||||||
{
|
{
|
||||||
// We query the h(X) polynomial at x_3
|
// We query the h(X) polynomial at x_3
|
||||||
let cur_row = *meta.query_rows.get(&0).unwrap();
|
let point_index = (*meta.rotations.get(&Rotation::default()).unwrap()).0;
|
||||||
|
|
||||||
if q_polys[cur_row].is_none() {
|
if q_polys[point_index].is_none() {
|
||||||
q_polys[cur_row] = Some(h_poly);
|
q_polys[point_index] = Some(h_poly);
|
||||||
q_blinds[cur_row] = *h_blind;
|
q_blinds[point_index] = *h_blind;
|
||||||
q_evals[cur_row] = *h_eval;
|
q_evals[point_index] = *h_eval;
|
||||||
} else {
|
} else {
|
||||||
parallelize(q_polys[cur_row].as_mut().unwrap(), |q, start| {
|
parallelize(q_polys[point_index].as_mut().unwrap(), |q, start| {
|
||||||
for (q, a) in q.iter_mut().zip(h_poly[start..].iter()) {
|
for (q, a) in q.iter_mut().zip(h_poly[start..].iter()) {
|
||||||
*q *= &x_4;
|
*q *= &x_4;
|
||||||
*q += a;
|
*q += a;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
q_blinds[cur_row] *= &x_4;
|
q_blinds[point_index] *= &x_4;
|
||||||
q_blinds[cur_row] += h_blind;
|
q_blinds[point_index] += h_blind;
|
||||||
q_evals[cur_row] *= &x_4;
|
q_evals[point_index] *= &x_4;
|
||||||
q_evals[cur_row] += h_eval;
|
q_evals[point_index] += h_eval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -316,17 +299,10 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
let x_5: C::Scalar = get_challenge_scalar(Challenge(transcript.squeeze().get_lower_128()));
|
let x_5: C::Scalar = get_challenge_scalar(Challenge(transcript.squeeze().get_lower_128()));
|
||||||
|
|
||||||
let mut f_poly = None;
|
let mut f_poly = None;
|
||||||
for (&row, &col) in meta.query_rows.iter() {
|
for (&row, &point_index) in meta.rotations.iter() {
|
||||||
let mut poly = q_polys[col].as_ref().unwrap().clone();
|
let mut poly = q_polys[point_index.0].as_ref().unwrap().clone();
|
||||||
let mut point = x_3;
|
let point = domain.rotate_omega(x_3, row);
|
||||||
if row >= 0 {
|
poly[0] -= &q_evals[point_index.0];
|
||||||
point *= &domain.get_omega().pow_vartime(&[row as u64, 0, 0, 0]);
|
|
||||||
} else {
|
|
||||||
point *= &domain
|
|
||||||
.get_omega_inv()
|
|
||||||
.pow_vartime(&[row.abs() as u64, 0, 0, 0]);
|
|
||||||
}
|
|
||||||
poly[0] -= &q_evals[col];
|
|
||||||
let mut poly = kate_division(&poly, point);
|
let mut poly = kate_division(&poly, point);
|
||||||
poly.push(C::Scalar::zero());
|
poly.push(C::Scalar::zero());
|
||||||
|
|
||||||
|
|
@ -352,8 +328,11 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
|
|
||||||
let mut q_evals = vec![];
|
let mut q_evals = vec![];
|
||||||
|
|
||||||
for (_, &col) in meta.query_rows.iter() {
|
for (_, &point_index) in meta.rotations.iter() {
|
||||||
q_evals.push(eval_polynomial(&q_polys[col].as_ref().unwrap(), x_6));
|
q_evals.push(eval_polynomial(
|
||||||
|
&q_polys[point_index.0].as_ref().unwrap(),
|
||||||
|
x_6,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
for eval in q_evals.iter() {
|
for eval in q_evals.iter() {
|
||||||
|
|
@ -366,14 +345,14 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
|
|
||||||
let x_7: C::Scalar = get_challenge_scalar(Challenge(transcript.squeeze().get_lower_128()));
|
let x_7: C::Scalar = get_challenge_scalar(Challenge(transcript.squeeze().get_lower_128()));
|
||||||
|
|
||||||
for (_, &col) in meta.query_rows.iter() {
|
for (_, &point_index) in meta.rotations.iter() {
|
||||||
f_blind *= &x_7;
|
f_blind *= &x_7;
|
||||||
f_blind += &q_blinds[col];
|
f_blind += &q_blinds[point_index.0];
|
||||||
|
|
||||||
parallelize(&mut f_poly, |f, start| {
|
parallelize(&mut f_poly, |f, start| {
|
||||||
for (f, a) in f
|
for (f, a) in f
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.zip(q_polys[col].as_ref().unwrap()[start..].iter())
|
.zip(q_polys[point_index.0].as_ref().unwrap()[start..].iter())
|
||||||
{
|
{
|
||||||
*f *= &x_7;
|
*f *= &x_7;
|
||||||
*f += a;
|
*f += a;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{hash_point, Proof, SRS};
|
use super::{domain::Rotation, hash_point, Proof, SRS};
|
||||||
use crate::arithmetic::{get_challenge_scalar, Challenge, Curve, CurveAffine, Field};
|
use crate::arithmetic::{get_challenge_scalar, Challenge, Curve, CurveAffine, Field};
|
||||||
use crate::polycommit::Params;
|
use crate::polycommit::Params;
|
||||||
use crate::transcript::Hasher;
|
use crate::transcript::Hasher;
|
||||||
|
|
@ -89,56 +89,57 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
|
|
||||||
// Compress the commitments and expected evaluations at x_3 together
|
// Compress the commitments and expected evaluations at x_3 together
|
||||||
// using the challenge x_4
|
// using the challenge x_4
|
||||||
let mut q_commitments: Vec<_> = vec![None; srs.meta.query_rows.len()];
|
let mut q_commitments: Vec<_> = vec![None; srs.meta.rotations.len()];
|
||||||
let mut q_evals: Vec<_> = vec![C::Scalar::zero(); srs.meta.query_rows.len()];
|
let mut q_evals: Vec<_> = vec![C::Scalar::zero(); srs.meta.rotations.len()];
|
||||||
{
|
{
|
||||||
for (i, &(wire, ref at)) in srs.meta.advice_queries.iter().enumerate() {
|
for (query_index, &(wire, ref at)) in srs.meta.advice_queries.iter().enumerate() {
|
||||||
let query_row = *srs.meta.query_rows.get(at).unwrap();
|
let point_index = (*srs.meta.rotations.get(at).unwrap()).0;
|
||||||
|
|
||||||
if q_commitments[query_row].is_none() {
|
if q_commitments[point_index].is_none() {
|
||||||
q_commitments[query_row] =
|
q_commitments[point_index] =
|
||||||
Some(self.advice_commitments[wire.0].to_projective());
|
Some(self.advice_commitments[wire.0].to_projective());
|
||||||
q_evals[query_row] = self.advice_evals[i];
|
q_evals[point_index] = self.advice_evals[query_index];
|
||||||
} else {
|
} else {
|
||||||
q_commitments[query_row].as_mut().map(|commitment| {
|
q_commitments[point_index].as_mut().map(|commitment| {
|
||||||
*commitment *= x_4;
|
*commitment *= x_4;
|
||||||
*commitment += self.advice_commitments[wire.0];
|
*commitment += self.advice_commitments[wire.0];
|
||||||
});
|
});
|
||||||
q_evals[query_row] *= &x_4;
|
q_evals[point_index] *= &x_4;
|
||||||
q_evals[query_row] += &self.advice_evals[i];
|
q_evals[point_index] += &self.advice_evals[query_index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i, &(wire, ref at)) in srs.meta.fixed_queries.iter().enumerate() {
|
for (query_index, &(wire, ref at)) in srs.meta.fixed_queries.iter().enumerate() {
|
||||||
let query_row = *srs.meta.query_rows.get(at).unwrap();
|
let point_index = (*srs.meta.rotations.get(at).unwrap()).0;
|
||||||
|
|
||||||
if q_commitments[query_row].is_none() {
|
if q_commitments[point_index].is_none() {
|
||||||
q_commitments[query_row] = Some(srs.fixed_commitments[wire.0].to_projective());
|
q_commitments[point_index] =
|
||||||
q_evals[query_row] = self.fixed_evals[i];
|
Some(srs.fixed_commitments[wire.0].to_projective());
|
||||||
|
q_evals[point_index] = self.fixed_evals[query_index];
|
||||||
} else {
|
} else {
|
||||||
q_commitments[query_row].as_mut().map(|commitment| {
|
q_commitments[point_index].as_mut().map(|commitment| {
|
||||||
*commitment *= x_4;
|
*commitment *= x_4;
|
||||||
*commitment += srs.fixed_commitments[wire.0];
|
*commitment += srs.fixed_commitments[wire.0];
|
||||||
});
|
});
|
||||||
q_evals[query_row] *= &x_4;
|
q_evals[point_index] *= &x_4;
|
||||||
q_evals[query_row] += &self.fixed_evals[i];
|
q_evals[point_index] += &self.fixed_evals[query_index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (h_commitment, h_eval) in self.h_commitments.iter().zip(self.h_evals.iter()) {
|
for (h_commitment, h_eval) in self.h_commitments.iter().zip(self.h_evals.iter()) {
|
||||||
// We query the h(X) polynomial at x_3
|
// We query the h(X) polynomial at x_3
|
||||||
let cur_row = *srs.meta.query_rows.get(&0).unwrap();
|
let point_index = (*srs.meta.rotations.get(&Rotation::default()).unwrap()).0;
|
||||||
|
|
||||||
if q_commitments[cur_row].is_none() {
|
if q_commitments[point_index].is_none() {
|
||||||
q_commitments[cur_row] = Some(h_commitment.to_projective());
|
q_commitments[point_index] = Some(h_commitment.to_projective());
|
||||||
q_evals[cur_row] = *h_eval;
|
q_evals[point_index] = *h_eval;
|
||||||
} else {
|
} else {
|
||||||
q_commitments[cur_row].as_mut().map(|commitment| {
|
q_commitments[point_index].as_mut().map(|commitment| {
|
||||||
*commitment *= x_4;
|
*commitment *= x_4;
|
||||||
*commitment += *h_commitment;
|
*commitment += *h_commitment;
|
||||||
});
|
});
|
||||||
q_evals[cur_row] *= &x_4;
|
q_evals[point_index] *= &x_4;
|
||||||
q_evals[cur_row] += h_eval;
|
q_evals[point_index] += h_eval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -166,18 +167,11 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
// We can compute the expected f_eval at x_6 using the q_evals provided
|
// We can compute the expected f_eval at x_6 using the q_evals provided
|
||||||
// by the prover and from x_5
|
// by the prover and from x_5
|
||||||
let mut f_eval = C::Scalar::zero();
|
let mut f_eval = C::Scalar::zero();
|
||||||
for (&row, &col) in srs.meta.query_rows.iter() {
|
for (&row, &point_index) in srs.meta.rotations.iter() {
|
||||||
let mut eval: C::Scalar = self.q_evals[col].clone();
|
let mut eval: C::Scalar = self.q_evals[point_index.0].clone();
|
||||||
let mut point = x_3;
|
|
||||||
if row >= 0 {
|
let point = srs.domain.rotate_omega(x_3, row);
|
||||||
point *= &srs.domain.get_omega().pow_vartime(&[row as u64, 0, 0, 0]);
|
eval = eval - &q_evals[point_index.0];
|
||||||
} else {
|
|
||||||
point *= &srs
|
|
||||||
.domain
|
|
||||||
.get_omega_inv()
|
|
||||||
.pow_vartime(&[row.abs() as u64, 0, 0, 0]);
|
|
||||||
}
|
|
||||||
eval = eval - &q_evals[col];
|
|
||||||
eval = eval * &(x_6 - &point).invert().unwrap();
|
eval = eval * &(x_6 - &point).invert().unwrap();
|
||||||
|
|
||||||
f_eval *= &x_5;
|
f_eval *= &x_5;
|
||||||
|
|
@ -190,11 +184,11 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
|
|
||||||
// Compute the final commitment that has to be opened
|
// Compute the final commitment that has to be opened
|
||||||
let mut f_commitment: C::Projective = self.f_commitment.to_projective();
|
let mut f_commitment: C::Projective = self.f_commitment.to_projective();
|
||||||
for (_, &col) in srs.meta.query_rows.iter() {
|
for (_, &point_index) in srs.meta.rotations.iter() {
|
||||||
f_commitment *= x_7;
|
f_commitment *= x_7;
|
||||||
f_commitment = f_commitment + &q_commitments[col].as_ref().unwrap();
|
f_commitment = f_commitment + &q_commitments[point_index.0].as_ref().unwrap();
|
||||||
f_eval *= &x_7;
|
f_eval *= &x_7;
|
||||||
f_eval += &self.q_evals[col];
|
f_eval += &self.q_evals[point_index.0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify the opening proof
|
// Verify the opening proof
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue