mirror of https://github.com/zcash/halo2.git
halo2_proofs: rename variables for consistency
This changes variable names in the multiopen and commitment opening implementations and the book's protocol description to keep names and indicies consistent with one another. Co-Authored-By: Jack Grigg <jack@electriccoin.co>
This commit is contained in:
parent
b45180273e
commit
a4d3c328b9
|
@ -369,7 +369,7 @@ $$
|
||||||
15. $\verifier$ responds with challenge $x_3$.
|
15. $\verifier$ responds with challenge $x_3$.
|
||||||
16. $\prover$ sends $\mathbf{u} \in \field^{n_q}$ such that $\mathbf{u}_i = q_i(x_3)$ for all $i \in [0, n_q)$.
|
16. $\prover$ sends $\mathbf{u} \in \field^{n_q}$ such that $\mathbf{u}_i = q_i(x_3)$ for all $i \in [0, n_q)$.
|
||||||
17. $\verifier$ responds with challenge $x_4$.
|
17. $\verifier$ responds with challenge $x_4$.
|
||||||
18. $\prover$ and $\verifier$ set $P = Q' + x_4 \sum\limits_{i=0}^{n_q - 1} [x_4^i] Q_i$ and $v = $
|
18. $\verifier$ set $P = Q' + x_4 \sum\limits_{i=0}^{n_q - 1} [x_4^i] Q_i$ and $v = $
|
||||||
$$
|
$$
|
||||||
\sum\limits_{i=0}^{n_q - 1}
|
\sum\limits_{i=0}^{n_q - 1}
|
||||||
\left(
|
\left(
|
||||||
|
@ -392,12 +392,12 @@ $$
|
||||||
19. $\prover$ sets $p(X) = q'(X) + [x_4] \sum\limits_{i=0}^{n_q - 1} x_4^i q_i(X)$.
|
19. $\prover$ sets $p(X) = q'(X) + [x_4] \sum\limits_{i=0}^{n_q - 1} x_4^i q_i(X)$.
|
||||||
20. $\prover$ samples a random polynomial $s(X)$ of degree $n - 1$ with a root at $x_3$ and sends a commitment $S = \innerprod{\mathbf{s}}{\mathbf{G}} + [\cdot] W$ where $\mathbf{s}$ defines the coefficients of $s(X)$.
|
20. $\prover$ samples a random polynomial $s(X)$ of degree $n - 1$ with a root at $x_3$ and sends a commitment $S = \innerprod{\mathbf{s}}{\mathbf{G}} + [\cdot] W$ where $\mathbf{s}$ defines the coefficients of $s(X)$.
|
||||||
21. $\verifier$ responds with challenges $\xi, z$.
|
21. $\verifier$ responds with challenges $\xi, z$.
|
||||||
22. $\prover$ and $\verifier$ set $P' = P - [v] \mathbf{G}_0 + [\xi] S$.
|
22. $\verifier$ sets $P' = P - [v] \mathbf{G}_0 + [\xi] S$.
|
||||||
23. $\prover$ sets $p'(X) = p(X) - v + \xi s(X)$.
|
23. $\prover$ sets $p'(X) = p(X) - p(x_3) + \xi s(X)$ (where $p(x_3)$ should correspond with the verifier's computed value $v$).
|
||||||
24. Initialize $\mathbf{p'}$ as the coefficients of $p'(X)$ and $\mathbf{G'} = \mathbf{G}$ and $\mathbf{b} = (x_3^0, x_3^1, ..., x_3^{n - 1})$. $\prover$ and $\verifier$ will interact in the following $k$ rounds, where in the $j$th round starting in round $j=0$ and ending in round $j=k-1$:
|
24. Initialize $\mathbf{p'}$ as the coefficients of $p'(X)$ and $\mathbf{G'} = \mathbf{G}$ and $\mathbf{b} = (x_3^0, x_3^1, ..., x_3^{n - 1})$. $\prover$ and $\verifier$ will interact in the following $k$ rounds, where in the $j$th round starting in round $j=0$ and ending in round $j=k-1$:
|
||||||
* $\prover$ sends $L_j = \innerprod{\mathbf{p'}_\hi}{\mathbf{G'}_\lo} + [z \innerprod{\mathbf{p'}_\hi}{\mathbf{b}_\lo}] U + [\cdot] W$ and $R_j = \innerprod{\mathbf{p'}_\lo}{\mathbf{G'}_\hi} + [z \innerprod{\mathbf{p'}_\lo}{\mathbf{b}_\hi}] U + [\cdot] W$.
|
* $\prover$ sends $L_j = \innerprod{\mathbf{p'}_\hi}{\mathbf{G'}_\lo} + [z \innerprod{\mathbf{p'}_\hi}{\mathbf{b}_\lo}] U + [\cdot] W$ and $R_j = \innerprod{\mathbf{p'}_\lo}{\mathbf{G'}_\hi} + [z \innerprod{\mathbf{p'}_\lo}{\mathbf{b}_\hi}] U + [\cdot] W$.
|
||||||
* $\verifier$ responds with challenge $u_j$.
|
* $\verifier$ responds with challenge $u_j$.
|
||||||
* $\prover$ and $\verifier$ set $\mathbf{G'} := \mathbf{G'}_\lo + u_j \mathbf{G'}_\hi$ and $\mathbf{b} = \mathbf{b}_\lo + u_j \mathbf{b}_\hi$.
|
* $\prover$ and $\verifier$ set $\mathbf{G'} := \mathbf{G'}_\lo + u_j \mathbf{G'}_\hi$ and $\mathbf{b} := \mathbf{b}_\lo + u_j \mathbf{b}_\hi$.
|
||||||
* $\prover$ sets $\mathbf{p'} := \mathbf{p'}_\lo + u_j^{-1} \mathbf{p'}_\hi$.
|
* $\prover$ sets $\mathbf{p'} := \mathbf{p'}_\lo + u_j^{-1} \mathbf{p'}_\hi$.
|
||||||
25. $\prover$ sends $c = \mathbf{p'}_0$ and synthetic blinding factor $f$.
|
25. $\prover$ sends $c = \mathbf{p'}_0$ and synthetic blinding factor $f$ computed from the elided blinding factors.
|
||||||
26. $\verifier$ accepts only if $\sum_{j=0}^{k - 1} [u_j^{-1}] L_j + P' + \sum_{j=0}^{k - 1} [u_j] R_j = [c] \mathbf{G'}_0 + [c \mathbf{b}_0 z] U + [f] W$.
|
26. $\verifier$ accepts only if $\sum_{j=0}^{k - 1} [u_j^{-1}] L_j + P' + \sum_{j=0}^{k - 1} [u_j] R_j = [c] \mathbf{G'}_0 + [c \mathbf{b}_0 z] U + [f] W$.
|
||||||
|
|
|
@ -30,7 +30,7 @@ pub struct Params<C: CurveAffine> {
|
||||||
pub(crate) n: u64,
|
pub(crate) n: u64,
|
||||||
pub(crate) g: Vec<C>,
|
pub(crate) g: Vec<C>,
|
||||||
pub(crate) g_lagrange: Vec<C>,
|
pub(crate) g_lagrange: Vec<C>,
|
||||||
pub(crate) h: C,
|
pub(crate) w: C,
|
||||||
pub(crate) u: C,
|
pub(crate) u: C,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ impl<C: CurveAffine> Params<C> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let hasher = C::CurveExt::hash_to_curve("Halo2-Parameters");
|
let hasher = C::CurveExt::hash_to_curve("Halo2-Parameters");
|
||||||
let h = hasher(&[1]).to_affine();
|
let w = hasher(&[1]).to_affine();
|
||||||
let u = hasher(&[2]).to_affine();
|
let u = hasher(&[2]).to_affine();
|
||||||
|
|
||||||
Params {
|
Params {
|
||||||
|
@ -110,7 +110,7 @@ impl<C: CurveAffine> Params<C> {
|
||||||
n,
|
n,
|
||||||
g,
|
g,
|
||||||
g_lagrange,
|
g_lagrange,
|
||||||
h,
|
w,
|
||||||
u,
|
u,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ impl<C: CurveAffine> Params<C> {
|
||||||
tmp_scalars.push(r.0);
|
tmp_scalars.push(r.0);
|
||||||
|
|
||||||
tmp_bases.extend(self.g.iter());
|
tmp_bases.extend(self.g.iter());
|
||||||
tmp_bases.push(self.h);
|
tmp_bases.push(self.w);
|
||||||
|
|
||||||
best_multiexp::<C>(&tmp_scalars, &tmp_bases)
|
best_multiexp::<C>(&tmp_scalars, &tmp_bases)
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,7 @@ impl<C: CurveAffine> Params<C> {
|
||||||
tmp_scalars.push(r.0);
|
tmp_scalars.push(r.0);
|
||||||
|
|
||||||
tmp_bases.extend(self.g_lagrange.iter());
|
tmp_bases.extend(self.g_lagrange.iter());
|
||||||
tmp_bases.push(self.h);
|
tmp_bases.push(self.w);
|
||||||
|
|
||||||
best_multiexp::<C>(&tmp_scalars, &tmp_bases)
|
best_multiexp::<C>(&tmp_scalars, &tmp_bases)
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ impl<C: CurveAffine> Params<C> {
|
||||||
for g_lagrange_element in &self.g_lagrange {
|
for g_lagrange_element in &self.g_lagrange {
|
||||||
writer.write_all(g_lagrange_element.to_bytes().as_ref())?;
|
writer.write_all(g_lagrange_element.to_bytes().as_ref())?;
|
||||||
}
|
}
|
||||||
writer.write_all(self.h.to_bytes().as_ref())?;
|
writer.write_all(self.w.to_bytes().as_ref())?;
|
||||||
writer.write_all(self.u.to_bytes().as_ref())?;
|
writer.write_all(self.u.to_bytes().as_ref())?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -188,7 +188,7 @@ impl<C: CurveAffine> Params<C> {
|
||||||
let g: Vec<_> = (0..n).map(|_| C::read(reader)).collect::<Result<_, _>>()?;
|
let g: Vec<_> = (0..n).map(|_| C::read(reader)).collect::<Result<_, _>>()?;
|
||||||
let g_lagrange: Vec<_> = (0..n).map(|_| C::read(reader)).collect::<Result<_, _>>()?;
|
let g_lagrange: Vec<_> = (0..n).map(|_| C::read(reader)).collect::<Result<_, _>>()?;
|
||||||
|
|
||||||
let h = C::read(reader)?;
|
let w = C::read(reader)?;
|
||||||
let u = C::read(reader)?;
|
let u = C::read(reader)?;
|
||||||
|
|
||||||
Ok(Params {
|
Ok(Params {
|
||||||
|
@ -196,7 +196,7 @@ impl<C: CurveAffine> Params<C> {
|
||||||
n,
|
n,
|
||||||
g,
|
g,
|
||||||
g_lagrange,
|
g_lagrange,
|
||||||
h,
|
w,
|
||||||
u,
|
u,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use group::Group;
|
||||||
pub struct MSM<'a, C: CurveAffine> {
|
pub struct MSM<'a, C: CurveAffine> {
|
||||||
pub(crate) params: &'a Params<C>,
|
pub(crate) params: &'a Params<C>,
|
||||||
g_scalars: Option<Vec<C::Scalar>>,
|
g_scalars: Option<Vec<C::Scalar>>,
|
||||||
h_scalar: Option<C::Scalar>,
|
w_scalar: Option<C::Scalar>,
|
||||||
u_scalar: Option<C::Scalar>,
|
u_scalar: Option<C::Scalar>,
|
||||||
other_scalars: Vec<C::Scalar>,
|
other_scalars: Vec<C::Scalar>,
|
||||||
other_bases: Vec<C>,
|
other_bases: Vec<C>,
|
||||||
|
@ -18,7 +18,7 @@ impl<'a, C: CurveAffine> MSM<'a, C> {
|
||||||
/// Create a new, empty MSM using the provided parameters.
|
/// Create a new, empty MSM using the provided parameters.
|
||||||
pub fn new(params: &'a Params<C>) -> Self {
|
pub fn new(params: &'a Params<C>) -> Self {
|
||||||
let g_scalars = None;
|
let g_scalars = None;
|
||||||
let h_scalar = None;
|
let w_scalar = None;
|
||||||
let u_scalar = None;
|
let u_scalar = None;
|
||||||
let other_scalars = vec![];
|
let other_scalars = vec![];
|
||||||
let other_bases = vec![];
|
let other_bases = vec![];
|
||||||
|
@ -26,7 +26,7 @@ impl<'a, C: CurveAffine> MSM<'a, C> {
|
||||||
MSM {
|
MSM {
|
||||||
params,
|
params,
|
||||||
g_scalars,
|
g_scalars,
|
||||||
h_scalar,
|
w_scalar,
|
||||||
u_scalar,
|
u_scalar,
|
||||||
other_scalars,
|
other_scalars,
|
||||||
other_bases,
|
other_bases,
|
||||||
|
@ -42,8 +42,8 @@ impl<'a, C: CurveAffine> MSM<'a, C> {
|
||||||
self.add_to_g_scalars(g_scalars);
|
self.add_to_g_scalars(g_scalars);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(h_scalar) = &other.h_scalar {
|
if let Some(w_scalar) = &other.w_scalar {
|
||||||
self.add_to_h_scalar(*h_scalar);
|
self.add_to_w_scalar(*w_scalar);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(u_scalar) = &other.u_scalar {
|
if let Some(u_scalar) = &other.u_scalar {
|
||||||
|
@ -83,9 +83,9 @@ impl<'a, C: CurveAffine> MSM<'a, C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add to `h_scalar`
|
/// Add to `w_scalar`
|
||||||
pub fn add_to_h_scalar(&mut self, scalar: C::Scalar) {
|
pub fn add_to_w_scalar(&mut self, scalar: C::Scalar) {
|
||||||
self.h_scalar = self.h_scalar.map_or(Some(scalar), |a| Some(a + &scalar));
|
self.w_scalar = self.w_scalar.map_or(Some(scalar), |a| Some(a + &scalar));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add to `u_scalar`
|
/// Add to `u_scalar`
|
||||||
|
@ -111,14 +111,14 @@ impl<'a, C: CurveAffine> MSM<'a, C> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
self.h_scalar = self.h_scalar.map(|a| a * &factor);
|
self.w_scalar = self.w_scalar.map(|a| a * &factor);
|
||||||
self.u_scalar = self.u_scalar.map(|a| a * &factor);
|
self.u_scalar = self.u_scalar.map(|a| a * &factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform multiexp and check that it results in zero
|
/// Perform multiexp and check that it results in zero
|
||||||
pub fn eval(self) -> bool {
|
pub fn eval(self) -> bool {
|
||||||
let len = self.g_scalars.as_ref().map(|v| v.len()).unwrap_or(0)
|
let len = self.g_scalars.as_ref().map(|v| v.len()).unwrap_or(0)
|
||||||
+ self.h_scalar.map(|_| 1).unwrap_or(0)
|
+ self.w_scalar.map(|_| 1).unwrap_or(0)
|
||||||
+ self.u_scalar.map(|_| 1).unwrap_or(0)
|
+ self.u_scalar.map(|_| 1).unwrap_or(0)
|
||||||
+ self.other_scalars.len();
|
+ self.other_scalars.len();
|
||||||
let mut scalars: Vec<C::Scalar> = Vec::with_capacity(len);
|
let mut scalars: Vec<C::Scalar> = Vec::with_capacity(len);
|
||||||
|
@ -127,9 +127,9 @@ impl<'a, C: CurveAffine> MSM<'a, C> {
|
||||||
scalars.extend(&self.other_scalars);
|
scalars.extend(&self.other_scalars);
|
||||||
bases.extend(&self.other_bases);
|
bases.extend(&self.other_bases);
|
||||||
|
|
||||||
if let Some(h_scalar) = self.h_scalar {
|
if let Some(w_scalar) = self.w_scalar {
|
||||||
scalars.push(h_scalar);
|
scalars.push(w_scalar);
|
||||||
bases.push(self.params.h);
|
bases.push(self.params.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(u_scalar) = self.u_scalar {
|
if let Some(u_scalar) = self.u_scalar {
|
||||||
|
|
|
@ -33,23 +33,23 @@ pub fn create_proof<
|
||||||
params: &Params<C>,
|
params: &Params<C>,
|
||||||
mut rng: R,
|
mut rng: R,
|
||||||
transcript: &mut T,
|
transcript: &mut T,
|
||||||
px: &Polynomial<C::Scalar, Coeff>,
|
p_poly: &Polynomial<C::Scalar, Coeff>,
|
||||||
blind: Blind<C::Scalar>,
|
p_blind: Blind<C::Scalar>,
|
||||||
x: C::Scalar,
|
x: C::Scalar,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
// We're limited to polynomials of degree n - 1.
|
// We're limited to polynomials of degree n - 1.
|
||||||
assert!(px.len() <= params.n as usize);
|
assert_eq!(p_poly.len(), params.n as usize);
|
||||||
|
|
||||||
// Sample a random polynomial (of same degree) that has a root at x, first
|
// Sample a random polynomial (of same degree) that has a root at x, first
|
||||||
// by setting all coefficients to random values.
|
// by setting all coefficients to random values.
|
||||||
let mut s_poly = (*px).clone();
|
let mut s_poly = (*p_poly).clone();
|
||||||
for coeff in s_poly.iter_mut() {
|
for coeff in s_poly.iter_mut() {
|
||||||
*coeff = C::Scalar::random(&mut rng);
|
*coeff = C::Scalar::random(&mut rng);
|
||||||
}
|
}
|
||||||
// Evaluate the random polynomial at x
|
// Evaluate the random polynomial at x
|
||||||
let v_prime = eval_polynomial(&s_poly[..], x);
|
let s_at_x = eval_polynomial(&s_poly[..], x);
|
||||||
// Subtract constant coefficient to get a random polynomial with a root at x
|
// Subtract constant coefficient to get a random polynomial with a root at x
|
||||||
s_poly[0] = s_poly[0] - &v_prime;
|
s_poly[0] = s_poly[0] - &s_at_x;
|
||||||
// And sample a random blind
|
// And sample a random blind
|
||||||
let s_poly_blind = Blind(C::Scalar::random(&mut rng));
|
let s_poly_blind = Blind(C::Scalar::random(&mut rng));
|
||||||
|
|
||||||
|
@ -60,27 +60,29 @@ pub fn create_proof<
|
||||||
// Challenge that will ensure that the prover cannot change P but can only
|
// Challenge that will ensure that the prover cannot change P but can only
|
||||||
// witness a random polynomial commitment that agrees with P at x, with high
|
// witness a random polynomial commitment that agrees with P at x, with high
|
||||||
// probability.
|
// probability.
|
||||||
let iota = *transcript.squeeze_challenge_scalar::<()>();
|
let xi = *transcript.squeeze_challenge_scalar::<()>();
|
||||||
|
|
||||||
// Challenge that ensures that the prover did not interfere with the U term
|
// Challenge that ensures that the prover did not interfere with the U term
|
||||||
// in their commitments.
|
// in their commitments.
|
||||||
let z = *transcript.squeeze_challenge_scalar::<()>();
|
let z = *transcript.squeeze_challenge_scalar::<()>();
|
||||||
|
|
||||||
// We'll be opening `s_poly_commitment * iota + P - [v] G_0` to ensure it
|
// We'll be opening `P' = P - [v] G_0 + [\xi] S` to ensure it has a root at
|
||||||
// has a root at zero.
|
// zero.
|
||||||
let mut final_poly = s_poly * iota + px;
|
let mut p_prime_poly = s_poly * xi + p_poly;
|
||||||
let v = eval_polynomial(&final_poly, x);
|
let v = eval_polynomial(&p_prime_poly, x);
|
||||||
final_poly[0] = final_poly[0] - &v;
|
p_prime_poly[0] = p_prime_poly[0] - &v;
|
||||||
let blind = s_poly_blind * Blind(iota) + blind;
|
let p_prime_blind = s_poly_blind * Blind(xi) + p_blind;
|
||||||
let mut blind = blind.0;
|
|
||||||
|
|
||||||
// Initialize the vector `a` as the coefficients of the polynomial,
|
// This accumulates the synthetic blinding factor `f` starting
|
||||||
// rounding up to the parameters.
|
// with the blinding factor for `P'`.
|
||||||
let mut a = final_poly.values;
|
let mut f = p_prime_blind.0;
|
||||||
a.resize(params.n as usize, C::Scalar::zero());
|
|
||||||
|
// Initialize the vector `p_prime` as the coefficients of the polynomial.
|
||||||
|
let mut p_prime = p_prime_poly.values;
|
||||||
|
assert_eq!(p_prime.len(), params.n as usize);
|
||||||
|
|
||||||
// Initialize the vector `b` as the powers of `x`. The inner product of
|
// Initialize the vector `b` as the powers of `x`. The inner product of
|
||||||
// `a` and `b` is the evaluation of the polynomial at `x`.
|
// `p_prime` and `b` is the evaluation of the polynomial at `x`.
|
||||||
let mut b = Vec::with_capacity(1 << params.k);
|
let mut b = Vec::with_capacity(1 << params.k);
|
||||||
{
|
{
|
||||||
let mut cur = C::Scalar::one();
|
let mut cur = C::Scalar::one();
|
||||||
|
@ -90,60 +92,60 @@ pub fn create_proof<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the vector `G` from the URS. We'll be progressively collapsing
|
// Initialize the vector `G'` from the URS. We'll be progressively collapsing
|
||||||
// this vector into smaller and smaller vectors until it is of length 1.
|
// this vector into smaller and smaller vectors until it is of length 1.
|
||||||
let mut g = params.g.clone();
|
let mut g_prime = params.g.clone();
|
||||||
|
|
||||||
// Perform the inner product argument, round by round.
|
// Perform the inner product argument, round by round.
|
||||||
for k in (1..=params.k).rev() {
|
for j in 0..params.k {
|
||||||
let half = 1 << (k - 1); // half the length of `a`, `b`, `G`
|
let half = 1 << (params.k - j - 1); // half the length of `p_prime`, `b`, `G'`
|
||||||
|
|
||||||
// Compute L, R
|
// Compute L, R
|
||||||
//
|
//
|
||||||
// TODO: If we modify multiexp to take "extra" bases, we could speed
|
// TODO: If we modify multiexp to take "extra" bases, we could speed
|
||||||
// this piece up a bit by combining the multiexps.
|
// this piece up a bit by combining the multiexps.
|
||||||
let l = best_multiexp(&a[half..], &g[0..half]);
|
let l_j = best_multiexp(&p_prime[half..], &g_prime[0..half]);
|
||||||
let r = best_multiexp(&a[0..half], &g[half..]);
|
let r_j = best_multiexp(&p_prime[0..half], &g_prime[half..]);
|
||||||
let value_l = compute_inner_product(&a[half..], &b[0..half]);
|
let value_l_j = compute_inner_product(&p_prime[half..], &b[0..half]);
|
||||||
let value_r = compute_inner_product(&a[0..half], &b[half..]);
|
let value_r_j = compute_inner_product(&p_prime[0..half], &b[half..]);
|
||||||
let l_randomness = C::Scalar::random(&mut rng);
|
let l_j_randomness = C::Scalar::random(&mut rng);
|
||||||
let r_randomness = C::Scalar::random(&mut rng);
|
let r_j_randomness = C::Scalar::random(&mut rng);
|
||||||
let l = l + &best_multiexp(&[value_l * &z, l_randomness], &[params.u, params.h]);
|
let l_j = l_j + &best_multiexp(&[value_l_j * &z, l_j_randomness], &[params.u, params.w]);
|
||||||
let r = r + &best_multiexp(&[value_r * &z, r_randomness], &[params.u, params.h]);
|
let r_j = r_j + &best_multiexp(&[value_r_j * &z, r_j_randomness], &[params.u, params.w]);
|
||||||
let l = l.to_affine();
|
let l_j = l_j.to_affine();
|
||||||
let r = r.to_affine();
|
let r_j = r_j.to_affine();
|
||||||
|
|
||||||
// Feed L and R into the real transcript
|
// Feed L and R into the real transcript
|
||||||
transcript.write_point(l)?;
|
transcript.write_point(l_j)?;
|
||||||
transcript.write_point(r)?;
|
transcript.write_point(r_j)?;
|
||||||
|
|
||||||
let challenge = *transcript.squeeze_challenge_scalar::<()>();
|
let u_j = *transcript.squeeze_challenge_scalar::<()>();
|
||||||
let challenge_inv = challenge.invert().unwrap(); // TODO, bubble this up
|
let u_j_inv = u_j.invert().unwrap(); // TODO, bubble this up
|
||||||
|
|
||||||
// Collapse `a` and `b`.
|
// Collapse `p_prime` and `b`.
|
||||||
// TODO: parallelize
|
// TODO: parallelize
|
||||||
for i in 0..half {
|
for i in 0..half {
|
||||||
a[i] = a[i] + &(a[i + half] * &challenge_inv);
|
p_prime[i] = p_prime[i] + &(p_prime[i + half] * &u_j_inv);
|
||||||
b[i] = b[i] + &(b[i + half] * &challenge);
|
b[i] = b[i] + &(b[i + half] * &u_j);
|
||||||
}
|
}
|
||||||
a.truncate(half);
|
p_prime.truncate(half);
|
||||||
b.truncate(half);
|
b.truncate(half);
|
||||||
|
|
||||||
// Collapse `G`
|
// Collapse `G'`
|
||||||
parallel_generator_collapse(&mut g, challenge);
|
parallel_generator_collapse(&mut g_prime, u_j);
|
||||||
g.truncate(half);
|
g_prime.truncate(half);
|
||||||
|
|
||||||
// Update randomness (the synthetic blinding factor at the end)
|
// Update randomness (the synthetic blinding factor at the end)
|
||||||
blind += &(l_randomness * &challenge_inv);
|
f += &(l_j_randomness * &u_j_inv);
|
||||||
blind += &(r_randomness * &challenge);
|
f += &(r_j_randomness * &u_j);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have fully collapsed `a`, `b`, `G`
|
// We have fully collapsed `p_prime`, `b`, `G'`
|
||||||
assert_eq!(a.len(), 1);
|
assert_eq!(p_prime.len(), 1);
|
||||||
let a = a[0];
|
let c = p_prime[0];
|
||||||
|
|
||||||
transcript.write_scalar(a)?;
|
transcript.write_scalar(c)?;
|
||||||
transcript.write_scalar(blind)?; // \xi
|
transcript.write_scalar(f)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,9 @@ use crate::arithmetic::{best_multiexp, CurveAffine};
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Guard<'a, C: CurveAffine, E: EncodedChallenge<C>> {
|
pub struct Guard<'a, C: CurveAffine, E: EncodedChallenge<C>> {
|
||||||
msm: MSM<'a, C>,
|
msm: MSM<'a, C>,
|
||||||
neg_a: C::Scalar,
|
neg_c: C::Scalar,
|
||||||
challenges: Vec<C::Scalar>,
|
u: Vec<C::Scalar>,
|
||||||
challenges_packed: Vec<E>,
|
u_packed: Vec<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An accumulator instance consisting of an evaluation claim and a proof.
|
/// An accumulator instance consisting of an evaluation claim and a proof.
|
||||||
|
@ -24,18 +24,18 @@ pub struct Accumulator<C: CurveAffine, E: EncodedChallenge<C>> {
|
||||||
/// The claimed output of the linear-time polycommit opening protocol
|
/// The claimed output of the linear-time polycommit opening protocol
|
||||||
pub g: C,
|
pub g: C,
|
||||||
|
|
||||||
/// A vector of 128-bit challenges sampled by the verifier, to be used in
|
/// A vector of 128-bit challenges u_0, ..., u_{k - 1} sampled by the
|
||||||
/// computing g.
|
/// verifier, to be used in computing G'_0.
|
||||||
pub challenges_packed: Vec<E>,
|
pub u_packed: Vec<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, C: CurveAffine, E: EncodedChallenge<C>> Guard<'a, C, E> {
|
impl<'a, C: CurveAffine, E: EncodedChallenge<C>> Guard<'a, C, E> {
|
||||||
/// Lets caller supply the challenges and obtain an MSM with updated
|
/// Lets caller supply the challenges and obtain an MSM with updated
|
||||||
/// scalars and points.
|
/// scalars and points.
|
||||||
pub fn use_challenges(mut self) -> MSM<'a, C> {
|
pub fn use_challenges(mut self) -> MSM<'a, C> {
|
||||||
let s = compute_s(&self.challenges, self.neg_a);
|
let s = compute_s(&self.u, self.neg_c);
|
||||||
self.msm.add_to_g_scalars(&s);
|
self.msm.add_to_g_scalars(&s);
|
||||||
self.msm.add_to_h_scalar(self.neg_a);
|
self.msm.add_to_w_scalar(self.neg_c);
|
||||||
|
|
||||||
self.msm
|
self.msm
|
||||||
}
|
}
|
||||||
|
@ -43,22 +43,22 @@ impl<'a, C: CurveAffine, E: EncodedChallenge<C>> Guard<'a, C, E> {
|
||||||
/// Lets caller supply the purported G point and simply appends
|
/// Lets caller supply the purported G point and simply appends
|
||||||
/// [-a] G to return an updated MSM.
|
/// [-a] G to return an updated MSM.
|
||||||
pub fn use_g(mut self, g: C) -> (MSM<'a, C>, Accumulator<C, E>) {
|
pub fn use_g(mut self, g: C) -> (MSM<'a, C>, Accumulator<C, E>) {
|
||||||
self.msm.append_term(self.neg_a, g);
|
self.msm.append_term(self.neg_c, g);
|
||||||
|
|
||||||
let accumulator = Accumulator {
|
let accumulator = Accumulator {
|
||||||
g,
|
g,
|
||||||
challenges_packed: self.challenges_packed,
|
u_packed: self.u_packed,
|
||||||
};
|
};
|
||||||
|
|
||||||
(self.msm, accumulator)
|
(self.msm, accumulator)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes G + H, where G = ⟨s, params.g⟩ and H is used for blinding
|
/// Computes G + W, where G = ⟨s, params.g⟩ and W is used for blinding
|
||||||
pub fn compute_g(&self) -> C {
|
pub fn compute_g(&self) -> C {
|
||||||
let s = compute_s(&self.challenges, C::Scalar::one());
|
let s = compute_s(&self.u, C::Scalar::one());
|
||||||
|
|
||||||
let mut tmp = best_multiexp(&s, &self.msm.params.g);
|
let mut tmp = best_multiexp(&s, &self.msm.params.g);
|
||||||
tmp += self.msm.params.h;
|
tmp += self.msm.params.w;
|
||||||
tmp.to_affine()
|
tmp.to_affine()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,14 +75,11 @@ pub fn verify_proof<'a, C: CurveAffine, E: EncodedChallenge<C>, T: TranscriptRea
|
||||||
) -> Result<Guard<'a, C, E>, Error> {
|
) -> Result<Guard<'a, C, E>, Error> {
|
||||||
let k = params.k as usize;
|
let k = params.k as usize;
|
||||||
|
|
||||||
// P - [v] G_0 + S * iota
|
// P' = P - [v] G_0 + [\xi] S
|
||||||
// + \sum(L_i * u_i^2) + \sum(R_i * u_i^-2)
|
msm.add_constant_term(-v); // add [-v] G_0
|
||||||
msm.add_constant_term(-v);
|
|
||||||
let s_poly_commitment = transcript.read_point().map_err(|_| Error::OpeningError)?;
|
let s_poly_commitment = transcript.read_point().map_err(|_| Error::OpeningError)?;
|
||||||
|
let xi = *transcript.squeeze_challenge_scalar::<()>();
|
||||||
let iota = *transcript.squeeze_challenge_scalar::<()>();
|
msm.append_term(xi, s_poly_commitment);
|
||||||
|
|
||||||
msm.append_term(iota, s_poly_commitment);
|
|
||||||
|
|
||||||
let z = *transcript.squeeze_challenge_scalar::<()>();
|
let z = *transcript.squeeze_challenge_scalar::<()>();
|
||||||
|
|
||||||
|
@ -92,92 +89,89 @@ pub fn verify_proof<'a, C: CurveAffine, E: EncodedChallenge<C>, T: TranscriptRea
|
||||||
let l = transcript.read_point().map_err(|_| Error::OpeningError)?;
|
let l = transcript.read_point().map_err(|_| Error::OpeningError)?;
|
||||||
let r = transcript.read_point().map_err(|_| Error::OpeningError)?;
|
let r = transcript.read_point().map_err(|_| Error::OpeningError)?;
|
||||||
|
|
||||||
let challenge_packed = transcript.squeeze_challenge();
|
let u_j_packed = transcript.squeeze_challenge();
|
||||||
let challenge = *challenge_packed.as_challenge_scalar::<()>();
|
let u_j = *u_j_packed.as_challenge_scalar::<()>();
|
||||||
|
|
||||||
rounds.push((
|
rounds.push((
|
||||||
l,
|
l, r, u_j, u_j, // to be inverted
|
||||||
r,
|
u_j_packed,
|
||||||
challenge,
|
|
||||||
/* to be inverted */ challenge,
|
|
||||||
challenge_packed,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
rounds
|
rounds
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.map(|&mut (_, _, _, ref mut challenge, _)| challenge)
|
.map(|&mut (_, _, _, ref mut u_j, _)| u_j)
|
||||||
.batch_invert();
|
.batch_invert();
|
||||||
|
|
||||||
let mut challenges = Vec::with_capacity(k);
|
// This is the left hand side of the verifier equation.
|
||||||
let mut challenges_packed: Vec<E> = Vec::with_capacity(k);
|
// P' + \sum([u_j^{-1}] L_j) + \sum([u_j] R_j)
|
||||||
for (l, r, challenge, challenge_inv, challenge_packed) in rounds {
|
let mut u = Vec::with_capacity(k);
|
||||||
msm.append_term(challenge_inv, l);
|
let mut u_packed: Vec<E> = Vec::with_capacity(k);
|
||||||
msm.append_term(challenge, r);
|
for (l, r, u_j, u_j_inv, u_j_packed) in rounds {
|
||||||
|
msm.append_term(u_j_inv, l);
|
||||||
|
msm.append_term(u_j, r);
|
||||||
|
|
||||||
challenges.push(challenge);
|
u.push(u_j);
|
||||||
challenges_packed.push(challenge_packed);
|
u_packed.push(u_j_packed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Our goal is to open
|
// Our goal is to check that the left hand side of the verifier
|
||||||
// msm - [v] G_0 + random_poly_commitment * iota
|
// equation
|
||||||
// + \sum(L_i * u_i^2) + \sum(R_i * u_i^-2)
|
// P' + \sum([u_j^{-1}] L_j) + \sum([u_j] R_j)
|
||||||
// at x to 0, by asking the prover to supply (a, \xi) such that it equals
|
// equals (given the prover's values c, f) the right hand side
|
||||||
// = [a] (G + [b * z] U) + [\xi] H
|
// = [c] (G'_0 + [b * z] U) + [f] W
|
||||||
// except that we wish for the prover to supply G as Commit(g(X); 1) so
|
// except that we wish for the prover to supply G'_0 as Commit(g(X); 1) so
|
||||||
// we must substitute to get
|
// we must substitute G'_0 with G'_0 - W to get
|
||||||
// = [a] ((G - H) + [b * z] U) + [\xi] H
|
// = [c] ((G'_0 - W) + [b * z] U) + [f] W
|
||||||
// = [a] G + [-a] H + [abz] U + [\xi] H
|
// = [c] G'_0 + [-c] W + [cbz] U + [f] W
|
||||||
// = [a] G + [abz] U + [\xi - a] H
|
// = [c] G'_0 + [cbz] U + [f - c] W
|
||||||
// but subtracting to get the desired equality
|
// and then subtracting the right hand side from both sides
|
||||||
// ... + [-a] G + [-abz] U + [a - \xi] H = 0
|
// to get
|
||||||
|
// P' + \sum([u_j^{-1}] L_j) + \sum([u_j] R_j)
|
||||||
|
// + [-c] G'_0 + [-cbz] U + [c - f] W
|
||||||
|
// = 0
|
||||||
|
|
||||||
let a = transcript.read_scalar().map_err(|_| Error::SamplingError)?;
|
let c = transcript.read_scalar().map_err(|_| Error::SamplingError)?;
|
||||||
let neg_a = -a;
|
let neg_c = -c;
|
||||||
let xi = transcript.read_scalar().map_err(|_| Error::SamplingError)?;
|
let f = transcript.read_scalar().map_err(|_| Error::SamplingError)?;
|
||||||
let b = compute_b(x, &challenges);
|
let b = compute_b(x, &u);
|
||||||
|
|
||||||
msm.add_to_u_scalar(neg_a * &b * &z);
|
msm.add_to_u_scalar(neg_c * &b * &z);
|
||||||
msm.add_to_h_scalar(a - &xi);
|
msm.add_to_w_scalar(c - &f);
|
||||||
|
|
||||||
let guard = Guard {
|
let guard = Guard {
|
||||||
msm,
|
msm,
|
||||||
neg_a,
|
neg_c,
|
||||||
challenges,
|
u,
|
||||||
challenges_packed,
|
u_packed,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(guard)
|
Ok(guard)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes $\prod\limits_{i=0}^{k-1} (1 + u_i x^{2^i})$.
|
/// Computes $\prod\limits_{i=0}^{k-1} (1 + u_{k - 1 - i} x^{2^i})$.
|
||||||
fn compute_b<F: Field>(x: F, challenges: &[F]) -> F {
|
fn compute_b<F: Field>(x: F, u: &[F]) -> F {
|
||||||
let mut tmp = F::one();
|
let mut tmp = F::one();
|
||||||
let mut cur = x;
|
let mut cur = x;
|
||||||
for challenge in challenges.iter().rev() {
|
for u_j in u.iter().rev() {
|
||||||
tmp *= F::one() + &(*challenge * &cur);
|
tmp *= F::one() + &(*u_j * &cur);
|
||||||
cur *= cur;
|
cur *= cur;
|
||||||
}
|
}
|
||||||
tmp
|
tmp
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the coefficients of $g(X) = \prod\limits_{i=0}^{k-1} (1 + u_i X^{2^i})$.
|
/// Computes the coefficients of $g(X) = \prod\limits_{i=0}^{k-1} (1 + u_{k - 1 - i} X^{2^i})$.
|
||||||
fn compute_s<F: Field>(challenges: &[F], init: F) -> Vec<F> {
|
fn compute_s<F: Field>(u: &[F], init: F) -> Vec<F> {
|
||||||
assert!(!challenges.is_empty());
|
assert!(!u.is_empty());
|
||||||
let mut v = vec![F::zero(); 1 << challenges.len()];
|
let mut v = vec![F::zero(); 1 << u.len()];
|
||||||
v[0] = init;
|
v[0] = init;
|
||||||
|
|
||||||
for (len, challenge) in challenges
|
for (len, u_j) in u.iter().rev().enumerate().map(|(i, u_j)| (1 << i, u_j)) {
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(i, challenge)| (1 << i, challenge))
|
|
||||||
{
|
|
||||||
let (left, right) = v.split_at_mut(len);
|
let (left, right) = v.split_at_mut(len);
|
||||||
let right = &mut right[0..len];
|
let right = &mut right[0..len];
|
||||||
right.copy_from_slice(left);
|
right.copy_from_slice(left);
|
||||||
for v in right {
|
for v in right {
|
||||||
*v *= challenge;
|
*v *= u_j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,10 +64,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let f_poly = point_sets
|
let q_prime_poly = point_sets
|
||||||
.iter()
|
.iter()
|
||||||
.zip(q_polys.iter())
|
.zip(q_polys.iter())
|
||||||
.fold(None, |f_poly, (points, poly)| {
|
.fold(None, |q_prime_poly, (points, poly)| {
|
||||||
let mut poly = points
|
let mut poly = points
|
||||||
.iter()
|
.iter()
|
||||||
.fold(poly.clone().unwrap().values, |poly, point| {
|
.fold(poly.clone().unwrap().values, |poly, point| {
|
||||||
|
@ -79,43 +79,40 @@ where
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
};
|
};
|
||||||
|
|
||||||
if f_poly.is_none() {
|
if q_prime_poly.is_none() {
|
||||||
Some(poly)
|
Some(poly)
|
||||||
} else {
|
} else {
|
||||||
f_poly.map(|f_poly| f_poly * *x_2 + &poly)
|
q_prime_poly.map(|q_prime_poly| q_prime_poly * *x_2 + &poly)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let f_blind = Blind(C::Scalar::random(&mut rng));
|
let q_prime_blind = Blind(C::Scalar::random(&mut rng));
|
||||||
let f_commitment = params.commit(&f_poly, f_blind).to_affine();
|
let q_prime_commitment = params.commit(&q_prime_poly, q_prime_blind).to_affine();
|
||||||
|
|
||||||
transcript.write_point(f_commitment)?;
|
transcript.write_point(q_prime_commitment)?;
|
||||||
|
|
||||||
let x_3: ChallengeX3<_> = transcript.squeeze_challenge_scalar();
|
let x_3: ChallengeX3<_> = transcript.squeeze_challenge_scalar();
|
||||||
|
|
||||||
let q_evals: Vec<C::Scalar> = q_polys
|
// Prover sends u_i for all i, which correspond to the evaluation
|
||||||
.iter()
|
// of each Q polynomial commitment at x_3.
|
||||||
.map(|poly| eval_polynomial(poly.as_ref().unwrap(), *x_3))
|
for q_i_poly in &q_polys {
|
||||||
.collect();
|
transcript.write_scalar(eval_polynomial(q_i_poly.as_ref().unwrap(), *x_3))?;
|
||||||
|
|
||||||
for eval in q_evals.iter() {
|
|
||||||
transcript.write_scalar(*eval)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let x_4: ChallengeX4<_> = transcript.squeeze_challenge_scalar();
|
let x_4: ChallengeX4<_> = transcript.squeeze_challenge_scalar();
|
||||||
|
|
||||||
let (f_poly, f_blind_try) = q_polys.iter().zip(q_blinds.iter()).fold(
|
let (p_poly, p_poly_blind) = q_polys.into_iter().zip(q_blinds.into_iter()).fold(
|
||||||
(f_poly, f_blind),
|
(q_prime_poly, q_prime_blind),
|
||||||
|(f_poly, f_blind), (poly, blind)| {
|
|(q_prime_poly, q_prime_blind), (poly, blind)| {
|
||||||
(
|
(
|
||||||
f_poly * *x_4 + poly.as_ref().unwrap(),
|
q_prime_poly * *x_4 + &poly.unwrap(),
|
||||||
Blind((f_blind.0 * &(*x_4)) + &blind.0),
|
Blind((q_prime_blind.0 * &(*x_4)) + &blind.0),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
commitment::create_proof(params, rng, transcript, &f_poly, f_blind_try, *x_3)
|
commitment::create_proof(params, rng, transcript, &p_poly, p_poly_blind, *x_3)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
|
|
@ -77,23 +77,25 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtain the commitment to the multi-point quotient polynomial f(X).
|
// Obtain the commitment to the multi-point quotient polynomial f(X).
|
||||||
let f_commitment = transcript.read_point().map_err(|_| Error::SamplingError)?;
|
let q_prime_commitment = transcript.read_point().map_err(|_| Error::SamplingError)?;
|
||||||
|
|
||||||
// Sample a challenge x_3 for checking that f(X) was committed to
|
// Sample a challenge x_3 for checking that f(X) was committed to
|
||||||
// correctly.
|
// correctly.
|
||||||
let x_3: ChallengeX3<_> = transcript.squeeze_challenge_scalar();
|
let x_3: ChallengeX3<_> = transcript.squeeze_challenge_scalar();
|
||||||
|
|
||||||
let mut q_evals = Vec::with_capacity(q_eval_sets.len());
|
// u is a vector containing the evaluations of the Q polynomial
|
||||||
|
// commitments at x_3
|
||||||
|
let mut u = Vec::with_capacity(q_eval_sets.len());
|
||||||
for _ in 0..q_eval_sets.len() {
|
for _ in 0..q_eval_sets.len() {
|
||||||
q_evals.push(transcript.read_scalar().map_err(|_| Error::SamplingError)?);
|
u.push(transcript.read_scalar().map_err(|_| Error::SamplingError)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can compute the expected msm_eval at x_3 using the q_evals provided
|
// We can compute the expected msm_eval at x_3 using the u provided
|
||||||
// by the prover and from x_2
|
// by the prover and from x_2
|
||||||
let msm_eval = point_sets
|
let msm_eval = point_sets
|
||||||
.iter()
|
.iter()
|
||||||
.zip(q_eval_sets.iter())
|
.zip(q_eval_sets.iter())
|
||||||
.zip(q_evals.iter())
|
.zip(u.iter())
|
||||||
.fold(
|
.fold(
|
||||||
C::Scalar::zero(),
|
C::Scalar::zero(),
|
||||||
|msm_eval, ((points, evals), proof_eval)| {
|
|msm_eval, ((points, evals), proof_eval)| {
|
||||||
|
@ -111,8 +113,8 @@ where
|
||||||
let x_4: ChallengeX4<_> = transcript.squeeze_challenge_scalar();
|
let x_4: ChallengeX4<_> = transcript.squeeze_challenge_scalar();
|
||||||
|
|
||||||
// Compute the final commitment that has to be opened
|
// Compute the final commitment that has to be opened
|
||||||
msm.append_term(C::Scalar::one(), f_commitment);
|
msm.append_term(C::Scalar::one(), q_prime_commitment);
|
||||||
let (msm, msm_eval) = q_commitments.into_iter().zip(q_evals.iter()).fold(
|
let (msm, v) = q_commitments.into_iter().zip(u.iter()).fold(
|
||||||
(msm, msm_eval),
|
(msm, msm_eval),
|
||||||
|(mut msm, msm_eval), (q_commitment, q_eval)| {
|
|(mut msm, msm_eval), (q_commitment, q_eval)| {
|
||||||
msm.scale(*x_4);
|
msm.scale(*x_4);
|
||||||
|
@ -122,7 +124,7 @@ where
|
||||||
);
|
);
|
||||||
|
|
||||||
// Verify the opening proof
|
// Verify the opening proof
|
||||||
super::commitment::verify_proof(params, msm, transcript, *x_3, msm_eval)
|
super::commitment::verify_proof(params, msm, transcript, *x_3, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, C: CurveAffine> Query<C::Scalar> for VerifierQuery<'a, 'b, C> {
|
impl<'a, 'b, C: CurveAffine> Query<C::Scalar> for VerifierQuery<'a, 'b, C> {
|
||||||
|
|
Loading…
Reference in New Issue