mirror of
https://github.com/saymrwulf/pasta_curves-source.git
synced 2026-09-06 20:20:34 +00:00
Optimisations and documentation updates
This commit is contained in:
parent
e51ab7eaa7
commit
9a3d1b1d05
4 changed files with 77 additions and 74 deletions
|
|
@ -364,6 +364,9 @@ impl<F: Field> ConstraintSystem<F> {
|
||||||
input_columns: &[Column<Any>],
|
input_columns: &[Column<Any>],
|
||||||
table_columns: &[Column<Any>],
|
table_columns: &[Column<Any>],
|
||||||
) -> usize {
|
) -> usize {
|
||||||
|
// The function will panic if the number of input columns and table columns are not the same.
|
||||||
|
assert_eq!(input_columns.len(), table_columns.len());
|
||||||
|
|
||||||
let index = self.lookups.len();
|
let index = self.lookups.len();
|
||||||
if self.lookups.is_empty() {
|
if self.lookups.is_empty() {
|
||||||
let at = Rotation(-1);
|
let at = Rotation(-1);
|
||||||
|
|
|
||||||
|
|
@ -192,12 +192,12 @@ impl Argument {
|
||||||
.commit_lagrange(&permuted_table_value, permuted_table_blind)
|
.commit_lagrange(&permuted_table_value, permuted_table_blind)
|
||||||
.to_affine();
|
.to_affine();
|
||||||
|
|
||||||
// Hash each permuted input commitment
|
// Hash permuted input commitment
|
||||||
transcript
|
transcript
|
||||||
.absorb_point(&permuted_input_commitment)
|
.absorb_point(&permuted_input_commitment)
|
||||||
.map_err(|_| Error::TranscriptError)?;
|
.map_err(|_| Error::TranscriptError)?;
|
||||||
|
|
||||||
// Hash each permuted table commitment
|
// Hash permuted table commitment
|
||||||
transcript
|
transcript
|
||||||
.absorb_point(&permuted_table_commitment)
|
.absorb_point(&permuted_table_commitment)
|
||||||
.map_err(|_| Error::TranscriptError)?;
|
.map_err(|_| Error::TranscriptError)?;
|
||||||
|
|
@ -239,16 +239,15 @@ impl<'a, C: CurveAffine> Permuted<'a, C> {
|
||||||
) -> Result<Committed<'a, C>, Error> {
|
) -> Result<Committed<'a, C>, Error> {
|
||||||
// Goal is to compute the products of fractions
|
// Goal is to compute the products of fractions
|
||||||
//
|
//
|
||||||
// (a_1(\omega^i) + \theta a_2(\omega^i) + ... + beta)(s_1(\omega^i) + \theta(\omega^i) + ... + \gamma) /
|
// (\theta^{m-1} a_1(\omega^i) + \theta^{m-2} a_2(\omega^i) + ... + a_m(\omega^i) + \beta)(\theta^{m-1} s_1(\omega^i) + \theta^{m-2} s_2(\omega^i) + ... + s_m(\omega^i) + \gamma)/
|
||||||
// (a'(\omega^i) + \beta)(s'(\omega^i) + \gamma)
|
// (a'(\omega^i) + \beta) (s'(\omega^i) + \gamma)
|
||||||
//
|
//
|
||||||
// where a_j(X) is the jth input column in this lookup,
|
// where a_j(X) is the jth input column in this lookup,
|
||||||
// where a'(X) is the compression of the permuted input columns,
|
// where a'(X) is the compression of the permuted input columns,
|
||||||
// s_j(X) is the jth table column in this lookup,
|
// s_j(X) is the jth table column in this lookup,
|
||||||
// s'(X) is the compression of the permuted table columns,
|
// s'(X) is the compression of the permuted table columns,
|
||||||
// and i is the ith row of the column.
|
// and i is the ith row of the column.
|
||||||
let mut lookup_product = vec![C::Scalar::one(); params.n as usize];
|
let mut lookup_product = vec![C::Scalar::zero(); params.n as usize];
|
||||||
|
|
||||||
// Denominator uses the permuted input column and permuted table column
|
// Denominator uses the permuted input column and permuted table column
|
||||||
parallelize(&mut lookup_product, |lookup_product, start| {
|
parallelize(&mut lookup_product, |lookup_product, start| {
|
||||||
for ((lookup_product, permuted_input_value), permuted_table_value) in lookup_product
|
for ((lookup_product, permuted_input_value), permuted_table_value) in lookup_product
|
||||||
|
|
@ -256,8 +255,7 @@ impl<'a, C: CurveAffine> Permuted<'a, C> {
|
||||||
.zip(self.permuted_input_value[start..].iter())
|
.zip(self.permuted_input_value[start..].iter())
|
||||||
.zip(self.permuted_table_value[start..].iter())
|
.zip(self.permuted_table_value[start..].iter())
|
||||||
{
|
{
|
||||||
*lookup_product *= &(*beta + permuted_input_value);
|
*lookup_product = (*beta + permuted_input_value) * &(*gamma + permuted_table_value);
|
||||||
*lookup_product *= &(*gamma + permuted_table_value);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -266,7 +264,7 @@ impl<'a, C: CurveAffine> Permuted<'a, C> {
|
||||||
lookup_product.iter_mut().batch_invert();
|
lookup_product.iter_mut().batch_invert();
|
||||||
|
|
||||||
// Finish the computation of the entire fraction by computing the numerators
|
// Finish the computation of the entire fraction by computing the numerators
|
||||||
// (a_1(X) + \theta a_2(X) + ... + \beta) (s_1(X) + \theta s_2(X) + ... + \gamma)
|
// (\theta^{m-1} a_1(\omega^i) + \theta^{m-2} a_2(\omega^i) + ... + \theta a_{m-1}(\omega^i) + a_m(\omega^i) + \beta)(\theta^{m-1} s_1(\omega^i) + \theta^{m-2} s_2(\omega^i) + ... + \theta s_{m-1}(\omega^i) + s_m(\omega^i) + \gamma)
|
||||||
// Compress unpermuted input columns
|
// Compress unpermuted input columns
|
||||||
let mut input_term = vec![C::Scalar::zero(); params.n as usize];
|
let mut input_term = vec![C::Scalar::zero(); params.n as usize];
|
||||||
for unpermuted_input_value in self.unpermuted_input_values.iter() {
|
for unpermuted_input_value in self.unpermuted_input_values.iter() {
|
||||||
|
|
@ -309,10 +307,10 @@ impl<'a, C: CurveAffine> Permuted<'a, C> {
|
||||||
|
|
||||||
// The product vector is a vector of products of fractions of the form
|
// The product vector is a vector of products of fractions of the form
|
||||||
//
|
//
|
||||||
// (a_1(\omega^i) + \theta a_2(\omega^i) + ... + \beta)(s_1(\omega^i) + \theta s_2(\omega^i) + ... + \gamma)/
|
// (\theta^{m-1} a_1(\omega^i) + \theta^{m-2} a_2(\omega^i) + ... + \theta a_{m-1}(\omega^i) + a_m(\omega^i) + \beta)(\theta^{m-1} s_1(\omega^i) + \theta^{m-2} s_2(\omega^i) + ... + \theta s_{m-1}(\omega^i) + s_m(\omega^i) + \gamma)
|
||||||
// (a'(\omega^i) + \beta) (s'(\omega^i) + \gamma)
|
|
||||||
//
|
//
|
||||||
// where a_j(\omega^i) is the jth input column in this lookup,
|
// where there are m input columns and m table columns,
|
||||||
|
// a_j(\omega^i) is the jth input column in this lookup,
|
||||||
// a'j(\omega^i) is the permuted input column,
|
// a'j(\omega^i) is the permuted input column,
|
||||||
// s_j(\omega^i) is the jth table column in this lookup,
|
// s_j(\omega^i) is the jth table column in this lookup,
|
||||||
// s'(\omega^i) is the permuted table column,
|
// s'(\omega^i) is the permuted table column,
|
||||||
|
|
@ -320,12 +318,13 @@ impl<'a, C: CurveAffine> Permuted<'a, C> {
|
||||||
|
|
||||||
// Compute the evaluations of the lookup product polynomial
|
// Compute the evaluations of the lookup product polynomial
|
||||||
// over our domain, starting with z[0] = 1
|
// over our domain, starting with z[0] = 1
|
||||||
let mut z = vec![C::Scalar::one()];
|
let z = iter::once(C::Scalar::one())
|
||||||
for row in 1..(params.n as usize) {
|
.chain(lookup_product.into_iter().skip(1))
|
||||||
let mut tmp = z[row - 1];
|
.scan(C::Scalar::one(), |state, cur| {
|
||||||
tmp *= &lookup_product[row];
|
*state *= &cur;
|
||||||
z.push(tmp);
|
Some(*state)
|
||||||
}
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
let z = pk.vk.domain.lagrange_from_vec(z);
|
let z = pk.vk.domain.lagrange_from_vec(z);
|
||||||
|
|
||||||
#[cfg(feature = "sanity-checks")]
|
#[cfg(feature = "sanity-checks")]
|
||||||
|
|
@ -336,7 +335,7 @@ impl<'a, C: CurveAffine> Permuted<'a, C> {
|
||||||
let n = params.n as usize;
|
let n = params.n as usize;
|
||||||
|
|
||||||
// z'(X) (a'(X) + \beta) (s'(X) + \gamma)
|
// z'(X) (a'(X) + \beta) (s'(X) + \gamma)
|
||||||
// - z'(\omega^{-1} X) (a_1(X) + \theta a_2(X) + ... + \beta) (s_1(X) + \theta s_2(X) + ... + \gamma)
|
// - z'(\omega^{-1} X) (\theta^m a_1(X) + \theta^{m-1} a_2(X) + ... + a_m(X) + \beta) (\theta^m s_1(X) + \theta^{m-1} s_2(X) + ... + s_m(X) + \gamma)
|
||||||
for i in 0..n {
|
for i in 0..n {
|
||||||
let prev_idx = (n + i - 1) % n;
|
let prev_idx = (n + i - 1) % n;
|
||||||
|
|
||||||
|
|
@ -374,7 +373,7 @@ impl<'a, C: CurveAffine> Permuted<'a, C> {
|
||||||
.coeff_to_extended(z.clone(), Rotation::default());
|
.coeff_to_extended(z.clone(), Rotation::default());
|
||||||
let product_inv_coset = pk.vk.domain.coeff_to_extended(z.clone(), Rotation(-1));
|
let product_inv_coset = pk.vk.domain.coeff_to_extended(z.clone(), Rotation(-1));
|
||||||
|
|
||||||
// Hash each product commitment
|
// Hash product commitment
|
||||||
transcript
|
transcript
|
||||||
.absorb_point(&product_commitment)
|
.absorb_point(&product_commitment)
|
||||||
.map_err(|_| Error::TranscriptError)?;
|
.map_err(|_| Error::TranscriptError)?;
|
||||||
|
|
@ -417,7 +416,7 @@ impl<'a, C: CurveAffine> Committed<'a, C> {
|
||||||
Polynomial::one_minus(self.product_coset.clone()) * &pk.l0,
|
Polynomial::one_minus(self.product_coset.clone()) * &pk.l0,
|
||||||
))
|
))
|
||||||
// z'(X) (a'(X) + \beta) (s'(X) + \gamma)
|
// z'(X) (a'(X) + \beta) (s'(X) + \gamma)
|
||||||
// - z'(\omega^{-1} X) (a_1(X) + \theta a_2(X) + ... + \beta) (s_1(X) + \theta s_2(X) + ... + \gamma)
|
// - z'(\omega^{-1} X) (\theta^m a_1(X) + \theta^{m-1} a_2(X) + ... + a_m(X) + \beta) (\theta^m s_1(X) + \theta^{m-1} s_2(X) + ... + s_m(X) + \gamma)
|
||||||
.chain({
|
.chain({
|
||||||
// z'(X) (a'(X) + \beta) (s'(X) + \gamma)
|
// z'(X) (a'(X) + \beta) (s'(X) + \gamma)
|
||||||
let mut left = self.product_coset.clone();
|
let mut left = self.product_coset.clone();
|
||||||
|
|
@ -432,13 +431,13 @@ impl<'a, C: CurveAffine> Committed<'a, C> {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// z'(\omega^{-1} X) (a_1(X) + \theta a_2(X) + ... + \beta) (s_1(X) + \theta s_2(X) + ... + \gamma)
|
// z'(\omega^{-1} X) (\theta^m a_1(X) + \theta^{m-1} a_2(X) + ... + a_m(X) + \beta) (\theta^m s_1(X) + \theta^{m-1} s_2(X) + ... + s_m(X) + \gamma)
|
||||||
let mut right = self.product_inv_coset;
|
let mut right = self.product_inv_coset;
|
||||||
let mut input_terms = pk.vk.domain.empty_extended();
|
let mut input_terms = pk.vk.domain.empty_extended();
|
||||||
|
|
||||||
// Compress the unpermuted input columns
|
// Compress the unpermuted input columns
|
||||||
for input in permuted.unpermuted_input_cosets.iter() {
|
for input in permuted.unpermuted_input_cosets.iter() {
|
||||||
// (a_1(X) + \theta a_2(X) + ...)
|
// \theta^m a_1(X) + \theta^{m-1} a_2(X) + ... + a_m(X)
|
||||||
parallelize(&mut input_terms, |input_term, start| {
|
parallelize(&mut input_terms, |input_term, start| {
|
||||||
for (input_term, input) in input_term.iter_mut().zip(input[start..].iter())
|
for (input_term, input) in input_term.iter_mut().zip(input[start..].iter())
|
||||||
{
|
{
|
||||||
|
|
@ -451,7 +450,7 @@ impl<'a, C: CurveAffine> Committed<'a, C> {
|
||||||
let mut table_terms = pk.vk.domain.empty_extended();
|
let mut table_terms = pk.vk.domain.empty_extended();
|
||||||
// Compress the unpermuted table columns
|
// Compress the unpermuted table columns
|
||||||
for table in permuted.unpermuted_table_cosets.iter() {
|
for table in permuted.unpermuted_table_cosets.iter() {
|
||||||
// (s_1(X) + \theta s_2(X) + ...)
|
// \theta^m s_1(X) + \theta^{m-1} s_2(X) + ... + s_m(X)
|
||||||
parallelize(&mut table_terms, |table_term, start| {
|
parallelize(&mut table_terms, |table_term, start| {
|
||||||
for (table_term, table) in table_term.iter_mut().zip(table[start..].iter())
|
for (table_term, table) in table_term.iter_mut().zip(table[start..].iter())
|
||||||
{
|
{
|
||||||
|
|
@ -633,28 +632,31 @@ fn permute_column_pair<C: CurveAffine>(
|
||||||
*acc.entry(*coeff).or_insert(0) += 1;
|
*acc.entry(*coeff).or_insert(0) += 1;
|
||||||
acc
|
acc
|
||||||
});
|
});
|
||||||
let mut repeated_input_rows = vec![];
|
|
||||||
let mut permuted_table_coeffs = vec![C::Scalar::zero(); table_column.len()];
|
let mut permuted_table_coeffs = vec![C::Scalar::zero(); table_column.len()];
|
||||||
|
|
||||||
for row in 0..permuted_input_column.len() {
|
let mut repeated_input_rows = permuted_input_column
|
||||||
let input_value = permuted_input_column[row];
|
.iter()
|
||||||
|
.zip(permuted_table_coeffs.iter_mut())
|
||||||
// If this is the first occurence of `input_value` in the input column
|
.enumerate()
|
||||||
if row == 0 || input_value != permuted_input_column[row - 1] {
|
.filter_map(|(row, (input_value, table_value))| {
|
||||||
permuted_table_coeffs[row] = input_value;
|
// If this is the first occurence of `input_value` in the input column
|
||||||
// Remove one instance of input_value from leftover_table_map
|
if row == 0 || *input_value != permuted_input_column[row - 1] {
|
||||||
if let Some(count) = leftover_table_map.get_mut(&input_value) {
|
*table_value = *input_value;
|
||||||
assert!(*count > 0);
|
// Remove one instance of input_value from leftover_table_map
|
||||||
*count -= 1;
|
if let Some(count) = leftover_table_map.get_mut(&input_value) {
|
||||||
|
assert!(*count > 0);
|
||||||
|
*count -= 1;
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
// Return error if input_value not found
|
||||||
|
Some(Err(Error::ConstraintSystemFailure))
|
||||||
|
}
|
||||||
|
// If input value is repeated
|
||||||
} else {
|
} else {
|
||||||
// Return error if input_value not found
|
Some(Ok(row))
|
||||||
return Err(Error::ConstraintSystemFailure);
|
|
||||||
}
|
}
|
||||||
// If input value is repeated
|
})
|
||||||
} else {
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
repeated_input_rows.push(row);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Populate permuted table at unfilled rows with leftover table elements
|
// Populate permuted table at unfilled rows with leftover table elements
|
||||||
for (coeff, count) in leftover_table_map.iter() {
|
for (coeff, count) in leftover_table_map.iter() {
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,7 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
.map_err(|_| Error::TranscriptError)?;
|
.map_err(|_| Error::TranscriptError)?;
|
||||||
transcript
|
transcript
|
||||||
.absorb_point(&self.permuted_table_commitment)
|
.absorb_point(&self.permuted_table_commitment)
|
||||||
.map_err(|_| Error::TranscriptError)?;
|
.map_err(|_| Error::TranscriptError)
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn absorb_product_commitment<HBase: Hasher<C::Base>, HScalar: Hasher<C::Scalar>>(
|
pub(crate) fn absorb_product_commitment<HBase: Hasher<C::Base>, HScalar: Hasher<C::Scalar>>(
|
||||||
|
|
@ -33,8 +32,7 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
transcript
|
transcript
|
||||||
.absorb_point(&self.product_commitment)
|
.absorb_point(&self.product_commitment)
|
||||||
.map_err(|_| Error::TranscriptError)?;
|
.map_err(|_| Error::TranscriptError)
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(in crate::plonk) fn expressions<'a>(
|
pub(in crate::plonk) fn expressions<'a>(
|
||||||
|
|
@ -51,7 +49,7 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
) -> impl Iterator<Item = C::Scalar> + 'a {
|
) -> impl Iterator<Item = C::Scalar> + 'a {
|
||||||
let product_expression = || {
|
let product_expression = || {
|
||||||
// z'(X) (a'(X) + \beta) (s'(X) + \gamma)
|
// z'(X) (a'(X) + \beta) (s'(X) + \gamma)
|
||||||
// - z'(\omega^{-1} X) (a_1(X) + \theta a_2(X) + ... + \beta) (s_1(X) + \theta s_2(X) + ... + \gamma)
|
// - z'(\omega^{-1} X) (\theta^m a_1(X) + \theta^{m-1} a_2(X) + ... + a_m(X) + \beta) (\theta^m s_1(X) + \theta^{m-1} s_2(X) + ... + s_m(X) + \gamma)
|
||||||
let left = self.product_eval
|
let left = self.product_eval
|
||||||
* &(self.permuted_input_eval + &beta)
|
* &(self.permuted_input_eval + &beta)
|
||||||
* &(self.permuted_table_eval + &gamma);
|
* &(self.permuted_table_eval + &gamma);
|
||||||
|
|
@ -94,13 +92,15 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
)
|
)
|
||||||
.chain(
|
.chain(
|
||||||
// z'(X) (a'(X) + \beta) (s'(X) + \gamma)
|
// z'(X) (a'(X) + \beta) (s'(X) + \gamma)
|
||||||
// - z'(\omega^{-1} X) (a_1(X) + \theta a_2(X) + ... + \beta) (s_1(X) + \theta s_2(X) + ... + \gamma)
|
// - z'(\omega^{-1} X) (\theta^m a_1(X) + \theta^{m-1} a_2(X) + ... + a_m(X) + \beta) (\theta^m s_1(X) + \theta^{m-1} s_2(X) + ... + s_m(X) + \gamma)
|
||||||
Some(product_expression()),
|
Some(product_expression()),
|
||||||
)
|
)
|
||||||
.chain(Some(
|
.chain(Some(
|
||||||
|
// l_0(X) * (a'(X) - s'(X)) = 0
|
||||||
l_0 * &(self.permuted_input_eval - &self.permuted_table_eval),
|
l_0 * &(self.permuted_input_eval - &self.permuted_table_eval),
|
||||||
))
|
))
|
||||||
.chain(Some(
|
.chain(Some(
|
||||||
|
// (a′(X)−s′(X))⋅(a′(X)−a′(\omega{-1} X)) = 0
|
||||||
(self.permuted_input_eval - &self.permuted_table_eval)
|
(self.permuted_input_eval - &self.permuted_table_eval)
|
||||||
* &(self.permuted_input_eval - &self.permuted_input_inv_eval),
|
* &(self.permuted_input_eval - &self.permuted_input_inv_eval),
|
||||||
))
|
))
|
||||||
|
|
|
||||||
|
|
@ -179,23 +179,21 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
.lookups
|
.lookups
|
||||||
.iter()
|
.iter()
|
||||||
.map(|lookup| {
|
.map(|lookup| {
|
||||||
lookup
|
lookup.commit_permuted(
|
||||||
.commit_permuted(
|
&pk,
|
||||||
&pk,
|
¶ms,
|
||||||
¶ms,
|
&domain,
|
||||||
&domain,
|
theta,
|
||||||
theta,
|
&witness.advice,
|
||||||
&witness.advice,
|
&pk.fixed_values,
|
||||||
&pk.fixed_values,
|
&aux,
|
||||||
&aux,
|
&advice_cosets,
|
||||||
&advice_cosets,
|
&pk.fixed_cosets,
|
||||||
&pk.fixed_cosets,
|
&aux_cosets,
|
||||||
&aux_cosets,
|
&mut transcript,
|
||||||
&mut transcript,
|
)
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
// Sample beta challenge
|
// Sample beta challenge
|
||||||
let beta = ChallengeBeta::get(&mut transcript);
|
let beta = ChallengeBeta::get(&mut transcript);
|
||||||
|
|
@ -220,12 +218,8 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
// Construct and commit to products for each lookup
|
// Construct and commit to products for each lookup
|
||||||
let lookups = lookups
|
let lookups = lookups
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|lookup| {
|
.map(|lookup| lookup.commit_product(&pk, ¶ms, theta, beta, gamma, &mut transcript))
|
||||||
lookup
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
.commit_product(&pk, ¶ms, theta, beta, gamma, &mut transcript)
|
|
||||||
.unwrap()
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
// Obtain challenge for keeping all separate gates linearly independent
|
// Obtain challenge for keeping all separate gates linearly independent
|
||||||
let y = ChallengeY::<C::Scalar>::get(&mut transcript);
|
let y = ChallengeY::<C::Scalar>::get(&mut transcript);
|
||||||
|
|
@ -238,10 +232,14 @@ impl<C: CurveAffine> Proof<C> {
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
// Evaluate the h(X) polynomial's constraint system expressions for the lookup constraints, if any.
|
// Evaluate the h(X) polynomial's constraint system expressions for the lookup constraints, if any.
|
||||||
let (lookups, lookup_expressions): (Vec<_>, Vec<_>) = lookups
|
let (lookups, lookup_expressions): (Vec<_>, Vec<_>) = {
|
||||||
.into_iter()
|
let tmp = lookups
|
||||||
.map(|p| p.construct(pk, theta, beta, gamma).unwrap())
|
.into_iter()
|
||||||
.unzip();
|
.map(|p| p.construct(pk, theta, beta, gamma))
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
|
tmp.into_iter().unzip()
|
||||||
|
};
|
||||||
|
|
||||||
// Evaluate the h(X) polynomial's constraint system expressions for the constraints provided
|
// Evaluate the h(X) polynomial's constraint system expressions for the constraints provided
|
||||||
let h_poly = iter::empty()
|
let h_poly = iter::empty()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue