diff --git a/beacon-light-client/plonky2/circuits/src/build_final_circuit.rs b/beacon-light-client/plonky2/circuits/src/build_final_circuit.rs index bd57d9ff7..b3c3d060e 100644 --- a/beacon-light-client/plonky2/circuits/src/build_final_circuit.rs +++ b/beacon-light-client/plonky2/circuits/src/build_final_circuit.rs @@ -271,7 +271,6 @@ fn setup_commitment_mapper_targets( ) } -// TODO: test fn verify_slot_is_in_range( builder: &mut CircuitBuilder, slot: &BigUintTarget, @@ -279,21 +278,9 @@ fn verify_slot_is_in_range( ) -> () { let slots_per_epoch = builder.constant_biguint(&BigUint::from_u32(32).unwrap()); - let current_slot_min = builder.mul_biguint(¤t_epoch, &slots_per_epoch); + let slot_epoch = builder.div_biguint(slot, &slots_per_epoch); - let slots_to_add = builder.constant_biguint(&BigUint::from_u32(31).unwrap()); - - let current_slot_max = builder.add_biguint(¤t_slot_min, &slots_to_add); - - let cmp1 = builder.cmp_biguint(¤t_slot_min, &slot); - - let cmp2 = builder.cmp_biguint(&slot, ¤t_slot_max); - - let slot_is_in_range = builder.and(cmp1, cmp2); - - let _true = builder._true(); - - builder.connect(slot_is_in_range.target, _true.target); + builder.connect_biguint(&slot_epoch, current_epoch); } fn setup_proof_targets( @@ -359,3 +346,119 @@ fn create_final_config() -> CircuitConfig { ..standard_recursion_config } } + +#[cfg(test)] +mod test_verify_slot_is_in_range { + use num::{BigUint, FromPrimitive}; + use plonky2::{ + field::goldilocks_field::GoldilocksField, + iop::witness::PartialWitness, + plonk::{ + circuit_builder::CircuitBuilder, circuit_data::CircuitConfig, + config::PoseidonGoldilocksConfig, + }, + }; + + use crate::{ + biguint::{CircuitBuilderBiguint, WitnessBigUint}, + build_final_circuit::verify_slot_is_in_range, + }; + + #[test] + fn test_verify_slot_is_in_range() -> std::result::Result<(), anyhow::Error> { + const D: usize = 2; + type C = PoseidonGoldilocksConfig; + type F = GoldilocksField; + + let mut pw = PartialWitness::new(); + + let mut builder = CircuitBuilder::::new(CircuitConfig::standard_recursion_config()); + + let slot_target = builder.add_virtual_biguint_target(2); + let current_epoch = builder.add_virtual_biguint_target(2); + + verify_slot_is_in_range(&mut builder, &slot_target, ¤t_epoch); + + pw.set_biguint_target(&slot_target, &BigUint::from_u64(6953401).unwrap()); + pw.set_biguint_target(¤t_epoch, &BigUint::from_u64(217293).unwrap()); + + let data = builder.build::(); + let proof = data.prove(pw)?; + + data.verify(proof) + } + + #[test] + fn test_verify_slot_is_in_range_first_slot_in_epoch() -> std::result::Result<(), anyhow::Error> + { + const D: usize = 2; + type C = PoseidonGoldilocksConfig; + type F = GoldilocksField; + + let mut pw = PartialWitness::new(); + + let mut builder = CircuitBuilder::::new(CircuitConfig::standard_recursion_config()); + + let slot_target = builder.add_virtual_biguint_target(2); + let current_epoch = builder.add_virtual_biguint_target(2); + + verify_slot_is_in_range(&mut builder, &slot_target, ¤t_epoch); + + pw.set_biguint_target(&slot_target, &BigUint::from_u64(7314752).unwrap()); + pw.set_biguint_target(¤t_epoch, &BigUint::from_u64(228586).unwrap()); + + let data = builder.build::(); + let proof = data.prove(pw)?; + + data.verify(proof) + } + + #[test] + fn test_verify_slot_is_in_range_last_slot_in_epoch() -> std::result::Result<(), anyhow::Error> { + const D: usize = 2; + type C = PoseidonGoldilocksConfig; + type F = GoldilocksField; + + let mut pw = PartialWitness::new(); + + let mut builder = CircuitBuilder::::new(CircuitConfig::standard_recursion_config()); + + let slot_target = builder.add_virtual_biguint_target(2); + let current_epoch = builder.add_virtual_biguint_target(2); + + verify_slot_is_in_range(&mut builder, &slot_target, ¤t_epoch); + + pw.set_biguint_target(&slot_target, &BigUint::from_u64(7314751).unwrap()); + pw.set_biguint_target(¤t_epoch, &BigUint::from_u64(228585).unwrap()); + + let data = builder.build::(); + let proof = data.prove(pw)?; + + data.verify(proof) + } + + #[test] + #[should_panic] + fn test_verify_slot_is_not_in_range() -> () { + const D: usize = 2; + type C = PoseidonGoldilocksConfig; + type F = GoldilocksField; + + let mut pw = PartialWitness::new(); + + let mut builder = CircuitBuilder::::new(CircuitConfig::standard_recursion_config()); + + let slot_target = builder.add_virtual_biguint_target(2); + let current_epoch = builder.add_virtual_biguint_target(2); + + verify_slot_is_in_range(&mut builder, &slot_target, ¤t_epoch); + + pw.set_biguint_target(&slot_target, &BigUint::from_u64(7314751).unwrap()); + pw.set_biguint_target(¤t_epoch, &BigUint::from_u64(228586).unwrap()); + + let data = builder.build::(); + let proof = data.prove(pw).unwrap(); + + data.verify(proof).unwrap(); + } +}