Skip to content

Commit

Permalink
add TestLessThanOrEqual match case + start implementing EvalCircuit Hint
Browse files Browse the repository at this point in the history
  • Loading branch information
FrancoGiachetta committed Sep 19, 2024
1 parent 5f8a011 commit 7a5998b
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 3 deletions.
30 changes: 30 additions & 0 deletions cairo_programs/cairo-1-programs/circuit.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use core::circuit::{
RangeCheck96, AddMod, MulMod, u96, CircuitElement, CircuitInput, circuit_add,
circuit_sub, circuit_mul, circuit_inverse, EvalCircuitTrait, u384,
CircuitOutputsTrait, CircuitModulus, AddInputResultTrait, CircuitInputs,
};

fn main() -> u384 {
let in1 = CircuitElement::<CircuitInput<0>> {};
let in2 = CircuitElement::<CircuitInput<1>> {};
let add1 = circuit_add(in1, in2);
let mul1 = circuit_mul(add1, in1);
let mul2 = circuit_mul(mul1, add1);
let inv1 = circuit_inverse(mul2);
let sub1 = circuit_sub(inv1, in2);
let sub2 = circuit_sub(sub1, mul2);
let inv2 = circuit_inverse(sub2);
let add2 = circuit_add(inv2, inv2);

let modulus = TryInto::<_, CircuitModulus>::try_into([17, 14, 14, 14]).unwrap();

let outputs = (add2,)
.new_inputs()
.next([9, 2, 9, 3])
.next([5, 7, 0, 8])
.done()
.eval(modulus)
.unwrap();

outputs.get_output(add2)
}
72 changes: 72 additions & 0 deletions vm/src/hint_processor/cairo_1_hint_processor/circuit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
use ark_ff::Zero;
use num_bigint::BigUint;

use crate::{types::relocatable::{MaybeRelocatable, Relocatable}, vm::vm_core::VirtualMachine};

// Represents the number of limbs use to represent a single value in a circuit
const LIMBS_COUNT: usize = 4;

struct CircuitInstance<'a> {
vm: &'a mut VirtualMachine,
values_ptr: Relocatable,
add_mod_offsets: Relocatable,
mul_mod_offsets: Relocatable,
modulus: BigUint,
}

impl CircuitInstance<'_> {
fn fill_add_gate(&mut self, index: usize) -> bool {todo!()}
fn fill_mul_gate(&mut self, index: usize) -> bool {todo!()}
}

fn read_circuit_value(vm: &mut VirtualMachine, add: Relocatable) -> Option<BigUint> {
let mut res = BigUint::zero();

for l in (0..LIMBS_COUNT).rev() {
let add_l = (add + l).unwrap();
match vm.get_maybe(&add_l) {
Some(MaybeRelocatable::Int(limb)) => res = (res << 96) + limb.to_biguint(),
_ => return None
}
}

Some(res)
}

pub fn fill_values(
vm: &mut VirtualMachine,
values_ptr: Relocatable,
add_mod_offsets: Relocatable,
n_add_mods: usize,
mul_mod_offsets: Relocatable,
n_mul_mods: usize,
modulus_ptr: Relocatable,
) -> usize {
let modulus = read_circuit_value(vm, modulus_ptr).unwrap();
let circuit = CircuitInstance {vm, values_ptr, add_mod_offsets, mul_mod_offsets, modulus};

let mut addmod_idx = 0;
let mut mulmod_idx = 0;

// A circuit evaluation can only fail through a mulmod operation
let mut first_failure_idx = n_mul_mods;

loop {
while addmod_idx < n_add_mods {
if !circuit.fill_add_gate() {
break;
}
addmod_idx += 1;
}

if mulmod_idx == n_mul_mods {
break;
}

if !circuit.fill_mul_gate(3 * mulmod_idx) && first_failure_idx == n_mul_mods {
first_failure_idx = mulmod_idx;
}
mulmod_idx += 1;
}
0
}
58 changes: 55 additions & 3 deletions vm/src/hint_processor/cairo_1_hint_processor/hint_processor.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use super::circuit::fill_values;
use super::dict_manager::DictManagerExecScope;
use super::hint_processor_utils::*;
use crate::any_box;
Expand Down Expand Up @@ -85,9 +86,12 @@ impl Cairo1HintProcessor {
Hint::Core(CoreHintBase::Core(CoreHint::TestLessThan { lhs, rhs, dst })) => {
self.test_less_than(vm, lhs, rhs, dst)
}
Hint::Core(CoreHintBase::Core(CoreHint::TestLessThanOrEqual { lhs, rhs, dst })) => {
self.test_less_than_or_equal(vm, lhs, rhs, dst)
}
Hint::Core(CoreHintBase::Core(CoreHint::TestLessThanOrEqual { lhs, rhs, dst }))
| Hint::Core(CoreHintBase::Core(CoreHint::TestLessThanOrEqualAddress {
lhs,
rhs,
dst,
})) => self.test_less_than_or_equal(vm, lhs, rhs, dst),
Hint::Core(CoreHintBase::Deprecated(DeprecatedHint::Felt252DictRead {
dict_ptr,
key,
Expand Down Expand Up @@ -274,6 +278,12 @@ impl Cairo1HintProcessor {
t_or_k0,
t_or_k1,
),
Hint::Core(CoreHintBase::Core(CoreHint::EvalCircuit {
n_add_mods,
add_mod_builtin,
n_mul_mods,
mul_mod_builtin,
})) => self.eval_circuit(vm, n_add_mods, add_mod_builtin, n_mul_mods, mul_mod_builtin),
Hint::Starknet(StarknetHint::Cheatcode { selector, .. }) => {
let selector = &selector.value.to_bytes_be().1;
let selector = crate::stdlib::str::from_utf8(selector).map_err(|_| {
Expand Down Expand Up @@ -1192,6 +1202,48 @@ impl Cairo1HintProcessor {
}
Ok(())
}
fn eval_circuit(
&self,
vm: &mut VirtualMachine,
n_add_mods: &ResOperand,
add_mod_builtin_ptr: &ResOperand,
n_mul_mods: &ResOperand,
mul_mod_builtin_ptr: &ResOperand,
) -> Result<(), HintError> {
let n_add_mods = get_val(vm, n_add_mods)?.to_usize().unwrap();
let n_mul_mods = get_val(vm, n_mul_mods)?.to_usize().unwrap();

let (add_mod_builtin_base, add_mod_builtin_offset) = extract_buffer(add_mod_builtin_ptr)?;
let (mul_mod_builtin_base, mul_mod_builtin_offset) = extract_buffer(mul_mod_builtin_ptr)?;

let add_mod_builtin_address = get_ptr(vm, add_mod_builtin_base, &add_mod_builtin_offset)?;
let mul_mod_builtin_address = get_ptr(vm, mul_mod_builtin_base, &mul_mod_builtin_offset)?;

let modulus_ptr = mul_mod_builtin_address;
// The offset of the values pointer inside the mul_mod_builtin
let values_offset = 4;
// The offset of the offsets pointer inside the mul_mod_builtin
let offsets_offset = 5;

let values_ptr = vm.get_relocatable((mul_mod_builtin_address + values_offset)?)?;
let mul_mod_offsets = vm.get_relocatable((mul_mod_builtin_address + offsets_offset)?)?;
let add_mod_offsets = if n_add_mods == 0 {
mul_mod_offsets
} else {
vm.get_relocatable((add_mod_builtin_address + offsets_offset)?)?
};

let n_computed_gates = fill_values(
vm,
values_ptr,
add_mod_offsets,
n_add_mods,
mul_mod_offsets,
n_mul_mods,
modulus_ptr,
);
Ok(())
}
}

impl HintProcessorLogic for Cairo1HintProcessor {
Expand Down
1 change: 1 addition & 0 deletions vm/src/hint_processor/cairo_1_hint_processor/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod circuit;
pub mod dict_manager;
pub mod hint_processor;
pub mod hint_processor_utils;

0 comments on commit 7a5998b

Please sign in to comment.