From 3ded9893a92cc78bcb6a5089c4416a767d8de73e Mon Sep 17 00:00:00 2001 From: amit0365 Date: Thu, 17 Aug 2023 03:17:11 +0530 Subject: [PATCH 01/14] init sqrt --- .../src/accumulation/protostar.rs | 22 +++++ .../src/accumulation/protostar/hyperplonk.rs | 86 ++++++++++++++++++- .../protostar/hyperplonk/prover.rs | 2 +- 3 files changed, 108 insertions(+), 2 deletions(-) diff --git a/plonkish_backend/src/accumulation/protostar.rs b/plonkish_backend/src/accumulation/protostar.rs index 7a7a6530..44ab42bc 100644 --- a/plonkish_backend/src/accumulation/protostar.rs +++ b/plonkish_backend/src/accumulation/protostar.rs @@ -172,6 +172,28 @@ where .for_each(|(power_of_r, poly)| self.e_poly += (&power_of_r, poly)); } + fn fold_compressed_sqrt( + &mut self, + rhs: &Self, + zeta_cross_term_poly: &Pcs::Polynomial, + zeta_cross_term_comm: &Pcs::Commitment, + compressed_cross_term_sums: &[F], + r: &F, + ) where + Pcs::Commitment: AdditiveCommitment, + { + self.instance.fold_compressed_sqrt( + &rhs.instance, + zeta_cross_term_comm, + compressed_cross_term_sums, + r, + ); + izip_eq!(&mut self.witness_polys, &rhs.witness_polys) + .for_each(|(lhs, rhs)| *lhs += (r, rhs)); + izip!(powers(*r).skip(1), [zeta_cross_term_poly, &rhs.e_poly]) + .for_each(|(power_of_r, poly)| self.e_poly += (&power_of_r, poly)); + } + pub fn instance(&self) -> &ProtostarAccumulatorInstance { &self.instance } diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs index 04992878..45e7463d 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs @@ -10,7 +10,7 @@ use crate::{ }, ivc::ProtostarAccumulationVerifierParam, Protostar, ProtostarAccumulator, ProtostarAccumulatorInstance, ProtostarProverParam, - ProtostarStrategy::{Compressing, NoCompressing}, + ProtostarStrategy::{Compressing, NoCompressing, CompressingWithSqrtPowers}, ProtostarVerifierParam, }, AccumulationScheme, PlonkishNark, PlonkishNarkInstance, @@ -197,6 +197,24 @@ where let powers_of_zeta_poly = powers_of_zeta_poly(pp.num_vars, zeta); end_timer(timer); + let powers_of_zeta_comm = + Pcs::commit_and_write(&pp.pcs, &powers_of_zeta_poly, transcript)?; + + ( + Some(zeta), + Some(powers_of_zeta_poly), + Some(powers_of_zeta_comm), + ) + }, + CompressingWithSqrtPowers => { + assert_eq!((pp.num_vars as f64).sqrt().fract(), 0.0, "The number is not a perfect square"); + + let zeta = transcript.squeeze_challenge(); + + let timer = start_timer(|| "powers_of_zeta_sqrt_poly"); + let powers_of_zeta_poly = powers_of_zeta_poly(pp.num_vars, zeta); + end_timer(timer); + let powers_of_zeta_comm = Pcs::commit_and_write(&pp.pcs, &powers_of_zeta_poly, transcript)?; @@ -316,6 +334,47 @@ where let r = transcript.squeeze_challenge(); + let timer = start_timer(|| "fold_compressed"); + accumulator.fold_compressed( + incoming, + &zeta_cross_term_poly, + &zeta_cross_term_comm, + &compressed_cross_term_sums, + &r, + ); + end_timer(timer); + } + CompressingWithSqrtPowers => { + let timer = start_timer(|| "evaluate_zeta_cross_term_poly"); + let zeta_cross_term_poly = evaluate_zeta_cross_term_poly( + pp.num_vars, + *num_alpha_primes, + accumulator, + incoming, + ); + end_timer(timer); + + let timer = start_timer(|| { + let len = cross_term_expressions.len(); + format!("evaluate_compressed_cross_term_sums-{len}") + }); + let compressed_cross_term_sums = evaluate_compressed_cross_term_sums( + cross_term_expressions, + pp.num_vars, + &pp.preprocess_polys, + accumulator, + incoming, + ); + end_timer(timer); + + let zeta_cross_term_comm = + Pcs::commit_and_write(&pp.pcs, &zeta_cross_term_poly, transcript)?; + transcript.write_field_elements(&compressed_cross_term_sums)?; + + // Round 0 + + let r = transcript.squeeze_challenge(); + let timer = start_timer(|| "fold_compressed"); accumulator.fold_compressed( incoming, @@ -390,6 +449,13 @@ where let powers_of_zeta_comm = Pcs::read_commitment(&vp.pcs, transcript)?; + (Some(zeta), Some(powers_of_zeta_comm)) + }, + CompressingWithSqrtPowers => { + let zeta = transcript.squeeze_challenge(); + + let powers_of_zeta_comm = Pcs::read_commitment(&vp.pcs, transcript)?; + (Some(zeta), Some(powers_of_zeta_comm)) } }; @@ -440,6 +506,22 @@ where let r = transcript.squeeze_challenge(); + accumulator.fold_compressed( + &incoming, + &zeta_cross_term_comm, + &compressed_cross_term_sums, + &r, + ); + } + CompressingWithSqrtPowers => { + let zeta_cross_term_comm = Pcs::read_commitment(&vp.pcs, transcript)?; + let compressed_cross_term_sums = + transcript.read_field_elements(*num_cross_terms)?; + + // Round n+4 + + let r = transcript.squeeze_challenge(); + accumulator.fold_compressed( &incoming, &zeta_cross_term_comm, @@ -609,6 +691,7 @@ where .chain(match vp.strategy { NoCompressing => None, Compressing => Some(1), + CompressingWithSqrtPowers => Some(1), }) .collect(); let num_challenges = { @@ -623,6 +706,7 @@ where .chain(match vp.strategy { NoCompressing => None, Compressing => Some(vec![1]), + CompressingWithSqrtPowers => Some(vec![1]), }) .chain([vec![vp.num_alpha_primes]]) .collect() diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs index 6fcf02b5..95109fc9 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs @@ -75,7 +75,7 @@ pub(super) fn powers_of_zeta_poly( num_vars: usize, zeta: F, ) -> MultilinearPolynomial { - let powers_of_zeta = powers(zeta).take(1 << num_vars).collect_vec(); + let powers_of_zeta: Vec = powers(zeta).take(1 << num_vars).collect_vec(); let nth_map = BooleanHypercube::new(num_vars).nth_map(); MultilinearPolynomial::new(par_map_collect(&nth_map, |b| powers_of_zeta[*b])) } From 379912b2e4ebfc656ea2efc49ee0a22d80e030cf Mon Sep 17 00:00:00 2001 From: amit0365 Date: Fri, 18 Aug 2023 04:36:47 +0530 Subject: [PATCH 02/14] added sqrt --- .../src/accumulation/protostar.rs | 34 +++---------------- .../src/accumulation/protostar/hyperplonk.rs | 15 +++++--- 2 files changed, 15 insertions(+), 34 deletions(-) diff --git a/plonkish_backend/src/accumulation/protostar.rs b/plonkish_backend/src/accumulation/protostar.rs index 44ab42bc..556336d4 100644 --- a/plonkish_backend/src/accumulation/protostar.rs +++ b/plonkish_backend/src/accumulation/protostar.rs @@ -1,6 +1,6 @@ use crate::{ accumulation::{ - protostar::ProtostarStrategy::{Compressing, NoCompressing}, + protostar::ProtostarStrategy::{Compressing, NoCompressing, CompressingWithSqrtPowers}, PlonkishNark, PlonkishNarkInstance, }, backend::PlonkishBackend, @@ -33,12 +33,12 @@ pub enum ProtostarStrategy { Compressing = 1, // TODO: // Compressing verification with square-root optimization applied as described in 2023/620 section 3.5 - // CompressingWithSqrtPowers = 3, + CompressingWithSqrtPowers = 3, } impl From for ProtostarStrategy { fn from(strategy: usize) -> Self { - [NoCompressing, Compressing][strategy] + [NoCompressing, Compressing, CompressingWithSqrtPowers][strategy] } } @@ -171,32 +171,6 @@ where izip!(powers(*r).skip(1), [zeta_cross_term_poly, &rhs.e_poly]) .for_each(|(power_of_r, poly)| self.e_poly += (&power_of_r, poly)); } - - fn fold_compressed_sqrt( - &mut self, - rhs: &Self, - zeta_cross_term_poly: &Pcs::Polynomial, - zeta_cross_term_comm: &Pcs::Commitment, - compressed_cross_term_sums: &[F], - r: &F, - ) where - Pcs::Commitment: AdditiveCommitment, - { - self.instance.fold_compressed_sqrt( - &rhs.instance, - zeta_cross_term_comm, - compressed_cross_term_sums, - r, - ); - izip_eq!(&mut self.witness_polys, &rhs.witness_polys) - .for_each(|(lhs, rhs)| *lhs += (r, rhs)); - izip!(powers(*r).skip(1), [zeta_cross_term_poly, &rhs.e_poly]) - .for_each(|(power_of_r, poly)| self.e_poly += (&power_of_r, poly)); - } - - pub fn instance(&self) -> &ProtostarAccumulatorInstance { - &self.instance - } } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -237,6 +211,7 @@ where compressed_e_sum: match strategy { NoCompressing => None, Compressing => Some(F::ZERO), + CompressingWithSqrtPowers => Some(F::ZERO), }, } } @@ -277,6 +252,7 @@ where compressed_e_sum: match strategy { NoCompressing => None, Compressing => Some(F::ZERO), + CompressingWithSqrtPowers => Some(F::ZERO), }, } } diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs index 45e7463d..1d54666c 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs @@ -207,12 +207,16 @@ where ) }, CompressingWithSqrtPowers => { - assert_eq!((pp.num_vars as f64).sqrt().fract(), 0.0, "The number is not a perfect square"); + assert_eq!((2**pp.num_vars as f64).sqrt().fract(), 0.0, "The number is not a perfect square"); let zeta = transcript.squeeze_challenge(); + // check if this is optimal let timer = start_timer(|| "powers_of_zeta_sqrt_poly"); - let powers_of_zeta_poly = powers_of_zeta_poly(pp.num_vars, zeta); + let l_sqrt = (2**pp.num_vars as f64).sqrt(); + let powers_of_zeta_first_poly = powers_of_zeta_poly((l_sqrt-1).log2(), zeta); + let powers_of_zeta_second_poly = powers_of_zeta_poly((l_sqrt-1).log2(), zeta**l_sqrt); + let powers_of_zeta_poly = powers_of_zeta_first_poly.add(powers_of_zeta_second_poly); end_timer(timer); let powers_of_zeta_comm = @@ -346,8 +350,9 @@ where } CompressingWithSqrtPowers => { let timer = start_timer(|| "evaluate_zeta_cross_term_poly"); + let l_sqrt = (2**pp.num_vars as f64).sqrt(); let zeta_cross_term_poly = evaluate_zeta_cross_term_poly( - pp.num_vars, + 2*l_sqrt, *num_alpha_primes, accumulator, incoming, @@ -360,7 +365,7 @@ where }); let compressed_cross_term_sums = evaluate_compressed_cross_term_sums( cross_term_expressions, - pp.num_vars, + 2*l_sqrt, &pp.preprocess_polys, accumulator, incoming, @@ -375,7 +380,7 @@ where let r = transcript.squeeze_challenge(); - let timer = start_timer(|| "fold_compressed"); + let timer = start_timer(|| "fold_compressed_sqrt"); accumulator.fold_compressed( incoming, &zeta_cross_term_poly, From 4d251bb8e1159b6b4fce0a8124782a9c36955679 Mon Sep 17 00:00:00 2001 From: amit0365 Date: Sun, 20 Aug 2023 01:32:19 +0530 Subject: [PATCH 03/14] up --- .../src/accumulation/protostar/hyperplonk/preprocessor.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs index 1ca692ca..3a7b82a9 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs @@ -40,6 +40,9 @@ pub(crate) fn batch_size( Compressing => { vec![1] } + CompressingWithSqrtPowers => { + vec![1] + } }, [2 * num_lookups + div_ceil(num_permutation_polys, max_degree(circuit_info, None) - 1)], [1], From 73013c75542c7f2411fd262196637695af9aebcb Mon Sep 17 00:00:00 2001 From: amit0365 Date: Sun, 20 Aug 2023 19:10:18 +0530 Subject: [PATCH 04/14] review1 sqrt --- .../src/accumulation/protostar/hyperplonk.rs | 6 +- .../protostar/hyperplonk/preprocessor.rs | 89 ++++++++++++++++++- .../src/accumulation/protostar/ivc/halo2.rs | 34 ++++++- 3 files changed, 124 insertions(+), 5 deletions(-) diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs index 1d54666c..5f109e95 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs @@ -207,13 +207,13 @@ where ) }, CompressingWithSqrtPowers => { - assert_eq!((2**pp.num_vars as f64).sqrt().fract(), 0.0, "The number is not a perfect square"); + assert_eq!((2**pp.num_vars as f64).sqrt().fract(), 0.0, "L is not a perfect square"); let zeta = transcript.squeeze_challenge(); // check if this is optimal let timer = start_timer(|| "powers_of_zeta_sqrt_poly"); - let l_sqrt = (2**pp.num_vars as f64).sqrt(); + let l_sqrt = (2**pp.num_vars as f64).sqrt() as usize; let powers_of_zeta_first_poly = powers_of_zeta_poly((l_sqrt-1).log2(), zeta); let powers_of_zeta_second_poly = powers_of_zeta_poly((l_sqrt-1).log2(), zeta**l_sqrt); let powers_of_zeta_poly = powers_of_zeta_first_poly.add(powers_of_zeta_second_poly); @@ -350,7 +350,7 @@ where } CompressingWithSqrtPowers => { let timer = start_timer(|| "evaluate_zeta_cross_term_poly"); - let l_sqrt = (2**pp.num_vars as f64).sqrt(); + let l_sqrt = (2**pp.num_vars as f64).sqrt() as usize; let zeta_cross_term_poly = evaluate_zeta_cross_term_poly( 2*l_sqrt, *num_alpha_primes, diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs index 3a7b82a9..da007028 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs @@ -1,7 +1,7 @@ use crate::{ accumulation::protostar::{ ProtostarProverParam, ProtostarStrategy, - ProtostarStrategy::{Compressing, NoCompressing}, + ProtostarStrategy::{Compressing, NoCompressing, CompressingWithSqrtPowers}, ProtostarVerifierParam, }, backend::{ @@ -233,6 +233,93 @@ where - Expression::Polynomial(Query::new(e, Rotation::cur())) }; + ( + num_builtin_witness_polys, + alpha_prime_offset, + cross_term_expressions, + Some(relexed_compressed_constraint), + relexed_zeta_constraint, + ) + } + CompressingWithSqrtPowers => { + let zeta = challenge_offset + num_theta_primes + 1; + let alpha_prime_offset = zeta + 1; + let num_builtin_witness_polys = 3 * circuit_info.lookups.len() + 1; + let builtin_witness_poly_offset = + witness_poly_offset + num_witness_polys + circuit_info.permutation_polys().len(); + + let poly_set = PolynomialSet { + preprocess: iter::empty() + .chain( + (circuit_info.num_instances.len()..) + .take(circuit_info.preprocess_polys.len()), + ) + .collect(), + folding: iter::empty() + .chain(0..circuit_info.num_instances.len()) + .chain((witness_poly_offset..).take(num_witness_polys)) + .chain((builtin_witness_poly_offset..).take(num_builtin_witness_polys)) + .collect(), + }; + + let powers_of_zeta = builtin_witness_poly_offset + circuit_info.lookups.len() * 3; + assert_eq!((powers_of_zeta as f64).sqrt().fract(), 0.0, "L is not a perfect square"); + let l_sqrt = (powers_of_zeta as f64).sqrt() as usize; + let powers_of_zeta_sqrt = l_sqrt - 1; + let compressed_products = { + let mut constraints = iter::empty() + .chain(circuit_info.constraints.iter()) + .chain(lookup_constraints.iter()) + .collect_vec(); + let folding_degrees = constraints + .iter() + .map(|constraint| folding_degree(&poly_set.preprocess, constraint)) + .enumerate() + .sorted_by(|a, b| b.1.cmp(&a.1)) + .collect_vec(); + if let &[a, b, ..] = &folding_degrees[..] { + if a.1 != b.1 { + constraints.swap(0, a.0); + } + } + let powers_of_zeta_sqrt = + Expression::::Polynomial(Query::new(powers_of_zeta_sqrt, Rotation::cur())); + let compressed_constraint = iter::empty() + .chain(constraints.first().cloned().cloned()) + .chain( + constraints + .into_iter() + .skip(1) + .zip((alpha_prime_offset..).map(Expression::Challenge)) + .map(|(constraint, challenge)| constraint * challenge), + ) + .sum::>() + * powers_of_zeta_sqrt; + products(&poly_set.preprocess, &compressed_constraint) + }; + let powers_of_zeta_sqrt1_constraint = powers_of_zeta_constraint(zeta, powers_of_zeta_sqrt); + let zeta_sqrt1_products = products(&poly_set.preprocess, &powers_of_zeta_sqrt1_constraint); + + let powers_of_zeta_sqrt2_constraint = powers_of_zeta_constraint(zeta**l_sqrt, powers_of_zeta_sqrt); + let zeta_sqrt2_products = products(&poly_set.preprocess, &powers_of_zeta_sqrt2_constraint); + + let zeta_products = iter::empty() + .chain(*zeta_sqrt1_products.iter()) + .chain(*zeta_sqrt2_products.iter()) + .collect_vec(); + + let num_folding_challenges = alpha_prime_offset + num_alpha_primes; + let cross_term_expressions = + cross_term_expressions(&poly_set, &compressed_products, num_folding_challenges); + + let u = num_folding_challenges; + let relexed_compressed_constraint = relaxed_expression(&compressed_products, u); + let relexed_zeta_constraint = { + let e = powers_of_zeta + num_permutation_z_polys + 1; + relaxed_expression(&zeta_products, u) + - Expression::Polynomial(Query::new(e, Rotation::cur())) + }; + ( num_builtin_witness_polys, alpha_prime_offset, diff --git a/plonkish_backend/src/accumulation/protostar/ivc/halo2.rs b/plonkish_backend/src/accumulation/protostar/ivc/halo2.rs index b165bbd1..941e8f13 100644 --- a/plonkish_backend/src/accumulation/protostar/ivc/halo2.rs +++ b/plonkish_backend/src/accumulation/protostar/ivc/halo2.rs @@ -4,7 +4,7 @@ use crate::{ ivc::ProtostarAccumulationVerifierParam, PlonkishNarkInstance, Protostar, ProtostarAccumulator, ProtostarAccumulatorInstance, ProtostarProverParam, - ProtostarStrategy::{Compressing, NoCompressing}, + ProtostarStrategy::{Compressing, NoCompressing, CompressingWithSqrtPowers}, ProtostarVerifierParam, }, AccumulationScheme, @@ -437,6 +437,7 @@ pub trait TranscriptInstruction: Debug { + match avp.strategy { NoCompressing => avp.num_cross_terms * uncompressed_comm_size, Compressing => uncompressed_comm_size + avp.num_cross_terms * scalar_size, + CompressingWithSqrtPowers => uncompressed_comm_size + avp.num_cross_terms * scalar_size, }; vec![0; proof_size] } @@ -625,6 +626,7 @@ where let compressed_e_sum = match self.avp.strategy { NoCompressing => None, Compressing => Some(tcc_chip.assign_constant_base(layouter, C::Base::ZERO)?), + CompressingWithSqrtPowers => Some(tcc_chip.assign_constant_base(layouter, C::Base::ZERO)?), }; Ok(ProtostarAccumulatorInstance { @@ -683,6 +685,10 @@ where tcc_chip .assign_witness_base(layouter, acc.map(|acc| acc.compressed_e_sum.unwrap()))?, ), + CompressingWithSqrtPowers => Some( + tcc_chip + .assign_witness_base(layouter, acc.map(|acc| acc.compressed_e_sum.unwrap()))?, + ), }; Ok(ProtostarAccumulatorInstance { @@ -715,6 +721,7 @@ where let compressed_e_sum = match self.avp.strategy { NoCompressing => None, Compressing => Some(tcc_chip.assign_constant_base(layouter, C::Base::ZERO)?), + CompressingWithSqrtPowers => Some(tcc_chip.assign_constant_base(layouter, C::Base::ZERO)?), }; Ok(ProtostarAccumulatorInstance { @@ -792,6 +799,13 @@ where (zeta_cross_term_comm, Some(compressed_cross_term_sums)) } + CompressingWithSqrtPowers => { + let zeta_cross_term_comm = vec![transcript.read_commitment(layouter)?]; + let compressed_cross_term_sums = + transcript.read_field_elements(layouter, *num_cross_terms)?; + + (zeta_cross_term_comm, Some(compressed_cross_term_sums)) + } }; let r = transcript.squeeze_challenge(layouter)?; @@ -908,6 +922,18 @@ where &rhs, )?) } + CompressingWithSqrtPowers => { + let rhs = tcc_chip.inner_product_base( + layouter, + &powers_of_r[1..], + compressed_cross_term_sums.unwrap(), + )?; + Some(tcc_chip.add_base( + layouter, + acc.compressed_e_sum.as_ref().unwrap(), + &rhs, + )?) + } }; ProtostarAccumulatorInstance { @@ -975,6 +1001,12 @@ where when_true.compressed_e_sum.as_ref().unwrap(), when_false.compressed_e_sum.as_ref().unwrap(), )?), + CompressingWithSqrtPowers => Some(tcc_chip.select_base( + layouter, + condition, + when_true.compressed_e_sum.as_ref().unwrap(), + when_false.compressed_e_sum.as_ref().unwrap(), + )?), }; Ok(ProtostarAccumulatorInstance { From cb8c7e971a5cd2c3e9eaec5236f6eeb943a34d95 Mon Sep 17 00:00:00 2001 From: amit0365 Date: Sun, 20 Aug 2023 19:35:29 +0530 Subject: [PATCH 05/14] review1 sqrt fixed --- plonkish_backend/src/accumulation/protostar.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plonkish_backend/src/accumulation/protostar.rs b/plonkish_backend/src/accumulation/protostar.rs index 556336d4..97760b44 100644 --- a/plonkish_backend/src/accumulation/protostar.rs +++ b/plonkish_backend/src/accumulation/protostar.rs @@ -169,8 +169,12 @@ where izip_eq!(&mut self.witness_polys, &rhs.witness_polys) .for_each(|(lhs, rhs)| *lhs += (r, rhs)); izip!(powers(*r).skip(1), [zeta_cross_term_poly, &rhs.e_poly]) - .for_each(|(power_of_r, poly)| self.e_poly += (&power_of_r, poly)); + .for_each(|(power_of_r, poly)| self.e_poly += (&power_of_r, poly)); } + + pub fn instance(&self) -> &ProtostarAccumulatorInstance { + &self.instance + } } #[derive(Clone, Debug, Serialize, Deserialize)] From 4d13762f4cf1cb640259e567e7f41c47f0711d0b Mon Sep 17 00:00:00 2001 From: amit0365 Date: Sun, 20 Aug 2023 20:44:01 +0530 Subject: [PATCH 06/14] review1 sqrt fix --- .../src/accumulation/protostar/hyperplonk.rs | 16 ++++++++-------- .../protostar/hyperplonk/preprocessor.rs | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs index 5f109e95..bd5662a0 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs @@ -41,6 +41,7 @@ use std::{borrow::BorrowMut, hash::Hash, iter}; mod preprocessor; mod prover; +use std::ops::Add; impl AccumulationScheme for Protostar, STRATEGY> where @@ -207,16 +208,15 @@ where ) }, CompressingWithSqrtPowers => { - assert_eq!((2**pp.num_vars as f64).sqrt().fract(), 0.0, "L is not a perfect square"); - + assert_eq!((2.0f64.powf(pp.num_vars as f64)).sqrt().fract(), 0.0, "L is not a perfect square"); let zeta = transcript.squeeze_challenge(); // check if this is optimal let timer = start_timer(|| "powers_of_zeta_sqrt_poly"); - let l_sqrt = (2**pp.num_vars as f64).sqrt() as usize; - let powers_of_zeta_first_poly = powers_of_zeta_poly((l_sqrt-1).log2(), zeta); - let powers_of_zeta_second_poly = powers_of_zeta_poly((l_sqrt-1).log2(), zeta**l_sqrt); - let powers_of_zeta_poly = powers_of_zeta_first_poly.add(powers_of_zeta_second_poly); + let l_sqrt = (2.0f64.powf(pp.num_vars as f64)).sqrt() as usize; + let powers_of_zeta_first_poly = powers_of_zeta_poly((l_sqrt-1).ilog2() as usize, zeta); + let powers_of_zeta_second_poly = powers_of_zeta_poly((l_sqrt-1).ilog2() as usize, zeta.pow(&[l_sqrt as u64])); + let powers_of_zeta_poly = powers_of_zeta_first_poly.add(&powers_of_zeta_second_poly); end_timer(timer); let powers_of_zeta_comm = @@ -350,9 +350,9 @@ where } CompressingWithSqrtPowers => { let timer = start_timer(|| "evaluate_zeta_cross_term_poly"); - let l_sqrt = (2**pp.num_vars as f64).sqrt() as usize; + let l_sqrt = (2.0f64.powf(pp.num_vars as f64)).sqrt() as usize; let zeta_cross_term_poly = evaluate_zeta_cross_term_poly( - 2*l_sqrt, + l_sqrt * l_sqrt, *num_alpha_primes, accumulator, incoming, diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs index da007028..583ab54f 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs @@ -300,12 +300,12 @@ where let powers_of_zeta_sqrt1_constraint = powers_of_zeta_constraint(zeta, powers_of_zeta_sqrt); let zeta_sqrt1_products = products(&poly_set.preprocess, &powers_of_zeta_sqrt1_constraint); - let powers_of_zeta_sqrt2_constraint = powers_of_zeta_constraint(zeta**l_sqrt, powers_of_zeta_sqrt); + let powers_of_zeta_sqrt2_constraint = powers_of_zeta_constraint(zeta.pow(l_sqrt as u32), powers_of_zeta_sqrt); let zeta_sqrt2_products = products(&poly_set.preprocess, &powers_of_zeta_sqrt2_constraint); let zeta_products = iter::empty() - .chain(*zeta_sqrt1_products.iter()) - .chain(*zeta_sqrt2_products.iter()) + .chain(zeta_sqrt1_products.iter().cloned()) + .chain(zeta_sqrt2_products.iter().cloned()) .collect_vec(); let num_folding_challenges = alpha_prime_offset + num_alpha_primes; From ce7d71d5fe6f6af26b44ff30128114b8326fce38 Mon Sep 17 00:00:00 2001 From: amit0365 Date: Sun, 1 Oct 2023 17:42:31 -0400 Subject: [PATCH 07/14] replace add with concat --- plonkish_backend/src/accumulation/protostar/hyperplonk.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs index bd5662a0..af19e03a 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs @@ -216,7 +216,8 @@ where let l_sqrt = (2.0f64.powf(pp.num_vars as f64)).sqrt() as usize; let powers_of_zeta_first_poly = powers_of_zeta_poly((l_sqrt-1).ilog2() as usize, zeta); let powers_of_zeta_second_poly = powers_of_zeta_poly((l_sqrt-1).ilog2() as usize, zeta.pow(&[l_sqrt as u64])); - let powers_of_zeta_poly = powers_of_zeta_first_poly.add(&powers_of_zeta_second_poly); + let powers_of_zeta_poly = MultilinearPolynomial::new(powers_of_zeta_first_poly.evals().iter() + .chain(powers_of_zeta_second_poly.evals().iter()).cloned().collect()); end_timer(timer); let powers_of_zeta_comm = From 858a4cf80f3b374cc5562aee98510d2967e4df1a Mon Sep 17 00:00:00 2001 From: amit0365 Date: Fri, 6 Oct 2023 22:23:00 -0400 Subject: [PATCH 08/14] fix eval_zeta_cross_term_poly --- .../src/accumulation/protostar.rs | 4 +- .../src/accumulation/protostar/hyperplonk.rs | 21 +++--- .../protostar/hyperplonk/prover.rs | 73 ++++++++++++++++++- 3 files changed, 82 insertions(+), 16 deletions(-) diff --git a/plonkish_backend/src/accumulation/protostar.rs b/plonkish_backend/src/accumulation/protostar.rs index 97760b44..b5f1e039 100644 --- a/plonkish_backend/src/accumulation/protostar.rs +++ b/plonkish_backend/src/accumulation/protostar.rs @@ -172,9 +172,9 @@ where .for_each(|(power_of_r, poly)| self.e_poly += (&power_of_r, poly)); } - pub fn instance(&self) -> &ProtostarAccumulatorInstance { + pub fn instance(&self) -> &ProtostarAccumulatorInstance { &self.instance - } + } } #[derive(Clone, Debug, Serialize, Deserialize)] diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs index af19e03a..c7ac20b0 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs @@ -5,7 +5,7 @@ use crate::{ preprocessor::{batch_size, preprocess}, prover::{ evaluate_compressed_cross_term_sums, evaluate_cross_term_polys, - evaluate_zeta_cross_term_poly, lookup_h_polys, powers_of_zeta_poly, + evaluate_zeta_cross_term_poly,evaluate_zeta_root_cross_term_poly, lookup_h_polys, powers_of_zeta_poly, }, }, ivc::ProtostarAccumulationVerifierParam, @@ -208,16 +208,14 @@ where ) }, CompressingWithSqrtPowers => { - assert_eq!((2.0f64.powf(pp.num_vars as f64)).sqrt().fract(), 0.0, "L is not a perfect square"); + assert_eq!(pp.num_vars % 2, 0, "L is not a perfect square"); let zeta = transcript.squeeze_challenge(); + let l_sqrt = (1 << (pp.num_vars / 2)); - // check if this is optimal let timer = start_timer(|| "powers_of_zeta_sqrt_poly"); - let l_sqrt = (2.0f64.powf(pp.num_vars as f64)).sqrt() as usize; - let powers_of_zeta_first_poly = powers_of_zeta_poly((l_sqrt-1).ilog2() as usize, zeta); - let powers_of_zeta_second_poly = powers_of_zeta_poly((l_sqrt-1).ilog2() as usize, zeta.pow(&[l_sqrt as u64])); - let powers_of_zeta_poly = MultilinearPolynomial::new(powers_of_zeta_first_poly.evals().iter() - .chain(powers_of_zeta_second_poly.evals().iter()).cloned().collect()); + let powers_of_zeta_first_poly = powers_of_zeta_poly(pp.num_vars/2, zeta); + let powers_of_zeta_second_poly = powers_of_zeta_poly(pp.num_vars/2, zeta.pow(l_sqrt as u64)); + let powers_of_zeta_poly = MultilinearPolynomial::new(powers_of_zeta_first_poly.evals().iter().chain(powers_of_zeta_second_poly.evals().iter()).cloned().collect()); end_timer(timer); let powers_of_zeta_comm = @@ -351,9 +349,8 @@ where } CompressingWithSqrtPowers => { let timer = start_timer(|| "evaluate_zeta_cross_term_poly"); - let l_sqrt = (2.0f64.powf(pp.num_vars as f64)).sqrt() as usize; - let zeta_cross_term_poly = evaluate_zeta_cross_term_poly( - l_sqrt * l_sqrt, + let zeta_cross_term_poly = evaluate_zeta_root_cross_term_poly( + pp.num_vars, *num_alpha_primes, accumulator, incoming, @@ -366,7 +363,7 @@ where }); let compressed_cross_term_sums = evaluate_compressed_cross_term_sums( cross_term_expressions, - 2*l_sqrt, + pp.num_vars, &pp.preprocess_polys, accumulator, incoming, diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs index 95109fc9..6705f60b 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs @@ -2,7 +2,7 @@ use crate::{ accumulation::protostar::ProtostarAccumulator, backend::hyperplonk::prover::instance_polys, pcs::PolynomialCommitmentScheme, - poly::multilinear::MultilinearPolynomial, + poly::{multilinear::MultilinearPolynomial, Polynomial}, util::{ arithmetic::{div_ceil, powers, sum, BatchInvert, BooleanHypercube, PrimeField}, expression::{evaluator::ExpressionRegistry, Expression, Rotation}, @@ -207,7 +207,7 @@ where .zip(start..) .for_each(|(cross_term, b)| { *cross_term = acc_pow[next_map[b]] + acc_u * incoming_pow[next_map[b]] - - (acc_pow[b] * incoming_zeta + incoming_pow[b] * acc_zeta); + - (acc_pow[b] * incoming_zeta + incoming_pow[b] * acc_zeta); }) }); let b_0 = 0; @@ -220,6 +220,75 @@ where MultilinearPolynomial::new(cross_term) } +pub(crate) fn evaluate_zeta_root_cross_term_poly( + num_vars: usize, + zeta_nth_back: usize, + accumulator: &ProtostarAccumulator, + incoming: &ProtostarAccumulator, +) -> MultilinearPolynomial +where + F: PrimeField, + Pcs: PolynomialCommitmentScheme>, +{ + let [(acc_pow, acc_zeta, acc_u), (incoming_pow, incoming_zeta, incoming_u)] = + [accumulator, incoming].map(|witness| { + let pow = witness.witness_polys.last().unwrap(); + let zeta = witness + .instance + .challenges + .iter() + .nth_back(zeta_nth_back) + .unwrap(); + (pow, zeta, witness.instance.u) + }); + assert_eq!(incoming_u, F::ONE); + + let size = 2*(1 << num_vars/2); + let mut cross_term = vec![F::ZERO; size]; + + let l_sqrt = 1usize << num_vars/2; + let incoming_zeta_sqrt = (powers(incoming_zeta).nth(l_sqrt).unwrap()); + let acc_zeta_sqrt = (powers(acc_zeta).nth(l_sqrt).unwrap()); + + let bh = BooleanHypercube::new(num_vars); + let next_map = bh.rotation_map(Rotation::next()); + parallelize(&mut cross_term, |(cross_term, start)| { + cross_term + .iter_mut() + .zip(start..) + .for_each(|(cross_term, b)| { + if b < l_sqrt { + *cross_term = acc_pow[next_map[b]] + acc_u * incoming_pow[next_map[b]] + - (acc_pow[b] * incoming_zeta + incoming_pow[b] * acc_zeta); + } + else { + *cross_term = acc_pow[next_map[b]] + acc_u * incoming_pow[next_map[b]] + - (acc_pow[b] * incoming_zeta_sqrt + incoming_pow[b] * acc_zeta_sqrt); + } + }) + }); + + let b_0 = 0; + let b_lsqrt = bh.rotate(1, Rotation(num_vars/2 as i32)); + let b_lsqrt_next = bh.rotate(1, Rotation::next()); + let b_last = bh.rotate(1, Rotation((num_vars/2 - 1) as i32)); + + cross_term[b_0] += acc_pow[b_0] * incoming_zeta + incoming_pow[b_0] * acc_zeta - acc_u.double(); + cross_term[b_lsqrt] += acc_pow[b_lsqrt] * incoming_zeta + incoming_pow[b_lsqrt] * acc_zeta + - acc_u * incoming_zeta + - acc_zeta; + + // todo check boundary conditions for these + cross_term[b_lsqrt_next] += acc_pow[b_lsqrt_next] * incoming_zeta_sqrt + + incoming_pow[b_lsqrt_next] * acc_zeta_sqrt - acc_u.double(); + + cross_term[b_last] += acc_pow[b_last] * incoming_zeta_sqrt + + incoming_pow[b_last] * acc_zeta_sqrt - acc_u * incoming_zeta_sqrt + - acc_zeta_sqrt; + + MultilinearPolynomial::new(cross_term) +} + fn init_hadamard_evaluator<'a, F, Pcs>( expressions: &[Expression], num_vars: usize, From ce6ee8ce815a9d25972b2ad7637b90934671e195 Mon Sep 17 00:00:00 2001 From: amit0365 Date: Mon, 23 Oct 2023 02:53:35 -0400 Subject: [PATCH 09/14] compiled --- plonkish_backend/src/accumulation/protostar/hyperplonk.rs | 7 +++---- .../src/accumulation/protostar/hyperplonk/prover.rs | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs index c7ac20b0..48885dd0 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs @@ -27,7 +27,7 @@ use crate::{ PlonkishBackend, PlonkishCircuit, PlonkishCircuitInfo, }, pcs::{AdditiveCommitment, CommitmentChunk, PolynomialCommitmentScheme}, - poly::multilinear::MultilinearPolynomial, + poly::{multilinear::MultilinearPolynomial, Polynomial}, util::{ arithmetic::{powers, PrimeField}, end_timer, start_timer, @@ -41,7 +41,6 @@ use std::{borrow::BorrowMut, hash::Hash, iter}; mod preprocessor; mod prover; -use std::ops::Add; impl AccumulationScheme for Protostar, STRATEGY> where @@ -210,11 +209,11 @@ where CompressingWithSqrtPowers => { assert_eq!(pp.num_vars % 2, 0, "L is not a perfect square"); let zeta = transcript.squeeze_challenge(); - let l_sqrt = (1 << (pp.num_vars / 2)); + let l_sqrt = 1 << (pp.num_vars / 2); let timer = start_timer(|| "powers_of_zeta_sqrt_poly"); let powers_of_zeta_first_poly = powers_of_zeta_poly(pp.num_vars/2, zeta); - let powers_of_zeta_second_poly = powers_of_zeta_poly(pp.num_vars/2, zeta.pow(l_sqrt as u64)); + let powers_of_zeta_second_poly = powers_of_zeta_poly(pp.num_vars/2, zeta.pow(&[l_sqrt as u64])); let powers_of_zeta_poly = MultilinearPolynomial::new(powers_of_zeta_first_poly.evals().iter().chain(powers_of_zeta_second_poly.evals().iter()).cloned().collect()); end_timer(timer); diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs index 6705f60b..a38b0042 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs @@ -247,8 +247,8 @@ where let mut cross_term = vec![F::ZERO; size]; let l_sqrt = 1usize << num_vars/2; - let incoming_zeta_sqrt = (powers(incoming_zeta).nth(l_sqrt).unwrap()); - let acc_zeta_sqrt = (powers(acc_zeta).nth(l_sqrt).unwrap()); + let incoming_zeta_sqrt = powers(*incoming_zeta).nth(l_sqrt).unwrap(); + let acc_zeta_sqrt = powers(*acc_zeta).nth(l_sqrt).unwrap(); let bh = BooleanHypercube::new(num_vars); let next_map = bh.rotation_map(Rotation::next()); @@ -269,7 +269,7 @@ where }); let b_0 = 0; - let b_lsqrt = bh.rotate(1, Rotation(num_vars/2 as i32)); + let b_lsqrt = bh.rotate(1, Rotation((num_vars/2) as i32)); let b_lsqrt_next = bh.rotate(1, Rotation::next()); let b_last = bh.rotate(1, Rotation((num_vars/2 - 1) as i32)); From 469bbeeb136a8ce144c312583c9829e016926e65 Mon Sep 17 00:00:00 2001 From: amit0365 Date: Mon, 23 Oct 2023 22:10:02 -0400 Subject: [PATCH 10/14] track zeta_pow_lsqrt --- .../src/accumulation/protostar/hyperplonk.rs | 23 ++++++++++++------- .../protostar/hyperplonk/preprocessor.rs | 11 +++++---- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs index 48885dd0..e3d91743 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs @@ -188,8 +188,8 @@ where // Round n+2 - let (zeta, powers_of_zeta_poly, powers_of_zeta_comm) = match strategy { - NoCompressing => (None, None, None), + let (zeta, zeta_pow_lsqrt, powers_of_zeta_poly, powers_of_zeta_comm) = match strategy { + NoCompressing => (None, None, None, None), Compressing => { let zeta = transcript.squeeze_challenge(); @@ -202,6 +202,7 @@ where ( Some(zeta), + None, Some(powers_of_zeta_poly), Some(powers_of_zeta_comm), ) @@ -210,10 +211,11 @@ where assert_eq!(pp.num_vars % 2, 0, "L is not a perfect square"); let zeta = transcript.squeeze_challenge(); let l_sqrt = 1 << (pp.num_vars / 2); + let zeta_pow_lsqrt = zeta.pow(&[l_sqrt as u64]); let timer = start_timer(|| "powers_of_zeta_sqrt_poly"); let powers_of_zeta_first_poly = powers_of_zeta_poly(pp.num_vars/2, zeta); - let powers_of_zeta_second_poly = powers_of_zeta_poly(pp.num_vars/2, zeta.pow(&[l_sqrt as u64])); + let powers_of_zeta_second_poly = powers_of_zeta_poly(pp.num_vars/2, zeta_pow_lsqrt); let powers_of_zeta_poly = MultilinearPolynomial::new(powers_of_zeta_first_poly.evals().iter().chain(powers_of_zeta_second_poly.evals().iter()).cloned().collect()); end_timer(timer); @@ -222,12 +224,13 @@ where ( Some(zeta), + Some(zeta_pow_lsqrt), Some(powers_of_zeta_poly), Some(powers_of_zeta_comm), ) } }; - + // Round n+3 let alpha_primes = powers(transcript.squeeze_challenge()) @@ -242,6 +245,7 @@ where .chain(theta_primes) .chain(Some(beta_prime)) .chain(zeta) + .chain(zeta_pow_lsqrt) .chain(alpha_primes) .collect(), iter::empty() @@ -444,21 +448,23 @@ where // Round n+2 - let (zeta, powers_of_zeta_comm) = match strategy { - NoCompressing => (None, None), + let (zeta, zeta_pow_lsqrt, powers_of_zeta_comm) = match strategy { + NoCompressing => (None, None, None), Compressing => { let zeta = transcript.squeeze_challenge(); let powers_of_zeta_comm = Pcs::read_commitment(&vp.pcs, transcript)?; - (Some(zeta), Some(powers_of_zeta_comm)) + (Some(zeta), None, Some(powers_of_zeta_comm)) }, CompressingWithSqrtPowers => { let zeta = transcript.squeeze_challenge(); + let l_sqrt = 1 << (vp.num_vars / 2); + let zeta_pow_lsqrt = zeta.pow(&[l_sqrt as u64]); let powers_of_zeta_comm = Pcs::read_commitment(&vp.pcs, transcript)?; - (Some(zeta), Some(powers_of_zeta_comm)) + (Some(zeta), Some(zeta_pow_lsqrt), Some(powers_of_zeta_comm)) } }; @@ -476,6 +482,7 @@ where .chain(theta_primes) .chain(Some(beta_prime)) .chain(zeta) + .chain(zeta_pow_lsqrt) .chain(alpha_primes) .collect(), iter::empty() diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs index 583ab54f..2e033942 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs @@ -22,6 +22,7 @@ use crate::{ Error, }; use std::{array, borrow::Cow, collections::BTreeSet, hash::Hash, iter}; +use num_integer::Roots; pub(crate) fn batch_size( circuit_info: &PlonkishCircuitInfo, @@ -219,6 +220,7 @@ where products(&poly_set.preprocess, &compressed_constraint) }; let powers_of_zeta_constraint = powers_of_zeta_constraint(zeta, powers_of_zeta); + let zeta_products = products(&poly_set.preprocess, &powers_of_zeta_constraint); let num_folding_challenges = alpha_prime_offset + num_alpha_primes; @@ -243,7 +245,8 @@ where } CompressingWithSqrtPowers => { let zeta = challenge_offset + num_theta_primes + 1; - let alpha_prime_offset = zeta + 1; + let zeta_sqrt = zeta + 1; + let alpha_prime_offset = zeta_sqrt + 1; let num_builtin_witness_polys = 3 * circuit_info.lookups.len() + 1; let builtin_witness_poly_offset = witness_poly_offset + num_witness_polys + circuit_info.permutation_polys().len(); @@ -264,7 +267,7 @@ where let powers_of_zeta = builtin_witness_poly_offset + circuit_info.lookups.len() * 3; assert_eq!((powers_of_zeta as f64).sqrt().fract(), 0.0, "L is not a perfect square"); - let l_sqrt = (powers_of_zeta as f64).sqrt() as usize; + let l_sqrt = powers_of_zeta.sqrt() as usize; let powers_of_zeta_sqrt = l_sqrt - 1; let compressed_products = { let mut constraints = iter::empty() @@ -300,7 +303,7 @@ where let powers_of_zeta_sqrt1_constraint = powers_of_zeta_constraint(zeta, powers_of_zeta_sqrt); let zeta_sqrt1_products = products(&poly_set.preprocess, &powers_of_zeta_sqrt1_constraint); - let powers_of_zeta_sqrt2_constraint = powers_of_zeta_constraint(zeta.pow(l_sqrt as u32), powers_of_zeta_sqrt); + let powers_of_zeta_sqrt2_constraint = powers_of_zeta_constraint(zeta_sqrt, powers_of_zeta_sqrt); let zeta_sqrt2_products = products(&poly_set.preprocess, &powers_of_zeta_sqrt2_constraint); let zeta_products = iter::empty() @@ -315,7 +318,7 @@ where let u = num_folding_challenges; let relexed_compressed_constraint = relaxed_expression(&compressed_products, u); let relexed_zeta_constraint = { - let e = powers_of_zeta + num_permutation_z_polys + 1; + let e = 2*powers_of_zeta_sqrt + num_permutation_z_polys + 1; relaxed_expression(&zeta_products, u) - Expression::Polynomial(Query::new(e, Rotation::cur())) }; From 6129686a482ecc44b90d2b6d1e3d03a596873f97 Mon Sep 17 00:00:00 2001 From: amit0365 Date: Tue, 7 Nov 2023 23:24:24 -0500 Subject: [PATCH 11/14] debug sqrt --- plonkish_backend/Cargo.toml | 3 +- .../src/accumulation/protostar.rs | 14 +++++-- .../src/accumulation/protostar/hyperplonk.rs | 8 ++-- .../protostar/hyperplonk/preprocessor.rs | 41 +++++++++---------- .../protostar/hyperplonk/prover.rs | 36 ++++++++-------- .../src/piop/sum_check/classic.rs | 1 + 6 files changed, 57 insertions(+), 46 deletions(-) diff --git a/plonkish_backend/Cargo.toml b/plonkish_backend/Cargo.toml index ac54a746..f1492f9b 100644 --- a/plonkish_backend/Cargo.toml +++ b/plonkish_backend/Cargo.toml @@ -35,8 +35,7 @@ pprof = { version = "0.11.0", features = ["criterion", "flamegraph"] } halo2_wrong_v2 = { git = "https://github.com/han0110/halo2wrong.git", branch = "feature/for-benchmark-v2", package = "halo2wrong" } [features] -default = ["parallel", "frontend-halo2"] - +default = ["parallel", "frontend-halo2", "timer"] timer = ["dep:ark-std", "ark-std?/print-trace", "halo2_proofs?/print-trace"] parallel = ["dep:rayon"] frontend-halo2 = ["dep:halo2_proofs"] diff --git a/plonkish_backend/src/accumulation/protostar.rs b/plonkish_backend/src/accumulation/protostar.rs index b5f1e039..1ce6d8cf 100644 --- a/plonkish_backend/src/accumulation/protostar.rs +++ b/plonkish_backend/src/accumulation/protostar.rs @@ -33,7 +33,7 @@ pub enum ProtostarStrategy { Compressing = 1, // TODO: // Compressing verification with square-root optimization applied as described in 2023/620 section 3.5 - CompressingWithSqrtPowers = 3, + CompressingWithSqrtPowers = 2, } impl From for ProtostarStrategy { @@ -108,6 +108,8 @@ where num_challenges: usize, ) -> Self { let zero_poly = Pcs::Polynomial::from_evals(vec![F::ZERO; 1 << k]); + let zero_poly_sqrt = Pcs::Polynomial::from_evals(vec![F::ZERO; 1 << (k/2 as usize + 1usize)]); + Self { instance: ProtostarAccumulatorInstance::init( strategy, @@ -116,9 +118,14 @@ where num_challenges, ), witness_polys: iter::repeat_with(|| zero_poly.clone()) - .take(num_witness_polys) - .collect(), + .take(num_witness_polys) + .collect(), e_poly: zero_poly, + // witness_polys: iter::repeat_with(|| zero_poly.clone()) + // .take(num_witness_polys - 1) + // .chain(iter::once(zero_poly_sqrt.clone())) + // .collect(), + // e_poly: zero_poly_sqrt, _marker: PhantomData, } } @@ -129,6 +136,7 @@ where instance: ProtostarAccumulatorInstance::from_nark(strategy, nark.instance), witness_polys, e_poly: Pcs::Polynomial::from_evals(vec![F::ZERO; 1 << k]), + //e_poly: Pcs::Polynomial::from_evals(vec![F::ZERO; 1 << (k/2 as usize + 1usize)]), _marker: PhantomData, } } diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs index e3d91743..fa7982bc 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs @@ -214,9 +214,9 @@ where let zeta_pow_lsqrt = zeta.pow(&[l_sqrt as u64]); let timer = start_timer(|| "powers_of_zeta_sqrt_poly"); - let powers_of_zeta_first_poly = powers_of_zeta_poly(pp.num_vars/2, zeta); - let powers_of_zeta_second_poly = powers_of_zeta_poly(pp.num_vars/2, zeta_pow_lsqrt); - let powers_of_zeta_poly = MultilinearPolynomial::new(powers_of_zeta_first_poly.evals().iter().chain(powers_of_zeta_second_poly.evals().iter()).cloned().collect()); + let powers_of_zeta_lo = powers_of_zeta_poly(pp.num_vars/2, zeta); + let powers_of_zeta_hi = powers_of_zeta_poly(pp.num_vars/2, zeta_pow_lsqrt); + let powers_of_zeta_poly = MultilinearPolynomial::new(powers_of_zeta_lo.evals().iter().chain(powers_of_zeta_hi.evals().iter()).cloned().collect()); end_timer(timer); let powers_of_zeta_comm = @@ -351,7 +351,7 @@ where end_timer(timer); } CompressingWithSqrtPowers => { - let timer = start_timer(|| "evaluate_zeta_cross_term_poly"); + let timer = start_timer(|| "evaluate_zeta_root_cross_term_poly"); let zeta_cross_term_poly = evaluate_zeta_root_cross_term_poly( pp.num_vars, *num_alpha_primes, diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs index 2e033942..064ce0a9 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs @@ -150,7 +150,7 @@ where cross_term_expressions(&poly_set, &products, num_folding_challenges); let u = num_folding_challenges; - let relexed_constraint = { + let relaxed_constraint = { let e = builtin_witness_poly_offset + circuit_info.lookups.len() * 3 + num_permutation_z_polys; @@ -163,7 +163,7 @@ where alpha_prime_offset, cross_term_expressions, None, - relexed_constraint, + relaxed_constraint, ) } Compressing => { @@ -228,8 +228,8 @@ where cross_term_expressions(&poly_set, &compressed_products, num_folding_challenges); let u = num_folding_challenges; - let relexed_compressed_constraint = relaxed_expression(&compressed_products, u); - let relexed_zeta_constraint = { + let relaxed_compressed_constraint = relaxed_expression(&compressed_products, u); + let relaxed_zeta_constraint = { let e = powers_of_zeta + num_permutation_z_polys + 1; relaxed_expression(&zeta_products, u) - Expression::Polynomial(Query::new(e, Rotation::cur())) @@ -239,14 +239,14 @@ where num_builtin_witness_polys, alpha_prime_offset, cross_term_expressions, - Some(relexed_compressed_constraint), - relexed_zeta_constraint, + Some(relaxed_compressed_constraint), + relaxed_zeta_constraint, ) } CompressingWithSqrtPowers => { let zeta = challenge_offset + num_theta_primes + 1; - let zeta_sqrt = zeta + 1; - let alpha_prime_offset = zeta_sqrt + 1; + let zeta_pow_lsqrt = zeta + 1; + let alpha_prime_offset = zeta_pow_lsqrt + 1; let num_builtin_witness_polys = 3 * circuit_info.lookups.len() + 1; let builtin_witness_poly_offset = witness_poly_offset + num_witness_polys + circuit_info.permutation_polys().len(); @@ -267,8 +267,7 @@ where let powers_of_zeta = builtin_witness_poly_offset + circuit_info.lookups.len() * 3; assert_eq!((powers_of_zeta as f64).sqrt().fract(), 0.0, "L is not a perfect square"); - let l_sqrt = powers_of_zeta.sqrt() as usize; - let powers_of_zeta_sqrt = l_sqrt - 1; + let powers_of_zeta_sqrt = powers_of_zeta.sqrt() as usize - 1; let compressed_products = { let mut constraints = iter::empty() .chain(circuit_info.constraints.iter()) @@ -299,16 +298,16 @@ where .sum::>() * powers_of_zeta_sqrt; products(&poly_set.preprocess, &compressed_constraint) - }; - let powers_of_zeta_sqrt1_constraint = powers_of_zeta_constraint(zeta, powers_of_zeta_sqrt); - let zeta_sqrt1_products = products(&poly_set.preprocess, &powers_of_zeta_sqrt1_constraint); + }; + let powers_of_zeta_constraint_lo = powers_of_zeta_constraint(zeta, powers_of_zeta_sqrt); + let zeta_products_lo = products(&poly_set.preprocess, &powers_of_zeta_constraint_lo); - let powers_of_zeta_sqrt2_constraint = powers_of_zeta_constraint(zeta_sqrt, powers_of_zeta_sqrt); - let zeta_sqrt2_products = products(&poly_set.preprocess, &powers_of_zeta_sqrt2_constraint); + let powers_of_zeta_constraint_hi = powers_of_zeta_constraint(zeta_pow_lsqrt, powers_of_zeta_sqrt); + let zeta_products_hi = products(&poly_set.preprocess, &powers_of_zeta_constraint_hi); let zeta_products = iter::empty() - .chain(zeta_sqrt1_products.iter().cloned()) - .chain(zeta_sqrt2_products.iter().cloned()) + .chain(zeta_products_lo.iter().cloned()) + .chain(zeta_products_hi.iter().cloned()) .collect_vec(); let num_folding_challenges = alpha_prime_offset + num_alpha_primes; @@ -316,8 +315,8 @@ where cross_term_expressions(&poly_set, &compressed_products, num_folding_challenges); let u = num_folding_challenges; - let relexed_compressed_constraint = relaxed_expression(&compressed_products, u); - let relexed_zeta_constraint = { + let relaxed_compressed_constraint = relaxed_expression(&compressed_products, u); + let relaxed_zeta_constraint = { let e = 2*powers_of_zeta_sqrt + num_permutation_z_polys + 1; relaxed_expression(&zeta_products, u) - Expression::Polynomial(Query::new(e, Rotation::cur())) @@ -327,8 +326,8 @@ where num_builtin_witness_polys, alpha_prime_offset, cross_term_expressions, - Some(relexed_compressed_constraint), - relexed_zeta_constraint, + Some(relaxed_compressed_constraint), + relaxed_zeta_constraint, ) } }; diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs index a38b0042..8c0d2cf3 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs @@ -230,27 +230,30 @@ where F: PrimeField, Pcs: PolynomialCommitmentScheme>, { - let [(acc_pow, acc_zeta, acc_u), (incoming_pow, incoming_zeta, incoming_u)] = + let [(acc_pow, acc_zeta, acc_zeta_pow_lsqrt, acc_u), (incoming_pow, incoming_zeta, incoming_zeta_pow_lsqrt, incoming_u)] = [accumulator, incoming].map(|witness| { let pow = witness.witness_polys.last().unwrap(); let zeta = witness + .instance + .challenges + .iter() + .nth_back(zeta_nth_back + 1usize) + .unwrap(); + let zeta_pow_lsqrt = witness .instance .challenges .iter() .nth_back(zeta_nth_back) .unwrap(); - (pow, zeta, witness.instance.u) + (pow, zeta, zeta_pow_lsqrt, witness.instance.u) }); assert_eq!(incoming_u, F::ONE); let size = 2*(1 << num_vars/2); let mut cross_term = vec![F::ZERO; size]; + let l_sqrt = 1 << num_vars/2; - let l_sqrt = 1usize << num_vars/2; - let incoming_zeta_sqrt = powers(*incoming_zeta).nth(l_sqrt).unwrap(); - let acc_zeta_sqrt = powers(*acc_zeta).nth(l_sqrt).unwrap(); - - let bh = BooleanHypercube::new(num_vars); + let bh = BooleanHypercube::new(num_vars/2 + 1usize); let next_map = bh.rotation_map(Rotation::next()); parallelize(&mut cross_term, |(cross_term, start)| { cross_term @@ -263,28 +266,29 @@ where } else { *cross_term = acc_pow[next_map[b]] + acc_u * incoming_pow[next_map[b]] - - (acc_pow[b] * incoming_zeta_sqrt + incoming_pow[b] * acc_zeta_sqrt); + - (acc_pow[b] * incoming_zeta_pow_lsqrt + incoming_pow[b] * acc_zeta_pow_lsqrt); } }) }); + // todo fix rotations for mid values let b_0 = 0; let b_lsqrt = bh.rotate(1, Rotation((num_vars/2) as i32)); - let b_lsqrt_next = bh.rotate(1, Rotation::next()); - let b_last = bh.rotate(1, Rotation((num_vars/2 - 1) as i32)); + let b_lsqrt_next = bh.rotate(b_lsqrt, Rotation::next()); + let b_last = bh.rotate(1, Rotation::prev()); cross_term[b_0] += acc_pow[b_0] * incoming_zeta + incoming_pow[b_0] * acc_zeta - acc_u.double(); cross_term[b_lsqrt] += acc_pow[b_lsqrt] * incoming_zeta + incoming_pow[b_lsqrt] * acc_zeta - acc_u * incoming_zeta - - acc_zeta; + - acc_zeta; // todo check boundary conditions for these - cross_term[b_lsqrt_next] += acc_pow[b_lsqrt_next] * incoming_zeta_sqrt - + incoming_pow[b_lsqrt_next] * acc_zeta_sqrt - acc_u.double(); + cross_term[b_lsqrt_next] += acc_pow[b_lsqrt_next] * incoming_zeta_pow_lsqrt + + incoming_pow[b_lsqrt_next] * acc_zeta_pow_lsqrt - acc_u.double(); - cross_term[b_last] += acc_pow[b_last] * incoming_zeta_sqrt - + incoming_pow[b_last] * acc_zeta_sqrt - acc_u * incoming_zeta_sqrt - - acc_zeta_sqrt; + cross_term[b_last] += acc_pow[b_last] * incoming_zeta_pow_lsqrt + + incoming_pow[b_last] * acc_zeta_pow_lsqrt - acc_u * incoming_zeta_pow_lsqrt + - acc_zeta_pow_lsqrt; MultilinearPolynomial::new(cross_term) } diff --git a/plonkish_backend/src/piop/sum_check/classic.rs b/plonkish_backend/src/piop/sum_check/classic.rs index 531c9253..105703f4 100644 --- a/plonkish_backend/src/piop/sum_check/classic.rs +++ b/plonkish_backend/src/piop/sum_check/classic.rs @@ -172,6 +172,7 @@ pub trait ClassicSumCheckRoundMessage: Sized + Debug { fn evaluate(&self, aux: &Self::Auxiliary, challenge: &F) -> F; + // todo pow_zeta_sqrt sum_check eval here fn verify_consistency( degree: usize, mut sum: F, From ff4e667e5d8b4ad204c1c2c0a0863c51e16e2f5e Mon Sep 17 00:00:00 2001 From: amit0365 Date: Thu, 23 Nov 2023 00:15:36 -0500 Subject: [PATCH 12/14] separate witness_poly for sumcheck --- .../src/accumulation/protostar.rs | 9 +- .../src/accumulation/protostar/hyperplonk.rs | 56 +++---- .../protostar/hyperplonk/preprocessor.rs | 59 +++++--- .../protostar/hyperplonk/prover.rs | 143 +++++++++++++----- .../src/backend/hyperplonk/prover.rs | 18 ++- plonkish_backend/src/pcs/multilinear/ipa.rs | 2 +- .../src/piop/sum_check/classic.rs | 1 - 7 files changed, 187 insertions(+), 101 deletions(-) diff --git a/plonkish_backend/src/accumulation/protostar.rs b/plonkish_backend/src/accumulation/protostar.rs index 1ce6d8cf..f118a080 100644 --- a/plonkish_backend/src/accumulation/protostar.rs +++ b/plonkish_backend/src/accumulation/protostar.rs @@ -22,7 +22,7 @@ pub mod hyperplonk; pub mod ivc; #[derive(Clone, Debug)] -pub struct Protostar(PhantomData); +pub struct Protostar(PhantomData); #[derive(Clone, Copy, Debug, Default, Serialize, Deserialize)] pub enum ProtostarStrategy { @@ -108,7 +108,6 @@ where num_challenges: usize, ) -> Self { let zero_poly = Pcs::Polynomial::from_evals(vec![F::ZERO; 1 << k]); - let zero_poly_sqrt = Pcs::Polynomial::from_evals(vec![F::ZERO; 1 << (k/2 as usize + 1usize)]); Self { instance: ProtostarAccumulatorInstance::init( @@ -121,11 +120,6 @@ where .take(num_witness_polys) .collect(), e_poly: zero_poly, - // witness_polys: iter::repeat_with(|| zero_poly.clone()) - // .take(num_witness_polys - 1) - // .chain(iter::once(zero_poly_sqrt.clone())) - // .collect(), - // e_poly: zero_poly_sqrt, _marker: PhantomData, } } @@ -136,7 +130,6 @@ where instance: ProtostarAccumulatorInstance::from_nark(strategy, nark.instance), witness_polys, e_poly: Pcs::Polynomial::from_evals(vec![F::ZERO; 1 << k]), - //e_poly: Pcs::Polynomial::from_evals(vec![F::ZERO; 1 << (k/2 as usize + 1usize)]), _marker: PhantomData, } } diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs index fa7982bc..ccf7390c 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs @@ -4,8 +4,8 @@ use crate::{ hyperplonk::{ preprocessor::{batch_size, preprocess}, prover::{ - evaluate_compressed_cross_term_sums, evaluate_cross_term_polys, - evaluate_zeta_cross_term_poly,evaluate_zeta_root_cross_term_poly, lookup_h_polys, powers_of_zeta_poly, + evaluate_compressed_cross_term_sums, evaluate_cross_term_polys, evaluate_zeta_root_cross_term_poly, + evaluate_zeta_cross_term_poly, lookup_h_polys, powers_of_zeta_poly, powers_of_zeta_sum_check_poly_lo, powers_of_zeta_sum_check_poly_hi, }, }, ivc::ProtostarAccumulationVerifierParam, @@ -37,10 +37,10 @@ use crate::{ Error, }; use rand::RngCore; -use std::{borrow::BorrowMut, hash::Hash, iter}; +use std::{borrow::BorrowMut, hash::Hash, iter::{self, repeat}}; mod preprocessor; -mod prover; +pub mod prover; impl AccumulationScheme for Protostar, STRATEGY> where @@ -188,8 +188,8 @@ where // Round n+2 - let (zeta, zeta_pow_lsqrt, powers_of_zeta_poly, powers_of_zeta_comm) = match strategy { - NoCompressing => (None, None, None, None), + let (zeta, powers_of_zeta_poly_lo, powers_of_zeta_poly_hi, powers_of_zeta_comm_lo, powers_of_zeta_comm_hi) = match strategy { + NoCompressing => (None, None, None, None, None), Compressing => { let zeta = transcript.squeeze_challenge(); @@ -202,31 +202,37 @@ where ( Some(zeta), - None, Some(powers_of_zeta_poly), + None, Some(powers_of_zeta_comm), + None, ) }, CompressingWithSqrtPowers => { assert_eq!(pp.num_vars % 2, 0, "L is not a perfect square"); let zeta = transcript.squeeze_challenge(); - let l_sqrt = 1 << (pp.num_vars / 2); + let l_sqrt = 1 << (pp.num_vars/2); let zeta_pow_lsqrt = zeta.pow(&[l_sqrt as u64]); let timer = start_timer(|| "powers_of_zeta_sqrt_poly"); let powers_of_zeta_lo = powers_of_zeta_poly(pp.num_vars/2, zeta); - let powers_of_zeta_hi = powers_of_zeta_poly(pp.num_vars/2, zeta_pow_lsqrt); - let powers_of_zeta_poly = MultilinearPolynomial::new(powers_of_zeta_lo.evals().iter().chain(powers_of_zeta_hi.evals().iter()).cloned().collect()); + let powers_of_zeta_hi = powers_of_zeta_poly(pp.num_vars/2, zeta_pow_lsqrt); + let powers_of_zeta_sum_check_lo = powers_of_zeta_sum_check_poly_lo(pp.num_vars, zeta); + let powers_of_zeta_sum_check_hi = powers_of_zeta_sum_check_poly_hi(pp.num_vars, zeta_pow_lsqrt); end_timer(timer); - let powers_of_zeta_comm = - Pcs::commit_and_write(&pp.pcs, &powers_of_zeta_poly, transcript)?; + let powers_of_zeta_comm_lo = + Pcs::commit_and_write(&pp.pcs, &powers_of_zeta_lo, transcript)?; + + let powers_of_zeta_comm_hi = + Pcs::commit_and_write(&pp.pcs, &powers_of_zeta_hi, transcript)?; ( Some(zeta), - Some(zeta_pow_lsqrt), - Some(powers_of_zeta_poly), - Some(powers_of_zeta_comm), + Some(powers_of_zeta_sum_check_lo), + Some(powers_of_zeta_sum_check_hi), + Some(powers_of_zeta_comm_lo), + Some(powers_of_zeta_comm_hi), ) } }; @@ -245,20 +251,21 @@ where .chain(theta_primes) .chain(Some(beta_prime)) .chain(zeta) - .chain(zeta_pow_lsqrt) .chain(alpha_primes) .collect(), iter::empty() .chain(witness_comms) .chain(lookup_m_comms) .chain(lookup_h_comms) - .chain(powers_of_zeta_comm) + .chain(powers_of_zeta_comm_lo) + .chain(powers_of_zeta_comm_hi) .collect(), iter::empty() .chain(witness_polys) .chain(lookup_m_polys) .chain(lookup_h_polys.into_iter().flatten()) - .chain(powers_of_zeta_poly) + .chain(powers_of_zeta_poly_lo) + .chain(powers_of_zeta_poly_hi) .collect(), )) } @@ -448,23 +455,21 @@ where // Round n+2 - let (zeta, zeta_pow_lsqrt, powers_of_zeta_comm) = match strategy { - NoCompressing => (None, None, None), + let (zeta, powers_of_zeta_comm) = match strategy { + NoCompressing => (None, None), Compressing => { let zeta = transcript.squeeze_challenge(); let powers_of_zeta_comm = Pcs::read_commitment(&vp.pcs, transcript)?; - (Some(zeta), None, Some(powers_of_zeta_comm)) + (Some(zeta), Some(powers_of_zeta_comm)) }, CompressingWithSqrtPowers => { let zeta = transcript.squeeze_challenge(); - let l_sqrt = 1 << (vp.num_vars / 2); - let zeta_pow_lsqrt = zeta.pow(&[l_sqrt as u64]); let powers_of_zeta_comm = Pcs::read_commitment(&vp.pcs, transcript)?; - (Some(zeta), Some(zeta_pow_lsqrt), Some(powers_of_zeta_comm)) + (Some(zeta), Some(powers_of_zeta_comm)) } }; @@ -482,7 +487,6 @@ where .chain(theta_primes) .chain(Some(beta_prime)) .chain(zeta) - .chain(zeta_pow_lsqrt) .chain(alpha_primes) .collect(), iter::empty() @@ -700,7 +704,7 @@ where .chain(match vp.strategy { NoCompressing => None, Compressing => Some(1), - CompressingWithSqrtPowers => Some(1), + CompressingWithSqrtPowers => Some(2), }) .collect(); let num_challenges = { diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs index 064ce0a9..9c2897e3 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs @@ -11,10 +11,10 @@ use crate::{ pcs::PolynomialCommitmentScheme, poly::multilinear::MultilinearPolynomial, util::{ - arithmetic::{div_ceil, PrimeField}, + arithmetic::{div_ceil, PrimeField, powers}, chain, expression::{ - relaxed::{cross_term_expressions, products, relaxed_expression, PolynomialSet}, + relaxed::{cross_term_expressions, products, relaxed_expression, PolynomialSet, Product}, Expression, Query, Rotation, }, DeserializeOwned, Itertools, Serialize, @@ -22,6 +22,7 @@ use crate::{ Error, }; use std::{array, borrow::Cow, collections::BTreeSet, hash::Hash, iter}; +use itertools::fold; use num_integer::Roots; pub(crate) fn batch_size( @@ -67,6 +68,7 @@ where F: PrimeField + Hash + Serialize + DeserializeOwned, Pcs: PolynomialCommitmentScheme>, { + let num_vars = circuit_info.k; let challenge_offset = circuit_info.num_challenges.iter().sum::(); let max_lookup_width = circuit_info.lookups.iter().map(Vec::len).max().unwrap_or(0); let num_theta_primes = max_lookup_width.checked_sub(1).unwrap_or_default(); @@ -220,7 +222,6 @@ where products(&poly_set.preprocess, &compressed_constraint) }; let powers_of_zeta_constraint = powers_of_zeta_constraint(zeta, powers_of_zeta); - let zeta_products = products(&poly_set.preprocess, &powers_of_zeta_constraint); let num_folding_challenges = alpha_prime_offset + num_alpha_primes; @@ -245,9 +246,8 @@ where } CompressingWithSqrtPowers => { let zeta = challenge_offset + num_theta_primes + 1; - let zeta_pow_lsqrt = zeta + 1; - let alpha_prime_offset = zeta_pow_lsqrt + 1; - let num_builtin_witness_polys = 3 * circuit_info.lookups.len() + 1; + let alpha_prime_offset = zeta + 1; + let num_builtin_witness_polys = 3 * circuit_info.lookups.len() + 2; let builtin_witness_poly_offset = witness_poly_offset + num_witness_polys + circuit_info.permutation_polys().len(); @@ -265,9 +265,9 @@ where .collect(), }; - let powers_of_zeta = builtin_witness_poly_offset + circuit_info.lookups.len() * 3; - assert_eq!((powers_of_zeta as f64).sqrt().fract(), 0.0, "L is not a perfect square"); - let powers_of_zeta_sqrt = powers_of_zeta.sqrt() as usize - 1; + let powers_of_zeta_poly_lo = builtin_witness_poly_offset + circuit_info.lookups.len() * 3; + let powers_of_zeta_poly_hi = powers_of_zeta_poly_lo + 1; + let compressed_products = { let mut constraints = iter::empty() .chain(circuit_info.constraints.iter()) @@ -284,8 +284,9 @@ where constraints.swap(0, a.0); } } - let powers_of_zeta_sqrt = - Expression::::Polynomial(Query::new(powers_of_zeta_sqrt, Rotation::cur())); + let powers_of_zeta_poly_lo = Expression::::Polynomial(Query::new(powers_of_zeta_poly_lo, Rotation::cur())); + let powers_of_zeta_poly_hi = Expression::::Polynomial(Query::new(powers_of_zeta_poly_hi, Rotation::cur())); + let compressed_constraint = iter::empty() .chain(constraints.first().cloned().cloned()) .chain( @@ -296,19 +297,12 @@ where .map(|(constraint, challenge)| constraint * challenge), ) .sum::>() - * powers_of_zeta_sqrt; + * powers_of_zeta_poly_lo * powers_of_zeta_poly_hi; products(&poly_set.preprocess, &compressed_constraint) - }; - let powers_of_zeta_constraint_lo = powers_of_zeta_constraint(zeta, powers_of_zeta_sqrt); - let zeta_products_lo = products(&poly_set.preprocess, &powers_of_zeta_constraint_lo); - - let powers_of_zeta_constraint_hi = powers_of_zeta_constraint(zeta_pow_lsqrt, powers_of_zeta_sqrt); - let zeta_products_hi = products(&poly_set.preprocess, &powers_of_zeta_constraint_hi); + }; - let zeta_products = iter::empty() - .chain(zeta_products_lo.iter().cloned()) - .chain(zeta_products_hi.iter().cloned()) - .collect_vec(); + let powers_of_zeta_constraint = powers_of_zeta_root_constraint(zeta, powers_of_zeta_poly_lo, powers_of_zeta_poly_hi); + let zeta_products = products(&poly_set.preprocess, &powers_of_zeta_constraint); let num_folding_challenges = alpha_prime_offset + num_alpha_primes; let cross_term_expressions = @@ -316,8 +310,8 @@ where let u = num_folding_challenges; let relaxed_compressed_constraint = relaxed_expression(&compressed_products, u); + let e = powers_of_zeta_poly_hi + num_permutation_z_polys + 1; let relaxed_zeta_constraint = { - let e = 2*powers_of_zeta_sqrt + num_permutation_z_polys + 1; relaxed_expression(&zeta_products, u) - Expression::Polynomial(Query::new(e, Rotation::cur())) }; @@ -496,3 +490,22 @@ fn powers_of_zeta_constraint(zeta: usize, powers_of_zeta: usize) powers_of_zeta_next - (l_0 + l_last * zeta + (one - (l_0 + l_last)) * powers_of_zeta * zeta) } + +fn powers_of_zeta_root_constraint(zeta: usize, powers_of_zeta_lo: usize, powers_of_zeta_hi: usize) -> Expression { + let l_0 = &Expression::::lagrange(0); + let l_last = &Expression::::lagrange(-1); + let one = &Expression::one(); + let zeta = &Expression::Challenge(zeta); + let rotations = [Rotation::cur(), Rotation::next()]; + let powers_of_zeta_polys = rotations.iter() + .map(|&rotation| { + Expression::::Polynomial(Query::new(powers_of_zeta_lo, rotation)) * + Expression::::Polynomial(Query::new(powers_of_zeta_hi, rotation)) + }) + .collect::>(); + + let powers_of_zeta = powers_of_zeta_polys[0].clone(); + let powers_of_zeta_next = powers_of_zeta_polys[1].clone(); + + powers_of_zeta_next - (l_0 + l_last * zeta + (one - (l_0 + l_last)) * powers_of_zeta * zeta) +} diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs index 8c0d2cf3..df3ba7cd 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs @@ -11,7 +11,7 @@ use crate::{ Itertools, }, }; -use std::{borrow::Cow, hash::Hash, iter}; +use std::{borrow::Cow, hash::Hash, iter::{self, repeat}}; pub(crate) fn lookup_h_polys( compressed_polys: &[[MultilinearPolynomial; 2]], @@ -71,7 +71,7 @@ fn lookup_h_poly( ] } -pub(super) fn powers_of_zeta_poly( +pub(crate) fn powers_of_zeta_poly( num_vars: usize, zeta: F, ) -> MultilinearPolynomial { @@ -80,6 +80,29 @@ pub(super) fn powers_of_zeta_poly( MultilinearPolynomial::new(par_map_collect(&nth_map, |b| powers_of_zeta[*b])) } +pub(crate) fn powers_of_zeta_sum_check_poly_hi( + num_vars: usize, + zeta: F, +) -> MultilinearPolynomial { + assert_eq!(num_vars % 2, 0, "L is not a perfect square"); + let l_sqrt = 1 << (num_vars/2); + let zeta_pow_lsqrt = zeta.pow(&[l_sqrt as u64]); + let powers_of_zeta: Vec = powers(zeta_pow_lsqrt).take(1 << num_vars/2).collect_vec(); + let powers_of_zeta_hi: Vec = powers_of_zeta.iter().flat_map(|zeta| repeat(zeta).take(1 << num_vars/2)).cloned().collect_vec(); + let nth_map = BooleanHypercube::new(num_vars).nth_map(); + MultilinearPolynomial::new(par_map_collect(&nth_map, |b| powers_of_zeta_hi[*b])) +} + +pub(crate) fn powers_of_zeta_sum_check_poly_lo( + num_vars: usize, + zeta: F, +) -> MultilinearPolynomial { + let powers_of_zeta: Vec = powers(zeta).take(1 << num_vars/2).collect_vec(); + let powers_of_zeta_lo: Vec = repeat(powers_of_zeta.iter().cloned()).take(1 << num_vars/2).flatten().collect_vec(); + let nth_map = BooleanHypercube::new(num_vars).nth_map(); + MultilinearPolynomial::new(par_map_collect(&nth_map, |b| powers_of_zeta_lo[*b])) +} + pub(crate) fn evaluate_cross_term_polys( cross_term_expressions: &[Expression], num_vars: usize, @@ -126,7 +149,7 @@ where .collect_vec() } -pub(super) fn evaluate_compressed_cross_term_sums( +pub(crate) fn evaluate_compressed_cross_term_sums( cross_term_expressions: &[Expression], num_vars: usize, preprocess_polys: &[MultilinearPolynomial], @@ -230,65 +253,44 @@ where F: PrimeField, Pcs: PolynomialCommitmentScheme>, { - let [(acc_pow, acc_zeta, acc_zeta_pow_lsqrt, acc_u), (incoming_pow, incoming_zeta, incoming_zeta_pow_lsqrt, incoming_u)] = + let [(acc_pow, acc_zeta, acc_u), (incoming_pow, incoming_zeta, incoming_u)] = [accumulator, incoming].map(|witness| { - let pow = witness.witness_polys.last().unwrap(); + let evals_lo = witness.witness_polys[witness.witness_polys.len() - 2].evals().clone(); + let evals_hi = witness.witness_polys.last().unwrap().evals().clone(); + let pow = MultilinearPolynomial::new(evals_lo.iter() + .zip(evals_hi.iter()) + .map(|(&x, &y)| x * y) + .collect_vec()); let zeta = witness - .instance - .challenges - .iter() - .nth_back(zeta_nth_back + 1usize) - .unwrap(); - let zeta_pow_lsqrt = witness .instance .challenges .iter() .nth_back(zeta_nth_back) .unwrap(); - (pow, zeta, zeta_pow_lsqrt, witness.instance.u) + (pow, zeta, witness.instance.u) }); assert_eq!(incoming_u, F::ONE); - let size = 2*(1 << num_vars/2); + let size = 1 << num_vars; let mut cross_term = vec![F::ZERO; size]; - let l_sqrt = 1 << num_vars/2; - let bh = BooleanHypercube::new(num_vars/2 + 1usize); + let bh = BooleanHypercube::new(num_vars); let next_map = bh.rotation_map(Rotation::next()); parallelize(&mut cross_term, |(cross_term, start)| { cross_term .iter_mut() .zip(start..) .for_each(|(cross_term, b)| { - if b < l_sqrt { - *cross_term = acc_pow[next_map[b]] + acc_u * incoming_pow[next_map[b]] - - (acc_pow[b] * incoming_zeta + incoming_pow[b] * acc_zeta); - } - else { - *cross_term = acc_pow[next_map[b]] + acc_u * incoming_pow[next_map[b]] - - (acc_pow[b] * incoming_zeta_pow_lsqrt + incoming_pow[b] * acc_zeta_pow_lsqrt); - } + *cross_term = acc_pow[next_map[b]] + acc_u * incoming_pow[next_map[b]] + - (acc_pow[b] * incoming_zeta + incoming_pow[b] * acc_zeta); }) }); - - // todo fix rotations for mid values let b_0 = 0; - let b_lsqrt = bh.rotate(1, Rotation((num_vars/2) as i32)); - let b_lsqrt_next = bh.rotate(b_lsqrt, Rotation::next()); let b_last = bh.rotate(1, Rotation::prev()); - cross_term[b_0] += acc_pow[b_0] * incoming_zeta + incoming_pow[b_0] * acc_zeta - acc_u.double(); - cross_term[b_lsqrt] += acc_pow[b_lsqrt] * incoming_zeta + incoming_pow[b_lsqrt] * acc_zeta + cross_term[b_last] += acc_pow[b_last] * incoming_zeta + incoming_pow[b_last] * acc_zeta - acc_u * incoming_zeta - - acc_zeta; - - // todo check boundary conditions for these - cross_term[b_lsqrt_next] += acc_pow[b_lsqrt_next] * incoming_zeta_pow_lsqrt - + incoming_pow[b_lsqrt_next] * acc_zeta_pow_lsqrt - acc_u.double(); - - cross_term[b_last] += acc_pow[b_last] * incoming_zeta_pow_lsqrt - + incoming_pow[b_last] * acc_zeta_pow_lsqrt - acc_u * incoming_zeta_pow_lsqrt - - acc_zeta_pow_lsqrt; + - acc_zeta; MultilinearPolynomial::new(cross_term) } @@ -405,3 +407,68 @@ impl<'a, F: PrimeField> HadamardEvaluator<'a, F> { .for_each(|(calculation, idx)| calculation.calculate(cache, idx)); } } + +#[cfg(test)] +pub mod test { + use crate::{ + poly::{ + multilinear::{rotation_eval, zip_self, MultilinearPolynomial, test::fix_vars}, + Polynomial, + }, + util::{ + arithmetic::{BooleanHypercube, Field, powers}, + expression::Rotation, + test::rand_vec, + Itertools, + }, accumulation::protostar::hyperplonk::prover::{powers_of_zeta_poly, powers_of_zeta_sum_check_poly_lo, powers_of_zeta_sum_check_poly_hi}, + }; + use halo2_curves::bn256::Fr; + use rand::{rngs::OsRng, RngCore}; + use std::{iter::{self, repeat}, ops::Mul}; + + #[test] + fn fix_lo() { + + let rand_x_i = || match OsRng.next_u32() % 3 { + 0 => Fr::zero(), + 1 => Fr::one(), + 2 => Fr::random(OsRng), + _ => unreachable!(), + }; + + let zeta = Fr::from(2); //Fr::random(OsRng); + let num_vars = 14; + let powers_of_zeta_full_poly = powers_of_zeta_poly(num_vars, zeta); + let powers_of_zeta_root_poly = powers_of_zeta_poly(num_vars/2, zeta); + let powers_of_zeta_sum_check_hi_poly = powers_of_zeta_sum_check_poly_hi(num_vars, zeta); + let powers_of_zeta_sum_check_lo_poly = powers_of_zeta_sum_check_poly_lo(num_vars, zeta); + let powers_of_zeta_sum_check_poly = MultilinearPolynomial::new( + powers_of_zeta_sum_check_lo_poly.evals().iter() + .zip(powers_of_zeta_sum_check_hi_poly.evals().iter()) + .map(|(&x, &y)| x * y) + .collect_vec()); + let x = iter::repeat_with(rand_x_i).take(num_vars).collect_vec(); + // println!("x {:?}", x); + let x_lo = x.iter().take(num_vars/2).cloned().collect_vec(); + // println!("x_lo {:?}", x_lo); + let x_lo_sumcheck = x.iter().take(num_vars/2).cloned() + .chain(vec![Fr::ONE; num_vars/2].into_iter()) + .collect_vec(); + let x_hi_sumcheck = vec![Fr::ONE; num_vars/2].into_iter() + .chain(x.iter().skip(num_vars/2).cloned()) + .collect_vec(); + + // let powers_of_zeta_full_poly_fixed_var = powers_of_zeta_full_poly.fix_last_vars(&vec![Fr::ZERO; num_vars/2]); + // let powers_of_zeta_sum_check_poly_fixed_var = powers_of_zeta_sum_check_poly.fix_last_vars(&vec![Fr::ZERO; num_vars/2]); + // let powers_of_zeta_sum_check_lo_poly_fixed_var = powers_of_zeta_sum_check_lo_poly.fix_vars(&vec![Fr::ZERO; num_vars/2]); + // let powers_of_zeta_sum_check_lo_poly_fixed_var = fix_vars(powers_of_zeta_sum_check_lo_poly.evals(), &x_lo); + // println!("powers_of_zeta_root_poly {:?}", powers_of_zeta_root_poly); + // println!("powers_of_zeta_sum_check_lo_poly_fixed_var {:?}", powers_of_zeta_sum_check_lo_poly_fixed_var); + // println!("x_lo_sumcheck {:?}", x_lo_sumcheck); + // assert_eq!(powers_of_zeta_full_poly.evaluate(&x), powers_of_zeta_sum_check_poly.evaluate(&x)); + // let sum_check_eval = powers_of_zeta_sum_check_lo_poly.evaluate(&x_lo_sumcheck) + powers_of_zeta_sum_check_lo_poly.evaluate(&x_hi_sumcheck); + // assert_eq!(powers_of_zeta_root_poly.evaluate(&x_lo), sum_check_eval); + // assert_eq!(powers_of_zeta_root_poly.evaluate(&x_lo), powers_of_zeta_sum_check_poly_fixed_var.evaluate(&x_lo)); + + } +} \ No newline at end of file diff --git a/plonkish_backend/src/backend/hyperplonk/prover.rs b/plonkish_backend/src/backend/hyperplonk/prover.rs index 19ef148a..af0e6b21 100644 --- a/plonkish_backend/src/backend/hyperplonk/prover.rs +++ b/plonkish_backend/src/backend/hyperplonk/prover.rs @@ -11,7 +11,7 @@ use crate::{ classic::{ClassicSumCheck, EvaluationsProver}, SumCheck, VirtualPolynomial, }, - poly::{multilinear::MultilinearPolynomial, Polynomial}, + poly::{multilinear::{MultilinearPolynomial, test::fix_vars}, Polynomial}, util::{ arithmetic::{div_ceil, steps_by, sum, BatchInvert, BooleanHypercube, PrimeField}, end_timer, @@ -21,7 +21,7 @@ use crate::{ transcript::FieldTranscriptWrite, Itertools, }, - Error, + Error, accumulation::protostar::hyperplonk::prover::powers_of_zeta_poly, }; use std::{ collections::{HashMap, HashSet}, @@ -396,7 +396,17 @@ pub(crate) fn prove_sum_check( .zip(if query.rotation() == Rotation::cur() { vec![evals[query.poly()]] } else { - polys[query.poly()].evaluate_for_rotation(&x, query.rotation()) + let (x_lo, x_hi) = x.split_at(num_vars >> 2); + if query.poly() == 36 { + polys[query.poly()].fix_last_vars(x_hi).evaluate_for_rotation(&x_lo, query.rotation()) + } + else if query.poly() == 37 { + MultilinearPolynomial::new(fix_vars(polys[query.poly()].evals(), x_lo)).evaluate_for_rotation(&x_hi, query.rotation()) + } + else { + polys[query.poly()].evaluate_for_rotation(&x, query.rotation()) + } + // polys[query.poly()].evaluate_for_rotation(&x, query.rotation()) }) .map(|(point, eval)| Evaluation::new(query.poly(), point, eval)) }) @@ -406,4 +416,4 @@ pub(crate) fn prove_sum_check( transcript.write_field_elements(evals.iter().map(Evaluation::value))?; Ok((points(&pcs_query, &x), evals)) -} +} \ No newline at end of file diff --git a/plonkish_backend/src/pcs/multilinear/ipa.rs b/plonkish_backend/src/pcs/multilinear/ipa.rs index c05db080..5c9814c8 100644 --- a/plonkish_backend/src/pcs/multilinear/ipa.rs +++ b/plonkish_backend/src/pcs/multilinear/ipa.rs @@ -147,7 +147,7 @@ where fn commit(pp: &Self::ProverParam, poly: &Self::Polynomial) -> Result { validate_input("commit", pp.num_vars(), [poly], None)?; - Ok(variable_base_msm(poly.evals(), pp.g()).into()).map(MultilinearIpaCommitment) + Ok(variable_base_msm(poly.evals(), &pp.g()[..poly.evals().len()]).into()).map(MultilinearIpaCommitment) } fn batch_commit<'a>( diff --git a/plonkish_backend/src/piop/sum_check/classic.rs b/plonkish_backend/src/piop/sum_check/classic.rs index 105703f4..531c9253 100644 --- a/plonkish_backend/src/piop/sum_check/classic.rs +++ b/plonkish_backend/src/piop/sum_check/classic.rs @@ -172,7 +172,6 @@ pub trait ClassicSumCheckRoundMessage: Sized + Debug { fn evaluate(&self, aux: &Self::Auxiliary, challenge: &F) -> F; - // todo pow_zeta_sqrt sum_check eval here fn verify_consistency( degree: usize, mut sum: F, From 1c13a7c7e5bda39f342280a1d5daa0ee7a98320c Mon Sep 17 00:00:00 2001 From: amit0365 Date: Thu, 4 Apr 2024 22:42:20 -0400 Subject: [PATCH 13/14] done except the decider --- .../src/accumulation/protostar.rs | 24 ++- .../src/accumulation/protostar/hyperplonk.rs | 26 +-- .../protostar/hyperplonk/preprocessor.rs | 49 +++--- .../protostar/hyperplonk/prover.rs | 154 ++++++++++-------- .../accumulation/protostar/ivc/halo2/test.rs | 2 +- plonkish_backend/src/backend/hyperplonk.rs | 3 +- .../src/backend/hyperplonk/prover.rs | 23 +-- plonkish_backend/src/frontend/halo2.rs | 1 - plonkish_backend/src/pcs/multilinear.rs | 24 +++ plonkish_backend/src/poly/multilinear.rs | 66 +++++++- 10 files changed, 241 insertions(+), 131 deletions(-) diff --git a/plonkish_backend/src/accumulation/protostar.rs b/plonkish_backend/src/accumulation/protostar.rs index f118a080..f1c83e15 100644 --- a/plonkish_backend/src/accumulation/protostar.rs +++ b/plonkish_backend/src/accumulation/protostar.rs @@ -107,7 +107,13 @@ where num_witness_polys: usize, num_challenges: usize, ) -> Self { - let zero_poly = Pcs::Polynomial::from_evals(vec![F::ZERO; 1 << k]); + + let witness_zero_poly = Pcs::Polynomial::from_evals(vec![F::ZERO; 1 << k]); + let error_zero_poly = match strategy { + NoCompressing => Pcs::Polynomial::from_evals(vec![F::ZERO; 1 << k]), + Compressing => Pcs::Polynomial::from_evals(vec![F::ZERO; 1 << k]), + CompressingWithSqrtPowers => Pcs::Polynomial::from_evals(vec![F::ZERO; 1 << (k/2 + 1)]) + }; Self { instance: ProtostarAccumulatorInstance::init( @@ -116,20 +122,26 @@ where num_witness_polys, num_challenges, ), - witness_polys: iter::repeat_with(|| zero_poly.clone()) - .take(num_witness_polys) - .collect(), - e_poly: zero_poly, + witness_polys: iter::repeat_with(|| witness_zero_poly.clone()) + .take(num_witness_polys) + .collect(), + e_poly: error_zero_poly, _marker: PhantomData, } } fn from_nark(strategy: ProtostarStrategy, k: usize, nark: PlonkishNark) -> Self { let witness_polys = nark.witness_polys; + let zero_poly = match strategy { + NoCompressing => Pcs::Polynomial::from_evals(vec![F::ZERO; 1 << k]), + Compressing => Pcs::Polynomial::from_evals(vec![F::ZERO; 1 << k]), + CompressingWithSqrtPowers => Pcs::Polynomial::from_evals(vec![F::ZERO; 1 << (k/2 + 1)]) + }; + Self { instance: ProtostarAccumulatorInstance::from_nark(strategy, nark.instance), witness_polys, - e_poly: Pcs::Polynomial::from_evals(vec![F::ZERO; 1 << k]), + e_poly: zero_poly, _marker: PhantomData, } } diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs index ccf7390c..9cd475aa 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs @@ -215,16 +215,14 @@ where let zeta_pow_lsqrt = zeta.pow(&[l_sqrt as u64]); let timer = start_timer(|| "powers_of_zeta_sqrt_poly"); - let powers_of_zeta_lo = powers_of_zeta_poly(pp.num_vars/2, zeta); - let powers_of_zeta_hi = powers_of_zeta_poly(pp.num_vars/2, zeta_pow_lsqrt); - let powers_of_zeta_sum_check_lo = powers_of_zeta_sum_check_poly_lo(pp.num_vars, zeta); - let powers_of_zeta_sum_check_hi = powers_of_zeta_sum_check_poly_hi(pp.num_vars, zeta_pow_lsqrt); + let (powers_of_zeta_lo, powers_of_zeta_sum_check_lo) = powers_of_zeta_sum_check_poly_lo(pp.num_vars/2, zeta); + let (powers_of_zeta_hi, powers_of_zeta_sum_check_hi) = powers_of_zeta_sum_check_poly_hi(pp.num_vars/2, zeta_pow_lsqrt); end_timer(timer); let powers_of_zeta_comm_lo = Pcs::commit_and_write(&pp.pcs, &powers_of_zeta_lo, transcript)?; - let powers_of_zeta_comm_hi = + let powers_of_zeta_comm_hi = Pcs::commit_and_write(&pp.pcs, &powers_of_zeta_hi, transcript)?; ( @@ -360,7 +358,7 @@ where CompressingWithSqrtPowers => { let timer = start_timer(|| "evaluate_zeta_root_cross_term_poly"); let zeta_cross_term_poly = evaluate_zeta_root_cross_term_poly( - pp.num_vars, + pp.num_vars/2, *num_alpha_primes, accumulator, incoming, @@ -455,21 +453,24 @@ where // Round n+2 - let (zeta, powers_of_zeta_comm) = match strategy { - NoCompressing => (None, None), + let (zeta, powers_of_zeta_comm_lo, powers_of_zeta_comm_hi) = match strategy { + NoCompressing => (None, None, None), Compressing => { let zeta = transcript.squeeze_challenge(); let powers_of_zeta_comm = Pcs::read_commitment(&vp.pcs, transcript)?; - (Some(zeta), Some(powers_of_zeta_comm)) + (Some(zeta), Some(powers_of_zeta_comm), None) }, CompressingWithSqrtPowers => { let zeta = transcript.squeeze_challenge(); - let powers_of_zeta_comm = Pcs::read_commitment(&vp.pcs, transcript)?; + let powers_of_zeta_comm_lo = Pcs::read_commitment(&vp.pcs, transcript)?; + + let powers_of_zeta_comm_hi = Pcs::read_commitment(&vp.pcs, transcript)?; - (Some(zeta), Some(powers_of_zeta_comm)) + + (Some(zeta), Some(powers_of_zeta_comm_lo), Some(powers_of_zeta_comm_hi)) } }; @@ -493,7 +494,8 @@ where .chain(witness_comms) .chain(lookup_m_comms) .chain(lookup_h_comms) - .chain(powers_of_zeta_comm) + .chain(powers_of_zeta_comm_lo) + .chain(powers_of_zeta_comm_hi) .collect(), ); let incoming = ProtostarAccumulatorInstance::from_nark(*strategy, nark); diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs index 9c2897e3..0c44fa3a 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs @@ -96,7 +96,8 @@ where alpha_prime_offset, cross_term_expressions, sum_check, - zero_check_on_every_row, + zero_check_on_every_row_lo, + zero_check_on_every_row_hi, ) = match strategy { NoCompressing => { let alpha_prime_offset = challenge_offset + num_theta_primes + 1; @@ -166,6 +167,7 @@ where cross_term_expressions, None, relaxed_constraint, + None, ) } Compressing => { @@ -242,6 +244,7 @@ where cross_term_expressions, Some(relaxed_compressed_constraint), relaxed_zeta_constraint, + None, ) } CompressingWithSqrtPowers => { @@ -301,18 +304,25 @@ where products(&poly_set.preprocess, &compressed_constraint) }; - let powers_of_zeta_constraint = powers_of_zeta_root_constraint(zeta, powers_of_zeta_poly_lo, powers_of_zeta_poly_hi); - let zeta_products = products(&poly_set.preprocess, &powers_of_zeta_constraint); + let powers_of_zeta_lo_constraint = powers_of_zeta_constraint(zeta, powers_of_zeta_poly_lo); + let powers_of_zeta_hi_constraint = powers_of_zeta_constraint(zeta, powers_of_zeta_poly_hi); + let zeta_products_lo = products(&poly_set.preprocess, &powers_of_zeta_lo_constraint); + let zeta_products_hi = products(&poly_set.preprocess, &powers_of_zeta_hi_constraint); let num_folding_challenges = alpha_prime_offset + num_alpha_primes; - let cross_term_expressions = + let cross_term_expressions = cross_term_expressions(&poly_set, &compressed_products, num_folding_challenges); let u = num_folding_challenges; let relaxed_compressed_constraint = relaxed_expression(&compressed_products, u); let e = powers_of_zeta_poly_hi + num_permutation_z_polys + 1; - let relaxed_zeta_constraint = { - relaxed_expression(&zeta_products, u) + let relaxed_zeta_lo_constraint = { + relaxed_expression(&zeta_products_lo, u) + - Expression::Polynomial(Query::new(e, Rotation::cur())) + }; + + let relaxed_zeta_hi_constraint = { + relaxed_expression(&zeta_products_hi, u) - Expression::Polynomial(Query::new(e, Rotation::cur())) }; @@ -321,7 +331,8 @@ where alpha_prime_offset, cross_term_expressions, Some(relaxed_compressed_constraint), - relaxed_zeta_constraint, + relaxed_zeta_lo_constraint, + Some(relaxed_zeta_hi_constraint) ) } }; @@ -342,7 +353,8 @@ where let expression = { let zero_check_on_every_row = Expression::distribute_powers( iter::empty() - .chain(Some(&zero_check_on_every_row)) + .chain(Some(&zero_check_on_every_row_lo)) + .chain(&zero_check_on_every_row_hi) .chain(&permutation_constraints), alpha, ) * Expression::eq_xy(0); @@ -489,23 +501,4 @@ fn powers_of_zeta_constraint(zeta: usize, powers_of_zeta: usize) .map(|rotation| Expression::Polynomial(Query::new(powers_of_zeta, rotation))); powers_of_zeta_next - (l_0 + l_last * zeta + (one - (l_0 + l_last)) * powers_of_zeta * zeta) -} - -fn powers_of_zeta_root_constraint(zeta: usize, powers_of_zeta_lo: usize, powers_of_zeta_hi: usize) -> Expression { - let l_0 = &Expression::::lagrange(0); - let l_last = &Expression::::lagrange(-1); - let one = &Expression::one(); - let zeta = &Expression::Challenge(zeta); - let rotations = [Rotation::cur(), Rotation::next()]; - let powers_of_zeta_polys = rotations.iter() - .map(|&rotation| { - Expression::::Polynomial(Query::new(powers_of_zeta_lo, rotation)) * - Expression::::Polynomial(Query::new(powers_of_zeta_hi, rotation)) - }) - .collect::>(); - - let powers_of_zeta = powers_of_zeta_polys[0].clone(); - let powers_of_zeta_next = powers_of_zeta_polys[1].clone(); - - powers_of_zeta_next - (l_0 + l_last * zeta + (one - (l_0 + l_last)) * powers_of_zeta * zeta) -} +} \ No newline at end of file diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs index df3ba7cd..9461d994 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk/prover.rs @@ -82,25 +82,24 @@ pub(crate) fn powers_of_zeta_poly( pub(crate) fn powers_of_zeta_sum_check_poly_hi( num_vars: usize, - zeta: F, -) -> MultilinearPolynomial { - assert_eq!(num_vars % 2, 0, "L is not a perfect square"); - let l_sqrt = 1 << (num_vars/2); - let zeta_pow_lsqrt = zeta.pow(&[l_sqrt as u64]); - let powers_of_zeta: Vec = powers(zeta_pow_lsqrt).take(1 << num_vars/2).collect_vec(); - let powers_of_zeta_hi: Vec = powers_of_zeta.iter().flat_map(|zeta| repeat(zeta).take(1 << num_vars/2)).cloned().collect_vec(); + zeta_pow_lsqrt: F, +) -> (MultilinearPolynomial, MultilinearPolynomial) { let nth_map = BooleanHypercube::new(num_vars).nth_map(); - MultilinearPolynomial::new(par_map_collect(&nth_map, |b| powers_of_zeta_hi[*b])) + let powers_of_zeta_hi = powers(zeta_pow_lsqrt).take(1 << num_vars).collect_vec(); + let powers_of_zeta_hi_poly = MultilinearPolynomial::new(par_map_collect(&nth_map, |b| powers_of_zeta_hi[*b])); + ( powers_of_zeta_hi_poly.clone(), + MultilinearPolynomial::new(powers_of_zeta_hi_poly.iter().flat_map(|zeta| repeat(zeta).take(1 << num_vars)).cloned().collect_vec())) } pub(crate) fn powers_of_zeta_sum_check_poly_lo( num_vars: usize, zeta: F, -) -> MultilinearPolynomial { - let powers_of_zeta: Vec = powers(zeta).take(1 << num_vars/2).collect_vec(); - let powers_of_zeta_lo: Vec = repeat(powers_of_zeta.iter().cloned()).take(1 << num_vars/2).flatten().collect_vec(); +) -> (MultilinearPolynomial, MultilinearPolynomial) { let nth_map = BooleanHypercube::new(num_vars).nth_map(); - MultilinearPolynomial::new(par_map_collect(&nth_map, |b| powers_of_zeta_lo[*b])) + let powers_of_zeta_lo = powers(zeta).take(1 << num_vars).collect_vec(); + let powers_of_zeta_lo_poly = MultilinearPolynomial::new(par_map_collect(&nth_map, |b| powers_of_zeta_lo[*b])); + ( powers_of_zeta_lo_poly.clone(), + MultilinearPolynomial::new(repeat(powers_of_zeta_lo_poly.clone().into_evals()).take(1 << num_vars).flatten().collect_vec())) } pub(crate) fn evaluate_cross_term_polys( @@ -253,45 +252,75 @@ where F: PrimeField, Pcs: PolynomialCommitmentScheme>, { - let [(acc_pow, acc_zeta, acc_u), (incoming_pow, incoming_zeta, incoming_u)] = - [accumulator, incoming].map(|witness| { - let evals_lo = witness.witness_polys[witness.witness_polys.len() - 2].evals().clone(); - let evals_hi = witness.witness_polys.last().unwrap().evals().clone(); - let pow = MultilinearPolynomial::new(evals_lo.iter() - .zip(evals_hi.iter()) - .map(|(&x, &y)| x * y) - .collect_vec()); + let [(acc_pow_lo, acc_pow_hi, acc_zeta, acc_zeta_sqrt, acc_u), + (incoming_pow_lo, incoming_pow_hi, incoming_zeta, incoming_zeta_sqrt, incoming_u)] = + [accumulator, incoming] + .map(|witness| { + let pow_lo = witness.witness_polys[witness.witness_polys.len() - 2].clone().into_evals().iter() + .cloned() + .take(1 << num_vars) + .collect_vec(); + + let pow_hi = witness.witness_polys.last().unwrap().clone().into_evals().iter() + .step_by(1 << num_vars) + .cloned() + .collect_vec(); + let zeta = witness + .instance + .challenges + .iter() + .nth_back(zeta_nth_back + 1) + .unwrap(); + + let zeta_sqrt = witness .instance .challenges .iter() .nth_back(zeta_nth_back) .unwrap(); - (pow, zeta, witness.instance.u) + + (pow_lo, pow_hi, zeta, zeta_sqrt, witness.instance.u) }); assert_eq!(incoming_u, F::ONE); let size = 1 << num_vars; - let mut cross_term = vec![F::ZERO; size]; - + let b_0 = 0; let bh = BooleanHypercube::new(num_vars); let next_map = bh.rotation_map(Rotation::next()); - parallelize(&mut cross_term, |(cross_term, start)| { - cross_term + let b_last = bh.rotate(1, Rotation::prev()); + + let mut cross_term_lo = vec![F::ZERO; size]; + parallelize(&mut cross_term_lo, |(cross_term_lo, start)| { + cross_term_lo .iter_mut() .zip(start..) - .for_each(|(cross_term, b)| { - *cross_term = acc_pow[next_map[b]] + acc_u * incoming_pow[next_map[b]] - - (acc_pow[b] * incoming_zeta + incoming_pow[b] * acc_zeta); + .for_each(|(cross_term_lo, b)| { + *cross_term_lo = acc_pow_lo[next_map[b]] + acc_u * incoming_pow_lo[next_map[b]] + - (acc_pow_lo[b] * incoming_zeta + incoming_pow_lo[b] * acc_zeta); }) }); - let b_0 = 0; - let b_last = bh.rotate(1, Rotation::prev()); - cross_term[b_0] += acc_pow[b_0] * incoming_zeta + incoming_pow[b_0] * acc_zeta - acc_u.double(); - cross_term[b_last] += acc_pow[b_last] * incoming_zeta + incoming_pow[b_last] * acc_zeta + cross_term_lo[b_0] += acc_pow_lo[b_0] * incoming_zeta + incoming_pow_lo[b_0] * acc_zeta - acc_u.double(); + cross_term_lo[b_last] += acc_pow_lo[b_last] * incoming_zeta + incoming_pow_lo[b_last] * acc_zeta - acc_u * incoming_zeta - acc_zeta; + let mut cross_term_hi = vec![F::ZERO; size]; + parallelize(&mut cross_term_hi, |(cross_term_hi, start)| { + cross_term_hi + .iter_mut() + .zip(start..) + .for_each(|(cross_term_hi, b)| { + *cross_term_hi = acc_pow_hi[next_map[b]] + acc_u * incoming_pow_hi[next_map[b]] + - (acc_pow_hi[b] * incoming_zeta_sqrt + incoming_pow_hi[b] * acc_zeta_sqrt); + }) + }); + cross_term_hi[b_0] += acc_pow_hi[b_0] * incoming_zeta_sqrt + incoming_pow_hi[b_0] * acc_zeta_sqrt - acc_u.double(); + cross_term_hi[b_last] += acc_pow_hi[b_last] * incoming_zeta_sqrt + incoming_pow_hi[b_last] * acc_zeta_sqrt + - acc_u * incoming_zeta_sqrt + - acc_zeta_sqrt; + + let cross_term = [cross_term_lo, cross_term_hi].concat(); MultilinearPolynomial::new(cross_term) } @@ -412,7 +441,7 @@ impl<'a, F: PrimeField> HadamardEvaluator<'a, F> { pub mod test { use crate::{ poly::{ - multilinear::{rotation_eval, zip_self, MultilinearPolynomial, test::fix_vars}, + multilinear::{rotation_eval, zip_self, MultilinearPolynomial, test::{fix_vars}}, Polynomial, }, util::{ @@ -424,10 +453,11 @@ pub mod test { }; use halo2_curves::bn256::Fr; use rand::{rngs::OsRng, RngCore}; + use core::num; use std::{iter::{self, repeat}, ops::Mul}; #[test] - fn fix_lo() { + fn eval_zeta_sqrt() { let rand_x_i = || match OsRng.next_u32() % 3 { 0 => Fr::zero(), @@ -436,39 +466,33 @@ pub mod test { _ => unreachable!(), }; - let zeta = Fr::from(2); //Fr::random(OsRng); - let num_vars = 14; - let powers_of_zeta_full_poly = powers_of_zeta_poly(num_vars, zeta); - let powers_of_zeta_root_poly = powers_of_zeta_poly(num_vars/2, zeta); - let powers_of_zeta_sum_check_hi_poly = powers_of_zeta_sum_check_poly_hi(num_vars, zeta); - let powers_of_zeta_sum_check_lo_poly = powers_of_zeta_sum_check_poly_lo(num_vars, zeta); - let powers_of_zeta_sum_check_poly = MultilinearPolynomial::new( - powers_of_zeta_sum_check_lo_poly.evals().iter() - .zip(powers_of_zeta_sum_check_hi_poly.evals().iter()) - .map(|(&x, &y)| x * y) - .collect_vec()); + let mut rng = OsRng; + let num_vars = 8; + let zeta = Fr::random(OsRng); + let l_sqrt = 1 << (num_vars/2); + let zeta_pow_lsqrt = zeta.pow(&[l_sqrt as u64]); + + // committed powers_of_zeta_polys + let powers_of_zeta_root_lo_poly = powers_of_zeta_poly(num_vars/2, zeta); + let powers_of_zeta_root_hi_poly = powers_of_zeta_poly(num_vars/2, zeta_pow_lsqrt); + + // sum_check witness polys + let powers_of_zeta_sum_check_lo = MultilinearPolynomial::new(repeat(powers_of_zeta_root_lo_poly.clone().into_evals()).take(1 << num_vars/2).flatten().collect_vec()); + let powers_of_zeta_sum_check_hi = MultilinearPolynomial::new(powers_of_zeta_root_hi_poly.iter().flat_map(|zeta| repeat(zeta).take(1 << num_vars/2)).cloned().collect_vec()); + + // full num_vars let x = iter::repeat_with(rand_x_i).take(num_vars).collect_vec(); - // println!("x {:?}", x); - let x_lo = x.iter().take(num_vars/2).cloned().collect_vec(); - // println!("x_lo {:?}", x_lo); - let x_lo_sumcheck = x.iter().take(num_vars/2).cloned() - .chain(vec![Fr::ONE; num_vars/2].into_iter()) - .collect_vec(); - let x_hi_sumcheck = vec![Fr::ONE; num_vars/2].into_iter() - .chain(x.iter().skip(num_vars/2).cloned()) - .collect_vec(); + // half num_vars used to fix the variables in the sum_check witness polys + let x_rand = iter::repeat_with(rand_x_i).take(num_vars/2).collect_vec(); + // split the query point x into two halves + let (x_lo, x_hi) = x.split_at(num_vars/2); + + // evaluation of the sum_check witness polys with half of num_vars fixed + let eval_lo_fix_vars = powers_of_zeta_sum_check_lo.fix_last_vars(&x_rand).evaluate(&x_lo); + let eval_hi_fix_vars = MultilinearPolynomial::new(fix_vars(powers_of_zeta_sum_check_hi.evals(), &x_rand)).evaluate(&x_hi); - // let powers_of_zeta_full_poly_fixed_var = powers_of_zeta_full_poly.fix_last_vars(&vec![Fr::ZERO; num_vars/2]); - // let powers_of_zeta_sum_check_poly_fixed_var = powers_of_zeta_sum_check_poly.fix_last_vars(&vec![Fr::ZERO; num_vars/2]); - // let powers_of_zeta_sum_check_lo_poly_fixed_var = powers_of_zeta_sum_check_lo_poly.fix_vars(&vec![Fr::ZERO; num_vars/2]); - // let powers_of_zeta_sum_check_lo_poly_fixed_var = fix_vars(powers_of_zeta_sum_check_lo_poly.evals(), &x_lo); - // println!("powers_of_zeta_root_poly {:?}", powers_of_zeta_root_poly); - // println!("powers_of_zeta_sum_check_lo_poly_fixed_var {:?}", powers_of_zeta_sum_check_lo_poly_fixed_var); - // println!("x_lo_sumcheck {:?}", x_lo_sumcheck); - // assert_eq!(powers_of_zeta_full_poly.evaluate(&x), powers_of_zeta_sum_check_poly.evaluate(&x)); - // let sum_check_eval = powers_of_zeta_sum_check_lo_poly.evaluate(&x_lo_sumcheck) + powers_of_zeta_sum_check_lo_poly.evaluate(&x_hi_sumcheck); - // assert_eq!(powers_of_zeta_root_poly.evaluate(&x_lo), sum_check_eval); - // assert_eq!(powers_of_zeta_root_poly.evaluate(&x_lo), powers_of_zeta_sum_check_poly_fixed_var.evaluate(&x_lo)); + assert_eq!(powers_of_zeta_root_lo_poly.evaluate(&x_lo), eval_lo_fix_vars); + assert_eq!(powers_of_zeta_root_hi_poly.evaluate(&x_hi), eval_hi_fix_vars); } } \ No newline at end of file diff --git a/plonkish_backend/src/accumulation/protostar/ivc/halo2/test.rs b/plonkish_backend/src/accumulation/protostar/ivc/halo2/test.rs index 11a24be9..c3ecfe38 100644 --- a/plonkish_backend/src/accumulation/protostar/ivc/halo2/test.rs +++ b/plonkish_backend/src/accumulation/protostar/ivc/halo2/test.rs @@ -433,7 +433,7 @@ where secondary_proof, ) = { let secondary_acc_before_last = secondary_acc.instance.clone(); - + let mut primary_transcript = strawman::PoseidonTranscript::new(primary_dtp.clone()); let mut secondary_transcript = strawman::PoseidonTranscript::new(secondary_dtp.clone()); prove_decider( diff --git a/plonkish_backend/src/backend/hyperplonk.rs b/plonkish_backend/src/backend/hyperplonk.rs index 70176636..b77fe685 100644 --- a/plonkish_backend/src/backend/hyperplonk.rs +++ b/plonkish_backend/src/backend/hyperplonk.rs @@ -120,6 +120,7 @@ where &circuit_info.permutation_polys(), &circuit_info.permutations, ); + let permutation_comms = Pcs::batch_commit(&pcs_pp, &permutation_polys)?; // Compose `VirtualPolynomialInfo` @@ -253,7 +254,7 @@ where // Round n+2 - let alpha = transcript.squeeze_challenge(); + let alpha = transcript.squeeze_challenge(); let y = transcript.squeeze_challenges(pp.num_vars); let polys = iter::empty() diff --git a/plonkish_backend/src/backend/hyperplonk/prover.rs b/plonkish_backend/src/backend/hyperplonk/prover.rs index af0e6b21..8cd80d5e 100644 --- a/plonkish_backend/src/backend/hyperplonk/prover.rs +++ b/plonkish_backend/src/backend/hyperplonk/prover.rs @@ -396,17 +396,18 @@ pub(crate) fn prove_sum_check( .zip(if query.rotation() == Rotation::cur() { vec![evals[query.poly()]] } else { - let (x_lo, x_hi) = x.split_at(num_vars >> 2); - if query.poly() == 36 { - polys[query.poly()].fix_last_vars(x_hi).evaluate_for_rotation(&x_lo, query.rotation()) - } - else if query.poly() == 37 { - MultilinearPolynomial::new(fix_vars(polys[query.poly()].evals(), x_lo)).evaluate_for_rotation(&x_hi, query.rotation()) - } - else { - polys[query.poly()].evaluate_for_rotation(&x, query.rotation()) - } - // polys[query.poly()].evaluate_for_rotation(&x, query.rotation()) + // let (x_lo, x_hi) = x.split_at(num_vars >> 1); + // let x_zero = vec![F::ZERO; num_vars >> 1]; + // if query.poly() == 36 { + // polys[query.poly()].fix_last_vars(&x_zero).evaluate_for_rotation(&x_lo, query.rotation()) + // } + // else if query.poly() == 37 { + // MultilinearPolynomial::new(fix_vars(polys[query.poly()].evals(), &x_zero)).evaluate_for_rotation(&x_hi, query.rotation()) + // } + // else { + // polys[query.poly()].evaluate_for_rotation(&x, query.rotation()) + // } + polys[query.poly()].evaluate_for_rotation(&x, query.rotation()) }) .map(|(point, eval)| Evaluation::new(query.poly(), point, eval)) }) diff --git a/plonkish_backend/src/frontend/halo2.rs b/plonkish_backend/src/frontend/halo2.rs index ac7f8b54..1cb4d769 100644 --- a/plonkish_backend/src/frontend/halo2.rs +++ b/plonkish_backend/src/frontend/halo2.rs @@ -215,7 +215,6 @@ impl> PlonkishCircuit for Halo2Circuit { })) .collect(); circuit_info.permutations = preprocess_collector.permutation.into_cycles(); - Ok(circuit_info) } diff --git a/plonkish_backend/src/pcs/multilinear.rs b/plonkish_backend/src/pcs/multilinear.rs index fd939d51..f8b4a728 100644 --- a/plonkish_backend/src/pcs/multilinear.rs +++ b/plonkish_backend/src/pcs/multilinear.rs @@ -168,6 +168,30 @@ mod additive { merged_polys[eval.point()].0 = F::ONE; *merged_polys[eval.point()].1.to_mut() *= &coeff; } + + // let points = + // (0..active_vars) + // .map(|i| { + // let mut point = vec![F::zero(); num_vars]; + // point[i] = F::one(); + // point + // }) + // .collect(); + // if eval.poly() == 36 { + // let mut x_lo = vec![F::ZERO; num_vars/2].into_iter() + // .chain(x.iter().take(num_vars/2).cloned()) + // .collect_vec(); + // polys[eval.poly()].evaluate_for_rotation(&x_lo, query.rotation()) + // } + // else if eval.poly() == 37 { + // let mut x_hi = vec![F::ZERO; num_vars/2].into_iter() + // .chain(x.iter().skip(num_vars/2).cloned()) + // .collect_vec(); + // polys[eval.poly()].evaluate_for_rotation(&x_hi, query.rotation()) + // } + // else { + // polys[eval.poly()].evaluate_for_rotation(&x, query.rotation()) + // }; *merged_polys[eval.point()].1.to_mut() += (eq_xt_i, polys[eval.poly()]); } merged_polys diff --git a/plonkish_backend/src/poly/multilinear.rs b/plonkish_backend/src/poly/multilinear.rs index 20ccf63b..6f3caa89 100644 --- a/plonkish_backend/src/poly/multilinear.rs +++ b/plonkish_backend/src/poly/multilinear.rs @@ -612,6 +612,59 @@ pub(crate) fn merge_into( }); } +// pub fn evals_bh(evals: Vec) -> Vec { +// let num_vars = (usize::BITS - evals.len().leading_zeros() - 1) as usize; +// let nth_map = BooleanHypercube::new(num_vars).nth_map(); +// let mut evals_bh = vec![F::ZERO; 1 << num_vars]; +// for (a, &b) in (0..(1 << num_vars)).zip(&nth_map) { +// evals_bh[b] = evals[a]; +// }; +// evals_bh +// } + +// pub fn evals_lo_lexical(evals_lo: Vec) -> Vec{ +// let num_vars = (usize::BITS - evals_lo.len().leading_zeros() - 1) as usize; +// let evals_lo_chunks = evals_lo +// .chunks(1 << num_vars/2) +// .map(|chunk| chunk.to_vec()) +// .collect_vec(); + +// let evals_lo_lexical_chunks = evals_lo_chunks +// .into_iter() +// .map(|mut chunk| { +// chunk = evals_bh(chunk); +// chunk +// }) +// .collect_vec(); + +// let evals_lo_lexical = evals_lo_lexical_chunks.into_iter().flatten().collect_vec(); +// evals_lo_lexical +// } + +// pub fn evals_hi_lexical(evals_hi: Vec) -> Vec{ +// let num_vars = (usize::BITS - evals_hi.len().leading_zeros() - 1) as usize; +// let evals_hi_chunks = evals_hi +// .chunks(1 << num_vars/2) +// .map(|chunk| chunk.to_vec()) +// .collect_vec(); + +// let nth_map = BooleanHypercube::new(num_vars/2).nth_map(); + +// let evals_hi_lexical_chunks = evals_hi_chunks +// .into_iter() +// .map(|chunk| { +// let mut evals_hi_lexical_chunks = vec![F::ZERO; (1 << num_vars/2)]; +// for (i, &index) in nth_map.iter().enumerate() { +// evals_hi_lexical_chunks[index] = chunk[i]; +// } +// evals_hi_lexical_chunks +// }) +// .collect_vec(); + +// let evals_hi_lexical = evals_hi_lexical_chunks.into_iter().flatten().collect_vec(); +// evals_hi_lexical +// } + macro_rules! zip_self { (@ $iter:expr, $step:expr, $skip:expr) => { $iter.skip($skip).step_by($step).zip($iter.skip($skip + ($step >> 1)).step_by($step)) @@ -630,24 +683,25 @@ macro_rules! zip_self { pub(crate) use zip_self; #[cfg(test)] -mod test { +pub mod test { use crate::{ poly::{ multilinear::{rotation_eval, zip_self, MultilinearPolynomial}, Polynomial, }, util::{ - arithmetic::{BooleanHypercube, Field}, + arithmetic::{BooleanHypercube, Field, powers}, expression::Rotation, test::rand_vec, - Itertools, - }, + Itertools, parallel::par_map_collect, + }, accumulation::protostar::hyperplonk::prover::powers_of_zeta_poly, }; use halo2_curves::bn256::Fr; use rand::{rngs::OsRng, RngCore}; - use std::iter; + use std::iter::{self, repeat}; + use rayon::iter::IntoParallelIterator; - fn fix_vars(evals: &[F], x: &[F]) -> Vec { + pub fn fix_vars(evals: &[F], x: &[F]) -> Vec { x.iter().fold(evals.to_vec(), |evals, x_i| { zip_self!(evals.iter()) .map(|(eval_0, eval_1)| (*eval_1 - eval_0) * x_i + eval_0) From 35970d9b3d6ad6582bb3491e9bed2d3d5ecf118c Mon Sep 17 00:00:00 2001 From: amit0365 Date: Fri, 5 Apr 2024 16:05:58 -0400 Subject: [PATCH 14/14] tracking zeta_pow_lsqrt --- .../src/accumulation/protostar.rs | 2 +- .../src/accumulation/protostar/hyperplonk.rs | 33 ++++++++++++------- .../protostar/hyperplonk/preprocessor.rs | 5 +-- .../src/accumulation/protostar/ivc.rs | 3 +- .../src/accumulation/protostar/ivc/halo2.rs | 21 +++++++++--- .../accumulation/protostar/ivc/halo2/test.rs | 2 +- 6 files changed, 45 insertions(+), 21 deletions(-) diff --git a/plonkish_backend/src/accumulation/protostar.rs b/plonkish_backend/src/accumulation/protostar.rs index f1c83e15..d584ec96 100644 --- a/plonkish_backend/src/accumulation/protostar.rs +++ b/plonkish_backend/src/accumulation/protostar.rs @@ -119,7 +119,7 @@ where instance: ProtostarAccumulatorInstance::init( strategy, num_instances, - num_witness_polys, + num_witness_polys - 1, num_challenges, ), witness_polys: iter::repeat_with(|| witness_zero_poly.clone()) diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs index 9cd475aa..d73c0983 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk.rs @@ -188,7 +188,7 @@ where // Round n+2 - let (zeta, powers_of_zeta_poly_lo, powers_of_zeta_poly_hi, powers_of_zeta_comm_lo, powers_of_zeta_comm_hi) = match strategy { + let (zeta, zeta_pow_lsqrt, powers_of_zeta_poly_lo, powers_of_zeta_poly_hi, powers_of_zeta_comm) = match strategy { NoCompressing => (None, None, None, None, None), Compressing => { let zeta = transcript.squeeze_challenge(); @@ -202,10 +202,10 @@ where ( Some(zeta), + None, Some(powers_of_zeta_poly), None, Some(powers_of_zeta_comm), - None, ) }, CompressingWithSqrtPowers => { @@ -217,20 +217,25 @@ where let timer = start_timer(|| "powers_of_zeta_sqrt_poly"); let (powers_of_zeta_lo, powers_of_zeta_sum_check_lo) = powers_of_zeta_sum_check_poly_lo(pp.num_vars/2, zeta); let (powers_of_zeta_hi, powers_of_zeta_sum_check_hi) = powers_of_zeta_sum_check_poly_hi(pp.num_vars/2, zeta_pow_lsqrt); + let powers_of_zeta_concat = MultilinearPolynomial::new([powers_of_zeta_lo.into_evals(), powers_of_zeta_hi.into_evals()].concat()); end_timer(timer); - let powers_of_zeta_comm_lo = - Pcs::commit_and_write(&pp.pcs, &powers_of_zeta_lo, transcript)?; + // let powers_of_zeta_comm_lo = + // Pcs::commit_and_write(&pp.pcs, &powers_of_zeta_lo, transcript)?; + + // let powers_of_zeta_comm_hi = + // Pcs::commit_and_write(&pp.pcs, &powers_of_zeta_hi, transcript)?; - let powers_of_zeta_comm_hi = - Pcs::commit_and_write(&pp.pcs, &powers_of_zeta_hi, transcript)?; + + let powers_of_zeta_comm = + Pcs::commit_and_write(&pp.pcs, &powers_of_zeta_concat, transcript)?; ( Some(zeta), + Some(zeta_pow_lsqrt), Some(powers_of_zeta_sum_check_lo), Some(powers_of_zeta_sum_check_hi), - Some(powers_of_zeta_comm_lo), - Some(powers_of_zeta_comm_hi), + Some(powers_of_zeta_comm), ) } }; @@ -249,14 +254,15 @@ where .chain(theta_primes) .chain(Some(beta_prime)) .chain(zeta) + .chain(zeta_pow_lsqrt) .chain(alpha_primes) .collect(), iter::empty() .chain(witness_comms) .chain(lookup_m_comms) .chain(lookup_h_comms) - .chain(powers_of_zeta_comm_lo) - .chain(powers_of_zeta_comm_hi) + .chain(powers_of_zeta_comm) + //.chain(powers_of_zeta_comm_hi) .collect(), iter::empty() .chain(witness_polys) @@ -427,7 +433,7 @@ where // Round 0..n - let mut witness_comms = Vec::with_capacity(vp.num_witness_polys.iter().sum()); + let mut witness_comms: Vec<>::Commitment> = Vec::with_capacity(vp.num_witness_polys.iter().sum()); let mut challenges = Vec::with_capacity(vp.num_challenges.iter().sum()); for (num_polys, num_challenges) in vp.num_witness_polys.iter().zip_eq(vp.num_challenges.iter()) @@ -706,7 +712,7 @@ where .chain(match vp.strategy { NoCompressing => None, Compressing => Some(1), - CompressingWithSqrtPowers => Some(2), + CompressingWithSqrtPowers => Some(1), }) .collect(); let num_challenges = { @@ -726,9 +732,12 @@ where .chain([vec![vp.num_alpha_primes]]) .collect() }; + + Self { vp_digest: N::ZERO, strategy: vp.strategy, + num_vars: vp.vp.num_vars, num_instances: vp.vp.num_instances.clone(), num_witness_polys, num_challenges, diff --git a/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs b/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs index 0c44fa3a..c4023015 100644 --- a/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs +++ b/plonkish_backend/src/accumulation/protostar/hyperplonk/preprocessor.rs @@ -249,7 +249,8 @@ where } CompressingWithSqrtPowers => { let zeta = challenge_offset + num_theta_primes + 1; - let alpha_prime_offset = zeta + 1; + let zeta_pow_lsqrt = zeta + 1; + let alpha_prime_offset = zeta_pow_lsqrt + 1; let num_builtin_witness_polys = 3 * circuit_info.lookups.len() + 2; let builtin_witness_poly_offset = witness_poly_offset + num_witness_polys + circuit_info.permutation_polys().len(); @@ -305,7 +306,7 @@ where }; let powers_of_zeta_lo_constraint = powers_of_zeta_constraint(zeta, powers_of_zeta_poly_lo); - let powers_of_zeta_hi_constraint = powers_of_zeta_constraint(zeta, powers_of_zeta_poly_hi); + let powers_of_zeta_hi_constraint = powers_of_zeta_constraint(zeta_pow_lsqrt, powers_of_zeta_poly_hi); let zeta_products_lo = products(&poly_set.preprocess, &powers_of_zeta_lo_constraint); let zeta_products_hi = products(&poly_set.preprocess, &powers_of_zeta_hi_constraint); diff --git a/plonkish_backend/src/accumulation/protostar/ivc.rs b/plonkish_backend/src/accumulation/protostar/ivc.rs index f98ae6aa..cf004fc9 100644 --- a/plonkish_backend/src/accumulation/protostar/ivc.rs +++ b/plonkish_backend/src/accumulation/protostar/ivc.rs @@ -10,6 +10,7 @@ pub mod halo2; pub struct ProtostarAccumulationVerifierParam { pub(crate) vp_digest: F, pub(crate) strategy: ProtostarStrategy, + pub(crate) num_vars: usize, pub(crate) num_instances: Vec, pub(crate) num_witness_polys: Vec, pub(crate) num_challenges: Vec>, @@ -32,7 +33,7 @@ impl ProtostarAccumulationVerifierParam { self.strategy, &self.num_instances, self.num_folding_witness_polys(), - self.num_folding_challenges(), + self.num_folding_challenges() + 1, ) } } diff --git a/plonkish_backend/src/accumulation/protostar/ivc/halo2.rs b/plonkish_backend/src/accumulation/protostar/ivc/halo2.rs index 941e8f13..f9864b96 100644 --- a/plonkish_backend/src/accumulation/protostar/ivc/halo2.rs +++ b/plonkish_backend/src/accumulation/protostar/ivc/halo2.rs @@ -37,6 +37,7 @@ use crate::{ BitIndex, DeserializeOwned, Itertools, Serialize, }, }; +use ark_std::iterable::Iterable; use halo2_proofs::{ circuit::{AssignedCell, Layouter, Value}, plonk::{Circuit, ConstraintSystem, Error}, @@ -619,7 +620,7 @@ where .try_collect::<_, Vec<_>, _>()?; let challenges = iter::repeat_with(|| tcc_chip.assign_constant_base(layouter, C::Base::ZERO)) - .take(self.avp.num_folding_challenges()) + .take(self.avp.num_folding_challenges() + 1) .try_collect::<_, Vec<_>, _>()?; let u = tcc_chip.assign_constant_base(layouter, C::Base::ZERO)?; let e_comm = tcc_chip.assign_constant_secondary(layouter, C::Secondary::identity())?; @@ -673,7 +674,7 @@ where .try_collect::<_, Vec<_>, _>()?; let challenges = acc .map(|acc| &acc.challenges) - .transpose_vec(avp.num_folding_challenges()) + .transpose_vec(avp.num_folding_challenges() + 1) .into_iter() .map(|challenge| tcc_chip.assign_witness_base(layouter, challenge.copied())) .try_collect::<_, Vec<_>, _>()?; @@ -755,6 +756,7 @@ where let tcc_chip = &self.tcc_chip; let ProtostarAccumulationVerifierParam { strategy, + num_vars, num_witness_polys, num_challenges, num_cross_terms, @@ -783,6 +785,18 @@ where } } + println!("num_witness_comm: {:?}", num_witness_polys); + println!("num_challenges: {:?}", num_challenges); + println!("challenges_without_zeta_pow_lsqrt: {:?}", challenges.len()); + + // insert zeta^l_sqrt into challenges + let num_alpha_prime = num_challenges.iter().nth_back(0).unwrap()[0]; + let l_sqrt = 1 << (num_vars/2); + let zeta = challenges.iter().nth_back(num_alpha_prime).unwrap(); + let zeta_pow_lsqrt = tcc_chip.powers_base(layouter, &zeta, l_sqrt + 1)?.iter().last().unwrap().clone(); + challenges.insert(challenges.len() - num_alpha_prime, zeta_pow_lsqrt); + println!("challenges_after_tracking_zeta_pow_lsqrt: {:?}", challenges.len()); + let nark = PlonkishNarkInstance::new(vec![instances], challenges, witness_comms); transcript.absorb_accumulator(acc)?; @@ -1209,7 +1223,6 @@ where let h_prime = tcc_chip.assign_witness(layouter, self.h_prime)?; self.check_initial_condition(layouter, &is_base_case, &initial_input, &input)?; - let acc = acc_verifier.assign_accumulator(layouter, self.acc.as_ref())?; let (nark, acc_r_nark, acc_prime) = { @@ -1296,7 +1309,7 @@ where mut layouter: impl Layouter, ) -> Result<(), Error> { let (input, output) = - StepCircuit::synthesize(&self.step_circuit, config, layouter.namespace(|| ""))?; + StepCircuit::synthesize(&self.step_circuit, config, layouter.namespace(|| ""))?; self.synthesize_accumulation_verifier(layouter.namespace(|| ""), &input, &output)?; Ok(()) } diff --git a/plonkish_backend/src/accumulation/protostar/ivc/halo2/test.rs b/plonkish_backend/src/accumulation/protostar/ivc/halo2/test.rs index c3ecfe38..60a4da71 100644 --- a/plonkish_backend/src/accumulation/protostar/ivc/halo2/test.rs +++ b/plonkish_backend/src/accumulation/protostar/ivc/halo2/test.rs @@ -633,7 +633,7 @@ fn gemini_kzg_ipa_protostar_hyperplonk_ivc_with_aggregation() { } } -mod strawman { +pub mod strawman { use crate::{ accumulation::protostar::{ ivc::halo2::{