Skip to content

Commit

Permalink
fix(plonky2): Improve verify slot is in range function
Browse files Browse the repository at this point in the history
  • Loading branch information
Dimo99 authored and stefan-nikolov96 committed Sep 18, 2023
1 parent 7728d8b commit d6eb39e
Showing 1 changed file with 118 additions and 15 deletions.
133 changes: 118 additions & 15 deletions beacon-light-client/plonky2/circuits/src/build_final_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,29 +271,16 @@ fn setup_commitment_mapper_targets(
)
}

// TODO: test
fn verify_slot_is_in_range(
builder: &mut CircuitBuilder<GoldilocksField, 2>,
slot: &BigUintTarget,
current_epoch: &BigUintTarget,
) -> () {
let slots_per_epoch = builder.constant_biguint(&BigUint::from_u32(32).unwrap());

let current_slot_min = builder.mul_biguint(&current_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(&current_slot_min, &slots_to_add);

let cmp1 = builder.cmp_biguint(&current_slot_min, &slot);

let cmp2 = builder.cmp_biguint(&slot, &current_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(
Expand Down Expand Up @@ -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::<F, D>::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, &current_epoch);

pw.set_biguint_target(&slot_target, &BigUint::from_u64(6953401).unwrap());
pw.set_biguint_target(&current_epoch, &BigUint::from_u64(217293).unwrap());

let data = builder.build::<C>();
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::<F, D>::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, &current_epoch);

pw.set_biguint_target(&slot_target, &BigUint::from_u64(7314752).unwrap());
pw.set_biguint_target(&current_epoch, &BigUint::from_u64(228586).unwrap());

let data = builder.build::<C>();
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::<F, D>::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, &current_epoch);

pw.set_biguint_target(&slot_target, &BigUint::from_u64(7314751).unwrap());
pw.set_biguint_target(&current_epoch, &BigUint::from_u64(228585).unwrap());

let data = builder.build::<C>();
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::<F, D>::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, &current_epoch);

pw.set_biguint_target(&slot_target, &BigUint::from_u64(7314751).unwrap());
pw.set_biguint_target(&current_epoch, &BigUint::from_u64(228586).unwrap());

let data = builder.build::<C>();
let proof = data.prove(pw).unwrap();

data.verify(proof).unwrap();
}
}

0 comments on commit d6eb39e

Please sign in to comment.