diff --git a/src/circuit_builder.rs b/src/circuit_builder.rs index c29fda79..3a26497e 100644 --- a/src/circuit_builder.rs +++ b/src/circuit_builder.rs @@ -11,8 +11,7 @@ use crate::field::cosets::get_unique_coset_shifts; use crate::field::extension_field::target::ExtensionTarget; use crate::field::extension_field::Extendable; use crate::gates::constant::ConstantGate; -use crate::gates::gate::{GateInstance, GatePrefixes, GateRef}; -use crate::gates::gate_tree::Tree; +use crate::gates::gate::{GateInstance, GateRef}; use crate::gates::noop::NoopGate; use crate::generator::{CopyGenerator, WitnessGenerator}; use crate::hash::hash_n_to_hash; @@ -280,12 +279,6 @@ impl, const D: usize> CircuitBuilder { /// Builds a "full circuit", with both prover and verifier data. pub fn build(mut self) -> CircuitData { - let gates = self.gates.iter().cloned().collect(); - let tree = Tree::from_gates(gates); - let prefixes = GatePrefixes::from(tree); - for (g, p) in &prefixes.prefixes { - println!("{}: {:?}", g.0.id(), p); - } let start = Instant::now(); info!( "degree before blinding & padding: {}", diff --git a/src/gates/gate_tree.rs b/src/gates/gate_tree.rs index 7ece765e..8081ab25 100644 --- a/src/gates/gate_tree.rs +++ b/src/gates/gate_tree.rs @@ -167,3 +167,71 @@ impl, const D: usize> Tree> { } } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::field::crandall_field::CrandallField; + use crate::gates::arithmetic::ArithmeticGate; + use crate::gates::base_sum::BaseSumGate; + use crate::gates::constant::ConstantGate; + use crate::gates::gmimc::GMiMCGate; + use crate::gates::interpolation::InterpolationGate; + use crate::gates::mul_extension::MulExtensionGate; + use crate::gates::noop::NoopGate; + use crate::hash::GMIMC_ROUNDS; + + #[test] + fn test_prefix_generation() { + type F = CrandallField; + const D: usize = 4; + + let gates = vec![ + NoopGate::get::(), + ConstantGate::get(), + ArithmeticGate::new(), + BaseSumGate::<4>::new(4), + GMiMCGate::::with_automatic_constants(), + InterpolationGate::new(4), + MulExtensionGate::new(), + ]; + let len = gates.len(); + + let tree = Tree::from_gates(gates.clone()); + let mut gates_with_prefix = tree.traversal(); + for (g, p) in &gates_with_prefix { + println!("{}: {:?}", g.0.id(), p); + } + + assert_eq!( + gates_with_prefix.len(), + gates.len(), + "The tree has too much or too little gates." + ); + assert!( + gates.iter().all(|g| gates_with_prefix + .iter() + .map(|(gg, _)| gg) + .find(|gg| *gg == g) + .is_some()), + "Some gates are not in the tree." + ); + assert!( + gates_with_prefix + .iter() + .all(|(g, p)| g.0.degree() + g.0.num_constants() + p.len() <= 8), + "Total degree is larger than 8." + ); + + gates_with_prefix.sort_unstable_by_key(|(g, p)| p.len()); + for i in 0..gates_with_prefix.len() { + for j in i + 1..gates_with_prefix.len() { + assert_ne!( + &gates_with_prefix[i].1, + &gates_with_prefix[j].1[0..gates_with_prefix[i].1.len()], + "Some gates share the same prefix" + ); + } + } + } +}