diff --git a/src/spartan/batched.rs b/src/spartan/batched.rs index baf972652..ebcc5508d 100644 --- a/src/spartan/batched.rs +++ b/src/spartan/batched.rs @@ -434,9 +434,15 @@ impl> BatchedRelaxedR1CSSNARKTrait ) } + let chis_r_x = r_x + .par_iter() + .map(|r_x| EqPolynomial::evals_from_points(r_x)) + .collect::>(); + // Evaluate τ(rₓ) for each instance - let evals_tau = zip_with!(iter, (polys_tau, r_x), |poly_tau, r_x| poly_tau - .evaluate(r_x)); + let evals_tau = zip_with!(iter, (polys_tau, chis_r_x), |poly_tau, er_x| { + MultilinearPolynomial::evaluate_with_chis(poly_tau.evaluations(), er_x) + }); // Compute expected claim for all instances ∑ᵢ rⁱ⋅τ(rₓ)⋅(Azᵢ⋅Bzᵢ − uᵢ⋅Czᵢ − Eᵢ) let claim_outer_final_expected = zip_with!( @@ -503,7 +509,7 @@ impl> BatchedRelaxedR1CSSNARKTrait // compute evaluations of R1CS matrices M(r_x, r_y) = eq(r_y)ᵀ⋅M⋅eq(r_x) let multi_evaluate = |M_vec: &[&SparseMatrix], - r_x: &[E::Scalar], + chi_r_x: &[E::Scalar], r_y: &[E::Scalar]| -> Vec { let evaluate_with_table = @@ -520,21 +526,19 @@ impl> BatchedRelaxedR1CSSNARKTrait .sum() }; - let (T_x, T_y) = rayon::join( - || EqPolynomial::evals_from_points(r_x), - || EqPolynomial::evals_from_points(r_y), - ); + let T_x = chi_r_x; + let T_y = EqPolynomial::evals_from_points(r_y); M_vec .par_iter() - .map(|&M_vec| evaluate_with_table(M_vec, &T_x, &T_y)) + .map(|&M_vec| evaluate_with_table(M_vec, T_x, &T_y)) .collect() }; // Compute inner claim ∑ᵢ r³ⁱ⋅(Aᵢ(r_x, r_y) + r⋅Bᵢ(r_x, r_y) + r²⋅Cᵢ(r_x, r_y))⋅Zᵢ(r_y) let claim_inner_final_expected = zip_with!( iter, - (vk.S, r_x, r_y, evals_Z, inner_r_powers), + (vk.S, chis_r_x, r_y, evals_Z, inner_r_powers), |S, r_x, r_y, eval_Z, r_i| { let evals = multi_evaluate(&[&S.A, &S.B, &S.C], r_x, r_y); let eval = evals[0] + inner_r * evals[1] + inner_r_square * evals[2]; diff --git a/src/spartan/polys/multilinear.rs b/src/spartan/polys/multilinear.rs index 9a995982a..bdb18e06f 100644 --- a/src/spartan/polys/multilinear.rs +++ b/src/spartan/polys/multilinear.rs @@ -116,11 +116,7 @@ impl MultilinearPolynomial { /// Evaluates the polynomial with the given evaluations and chi coefficients pub fn evaluate_with_chis(Z: &[Scalar], chis: &[Scalar]) -> Scalar { - zip_with!( - (chis.into_par_iter(), Z.par_iter()), - |a, b| *a * b - ) - .sum() + zip_with!(par_iter, (chis, Z), |a, b| *a * b).sum() } } diff --git a/src/supernova/circuit.rs b/src/supernova/circuit.rs index 5e1be44f5..2a1d3209b 100644 --- a/src/supernova/circuit.rs +++ b/src/supernova/circuit.rs @@ -1,6 +1,6 @@ //! Supernova implementation support arbitrary argumented circuits and running instances. //! There are two Verification Circuits for each argumented circuit: The primary and the secondary. -//! Each of them is over a Pasta curve but +//! Each of them is over a cycle curve but //! only the primary executes the next step of the computation. //! Each circuit takes as input 2 hashes. //! Each circuit folds the last invocation of the other into the respective running instance, specified by `augmented_circuit_index` @@ -10,7 +10,7 @@ //! 1. Ui[] are contained in X[0] hash pre-image. //! 2. R1CS Instance u is folded into Ui[augmented_circuit_index] correctly; just like Nova IVC. //! 3. (optional by F logic) F circuit might check `program_counter_{i}` invoked current F circuit is legal or not. -//! 3. F circuit produce `program_counter_{i+1}` and sent to next round for optionally constraint the next F' argumented circuit. +//! 3. F circuit produce `program_counter_{i+1}` and sent to next round to optionally constraint the next F' argumented circuit. use crate::{ constants::{NIO_NOVA_FOLD, NUM_HASH_BITS}, gadgets::{ diff --git a/src/supernova/utils.rs b/src/supernova/utils.rs index af4c4d330..ec36281ea 100644 --- a/src/supernova/utils.rs +++ b/src/supernova/utils.rs @@ -37,6 +37,7 @@ pub fn get_from_vec_alloc_relaxed_r1cs