diff --git a/stwo_cairo_prover/src/components/range_check_unit.rs b/stwo_cairo_prover/src/components/range_check_unit.rs index 62d3e7e2..9101e2f0 100644 --- a/stwo_cairo_prover/src/components/range_check_unit.rs +++ b/stwo_cairo_prover/src/components/range_check_unit.rs @@ -2,12 +2,14 @@ use itertools::{zip_eq, Itertools}; use num_traits::Zero; use stwo_prover::core::air::accumulation::PointEvaluationAccumulator; +use stwo_prover::core::air::mask::fixed_mask_points; use stwo_prover::core::air::Component; use stwo_prover::core::backend::CpuBackend; -use stwo_prover::core::circle::CirclePoint; +use stwo_prover::core::circle::{CirclePoint, Coset}; +use stwo_prover::core::constraints::point_vanishing; use stwo_prover::core::fields::m31::BaseField; use stwo_prover::core::fields::qm31::SecureField; -use stwo_prover::core::fields::secure_column::SecureColumn; +use stwo_prover::core::fields::secure_column::{SecureColumn, SECURE_EXTENSION_DEGREE}; use stwo_prover::core::fields::FieldExpOps; use stwo_prover::core::pcs::TreeVec; use stwo_prover::core::poly::circle::{CanonicCoset, CircleEvaluation}; @@ -22,7 +24,7 @@ pub const RC_Z: &str = "RangeCheckUnit_Z"; pub const RC_COMPONENT_ID: &str = "RC_UNIT"; pub struct RangeCheckUnitComponent { - pub log_n_instances: usize, + pub log_n_instances: u32, } pub struct RangeCheckUnitTraceGenerator { @@ -30,39 +32,66 @@ pub struct RangeCheckUnitTraceGenerator { pub multiplicities: Vec, } +impl RangeCheckUnitComponent { + fn evaluate_lookup_boundary_constraints_at_point( + &self, + point: CirclePoint, + mask: &TreeVec>>, + evaluation_accumulator: &mut PointEvaluationAccumulator, + interaction_elements: &InteractionElements, + constraint_zero_domain: Coset, + ) { + let z = interaction_elements[RC_Z]; + let value = SecureField::from_partial_evals(std::array::from_fn(|i| mask[1][i][0])); + let numerator = value * (z - mask[0][0][0]) - mask[0][1][0]; + let denom = point_vanishing(constraint_zero_domain.at(0), point); + evaluation_accumulator.accumulate(numerator / denom); + } +} + impl Component for RangeCheckUnitComponent { fn n_constraints(&self) -> usize { - unimplemented!() + 1 } fn max_constraint_log_degree_bound(&self) -> u32 { - unimplemented!() + self.log_n_instances + 1 } fn n_interaction_phases(&self) -> u32 { - unimplemented!() + 2 } fn trace_log_degree_bounds(&self) -> TreeVec> { - unimplemented!() + TreeVec::new(vec![ + vec![self.log_n_instances; 2], + vec![self.log_n_instances; SECURE_EXTENSION_DEGREE], + ]) } fn mask_points( &self, - _point: CirclePoint, + point: CirclePoint, ) -> TreeVec>>> { - unimplemented!() + TreeVec::new(vec![fixed_mask_points(&vec![vec![0_usize]], point)]) } fn evaluate_constraint_quotients_at_point( &self, - _point: CirclePoint, - _mask: &TreeVec>>, - _evaluation_accumulator: &mut PointEvaluationAccumulator, - _interaction_elements: &InteractionElements, + point: CirclePoint, + mask: &TreeVec>>, + evaluation_accumulator: &mut PointEvaluationAccumulator, + interaction_elements: &InteractionElements, _lookup_values: &LookupValues, ) { - unimplemented!() + let constraint_zero_domain = CanonicCoset::new(self.log_n_instances).coset; + self.evaluate_lookup_boundary_constraints_at_point( + point, + mask, + evaluation_accumulator, + interaction_elements, + constraint_zero_domain, + ); } } @@ -143,7 +172,7 @@ impl ComponentTraceGenerator for RangeCheckUnitTraceGenerator { fn component(&self) -> RangeCheckUnitComponent { RangeCheckUnitComponent { - log_n_instances: self.max_value.checked_ilog2().unwrap() as usize, + log_n_instances: self.max_value.checked_ilog2().unwrap(), } } }