mirror of https://github.com/zcash/halo2.git
Merge pull request #139 from zcash/remove-eval-from-multiopen-prover
Remove eval from ProverQuery in multiopen
This commit is contained in:
commit
6c6b30dde4
|
@ -55,11 +55,6 @@ pub(in crate::plonk) struct Constructed<C: CurveAffine> {
|
|||
|
||||
pub(in crate::plonk) struct Evaluated<C: CurveAffine> {
|
||||
constructed: Constructed<C>,
|
||||
product_eval: C::Scalar,
|
||||
product_inv_eval: C::Scalar,
|
||||
permuted_input_eval: C::Scalar,
|
||||
permuted_input_inv_eval: C::Scalar,
|
||||
permuted_table_eval: C::Scalar,
|
||||
}
|
||||
|
||||
impl Argument {
|
||||
|
@ -465,14 +460,7 @@ impl<C: CurveAffine> Constructed<C> {
|
|||
.map_err(|_| Error::TranscriptError)?;
|
||||
}
|
||||
|
||||
Ok(Evaluated {
|
||||
constructed: self,
|
||||
product_eval,
|
||||
product_inv_eval,
|
||||
permuted_input_eval,
|
||||
permuted_input_inv_eval,
|
||||
permuted_table_eval,
|
||||
})
|
||||
Ok(Evaluated { constructed: self })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -490,35 +478,30 @@ impl<C: CurveAffine> Evaluated<C> {
|
|||
point: *x,
|
||||
poly: &self.constructed.product_poly,
|
||||
blind: self.constructed.product_blind,
|
||||
eval: self.product_eval,
|
||||
}))
|
||||
// Open lookup input commitments at x
|
||||
.chain(Some(ProverQuery {
|
||||
point: *x,
|
||||
poly: &self.constructed.permuted_input_poly,
|
||||
blind: self.constructed.permuted_input_blind,
|
||||
eval: self.permuted_input_eval,
|
||||
}))
|
||||
// Open lookup table commitments at x
|
||||
.chain(Some(ProverQuery {
|
||||
point: *x,
|
||||
poly: &self.constructed.permuted_table_poly,
|
||||
blind: self.constructed.permuted_table_blind,
|
||||
eval: self.permuted_table_eval,
|
||||
}))
|
||||
// Open lookup input commitments at x_inv
|
||||
.chain(Some(ProverQuery {
|
||||
point: x_inv,
|
||||
poly: &self.constructed.permuted_input_poly,
|
||||
blind: self.constructed.permuted_input_blind,
|
||||
eval: self.permuted_input_inv_eval,
|
||||
}))
|
||||
// Open lookup product commitments at x_inv
|
||||
.chain(Some(ProverQuery {
|
||||
point: x_inv,
|
||||
poly: &self.constructed.product_poly,
|
||||
blind: self.constructed.product_blind,
|
||||
eval: self.product_inv_eval,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,9 +27,6 @@ pub(crate) struct Constructed<C: CurveAffine> {
|
|||
|
||||
pub(crate) struct Evaluated<C: CurveAffine> {
|
||||
constructed: Constructed<C>,
|
||||
permutation_product_eval: C::Scalar,
|
||||
permutation_product_inv_eval: C::Scalar,
|
||||
permutation_evals: Vec<C::Scalar>,
|
||||
}
|
||||
|
||||
impl Argument {
|
||||
|
@ -218,20 +215,12 @@ impl<C: CurveAffine> super::ProvingKey<C> {
|
|||
.collect()
|
||||
}
|
||||
|
||||
fn open<'a>(
|
||||
&'a self,
|
||||
evals: &'a [C::Scalar],
|
||||
x: ChallengeX<C>,
|
||||
) -> impl Iterator<Item = ProverQuery<'a, C>> + Clone {
|
||||
self.polys
|
||||
.iter()
|
||||
.zip(evals.iter())
|
||||
.map(move |(poly, eval)| ProverQuery {
|
||||
point: *x,
|
||||
poly,
|
||||
blind: Blind::default(),
|
||||
eval: *eval,
|
||||
})
|
||||
fn open<'a>(&'a self, x: ChallengeX<C>) -> impl Iterator<Item = ProverQuery<'a, C>> + Clone {
|
||||
self.polys.iter().map(move |poly| ProverQuery {
|
||||
point: *x,
|
||||
poly,
|
||||
blind: Blind::default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -265,12 +254,7 @@ impl<C: CurveAffine> Constructed<C> {
|
|||
.map_err(|_| Error::TranscriptError)?;
|
||||
}
|
||||
|
||||
Ok(Evaluated {
|
||||
constructed: self,
|
||||
permutation_product_eval,
|
||||
permutation_product_inv_eval,
|
||||
permutation_evals,
|
||||
})
|
||||
Ok(Evaluated { constructed: self })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,15 +273,13 @@ impl<C: CurveAffine> Evaluated<C> {
|
|||
point: *x,
|
||||
poly: &self.constructed.permutation_product_poly,
|
||||
blind: self.constructed.permutation_product_blind,
|
||||
eval: self.permutation_product_eval,
|
||||
}))
|
||||
.chain(Some(ProverQuery {
|
||||
point: x_inv,
|
||||
poly: &self.constructed.permutation_product_poly,
|
||||
blind: self.constructed.permutation_product_blind,
|
||||
eval: self.permutation_product_inv_eval,
|
||||
}))
|
||||
// Open permutation polynomial commitments at x
|
||||
.chain(pkey.open(&self.permutation_evals, x))
|
||||
.chain(pkey.open(x))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -304,53 +304,51 @@ pub fn create_proof<C: CurveAffine, T: TranscriptWrite<C>, ConcreteCircuit: Circ
|
|||
.map(|p| p.evaluate(pk, x, transcript))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
let instances =
|
||||
iter::empty()
|
||||
.chain(pk.vk.cs.advice_queries.iter().enumerate().map(
|
||||
|(query_index, &(column, at))| ProverQuery {
|
||||
let instances = iter::empty()
|
||||
.chain(
|
||||
pk.vk
|
||||
.cs
|
||||
.advice_queries
|
||||
.iter()
|
||||
.map(|&(column, at)| ProverQuery {
|
||||
point: domain.rotate_omega(*x, at),
|
||||
poly: &advice_polys[column.index()],
|
||||
blind: advice_blinds[column.index()],
|
||||
eval: advice_evals[query_index],
|
||||
},
|
||||
))
|
||||
.chain(
|
||||
pk.vk
|
||||
.cs
|
||||
.aux_queries
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(query_index, &(column, at))| ProverQuery {
|
||||
point: domain.rotate_omega(*x, at),
|
||||
poly: &aux_polys[column.index()],
|
||||
blind: Blind::default(),
|
||||
eval: aux_evals[query_index],
|
||||
}),
|
||||
)
|
||||
.chain(
|
||||
pk.vk
|
||||
.cs
|
||||
.fixed_queries
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(query_index, &(column, at))| ProverQuery {
|
||||
point: domain.rotate_omega(*x, at),
|
||||
poly: &pk.fixed_polys[column.index()],
|
||||
blind: Blind::default(),
|
||||
eval: fixed_evals[query_index],
|
||||
}),
|
||||
)
|
||||
// We query the h(X) polynomial at x
|
||||
.chain(vanishing.open(x))
|
||||
.chain(
|
||||
permutations
|
||||
.iter()
|
||||
.zip(pk.permutations.iter())
|
||||
.map(|(p, pkey)| p.open(pk, pkey, x))
|
||||
.into_iter()
|
||||
.flatten(),
|
||||
)
|
||||
.chain(lookups.iter().map(|p| p.open(pk, x)).into_iter().flatten());
|
||||
}),
|
||||
)
|
||||
.chain(
|
||||
pk.vk
|
||||
.cs
|
||||
.aux_queries
|
||||
.iter()
|
||||
.map(|&(column, at)| ProverQuery {
|
||||
point: domain.rotate_omega(*x, at),
|
||||
poly: &aux_polys[column.index()],
|
||||
blind: Blind::default(),
|
||||
}),
|
||||
)
|
||||
.chain(
|
||||
pk.vk
|
||||
.cs
|
||||
.fixed_queries
|
||||
.iter()
|
||||
.map(|&(column, at)| ProverQuery {
|
||||
point: domain.rotate_omega(*x, at),
|
||||
poly: &pk.fixed_polys[column.index()],
|
||||
blind: Blind::default(),
|
||||
}),
|
||||
)
|
||||
// We query the h(X) polynomial at x
|
||||
.chain(vanishing.open(x))
|
||||
.chain(
|
||||
permutations
|
||||
.iter()
|
||||
.zip(pk.permutations.iter())
|
||||
.map(|(p, pkey)| p.open(pk, pkey, x))
|
||||
.into_iter()
|
||||
.flatten(),
|
||||
)
|
||||
.chain(lookups.iter().map(|p| p.open(pk, x)).into_iter().flatten());
|
||||
|
||||
multiopen::create_proof(params, transcript, instances).map_err(|_| Error::OpeningError)
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ pub(in crate::plonk) struct Constructed<C: CurveAffine> {
|
|||
|
||||
pub(in crate::plonk) struct Evaluated<C: CurveAffine> {
|
||||
constructed: Constructed<C>,
|
||||
h_evals: Vec<C::Scalar>,
|
||||
}
|
||||
|
||||
impl<C: CurveAffine> Argument<C> {
|
||||
|
@ -85,10 +84,7 @@ impl<C: CurveAffine> Constructed<C> {
|
|||
.map_err(|_| Error::TranscriptError)?;
|
||||
}
|
||||
|
||||
Ok(Evaluated {
|
||||
constructed: self,
|
||||
h_evals,
|
||||
})
|
||||
Ok(Evaluated { constructed: self })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,12 +97,10 @@ impl<C: CurveAffine> Evaluated<C> {
|
|||
.h_pieces
|
||||
.iter()
|
||||
.zip(self.constructed.h_blinds.iter())
|
||||
.zip(self.h_evals.iter())
|
||||
.map(move |((h_poly, h_blind), h_eval)| ProverQuery {
|
||||
.map(move |(h_poly, h_blind)| ProverQuery {
|
||||
point: *x,
|
||||
poly: h_poly,
|
||||
blind: *h_blind,
|
||||
eval: *h_eval,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
//!
|
||||
//! [halo]: https://eprint.iacr.org/2019/1021
|
||||
|
||||
use ff::Field;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
use super::*;
|
||||
|
@ -48,8 +47,6 @@ pub struct ProverQuery<'a, C: CurveAffine> {
|
|||
pub poly: &'a Polynomial<C::Scalar, Coeff>,
|
||||
/// blinding factor of polynomial
|
||||
pub blind: commitment::Blind<C::Scalar>,
|
||||
/// evaluation of polynomial at query point
|
||||
pub eval: C::Scalar,
|
||||
}
|
||||
|
||||
/// A polynomial query at a point
|
||||
|
@ -63,14 +60,14 @@ pub struct VerifierQuery<'a, C: CurveAffine> {
|
|||
pub eval: C::Scalar,
|
||||
}
|
||||
|
||||
struct CommitmentData<F: Field, T: PartialEq> {
|
||||
struct CommitmentData<F, T: PartialEq> {
|
||||
commitment: T,
|
||||
set_index: usize,
|
||||
point_indices: Vec<usize>,
|
||||
evals: Vec<F>,
|
||||
}
|
||||
|
||||
impl<F: Field, T: PartialEq> CommitmentData<F, T> {
|
||||
impl<F, T: PartialEq> CommitmentData<F, T> {
|
||||
fn new(commitment: T) -> Self {
|
||||
CommitmentData {
|
||||
commitment,
|
||||
|
@ -83,21 +80,22 @@ impl<F: Field, T: PartialEq> CommitmentData<F, T> {
|
|||
|
||||
trait Query<F>: Sized {
|
||||
type Commitment: PartialEq + Copy;
|
||||
type Eval: Clone + Default;
|
||||
|
||||
fn get_point(&self) -> F;
|
||||
fn get_eval(&self) -> F;
|
||||
fn get_eval(&self) -> Self::Eval;
|
||||
fn get_commitment(&self) -> Self::Commitment;
|
||||
}
|
||||
|
||||
fn construct_intermediate_sets<F: FieldExt, I, Q: Query<F>>(
|
||||
queries: I,
|
||||
) -> (Vec<CommitmentData<F, Q::Commitment>>, Vec<Vec<F>>)
|
||||
) -> (Vec<CommitmentData<Q::Eval, Q::Commitment>>, Vec<Vec<F>>)
|
||||
where
|
||||
I: IntoIterator<Item = Q> + Clone,
|
||||
{
|
||||
// Construct sets of unique commitments and corresponding information about
|
||||
// their queries.
|
||||
let mut commitment_map: Vec<CommitmentData<F, Q::Commitment>> = vec![];
|
||||
let mut commitment_map: Vec<CommitmentData<Q::Eval, Q::Commitment>> = vec![];
|
||||
|
||||
// Also construct mapping from a unique point to a point_index. This defines
|
||||
// an ordering on the points.
|
||||
|
@ -151,7 +149,7 @@ where
|
|||
// Initialise empty evals vec for each unique commitment
|
||||
for commitment_data in commitment_map.iter_mut() {
|
||||
let len = commitment_data.point_indices.len();
|
||||
commitment_data.evals = vec![F::zero(); len];
|
||||
commitment_data.evals = vec![Q::Eval::default(); len];
|
||||
}
|
||||
|
||||
// Populate set_index, evals and points for each commitment using point_idx_sets
|
||||
|
@ -203,6 +201,134 @@ where
|
|||
(commitment_map, point_sets)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_roundtrip() {
|
||||
use super::commitment::{Blind, Params};
|
||||
use crate::arithmetic::{eval_polynomial, Curve, FieldExt};
|
||||
use crate::pasta::{EqAffine, Fp};
|
||||
|
||||
const K: u32 = 4;
|
||||
|
||||
let params: Params<EqAffine> = Params::new(K);
|
||||
let domain = EvaluationDomain::new(1, K);
|
||||
|
||||
let mut ax = domain.empty_coeff();
|
||||
for (i, a) in ax.iter_mut().enumerate() {
|
||||
*a = Fp::from(10 + i as u64);
|
||||
}
|
||||
|
||||
let mut bx = domain.empty_coeff();
|
||||
for (i, a) in bx.iter_mut().enumerate() {
|
||||
*a = Fp::from(100 + i as u64);
|
||||
}
|
||||
|
||||
let mut cx = domain.empty_coeff();
|
||||
for (i, a) in cx.iter_mut().enumerate() {
|
||||
*a = Fp::from(100 + i as u64);
|
||||
}
|
||||
|
||||
let blind = Blind(Fp::rand());
|
||||
|
||||
let a = params.commit(&ax, blind).to_affine();
|
||||
let b = params.commit(&bx, blind).to_affine();
|
||||
let c = params.commit(&cx, blind).to_affine();
|
||||
|
||||
let x = Fp::rand();
|
||||
let y = Fp::rand();
|
||||
let avx = eval_polynomial(&ax, x);
|
||||
let bvx = eval_polynomial(&bx, x);
|
||||
let cvy = eval_polynomial(&cx, y);
|
||||
|
||||
let mut transcript = crate::transcript::DummyHashWrite::init(vec![], Field::one());
|
||||
create_proof(
|
||||
¶ms,
|
||||
&mut transcript,
|
||||
std::iter::empty()
|
||||
.chain(Some(ProverQuery {
|
||||
point: x,
|
||||
poly: &ax,
|
||||
blind,
|
||||
}))
|
||||
.chain(Some(ProverQuery {
|
||||
point: x,
|
||||
poly: &bx,
|
||||
blind,
|
||||
}))
|
||||
.chain(Some(ProverQuery {
|
||||
point: y,
|
||||
poly: &cx,
|
||||
blind,
|
||||
})),
|
||||
)
|
||||
.unwrap();
|
||||
let proof = transcript.finalize();
|
||||
|
||||
{
|
||||
let mut proof = &proof[..];
|
||||
let mut transcript = crate::transcript::DummyHashRead::init(&mut proof, Field::one());
|
||||
let msm = params.empty_msm();
|
||||
|
||||
let guard = verify_proof(
|
||||
¶ms,
|
||||
&mut transcript,
|
||||
std::iter::empty()
|
||||
.chain(Some(VerifierQuery {
|
||||
point: x,
|
||||
commitment: &a,
|
||||
eval: avx,
|
||||
}))
|
||||
.chain(Some(VerifierQuery {
|
||||
point: x,
|
||||
commitment: &b,
|
||||
eval: avx, // NB: wrong!
|
||||
}))
|
||||
.chain(Some(VerifierQuery {
|
||||
point: y,
|
||||
commitment: &c,
|
||||
eval: cvy,
|
||||
})),
|
||||
msm,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Should fail.
|
||||
assert!(!guard.use_challenges().eval());
|
||||
}
|
||||
|
||||
{
|
||||
let mut proof = &proof[..];
|
||||
|
||||
let mut transcript = crate::transcript::DummyHashRead::init(&mut proof, Field::one());
|
||||
let msm = params.empty_msm();
|
||||
|
||||
let guard = verify_proof(
|
||||
¶ms,
|
||||
&mut transcript,
|
||||
std::iter::empty()
|
||||
.chain(Some(VerifierQuery {
|
||||
point: x,
|
||||
commitment: &a,
|
||||
eval: avx,
|
||||
}))
|
||||
.chain(Some(VerifierQuery {
|
||||
point: x,
|
||||
commitment: &b,
|
||||
eval: bvx,
|
||||
}))
|
||||
.chain(Some(VerifierQuery {
|
||||
point: y,
|
||||
commitment: &c,
|
||||
eval: cvy,
|
||||
})),
|
||||
msm,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Should succeed.
|
||||
assert!(guard.use_challenges().eval());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{construct_intermediate_sets, Query};
|
||||
|
@ -216,14 +342,15 @@ mod tests {
|
|||
eval: F,
|
||||
}
|
||||
|
||||
impl<F: Copy> Query<F> for MyQuery<F> {
|
||||
impl<F: Clone + Default> Query<F> for MyQuery<F> {
|
||||
type Commitment = usize;
|
||||
type Eval = F;
|
||||
|
||||
fn get_point(&self) -> F {
|
||||
self.point
|
||||
self.point.clone()
|
||||
}
|
||||
fn get_eval(&self) -> F {
|
||||
self.eval
|
||||
fn get_eval(&self) -> Self::Eval {
|
||||
self.eval.clone()
|
||||
}
|
||||
fn get_commitment(&self) -> Self::Commitment {
|
||||
self.commitment
|
||||
|
|
|
@ -7,9 +7,7 @@ use super::{
|
|||
Query,
|
||||
};
|
||||
|
||||
use crate::arithmetic::{
|
||||
eval_polynomial, kate_division, lagrange_interpolate, Curve, CurveAffine, FieldExt,
|
||||
};
|
||||
use crate::arithmetic::{eval_polynomial, kate_division, Curve, CurveAffine, FieldExt};
|
||||
use crate::transcript::TranscriptWrite;
|
||||
|
||||
use ff::Field;
|
||||
|
@ -43,56 +41,36 @@ where
|
|||
let mut q_polys: Vec<Option<Polynomial<C::Scalar, Coeff>>> = vec![None; point_sets.len()];
|
||||
let mut q_blinds = vec![Blind(C::Scalar::zero()); point_sets.len()];
|
||||
|
||||
// A vec of vecs of evals. The outer vec corresponds to the point set,
|
||||
// while the inner vec corresponds to the points in a particular set.
|
||||
let mut q_eval_sets = Vec::with_capacity(point_sets.len());
|
||||
for point_set in point_sets.iter() {
|
||||
q_eval_sets.push(vec![C::Scalar::zero(); point_set.len()]);
|
||||
}
|
||||
|
||||
{
|
||||
let mut accumulate = |set_idx: usize,
|
||||
new_poly: &Polynomial<C::Scalar, Coeff>,
|
||||
blind: Blind<C::Scalar>,
|
||||
evals: Vec<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;
|
||||
// Each polynomial is evaluated at a set of points. For each set,
|
||||
// we collapse each polynomial's evals pointwise.
|
||||
for (eval, set_eval) in evals.iter().zip(q_eval_sets[set_idx].iter_mut()) {
|
||||
*set_eval *= &(*x_1);
|
||||
*set_eval += eval;
|
||||
}
|
||||
};
|
||||
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;
|
||||
};
|
||||
|
||||
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,
|
||||
commitment_data.evals, // evals
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let f_poly = point_sets
|
||||
.iter()
|
||||
.zip(q_eval_sets.iter())
|
||||
.zip(q_polys.iter())
|
||||
.fold(None, |f_poly, ((points, evals), poly)| {
|
||||
let mut poly = poly.clone().unwrap().values;
|
||||
// TODO: makes implicit asssumption that poly degree is smaller than interpolation poly degree
|
||||
for (p, r) in poly.iter_mut().zip(lagrange_interpolate(points, evals)) {
|
||||
*p -= &r;
|
||||
}
|
||||
.fold(None, |f_poly, (points, poly)| {
|
||||
let mut poly = points
|
||||
.iter()
|
||||
.fold(poly, |poly, point| kate_division(&poly, *point));
|
||||
.fold(poly.clone().unwrap().values, |poly, point| {
|
||||
kate_division(&poly, *point)
|
||||
});
|
||||
poly.resize(params.n as usize, C::Scalar::zero());
|
||||
let poly = Polynomial {
|
||||
values: poly,
|
||||
|
@ -153,13 +131,12 @@ impl<'a, C: CurveAffine> PartialEq for PolynomialPointer<'a, C> {
|
|||
|
||||
impl<'a, C: CurveAffine> Query<C::Scalar> for ProverQuery<'a, C> {
|
||||
type Commitment = PolynomialPointer<'a, C>;
|
||||
type Eval = ();
|
||||
|
||||
fn get_point(&self) -> C::Scalar {
|
||||
self.point
|
||||
}
|
||||
fn get_eval(&self) -> C::Scalar {
|
||||
self.eval
|
||||
}
|
||||
fn get_eval(&self) -> () {}
|
||||
fn get_commitment(&self) -> Self::Commitment {
|
||||
PolynomialPointer {
|
||||
poly: self.poly,
|
||||
|
|
|
@ -133,6 +133,7 @@ impl<'a, C> PartialEq for CommitmentPointer<'a, C> {
|
|||
|
||||
impl<'a, C: CurveAffine> Query<C::Scalar> for VerifierQuery<'a, C> {
|
||||
type Commitment = CommitmentPointer<'a, C>;
|
||||
type Eval = C::Scalar;
|
||||
|
||||
fn get_point(&self) -> C::Scalar {
|
||||
self.point
|
||||
|
|
Loading…
Reference in New Issue