From 23dff5062479a6f24a05c20f77f02f3e0c262cf8 Mon Sep 17 00:00:00 2001 From: Balazs Komuves Date: Thu, 23 Jan 2025 20:25:29 +0100 Subject: [PATCH] add "test vectors" for gate constraints, to help debugging --- plonky2/src/gates/arithmetic_extension.rs | 8 +- plonky2/src/gates/coset_interpolation.rs | 11 ++ plonky2/src/gates/mod.rs | 1 + plonky2/src/gates/multiplication_extension.rs | 5 +- plonky2/src/gates/random_access.rs | 6 + plonky2/src/gates/test_gate_constraints.rs | 114 ++++++++++++++++++ 6 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 plonky2/src/gates/test_gate_constraints.rs diff --git a/plonky2/src/gates/arithmetic_extension.rs b/plonky2/src/gates/arithmetic_extension.rs index 8b953aa0..b5a8e3a7 100644 --- a/plonky2/src/gates/arithmetic_extension.rs +++ b/plonky2/src/gates/arithmetic_extension.rs @@ -87,7 +87,13 @@ impl, const D: usize> Gate for ArithmeticExte let computed_output = (multiplicand_0 * multiplicand_1).scalar_mul(const_0) + addend.scalar_mul(const_1); - constraints.extend((output - computed_output).to_basefield_array()); + // constraints.extend((output - computed_output).to_basefield_array()); + let diff = output - computed_output; + let base_arr = diff.to_basefield_array(); + // println!("mult_0 = {:?}",multiplicand_0); + // println!("diff = {:?}",diff); + // println!("base_arr = {:?}",base_arr); + constraints.extend(base_arr); } constraints diff --git a/plonky2/src/gates/coset_interpolation.rs b/plonky2/src/gates/coset_interpolation.rs index b6c8bb6d..8d093968 100644 --- a/plonky2/src/gates/coset_interpolation.rs +++ b/plonky2/src/gates/coset_interpolation.rs @@ -86,6 +86,13 @@ impl, const D: usize> CosetInterpolationGate .map(|x| (x, F::ZERO)) .collect::>(), ); + + // println!("subgroup_bits = {}",subgroup_bits); + // println!("max_degree = {}",max_degree); + // println!("n_points = {}",n_points); + // println!("n_intermediates = {}",n_intermediates); + // println!("degree = {}",degree); + // println!("barycentric_weights = {:?}",barycentric_weights); Self { subgroup_bits, @@ -228,6 +235,8 @@ impl, const D: usize> Gate for CosetInterpola ExtensionAlgebra::one(), ); + // println!("self.degree = {}",self.degree()); + for i in 0..self.num_intermediates() { let intermediate_eval = vars.get_local_ext_algebra(self.wires_intermediate_eval(i)); let intermediate_prod = vars.get_local_ext_algebra(self.wires_intermediate_prod(i)); @@ -236,6 +245,7 @@ impl, const D: usize> Gate for CosetInterpola let start_index = 1 + (self.degree() - 1) * (i + 1); let end_index = (start_index + self.degree() - 1).min(self.num_points()); + // println!("(start,end) = ({},{})",start_index,end_index); (computed_eval, computed_prod) = partial_interpolate_ext_algebra( &domain[start_index..end_index], &values[start_index..end_index], @@ -877,3 +887,4 @@ mod tests { assert_eq!(gate.num_constraints(), 4); } } + diff --git a/plonky2/src/gates/mod.rs b/plonky2/src/gates/mod.rs index e349cf75..478e3c5a 100644 --- a/plonky2/src/gates/mod.rs +++ b/plonky2/src/gates/mod.rs @@ -43,6 +43,7 @@ pub mod reducing; pub mod reducing_extension; pub(crate) mod selectors; pub mod util; +pub mod test_gate_constraints; // Can't use #[cfg(test)] here because it needs to be visible to other crates. // See https://github.com/rust-lang/cargo/issues/8379 diff --git a/plonky2/src/gates/multiplication_extension.rs b/plonky2/src/gates/multiplication_extension.rs index 5178b060..de1fd7b6 100644 --- a/plonky2/src/gates/multiplication_extension.rs +++ b/plonky2/src/gates/multiplication_extension.rs @@ -81,7 +81,10 @@ impl, const D: usize> Gate for MulExtensionGa let output = vars.get_local_ext_algebra(Self::wires_ith_output(i)); let computed_output = (multiplicand_0 * multiplicand_1).scalar_mul(const_0); - constraints.extend((output - computed_output).to_basefield_array()); + // constraints.extend((output - computed_output).to_basefield_array()); + let diff = output - computed_output; + let bae_arr = diff.to_basefield_array(); + constraints.extend(bae_arr); } constraints diff --git a/plonky2/src/gates/random_access.rs b/plonky2/src/gates/random_access.rs index a4b04713..f1748a6f 100644 --- a/plonky2/src/gates/random_access.rs +++ b/plonky2/src/gates/random_access.rs @@ -148,6 +148,8 @@ impl, const D: usize> Gate for RandomAccessGa fn eval_unfiltered(&self, vars: EvaluationVars) -> Vec { let mut constraints = Vec::with_capacity(self.num_constraints()); + // println!("self.routed_wires = {}",self.num_routed_wires() ); + for copy in 0..self.num_copies { let access_index = vars.local_wires[self.wire_access_index(copy)]; let mut list_items = (0..self.vec_size()) @@ -158,6 +160,10 @@ impl, const D: usize> Gate for RandomAccessGa .map(|i| vars.local_wires[self.wire_bit(i, copy)]) .collect::>(); + // for i in 0..self.bits { + // println!("copy = {} | i = {} -> wire = {}",copy,i, self.wire_bit(i,copy)); + // } + // Assert that each bit wire value is indeed boolean. for &b in &bits { constraints.push(b * (b - F::Extension::ONE)); diff --git a/plonky2/src/gates/test_gate_constraints.rs b/plonky2/src/gates/test_gate_constraints.rs new file mode 100644 index 00000000..26b8e8a6 --- /dev/null +++ b/plonky2/src/gates/test_gate_constraints.rs @@ -0,0 +1,114 @@ + +// used for debugging the constraint equations + +use crate::field::extension::{Extendable, FieldExtension}; +use crate::field::types::Field; + +use crate::hash::hash_types::{HashOut, RichField}; + +use crate::plonk::circuit_data::{CircuitConfig}; +use crate::plonk::vars::{EvaluationVars}; + +use crate::gates::gate::Gate; + +use crate::gates::arithmetic_extension::*; +use crate::gates::base_sum::*; +use crate::gates::coset_interpolation::*; +use crate::gates::exponentiation::*; +use crate::gates::multiplication_extension::*; +use crate::gates::random_access::*; +use crate::gates::poseidon::*; +use crate::gates::poseidon_mds::*; +use crate::gates::reducing::*; +use crate::gates::reducing_extension::*; + +fn make_fext, const D: usize>( x: u64 ) -> F::Extension { + let mut vec: [F; D] = [F::ZERO; D]; + vec[0] = F::from_canonical_u64(x); + vec[1] = F::from_canonical_u64(13); + F::Extension::from_basefield_array(vec) +} + +pub fn test_gate_constraints, const D: usize>() { + + // create some fixed evaluation vars + let loc_constants = + [ make_fext::(666) + , make_fext::(77) + ]; + let input_hash = HashOut{ elements: + [ F::from_canonical_u64(101) + , F::from_canonical_u64(102) + , F::from_canonical_u64(103) + , F::from_canonical_u64(104) + ] }; + let loc_wires: [F::Extension; 135] = (0..135).map( |i| make_fext::(1001 + 71*i) ).collect::>().try_into().unwrap(); + + let vars = EvaluationVars + { local_constants: &loc_constants + , local_wires: &loc_wires + , public_inputs_hash: &input_hash + }; + + let circuit_config: CircuitConfig = CircuitConfig::standard_recursion_config(); + + println!("\n------------------------------------------------------------------"); + println!("ArithmeticExtensionGate"); + let arith_ext_gate: ArithmeticExtensionGate = ArithmeticExtensionGate::new_from_config(&circuit_config); + println!("{:?}", arith_ext_gate.eval_unfiltered(vars) ); + + println!("\n------------------------------------------------------------------"); + let base_sum_gate_2: BaseSumGate<2> = BaseSumGate::new(13); + let base_sum_gate_3: BaseSumGate<3> = BaseSumGate::new(13); + println!("\nBaseSumGate (radix = 2)"); + println!("{:?}", base_sum_gate_2.eval_unfiltered(vars) ); + println!("\nBaseSumGate (radix = 3)"); + println!("{:?}", base_sum_gate_3.eval_unfiltered(vars) ); + + println!("\n------------------------------------------------------------------"); + let coset_gate_3: CosetInterpolationGate = CosetInterpolationGate::with_max_degree(3,8); + let coset_gate_4: CosetInterpolationGate = CosetInterpolationGate::with_max_degree(4,8); + let coset_gate_5: CosetInterpolationGate = CosetInterpolationGate::with_max_degree(5,8); + println!("\nCosetInterpolationGate (num_bits = 3)"); + println!("{:?}", coset_gate_3.eval_unfiltered(vars) ); + println!("\nCosetInterpolationGate (num_bits = 4)"); + println!("{:?}", coset_gate_4.eval_unfiltered(vars) ); + println!("\nCosetInterpolationGate (num_bits = 5)"); + println!("{:?}", coset_gate_5.eval_unfiltered(vars) ); + + println!("\n------------------------------------------------------------------"); + println!("ExponentiationGate (13)"); + let exp_gate: ExponentiationGate = ExponentiationGate::new(13); + println!("{:?}", exp_gate.eval_unfiltered(vars) ); + + println!("\n------------------------------------------------------------------"); + println!("MulExtensionGate"); + let mul_ext_gate: MulExtensionGate = MulExtensionGate::new_from_config(&circuit_config); + println!("{:?}", mul_ext_gate.eval_unfiltered(vars) ); + + println!("\n------------------------------------------------------------------"); + println!("PosideonGate"); + let pos_gate: PoseidonGate = PoseidonGate::new(); + println!("{:?}", pos_gate.eval_unfiltered(vars) ); + + println!("\n------------------------------------------------------------------"); + println!("PosideonMdsGate"); + let mds_gate: PoseidonMdsGate = PoseidonMdsGate::new(); + println!("{:?}", mds_gate.eval_unfiltered(vars) ); + + println!("\n------------------------------------------------------------------"); + println!("RandomAccessGate"); + let ra_gate: RandomAccessGate = RandomAccessGate::new_from_config(&circuit_config, 4); + println!("{:?}", ra_gate.eval_unfiltered(vars) ); + + println!("\n------------------------------------------------------------------"); + println!("ReducingGate"); + let red_gate: ReducingGate = ReducingGate::new(13); + println!("{:?}", red_gate.eval_unfiltered(vars) ); + + println!("\n------------------------------------------------------------------"); + println!("ReducingExtensionGate"); + let red_ext_gate: ReducingExtensionGate = ReducingExtensionGate::new(13); + println!("{:?}", red_ext_gate.eval_unfiltered(vars) ); + +} \ No newline at end of file