From 64f91390206b09be852b0b35a0c9b522f662c45c Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Mon, 5 May 2025 10:40:17 -0300 Subject: [PATCH 01/41] change initial gas due to overflows --- debug_utils/sierra-emu/tests/corelib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debug_utils/sierra-emu/tests/corelib.rs b/debug_utils/sierra-emu/tests/corelib.rs index 50bd5d5ea..052d99643 100644 --- a/debug_utils/sierra-emu/tests/corelib.rs +++ b/debug_utils/sierra-emu/tests/corelib.rs @@ -104,7 +104,7 @@ fn run_tests(compiled: TestCompilation) -> Vec { program.clone(), EntryPoint::String(name.clone()), vec![], - u64::MAX, + test.available_gas.map(|g| g as u64).unwrap_or_default(), ) }); From b604c090c887ac159528c076a767e84071b333bc Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Mon, 5 May 2025 15:31:42 -0300 Subject: [PATCH 02/41] fix some libfuncs in circuits --- debug_utils/sierra-emu/src/value.rs | 17 ++- debug_utils/sierra-emu/src/vm/circuit.rs | 143 +++++++++++++++------ debug_utils/sierra-emu/tests/common/mod.rs | 4 +- 3 files changed, 119 insertions(+), 45 deletions(-) diff --git a/debug_utils/sierra-emu/src/value.rs b/debug_utils/sierra-emu/src/value.rs index 6f37a2d71..596806237 100644 --- a/debug_utils/sierra-emu/src/value.rs +++ b/debug_utils/sierra-emu/src/value.rs @@ -26,8 +26,11 @@ pub enum Value { value: BigInt, }, Circuit(Vec), + CircuitOutputs { + circuits: Vec, + modulus: BigUint, + }, CircuitModulus(BigUint), - CircuitOutputs(Vec), Enum { self_ty: ConcreteTypeId, index: usize, @@ -166,14 +169,14 @@ impl Value { // Circuit related types CoreTypeConcrete::Circuit(selector) => match selector { - CircuitTypeConcrete::Circuit(_) => matches!(self, Self::Circuit(_)), - CircuitTypeConcrete::CircuitData(_) => matches!(self, Self::Circuit(_)), - CircuitTypeConcrete::CircuitOutputs(_) => matches!(self, Self::CircuitOutputs(_)), - CircuitTypeConcrete::CircuitInput(_) => matches!(self, Self::Unit), - CircuitTypeConcrete::CircuitInputAccumulator(_) => matches!(self, Self::Circuit(_)), + CircuitTypeConcrete::Circuit(_) + | CircuitTypeConcrete::CircuitData(_) + | CircuitTypeConcrete::CircuitInputAccumulator(_) + | CircuitTypeConcrete::CircuitOutputs(_) => matches!(self, Self::Circuit(_)), CircuitTypeConcrete::CircuitModulus(_) => matches!(self, Self::CircuitModulus(_)), CircuitTypeConcrete::U96Guarantee(_) => matches!(self, Self::U128(_)), - CircuitTypeConcrete::CircuitDescriptor(_) + CircuitTypeConcrete::CircuitInput(_) + | CircuitTypeConcrete::CircuitDescriptor(_) | CircuitTypeConcrete::CircuitFailureGuarantee(_) | CircuitTypeConcrete::AddMod(_) | CircuitTypeConcrete::MulMod(_) diff --git a/debug_utils/sierra-emu/src/vm/circuit.rs b/debug_utils/sierra-emu/src/vm/circuit.rs index 17166148d..ea05293a4 100644 --- a/debug_utils/sierra-emu/src/vm/circuit.rs +++ b/debug_utils/sierra-emu/src/vm/circuit.rs @@ -12,8 +12,37 @@ use cairo_lang_sierra::{ program_registry::ProgramRegistry, }; use num_bigint::{BigInt, BigUint, Sign, ToBigInt}; +use num_traits::{One, Zero}; use smallvec::smallvec; +fn u384_to_struct(num: BigUint) -> Value { + let output_big = num.to_bigint().unwrap(); + + let mask: BigInt = BigInt::from_bytes_be(Sign::Plus, &[255; 12]); + + let l0: BigInt = &output_big & &mask; + let l1: BigInt = (&output_big >> 96) & &mask; + let l2: BigInt = (&output_big >> 192) & &mask; + let l3: BigInt = (output_big >> 288) & &mask; + + let range = BigInt::ZERO..(BigInt::from(1) << 96); + Value::Struct(vec![ + Value::BoundedInt { + range: range.clone(), + value: l0, + }, + Value::BoundedInt { + range: range.clone(), + value: l1, + }, + Value::BoundedInt { + range: range.clone(), + value: l2, + }, + Value::BoundedInt { range, value: l3 }, + ]) +} + pub fn eval( registry: &ProgramRegistry, selector: &CircuitConcreteLibfunc, @@ -57,7 +86,6 @@ pub fn eval_add_input( else { panic!() }; - assert_ne!(values.len(), values.capacity()); let [Value::U128(l0), Value::U128(l1), Value::U128(l2), Value::U128(l3)]: [Value; 4] = members.try_into().unwrap() @@ -171,7 +199,14 @@ pub fn eval_eval( if success { EvalAction::NormalBranch( 0, - smallvec![add_mod, mul_mod, Value::CircuitOutputs(values)], + smallvec![ + add_mod, + mul_mod, + Value::CircuitOutputs { + circuits: values, + modulus + } + ], ) } else { EvalAction::NormalBranch(1, smallvec![add_mod, mul_mod, Value::Unit, Value::Unit]) @@ -183,7 +218,11 @@ pub fn eval_get_output( _info: &ConcreteGetOutputLibFunc, args: Vec, ) -> EvalAction { - let [Value::CircuitOutputs(outputs)]: [Value; 1] = args.try_into().unwrap() else { + let [Value::CircuitOutputs { + circuits: outputs, + modulus, + }]: [Value; 1] = args.try_into().unwrap() + else { panic!() }; let circuit_info = match _registry.get_type(&_info.circuit_ty).unwrap() { @@ -193,41 +232,66 @@ pub fn eval_get_output( let gate_offset = *circuit_info.values.get(&_info.output_ty).unwrap(); let output_idx = gate_offset - 1 - circuit_info.n_inputs; let output = outputs[output_idx].to_owned(); - let output_big = output.to_bigint().unwrap(); - - let mask: BigInt = BigInt::from_bytes_be(Sign::Plus, &[255; 12]); - let l0: BigInt = &output_big & &mask; - let l1: BigInt = (&output_big >> 96) & &mask; - let l2: BigInt = (&output_big >> 192) & &mask; - let l3: BigInt = (output_big >> 288) & &mask; - - let range = BigInt::ZERO..(BigInt::from(1) << 96); - let vec_values = vec![ - Value::BoundedInt { - range: range.clone(), - value: l0, - }, - Value::BoundedInt { - range: range.clone(), - value: l1, - }, - Value::BoundedInt { - range: range.clone(), - value: l2, - }, - Value::BoundedInt { range, value: l3 }, - ]; + let output_struct = u384_to_struct(output); + let modulus = u384_to_struct(modulus); - EvalAction::NormalBranch(0, smallvec![Value::Struct(vec_values), Value::Unit]) + EvalAction::NormalBranch( + 0, + smallvec![ + output_struct.clone(), + Value::Struct(vec![output_struct, modulus]), + Value::Unit + ], + ) } pub fn eval_u96_limbs_less_than_guarantee_verify( _registry: &ProgramRegistry, - _info: &ConcreteU96LimbsLessThanGuaranteeVerifyLibfunc, - _args: Vec, + info: &ConcreteU96LimbsLessThanGuaranteeVerifyLibfunc, + args: Vec, ) -> EvalAction { - EvalAction::NormalBranch(0, smallvec![Value::Unit]) + let [Value::Struct(garantee)]: [Value; 1] = args.try_into().unwrap() else { + panic!() + }; + let limb_count = info.limb_count; + let Value::Struct(gate) = garantee.get(0).unwrap() else { + panic!(); + }; + let Value::Struct(modulus) = garantee.get(1).unwrap() else { + panic!(); + }; + let Value::BoundedInt { + value: gate_last_limb, + range: u96_range, + } = &gate[limb_count - 1] + else { + panic!(); + }; + let Value::BoundedInt { + value: modulus_last_limb, + .. + } = &modulus[limb_count - 1] + else { + panic!(); + }; + let diff = modulus_last_limb - gate_last_limb; + + if (modulus_last_limb - gate_last_limb) != BigInt::zero() { + EvalAction::NormalBranch( + 1, + smallvec![Value::BoundedInt { + range: u96_range.clone(), + value: diff + }], + ) + } else { + // if there is no diff, build a new garantee, skipping the last limb + let new_gate = Value::Struct(gate[0..limb_count].to_vec()); + let new_modulus = Value::Struct(modulus[0..limb_count].to_vec()); + + EvalAction::NormalBranch(0, smallvec![Value::Struct(vec![new_gate, new_modulus])]) + } } pub fn eval_u96_single_limb_less_than_guarantee_verify( @@ -331,11 +395,11 @@ pub fn eval_try_into_circuit_modulus( let value = l0 | (l1 << 96) | (l2 << 192) | (l3 << 288); - // a CircuitModulus must not be neither 0 nor 1 - assert_ne!(value, 0_u8.into()); - assert_ne!(value, 1_u8.into()); - - EvalAction::NormalBranch(0, smallvec![Value::CircuitModulus(value)]) + if value > BigUint::one() { + EvalAction::NormalBranch(0, smallvec![Value::CircuitModulus(value)]) + } else { + EvalAction::NormalBranch(1, smallvec![]) + } } pub fn eval_into_u96_guarantee( @@ -343,10 +407,15 @@ pub fn eval_into_u96_guarantee( _info: &SignatureAndTypeConcreteLibfunc, args: Vec, ) -> EvalAction { - let [Value::BoundedInt { range, value }]: [Value; 1] = args.try_into().unwrap() else { + let [Value::BoundedInt { range, mut value }]: [Value; 1] = args.try_into().unwrap() else { panic!() }; assert_eq!(range, BigInt::ZERO..(BigInt::from(1) << 96)); + // offset by the lower bound to get the actual value + if range.start > BigInt::ZERO { + value = range.start; + } + EvalAction::NormalBranch(0, smallvec![Value::U128(value.try_into().unwrap())]) } diff --git a/debug_utils/sierra-emu/tests/common/mod.rs b/debug_utils/sierra-emu/tests/common/mod.rs index fa77478ad..92233b773 100644 --- a/debug_utils/sierra-emu/tests/common/mod.rs +++ b/debug_utils/sierra-emu/tests/common/mod.rs @@ -20,7 +20,9 @@ pub fn value_to_felt(value: &Value) -> Vec { costs.mul_mod.into(), ], Value::CircuitModulus(value) => vec![value.into()], - Value::Circuit(data) | Value::CircuitOutputs(data) => data.iter().map(Felt::from).collect(), + Value::Circuit(data) | Value::CircuitOutputs { circuits: data, .. } => { + data.iter().map(Felt::from).collect() + } Value::EcPoint { x, y } => { vec![*x, *y] } From 8cc92239c31b879b45992ad1109be482c1dd679d Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Mon, 5 May 2025 17:25:43 -0300 Subject: [PATCH 03/41] fix is() for circuits --- debug_utils/sierra-emu/src/value.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debug_utils/sierra-emu/src/value.rs b/debug_utils/sierra-emu/src/value.rs index 596806237..b21197a3f 100644 --- a/debug_utils/sierra-emu/src/value.rs +++ b/debug_utils/sierra-emu/src/value.rs @@ -171,8 +171,8 @@ impl Value { CoreTypeConcrete::Circuit(selector) => match selector { CircuitTypeConcrete::Circuit(_) | CircuitTypeConcrete::CircuitData(_) - | CircuitTypeConcrete::CircuitInputAccumulator(_) - | CircuitTypeConcrete::CircuitOutputs(_) => matches!(self, Self::Circuit(_)), + | CircuitTypeConcrete::CircuitInputAccumulator(_) => matches!(self, Self::Circuit(_)), + CircuitTypeConcrete::CircuitOutputs(_) => matches!(self, Self::CircuitOutputs { .. }), CircuitTypeConcrete::CircuitModulus(_) => matches!(self, Self::CircuitModulus(_)), CircuitTypeConcrete::U96Guarantee(_) => matches!(self, Self::U128(_)), CircuitTypeConcrete::CircuitInput(_) From d8ec998ec9137f31c2e91e338eaff2e27de6a4c0 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Mon, 5 May 2025 17:44:16 -0300 Subject: [PATCH 04/41] remove Value::Unit from return values in get_output --- debug_utils/sierra-emu/src/value.rs | 8 ++++++-- debug_utils/sierra-emu/src/vm/circuit.rs | 1 - 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/debug_utils/sierra-emu/src/value.rs b/debug_utils/sierra-emu/src/value.rs index b21197a3f..e4508eabb 100644 --- a/debug_utils/sierra-emu/src/value.rs +++ b/debug_utils/sierra-emu/src/value.rs @@ -171,8 +171,12 @@ impl Value { CoreTypeConcrete::Circuit(selector) => match selector { CircuitTypeConcrete::Circuit(_) | CircuitTypeConcrete::CircuitData(_) - | CircuitTypeConcrete::CircuitInputAccumulator(_) => matches!(self, Self::Circuit(_)), - CircuitTypeConcrete::CircuitOutputs(_) => matches!(self, Self::CircuitOutputs { .. }), + | CircuitTypeConcrete::CircuitInputAccumulator(_) => { + matches!(self, Self::Circuit(_)) + } + CircuitTypeConcrete::CircuitOutputs(_) => { + matches!(self, Self::CircuitOutputs { .. }) + } CircuitTypeConcrete::CircuitModulus(_) => matches!(self, Self::CircuitModulus(_)), CircuitTypeConcrete::U96Guarantee(_) => matches!(self, Self::U128(_)), CircuitTypeConcrete::CircuitInput(_) diff --git a/debug_utils/sierra-emu/src/vm/circuit.rs b/debug_utils/sierra-emu/src/vm/circuit.rs index ea05293a4..4a33b42f9 100644 --- a/debug_utils/sierra-emu/src/vm/circuit.rs +++ b/debug_utils/sierra-emu/src/vm/circuit.rs @@ -241,7 +241,6 @@ pub fn eval_get_output( smallvec![ output_struct.clone(), Value::Struct(vec![output_struct, modulus]), - Value::Unit ], ) } From 715f1c9f55c4e1bd74da00e9349d12b6fb09ec8b Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Mon, 5 May 2025 17:59:35 -0300 Subject: [PATCH 05/41] match U96LimbsLessThanGuarantee correctly --- debug_utils/sierra-emu/src/value.rs | 2 +- debug_utils/sierra-emu/src/vm/circuit.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/debug_utils/sierra-emu/src/value.rs b/debug_utils/sierra-emu/src/value.rs index e4508eabb..b265a50f4 100644 --- a/debug_utils/sierra-emu/src/value.rs +++ b/debug_utils/sierra-emu/src/value.rs @@ -190,7 +190,7 @@ impl Value { | CircuitTypeConcrete::MulModGate(_) | CircuitTypeConcrete::SubModGate(_) | CircuitTypeConcrete::U96LimbsLessThanGuarantee(_) => { - matches!(self, Self::Unit) + matches!(self, Self::Struct(_)) } }, CoreTypeConcrete::Const(info) => self.is(registry, &info.inner_ty), diff --git a/debug_utils/sierra-emu/src/vm/circuit.rs b/debug_utils/sierra-emu/src/vm/circuit.rs index 4a33b42f9..f68f92548 100644 --- a/debug_utils/sierra-emu/src/vm/circuit.rs +++ b/debug_utils/sierra-emu/src/vm/circuit.rs @@ -254,7 +254,7 @@ pub fn eval_u96_limbs_less_than_guarantee_verify( panic!() }; let limb_count = info.limb_count; - let Value::Struct(gate) = garantee.get(0).unwrap() else { + let Value::Struct(gate) = garantee.first().unwrap() else { panic!(); }; let Value::Struct(modulus) = garantee.get(1).unwrap() else { From 11dae8c6362848444a418313d062f7fdebc550e1 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Tue, 6 May 2025 16:11:27 -0300 Subject: [PATCH 06/41] some corrections to circuits --- debug_utils/sierra-emu/Cargo.toml | 1 + debug_utils/sierra-emu/src/value.rs | 16 ++-- debug_utils/sierra-emu/src/vm.rs | 2 +- debug_utils/sierra-emu/src/vm/circuit.rs | 115 ++++++++++++++++++----- debug_utils/sierra-emu/tests/corelib.rs | 1 + 5 files changed, 106 insertions(+), 29 deletions(-) diff --git a/debug_utils/sierra-emu/Cargo.toml b/debug_utils/sierra-emu/Cargo.toml index 71face6be..b0517483a 100644 --- a/debug_utils/sierra-emu/Cargo.toml +++ b/debug_utils/sierra-emu/Cargo.toml @@ -25,6 +25,7 @@ k256 = "0.13.4" keccak = "0.1.5" num-bigint = "0.4.6" num-traits = "0.2.19" +num-integer = "0.1.46" p256 = "0.13.2" rand = "0.8.5" sec1 = { version = "0.7.3", features = ["std"] } diff --git a/debug_utils/sierra-emu/src/value.rs b/debug_utils/sierra-emu/src/value.rs index b265a50f4..d15c5a374 100644 --- a/debug_utils/sierra-emu/src/value.rs +++ b/debug_utils/sierra-emu/src/value.rs @@ -179,19 +179,21 @@ impl Value { } CircuitTypeConcrete::CircuitModulus(_) => matches!(self, Self::CircuitModulus(_)), CircuitTypeConcrete::U96Guarantee(_) => matches!(self, Self::U128(_)), - CircuitTypeConcrete::CircuitInput(_) + CircuitTypeConcrete::CircuitInput(_) => { + matches!(self, Self::Struct(_)) + } + CircuitTypeConcrete::U96LimbsLessThanGuarantee(_) => { + matches!(self, Self::Struct(_)) + } + CircuitTypeConcrete::AddMod(_) + | CircuitTypeConcrete::MulMod(_) | CircuitTypeConcrete::CircuitDescriptor(_) | CircuitTypeConcrete::CircuitFailureGuarantee(_) - | CircuitTypeConcrete::AddMod(_) - | CircuitTypeConcrete::MulMod(_) | CircuitTypeConcrete::AddModGate(_) | CircuitTypeConcrete::CircuitPartialOutputs(_) | CircuitTypeConcrete::InverseGate(_) | CircuitTypeConcrete::MulModGate(_) - | CircuitTypeConcrete::SubModGate(_) - | CircuitTypeConcrete::U96LimbsLessThanGuarantee(_) => { - matches!(self, Self::Struct(_)) - } + | CircuitTypeConcrete::SubModGate(_) => matches!(self, Self::Unit), }, CoreTypeConcrete::Const(info) => self.is(registry, &info.inner_ty), CoreTypeConcrete::EcOp(_) => matches!(self, Self::Unit), diff --git a/debug_utils/sierra-emu/src/vm.rs b/debug_utils/sierra-emu/src/vm.rs index b82b71c69..aae0e7879 100644 --- a/debug_utils/sierra-emu/src/vm.rs +++ b/debug_utils/sierra-emu/src/vm.rs @@ -308,7 +308,7 @@ impl VirtualMachine { match &self.program.statements[frame.pc.0] { GenStatement::Invocation(invocation) => { let libfunc = self.registry.get_libfunc(&invocation.libfunc_id).unwrap(); - debug!( + dbg!( "Executing invocation of libfunc: {}", libfunc_to_name(libfunc) ); diff --git a/debug_utils/sierra-emu/src/vm/circuit.rs b/debug_utils/sierra-emu/src/vm/circuit.rs index f68f92548..3c9d31b1d 100644 --- a/debug_utils/sierra-emu/src/vm/circuit.rs +++ b/debug_utils/sierra-emu/src/vm/circuit.rs @@ -1,5 +1,5 @@ use super::EvalAction; -use crate::Value; +use crate::{debug::debug_signature, Value}; use cairo_lang_sierra::{ extensions::{ circuit::{ @@ -12,7 +12,8 @@ use cairo_lang_sierra::{ program_registry::ProgramRegistry, }; use num_bigint::{BigInt, BigUint, Sign, ToBigInt}; -use num_traits::{One, Zero}; +use num_integer::{ExtendedGcd, Integer}; +use num_traits::{One, Signed, Zero}; use smallvec::smallvec; fn u384_to_struct(num: BigUint) -> Value { @@ -43,6 +44,31 @@ fn u384_to_struct(num: BigUint) -> Value { ]) } +fn modular_inverse(num: &BigInt, modulus: &BigUint) -> (bool, BigUint) { + let ExtendedGcd { gcd, x, .. } = num + .to_bigint() + .unwrap() + .extended_gcd(&modulus.to_bigint().unwrap()); + let gcd = gcd.to_biguint().unwrap(); + + if gcd.is_one() { + // calculate positive modulus + let num_mod = x.magnitude().mod_floor(modulus); + + return ( + true, + if num.is_negative() { + modulus - num_mod + } else { + num_mod + }, + ); + } + + // If there's no inverse, find the value which nullifys the operation + (false, modulus / gcd) +} + pub fn eval( registry: &ProgramRegistry, selector: &CircuitConcreteLibfunc, @@ -172,14 +198,17 @@ pub fn eval_eval( outputs[mul_gate.output] = Some((l * r) % &modulus); } (None, Some(r)) => { - let res = match r.modinv(&modulus) { - Some(inv) => inv, - None => { - panic!("attempt to divide by 0"); - } - }; - // if it is a inv_gate the output index is store in lhs - outputs[mul_gate.lhs] = Some(res); + let r = r.to_bigint().unwrap(); + let (sucess, res) = modular_inverse(&r, &modulus); + + if sucess { + // if it is a inv_gate the output index is store in lhs + outputs[mul_gate.lhs] = Some(res); + } else { + // Since we don't calculate CircuitPartialOutputs + // perform an early break + break false; + } } // this state should not be reached since it would mean that // not all the circuit's inputs where filled @@ -190,13 +219,13 @@ pub fn eval_eval( } }; - let values = outputs - .into_iter() - .skip(1 + circ_info.n_inputs) - .collect::>>() - .expect("The circuit cannot be calculated"); - if success { + let values = outputs + .into_iter() + .skip(1 + circ_info.n_inputs) + .collect::>>() + .expect("The circuit cannot be calculated"); + EvalAction::NormalBranch( 0, smallvec![ @@ -296,20 +325,23 @@ pub fn eval_u96_limbs_less_than_guarantee_verify( pub fn eval_u96_single_limb_less_than_guarantee_verify( _registry: &ProgramRegistry, _info: &SignatureOnlyConcreteLibfunc, - _args: Vec, + args: Vec, ) -> EvalAction { - EvalAction::NormalBranch(0, smallvec![Value::U128(0)]) + let [range_check_96 @ Value::Unit, garantee]: [Value; 2] = args.try_into().unwrap() else { + panic!() + }; + EvalAction::NormalBranch(0, smallvec![range_check_96, garantee]) } pub fn eval_u96_guarantee_verify( _registry: &ProgramRegistry, _info: &SignatureOnlyConcreteLibfunc, - _args: Vec, + args: Vec, ) -> EvalAction { - let [range_check_96 @ Value::Unit, _]: [Value; 2] = _args.try_into().unwrap() else { + let [range_check_96 @ Value::Unit, garantee]: [Value; 2] = args.try_into().unwrap() else { panic!() }; - EvalAction::NormalBranch(0, smallvec![range_check_96]) + EvalAction::NormalBranch(0, smallvec![range_check_96, garantee]) } pub fn eval_failure_guarantee_verify( @@ -418,3 +450,44 @@ pub fn eval_into_u96_guarantee( EvalAction::NormalBranch(0, smallvec![Value::U128(value.try_into().unwrap())]) } + +#[cfg(test)] +mod tests { + use crate::{load_cairo, test_utils::run_test_program}; + + #[test] + fn test_failure() { + let (_, program) = load_cairo!( + use core::circuit::{ + AddInputResultTrait, AddMod, CircuitElement, CircuitInput, CircuitInputs, + CircuitModulus, CircuitOutputsTrait, EvalCircuitTrait, MulMod, RangeCheck96, + circuit_add, circuit_inverse, circuit_mul, circuit_sub, u384, u96, + }; + use core::num::traits::Zero; + use core::traits::TryInto; + + fn main() { + let _in0 = CircuitElement::> {}; + let _out0 = circuit_inverse(_in0); + + let _modulus = TryInto::<_, CircuitModulus>::try_into([55, 0, 0, 0]).unwrap(); + (_out0,) + .new_inputs() + .next([11, 0, 0, 0]) + .done() + .eval(_modulus) + .unwrap_err(); + (_out0,) + .new_inputs() + .next([11, 0, 0, 0]) + .done() + .eval(_modulus) + .unwrap_err(); + } + ); + + //println!("{}", &program); + + run_test_program(program); + } +} diff --git a/debug_utils/sierra-emu/tests/corelib.rs b/debug_utils/sierra-emu/tests/corelib.rs index 052d99643..1b032abcc 100644 --- a/debug_utils/sierra-emu/tests/corelib.rs +++ b/debug_utils/sierra-emu/tests/corelib.rs @@ -65,6 +65,7 @@ fn test_corelib() { "core::test::dict_test::test_array_from_squash_dict", "core::test::hash_test::test_blake2s", "core::test::testing_test::test_get_unspent_gas", + "core::test::qm31_test::", ]; let compiled = compile_tests( From 113327ea9e54c0471a962e6854089c0bff80a507 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Tue, 6 May 2025 16:12:00 -0300 Subject: [PATCH 07/41] some corrections to circuits --- debug_utils/sierra-emu/src/vm/circuit.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debug_utils/sierra-emu/src/vm/circuit.rs b/debug_utils/sierra-emu/src/vm/circuit.rs index 3c9d31b1d..7a44c7934 100644 --- a/debug_utils/sierra-emu/src/vm/circuit.rs +++ b/debug_utils/sierra-emu/src/vm/circuit.rs @@ -1,5 +1,5 @@ use super::EvalAction; -use crate::{debug::debug_signature, Value}; +use crate::Value; use cairo_lang_sierra::{ extensions::{ circuit::{ From 882cd61515d0f096a3ae1b0046caf82f62cad6f8 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Tue, 6 May 2025 18:08:38 -0300 Subject: [PATCH 08/41] fix failure_guarantee_verify to avoid panicking --- debug_utils/sierra-emu/src/vm/circuit.rs | 41 ++++++++++++++++++------ 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/debug_utils/sierra-emu/src/vm/circuit.rs b/debug_utils/sierra-emu/src/vm/circuit.rs index 7a44c7934..3ff596e52 100644 --- a/debug_utils/sierra-emu/src/vm/circuit.rs +++ b/debug_utils/sierra-emu/src/vm/circuit.rs @@ -1,5 +1,5 @@ use super::EvalAction; -use crate::Value; +use crate::{debug::debug_signature, Value}; use cairo_lang_sierra::{ extensions::{ circuit::{ @@ -7,7 +7,7 @@ use cairo_lang_sierra::{ ConcreteU96LimbsLessThanGuaranteeVerifyLibfunc, }, core::{CoreLibfunc, CoreType, CoreTypeConcrete}, - lib_func::{SignatureAndTypeConcreteLibfunc, SignatureOnlyConcreteLibfunc}, + lib_func::{SignatureAndTypeConcreteLibfunc, SignatureOnlyConcreteLibfunc}, ConcreteLibfunc, }, program_registry::ProgramRegistry, }; @@ -327,10 +327,10 @@ pub fn eval_u96_single_limb_less_than_guarantee_verify( _info: &SignatureOnlyConcreteLibfunc, args: Vec, ) -> EvalAction { - let [range_check_96 @ Value::Unit, garantee]: [Value; 2] = args.try_into().unwrap() else { - panic!() - }; - EvalAction::NormalBranch(0, smallvec![range_check_96, garantee]) + debug_signature(_registry, _info.param_signatures(), _info.branch_signatures(), &args); + let [garantee]: [Value; 1] = args.try_into().unwrap(); + + EvalAction::NormalBranch(0, smallvec![garantee]) } pub fn eval_u96_guarantee_verify( @@ -345,8 +345,8 @@ pub fn eval_u96_guarantee_verify( } pub fn eval_failure_guarantee_verify( - _registry: &ProgramRegistry, - _info: &SignatureOnlyConcreteLibfunc, + registry: &ProgramRegistry, + info: &SignatureOnlyConcreteLibfunc, _args: Vec, ) -> EvalAction { let [rc96 @ Value::Unit, mul_mod @ Value::Unit, _, _, _]: [Value; 5] = @@ -355,7 +355,30 @@ pub fn eval_failure_guarantee_verify( panic!() }; - EvalAction::NormalBranch(0, smallvec![rc96, mul_mod, Value::Unit]) + let limbs_cout = match registry + .get_type(&info.signature.branch_signatures[0].vars[2].ty) + .unwrap() + { + CoreTypeConcrete::Circuit(CircuitTypeConcrete::U96LimbsLessThanGuarantee(info)) => { + info.limb_count + } + _ => panic!(), + }; + + let zero_u96 = Value::BoundedInt { + range: BigInt::zero()..BigInt::one() << 96, + value: 0.into(), + }; + let limbs_struct = Value::Struct(vec![zero_u96; limbs_cout]); + + EvalAction::NormalBranch( + 0, + smallvec![ + rc96, + mul_mod, + Value::Struct(vec![limbs_struct.clone(), limbs_struct]) + ], + ) } pub fn eval_get_descriptor( From 2710ca454e34cddba4e29c1d220d2caec5a27de7 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Wed, 7 May 2025 12:48:41 -0300 Subject: [PATCH 09/41] fix circuits --- Cargo.lock | 1 + debug_utils/sierra-emu/src/vm.rs | 2 +- debug_utils/sierra-emu/src/vm/circuit.rs | 154 +++++++++++------------ program.cairo | 26 ++++ 4 files changed, 98 insertions(+), 85 deletions(-) create mode 100644 program.cairo diff --git a/Cargo.lock b/Cargo.lock index d065958dc..b69cf71fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3335,6 +3335,7 @@ dependencies = [ "k256", "keccak", "num-bigint", + "num-integer", "num-traits", "p256", "rand 0.8.5", diff --git a/debug_utils/sierra-emu/src/vm.rs b/debug_utils/sierra-emu/src/vm.rs index aae0e7879..b82b71c69 100644 --- a/debug_utils/sierra-emu/src/vm.rs +++ b/debug_utils/sierra-emu/src/vm.rs @@ -308,7 +308,7 @@ impl VirtualMachine { match &self.program.statements[frame.pc.0] { GenStatement::Invocation(invocation) => { let libfunc = self.registry.get_libfunc(&invocation.libfunc_id).unwrap(); - dbg!( + debug!( "Executing invocation of libfunc: {}", libfunc_to_name(libfunc) ); diff --git a/debug_utils/sierra-emu/src/vm/circuit.rs b/debug_utils/sierra-emu/src/vm/circuit.rs index 3ff596e52..f888a167d 100644 --- a/debug_utils/sierra-emu/src/vm/circuit.rs +++ b/debug_utils/sierra-emu/src/vm/circuit.rs @@ -1,5 +1,5 @@ use super::EvalAction; -use crate::{debug::debug_signature, Value}; +use crate::Value; use cairo_lang_sierra::{ extensions::{ circuit::{ @@ -7,13 +7,13 @@ use cairo_lang_sierra::{ ConcreteU96LimbsLessThanGuaranteeVerifyLibfunc, }, core::{CoreLibfunc, CoreType, CoreTypeConcrete}, - lib_func::{SignatureAndTypeConcreteLibfunc, SignatureOnlyConcreteLibfunc}, ConcreteLibfunc, + lib_func::{SignatureAndTypeConcreteLibfunc, SignatureOnlyConcreteLibfunc}, }, program_registry::ProgramRegistry, }; use num_bigint::{BigInt, BigUint, Sign, ToBigInt}; use num_integer::{ExtendedGcd, Integer}; -use num_traits::{One, Signed, Zero}; +use num_traits::{One, Zero}; use smallvec::smallvec; fn u384_to_struct(num: BigUint) -> Value { @@ -44,29 +44,39 @@ fn u384_to_struct(num: BigUint) -> Value { ]) } -fn modular_inverse(num: &BigInt, modulus: &BigUint) -> (bool, BigUint) { - let ExtendedGcd { gcd, x, .. } = num +fn struct_to_u384(struct_members: Vec) -> BigUint { + let [Value::U128(l0), Value::U128(l1), Value::U128(l2), Value::U128(l3)]: [Value; 4] = + struct_members.try_into().unwrap() + else { + panic!() + }; + + let l0 = l0.to_le_bytes(); + let l1 = l1.to_le_bytes(); + let l2 = l2.to_le_bytes(); + let l3 = l3.to_le_bytes(); + + BigUint::from_bytes_le(&[ + l0[0], l0[1], l0[2], l0[3], l0[4], l0[5], l0[6], l0[7], l0[8], l0[9], l0[10], + l0[11], // + l1[0], l1[1], l1[2], l1[3], l1[4], l1[5], l1[6], l1[7], l1[8], l1[9], l1[10], + l1[11], // + l2[0], l2[1], l2[2], l2[3], l2[4], l2[5], l2[6], l2[7], l2[8], l2[9], l2[10], + l2[11], // + l3[0], l3[1], l3[2], l3[3], l3[4], l3[5], l3[6], l3[7], l3[8], l3[9], l3[10], + l3[11], // + ]) +} + +fn find_nullifier(num: &BigUint, modulus: &BigUint) -> BigUint { + let ExtendedGcd { gcd, .. } = num .to_bigint() .unwrap() .extended_gcd(&modulus.to_bigint().unwrap()); let gcd = gcd.to_biguint().unwrap(); - if gcd.is_one() { - // calculate positive modulus - let num_mod = x.magnitude().mod_floor(modulus); - - return ( - true, - if num.is_negative() { - modulus - num_mod - } else { - num_mod - }, - ); - } - // If there's no inverse, find the value which nullifys the operation - (false, modulus / gcd) + modulus / gcd } pub fn eval( @@ -103,7 +113,7 @@ pub fn eval( } } -pub fn eval_add_input( +fn eval_add_input( _registry: &ProgramRegistry, _info: &SignatureAndTypeConcreteLibfunc, args: Vec, @@ -113,26 +123,7 @@ pub fn eval_add_input( panic!() }; - let [Value::U128(l0), Value::U128(l1), Value::U128(l2), Value::U128(l3)]: [Value; 4] = - members.try_into().unwrap() - else { - panic!() - }; - - let l0 = l0.to_le_bytes(); - let l1 = l1.to_le_bytes(); - let l2 = l2.to_le_bytes(); - let l3 = l3.to_le_bytes(); - values.push(BigUint::from_bytes_le(&[ - l0[0], l0[1], l0[2], l0[3], l0[4], l0[5], l0[6], l0[7], l0[8], l0[9], l0[10], - l0[11], // - l1[0], l1[1], l1[2], l1[3], l1[4], l1[5], l1[6], l1[7], l1[8], l1[9], l1[10], - l1[11], // - l2[0], l2[1], l2[2], l2[3], l2[4], l2[5], l2[6], l2[7], l2[8], l2[9], l2[10], - l2[11], // - l3[0], l3[1], l3[2], l3[3], l3[4], l3[5], l3[6], l3[7], l3[8], l3[9], l3[10], - l3[11], // - ])); + values.push(struct_to_u384(members)); EvalAction::NormalBranch( (values.len() != values.capacity()) as usize, @@ -140,7 +131,7 @@ pub fn eval_add_input( ) } -pub fn eval_eval( +fn eval_eval( _registry: &ProgramRegistry, _info: &SignatureAndTypeConcreteLibfunc, _args: Vec, @@ -198,16 +189,15 @@ pub fn eval_eval( outputs[mul_gate.output] = Some((l * r) % &modulus); } (None, Some(r)) => { - let r = r.to_bigint().unwrap(); - let (sucess, res) = modular_inverse(&r, &modulus); - - if sucess { + match r.modinv(&modulus) { // if it is a inv_gate the output index is store in lhs - outputs[mul_gate.lhs] = Some(res); - } else { + Some(r) => outputs[mul_gate.lhs] = Some(r), // Since we don't calculate CircuitPartialOutputs // perform an early break - break false; + None => { + outputs[mul_gate.lhs] = Some(find_nullifier(&r, &modulus)); + break false + } } } // this state should not be reached since it would mean that @@ -242,7 +232,7 @@ pub fn eval_eval( } } -pub fn eval_get_output( +fn eval_get_output( _registry: &ProgramRegistry, _info: &ConcreteGetOutputLibFunc, args: Vec, @@ -274,7 +264,7 @@ pub fn eval_get_output( ) } -pub fn eval_u96_limbs_less_than_guarantee_verify( +fn eval_u96_limbs_less_than_guarantee_verify( _registry: &ProgramRegistry, info: &ConcreteU96LimbsLessThanGuaranteeVerifyLibfunc, args: Vec, @@ -322,29 +312,29 @@ pub fn eval_u96_limbs_less_than_guarantee_verify( } } -pub fn eval_u96_single_limb_less_than_guarantee_verify( +fn eval_u96_single_limb_less_than_guarantee_verify( _registry: &ProgramRegistry, _info: &SignatureOnlyConcreteLibfunc, args: Vec, ) -> EvalAction { - debug_signature(_registry, _info.param_signatures(), _info.branch_signatures(), &args); - let [garantee]: [Value; 1] = args.try_into().unwrap(); + let [_garantee]: [Value; 1] = args.try_into().unwrap(); - EvalAction::NormalBranch(0, smallvec![garantee]) + EvalAction::NormalBranch(0, smallvec![Value::U128(0)]) } -pub fn eval_u96_guarantee_verify( +fn eval_u96_guarantee_verify( _registry: &ProgramRegistry, _info: &SignatureOnlyConcreteLibfunc, args: Vec, ) -> EvalAction { - let [range_check_96 @ Value::Unit, garantee]: [Value; 2] = args.try_into().unwrap() else { - panic!() + let [range_check_96 @ Value::Unit, _]: [Value; 2] = args.try_into().unwrap() else { + panic!(); }; - EvalAction::NormalBranch(0, smallvec![range_check_96, garantee]) + + EvalAction::NormalBranch(0, smallvec![range_check_96]) } -pub fn eval_failure_guarantee_verify( +fn eval_failure_guarantee_verify( registry: &ProgramRegistry, info: &SignatureOnlyConcreteLibfunc, _args: Vec, @@ -381,7 +371,7 @@ pub fn eval_failure_guarantee_verify( ) } -pub fn eval_get_descriptor( +fn eval_get_descriptor( _registry: &ProgramRegistry, _info: &SignatureAndTypeConcreteLibfunc, _args: Vec, @@ -389,7 +379,7 @@ pub fn eval_get_descriptor( EvalAction::NormalBranch(0, smallvec![Value::Unit]) } -pub fn eval_init_circuit_data( +fn eval_init_circuit_data( _registry: &ProgramRegistry, info: &SignatureAndTypeConcreteLibfunc, args: Vec, @@ -412,7 +402,7 @@ pub fn eval_init_circuit_data( ) } -pub fn eval_try_into_circuit_modulus( +fn eval_try_into_circuit_modulus( _registry: &ProgramRegistry, _info: &SignatureOnlyConcreteLibfunc, args: Vec, @@ -456,7 +446,7 @@ pub fn eval_try_into_circuit_modulus( } } -pub fn eval_into_u96_guarantee( +fn eval_into_u96_guarantee( _registry: &ProgramRegistry, _info: &SignatureAndTypeConcreteLibfunc, args: Vec, @@ -479,38 +469,34 @@ mod tests { use crate::{load_cairo, test_utils::run_test_program}; #[test] - fn test_failure() { + fn test_inputs() { let (_, program) = load_cairo!( use core::circuit::{ - AddInputResultTrait, AddMod, CircuitElement, CircuitInput, CircuitInputs, - CircuitModulus, CircuitOutputsTrait, EvalCircuitTrait, MulMod, RangeCheck96, - circuit_add, circuit_inverse, circuit_mul, circuit_sub, u384, u96, + AddInputResultTrait, AddMod, CircuitElement, CircuitInput, CircuitInputs, CircuitModulus, + CircuitOutputsTrait, EvalCircuitTrait, MulMod, RangeCheck96, circuit_add, circuit_inverse, + circuit_mul, circuit_sub, u384, u96, }; + use core::result::ResultTrait; use core::num::traits::Zero; use core::traits::TryInto; fn main() { - let _in0 = CircuitElement::> {}; - let _out0 = circuit_inverse(_in0); + let _in1 = CircuitElement::> {}; + let _in2 = CircuitElement::> {}; + let _add = circuit_add(_in1, _in2); + + let mut _inputs: Array<[u96; 4]> = array![[1, 0, 0, 0], [2, 0, 0, 0]]; + let mut _circuit_inputs = (_add,).new_inputs(); + + while let Some(_input) = _inputs.pop_front() { + _circuit_inputs = _circuit_inputs.next(_input); + } let _modulus = TryInto::<_, CircuitModulus>::try_into([55, 0, 0, 0]).unwrap(); - (_out0,) - .new_inputs() - .next([11, 0, 0, 0]) - .done() - .eval(_modulus) - .unwrap_err(); - (_out0,) - .new_inputs() - .next([11, 0, 0, 0]) - .done() - .eval(_modulus) - .unwrap_err(); + let _res = ResultTrait::unwrap(_circuit_inputs.done().eval(_modulus)); } ); - //println!("{}", &program); - run_test_program(program); } } diff --git a/program.cairo b/program.cairo new file mode 100644 index 000000000..1746cfc6f --- /dev/null +++ b/program.cairo @@ -0,0 +1,26 @@ +use core::circuit::{ + AddInputResultTrait, AddMod, CircuitElement, CircuitInput, CircuitInputs, + CircuitModulus, CircuitOutputsTrait, EvalCircuitTrait, MulMod, RangeCheck96, + circuit_add, circuit_inverse, circuit_mul, circuit_sub, u384, u96, +}; +use core::num::traits::Zero; +use core::traits::TryInto; + +fn main() { + let _in0 = CircuitElement::> {}; + let _out0 = circuit_inverse(_in0); + + let _modulus = TryInto::<_, CircuitModulus>::try_into([55, 0, 0, 0]).unwrap(); + (_out0,) + .new_inputs() + .next([11, 0, 0, 0]) + .done() + .eval(_modulus) + .unwrap_err(); + (_out0,) + .new_inputs() + .next([11, 0, 0, 0]) + .done() + .eval(_modulus) + .unwrap_err(); +} From f470f232371e35c6a62996c5ab8e4482b083d272 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Wed, 7 May 2025 14:57:32 -0300 Subject: [PATCH 10/41] more fixes to circuits + implement ec_zero libfunc --- debug_utils/sierra-emu/src/vm/circuit.rs | 22 +++++---- debug_utils/sierra-emu/src/vm/ec.rs | 34 ++++++++++---- debug_utils/sierra-emu/src/vm/felt252_dict.rs | 29 ++++++++++++ .../sierra-emu/src/vm/felt252_dict_entry.rs | 46 +++++++++++++------ 4 files changed, 98 insertions(+), 33 deletions(-) diff --git a/debug_utils/sierra-emu/src/vm/circuit.rs b/debug_utils/sierra-emu/src/vm/circuit.rs index f888a167d..25f6c2589 100644 --- a/debug_utils/sierra-emu/src/vm/circuit.rs +++ b/debug_utils/sierra-emu/src/vm/circuit.rs @@ -1,5 +1,5 @@ use super::EvalAction; -use crate::Value; +use crate::{debug::debug_signature, Value}; use cairo_lang_sierra::{ extensions::{ circuit::{ @@ -8,6 +8,7 @@ use cairo_lang_sierra::{ }, core::{CoreLibfunc, CoreType, CoreTypeConcrete}, lib_func::{SignatureAndTypeConcreteLibfunc, SignatureOnlyConcreteLibfunc}, + ConcreteLibfunc, }, program_registry::ProgramRegistry, }; @@ -114,8 +115,8 @@ pub fn eval( } fn eval_add_input( - _registry: &ProgramRegistry, - _info: &SignatureAndTypeConcreteLibfunc, + registry: &ProgramRegistry, + info: &SignatureAndTypeConcreteLibfunc, args: Vec, ) -> EvalAction { let [Value::Circuit(mut values), Value::Struct(members)]: [Value; 2] = args.try_into().unwrap() @@ -123,10 +124,15 @@ fn eval_add_input( panic!() }; + let n_inputs = match registry.get_type(&info.ty).unwrap() { + CoreTypeConcrete::Circuit(CircuitTypeConcrete::Circuit(info)) => info.circuit_info.n_inputs, + _ => panic!(), + }; + values.push(struct_to_u384(members)); EvalAction::NormalBranch( - (values.len() != values.capacity()) as usize, + (values.len() != n_inputs) as usize, smallvec![Value::Circuit(values)], ) } @@ -196,7 +202,7 @@ fn eval_eval( // perform an early break None => { outputs[mul_gate.lhs] = Some(find_nullifier(&r, &modulus)); - break false + break false; } } } @@ -472,9 +478,9 @@ mod tests { fn test_inputs() { let (_, program) = load_cairo!( use core::circuit::{ - AddInputResultTrait, AddMod, CircuitElement, CircuitInput, CircuitInputs, CircuitModulus, - CircuitOutputsTrait, EvalCircuitTrait, MulMod, RangeCheck96, circuit_add, circuit_inverse, - circuit_mul, circuit_sub, u384, u96, + AddInputResultTrait, AddMod, CircuitElement, CircuitInput, CircuitInputs, + CircuitModulus, CircuitOutputsTrait, EvalCircuitTrait, MulMod, RangeCheck96, + circuit_add, circuit_inverse, circuit_mul, circuit_sub, u384, u96, }; use core::result::ResultTrait; use core::num::traits::Zero; diff --git a/debug_utils/sierra-emu/src/vm/ec.rs b/debug_utils/sierra-emu/src/vm/ec.rs index 64ab9828a..b9ab8933d 100644 --- a/debug_utils/sierra-emu/src/vm/ec.rs +++ b/debug_utils/sierra-emu/src/vm/ec.rs @@ -34,11 +34,11 @@ pub fn eval( EcConcreteLibfunc::StateAddMul(info) => eval_state_add_mul(registry, info, args), EcConcreteLibfunc::PointFromX(info) => eval_point_from_x(registry, info, args), EcConcreteLibfunc::UnwrapPoint(info) => eval_unwrap_point(registry, info, args), - EcConcreteLibfunc::Zero(_) => todo!(), + EcConcreteLibfunc::Zero(info) => eval_zero(registry, info, args), } } -pub fn eval_is_zero( +fn eval_is_zero( _registry: &ProgramRegistry, _info: &SignatureOnlyConcreteLibfunc, args: Vec, @@ -55,7 +55,7 @@ pub fn eval_is_zero( } } -pub fn eval_unwrap_point( +fn eval_unwrap_point( _registry: &ProgramRegistry, _info: &SignatureOnlyConcreteLibfunc, args: Vec, @@ -66,7 +66,7 @@ pub fn eval_unwrap_point( EvalAction::NormalBranch(0, smallvec![Value::Felt(x), Value::Felt(y)]) } -pub fn eval_neg( +fn eval_neg( _registry: &ProgramRegistry, _info: &SignatureOnlyConcreteLibfunc, args: Vec, @@ -86,7 +86,7 @@ pub fn eval_neg( ) } -pub fn eval_new( +fn eval_new( _registry: &ProgramRegistry, _info: &SignatureOnlyConcreteLibfunc, args: Vec, @@ -107,7 +107,7 @@ pub fn eval_new( } } -pub fn eval_state_init( +fn eval_state_init( _registry: &ProgramRegistry, _info: &SignatureOnlyConcreteLibfunc, _args: Vec, @@ -125,7 +125,7 @@ pub fn eval_state_init( ) } -pub fn eval_state_add( +fn eval_state_add( _registry: &ProgramRegistry, _info: &SignatureOnlyConcreteLibfunc, args: Vec, @@ -153,7 +153,7 @@ pub fn eval_state_add( ) } -pub fn eval_state_add_mul( +fn eval_state_add_mul( _registry: &ProgramRegistry, _info: &SignatureOnlyConcreteLibfunc, args: Vec, @@ -184,7 +184,7 @@ pub fn eval_state_add_mul( ) } -pub fn eval_state_finalize( +fn eval_state_finalize( _registry: &ProgramRegistry, _info: &SignatureOnlyConcreteLibfunc, args: Vec, @@ -211,7 +211,7 @@ pub fn eval_state_finalize( } } -pub fn eval_point_from_x( +fn eval_point_from_x( _registry: &ProgramRegistry, _info: &SignatureOnlyConcreteLibfunc, args: Vec, @@ -258,3 +258,17 @@ fn random_ec_point() -> AffinePoint { AffinePoint::new(random_x, random_y).unwrap() } + +fn eval_zero( + _registry: &ProgramRegistry, + _info: &SignatureOnlyConcreteLibfunc, + _args: Vec, +) -> EvalAction { + EvalAction::NormalBranch( + 0, + smallvec![Value::EcPoint { + x: 0.into(), + y: 0.into() + }], + ) +} diff --git a/debug_utils/sierra-emu/src/vm/felt252_dict.rs b/debug_utils/sierra-emu/src/vm/felt252_dict.rs index 59807b451..a0d6cc914 100644 --- a/debug_utils/sierra-emu/src/vm/felt252_dict.rs +++ b/debug_utils/sierra-emu/src/vm/felt252_dict.rs @@ -82,3 +82,32 @@ pub fn eval_squash( ], ) } + +#[cfg(test)] +mod tests { + use crate::{load_cairo, test_utils::run_test_program}; + + #[test] + fn test_felt_dict() { + let (_, program) = load_cairo!( + use core::dict::{Felt252Dict, Felt252DictEntryTrait, SquashedFelt252DictImpl}; + use core::nullable; + + #[inline] + pub fn assert_eq>(a: @T, b: @T) { + assert(a == b, ' '); + } + + fn main() -> (felt252,felt252,felt252) { + let mut _dict = Default::default(); + _dict.insert(10, 110); + _dict.insert(11, 111); + (_dict[10], + _dict[11], + _dict[12]) + } + ); + + dbg!(run_test_program(program)); + } +} diff --git a/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs b/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs index a93132580..acb71cc90 100644 --- a/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs +++ b/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs @@ -36,23 +36,39 @@ pub fn eval_get( }; assert_eq!(info.ty, ty); - let default_value = Value::default_for_type(registry, &info.ty); - data.insert(key, default_value.clone()); + if data.contains_key(&key) { + let value = data.get(&key).unwrap().to_owned(); + EvalAction::NormalBranch( + 0, + smallvec![ + Value::FeltDictEntry { + ty, + data, + count, + key + }, + value, + ], + ) + } else { + let default_value = Value::default_for_type(registry, &info.ty); + data.insert(key, default_value.clone()); - let count = count + 1; + let count = count + 1; - EvalAction::NormalBranch( - 0, - smallvec![ - Value::FeltDictEntry { - ty, - data, - count, - key - }, - default_value, - ], - ) + EvalAction::NormalBranch( + 0, + smallvec![ + Value::FeltDictEntry { + ty, + data, + count, + key + }, + default_value, + ], + ) + } } pub fn eval_finalize( From 553b0f3c2ca12daab9bbdc71e7fcb1670670bd5a Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Wed, 7 May 2025 14:59:19 -0300 Subject: [PATCH 11/41] clippy --- debug_utils/sierra-emu/src/vm/circuit.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/debug_utils/sierra-emu/src/vm/circuit.rs b/debug_utils/sierra-emu/src/vm/circuit.rs index 25f6c2589..c08da0b79 100644 --- a/debug_utils/sierra-emu/src/vm/circuit.rs +++ b/debug_utils/sierra-emu/src/vm/circuit.rs @@ -1,5 +1,5 @@ use super::EvalAction; -use crate::{debug::debug_signature, Value}; +use crate::Value; use cairo_lang_sierra::{ extensions::{ circuit::{ @@ -8,7 +8,6 @@ use cairo_lang_sierra::{ }, core::{CoreLibfunc, CoreType, CoreTypeConcrete}, lib_func::{SignatureAndTypeConcreteLibfunc, SignatureOnlyConcreteLibfunc}, - ConcreteLibfunc, }, program_registry::ProgramRegistry, }; From 72ee4f9a4d318585f5ac88c6b10110028d721864 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Wed, 7 May 2025 15:11:41 -0300 Subject: [PATCH 12/41] remove unnecesary tests --- debug_utils/sierra-emu/src/vm/circuit.rs | 37 ------------------- debug_utils/sierra-emu/src/vm/felt252_dict.rs | 29 --------------- 2 files changed, 66 deletions(-) diff --git a/debug_utils/sierra-emu/src/vm/circuit.rs b/debug_utils/sierra-emu/src/vm/circuit.rs index c08da0b79..bae5d4a2a 100644 --- a/debug_utils/sierra-emu/src/vm/circuit.rs +++ b/debug_utils/sierra-emu/src/vm/circuit.rs @@ -468,40 +468,3 @@ fn eval_into_u96_guarantee( EvalAction::NormalBranch(0, smallvec![Value::U128(value.try_into().unwrap())]) } - -#[cfg(test)] -mod tests { - use crate::{load_cairo, test_utils::run_test_program}; - - #[test] - fn test_inputs() { - let (_, program) = load_cairo!( - use core::circuit::{ - AddInputResultTrait, AddMod, CircuitElement, CircuitInput, CircuitInputs, - CircuitModulus, CircuitOutputsTrait, EvalCircuitTrait, MulMod, RangeCheck96, - circuit_add, circuit_inverse, circuit_mul, circuit_sub, u384, u96, - }; - use core::result::ResultTrait; - use core::num::traits::Zero; - use core::traits::TryInto; - - fn main() { - let _in1 = CircuitElement::> {}; - let _in2 = CircuitElement::> {}; - let _add = circuit_add(_in1, _in2); - - let mut _inputs: Array<[u96; 4]> = array![[1, 0, 0, 0], [2, 0, 0, 0]]; - let mut _circuit_inputs = (_add,).new_inputs(); - - while let Some(_input) = _inputs.pop_front() { - _circuit_inputs = _circuit_inputs.next(_input); - } - - let _modulus = TryInto::<_, CircuitModulus>::try_into([55, 0, 0, 0]).unwrap(); - let _res = ResultTrait::unwrap(_circuit_inputs.done().eval(_modulus)); - } - ); - - run_test_program(program); - } -} diff --git a/debug_utils/sierra-emu/src/vm/felt252_dict.rs b/debug_utils/sierra-emu/src/vm/felt252_dict.rs index a0d6cc914..59807b451 100644 --- a/debug_utils/sierra-emu/src/vm/felt252_dict.rs +++ b/debug_utils/sierra-emu/src/vm/felt252_dict.rs @@ -82,32 +82,3 @@ pub fn eval_squash( ], ) } - -#[cfg(test)] -mod tests { - use crate::{load_cairo, test_utils::run_test_program}; - - #[test] - fn test_felt_dict() { - let (_, program) = load_cairo!( - use core::dict::{Felt252Dict, Felt252DictEntryTrait, SquashedFelt252DictImpl}; - use core::nullable; - - #[inline] - pub fn assert_eq>(a: @T, b: @T) { - assert(a == b, ' '); - } - - fn main() -> (felt252,felt252,felt252) { - let mut _dict = Default::default(); - _dict.insert(10, 110); - _dict.insert(11, 111); - (_dict[10], - _dict[11], - _dict[12]) - } - ); - - dbg!(run_test_program(program)); - } -} From be4f4c5148440689fc939dae7b12355c40fcceb5 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Wed, 7 May 2025 15:13:43 -0300 Subject: [PATCH 13/41] remove unnecesary file --- program.cairo | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 program.cairo diff --git a/program.cairo b/program.cairo deleted file mode 100644 index 1746cfc6f..000000000 --- a/program.cairo +++ /dev/null @@ -1,26 +0,0 @@ -use core::circuit::{ - AddInputResultTrait, AddMod, CircuitElement, CircuitInput, CircuitInputs, - CircuitModulus, CircuitOutputsTrait, EvalCircuitTrait, MulMod, RangeCheck96, - circuit_add, circuit_inverse, circuit_mul, circuit_sub, u384, u96, -}; -use core::num::traits::Zero; -use core::traits::TryInto; - -fn main() { - let _in0 = CircuitElement::> {}; - let _out0 = circuit_inverse(_in0); - - let _modulus = TryInto::<_, CircuitModulus>::try_into([55, 0, 0, 0]).unwrap(); - (_out0,) - .new_inputs() - .next([11, 0, 0, 0]) - .done() - .eval(_modulus) - .unwrap_err(); - (_out0,) - .new_inputs() - .next([11, 0, 0, 0]) - .done() - .eval(_modulus) - .unwrap_err(); -} From 2943dae2ab62c7153f93d61b533e8a736f46f1cf Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Wed, 7 May 2025 15:16:58 -0300 Subject: [PATCH 14/41] fix branch index --- debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs b/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs index acb71cc90..d2f5ae3ae 100644 --- a/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs +++ b/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs @@ -57,7 +57,7 @@ pub fn eval_get( let count = count + 1; EvalAction::NormalBranch( - 0, + 1, smallvec![ Value::FeltDictEntry { ty, From 2d36e5a58c7f9026244cec312f58e5a06381b2cd Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Wed, 7 May 2025 15:24:25 -0300 Subject: [PATCH 15/41] add comment --- debug_utils/sierra-emu/src/vm/circuit.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/debug_utils/sierra-emu/src/vm/circuit.rs b/debug_utils/sierra-emu/src/vm/circuit.rs index bae5d4a2a..f1a248a64 100644 --- a/debug_utils/sierra-emu/src/vm/circuit.rs +++ b/debug_utils/sierra-emu/src/vm/circuit.rs @@ -364,6 +364,7 @@ fn eval_failure_guarantee_verify( range: BigInt::zero()..BigInt::one() << 96, value: 0.into(), }; + // This should be changed with it correct value when we implement this libfunc in native let limbs_struct = Value::Struct(vec![zero_u96; limbs_cout]); EvalAction::NormalBranch( From 7b87748728513050b4e585c4b97b585f0b00f90c Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Wed, 7 May 2025 15:43:51 -0300 Subject: [PATCH 16/41] fix eval_u96_limbs_less_than_guarantee_verify --- debug_utils/sierra-emu/src/vm/circuit.rs | 16 +++++--------- .../sierra-emu/src/vm/felt252_dict_entry.rs | 22 +++++++++---------- debug_utils/sierra-emu/tests/libfuncs.rs | 1 - .../tests/tests/circuits_failure.cairo | 6 ++--- 4 files changed, 18 insertions(+), 27 deletions(-) diff --git a/debug_utils/sierra-emu/src/vm/circuit.rs b/debug_utils/sierra-emu/src/vm/circuit.rs index f1a248a64..36f00947a 100644 --- a/debug_utils/sierra-emu/src/vm/circuit.rs +++ b/debug_utils/sierra-emu/src/vm/circuit.rs @@ -13,7 +13,7 @@ use cairo_lang_sierra::{ }; use num_bigint::{BigInt, BigUint, Sign, ToBigInt}; use num_integer::{ExtendedGcd, Integer}; -use num_traits::{One, Zero}; +use num_traits::{One, ToPrimitive, Zero}; use smallvec::smallvec; fn u384_to_struct(num: BigUint) -> Value { @@ -286,7 +286,7 @@ fn eval_u96_limbs_less_than_guarantee_verify( }; let Value::BoundedInt { value: gate_last_limb, - range: u96_range, + .. } = &gate[limb_count - 1] else { panic!(); @@ -298,16 +298,10 @@ fn eval_u96_limbs_less_than_guarantee_verify( else { panic!(); }; - let diff = modulus_last_limb - gate_last_limb; + let diff = (modulus_last_limb - gate_last_limb).to_u128().unwrap(); - if (modulus_last_limb - gate_last_limb) != BigInt::zero() { - EvalAction::NormalBranch( - 1, - smallvec![Value::BoundedInt { - range: u96_range.clone(), - value: diff - }], - ) + if diff != 0 { + EvalAction::NormalBranch(1, smallvec![Value::U128(diff)]) } else { // if there is no diff, build a new garantee, skipping the last limb let new_gate = Value::Struct(gate[0..limb_count].to_vec()); diff --git a/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs b/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs index d2f5ae3ae..563ba0503 100644 --- a/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs +++ b/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs @@ -36,10 +36,14 @@ pub fn eval_get( }; assert_eq!(info.ty, ty); - if data.contains_key(&key) { - let value = data.get(&key).unwrap().to_owned(); + if let std::collections::hash_map::Entry::Vacant(e) = data.entry(key) { + let default_value = Value::default_for_type(registry, &info.ty); + e.insert(default_value.clone()); + + let count = count + 1; + EvalAction::NormalBranch( - 0, + 1, smallvec![ Value::FeltDictEntry { ty, @@ -47,17 +51,13 @@ pub fn eval_get( count, key }, - value, + default_value, ], ) } else { - let default_value = Value::default_for_type(registry, &info.ty); - data.insert(key, default_value.clone()); - - let count = count + 1; - + let value = data.get(&key).unwrap().to_owned(); EvalAction::NormalBranch( - 1, + 0, smallvec![ Value::FeltDictEntry { ty, @@ -65,7 +65,7 @@ pub fn eval_get( count, key }, - default_value, + value, ], ) } diff --git a/debug_utils/sierra-emu/tests/libfuncs.rs b/debug_utils/sierra-emu/tests/libfuncs.rs index e7181885a..96cd9dad5 100644 --- a/debug_utils/sierra-emu/tests/libfuncs.rs +++ b/debug_utils/sierra-emu/tests/libfuncs.rs @@ -147,7 +147,6 @@ fn test_run_full_circuit() { } #[test] -#[should_panic(expected = "attempt to divide by 0")] fn test_circuit_failure() { run_program( "tests/tests/circuits_failure.cairo", diff --git a/debug_utils/sierra-emu/tests/tests/circuits_failure.cairo b/debug_utils/sierra-emu/tests/tests/circuits_failure.cairo index fcf2684d0..6994b0afe 100644 --- a/debug_utils/sierra-emu/tests/tests/circuits_failure.cairo +++ b/debug_utils/sierra-emu/tests/tests/circuits_failure.cairo @@ -9,12 +9,10 @@ fn main() { let inv = circuit_inverse(in1); let modulus = TryInto::<_, CircuitModulus>::try_into([7, 0, 0, 0]).unwrap(); - let outputs = (inv,) + (inv,) .new_inputs() .next([0, 0, 0, 0]) .done() .eval(modulus) - .unwrap(); - - outputs.get_output(inv); + .unwrap_err(); } From 90d61703eb5e2ac79d6b2deefcfa70fba9e69f87 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Wed, 7 May 2025 15:49:26 -0300 Subject: [PATCH 17/41] remove circuit failure test --- debug_utils/sierra-emu/tests/libfuncs.rs | 9 --------- .../tests/tests/circuits_failure.cairo | 18 ------------------ 2 files changed, 27 deletions(-) delete mode 100644 debug_utils/sierra-emu/tests/tests/circuits_failure.cairo diff --git a/debug_utils/sierra-emu/tests/libfuncs.rs b/debug_utils/sierra-emu/tests/libfuncs.rs index 96cd9dad5..ff7a5ad82 100644 --- a/debug_utils/sierra-emu/tests/libfuncs.rs +++ b/debug_utils/sierra-emu/tests/libfuncs.rs @@ -145,12 +145,3 @@ fn test_run_full_circuit() { assert_eq!(**payload, expected_output); } - -#[test] -fn test_circuit_failure() { - run_program( - "tests/tests/circuits_failure.cairo", - "circuits_failure::circuits_failure::main", - &[], - ); -} diff --git a/debug_utils/sierra-emu/tests/tests/circuits_failure.cairo b/debug_utils/sierra-emu/tests/tests/circuits_failure.cairo deleted file mode 100644 index 6994b0afe..000000000 --- a/debug_utils/sierra-emu/tests/tests/circuits_failure.cairo +++ /dev/null @@ -1,18 +0,0 @@ -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() { - let in1 = CircuitElement::> {}; - let inv = circuit_inverse(in1); - - let modulus = TryInto::<_, CircuitModulus>::try_into([7, 0, 0, 0]).unwrap(); - (inv,) - .new_inputs() - .next([0, 0, 0, 0]) - .done() - .eval(modulus) - .unwrap_err(); -} From ecf145855b0e60cac96166a9b62983b413e60913 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Wed, 7 May 2025 16:02:07 -0300 Subject: [PATCH 18/41] update trace dump with new Value::CircitOutputs --- src/metadata/trace_dump.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/metadata/trace_dump.rs b/src/metadata/trace_dump.rs index 92e89aa0e..768204a55 100644 --- a/src/metadata/trace_dump.rs +++ b/src/metadata/trace_dump.rs @@ -572,14 +572,18 @@ pub mod trace_dump_runtime { let value_ptr = value_ptr.cast::<[u8; 48]>(); + let size = u384_layout.pad_to_align().size(); + for i in 0..n_outputs { - let size = u384_layout.pad_to_align().size(); let current_ptr = value_ptr.byte_add(size * i); let current_value = current_ptr.as_ref(); values.push(BigUint::from_bytes_le(current_value)); } - Value::CircuitOutputs(values) + let current_ptr = value_ptr.byte_add(size * n_outputs); + let modulus = BigUint::from_bytes_le(current_ptr.as_ref()); + + Value::CircuitOutputs { circuits: values, modulus } } CircuitTypeConcrete::CircuitPartialOutputs(_) => { todo!("CircuitTypeConcrete::CircuitPartialOutputs") From fbd7efe7608ed8c4eb5cbea6fb7b2bb7f9e7f3c4 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Wed, 7 May 2025 16:03:35 -0300 Subject: [PATCH 19/41] fmt --- src/metadata/trace_dump.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/metadata/trace_dump.rs b/src/metadata/trace_dump.rs index 768204a55..994f28868 100644 --- a/src/metadata/trace_dump.rs +++ b/src/metadata/trace_dump.rs @@ -583,7 +583,10 @@ pub mod trace_dump_runtime { let current_ptr = value_ptr.byte_add(size * n_outputs); let modulus = BigUint::from_bytes_le(current_ptr.as_ref()); - Value::CircuitOutputs { circuits: values, modulus } + Value::CircuitOutputs { + circuits: values, + modulus, + } } CircuitTypeConcrete::CircuitPartialOutputs(_) => { todo!("CircuitTypeConcrete::CircuitPartialOutputs") From 35bda85fdb936433afc8452e7167ebb54aba4d1f Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Thu, 8 May 2025 12:58:12 -0300 Subject: [PATCH 20/41] reviews + fix modulus in trace dump --- Cargo.lock | 227 +++++++++------------ debug_utils/sierra-emu/Cargo.toml | 2 +- debug_utils/sierra-emu/src/vm/circuit.rs | 21 +- debug_utils/sierra-emu/tests/common/mod.rs | 10 +- program.cairo | 30 +++ src/libfuncs/circuit.rs | 2 +- src/metadata/trace_dump.rs | 26 ++- 7 files changed, 165 insertions(+), 153 deletions(-) create mode 100644 program.cairo diff --git a/Cargo.lock b/Cargo.lock index e20c4af34..c8bf58587 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,14 +10,14 @@ checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", "once_cell", "version_check", - "zerocopy 0.7.35", + "zerocopy", ] [[package]] @@ -108,7 +108,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -124,7 +124,7 @@ dependencies = [ "ark-std 0.5.0", "educe 0.6.0", "fnv", - "hashbrown 0.15.2", + "hashbrown 0.15.3", "itertools 0.13.0", "num-bigint", "num-integer", @@ -189,7 +189,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" dependencies = [ "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -215,7 +215,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -230,7 +230,7 @@ dependencies = [ "ark-std 0.5.0", "educe 0.6.0", "fnv", - "hashbrown 0.15.2", + "hashbrown 0.15.3", ] [[package]] @@ -287,7 +287,7 @@ checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -385,7 +385,7 @@ dependencies = [ "regex", "rustc-hash 2.1.1", "shlex", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -504,7 +504,7 @@ dependencies = [ "rust-analyzer-salsa", "semver", "smol_str", - "thiserror 2.0.12", + "thiserror", ] [[package]] @@ -591,7 +591,7 @@ dependencies = [ "itertools 0.14.0", "rust-analyzer-salsa", "serde", - "thiserror 2.0.12", + "thiserror", ] [[package]] @@ -675,7 +675,7 @@ checksum = "b1e4872352761cf6d7f47eeb1626e3b1d84a514017fb4251173148d8c04f36d5" dependencies = [ "cairo-lang-debug", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -687,7 +687,7 @@ dependencies = [ "cairo-lang-filesystem", "cairo-lang-utils", "serde", - "thiserror 2.0.12", + "thiserror", "toml", ] @@ -706,7 +706,7 @@ dependencies = [ "cairo-lang-utils", "cairo-vm 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.14.0", - "thiserror 2.0.12", + "thiserror", ] [[package]] @@ -736,7 +736,7 @@ dependencies = [ "sha2", "smol_str", "starknet-types-core", - "thiserror 2.0.12", + "thiserror", ] [[package]] @@ -790,7 +790,7 @@ dependencies = [ "sha3", "smol_str", "starknet-types-core", - "thiserror 2.0.12", + "thiserror", ] [[package]] @@ -806,7 +806,7 @@ dependencies = [ "itertools 0.14.0", "num-bigint", "num-traits", - "thiserror 2.0.12", + "thiserror", ] [[package]] @@ -822,7 +822,7 @@ dependencies = [ "itertools 0.14.0", "num-bigint", "num-traits", - "thiserror 2.0.12", + "thiserror", ] [[package]] @@ -867,7 +867,7 @@ dependencies = [ "num-bigint", "num-traits", "starknet-types-core", - "thiserror 2.0.12", + "thiserror", ] [[package]] @@ -907,7 +907,7 @@ dependencies = [ "serde_json", "smol_str", "starknet-types-core", - "thiserror 2.0.12", + "thiserror", "typetag", ] @@ -931,7 +931,7 @@ dependencies = [ "sha3", "smol_str", "starknet-types-core", - "thiserror 2.0.12", + "thiserror", ] [[package]] @@ -1008,7 +1008,7 @@ version = "2.12.0-dev.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f043065d60a8a2510bfacb6c91767298fed50ed9abbd69ff7698322b7cb1e65" dependencies = [ - "hashbrown 0.15.2", + "hashbrown 0.15.3", "indexmap 2.9.0", "itertools 0.14.0", "num-bigint", @@ -1077,7 +1077,7 @@ dependencies = [ "stats_alloc", "tempfile", "test-case", - "thiserror 2.0.12", + "thiserror", "tracing", "tracing-subscriber", "utf8_iter", @@ -1094,7 +1094,7 @@ dependencies = [ "bincode 2.0.1", "bitvec", "generic-array", - "hashbrown 0.15.2", + "hashbrown 0.15.3", "hex", "indoc", "keccak", @@ -1130,7 +1130,7 @@ dependencies = [ "cairo-lang-starknet", "cairo-lang-starknet-classes", "generic-array", - "hashbrown 0.15.2", + "hashbrown 0.15.3", "hex", "indoc", "keccak", @@ -1148,7 +1148,7 @@ dependencies = [ "sha3", "starknet-crypto", "starknet-types-core", - "thiserror 2.0.12", + "thiserror", "zip", ] @@ -1178,9 +1178,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.19" +version = "1.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362" +checksum = "8691782945451c1c383942c4874dbe63814f61cb57ef773cda2972682b7bb3c0" dependencies = [ "shlex", ] @@ -1275,7 +1275,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -1529,9 +1529,9 @@ dependencies = [ [[package]] name = "deunicode" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc55fe0d1f6c107595572ec8b107c0999bb1a2e0b75e37429a4fb0d6474a0e7d" +checksum = "abd57806937c9cc163efc8ea3910e00a62e2aeb0b8119f1793a978088f8f6b04" [[package]] name = "diff" @@ -1589,7 +1589,7 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -1601,7 +1601,7 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -1668,7 +1668,7 @@ checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -1761,7 +1761,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -1809,7 +1809,7 @@ checksum = "43eaff6bbc0b3a878361aced5ec6a2818ee7c541c5b33b5880dfa9a86c23e9e7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -1904,9 +1904,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" dependencies = [ "allocator-api2", "equivalent", @@ -1928,9 +1928,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e" +checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08" [[package]] name = "hex" @@ -1995,7 +1995,7 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -2041,7 +2041,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", - "hashbrown 0.15.2", + "hashbrown 0.15.3", "serde", ] @@ -2288,7 +2288,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.2", + "hashbrown 0.15.3", ] [[package]] @@ -2331,7 +2331,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.100", + "syn 2.0.101", "tblgen", "unindent", ] @@ -2562,7 +2562,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -2705,7 +2705,7 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy 0.8.24", + "zerocopy", ] [[package]] @@ -2741,7 +2741,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "664ec5419c51e34154eec046ebcba56312d5a2fc3b09a06da188e1ad21afadf6" dependencies = [ "proc-macro2", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -2935,9 +2935,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" +checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" dependencies = [ "bitflags", ] @@ -3034,7 +3034,7 @@ dependencies = [ "regex", "relative-path", "rustc_version", - "syn 2.0.100", + "syn 2.0.101", "unicode-ident", ] @@ -3064,7 +3064,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -3100,9 +3100,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.5" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ "bitflags", "errno", @@ -3154,7 +3154,7 @@ dependencies = [ "semver", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror", ] [[package]] @@ -3196,7 +3196,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -3245,7 +3245,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -3256,7 +3256,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -3282,9 +3282,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", @@ -3350,7 +3350,7 @@ dependencies = [ "starknet-curve", "starknet-types-core", "tempfile", - "thiserror 2.0.12", + "thiserror", "tracing", "tracing-subscriber", ] @@ -3547,9 +3547,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.100" +version = "2.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" dependencies = [ "proc-macro2", "quote", @@ -3571,7 +3571,7 @@ dependencies = [ "bindgen", "cc", "paste", - "thiserror 2.0.12", + "thiserror", ] [[package]] @@ -3615,7 +3615,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -3626,37 +3626,17 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", "test-case-core", ] -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl 1.0.69", -] - [[package]] name = "thiserror" version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "thiserror-impl 2.0.12", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", + "thiserror-impl", ] [[package]] @@ -3667,7 +3647,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -3727,9 +3707,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "toml" -version = "0.8.20" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" +checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae" dependencies = [ "serde", "serde_spanned", @@ -3739,26 +3719,33 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.24" +version = "0.22.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" +checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" dependencies = [ "indexmap 2.9.0", "serde", "serde_spanned", "toml_datetime", + "toml_write", "winnow", ] +[[package]] +name = "toml_write" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076" + [[package]] name = "tracing" version = "0.1.41" @@ -3778,7 +3765,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -3882,7 +3869,7 @@ checksum = "35f5380909ffc31b4de4f4bdf96b877175a016aa2ca98cee39fcfd8c4d53d952" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -3893,11 +3880,11 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unescaper" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c878a167baa8afd137494101a688ef8c67125089ff2249284bd2b5f9bfedb815" +checksum = "c01d12e3a56a4432a8b436f293c25f4808bdf9e9f9f98f9260bba1f1bc5a1f26" dependencies = [ - "thiserror 1.0.69", + "thiserror", ] [[package]] @@ -4037,7 +4024,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", "wasm-bindgen-shared", ] @@ -4059,7 +4046,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4208,9 +4195,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.7.6" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10" +checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" dependencies = [ "memchr", ] @@ -4256,42 +4243,22 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" dependencies = [ - "zerocopy-derive 0.7.35", -] - -[[package]] -name = "zerocopy" -version = "0.8.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" -dependencies = [ - "zerocopy-derive 0.8.24", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", + "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.24" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" +checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -4311,7 +4278,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] diff --git a/debug_utils/sierra-emu/Cargo.toml b/debug_utils/sierra-emu/Cargo.toml index f961294e8..71fbc3484 100644 --- a/debug_utils/sierra-emu/Cargo.toml +++ b/debug_utils/sierra-emu/Cargo.toml @@ -23,7 +23,7 @@ cairo-lang-utils.workspace = true clap = { version = "4.5.26", features = ["derive"] } k256 = "0.13.4" keccak = "0.1.5" -num-integer = "0.1.46" +num-integer.workspace = true num-bigint.workspace = true num-traits.workspace = true p256 = "0.13.2" diff --git a/debug_utils/sierra-emu/src/vm/circuit.rs b/debug_utils/sierra-emu/src/vm/circuit.rs index 36f00947a..29c716dae 100644 --- a/debug_utils/sierra-emu/src/vm/circuit.rs +++ b/debug_utils/sierra-emu/src/vm/circuit.rs @@ -274,14 +274,14 @@ fn eval_u96_limbs_less_than_guarantee_verify( info: &ConcreteU96LimbsLessThanGuaranteeVerifyLibfunc, args: Vec, ) -> EvalAction { - let [Value::Struct(garantee)]: [Value; 1] = args.try_into().unwrap() else { + let [Value::Struct(guarantee)]: [Value; 1] = args.try_into().unwrap() else { panic!() }; let limb_count = info.limb_count; - let Value::Struct(gate) = garantee.first().unwrap() else { + let Value::Struct(gate) = &guarantee[0] else { panic!(); }; - let Value::Struct(modulus) = garantee.get(1).unwrap() else { + let Value::Struct(modulus) = &guarantee[1] else { panic!(); }; let Value::BoundedInt { @@ -303,7 +303,7 @@ fn eval_u96_limbs_less_than_guarantee_verify( if diff != 0 { EvalAction::NormalBranch(1, smallvec![Value::U128(diff)]) } else { - // if there is no diff, build a new garantee, skipping the last limb + // if there is no diff, build a new guarantee, skipping the last limb let new_gate = Value::Struct(gate[0..limb_count].to_vec()); let new_modulus = Value::Struct(modulus[0..limb_count].to_vec()); @@ -316,7 +316,7 @@ fn eval_u96_single_limb_less_than_guarantee_verify( _info: &SignatureOnlyConcreteLibfunc, args: Vec, ) -> EvalAction { - let [_garantee]: [Value; 1] = args.try_into().unwrap(); + let [_guarantee]: [Value; 1] = args.try_into().unwrap(); EvalAction::NormalBranch(0, smallvec![Value::U128(0)]) } @@ -344,7 +344,7 @@ fn eval_failure_guarantee_verify( panic!() }; - let limbs_cout = match registry + let limbs_count = match registry .get_type(&info.signature.branch_signatures[0].vars[2].ty) .unwrap() { @@ -359,7 +359,7 @@ fn eval_failure_guarantee_verify( value: 0.into(), }; // This should be changed with it correct value when we implement this libfunc in native - let limbs_struct = Value::Struct(vec![zero_u96; limbs_cout]); + let limbs_struct = Value::Struct(vec![zero_u96; limbs_count]); EvalAction::NormalBranch( 0, @@ -451,15 +451,10 @@ fn eval_into_u96_guarantee( _info: &SignatureAndTypeConcreteLibfunc, args: Vec, ) -> EvalAction { - let [Value::BoundedInt { range, mut value }]: [Value; 1] = args.try_into().unwrap() else { + let [Value::BoundedInt { range, value }]: [Value; 1] = args.try_into().unwrap() else { panic!() }; assert_eq!(range, BigInt::ZERO..(BigInt::from(1) << 96)); - // offset by the lower bound to get the actual value - if range.start > BigInt::ZERO { - value = range.start; - } - EvalAction::NormalBranch(0, smallvec![Value::U128(value.try_into().unwrap())]) } diff --git a/debug_utils/sierra-emu/tests/common/mod.rs b/debug_utils/sierra-emu/tests/common/mod.rs index daead6ba6..ffbd75c5e 100644 --- a/debug_utils/sierra-emu/tests/common/mod.rs +++ b/debug_utils/sierra-emu/tests/common/mod.rs @@ -20,8 +20,14 @@ pub fn value_to_felt(value: &Value) -> Vec { costs.mul_mod.into(), ], Value::CircuitModulus(value) => vec![value.into()], - Value::Circuit(data) | Value::CircuitOutputs { circuits: data, .. } => { - data.iter().map(Felt::from).collect() + Value::Circuit(data) => data.iter().map(Felt::from).collect(), + Value::CircuitOutputs { + circuits: data, + modulus, + } => { + let mut felts = data.iter().map(Felt::from).collect::>(); + felts.push(modulus.into()); + felts } Value::EcPoint { x, y } => { vec![*x, *y] diff --git a/program.cairo b/program.cairo new file mode 100644 index 000000000..5624c92cc --- /dev/null +++ b/program.cairo @@ -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::> {}; + let in2 = CircuitElement::> {}; + 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) +} diff --git a/src/libfuncs/circuit.rs b/src/libfuncs/circuit.rs index 1e03e8448..baae4caa5 100644 --- a/src/libfuncs/circuit.rs +++ b/src/libfuncs/circuit.rs @@ -75,7 +75,7 @@ pub fn build<'ctx, 'this>( SignatureOnlyConcreteLibfunc { signature, .. }, ) | CircuitConcreteLibfunc::U96GuaranteeVerify(SignatureOnlyConcreteLibfunc { signature }) => { - super::build_noop::<1, true>( + super::build_noop::<1, false>( context, registry, entry, diff --git a/src/metadata/trace_dump.rs b/src/metadata/trace_dump.rs index 994f28868..c4fc24c9a 100644 --- a/src/metadata/trace_dump.rs +++ b/src/metadata/trace_dump.rs @@ -566,22 +566,36 @@ pub mod trace_dump_runtime { }; let u384_layout = Layout::from_size_align(48, 16).unwrap(); + let u96_layout = Layout::from_size_align(12, 16).unwrap(); + + let u384_layout_size = u384_layout.pad_to_align().size(); + let u96_layout_size = u96_layout.pad_to_align().size(); let n_outputs = circuit.circuit_info.values.len(); let mut values = Vec::with_capacity(n_outputs); - let value_ptr = value_ptr.cast::<[u8; 48]>(); - - let size = u384_layout.pad_to_align().size(); + let circuits_ptr = value_ptr.cast::<[u8; 48]>(); for i in 0..n_outputs { - let current_ptr = value_ptr.byte_add(size * i); + let current_ptr = circuits_ptr.byte_add(u384_layout_size * i); let current_value = current_ptr.as_ref(); values.push(BigUint::from_bytes_le(current_value)); } - let current_ptr = value_ptr.byte_add(size * n_outputs); - let modulus = BigUint::from_bytes_le(current_ptr.as_ref()); + let (outputs_layout, _) = layout_repeat(&u384_layout, n_outputs).unwrap(); + let (_, modulus_start_offset) = outputs_layout.extend(u96_layout).unwrap(); + + let modulus_ptr = value_ptr.byte_add(modulus_start_offset).cast::<[u8; 12]>(); + let modulus_values: &[u8] = &[]; + + // A modulus is a struct of four limbs + for i in 0..4 { + let current_ptr = modulus_ptr.byte_add(u96_layout_size * i); + let current_value = current_ptr.as_ref(); + [modulus_values, current_value].concat(); + } + + let modulus = BigUint::from_bytes_le(modulus_values); Value::CircuitOutputs { circuits: values, From c3732181b3bd7f7d5d2af9a00f1e6d2e9891f232 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Thu, 8 May 2025 12:59:11 -0300 Subject: [PATCH 21/41] remove unnecesary file --- program.cairo | 30 ------------------------------ 1 file changed, 30 deletions(-) delete mode 100644 program.cairo diff --git a/program.cairo b/program.cairo deleted file mode 100644 index 5624c92cc..000000000 --- a/program.cairo +++ /dev/null @@ -1,30 +0,0 @@ -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::> {}; - let in2 = CircuitElement::> {}; - 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) -} From 833471255c5fe94d68926baf4c78af4092cc1015 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Thu, 8 May 2025 13:05:58 -0300 Subject: [PATCH 22/41] fix clippy --- src/metadata/trace_dump.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/metadata/trace_dump.rs b/src/metadata/trace_dump.rs index c4fc24c9a..737daa28b 100644 --- a/src/metadata/trace_dump.rs +++ b/src/metadata/trace_dump.rs @@ -227,7 +227,7 @@ pub mod trace_dump_runtime { sync::{LazyLock, Mutex}, }; - use crate::{starknet::ArrayAbi, types::TypeBuilder}; + use crate::{starknet::ArrayAbi, types::TypeBuilder, utils::layout_repeat}; use crate::runtime::FeltDict; From 9b9cea863c029fd464574a88fd7457cdbf1cbcd0 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Thu, 8 May 2025 13:52:48 -0300 Subject: [PATCH 23/41] implement circuit_single_limb_less_than_guarantee_verify --- src/libfuncs/circuit.rs | 42 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/src/libfuncs/circuit.rs b/src/libfuncs/circuit.rs index 1e03e8448..9e65da478 100644 --- a/src/libfuncs/circuit.rs +++ b/src/libfuncs/circuit.rs @@ -71,10 +71,12 @@ pub fn build<'ctx, 'this>( CircuitConcreteLibfunc::IntoU96Guarantee(info) => { build_into_u96_guarantee(context, registry, entry, location, helper, metadata, info) } - CircuitConcreteLibfunc::U96SingleLimbLessThanGuaranteeVerify( - SignatureOnlyConcreteLibfunc { signature, .. }, - ) - | CircuitConcreteLibfunc::U96GuaranteeVerify(SignatureOnlyConcreteLibfunc { signature }) => { + CircuitConcreteLibfunc::U96SingleLimbLessThanGuaranteeVerify(info) => { + build_u96_single_limb_less_than_guarantee_verify( + context, registry, entry, location, helper, metadata, info, + ) + } + CircuitConcreteLibfunc::U96GuaranteeVerify(SignatureOnlyConcreteLibfunc { signature }) => { super::build_noop::<1, true>( context, registry, @@ -821,6 +823,38 @@ fn build_u96_limbs_less_than_guarantee_verify<'ctx, 'this>( Ok(()) } +fn build_u96_single_limb_less_than_guarantee_verify<'ctx, 'this>( + context: &'ctx Context, + _registry: &ProgramRegistry, + entry: &'this Block<'ctx>, + location: Location<'ctx>, + helper: &LibfuncHelper<'ctx, 'this>, + _metadata: &mut MetadataStorage, + _info: &SignatureOnlyConcreteLibfunc, +) -> Result<()> { + let guarantee = entry.arg(0)?; + + let u96_type = IntegerType::new(context, 96).into(); + // we receive a struct with one attribute + let limb_struct_type = llvm::r#type::r#struct(context, &vec![u96_type; 1], false); + + // extract gate and modulus from input value + let gate = entry.extract_value(context, location, guarantee, limb_struct_type, 0)?; + let modulus = entry.extract_value(context, location, guarantee, limb_struct_type, 1)?; + + // extract the only limb from gate and modulus + let gate_limb = entry.extract_value(context, location, gate, u96_type, 0)?; + let modulus_limb = + entry.extract_value(context, location, modulus, u96_type, 0)?; + + // calcualte diff between limbs + let diff = entry.append_op_result(arith::subi(modulus_limb, gate_limb, location))?; + + entry.append_operation(helper.br(0, &[diff], location)); + + Ok(()) +} + /// Generate MLIR operations for the `get_circuit_output` libfunc. #[allow(clippy::too_many_arguments)] fn build_get_output<'ctx, 'this>( From 8320eed3ab3f41259da44b15b605fbae1746c10c Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Thu, 8 May 2025 16:57:54 -0300 Subject: [PATCH 24/41] fix trace dump for circuit outputs --- program.cairo | 30 ++++++++++++++++++++++++++++++ src/metadata/trace_dump.rs | 38 +++++++++++++++++++++----------------- 2 files changed, 51 insertions(+), 17 deletions(-) create mode 100644 program.cairo diff --git a/program.cairo b/program.cairo new file mode 100644 index 000000000..5624c92cc --- /dev/null +++ b/program.cairo @@ -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::> {}; + let in2 = CircuitElement::> {}; + 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) +} diff --git a/src/metadata/trace_dump.rs b/src/metadata/trace_dump.rs index 737daa28b..510aa8a7b 100644 --- a/src/metadata/trace_dump.rs +++ b/src/metadata/trace_dump.rs @@ -565,37 +565,41 @@ pub mod trace_dump_runtime { panic!("generic arg should be a Circuit"); }; - let u384_layout = Layout::from_size_align(48, 16).unwrap(); let u96_layout = Layout::from_size_align(12, 16).unwrap(); - let u384_layout_size = u384_layout.pad_to_align().size(); - let u96_layout_size = u96_layout.pad_to_align().size(); - let n_outputs = circuit.circuit_info.values.len(); let mut values = Vec::with_capacity(n_outputs); - let circuits_ptr = value_ptr.cast::<[u8; 48]>(); + let circuits_ptr = value_ptr.cast::<[u8; 12]>(); + + let mut outputs_layout = Layout::new::<()>(); + let mut limb_offset; + // get gate values for i in 0..n_outputs { - let current_ptr = circuits_ptr.byte_add(u384_layout_size * i); - let current_value = current_ptr.as_ref(); - values.push(BigUint::from_bytes_le(current_value)); + let mut gate_value = [0u8; 48]; + for j in 0..4 { + (outputs_layout, limb_offset) = + outputs_layout.extend(u96_layout).unwrap(); + let current_ptr = circuits_ptr.byte_add(limb_offset); + let current_value = current_ptr.as_ref(); + gate_value[(12 * j)..(12 + 12 * j)].copy_from_slice(current_value); + } + values.push(BigUint::from_bytes_le(&gate_value)); } - let (outputs_layout, _) = layout_repeat(&u384_layout, n_outputs).unwrap(); - let (_, modulus_start_offset) = outputs_layout.extend(u96_layout).unwrap(); - - let modulus_ptr = value_ptr.byte_add(modulus_start_offset).cast::<[u8; 12]>(); - let modulus_values: &[u8] = &[]; + let mut limb_offset; + let mut modulus_value = [0u8; 48]; - // A modulus is a struct of four limbs + // get modulus value for i in 0..4 { - let current_ptr = modulus_ptr.byte_add(u96_layout_size * i); + (outputs_layout, limb_offset) = outputs_layout.extend(u96_layout).unwrap(); + let current_ptr = circuits_ptr.byte_add(limb_offset); let current_value = current_ptr.as_ref(); - [modulus_values, current_value].concat(); + modulus_value[(12 * i)..(12 + 12 * i)].copy_from_slice(current_value); } - let modulus = BigUint::from_bytes_le(modulus_values); + let modulus = BigUint::from_bytes_le(&modulus_value); Value::CircuitOutputs { circuits: values, From adb2132397b5d09603084bd10f70fe8f4aaf689d Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Fri, 9 May 2025 09:46:36 -0300 Subject: [PATCH 25/41] fix felt_dict_get --- .../sierra-emu/src/vm/felt252_dict_entry.rs | 41 +++++-------------- 1 file changed, 10 insertions(+), 31 deletions(-) diff --git a/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs b/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs index 563ba0503..b7b8b3b49 100644 --- a/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs +++ b/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs @@ -36,39 +36,18 @@ pub fn eval_get( }; assert_eq!(info.ty, ty); - if let std::collections::hash_map::Entry::Vacant(e) = data.entry(key) { - let default_value = Value::default_for_type(registry, &info.ty); - e.insert(default_value.clone()); + let mut count = count; - let count = count + 1; + let value = data + .entry(key) + .or_insert_with(|| { + count += 1; - EvalAction::NormalBranch( - 1, - smallvec![ - Value::FeltDictEntry { - ty, - data, - count, - key - }, - default_value, - ], - ) - } else { - let value = data.get(&key).unwrap().to_owned(); - EvalAction::NormalBranch( - 0, - smallvec![ - Value::FeltDictEntry { - ty, - data, - count, - key - }, - value, - ], - ) - } + Value::default_for_type(registry, &ty) + }) + .to_owned(); + + EvalAction::NormalBranch(0, smallvec![Value::FeltDict { ty, data, count }, value]) } pub fn eval_finalize( From e8d7c31dcde4ea201794aea73ad90cdbe42b41f1 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Fri, 9 May 2025 09:47:17 -0300 Subject: [PATCH 26/41] fix felt_dict_get --- debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs b/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs index b7b8b3b49..42a6055f2 100644 --- a/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs +++ b/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs @@ -29,15 +29,13 @@ pub fn eval_get( let [Value::FeltDict { ty, mut data, - count, + mut count, }, Value::Felt(key)]: [Value; 2] = args.try_into().unwrap() else { panic!() }; assert_eq!(info.ty, ty); - let mut count = count; - let value = data .entry(key) .or_insert_with(|| { From 52f18cf34120256e0a737d827c7a9fea83fd130a Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Fri, 9 May 2025 10:30:55 -0300 Subject: [PATCH 27/41] implement U96LimbsLessThanGuarantee for trace dump --- Cargo.lock | 4 +-- src/libfuncs/circuit.rs | 41 ++++++++++++++++++++++++++--- src/metadata/trace_dump.rs | 51 ++++++++++++++++++++++++++++++++---- src/utils/trace_dump.rs | 53 ++++++++++++++++++++++++++++++++------ 4 files changed, 130 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 146901f47..7a0220f8b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1166,7 +1166,7 @@ dependencies = [ "cairo-lang-starknet", "cairo-lang-starknet-classes", "generic-array", - "hashbrown 0.15.2", + "hashbrown 0.15.3", "hex", "indoc", "keccak", @@ -1184,7 +1184,7 @@ dependencies = [ "sha3", "starknet-crypto", "starknet-types-core", - "thiserror 2.0.12", + "thiserror", "zip", ] diff --git a/src/libfuncs/circuit.rs b/src/libfuncs/circuit.rs index baae4caa5..959815372 100644 --- a/src/libfuncs/circuit.rs +++ b/src/libfuncs/circuit.rs @@ -71,10 +71,12 @@ pub fn build<'ctx, 'this>( CircuitConcreteLibfunc::IntoU96Guarantee(info) => { build_into_u96_guarantee(context, registry, entry, location, helper, metadata, info) } - CircuitConcreteLibfunc::U96SingleLimbLessThanGuaranteeVerify( - SignatureOnlyConcreteLibfunc { signature, .. }, - ) - | CircuitConcreteLibfunc::U96GuaranteeVerify(SignatureOnlyConcreteLibfunc { signature }) => { + CircuitConcreteLibfunc::U96SingleLimbLessThanGuaranteeVerify(info) => { + build_u96_single_limb_less_than_guarantee_verify( + context, registry, entry, location, helper, metadata, info, + ) + } + CircuitConcreteLibfunc::U96GuaranteeVerify(SignatureOnlyConcreteLibfunc { signature }) => { super::build_noop::<1, false>( context, registry, @@ -821,6 +823,37 @@ fn build_u96_limbs_less_than_guarantee_verify<'ctx, 'this>( Ok(()) } +fn build_u96_single_limb_less_than_guarantee_verify<'ctx, 'this>( + context: &'ctx Context, + _registry: &ProgramRegistry, + entry: &'this Block<'ctx>, + location: Location<'ctx>, + helper: &LibfuncHelper<'ctx, 'this>, + _metadata: &mut MetadataStorage, + _info: &SignatureOnlyConcreteLibfunc, +) -> Result<()> { + let guarantee = entry.arg(0)?; + + let u96_type = IntegerType::new(context, 96).into(); + // this libfunc will always receive gate and modulus with single limb + let limb_struct_type = llvm::r#type::r#struct(context, &[u96_type; 1], false); + + // extract gate and modulus from input value + let gate = entry.extract_value(context, location, guarantee, limb_struct_type, 0)?; + let modulus = entry.extract_value(context, location, guarantee, limb_struct_type, 1)?; + + // extract the only limb from gate and modulus + let gate_limb = entry.extract_value(context, location, gate, u96_type, 0)?; + let modulus_limb = entry.extract_value(context, location, modulus, u96_type, 0)?; + + // calcualte diff between limbs + let diff = entry.append_op_result(arith::subi(modulus_limb, gate_limb, location))?; + + entry.append_operation(helper.br(0, &[diff], location)); + + Ok(()) +} + /// Generate MLIR operations for the `get_circuit_output` libfunc. #[allow(clippy::too_many_arguments)] fn build_get_output<'ctx, 'this>( diff --git a/src/metadata/trace_dump.rs b/src/metadata/trace_dump.rs index 510aa8a7b..7108d1512 100644 --- a/src/metadata/trace_dump.rs +++ b/src/metadata/trace_dump.rs @@ -208,7 +208,7 @@ pub mod trace_dump_runtime { }; use cairo_lang_utils::ordered_hash_map::OrderedHashMap; use itertools::Itertools; - use num_bigint::{BigInt, BigUint}; + use num_bigint::{BigInt, BigUint, Sign}; use num_traits::One; use sierra_emu::{ starknet::{ @@ -227,7 +227,7 @@ pub mod trace_dump_runtime { sync::{LazyLock, Mutex}, }; - use crate::{starknet::ArrayAbi, types::TypeBuilder, utils::layout_repeat}; + use crate::{starknet::ArrayAbi, types::TypeBuilder}; use crate::runtime::FeltDict; @@ -576,7 +576,7 @@ pub mod trace_dump_runtime { let mut limb_offset; // get gate values - for i in 0..n_outputs { + for _i in 0..n_outputs { let mut gate_value = [0u8; 48]; for j in 0..4 { (outputs_layout, limb_offset) = @@ -652,7 +652,6 @@ pub mod trace_dump_runtime { let value = unsafe { value_ptr.as_ref() }; Value::CircuitModulus(BigUint::from_bytes_le(value)) } - CircuitTypeConcrete::InverseGate(_) => Value::Unit, CircuitTypeConcrete::MulModGate(_) => Value::Unit, CircuitTypeConcrete::SubModGate(_) => Value::Unit, @@ -665,7 +664,49 @@ pub mod trace_dump_runtime { Value::U128(u128::from_le_bytes(array_value)) } - CircuitTypeConcrete::U96LimbsLessThanGuarantee(_) => Value::Unit, + CircuitTypeConcrete::U96LimbsLessThanGuarantee(info) => { + let u96_layout = Layout::from_size_align(12, 16).unwrap(); + + let mut limb_value = [0u8; 16]; + + let value_ptr = value_ptr.cast::<[u8; 12]>(); + + let mut guarantee_layout = Layout::new::<()>(); + let mut limb_offset = 0; + + let output_limbs = (0..info.limb_count) + .map(|_| { + (guarantee_layout, limb_offset) = + guarantee_layout.extend(u96_layout).unwrap(); + let current_ptr = value_ptr.byte_add(limb_offset); + limb_value[..12].copy_from_slice(current_ptr.as_ref()); + + Value::BoundedInt { + range: 0.into()..BigInt::one() << 96, + value: BigInt::from_bytes_le(Sign::Plus, &limb_value), + } + }) + .collect::>(); + + let modulus_limbs = (0..info.limb_count) + .map(|_| { + (guarantee_layout, limb_offset) = + guarantee_layout.extend(u96_layout).unwrap(); + let current_ptr = value_ptr.byte_add(limb_offset); + limb_value[..12].copy_from_slice(current_ptr.as_ref()); + + Value::BoundedInt { + range: 0.into()..BigInt::one() << 96, + value: BigInt::from_bytes_le(Sign::Plus, &limb_value), + } + }) + .collect::>(); + + Value::Struct(vec![ + Value::Struct(output_limbs), + Value::Struct(modulus_limbs), + ]) + } }, CoreTypeConcrete::Const(_) => todo!("CoreTypeConcrete::Const"), CoreTypeConcrete::Sint8(_) => Value::I8(value_ptr.cast().read()), diff --git a/src/utils/trace_dump.rs b/src/utils/trace_dump.rs index afa489e03..723222a2e 100644 --- a/src/utils/trace_dump.rs +++ b/src/utils/trace_dump.rs @@ -168,9 +168,46 @@ mod tests { program } + #[fixture] + fn program_circuit() -> Program { + let (_, program) = load_cairo!( + 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::> {}; + let in2 = CircuitElement::> {}; + 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) + } + ); + program + } + #[rstest] - fn test_program(program: Program) { - let entrypoint_function = &program + fn test_program(program_circuit: Program) { + let entrypoint_function = &program_circuit .funcs .iter() .find(|x| { @@ -184,7 +221,7 @@ mod tests { let native_context = NativeContext::new(); let module = native_context - .compile(&program, false, Some(Default::default())) + .compile(&program_circuit, false, Some(Default::default())) .expect("failed to compile context"); let executor = AotNativeExecutor::from_native_module(module, OptLevel::default()).unwrap(); @@ -193,10 +230,10 @@ mod tests { unsafe { *trace_id = 0 }; } - TRACE_DUMP - .lock() - .unwrap() - .insert(0, TraceDump::new(ProgramRegistry::new(&program).unwrap())); + TRACE_DUMP.lock().unwrap().insert( + 0, + TraceDump::new(ProgramRegistry::new(&program_circuit).unwrap()), + ); executor .invoke_dynamic(&entrypoint_function.id, &[], Some(u64::MAX)) @@ -211,7 +248,7 @@ mod tests { .trace .clone(); - let mut vm = VirtualMachine::new(Arc::new(program)); + let mut vm = VirtualMachine::new(Arc::new(program_circuit)); let initial_gas = u64::MAX; let args = []; From 7109dedb30e2b473dfdb6ed5b69f58feb08e8cd7 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Fri, 9 May 2025 10:33:06 -0300 Subject: [PATCH 28/41] remove unnecessary code --- src/libfuncs/circuit.rs | 41 ++++--------------------------- src/utils/trace_dump.rs | 53 +++++++---------------------------------- 2 files changed, 12 insertions(+), 82 deletions(-) diff --git a/src/libfuncs/circuit.rs b/src/libfuncs/circuit.rs index 959815372..baae4caa5 100644 --- a/src/libfuncs/circuit.rs +++ b/src/libfuncs/circuit.rs @@ -71,12 +71,10 @@ pub fn build<'ctx, 'this>( CircuitConcreteLibfunc::IntoU96Guarantee(info) => { build_into_u96_guarantee(context, registry, entry, location, helper, metadata, info) } - CircuitConcreteLibfunc::U96SingleLimbLessThanGuaranteeVerify(info) => { - build_u96_single_limb_less_than_guarantee_verify( - context, registry, entry, location, helper, metadata, info, - ) - } - CircuitConcreteLibfunc::U96GuaranteeVerify(SignatureOnlyConcreteLibfunc { signature }) => { + CircuitConcreteLibfunc::U96SingleLimbLessThanGuaranteeVerify( + SignatureOnlyConcreteLibfunc { signature, .. }, + ) + | CircuitConcreteLibfunc::U96GuaranteeVerify(SignatureOnlyConcreteLibfunc { signature }) => { super::build_noop::<1, false>( context, registry, @@ -823,37 +821,6 @@ fn build_u96_limbs_less_than_guarantee_verify<'ctx, 'this>( Ok(()) } -fn build_u96_single_limb_less_than_guarantee_verify<'ctx, 'this>( - context: &'ctx Context, - _registry: &ProgramRegistry, - entry: &'this Block<'ctx>, - location: Location<'ctx>, - helper: &LibfuncHelper<'ctx, 'this>, - _metadata: &mut MetadataStorage, - _info: &SignatureOnlyConcreteLibfunc, -) -> Result<()> { - let guarantee = entry.arg(0)?; - - let u96_type = IntegerType::new(context, 96).into(); - // this libfunc will always receive gate and modulus with single limb - let limb_struct_type = llvm::r#type::r#struct(context, &[u96_type; 1], false); - - // extract gate and modulus from input value - let gate = entry.extract_value(context, location, guarantee, limb_struct_type, 0)?; - let modulus = entry.extract_value(context, location, guarantee, limb_struct_type, 1)?; - - // extract the only limb from gate and modulus - let gate_limb = entry.extract_value(context, location, gate, u96_type, 0)?; - let modulus_limb = entry.extract_value(context, location, modulus, u96_type, 0)?; - - // calcualte diff between limbs - let diff = entry.append_op_result(arith::subi(modulus_limb, gate_limb, location))?; - - entry.append_operation(helper.br(0, &[diff], location)); - - Ok(()) -} - /// Generate MLIR operations for the `get_circuit_output` libfunc. #[allow(clippy::too_many_arguments)] fn build_get_output<'ctx, 'this>( diff --git a/src/utils/trace_dump.rs b/src/utils/trace_dump.rs index 723222a2e..afa489e03 100644 --- a/src/utils/trace_dump.rs +++ b/src/utils/trace_dump.rs @@ -168,46 +168,9 @@ mod tests { program } - #[fixture] - fn program_circuit() -> Program { - let (_, program) = load_cairo!( - 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::> {}; - let in2 = CircuitElement::> {}; - 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) - } - ); - program - } - #[rstest] - fn test_program(program_circuit: Program) { - let entrypoint_function = &program_circuit + fn test_program(program: Program) { + let entrypoint_function = &program .funcs .iter() .find(|x| { @@ -221,7 +184,7 @@ mod tests { let native_context = NativeContext::new(); let module = native_context - .compile(&program_circuit, false, Some(Default::default())) + .compile(&program, false, Some(Default::default())) .expect("failed to compile context"); let executor = AotNativeExecutor::from_native_module(module, OptLevel::default()).unwrap(); @@ -230,10 +193,10 @@ mod tests { unsafe { *trace_id = 0 }; } - TRACE_DUMP.lock().unwrap().insert( - 0, - TraceDump::new(ProgramRegistry::new(&program_circuit).unwrap()), - ); + TRACE_DUMP + .lock() + .unwrap() + .insert(0, TraceDump::new(ProgramRegistry::new(&program).unwrap())); executor .invoke_dynamic(&entrypoint_function.id, &[], Some(u64::MAX)) @@ -248,7 +211,7 @@ mod tests { .trace .clone(); - let mut vm = VirtualMachine::new(Arc::new(program_circuit)); + let mut vm = VirtualMachine::new(Arc::new(program)); let initial_gas = u64::MAX; let args = []; From f8c5622b81b828fb1f6db645cddd142ed443c9b6 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Fri, 9 May 2025 12:31:01 -0300 Subject: [PATCH 29/41] fmt --- debug_utils/sierra-emu/src/utils.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/debug_utils/sierra-emu/src/utils.rs b/debug_utils/sierra-emu/src/utils.rs index 7a4fec461..979a4896c 100644 --- a/debug_utils/sierra-emu/src/utils.rs +++ b/debug_utils/sierra-emu/src/utils.rs @@ -1,5 +1,7 @@ use cairo_lang_sierra::{ - extensions::core::{CoreLibfunc, CoreType, CoreTypeConcrete}, ids::ConcreteTypeId, program_registry::ProgramRegistry + extensions::core::{CoreLibfunc, CoreType, CoreTypeConcrete}, + ids::ConcreteTypeId, + program_registry::ProgramRegistry, }; use num_bigint::BigInt; use num_traits::ToPrimitive; @@ -36,9 +38,7 @@ pub fn get_value_from_integer( ) -> Value { let ty = registry.get_type(ty_id).unwrap(); match ty { - CoreTypeConcrete::NonZero(info) => { - get_value_from_integer(registry, &info.ty, value) - } + CoreTypeConcrete::NonZero(info) => get_value_from_integer(registry, &info.ty, value), CoreTypeConcrete::Sint8(_) => Value::I8(value.to_i8().unwrap()), CoreTypeConcrete::Sint16(_) => Value::I16(value.to_i16().unwrap()), CoreTypeConcrete::Sint32(_) => Value::I32(value.to_i32().unwrap()), @@ -55,8 +55,11 @@ pub fn get_value_from_integer( range: range.lower.clone()..range.upper.clone(), value, } - }, + } CoreTypeConcrete::Felt252(_) => Value::Felt(value.into()), - _ => panic!("cannot get integer value for a non-integer type: {}", type_to_name(ty_id, registry)), + _ => panic!( + "cannot get integer value for a non-integer type: {}", + type_to_name(ty_id, registry) + ), } } From 6a03cbd36bd7147c61b891e53783c173eca05d60 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Fri, 9 May 2025 14:30:07 -0300 Subject: [PATCH 30/41] fix felt_dict_entry_get --- debug_utils/sierra-emu/src/utils.rs | 16 +++++------ debug_utils/sierra-emu/src/vm/cast.rs | 11 ++++---- .../sierra-emu/src/vm/felt252_dict_entry.rs | 27 +++++++++++-------- debug_utils/sierra-emu/src/vm/int_range.rs | 16 +++++------ 4 files changed, 36 insertions(+), 34 deletions(-) diff --git a/debug_utils/sierra-emu/src/utils.rs b/debug_utils/sierra-emu/src/utils.rs index 979a4896c..0b4689f1c 100644 --- a/debug_utils/sierra-emu/src/utils.rs +++ b/debug_utils/sierra-emu/src/utils.rs @@ -1,12 +1,11 @@ use cairo_lang_sierra::{ extensions::core::{CoreLibfunc, CoreType, CoreTypeConcrete}, - ids::ConcreteTypeId, program_registry::ProgramRegistry, }; use num_bigint::BigInt; use num_traits::ToPrimitive; -use crate::{debug::type_to_name, Value}; +use crate::Value; /// Receives a vector of values, filters any which is non numeric and returns a `Vec` /// Useful when a binary operation takes generic values (like with bounded ints). @@ -33,12 +32,14 @@ pub fn get_numeric_args_as_bigints(args: &[Value]) -> Vec { pub fn get_value_from_integer( registry: &ProgramRegistry, - ty_id: &ConcreteTypeId, + ty: &CoreTypeConcrete, value: BigInt, ) -> Value { - let ty = registry.get_type(ty_id).unwrap(); match ty { - CoreTypeConcrete::NonZero(info) => get_value_from_integer(registry, &info.ty, value), + CoreTypeConcrete::NonZero(info) => { + let ty = registry.get_type(&info.ty).unwrap(); + get_value_from_integer(registry, ty, value) + } CoreTypeConcrete::Sint8(_) => Value::I8(value.to_i8().unwrap()), CoreTypeConcrete::Sint16(_) => Value::I16(value.to_i16().unwrap()), CoreTypeConcrete::Sint32(_) => Value::I32(value.to_i32().unwrap()), @@ -57,9 +58,6 @@ pub fn get_value_from_integer( } } CoreTypeConcrete::Felt252(_) => Value::Felt(value.into()), - _ => panic!( - "cannot get integer value for a non-integer type: {}", - type_to_name(ty_id, registry) - ), + _ => panic!("cannot get integer value for a non-integer type"), } } diff --git a/debug_utils/sierra-emu/src/vm/cast.rs b/debug_utils/sierra-emu/src/vm/cast.rs index f2a9d66ca..cc0d77a1f 100644 --- a/debug_utils/sierra-emu/src/vm/cast.rs +++ b/debug_utils/sierra-emu/src/vm/cast.rs @@ -35,14 +35,13 @@ fn eval_downcast( }; let [value] = get_numeric_args_as_bigints(&args[1..]).try_into().unwrap(); + let int_ty = registry.get_type(&info.to_ty).unwrap(); + let range = info.to_range.lower.clone()..info.to_range.upper.clone(); if range.contains(&value) { EvalAction::NormalBranch( 0, - smallvec![ - range_check, - get_value_from_integer(registry, &info.to_ty, value) - ], + smallvec![range_check, get_value_from_integer(registry, int_ty, value)], ) } else { EvalAction::NormalBranch(1, smallvec![range_check]) @@ -55,10 +54,10 @@ fn eval_upcast( args: Vec, ) -> EvalAction { let [value] = get_numeric_args_as_bigints(&args).try_into().unwrap(); - let int_ty_id = &info.branch_signatures()[0].vars[0].ty; + let int_ty = registry.get_type(&info.param_signatures()[1].ty).unwrap(); EvalAction::NormalBranch( 0, - smallvec![get_value_from_integer(registry, int_ty_id, value)], + smallvec![get_value_from_integer(registry, int_ty, value)], ) } diff --git a/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs b/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs index a3f679294..acfe527f4 100644 --- a/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs +++ b/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs @@ -36,20 +36,25 @@ pub fn eval_get( }; assert_eq!(info.ty, ty); - let _ = data.entry(key).or_insert_with(|| { - count += 1; - - Value::default_for_type(registry, &ty) - }); + let value = data + .entry(key) + .or_insert_with(|| { + count += 1; + Value::default_for_type(registry, &ty) + }) + .clone(); EvalAction::NormalBranch( 0, - smallvec![Value::FeltDictEntry { - ty, - data, - count, - key - }], + smallvec![ + Value::FeltDictEntry { + ty, + data, + count, + key + }, + value + ], ) } diff --git a/debug_utils/sierra-emu/src/vm/int_range.rs b/debug_utils/sierra-emu/src/vm/int_range.rs index ffd46eafd..50b794bd2 100644 --- a/debug_utils/sierra-emu/src/vm/int_range.rs +++ b/debug_utils/sierra-emu/src/vm/int_range.rs @@ -38,12 +38,12 @@ fn eval_try_new( }; let [x, y]: [BigInt; 2] = get_numeric_args_as_bigints(&args[1..]).try_into().unwrap(); - let int_ty_id = &info.param_signatures()[1].ty; + let int_ty = registry.get_type(&info.param_signatures()[1].ty).unwrap(); // if x >= y then the range is not valid and we return [y, y) (empty range) if x < y { - let x = get_value_from_integer(registry, int_ty_id, x); - let y = get_value_from_integer(registry, int_ty_id, y); + let x = get_value_from_integer(registry, int_ty, x); + let y = get_value_from_integer(registry, int_ty, y); EvalAction::NormalBranch( 0, smallvec![ @@ -55,7 +55,7 @@ fn eval_try_new( ], ) } else { - let y = get_value_from_integer(registry, int_ty_id, y); + let y = get_value_from_integer(registry, int_ty, y); EvalAction::NormalBranch( 1, smallvec![ @@ -78,12 +78,12 @@ fn eval_pop_front( panic!() }; let [x, y]: [BigInt; 2] = get_numeric_args_as_bigints(&[*x, *y]).try_into().unwrap(); - let int_ty_id = &info.param_signatures()[0].ty; + let int_ty = registry.get_type(&info.param_signatures()[1].ty).unwrap(); if x < y { - let x_plus_1 = get_value_from_integer(registry, int_ty_id, &x + 1); - let x = get_value_from_integer(registry, int_ty_id, x); - let y = get_value_from_integer(registry, int_ty_id, y); + let x_plus_1 = get_value_from_integer(registry, int_ty, &x + 1); + let x = get_value_from_integer(registry, int_ty, x); + let y = get_value_from_integer(registry, int_ty, y); EvalAction::NormalBranch( 0, From efcc99d59dcdbc5a5f60196a409d4ba7f535774b Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Fri, 9 May 2025 14:32:53 -0300 Subject: [PATCH 31/41] revert change in circuits.rs --- src/libfuncs/circuit.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libfuncs/circuit.rs b/src/libfuncs/circuit.rs index baae4caa5..1e03e8448 100644 --- a/src/libfuncs/circuit.rs +++ b/src/libfuncs/circuit.rs @@ -75,7 +75,7 @@ pub fn build<'ctx, 'this>( SignatureOnlyConcreteLibfunc { signature, .. }, ) | CircuitConcreteLibfunc::U96GuaranteeVerify(SignatureOnlyConcreteLibfunc { signature }) => { - super::build_noop::<1, false>( + super::build_noop::<1, true>( context, registry, entry, From 969fbd44140fd33dbb57fd4654b2122e92aa651a Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Fri, 9 May 2025 14:33:30 -0300 Subject: [PATCH 32/41] remove unwanted file --- program.cairo | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 program.cairo diff --git a/program.cairo b/program.cairo deleted file mode 100644 index 644d1d883..000000000 --- a/program.cairo +++ /dev/null @@ -1,12 +0,0 @@ -use core::circuit::{ - AddInputResultTrait, AddMod, CircuitElement, CircuitInput, CircuitInputs, CircuitModulus, - CircuitOutputsTrait, EvalCircuitTrait, MulMod, RangeCheck96, circuit_add, circuit_inverse, - circuit_mul, circuit_sub, u384, u96, -}; -use core::num::traits::Zero; -use core::traits::TryInto; - -fn test_into_u384() -> u384 { - 0x100000023000000450000006700000089000000ab000000cd000000ef0000000_u256 - .into() -} From a5b6a0c8481aea3bddee2b5e7bb047d6d1785162 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Fri, 9 May 2025 14:39:46 -0300 Subject: [PATCH 33/41] revert unwanted change --- debug_utils/sierra-emu/src/vm/cast.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/debug_utils/sierra-emu/src/vm/cast.rs b/debug_utils/sierra-emu/src/vm/cast.rs index cc0d77a1f..8718dca64 100644 --- a/debug_utils/sierra-emu/src/vm/cast.rs +++ b/debug_utils/sierra-emu/src/vm/cast.rs @@ -54,7 +54,9 @@ fn eval_upcast( args: Vec, ) -> EvalAction { let [value] = get_numeric_args_as_bigints(&args).try_into().unwrap(); - let int_ty = registry.get_type(&info.param_signatures()[1].ty).unwrap(); + let int_ty = registry + .get_type(&info.branch_signatures()[0].vars[0].ty) + .unwrap(); EvalAction::NormalBranch( 0, From 729faff53bb54979d0c80b58b8a2156ef05e733d Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Fri, 9 May 2025 14:44:37 -0300 Subject: [PATCH 34/41] revert unwanted change --- debug_utils/sierra-emu/src/vm/bounded_int.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/debug_utils/sierra-emu/src/vm/bounded_int.rs b/debug_utils/sierra-emu/src/vm/bounded_int.rs index e7c421624..55d4955d5 100644 --- a/debug_utils/sierra-emu/src/vm/bounded_int.rs +++ b/debug_utils/sierra-emu/src/vm/bounded_int.rs @@ -126,10 +126,7 @@ pub fn eval_div_rem( info: &BoundedIntDivRemConcreteLibfunc, args: Vec, ) -> EvalAction { - let range_check @ Value::Unit: Value = args[0].clone() else { - panic!() - }; - let [lhs, rhs]: [BigInt; 2] = get_numeric_args_as_bigints(&args[1..]).try_into().unwrap(); + let [lhs, rhs]: [BigInt; 2] = get_numeric_args_as_bigints(&args).try_into().unwrap(); let quo = &lhs / &rhs; let rem = lhs % rhs; @@ -154,7 +151,7 @@ pub fn eval_div_rem( EvalAction::NormalBranch( 0, smallvec![ - range_check, + Value::Unit, // range_check Value::BoundedInt { range: quo_range, value: quo, From acd1608817d13eb9f816da58db938ba6d6b5a09b Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Fri, 9 May 2025 17:25:53 -0300 Subject: [PATCH 35/41] make trace dump for circuit outputs cleaner --- src/libfuncs/circuit.rs | 41 +++++++++++++++-- src/metadata/trace_dump.rs | 93 ++++++++++++++------------------------ src/utils/trace_dump.rs | 47 +++++++++++++++++-- 3 files changed, 114 insertions(+), 67 deletions(-) diff --git a/src/libfuncs/circuit.rs b/src/libfuncs/circuit.rs index 1e03e8448..9af589c3a 100644 --- a/src/libfuncs/circuit.rs +++ b/src/libfuncs/circuit.rs @@ -71,10 +71,12 @@ pub fn build<'ctx, 'this>( CircuitConcreteLibfunc::IntoU96Guarantee(info) => { build_into_u96_guarantee(context, registry, entry, location, helper, metadata, info) } - CircuitConcreteLibfunc::U96SingleLimbLessThanGuaranteeVerify( - SignatureOnlyConcreteLibfunc { signature, .. }, - ) - | CircuitConcreteLibfunc::U96GuaranteeVerify(SignatureOnlyConcreteLibfunc { signature }) => { + CircuitConcreteLibfunc::U96SingleLimbLessThanGuaranteeVerify(info) => { + build_u96_single_limb_less_than_guarantee_verify( + context, registry, entry, location, helper, metadata, info, + ) + } + CircuitConcreteLibfunc::U96GuaranteeVerify(SignatureOnlyConcreteLibfunc { signature }) => { super::build_noop::<1, true>( context, registry, @@ -93,6 +95,37 @@ pub fn build<'ctx, 'this>( } } +fn build_u96_single_limb_less_than_guarantee_verify<'ctx, 'this>( + context: &'ctx Context, + _registry: &ProgramRegistry, + entry: &'this Block<'ctx>, + location: Location<'ctx>, + helper: &LibfuncHelper<'ctx, 'this>, + _metadata: &mut MetadataStorage, + _info: &SignatureOnlyConcreteLibfunc, +) -> Result<()> { + let guarantee = entry.arg(0)?; + + let u96_type = IntegerType::new(context, 96).into(); + // this libfunc will always receive gate and modulus with single limb + let limb_struct_type = llvm::r#type::r#struct(context, &[u96_type; 1], false); + + // extract gate and modulus from input value + let gate = entry.extract_value(context, location, guarantee, limb_struct_type, 0)?; + let modulus = entry.extract_value(context, location, guarantee, limb_struct_type, 1)?; + + // extract the only limb from gate and modulus + let gate_limb = entry.extract_value(context, location, gate, u96_type, 0)?; + let modulus_limb = entry.extract_value(context, location, modulus, u96_type, 0)?; + + // calcualte diff between limbs + let diff = entry.append_op_result(arith::subi(modulus_limb, gate_limb, location))?; + + entry.append_operation(helper.br(0, &[diff], location)); + + Ok(()) +} + /// Generate MLIR operations for the `init_circuit_data` libfunc. #[allow(clippy::too_many_arguments)] fn build_init_circuit_data<'ctx, 'this>( diff --git a/src/metadata/trace_dump.rs b/src/metadata/trace_dump.rs index 7108d1512..2f1cd83e3 100644 --- a/src/metadata/trace_dump.rs +++ b/src/metadata/trace_dump.rs @@ -227,7 +227,7 @@ pub mod trace_dump_runtime { sync::{LazyLock, Mutex}, }; - use crate::{starknet::ArrayAbi, types::TypeBuilder}; + use crate::{starknet::ArrayAbi, types::TypeBuilder, utils::{get_integer_layout, layout_repeat}}; use crate::runtime::FeltDict; @@ -565,40 +565,31 @@ pub mod trace_dump_runtime { panic!("generic arg should be a Circuit"); }; - let u96_layout = Layout::from_size_align(12, 16).unwrap(); + let u96_layout = get_integer_layout(96); let n_outputs = circuit.circuit_info.values.len(); let mut values = Vec::with_capacity(n_outputs); - let circuits_ptr = value_ptr.cast::<[u8; 12]>(); + let (u384_struct_layout, _) = layout_repeat(&u96_layout, 4).unwrap(); + let (gates_array_layout, _) = layout_repeat(&u384_struct_layout, n_outputs).unwrap(); + let (_, modulus_offset) = gates_array_layout.extend(u384_struct_layout).unwrap(); - let mut outputs_layout = Layout::new::<()>(); - let mut limb_offset; + let value_ptr = value_ptr.cast::<[u8; 12]>(); // get gate values - for _i in 0..n_outputs { - let mut gate_value = [0u8; 48]; - for j in 0..4 { - (outputs_layout, limb_offset) = - outputs_layout.extend(u96_layout).unwrap(); - let current_ptr = circuits_ptr.byte_add(limb_offset); - let current_value = current_ptr.as_ref(); - gate_value[(12 * j)..(12 + 12 * j)].copy_from_slice(current_value); - } - values.push(BigUint::from_bytes_le(&gate_value)); + for i in 0..n_outputs { + let output_limbs = (0..4).flat_map(|j| { + let offset = u96_layout.size() * j + u384_struct_layout.size() * i; + *value_ptr.byte_add(offset).as_ref() + }).collect::>(); + values.push(BigUint::from_bytes_le(&output_limbs)); } - let mut limb_offset; - let mut modulus_value = [0u8; 48]; - // get modulus value - for i in 0..4 { - (outputs_layout, limb_offset) = outputs_layout.extend(u96_layout).unwrap(); - let current_ptr = circuits_ptr.byte_add(limb_offset); - let current_value = current_ptr.as_ref(); - modulus_value[(12 * i)..(12 + 12 * i)].copy_from_slice(current_value); - } - + let modulus_ptr = value_ptr.byte_add(modulus_offset); + let modulus_value = (0..4).flat_map(|i| { + *modulus_ptr.byte_add(u96_layout.size() * i).as_ref() + }).collect::>(); let modulus = BigUint::from_bytes_le(&modulus_value); Value::CircuitOutputs { @@ -665,42 +656,28 @@ pub mod trace_dump_runtime { Value::U128(u128::from_le_bytes(array_value)) } CircuitTypeConcrete::U96LimbsLessThanGuarantee(info) => { - let u96_layout = Layout::from_size_align(12, 16).unwrap(); + let value_ptr = value_ptr.cast::<[u8; 12]>(); - let mut limb_value = [0u8; 16]; + let u96_layout = get_integer_layout(96); + let (u384_struct_layout, _) = layout_repeat(&u96_layout, info.limb_count).unwrap(); - let value_ptr = value_ptr.cast::<[u8; 12]>(); + let output_limbs = (0..info.limb_count).map(|i| { + let current_ptr = value_ptr.byte_add(u96_layout.size() * i); + Value::BoundedInt { + range: 0.into()..BigInt::one() << 96, + value: BigInt::from_bytes_le(Sign::Plus, current_ptr.as_ref()), + } + }).collect::>(); - let mut guarantee_layout = Layout::new::<()>(); - let mut limb_offset = 0; - - let output_limbs = (0..info.limb_count) - .map(|_| { - (guarantee_layout, limb_offset) = - guarantee_layout.extend(u96_layout).unwrap(); - let current_ptr = value_ptr.byte_add(limb_offset); - limb_value[..12].copy_from_slice(current_ptr.as_ref()); - - Value::BoundedInt { - range: 0.into()..BigInt::one() << 96, - value: BigInt::from_bytes_le(Sign::Plus, &limb_value), - } - }) - .collect::>(); - - let modulus_limbs = (0..info.limb_count) - .map(|_| { - (guarantee_layout, limb_offset) = - guarantee_layout.extend(u96_layout).unwrap(); - let current_ptr = value_ptr.byte_add(limb_offset); - limb_value[..12].copy_from_slice(current_ptr.as_ref()); - - Value::BoundedInt { - range: 0.into()..BigInt::one() << 96, - value: BigInt::from_bytes_le(Sign::Plus, &limb_value), - } - }) - .collect::>(); + let modulus_ptr = value_ptr.byte_add(u384_struct_layout.size()); + + let modulus_limbs = (0..info.limb_count).map(|i| { + let current_ptr = modulus_ptr.byte_add(u96_layout.size() * i); + Value::BoundedInt { + range: 0.into()..BigInt::one() << 96, + value: BigInt::from_bytes_le(Sign::Plus, current_ptr.as_ref()), + } + }).collect::>(); Value::Struct(vec![ Value::Struct(output_limbs), diff --git a/src/utils/trace_dump.rs b/src/utils/trace_dump.rs index afa489e03..b2d977a84 100644 --- a/src/utils/trace_dump.rs +++ b/src/utils/trace_dump.rs @@ -168,9 +168,46 @@ mod tests { program } + #[fixture] + fn program_circuit() -> Program { + let (_, program) = load_cairo! { + 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::> {}; + let in2 = CircuitElement::> {}; + 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) + } + }; + program + } + #[rstest] - fn test_program(program: Program) { - let entrypoint_function = &program + fn test_program(program_circuit: Program) { + let entrypoint_function = &program_circuit .funcs .iter() .find(|x| { @@ -184,7 +221,7 @@ mod tests { let native_context = NativeContext::new(); let module = native_context - .compile(&program, false, Some(Default::default())) + .compile(&program_circuit, false, Some(Default::default())) .expect("failed to compile context"); let executor = AotNativeExecutor::from_native_module(module, OptLevel::default()).unwrap(); @@ -196,7 +233,7 @@ mod tests { TRACE_DUMP .lock() .unwrap() - .insert(0, TraceDump::new(ProgramRegistry::new(&program).unwrap())); + .insert(0, TraceDump::new(ProgramRegistry::new(&program_circuit).unwrap())); executor .invoke_dynamic(&entrypoint_function.id, &[], Some(u64::MAX)) @@ -211,7 +248,7 @@ mod tests { .trace .clone(); - let mut vm = VirtualMachine::new(Arc::new(program)); + let mut vm = VirtualMachine::new(Arc::new(program_circuit)); let initial_gas = u64::MAX; let args = []; From 4d4c8a2dd7e6bc1a720a58ac9302198b7f193500 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Fri, 9 May 2025 17:32:22 -0300 Subject: [PATCH 36/41] remove unwanted code --- src/libfuncs/circuit.rs | 41 ++++------------------------------- src/utils/trace_dump.rs | 47 +++++------------------------------------ 2 files changed, 9 insertions(+), 79 deletions(-) diff --git a/src/libfuncs/circuit.rs b/src/libfuncs/circuit.rs index 9af589c3a..1e03e8448 100644 --- a/src/libfuncs/circuit.rs +++ b/src/libfuncs/circuit.rs @@ -71,12 +71,10 @@ pub fn build<'ctx, 'this>( CircuitConcreteLibfunc::IntoU96Guarantee(info) => { build_into_u96_guarantee(context, registry, entry, location, helper, metadata, info) } - CircuitConcreteLibfunc::U96SingleLimbLessThanGuaranteeVerify(info) => { - build_u96_single_limb_less_than_guarantee_verify( - context, registry, entry, location, helper, metadata, info, - ) - } - CircuitConcreteLibfunc::U96GuaranteeVerify(SignatureOnlyConcreteLibfunc { signature }) => { + CircuitConcreteLibfunc::U96SingleLimbLessThanGuaranteeVerify( + SignatureOnlyConcreteLibfunc { signature, .. }, + ) + | CircuitConcreteLibfunc::U96GuaranteeVerify(SignatureOnlyConcreteLibfunc { signature }) => { super::build_noop::<1, true>( context, registry, @@ -95,37 +93,6 @@ pub fn build<'ctx, 'this>( } } -fn build_u96_single_limb_less_than_guarantee_verify<'ctx, 'this>( - context: &'ctx Context, - _registry: &ProgramRegistry, - entry: &'this Block<'ctx>, - location: Location<'ctx>, - helper: &LibfuncHelper<'ctx, 'this>, - _metadata: &mut MetadataStorage, - _info: &SignatureOnlyConcreteLibfunc, -) -> Result<()> { - let guarantee = entry.arg(0)?; - - let u96_type = IntegerType::new(context, 96).into(); - // this libfunc will always receive gate and modulus with single limb - let limb_struct_type = llvm::r#type::r#struct(context, &[u96_type; 1], false); - - // extract gate and modulus from input value - let gate = entry.extract_value(context, location, guarantee, limb_struct_type, 0)?; - let modulus = entry.extract_value(context, location, guarantee, limb_struct_type, 1)?; - - // extract the only limb from gate and modulus - let gate_limb = entry.extract_value(context, location, gate, u96_type, 0)?; - let modulus_limb = entry.extract_value(context, location, modulus, u96_type, 0)?; - - // calcualte diff between limbs - let diff = entry.append_op_result(arith::subi(modulus_limb, gate_limb, location))?; - - entry.append_operation(helper.br(0, &[diff], location)); - - Ok(()) -} - /// Generate MLIR operations for the `init_circuit_data` libfunc. #[allow(clippy::too_many_arguments)] fn build_init_circuit_data<'ctx, 'this>( diff --git a/src/utils/trace_dump.rs b/src/utils/trace_dump.rs index b2d977a84..afa489e03 100644 --- a/src/utils/trace_dump.rs +++ b/src/utils/trace_dump.rs @@ -168,46 +168,9 @@ mod tests { program } - #[fixture] - fn program_circuit() -> Program { - let (_, program) = load_cairo! { - 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::> {}; - let in2 = CircuitElement::> {}; - 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) - } - }; - program - } - #[rstest] - fn test_program(program_circuit: Program) { - let entrypoint_function = &program_circuit + fn test_program(program: Program) { + let entrypoint_function = &program .funcs .iter() .find(|x| { @@ -221,7 +184,7 @@ mod tests { let native_context = NativeContext::new(); let module = native_context - .compile(&program_circuit, false, Some(Default::default())) + .compile(&program, false, Some(Default::default())) .expect("failed to compile context"); let executor = AotNativeExecutor::from_native_module(module, OptLevel::default()).unwrap(); @@ -233,7 +196,7 @@ mod tests { TRACE_DUMP .lock() .unwrap() - .insert(0, TraceDump::new(ProgramRegistry::new(&program_circuit).unwrap())); + .insert(0, TraceDump::new(ProgramRegistry::new(&program).unwrap())); executor .invoke_dynamic(&entrypoint_function.id, &[], Some(u64::MAX)) @@ -248,7 +211,7 @@ mod tests { .trace .clone(); - let mut vm = VirtualMachine::new(Arc::new(program_circuit)); + let mut vm = VirtualMachine::new(Arc::new(program)); let initial_gas = u64::MAX; let args = []; From 6817c494ddb124188ab94ba019489e727da839df Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Fri, 9 May 2025 17:36:06 -0300 Subject: [PATCH 37/41] increase felt dict count always during get() --- .../sierra-emu/src/vm/felt252_dict_entry.rs | 7 +- src/metadata/trace_dump.rs | 65 +++++++++++-------- 2 files changed, 42 insertions(+), 30 deletions(-) diff --git a/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs b/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs index acfe527f4..1f0da1a01 100644 --- a/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs +++ b/debug_utils/sierra-emu/src/vm/felt252_dict_entry.rs @@ -38,12 +38,11 @@ pub fn eval_get( let value = data .entry(key) - .or_insert_with(|| { - count += 1; - Value::default_for_type(registry, &ty) - }) + .or_insert(Value::default_for_type(registry, &ty)) .clone(); + count += 1; + EvalAction::NormalBranch( 0, smallvec![ diff --git a/src/metadata/trace_dump.rs b/src/metadata/trace_dump.rs index 2f1cd83e3..56999a7b2 100644 --- a/src/metadata/trace_dump.rs +++ b/src/metadata/trace_dump.rs @@ -227,7 +227,11 @@ pub mod trace_dump_runtime { sync::{LazyLock, Mutex}, }; - use crate::{starknet::ArrayAbi, types::TypeBuilder, utils::{get_integer_layout, layout_repeat}}; + use crate::{ + starknet::ArrayAbi, + types::TypeBuilder, + utils::{get_integer_layout, layout_repeat}, + }; use crate::runtime::FeltDict; @@ -571,25 +575,29 @@ pub mod trace_dump_runtime { let mut values = Vec::with_capacity(n_outputs); let (u384_struct_layout, _) = layout_repeat(&u96_layout, 4).unwrap(); - let (gates_array_layout, _) = layout_repeat(&u384_struct_layout, n_outputs).unwrap(); - let (_, modulus_offset) = gates_array_layout.extend(u384_struct_layout).unwrap(); + let (gates_array_layout, _) = + layout_repeat(&u384_struct_layout, n_outputs).unwrap(); + let (_, modulus_offset) = + gates_array_layout.extend(u384_struct_layout).unwrap(); let value_ptr = value_ptr.cast::<[u8; 12]>(); // get gate values for i in 0..n_outputs { - let output_limbs = (0..4).flat_map(|j| { - let offset = u96_layout.size() * j + u384_struct_layout.size() * i; - *value_ptr.byte_add(offset).as_ref() - }).collect::>(); + let output_limbs = (0..4) + .flat_map(|j| { + let offset = u96_layout.size() * j + u384_struct_layout.size() * i; + *value_ptr.byte_add(offset).as_ref() + }) + .collect::>(); values.push(BigUint::from_bytes_le(&output_limbs)); } // get modulus value let modulus_ptr = value_ptr.byte_add(modulus_offset); - let modulus_value = (0..4).flat_map(|i| { - *modulus_ptr.byte_add(u96_layout.size() * i).as_ref() - }).collect::>(); + let modulus_value = (0..4) + .flat_map(|i| *modulus_ptr.byte_add(u96_layout.size() * i).as_ref()) + .collect::>(); let modulus = BigUint::from_bytes_le(&modulus_value); Value::CircuitOutputs { @@ -659,25 +667,30 @@ pub mod trace_dump_runtime { let value_ptr = value_ptr.cast::<[u8; 12]>(); let u96_layout = get_integer_layout(96); - let (u384_struct_layout, _) = layout_repeat(&u96_layout, info.limb_count).unwrap(); - - let output_limbs = (0..info.limb_count).map(|i| { - let current_ptr = value_ptr.byte_add(u96_layout.size() * i); - Value::BoundedInt { - range: 0.into()..BigInt::one() << 96, - value: BigInt::from_bytes_le(Sign::Plus, current_ptr.as_ref()), - } - }).collect::>(); + let (u384_struct_layout, _) = + layout_repeat(&u96_layout, info.limb_count).unwrap(); + + let output_limbs = (0..info.limb_count) + .map(|i| { + let current_ptr = value_ptr.byte_add(u96_layout.size() * i); + Value::BoundedInt { + range: 0.into()..BigInt::one() << 96, + value: BigInt::from_bytes_le(Sign::Plus, current_ptr.as_ref()), + } + }) + .collect::>(); let modulus_ptr = value_ptr.byte_add(u384_struct_layout.size()); - let modulus_limbs = (0..info.limb_count).map(|i| { - let current_ptr = modulus_ptr.byte_add(u96_layout.size() * i); - Value::BoundedInt { - range: 0.into()..BigInt::one() << 96, - value: BigInt::from_bytes_le(Sign::Plus, current_ptr.as_ref()), - } - }).collect::>(); + let modulus_limbs = (0..info.limb_count) + .map(|i| { + let current_ptr = modulus_ptr.byte_add(u96_layout.size() * i); + Value::BoundedInt { + range: 0.into()..BigInt::one() << 96, + value: BigInt::from_bytes_le(Sign::Plus, current_ptr.as_ref()), + } + }) + .collect::>(); Value::Struct(vec![ Value::Struct(output_limbs), From 409cb03a4f6444f00ac66a1ea21fa3317770b511 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Fri, 9 May 2025 17:43:47 -0300 Subject: [PATCH 38/41] doc function + merge main --- debug_utils/sierra-emu/src/vm/circuit.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debug_utils/sierra-emu/src/vm/circuit.rs b/debug_utils/sierra-emu/src/vm/circuit.rs index 54e8eced7..c08640675 100644 --- a/debug_utils/sierra-emu/src/vm/circuit.rs +++ b/debug_utils/sierra-emu/src/vm/circuit.rs @@ -68,6 +68,8 @@ fn struct_to_u384(struct_members: Vec) -> BigUint { ]) } +/// If the value is non-invertible a nullifier is returned instead. A nullifier +/// is value which satisfies this following equation: num * nullifier ≡ 0(modulus). fn find_nullifier(num: &BigUint, modulus: &BigUint) -> BigUint { let ExtendedGcd { gcd, .. } = num .to_bigint() From 5a3c5898cc450184d9db0d206f21eac4397e85f5 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Mon, 12 May 2025 12:49:52 -0300 Subject: [PATCH 39/41] reviews --- debug_utils/sierra-emu/src/vm/circuit.rs | 1 - src/metadata/trace_dump.rs | 27 ++++++++++++++---------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/debug_utils/sierra-emu/src/vm/circuit.rs b/debug_utils/sierra-emu/src/vm/circuit.rs index c08640675..3f154688a 100644 --- a/debug_utils/sierra-emu/src/vm/circuit.rs +++ b/debug_utils/sierra-emu/src/vm/circuit.rs @@ -77,7 +77,6 @@ fn find_nullifier(num: &BigUint, modulus: &BigUint) -> BigUint { .extended_gcd(&modulus.to_bigint().unwrap()); let gcd = gcd.to_biguint().unwrap(); - // If there's no inverse, find the value which nulifies the operation modulus / gcd } diff --git a/src/metadata/trace_dump.rs b/src/metadata/trace_dump.rs index 56999a7b2..23e48a29f 100644 --- a/src/metadata/trace_dump.rs +++ b/src/metadata/trace_dump.rs @@ -584,21 +584,13 @@ pub mod trace_dump_runtime { // get gate values for i in 0..n_outputs { - let output_limbs = (0..4) - .flat_map(|j| { - let offset = u96_layout.size() * j + u384_struct_layout.size() * i; - *value_ptr.byte_add(offset).as_ref() - }) - .collect::>(); - values.push(BigUint::from_bytes_le(&output_limbs)); + let gate_ptr = value_ptr.byte_add(u384_struct_layout.size() * i); + values.push(u384_struct_to_bigint(gate_ptr, 4)); } // get modulus value let modulus_ptr = value_ptr.byte_add(modulus_offset); - let modulus_value = (0..4) - .flat_map(|i| *modulus_ptr.byte_add(u96_layout.size() * i).as_ref()) - .collect::>(); - let modulus = BigUint::from_bytes_le(&modulus_value); + let modulus = u384_struct_to_bigint(modulus_ptr, 4); Value::CircuitOutputs { circuits: values, @@ -828,6 +820,19 @@ pub mod trace_dump_runtime { } } + unsafe fn u384_struct_to_bigint(value_ptr: NonNull<[u8; 12]>, limbs_count: usize) -> BigUint { + let u96_layout = get_integer_layout(96); + + let output_limbs = (0..limbs_count) + .flat_map(|i| { + let offset = u96_layout.size() * i; + *value_ptr.byte_add(offset).as_ref() + }) + .collect::>(); + + BigUint::from_bytes_le(&output_limbs) + } + #[derive(Debug)] struct FeltDictEntry<'a> { dict: &'a FeltDict, From 9593e163a80b7029df8339b147cf8bf8157c6b68 Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Mon, 12 May 2025 16:38:21 -0300 Subject: [PATCH 40/41] use elemts stride for offseting u384 structs --- src/metadata/trace_dump.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/metadata/trace_dump.rs b/src/metadata/trace_dump.rs index 23e48a29f..b1936af8a 100644 --- a/src/metadata/trace_dump.rs +++ b/src/metadata/trace_dump.rs @@ -575,7 +575,7 @@ pub mod trace_dump_runtime { let mut values = Vec::with_capacity(n_outputs); let (u384_struct_layout, _) = layout_repeat(&u96_layout, 4).unwrap(); - let (gates_array_layout, _) = + let (gates_array_layout, gate_stride) = layout_repeat(&u384_struct_layout, n_outputs).unwrap(); let (_, modulus_offset) = gates_array_layout.extend(u384_struct_layout).unwrap(); @@ -584,7 +584,7 @@ pub mod trace_dump_runtime { // get gate values for i in 0..n_outputs { - let gate_ptr = value_ptr.byte_add(u384_struct_layout.size() * i); + let gate_ptr = value_ptr.byte_add(gate_stride * i); values.push(u384_struct_to_bigint(gate_ptr, 4)); } @@ -659,12 +659,12 @@ pub mod trace_dump_runtime { let value_ptr = value_ptr.cast::<[u8; 12]>(); let u96_layout = get_integer_layout(96); - let (u384_struct_layout, _) = + let (u384_struct_layout, struct_stride) = layout_repeat(&u96_layout, info.limb_count).unwrap(); let output_limbs = (0..info.limb_count) .map(|i| { - let current_ptr = value_ptr.byte_add(u96_layout.size() * i); + let current_ptr = value_ptr.byte_add(struct_stride * i); Value::BoundedInt { range: 0.into()..BigInt::one() << 96, value: BigInt::from_bytes_le(Sign::Plus, current_ptr.as_ref()), @@ -822,10 +822,11 @@ pub mod trace_dump_runtime { unsafe fn u384_struct_to_bigint(value_ptr: NonNull<[u8; 12]>, limbs_count: usize) -> BigUint { let u96_layout = get_integer_layout(96); + let (_, elem_stride) = layout_repeat(&u96_layout, 4).unwrap(); let output_limbs = (0..limbs_count) .flat_map(|i| { - let offset = u96_layout.size() * i; + let offset = elem_stride * i; *value_ptr.byte_add(offset).as_ref() }) .collect::>(); From 64e439a2c193a9840a7f8414bd255ffb7a56277a Mon Sep 17 00:00:00 2001 From: FrancoGiachetta Date: Mon, 12 May 2025 16:44:29 -0300 Subject: [PATCH 41/41] forgot to update one stride --- src/metadata/trace_dump.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/metadata/trace_dump.rs b/src/metadata/trace_dump.rs index b1936af8a..c0fb53d87 100644 --- a/src/metadata/trace_dump.rs +++ b/src/metadata/trace_dump.rs @@ -676,7 +676,7 @@ pub mod trace_dump_runtime { let modulus_limbs = (0..info.limb_count) .map(|i| { - let current_ptr = modulus_ptr.byte_add(u96_layout.size() * i); + let current_ptr = modulus_ptr.byte_add(struct_stride * i); Value::BoundedInt { range: 0.into()..BigInt::one() << 96, value: BigInt::from_bytes_le(Sign::Plus, current_ptr.as_ref()),