From c4c664317bf9a6de4b24f310c7efae2fa8548fb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Tue, 2 Sep 2025 17:17:13 -0300 Subject: [PATCH 01/20] Add support for accessible scopes Co-authored-by: Mathieu <60658558+enitrat@users.noreply.github.com> --- fuzzer/Cargo.lock | 93 ++++--------------- hint_accountant/src/main.rs | 4 +- .../builtin_hint_processor_definition.rs | 2 + .../cairo_1_hint_processor/hint_processor.rs | 1 + .../hint_processor_definition.rs | 3 + ...un_deprecated_contract_class_simplified.rs | 5 + vm/src/vm/runners/cairo_runner.rs | 1 + 7 files changed, 34 insertions(+), 75 deletions(-) diff --git a/fuzzer/Cargo.lock b/fuzzer/Cargo.lock index 8d9373664e..5ac4486ae5 100644 --- a/fuzzer/Cargo.lock +++ b/fuzzer/Cargo.lock @@ -69,6 +69,15 @@ dependencies = [ "wyz", ] +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -78,12 +87,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "bumpalo" -version = "3.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" - [[package]] name = "byteorder" version = "1.5.0" @@ -92,7 +95,7 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cairo-vm" -version = "2.0.0" +version = "2.4.0" dependencies = [ "anyhow", "arbitrary", @@ -118,7 +121,6 @@ dependencies = [ "starknet-crypto", "starknet-types-core", "thiserror", - "wasm-bindgen", "zip", ] @@ -407,12 +409,6 @@ dependencies = [ "scopeguard", ] -[[package]] -name = "log" -version = "0.4.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" - [[package]] name = "lru" version = "0.12.5" @@ -809,9 +805,9 @@ checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] name = "starknet-crypto" -version = "0.7.4" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "039a3bad70806b494c9e6b21c5238a6c8a373d66a26071859deb0ccca6f93634" +checksum = "1004a16c25dc6113c19d4f9d0c19ff97d85804829894bba22c0d0e9e7b249812" dependencies = [ "crypto-bigint", "hex", @@ -828,26 +824,29 @@ dependencies = [ [[package]] name = "starknet-curve" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcde6bd74269b8161948190ace6cf069ef20ac6e79cd2ba09b320efa7500b6de" +checksum = "22c898ae81b6409532374cf237f1bd752d068b96c6ad500af9ebbd0d9bb712f6" dependencies = [ "starknet-types-core", ] [[package]] name = "starknet-types-core" -version = "0.1.7" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa1b9e01ccb217ab6d475c5cda05dbb22c30029f7bb52b192a010a00d77a3d74" +checksum = "5fa3d91e38f091dbc543d33589eb7716bed2a8eb1c20879e484561977832b60a" dependencies = [ "arbitrary", + "blake2", + "digest", "lambdaworks-crypto", "lambdaworks-math", "num-bigint", "num-integer", "num-traits", "serde", + "zeroize", ] [[package]] @@ -946,60 +945,6 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "wasm-bindgen" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.100", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" - [[package]] name = "windows-targets" version = "0.52.6" diff --git a/hint_accountant/src/main.rs b/hint_accountant/src/main.rs index 9483bd4168..12d9dba572 100644 --- a/hint_accountant/src/main.rs +++ b/hint_accountant/src/main.rs @@ -51,11 +51,12 @@ fn run() { } let mut vm = VirtualMachine::new(false, false); let mut hint_executor = BuiltinHintProcessor::new_empty(); - let (ap_tracking_data, reference_ids, references, mut exec_scopes) = ( + let (ap_tracking_data, reference_ids, references, mut exec_scopes, accessible_scopes) = ( ApTracking::default(), HashMap::new(), Vec::new(), ExecutionScopes::new(), + Vec::new(), ); let missing_hints: HashSet<_> = whitelists .into_iter() @@ -69,6 +70,7 @@ fn run() { &reference_ids, &references, Default::default(), + &accessible_scopes, ) .expect("this implementation is infallible"); matches!( diff --git a/vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs b/vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs index c3cab5b58b..ffef80c6db 100644 --- a/vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs +++ b/vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs @@ -133,6 +133,7 @@ pub struct HintProcessorData { pub ap_tracking: ApTracking, pub ids_data: HashMap, pub constants: Rc>, + pub accessible_scopes: Vec, } impl HintProcessorData { @@ -142,6 +143,7 @@ impl HintProcessorData { ap_tracking: ApTracking::default(), ids_data, constants: Default::default(), + accessible_scopes: Default::default(), } } } diff --git a/vm/src/hint_processor/cairo_1_hint_processor/hint_processor.rs b/vm/src/hint_processor/cairo_1_hint_processor/hint_processor.rs index 426df07159..22ede0ebca 100644 --- a/vm/src/hint_processor/cairo_1_hint_processor/hint_processor.rs +++ b/vm/src/hint_processor/cairo_1_hint_processor/hint_processor.rs @@ -1266,6 +1266,7 @@ impl HintProcessorLogic for Cairo1HintProcessor { _references: &[HintReference], // Identifiers stored in the hint's program. _constants: Rc>, + _accessible_scopes: &[String], ) -> Result, VirtualMachineError> { let data = hint_code.parse().ok().and_then(|x: usize| self.hints.get(&x).cloned()) .ok_or_else(|| VirtualMachineError::CompileHintFail( diff --git a/vm/src/hint_processor/hint_processor_definition.rs b/vm/src/hint_processor/hint_processor_definition.rs index 60d57772ee..41f66e9837 100644 --- a/vm/src/hint_processor/hint_processor_definition.rs +++ b/vm/src/hint_processor/hint_processor_definition.rs @@ -43,12 +43,15 @@ pub trait HintProcessorLogic { references: &[HintReference], // Identifiers stored in the hint's program. constants: Rc>, + // List of accessible scopes in the hint + accessible_scopes: &[String], ) -> Result, VirtualMachineError> { Ok(any_box!(HintProcessorData { code: hint_code.to_string(), ap_tracking: ap_tracking_data.clone(), ids_data: get_ids_data(reference_ids, references)?, constants, + accessible_scopes: accessible_scopes.to_vec(), })) } diff --git a/vm/src/tests/run_deprecated_contract_class_simplified.rs b/vm/src/tests/run_deprecated_contract_class_simplified.rs index 13f6869a1c..d017eba7f3 100644 --- a/vm/src/tests/run_deprecated_contract_class_simplified.rs +++ b/vm/src/tests/run_deprecated_contract_class_simplified.rs @@ -290,6 +290,10 @@ pub fn vm_load_program( let hint_ap_tracking_data = ApTracking::default(); let reference_ids = HashMap::default(); let references = vec![]; + let accessible_scopes = vec![ + String::from("__main__"), + String::from("__main__.get_number"), + ]; // Compile the hint let compiled_hint = hint_processor.compile_hint( hint_code, @@ -297,6 +301,7 @@ pub fn vm_load_program( &reference_ids, &references, Default::default(), + &accessible_scopes, )?; // Create the hint extension // As the hint from the compiled constract has offset 0, the hint pc will be equal to the loaded contract's program base: diff --git a/vm/src/vm/runners/cairo_runner.rs b/vm/src/vm/runners/cairo_runner.rs index 2a0ecfe964..6b242a5d31 100644 --- a/vm/src/vm/runners/cairo_runner.rs +++ b/vm/src/vm/runners/cairo_runner.rs @@ -658,6 +658,7 @@ impl CairoRunner { &hint.flow_tracking_data.reference_ids, references, constants.clone(), + &hint.accessible_scopes, ) .map_err(|_| VirtualMachineError::CompileHintFail(hint.code.clone().into())) }) From 0eb7bc9fa990e1fb24597811214e58c9e15b0852 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Tue, 2 Sep 2025 17:22:35 -0300 Subject: [PATCH 02/20] Add constant_collision.cairo example --- cairo_programs/constant_collision.cairo | 41 +++++++++++++++++++++++++ vm/src/tests/cairo_run_test.rs | 7 +++++ 2 files changed, 48 insertions(+) create mode 100644 cairo_programs/constant_collision.cairo diff --git a/cairo_programs/constant_collision.cairo b/cairo_programs/constant_collision.cairo new file mode 100644 index 0000000000..1d74bd393f --- /dev/null +++ b/cairo_programs/constant_collision.cairo @@ -0,0 +1,41 @@ +%builtins range_check + +from starkware.cairo.common.math import assert_le +from starkware.cairo.common.math import split_felt + +func override_constants{range_check_ptr}() { + const MAX_HIGH = -1; + const MAX_LOW = -1; + return (); +} +func split_felt_ok{range_check_ptr}(value) -> (high: felt, low: felt) { + const MAX_HIGH = (-1) / 2 ** 128; + const MAX_LOW = 0; + let low = [range_check_ptr]; + let high = [range_check_ptr + 1]; + let range_check_ptr = range_check_ptr + 2; + + %{ + from starkware.cairo.common.math_utils import assert_integer + assert ids.MAX_HIGH < 2**128 and ids.MAX_LOW < 2**128 + assert PRIME - 1 == ids.MAX_HIGH * 2**128 + ids.MAX_LOW + assert_integer(ids.value) + ids.low = ids.value & ((1 << 128) - 1) + ids.high = ids.value >> 128 + %} + + assert value = high * (2 ** 128) + low; + if (high == MAX_HIGH) { + assert_le(low, MAX_LOW); + } else { + assert_le(high, MAX_HIGH - 1); + } + return (high=high, low=low); +} + +func main{range_check_ptr: felt}() { + let (m, n) = split_felt_ok(5784800237655953878877368326340059594760); + assert m = 17; + assert n = 8; + return (); +} diff --git a/vm/src/tests/cairo_run_test.rs b/vm/src/tests/cairo_run_test.rs index 03758cc285..391f854dbc 100644 --- a/vm/src/tests/cairo_run_test.rs +++ b/vm/src/tests/cairo_run_test.rs @@ -1370,3 +1370,10 @@ fn cairo_run_data_availability_reduced_mul() { include_bytes!("../../../cairo_programs/cairo-0-kzg-da-hints/reduced_mul.json"); run_program_simple(program_data.as_slice()); } + +#[test] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +fn constant_collision() { + let program_data = include_bytes!("../../../cairo_programs/constant_collision.json"); + run_program_simple(program_data.as_slice()); +} From a9177ea0a63bf0960e76c6b6ffe516963f7fbf9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Tue, 9 Sep 2025 17:02:58 -0300 Subject: [PATCH 03/20] Pass identifiers instead of only constants to hint data --- .../builtin_hint_processor_definition.rs | 20 +- .../cairo_keccak/keccak_hints.rs | 34 ++- .../builtin_hint_processor/keccak_utils.rs | 18 +- .../builtin_hint_processor/math_utils.rs | 250 ++++++++++-------- .../secp/bigint_utils.rs | 11 +- .../builtin_hint_processor/secp/signature.rs | 22 +- .../builtin_hint_processor/sha256_utils.rs | 77 ++++-- .../builtin_hint_processor/uint384.rs | 11 +- .../cairo_1_hint_processor/hint_processor.rs | 3 +- .../hint_processor_definition.rs | 7 +- vm/src/utils.rs | 21 +- vm/src/vm/runners/cairo_runner.rs | 4 +- 12 files changed, 304 insertions(+), 174 deletions(-) diff --git a/vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs b/vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs index ffef80c6db..3846779cac 100644 --- a/vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs +++ b/vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs @@ -23,6 +23,7 @@ use super::{ pack::*, }, }; +use crate::serde::deserialize_program::Identifier; use crate::Felt252; use crate::{ hint_processor::builtin_hint_processor::secp::secp_utils::{SECP256R1_ALPHA, SECP256R1_P}, @@ -132,7 +133,7 @@ pub struct HintProcessorData { pub code: String, pub ap_tracking: ApTracking, pub ids_data: HashMap, - pub constants: Rc>, + pub identifiers: Rc>, pub accessible_scopes: Vec, } @@ -142,7 +143,7 @@ impl HintProcessorData { code, ap_tracking: ApTracking::default(), ids_data, - constants: Default::default(), + identifiers: Default::default(), accessible_scopes: Default::default(), } } @@ -195,7 +196,20 @@ impl HintProcessorLogic for BuiltinHintProcessor { let hint_data = hint_data .downcast_ref::() .ok_or(HintError::WrongHintData)?; - let constants = hint_data.constants.as_ref(); + + let identifiers = hint_data.identifiers.as_ref(); + let owned_constants = identifiers + .clone() + .into_iter() + .filter_map(|(key, identifier)| { + if identifier.type_? == "const" { + Some((key, identifier.value?)) + } else { + None + } + }) + .collect(); + let constants = &owned_constants; if let Some(hint_func) = self.extra_hints.get(&hint_data.code) { return hint_func.0( diff --git a/vm/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs b/vm/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs index 202cba60a0..deb73b6f7a 100644 --- a/vm/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs +++ b/vm/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs @@ -366,7 +366,6 @@ pub fn u64_array_to_mayberelocatable_vec(array: &[u64]) -> Vec mod tests { use super::*; use crate::stdlib::string::ToString; - use crate::{ any_box, hint_processor::{ @@ -448,16 +447,19 @@ mod tests { run_context!(vm, 0, 1, 1); let ids_data = ids_data!["n_bytes"]; + let identifiers = HashMap::from([( + "starkware.cairo.common.cairo_keccak.keccak.KECCAK_FULL_RATE_IN_BYTES".to_string(), + const_identifier(136), + )]); + let accessible_scopes = vec!["starkware.cairo.common.cairo_keccak.keccak".to_string()]; assert_matches!( run_hint!( vm, ids_data, hint_code, exec_scopes_ref!(), - &[(KECCAK_FULL_RATE_IN_BYTES_CAIRO_KECCAK, Felt252::from(136))] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() + identifiers, + accessible_scopes ), Ok(()) ); @@ -477,16 +479,19 @@ mod tests { run_context!(vm, 0, 1, 1); let ids_data = ids_data!["n_bytes"]; + let identifiers = HashMap::from([( + "starkware.cairo.common.cairo_keccak.keccak.KECCAK_FULL_RATE_IN_BYTES".to_string(), + const_identifier(136), + )]); + let accessible_scopes = vec!["starkware.cairo.common.cairo_keccak.keccak".to_string()]; assert_matches!( run_hint!( vm, ids_data, hint_code, exec_scopes_ref!(), - &[(KECCAK_FULL_RATE_IN_BYTES_CAIRO_KECCAK, Felt252::from(136))] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() + identifiers, + accessible_scopes ), Ok(()) ); @@ -505,16 +510,19 @@ mod tests { run_context!(vm, 0, 1, 1); let ids_data = ids_data!["n_bytes"]; + let identifiers = HashMap::from([( + "starkware.cairo.common.cairo_keccak.keccak.KECCAK_FULL_RATE_IN_BYTES".to_string(), + const_identifier(136), + )]); + let accessible_scopes = vec!["starkware.cairo.common.cairo_keccak.keccak".to_string()]; assert_matches!( run_hint!( vm, ids_data, hint_code, exec_scopes_ref!(), - &[(KECCAK_FULL_RATE_IN_BYTES_CAIRO_KECCAK, Felt252::from(136))] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() + identifiers, + accessible_scopes ), Ok(()) ); diff --git a/vm/src/hint_processor/builtin_hint_processor/keccak_utils.rs b/vm/src/hint_processor/builtin_hint_processor/keccak_utils.rs index b348df8a04..3193105f48 100644 --- a/vm/src/hint_processor/builtin_hint_processor/keccak_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/keccak_utils.rs @@ -357,13 +357,21 @@ mod tests { vm.segments = segments![((1, 2), 17)]; vm.set_fp(3); let ids_data = ids_data!["n_words_to_copy", "n_bytes_left", "n_bytes"]; + + let identifiers = HashMap::from([( + "starkware.cairo.common.builtin_keccak.keccak.BYTES_IN_WORD".to_string(), + const_identifier(8), + )]); + let accessible_scopes = vec!["starkware.cairo.common.builtin_keccak.keccak".to_string()]; + assert_matches!( run_hint!( vm, ids_data, hint_code::SPLIT_N_BYTES, exec_scopes_ref!(), - &HashMap::from([(String::from(BYTES_IN_WORD), Felt252::from(8))]) + identifiers, + accessible_scopes ), Ok(()) ); @@ -376,13 +384,19 @@ mod tests { vm.segments = segments![((1, 0), 72057594037927938)]; vm.set_fp(4); let ids_data = ids_data!["output1", "output1_low", "output1_mid", "output1_high"]; + let identifiers = HashMap::from([( + "starkware.cairo.common.builtin_keccak.keccak.BYTES_IN_WORD".to_string(), + const_identifier(8), + )]); + let accessible_scopes = vec!["starkware.cairo.common.builtin_keccak.keccak".to_string()]; assert_matches!( run_hint!( vm, ids_data, hint_code::SPLIT_OUTPUT_MID_LOW_HIGH, exec_scopes_ref!(), - &HashMap::from([(String::from(BYTES_IN_WORD), Felt252::from(8))]) + identifiers, + accessible_scopes ), Ok(()) ); diff --git a/vm/src/hint_processor/builtin_hint_processor/math_utils.rs b/vm/src/hint_processor/builtin_hint_processor/math_utils.rs index eb65aed496..2c64ff89d2 100644 --- a/vm/src/hint_processor/builtin_hint_processor/math_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/math_utils.rs @@ -916,15 +916,6 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn run_assert_le_felt_valid() { - let mut constants = HashMap::new(); - constants.insert( - "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_3_HIGH".to_string(), - felt_hex!("4000000000000088000000000000001"), - ); - constants.insert( - "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_2_HIGH".to_string(), - felt_hex!("2AAAAAAAAAAAAB05555555555555556"), - ); let mut vm = vm_with_range_check!(); let mut exec_scopes = scope![("excluded", 1)]; //Initialize fp @@ -934,6 +925,17 @@ mod tests { add_segments!(vm, 1); //Create ids_data & hint_data let ids_data = ids_data!["a", "b", "range_check_ptr"]; + let identifiers = HashMap::from([ + ( + "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_3_HIGH".to_string(), + const_identifier(felt_hex!("4000000000000088000000000000001")), + ), + ( + "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_2_HIGH".to_string(), + const_identifier(felt_hex!("2AAAAAAAAAAAAB05555555555555556")), + ), + ]); + let accessible_scopes = vec!["starkware.cairo.common.math.assert_le_felt".to_string()]; //Execute the hint assert_matches!( run_hint!( @@ -941,7 +943,8 @@ mod tests { ids_data, hint_code::ASSERT_LE_FELT, &mut exec_scopes, - &constants + identifiers, + accessible_scopes ), Ok(()) ); @@ -1108,15 +1111,6 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn run_is_assert_le_felt_invalid() { let mut vm = vm_with_range_check!(); - let mut constants = HashMap::new(); - constants.insert( - "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_3_HIGH".to_string(), - felt_hex!("4000000000000088000000000000001"), - ); - constants.insert( - "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_2_HIGH".to_string(), - felt_hex!("2AAAAAAAAAAAAB05555555555555556"), - ); let mut exec_scopes = scope![("excluded", Felt252::ONE)]; //Initialize fp vm.run_context.fp = 3; @@ -1124,9 +1118,20 @@ mod tests { vm.segments = segments![((1, 0), 2), ((1, 1), 1), ((1, 2), (2, 0))]; let ids_data = ids_data!["a", "b", "range_check_ptr"]; add_segments!(vm, 1); + let identifiers = HashMap::from([ + ( + "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_3_HIGH".to_string(), + const_identifier(felt_hex!("4000000000000088000000000000001")), + ), + ( + "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_2_HIGH".to_string(), + const_identifier(felt_hex!("2AAAAAAAAAAAAB05555555555555556")), + ), + ]); + let accessible_scopes = vec!["starkware.cairo.common.math.assert_le_felt".to_string()]; //Execute the hint assert_matches!( - run_hint!(vm, ids_data, hint_code::ASSERT_LE_FELT, &mut exec_scopes, &constants), + run_hint!(vm, ids_data, hint_code::ASSERT_LE_FELT, &mut exec_scopes, identifiers, accessible_scopes), Err(HintError::NonLeFelt252(bx)) if *bx == (Felt252::from(2), Felt252::ONE) ); } @@ -1135,24 +1140,26 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn run_is_assert_le_felt_a_is_not_integer() { let mut vm = vm_with_range_check!(); - let mut constants = HashMap::new(); - constants.insert( - "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_3_HIGH".to_string(), - felt_hex!("4000000000000088000000000000001"), - ); - constants.insert( - "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_2_HIGH".to_string(), - felt_hex!("2AAAAAAAAAAAAB05555555555555556"), - ); let mut exec_scopes = scope![("excluded", 1)]; //Initialize fp vm.run_context.fp = 3; //Insert ids into memory vm.segments = segments![((1, 0), (1, 0)), ((1, 1), 1), ((1, 2), (2, 0))]; let ids_data = ids_data!["a", "b", "range_check_ptr"]; + let identifiers = HashMap::from([ + ( + "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_3_HIGH".to_string(), + const_identifier(felt_hex!("4000000000000088000000000000001")), + ), + ( + "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_2_HIGH".to_string(), + const_identifier(felt_hex!("2AAAAAAAAAAAAB05555555555555556")), + ), + ]); + let accessible_scopes = vec!["starkware.cairo.common.math.assert_le_felt".to_string()]; //Execute the hint assert_matches!( - run_hint!(vm, ids_data, hint_code::ASSERT_LE_FELT, &mut exec_scopes, &constants), + run_hint!(vm, ids_data, hint_code::ASSERT_LE_FELT, &mut exec_scopes, identifiers, accessible_scopes), Err(HintError::IdentifierNotInteger(bx)) if bx.as_ref() == "a" ); } @@ -1161,24 +1168,26 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn run_is_assert_le_felt_b_is_not_integer() { let mut vm = vm_with_range_check!(); - let mut constants = HashMap::new(); - constants.insert( - "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_3_HIGH".to_string(), - felt_hex!("4000000000000088000000000000001"), - ); - constants.insert( - "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_2_HIGH".to_string(), - felt_hex!("2AAAAAAAAAAAAB05555555555555556"), - ); let mut exec_scopes = scope![("excluded", 1)]; //Initialize fp vm.run_context.fp = 3; //Insert ids into memory vm.segments = segments![((1, 0), 1), ((1, 1), (1, 0)), ((1, 2), (2, 0))]; let ids_data = ids_data!["a", "b", "range_check_builtin"]; + let identifiers = HashMap::from([ + ( + "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_3_HIGH".to_string(), + const_identifier(felt_hex!("4000000000000088000000000000001")), + ), + ( + "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_2_HIGH".to_string(), + const_identifier(felt_hex!("2AAAAAAAAAAAAB05555555555555556")), + ), + ]); + let accessible_scopes = vec!["starkware.cairo.common.math.assert_le_felt".to_string()]; //Execute the hint assert_matches!( - run_hint!(vm, ids_data, hint_code::ASSERT_LE_FELT, &mut exec_scopes, &constants), + run_hint!(vm, ids_data, hint_code::ASSERT_LE_FELT, &mut exec_scopes, identifiers, accessible_scopes), Err(HintError::IdentifierNotInteger(bx)) if bx.as_ref() == "b" ); } @@ -1858,10 +1867,6 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn run_assert_250_bit_valid() { let hint_code = hint_code::ASSERT_250_BITS; - let constants = HashMap::from([ - ("UPPER_BOUND".to_string(), Felt252::from(15)), - ("SHIFT".to_string(), Felt252::from(5)), - ]); let mut vm = vm!(); //Initialize fp vm.run_context.fp = 3; @@ -1869,9 +1874,21 @@ mod tests { vm.segments = segments![((1, 0), 1)]; //Create ids let ids_data = ids_data!["value", "high", "low"]; + let identifiers = HashMap::from([ + ("__main__.UPPER_BOUND".to_string(), const_identifier(15)), + ("__main__.SHIFT".to_string(), const_identifier(5)), + ]); + let accessible_scopes = vec!["__main__".to_string()]; //Execute the hint assert_matches!( - run_hint!(vm, ids_data, hint_code, &mut exec_scopes_ref!(), &constants), + run_hint!( + vm, + ids_data, + hint_code, + &mut exec_scopes_ref!(), + identifiers, + accessible_scopes + ), Ok(()) ); //Hint would return an error if the assertion fails @@ -1883,10 +1900,6 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn run_assert_250_bit_invalid() { let hint_code = hint_code::ASSERT_250_BITS; - let constants = HashMap::from([ - ("UPPER_BOUND".to_string(), Felt252::from(15)), - ("SHIFT".to_string(), Felt252::from(5)), - ]); let mut vm = vm!(); //Initialize fp vm.run_context.fp = 3; @@ -1901,9 +1914,14 @@ mod tests { )]; //Create ids let ids_data = ids_data!["value", "high", "low"]; + let identifiers = HashMap::from([ + ("__main__.UPPER_BOUND".to_string(), const_identifier(15)), + ("__main__.SHIFT".to_string(), const_identifier(5)), + ]); + let accessible_scopes = vec!["__main__".to_string()]; //Execute the hint assert_matches!( - run_hint!(vm, ids_data, hint_code, &mut exec_scopes_ref!(), &constants), + run_hint!(vm, ids_data, hint_code, &mut exec_scopes_ref!(), identifiers, accessible_scopes), Err(HintError::ValueOutside250BitRange(bx)) if *bx == pow2_const(251) ); } @@ -1969,6 +1987,11 @@ mod tests { ),]; //Create ids let ids_data = ids_data!["addr", "is_small"]; + let identifiers = HashMap::from([( + "starkware.starknet.common.storage.ADDR_BOUND".to_string(), + const_identifier(addr_bound), + )]); + let accessible_scopes = vec!["starkware.starknet.common.storage".to_string()]; //Execute the hint assert_matches!( run_hint!( @@ -1976,10 +1999,8 @@ mod tests { ids_data, hint_code, exec_scopes_ref!(), - &[(ADDR_BOUND, addr_bound)] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() + identifiers, + accessible_scopes ), Ok(()) ); @@ -2005,6 +2026,11 @@ mod tests { ),]; //Create ids let ids_data = ids_data!["addr", "is_small"]; + let identifiers = HashMap::from([( + "starkware.starknet.common.storage.ADDR_BOUND".to_string(), + const_identifier(addr_bound), + )]); + let accessible_scopes = vec!["starkware.starknet.common.storage".to_string()]; //Execute the hint assert_matches!( run_hint!( @@ -2012,7 +2038,8 @@ mod tests { ids_data, hint_code, exec_scopes_ref!(), - &HashMap::from([(ADDR_BOUND.to_string(), addr_bound)]) + identifiers, + accessible_scopes ), Err(HintError::AssertionFailed(bx)) if bx.as_ref() == "normalize_address() cannot be used with the current constants." @@ -2062,6 +2089,14 @@ mod tests { HintReference::new(-3, 1, true, true, true), ), ]); + let identifiers = HashMap::from([ + ("__main__.MAX_LOW".to_string(), const_identifier(0)), + ( + "__main__.MAX_HIGH".to_string(), + const_identifier(felt_str!("10633823966279327296825105735305134080")), + ), + ]); + let accessible_scopes = vec!["__main__".to_string()]; //Execute the hint assert_matches!( run_hint!( @@ -2069,13 +2104,8 @@ mod tests { ids_data, hint_code, exec_scopes_ref!(), - &HashMap::from([ - ("MAX_LOW".to_string(), Felt252::ZERO), - ( - "MAX_HIGH".to_string(), - felt_str!("10633823966279327296825105735305134080") - ) - ]) + identifiers, + accessible_scopes ), Ok(()) ); @@ -2102,6 +2132,14 @@ mod tests { //Create incomplete ids //Create ids_data & hint_data let ids_data = ids_data!["low"]; + let identifiers = HashMap::from([ + ("__main__.MAX_LOW".to_string(), const_identifier(0)), + ( + "__main__.MAX_HIGH".to_string(), + const_identifier(felt_str!("10633823966279327296825105735305134080")), + ), + ]); + let accessible_scopes = vec!["__main__".to_string()]; //Execute the hint assert_matches!( run_hint!( @@ -2109,13 +2147,8 @@ mod tests { ids_data, hint_code, exec_scopes_ref!(), - &HashMap::from([ - ("MAX_LOW".to_string(), Felt252::ZERO), - ( - "MAX_HIGH".to_string(), - felt_str!("10633823966279327296825105735305134080") - ) - ]) + identifiers, + accessible_scopes ), Err(HintError::UnknownIdentifier(bx)) if bx.as_ref() == "value" ); @@ -2146,6 +2179,14 @@ mod tests { HintReference::new(-3, 1, true, true, true), ), ]); + let identifiers = HashMap::from([ + ("__main__.MAX_LOW".to_string(), const_identifier(0)), + ( + "__main__.MAX_HIGH".to_string(), + const_identifier(felt_str!("10633823966279327296825105735305134080")), + ), + ]); + let accessible_scopes = vec!["__main__".to_string()]; //Execute the hint assert_matches!( @@ -2154,13 +2195,8 @@ mod tests { ids_data, hint_code, exec_scopes_ref!(), - &HashMap::from([ - ("MAX_LOW".to_string(), Felt252::ZERO), - ( - "MAX_HIGH".to_string(), - felt_str!("10633823966279327296825105735305134080") - ) - ]) + identifiers, + accessible_scopes ), Err(HintError::Memory( MemoryError::InconsistentMemory(bx) @@ -2196,6 +2232,14 @@ mod tests { HintReference::new(-3, 1, true, true, true), ), ]); + let identifiers = HashMap::from([ + ("__main__.MAX_LOW".to_string(), const_identifier(0)), + ( + "__main__.MAX_HIGH".to_string(), + const_identifier(felt_str!("10633823966279327296825105735305134080")), + ), + ]); + let accessible_scopes = vec!["__main__".to_string()]; //Execute the hint assert_matches!( run_hint!( @@ -2203,13 +2247,8 @@ mod tests { ids_data, hint_code, exec_scopes_ref!(), - &HashMap::from([ - ("MAX_LOW".to_string(), Felt252::ZERO), - ( - "MAX_HIGH".to_string(), - felt_str!("10633823966279327296825105735305134080") - ) - ]) + identifiers, + accessible_scopes ), Err(HintError::Memory( MemoryError::InconsistentMemory(bx) @@ -2240,6 +2279,14 @@ mod tests { HintReference::new(-3, 1, true, true, true), ), ]); + let identifiers = HashMap::from([ + ("__main__.MAX_LOW".to_string(), const_identifier(0)), + ( + "__main__.MAX_HIGH".to_string(), + const_identifier(felt_str!("10633823966279327296825105735305134080")), + ), + ]); + let accessible_scopes = vec!["__main__".to_string()]; //Execute the hint assert_matches!( run_hint!( @@ -2247,13 +2294,8 @@ mod tests { ids_data, hint_code, exec_scopes_ref!(), - &HashMap::from([ - ("MAX_LOW".to_string(), Felt252::ZERO), - ( - "MAX_HIGH".to_string(), - felt_str!("10633823966279327296825105735305134080") - ) - ]) + identifiers, + accessible_scopes ), Err(HintError::IdentifierNotInteger(bx)) if bx.as_ref() == "value" ); @@ -2316,6 +2358,11 @@ mod tests { HintReference::new(-3, 1, true, true, true), ), ]); + let identifiers = HashMap::from([ + ("__main__.MAX_LOW".to_string(), const_identifier(-1)), + ("__main__.MAX_HIGH".to_string(), const_identifier(-1)), + ]); + let accessible_scopes = vec!["__main__".to_string()]; //Execute the hint assert_matches!( run_hint!( @@ -2323,13 +2370,8 @@ mod tests { ids_data, hint_code, exec_scopes_ref!(), - &HashMap::from([ - ("MAX_LOW".to_string(), Felt252::from(-1)), - ( - "MAX_HIGH".to_string(), - Felt252::from(-1), - ) - ]) + identifiers, + accessible_scopes ), Err(HintError::AssertionFailed(x)) if &(*x) == "assert ids.MAX_HIGH < 2**128 and ids.MAX_LOW < 2**128" ); @@ -2360,6 +2402,11 @@ mod tests { HintReference::new(-3, 1, true, true, true), ), ]); + let identifiers = HashMap::from([ + ("__main__.MAX_LOW".to_string(), const_identifier(0)), + ("__main__.MAX_HIGH".to_string(), const_identifier(0)), + ]); + let accessible_scopes = vec!["__main__".to_string()]; //Execute the hint assert_matches!( run_hint!( @@ -2367,13 +2414,8 @@ mod tests { ids_data, hint_code, exec_scopes_ref!(), - &HashMap::from([ - ("MAX_LOW".to_string(), Felt252::ZERO), - ( - "MAX_HIGH".to_string(), - Felt252::ZERO, - ) - ]) + identifiers, + accessible_scopes ), Err(HintError::AssertionFailed(x)) if &(*x) == "assert PRIME - 1 == ids.MAX_HIGH * 2**128 + ids.MAX_LOW" ); diff --git a/vm/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs b/vm/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs index d355ac67c0..072b4f6d88 100644 --- a/vm/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs @@ -227,16 +227,19 @@ mod tests { run_context!(vm, 0, 6, 6); //Create hint_data let ids_data = non_continuous_ids_data![("res", 5)]; + let identifiers = HashMap::from([( + "starkware.cairo.common.cairo_secp.constants.BASE".to_string(), + const_identifier(crate::math_utils::pow2_const(86)), + )]); + let accessible_scopes = vec!["starkware.cairo.common.cairo_secp.constants".to_string()]; assert_matches!( run_hint!( vm, ids_data, hint_code, &mut exec_scopes, - &[(BASE_86, crate::math_utils::pow2_const(86))] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() + identifiers, + accessible_scopes ), Ok(()) ); diff --git a/vm/src/hint_processor/builtin_hint_processor/secp/signature.rs b/vm/src/hint_processor/builtin_hint_processor/secp/signature.rs index b495ab073f..fd5951e9fb 100644 --- a/vm/src/hint_processor/builtin_hint_processor/secp/signature.rs +++ b/vm/src/hint_processor/builtin_hint_processor/secp/signature.rs @@ -252,16 +252,19 @@ mod tests { ]; vm.run_context.fp = 1; let ids_data = non_continuous_ids_data![("v", -1), ("x_cube", 0)]; + let identifiers = HashMap::from([( + "starkware.cairo.common.cairo_secp.constants.BETA".to_string(), + const_identifier(7), + )]); + let accessible_scopes = vec!["starkware.cairo.common.cairo_secp.constants".to_string()]; assert_matches!( run_hint!( vm, ids_data, hint_code, exec_scopes_ref!(), - &[(BETA, Felt252::from(7)),] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() + identifiers, + accessible_scopes ), Ok(()) ) @@ -282,16 +285,19 @@ mod tests { vm.run_context.fp = 2; let ids_data = ids_data!["v", "x_cube"]; + let identifiers = HashMap::from([( + "starkware.cairo.common.cairo_secp.constants.BETA".to_string(), + const_identifier(7), + )]); + let accessible_scopes = vec!["starkware.cairo.common.cairo_secp.constants".to_string()]; assert_matches!( run_hint!( vm, ids_data, hint_code, &mut exec_scopes, - &[(BETA, Felt252::from(7)),] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() + identifiers, + accessible_scopes ), Ok(()) ); diff --git a/vm/src/hint_processor/builtin_hint_processor/sha256_utils.rs b/vm/src/hint_processor/builtin_hint_processor/sha256_utils.rs index a7e77bd42c..67bfc7dfd3 100644 --- a/vm/src/hint_processor/builtin_hint_processor/sha256_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/sha256_utils.rs @@ -287,12 +287,20 @@ mod tests { ]; vm.run_context.fp = 2; let ids_data = ids_data!["sha256_start", "output"]; - let constants = HashMap::from([( - "SHA256_INPUT_CHUNK_SIZE_FELTS".to_string(), - Felt252::from(SHA256_INPUT_CHUNK_SIZE_FELTS), + let identifiers = HashMap::from([( + "__main__.SHA256_INPUT_CHUNK_SIZE_FELTS".to_string(), + const_identifier(SHA256_INPUT_CHUNK_SIZE_FELTS), )]); + let accessible_scopes = vec!["__main__".to_string()]; assert_matches!( - run_hint!(&mut vm, ids_data, hint_code, exec_scopes_ref!(), &constants), + run_hint!( + &mut vm, + ids_data, + hint_code, + exec_scopes_ref!(), + identifiers, + accessible_scopes + ), Ok(()) ); @@ -347,18 +355,26 @@ mod tests { ]; vm.run_context.fp = 3; let ids_data = ids_data!["sha256_start", "output", "state"]; - let constants = HashMap::from([ + let identifiers = HashMap::from([ ( - "SHA256_INPUT_CHUNK_SIZE_FELTS".to_string(), - Felt252::from(SHA256_INPUT_CHUNK_SIZE_FELTS), + "__main__.SHA256_INPUT_CHUNK_SIZE_FELTS".to_string(), + const_identifier(SHA256_INPUT_CHUNK_SIZE_FELTS), ), ( - "SHA256_STATE_SIZE_FELTS".to_string(), - Felt252::from(SHA256_STATE_SIZE_FELTS), + "__main__.SHA256_STATE_SIZE_FELTS".to_string(), + const_identifier(SHA256_STATE_SIZE_FELTS), ), ]); + let accessible_scopes = vec!["__main__".to_string()]; assert_matches!( - run_hint!(&mut vm, ids_data, hint_code, exec_scopes_ref!(), &constants), + run_hint!( + &mut vm, + ids_data, + hint_code, + exec_scopes_ref!(), + identifiers, + accessible_scopes + ), Ok(()) ); check_memory![ @@ -396,18 +412,19 @@ mod tests { ]; vm.run_context.fp = 3; let ids_data = ids_data!["sha256_start", "output", "state"]; - let constants = HashMap::from([ + let identifiers = HashMap::from([ ( - "SHA256_INPUT_CHUNK_SIZE_FELTS".to_string(), - Felt252::from(100), + "__main__.SHA256_INPUT_CHUNK_SIZE_FELTS".to_string(), + const_identifier(100), ), ( - "SHA256_STATE_SIZE_FELTS".to_string(), - Felt252::from(SHA256_STATE_SIZE_FELTS), + "__main__.SHA256_STATE_SIZE_FELTS".to_string(), + const_identifier(SHA256_STATE_SIZE_FELTS), ), ]); + let accessible_scopes = vec!["__main__".to_string()]; assert_matches!( - run_hint!(&mut vm, ids_data, hint_code, exec_scopes_ref!(), &constants), + run_hint!(&mut vm, ids_data, hint_code, exec_scopes_ref!(), identifiers, accessible_scopes), Err(HintError::AssertionFailed(bx)) if bx.as_ref() == "assert 0 <= _sha256_input_chunk_size_felts < 100" ); } @@ -433,15 +450,19 @@ mod tests { ]; vm.run_context.fp = 3; let ids_data = ids_data!["sha256_start", "output", "state"]; - let constants = HashMap::from([ + let identifiers = HashMap::from([ + ( + "__main__.SHA256_INPUT_CHUNK_SIZE_FELTS".to_string(), + const_identifier(SHA256_INPUT_CHUNK_SIZE_FELTS), + ), ( - "SHA256_INPUT_CHUNK_SIZE_FELTS".to_string(), - Felt252::from(SHA256_INPUT_CHUNK_SIZE_FELTS), + "__main__.SHA256_STATE_SIZE_FELTS".to_string(), + const_identifier(100), ), - ("SHA256_STATE_SIZE_FELTS".to_string(), Felt252::from(100)), ]); + let accessible_scopes = vec!["__main__".to_string()]; assert_matches!( - run_hint!(&mut vm, ids_data, hint_code, exec_scopes_ref!(), &constants), + run_hint!(&mut vm, ids_data, hint_code, exec_scopes_ref!(), identifiers, accessible_scopes), Err(HintError::AssertionFailed(bx)) if bx.as_ref() == "assert 0 <= _sha256_state_size_felts < 100" ); } @@ -468,16 +489,20 @@ mod tests { ]; vm.run_context.fp = 3; let ids_data = ids_data!["sha256_start", "output", "state"]; - let constants = HashMap::from([ + let identifiers = HashMap::from([ + ( + "__main__.SHA256_INPUT_CHUNK_SIZE_FELTS".to_string(), + const_identifier(SHA256_INPUT_CHUNK_SIZE_FELTS), + ), ( - "SHA256_INPUT_CHUNK_SIZE_FELTS".to_string(), - Felt252::from(SHA256_INPUT_CHUNK_SIZE_FELTS), + "__main__.SHA256_STATE_SIZE_FELTS".to_string(), + const_identifier(state_size), ), - ("SHA256_STATE_SIZE_FELTS".to_string(), state_size), ]); + let accessible_scopes = vec!["__main__".to_string()]; let expected_size = Felt252::from(SHA256_STATE_SIZE_FELTS); assert_matches!( - run_hint!(&mut vm, ids_data, hint_code, exec_scopes_ref!(), &constants), + run_hint!(&mut vm, ids_data, hint_code, exec_scopes_ref!(), identifiers, accessible_scopes), Err(HintError::InvalidValue(bx)) if *bx == ("SHA256_STATE_SIZE_FELTS", state_size, expected_size) ); diff --git a/vm/src/hint_processor/builtin_hint_processor/uint384.rs b/vm/src/hint_processor/builtin_hint_processor/uint384.rs index a973fb9d3d..6a627daea2 100644 --- a/vm/src/hint_processor/builtin_hint_processor/uint384.rs +++ b/vm/src/hint_processor/builtin_hint_processor/uint384.rs @@ -488,6 +488,11 @@ mod tests { ((1, 4), 17), ((1, 5), 8) ]; + let identifiers = HashMap::from([( + "path.path.path.SHIFT".to_string(), + const_identifier(crate::math_utils::pow2_const(128)), + )]); + let accessible_scopes = vec!["path.path.path".to_string()]; //Execute the hint assert_matches!( run_hint!( @@ -495,10 +500,8 @@ mod tests { ids_data, hint_code::ADD_NO_UINT384_CHECK, &mut exec_scopes_ref!(), - &[("path.path.path.SHIFT", crate::math_utils::pow2_const(128))] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() + identifiers, + accessible_scopes ), Ok(()) ); diff --git a/vm/src/hint_processor/cairo_1_hint_processor/hint_processor.rs b/vm/src/hint_processor/cairo_1_hint_processor/hint_processor.rs index 22ede0ebca..d3048fdfd5 100644 --- a/vm/src/hint_processor/cairo_1_hint_processor/hint_processor.rs +++ b/vm/src/hint_processor/cairo_1_hint_processor/hint_processor.rs @@ -9,6 +9,7 @@ use super::hint_processor_utils::*; use crate::any_box; use crate::hint_processor::cairo_1_hint_processor::dict_manager::DictSquashExecScope; use crate::hint_processor::hint_processor_definition::HintReference; +use crate::serde::deserialize_program::Identifier; use crate::stdlib::rc::Rc; use crate::stdlib::{boxed::Box, collections::HashMap, prelude::*}; use crate::types::relocatable::{MaybeRelocatable, Relocatable}; @@ -1265,7 +1266,7 @@ impl HintProcessorLogic for Cairo1HintProcessor { //List of all references (key corresponds to element of the previous dictionary) _references: &[HintReference], // Identifiers stored in the hint's program. - _constants: Rc>, + _constants: Rc>, _accessible_scopes: &[String], ) -> Result, VirtualMachineError> { let data = hint_code.parse().ok().and_then(|x: usize| self.hints.get(&x).cloned()) diff --git a/vm/src/hint_processor/hint_processor_definition.rs b/vm/src/hint_processor/hint_processor_definition.rs index 41f66e9837..b1a05e9910 100644 --- a/vm/src/hint_processor/hint_processor_definition.rs +++ b/vm/src/hint_processor/hint_processor_definition.rs @@ -1,9 +1,9 @@ use crate::stdlib::{any::Any, boxed::Box, collections::HashMap, prelude::*, rc::Rc}; use crate::any_box; -use crate::serde::deserialize_program::ApTracking; use crate::serde::deserialize_program::OffsetValue; use crate::serde::deserialize_program::Reference; +use crate::serde::deserialize_program::{ApTracking, Identifier}; use crate::types::exec_scope::ExecutionScopes; use crate::types::instruction::Register; use crate::types::relocatable::Relocatable; @@ -13,7 +13,6 @@ use crate::vm::runners::cairo_runner::ResourceTracker; use crate::vm::vm_core::VirtualMachine; use super::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; -use crate::Felt252; #[cfg(feature = "test_utils")] use arbitrary::Arbitrary; @@ -42,7 +41,7 @@ pub trait HintProcessorLogic { //List of all references (key corresponds to element of the previous dictionary) references: &[HintReference], // Identifiers stored in the hint's program. - constants: Rc>, + identifiers: Rc>, // List of accessible scopes in the hint accessible_scopes: &[String], ) -> Result, VirtualMachineError> { @@ -50,7 +49,7 @@ pub trait HintProcessorLogic { code: hint_code.to_string(), ap_tracking: ap_tracking_data.clone(), ids_data: get_ids_data(reference_ids, references)?, - constants, + identifiers, accessible_scopes: accessible_scopes.to_vec(), })) } diff --git a/vm/src/utils.rs b/vm/src/utils.rs index 6824252fe2..dc1c675329 100644 --- a/vm/src/utils.rs +++ b/vm/src/utils.rs @@ -52,9 +52,11 @@ pub fn from_relocatable_to_indexes(relocatable: Relocatable) -> (usize, usize) { #[cfg(test)] #[macro_use] pub mod test_utils { + use crate::serde::deserialize_program::Identifier; use crate::types::exec_scope::ExecutionScopes; use crate::types::relocatable::MaybeRelocatable; use crate::vm::trace::trace_entry::TraceEntry; + use crate::Felt252; #[macro_export] macro_rules! felt_hex { @@ -472,11 +474,24 @@ pub mod test_utils { } pub(crate) use exec_scopes_ref; + pub fn const_identifier(value: impl Into) -> Identifier { + Identifier { + pc: None, + type_: Some(String::from("const")), + value: Some(value.into()), + full_name: None, + members: None, + cairo_type: None, + size: None, + destination: None, + } + } + macro_rules! run_hint { - ($vm:expr, $ids_data:expr, $hint_code:expr, $exec_scopes:expr, $constants:expr) => {{ + ($vm:expr, $ids_data:expr, $hint_code:expr, $exec_scopes:expr, $identifiers:expr, $accessible_scopes:expr) => {{ let mut hint_data = HintProcessorData::new_default($hint_code.to_string(), $ids_data); - let constants: &HashMap = $constants; - hint_data.constants = crate::stdlib::rc::Rc::new(constants.clone()); + hint_data.identifiers = crate::stdlib::rc::Rc::new($identifiers); + hint_data.accessible_scopes = $accessible_scopes; let mut hint_processor = BuiltinHintProcessor::new_empty(); hint_processor.execute_hint(&mut $vm, $exec_scopes, &any_box!(hint_data)) }}; diff --git a/vm/src/vm/runners/cairo_runner.rs b/vm/src/vm/runners/cairo_runner.rs index 6b242a5d31..f7dac14bd6 100644 --- a/vm/src/vm/runners/cairo_runner.rs +++ b/vm/src/vm/runners/cairo_runner.rs @@ -644,7 +644,7 @@ impl CairoRunner { references: &[HintReference], hint_executor: &mut dyn HintProcessor, ) -> Result>, VirtualMachineError> { - let constants = Rc::new(self.program.constants.clone()); + let identifiers = Rc::new(self.program.shared_program_data.identifiers.clone()); self.program .shared_program_data @@ -657,7 +657,7 @@ impl CairoRunner { &hint.flow_tracking_data.ap_tracking, &hint.flow_tracking_data.reference_ids, references, - constants.clone(), + identifiers.clone(), &hint.accessible_scopes, ) .map_err(|_| VirtualMachineError::CompileHintFail(hint.code.clone().into())) From a5080947b1837302514977fe0f421679d9d8959f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Tue, 9 Sep 2025 17:32:56 -0300 Subject: [PATCH 04/20] Modify functions that already used get_constant_from_var --- .../builtin_hint_processor_definition.rs | 45 +++++++++++++------ .../builtin_hint_processor/excess_balance.rs | 26 ++++++++--- .../builtin_hint_processor/hint_utils.rs | 18 +++++--- .../builtin_hint_processor/math_utils.rs | 37 +++++++-------- .../secp/cairo0_hints.rs | 38 ++++++++-------- .../builtin_hint_processor/sha256_utils.rs | 42 ++++++++++++----- .../builtin_hint_processor/uint384.rs | 6 ++- 7 files changed, 132 insertions(+), 80 deletions(-) diff --git a/vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs b/vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs index 3846779cac..8d97f22815 100644 --- a/vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs +++ b/vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs @@ -231,15 +231,20 @@ impl HintProcessorLogic for BuiltinHintProcessor { exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + &hint_data.identifiers, + &hint_data.accessible_scopes, ), hint_code::ASSERT_LE_FELT_EXCLUDED_2 => assert_le_felt_excluded_2(exec_scopes), hint_code::ASSERT_LE_FELT_EXCLUDED_1 => assert_le_felt_excluded_1(vm, exec_scopes), hint_code::ASSERT_LE_FELT_EXCLUDED_0 => assert_le_felt_excluded_0(vm, exec_scopes), hint_code::IS_LE_FELT => is_le_felt(vm, &hint_data.ids_data, &hint_data.ap_tracking), - hint_code::ASSERT_250_BITS => { - assert_250_bit(vm, &hint_data.ids_data, &hint_data.ap_tracking, constants) - } + hint_code::ASSERT_250_BITS => assert_250_bit( + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + &hint_data.identifiers, + &hint_data.accessible_scopes, + ), hint_code::IS_250_BITS => is_250_bits(vm, &hint_data.ids_data, &hint_data.ap_tracking), hint_code::IS_ADDR_BOUNDED => { is_addr_bounded(vm, &hint_data.ids_data, &hint_data.ap_tracking, constants) @@ -281,9 +286,13 @@ impl HintProcessorLogic for BuiltinHintProcessor { &hint_data.ap_tracking, "continue_loop", ), - hint_code::SPLIT_FELT => { - split_felt(vm, &hint_data.ids_data, &hint_data.ap_tracking, constants) - } + hint_code::SPLIT_FELT => split_felt( + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + &hint_data.identifiers, + &hint_data.accessible_scopes, + ), hint_code::UNSIGNED_DIV_REM => { unsigned_div_rem(vm, &hint_data.ids_data, &hint_data.ap_tracking) } @@ -679,13 +688,15 @@ impl HintProcessorLogic for BuiltinHintProcessor { vm, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + identifiers, + &hint_data.accessible_scopes, ), hint_code::SHA256_MAIN_ARBITRARY_INPUT_LENGTH => sha256_main_arbitrary_input_length( vm, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + identifiers, + &hint_data.accessible_scopes, ), hint_code::SHA256_INPUT => { sha256_input(vm, &hint_data.ids_data, &hint_data.ap_tracking) @@ -812,9 +823,13 @@ impl HintProcessorLogic for BuiltinHintProcessor { hint_code::UINT384_SPLIT_128 => { uint384_split_128(vm, &hint_data.ids_data, &hint_data.ap_tracking) } - hint_code::ADD_NO_UINT384_CHECK => { - add_no_uint384_check(vm, &hint_data.ids_data, &hint_data.ap_tracking, constants) - } + hint_code::ADD_NO_UINT384_CHECK => add_no_uint384_check( + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + &hint_data.identifiers, + &hint_data.accessible_scopes, + ), hint_code::UINT384_SQRT => { uint384_sqrt(vm, &hint_data.ids_data, &hint_data.ap_tracking) } @@ -905,7 +920,8 @@ impl HintProcessorLogic for BuiltinHintProcessor { vm, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + identifiers, + &hint_data.accessible_scopes, exec_scopes, ), #[cfg(feature = "cairo-0-secp-hints")] @@ -922,7 +938,8 @@ impl HintProcessorLogic for BuiltinHintProcessor { exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + identifiers, + &hint_data.accessible_scopes, ), #[cfg(feature = "cairo-0-secp-hints")] cairo0_hints::SECP_DOUBLE_ASSIGN_NEW_X => cairo0_hints::secp_double_assign_new_x( diff --git a/vm/src/hint_processor/builtin_hint_processor/excess_balance.rs b/vm/src/hint_processor/builtin_hint_processor/excess_balance.rs index 4c676053ce..247e56b944 100644 --- a/vm/src/hint_processor/builtin_hint_processor/excess_balance.rs +++ b/vm/src/hint_processor/builtin_hint_processor/excess_balance.rs @@ -1,6 +1,6 @@ use crate::{ hint_processor::hint_processor_definition::HintReference, - serde::deserialize_program::ApTracking, + serde::deserialize_program::{ApTracking, Identifier}, stdlib::collections::HashMap, types::{exec_scope::ExecutionScopes, relocatable::MaybeRelocatable}, vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, @@ -262,13 +262,15 @@ pub fn excess_balance_hint( vm: &mut VirtualMachine, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, + identifiers: &HashMap, + accessible_scopes: &[String], exec_scopes: &ExecutionScopes, ) -> Result<(), HintError> { // Fetch constants & variables let margin_check_type = get_integer_from_var_name("margin_check_type", vm, ids_data, ap_tracking)?; - let margin_check_initial = get_constant_from_var_name("MARGIN_CHECK_INITIAL", constants)?; + let margin_check_initial = + get_constant_from_var_name("MARGIN_CHECK_INITIAL", identifiers, accessible_scopes)?; let token_assets_value_d = get_integer_from_var_name("token_assets_value_d", vm, ids_data, ap_tracking)?; let account = get_integer_from_var_name("account", vm, ids_data, ap_tracking)?; @@ -593,7 +595,11 @@ mod tests { // SETUP let mut vm = vm!(); // CONSTANTS - let constants = HashMap::from([("MARGIN_CHECK_INITIAL".to_string(), Felt252::ONE)]); + let identifiers = HashMap::from([( + "__main__.MARGIN_CHECK_INITIAL".to_string(), + const_identifier(1), + )]); + let accessible_scopes = vec!["__main__".to_string()]; // IDS vm.segments = segments!( ((1, 0), 1), // ids.margin_check_type @@ -826,7 +832,8 @@ mod tests { &mut vm, &ids, &ApTracking::default(), - &constants, + &identifiers, + &accessible_scopes, &exec_scopes ) .is_ok()); @@ -935,7 +942,11 @@ mod tests { // SETUP let mut vm = vm!(); // CONSTANTS - let constants = HashMap::from([("MARGIN_CHECK_INITIAL".to_string(), Felt252::ONE)]); + let identifiers = HashMap::from([( + "__main__.MARGIN_CHECK_INITIAL".to_string(), + const_identifier(1), + )]); + let accessible_scopes = vec!["__main__".to_string()]; // IDS vm.segments = segments!( ((1, 0), 1), // ids.margin_check_type @@ -1192,7 +1203,8 @@ mod tests { &mut vm, &ids, &ApTracking::default(), - &constants, + &identifiers, + &accessible_scopes, &exec_scopes ) .is_ok()); diff --git a/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs b/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs index 1da3905e02..2f6eca2ef5 100644 --- a/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs @@ -9,7 +9,7 @@ use crate::hint_processor::hint_processor_utils::{ use crate::hint_processor::hint_processor_utils::{ get_integer_from_reference, get_maybe_relocatable_from_reference, }; -use crate::serde::deserialize_program::ApTracking; +use crate::serde::deserialize_program::{ApTracking, Identifier}; use crate::types::relocatable::MaybeRelocatable; use crate::types::relocatable::Relocatable; use crate::vm::errors::hint_errors::HintError; @@ -176,12 +176,20 @@ pub fn get_reference_from_var_name<'a>( pub fn get_constant_from_var_name<'a>( var_name: &'static str, - constants: &'a HashMap, + identifiers: &'a HashMap, + accessible_scopes: &[String], ) -> Result<&'a Felt252, HintError> { - constants + accessible_scopes .iter() - .find(|(k, _)| k.rsplit('.').next() == Some(var_name)) - .map(|(_, n)| n) + .rev() + .find_map(|scope| { + let identifier = identifiers.get(&format!("{}.{}", scope, var_name))?; + if identifier.type_.as_ref()? == "const" { + identifier.value.as_ref() + } else { + None + } + }) .ok_or_else(|| HintError::MissingConstant(Box::new(var_name))) } diff --git a/vm/src/hint_processor/builtin_hint_processor/math_utils.rs b/vm/src/hint_processor/builtin_hint_processor/math_utils.rs index 2c64ff89d2..66f88abf78 100644 --- a/vm/src/hint_processor/builtin_hint_processor/math_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/math_utils.rs @@ -1,6 +1,7 @@ use crate::{ hint_processor::builtin_hint_processor::hint_utils::get_constant_from_var_name, math_utils::signed_felt, + serde::deserialize_program::Identifier, stdlib::{boxed::Box, collections::HashMap, prelude::*}, types::errors::math_errors::MathError, }; @@ -90,17 +91,13 @@ pub fn assert_le_felt( exec_scopes: &mut ExecutionScopes, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, + identifiers: &HashMap, + accessible_scopes: &[String], ) -> Result<(), HintError> { - const PRIME_OVER_3_HIGH: &str = "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_3_HIGH"; - const PRIME_OVER_2_HIGH: &str = "starkware.cairo.common.math.assert_le_felt.PRIME_OVER_2_HIGH"; - - let prime_over_3_high = constants - .get(PRIME_OVER_3_HIGH) - .ok_or_else(|| HintError::MissingConstant(Box::new(PRIME_OVER_3_HIGH)))?; - let prime_over_2_high = constants - .get(PRIME_OVER_2_HIGH) - .ok_or_else(|| HintError::MissingConstant(Box::new(PRIME_OVER_2_HIGH)))?; + let prime_over_3_high = + get_constant_from_var_name("PRIME_OVER_3_HIGH", identifiers, accessible_scopes)?; + let prime_over_2_high = + get_constant_from_var_name("PRIME_OVER_2_HIGH", identifiers, accessible_scopes)?; let a = get_integer_from_var_name("a", vm, ids_data, ap_tracking)?.to_biguint(); let b = get_integer_from_var_name("b", vm, ids_data, ap_tracking)?.to_biguint(); let range_check_ptr = get_ptr_from_var_name("range_check_ptr", vm, ids_data, ap_tracking)?; @@ -384,15 +381,16 @@ pub fn split_felt( vm: &mut VirtualMachine, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, + identifiers: &HashMap, + accessible_scopes: &[String], ) -> Result<(), HintError> { let assert = |b: bool, msg: &str| { b.then_some(()) .ok_or_else(|| HintError::AssertionFailed(msg.to_string().into_boxed_str())) }; let bound = pow2_const(128); - let max_high = get_constant_from_var_name("MAX_HIGH", constants)?; - let max_low = get_constant_from_var_name("MAX_LOW", constants)?; + let max_high = get_constant_from_var_name("MAX_HIGH", identifiers, accessible_scopes)?; + let max_low = get_constant_from_var_name("MAX_LOW", identifiers, accessible_scopes)?; assert( max_high < &bound && max_low < &bound, "assert ids.MAX_HIGH < 2**128 and ids.MAX_LOW < 2**128", @@ -521,17 +519,12 @@ pub fn assert_250_bit( vm: &mut VirtualMachine, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, + identifiers: &HashMap, + accessible_scopes: &[String], ) -> Result<(), HintError> { - const UPPER_BOUND: &str = "starkware.cairo.common.math.assert_250_bit.UPPER_BOUND"; - const SHIFT: &str = "starkware.cairo.common.math.assert_250_bit.SHIFT"; //Declare constant values - let upper_bound = constants - .get(UPPER_BOUND) - .map_or_else(|| get_constant_from_var_name("UPPER_BOUND", constants), Ok)?; - let shift = constants - .get(SHIFT) - .map_or_else(|| get_constant_from_var_name("SHIFT", constants), Ok)?; + let upper_bound = get_constant_from_var_name("UPPER_BOUND", identifiers, accessible_scopes)?; + let shift = get_constant_from_var_name("SHIFT", identifiers, accessible_scopes)?; let value = Felt252::from(&signed_felt(get_integer_from_var_name( "value", vm, diff --git a/vm/src/hint_processor/builtin_hint_processor/secp/cairo0_hints.rs b/vm/src/hint_processor/builtin_hint_processor/secp/cairo0_hints.rs index 92ab043479..be151bdd04 100644 --- a/vm/src/hint_processor/builtin_hint_processor/secp/cairo0_hints.rs +++ b/vm/src/hint_processor/builtin_hint_processor/secp/cairo0_hints.rs @@ -1,8 +1,10 @@ -use crate::stdlib::{ - collections::HashMap, - ops::Deref, - ops::{Add, Mul, Rem}, - prelude::*, +use crate::{ + serde::deserialize_program::Identifier, + stdlib::{ + collections::HashMap, + ops::{Add, Deref, Mul, Rem}, + prelude::*, + }, }; use crate::define_hint_string_map; @@ -166,19 +168,13 @@ pub fn compute_ids_high_low( exec_scopes: &mut ExecutionScopes, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, + identifiers: &HashMap, + accessible_scopes: &[String], ) -> Result<(), HintError> { exec_scopes.insert_value::("SECP256R1_P", SECP256R1_P.clone()); - const UPPER_BOUND: &str = "starkware.cairo.common.secp256r1.field.assert_165_bit.UPPER_BOUND"; - const SHIFT: &str = "starkware.cairo.common.secp256r1.field.assert_165_bit.SHIFT"; - - let upper_bound = constants - .get(UPPER_BOUND) - .map_or_else(|| get_constant_from_var_name("UPPER_BOUND", constants), Ok)?; - let shift = constants - .get(SHIFT) - .map_or_else(|| get_constant_from_var_name("SHIFT", constants), Ok)?; + let upper_bound = get_constant_from_var_name("UPPER_BOUND", identifiers, accessible_scopes)?; + let shift = get_constant_from_var_name("SHIFT", identifiers, accessible_scopes)?; let value = Felt252::from(&signed_felt(get_integer_from_var_name( "value", vm, @@ -503,19 +499,21 @@ mod tests { let mut exec_scopes = ExecutionScopes::new(); - let constants = HashMap::from([ + let identifiers = HashMap::from([ ( - "UPPER_BOUND".to_string(), - Felt252::from(18446744069414584321_u128), + "__main__.UPPER_BOUND".to_string(), + const_identifier(18446744069414584321_u128), ), - ("SHIFT".to_string(), Felt252::from(12)), + ("__main__.SHIFT".to_string(), const_identifier(12)), ]); + let accessible_scopes = vec!["__main__".to_string()]; compute_ids_high_low( &mut vm, &mut exec_scopes, &ids_data, &ap_tracking, - &constants, + &identifiers, + &accessible_scopes, ) .expect("compute_ids_high_low() failed"); diff --git a/vm/src/hint_processor/builtin_hint_processor/sha256_utils.rs b/vm/src/hint_processor/builtin_hint_processor/sha256_utils.rs index 67bfc7dfd3..e7ce7e44ec 100644 --- a/vm/src/hint_processor/builtin_hint_processor/sha256_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/sha256_utils.rs @@ -1,3 +1,4 @@ +use crate::serde::deserialize_program::Identifier; use crate::stdlib::{boxed::Box, collections::HashMap, prelude::*}; use crate::Felt252; @@ -53,17 +54,21 @@ fn sha256_main( vm: &mut VirtualMachine, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, + identifiers: &HashMap, + accessible_scopes: &[String], iv: &mut [u32; 8], ) -> Result<(), HintError> { let input_ptr = get_ptr_from_var_name("sha256_start", vm, ids_data, ap_tracking)?; // The original code gets it from `ids` in both cases, and this makes it easier // to implement the arbitrary length one - let input_chunk_size_felts = - get_constant_from_var_name("SHA256_INPUT_CHUNK_SIZE_FELTS", constants)? - .to_usize() - .unwrap_or(100); // Hack: enough to fail the assertion + let input_chunk_size_felts = get_constant_from_var_name( + "SHA256_INPUT_CHUNK_SIZE_FELTS", + identifiers, + accessible_scopes, + )? + .to_usize() + .unwrap_or(100); // Hack: enough to fail the assertion if input_chunk_size_felts >= 100 { return Err(HintError::AssertionFailed( @@ -113,10 +118,18 @@ pub fn sha256_main_constant_input_length( vm: &mut VirtualMachine, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, + identifiers: &HashMap, + accessible_scopes: &[String], ) -> Result<(), HintError> { let mut iv = IV; - sha256_main(vm, ids_data, ap_tracking, constants, &mut iv) + sha256_main( + vm, + ids_data, + ap_tracking, + identifiers, + accessible_scopes, + &mut iv, + ) } /* Implements hint: @@ -136,11 +149,13 @@ pub fn sha256_main_arbitrary_input_length( vm: &mut VirtualMachine, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, + identifiers: &HashMap, + accessible_scopes: &[String], ) -> Result<(), HintError> { let iv_ptr = get_ptr_from_var_name("state", vm, ids_data, ap_tracking)?; - let state_size_felt = get_constant_from_var_name("SHA256_STATE_SIZE_FELTS", constants)?; + let state_size_felt = + get_constant_from_var_name("SHA256_STATE_SIZE_FELTS", identifiers, accessible_scopes)?; let state_size = match state_size_felt.to_usize() { Some(size) if size == SHA256_STATE_SIZE_FELTS => size, @@ -171,7 +186,14 @@ pub fn sha256_main_arbitrary_input_length( .try_into() .expect("size is constant"); - sha256_main(vm, ids_data, ap_tracking, constants, &mut iv) + sha256_main( + vm, + ids_data, + ap_tracking, + identifiers, + accessible_scopes, + &mut iv, + ) } pub fn sha256_finalize( diff --git a/vm/src/hint_processor/builtin_hint_processor/uint384.rs b/vm/src/hint_processor/builtin_hint_processor/uint384.rs index 6a627daea2..5c10ba4928 100644 --- a/vm/src/hint_processor/builtin_hint_processor/uint384.rs +++ b/vm/src/hint_processor/builtin_hint_processor/uint384.rs @@ -1,3 +1,4 @@ +use crate::serde::deserialize_program::Identifier; use crate::Felt252; use num_bigint::BigUint; use num_integer::Integer; @@ -102,12 +103,13 @@ pub fn add_no_uint384_check( vm: &mut VirtualMachine, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, + identifiers: &HashMap, + accessible_scopes: &[String], ) -> Result<(), HintError> { let a = Uint384::from_var_name("a", vm, ids_data, ap_tracking)?; let b = Uint384::from_var_name("b", vm, ids_data, ap_tracking)?; // This hint is not from the cairo commonlib, and its lib can be found under different paths, so we cant rely on a full path name - let shift = get_constant_from_var_name("SHIFT", constants)?.to_biguint(); + let shift = get_constant_from_var_name("SHIFT", identifiers, accessible_scopes)?.to_biguint(); let sum_d0 = (a.limbs[0].as_ref().to_biguint()) + (b.limbs[0].as_ref().to_biguint()); let carry_d0 = BigUint::from((sum_d0 >= shift) as usize); From 6c5b43f10a09e6fee1ffeb52b9398915aabb66be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 10 Sep 2025 10:27:01 -0300 Subject: [PATCH 05/20] Import String --- vm/src/utils.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/vm/src/utils.rs b/vm/src/utils.rs index dc1c675329..ec53804e4b 100644 --- a/vm/src/utils.rs +++ b/vm/src/utils.rs @@ -53,6 +53,7 @@ pub fn from_relocatable_to_indexes(relocatable: Relocatable) -> (usize, usize) { #[macro_use] pub mod test_utils { use crate::serde::deserialize_program::Identifier; + use crate::stdlib::string::String; use crate::types::exec_scope::ExecutionScopes; use crate::types::relocatable::MaybeRelocatable; use crate::vm::trace::trace_entry::TraceEntry; From 4a8eba3f7866f6024611a03b22c840a3d135279f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 10 Sep 2025 14:30:36 -0300 Subject: [PATCH 06/20] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8c10f0fbc..287f86cae3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ #### Upcoming Changes +* fix(breaking): Match constants by full path [#2192](https://github.com/lambdaclass/cairo-vm/pull/2192) + #### [2.5.0] - 2025-09-11 * breaking: Store constants in Hint Data [#2191](https://github.com/lambdaclass/cairo-vm/pull/2191) From aea7959eb3734fe31e37b2cc175f232e1ee2c98a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 10 Sep 2025 14:58:11 -0300 Subject: [PATCH 07/20] Minor improvement to code --- .../builtin_hint_processor/sha256_utils.rs | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/vm/src/hint_processor/builtin_hint_processor/sha256_utils.rs b/vm/src/hint_processor/builtin_hint_processor/sha256_utils.rs index e7ce7e44ec..69beefcab8 100644 --- a/vm/src/hint_processor/builtin_hint_processor/sha256_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/sha256_utils.rs @@ -60,23 +60,25 @@ fn sha256_main( ) -> Result<(), HintError> { let input_ptr = get_ptr_from_var_name("sha256_start", vm, ids_data, ap_tracking)?; - // The original code gets it from `ids` in both cases, and this makes it easier - // to implement the arbitrary length one + // The code gets the value from `ids.SHA256_INPUT_CHUNK_SIZE_FELTS` in both + // constant and arbitrary input length cases. let input_chunk_size_felts = get_constant_from_var_name( "SHA256_INPUT_CHUNK_SIZE_FELTS", identifiers, accessible_scopes, - )? - .to_usize() - .unwrap_or(100); // Hack: enough to fail the assertion - - if input_chunk_size_felts >= 100 { - return Err(HintError::AssertionFailed( - "assert 0 <= _sha256_input_chunk_size_felts < 100" - .to_string() - .into_boxed_str(), - )); - } + )?; + + // The input chunk size must be less than 100. + let input_chunk_size_felts = match input_chunk_size_felts.to_usize() { + Some(size) if size < 100 => size, + _ => { + return Err(HintError::AssertionFailed( + "assert 0 <= _sha256_input_chunk_size_felts < 100" + .to_string() + .into_boxed_str(), + )); + } + }; let mut message: Vec = Vec::with_capacity(4 * input_chunk_size_felts); From 737f9d44d29cbee1df85d0a680b57db43514a2d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 10 Sep 2025 18:29:13 -0300 Subject: [PATCH 08/20] Adapt other methods --- .../builtin_hint_processor_definition.rs | 157 ++++++++++++------ .../cairo_keccak/keccak_hints.rs | 98 +++++------ .../builtin_hint_processor/keccak_utils.rs | 17 +- .../builtin_hint_processor/kzg_da/mod.rs | 5 +- .../builtin_hint_processor/math_utils.rs | 13 +- .../builtin_hint_processor/mod_circuit.rs | 23 +-- .../secp/bigint_utils.rs | 11 +- .../secp/cairo0_hints.rs | 35 ++-- .../builtin_hint_processor/secp/signature.rs | 13 +- 9 files changed, 214 insertions(+), 158 deletions(-) diff --git a/vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs b/vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs index 8d97f22815..cb22944e75 100644 --- a/vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs +++ b/vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs @@ -197,27 +197,27 @@ impl HintProcessorLogic for BuiltinHintProcessor { .downcast_ref::() .ok_or(HintError::WrongHintData)?; - let identifiers = hint_data.identifiers.as_ref(); - let owned_constants = identifiers - .clone() - .into_iter() - .filter_map(|(key, identifier)| { - if identifier.type_? == "const" { - Some((key, identifier.value?)) - } else { - None - } - }) - .collect(); - let constants = &owned_constants; - if let Some(hint_func) = self.extra_hints.get(&hint_data.code) { + let constants = hint_data + .identifiers + .as_ref() + .clone() + .into_iter() + .filter_map(|(key, identifier)| { + if identifier.type_? == "const" { + Some((key, identifier.value?)) + } else { + None + } + }) + .collect(); + return hint_func.0( vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + &constants, ); } match &*hint_data.code { @@ -246,9 +246,13 @@ impl HintProcessorLogic for BuiltinHintProcessor { &hint_data.accessible_scopes, ), hint_code::IS_250_BITS => is_250_bits(vm, &hint_data.ids_data, &hint_data.ap_tracking), - hint_code::IS_ADDR_BOUNDED => { - is_addr_bounded(vm, &hint_data.ids_data, &hint_data.ap_tracking, constants) - } + hint_code::IS_ADDR_BOUNDED => is_addr_bounded( + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + &hint_data.identifiers, + &hint_data.accessible_scopes, + ), hint_code::IS_POSITIVE => is_positive(vm, &hint_data.ids_data, &hint_data.ap_tracking), hint_code::SPLIT_INT_ASSERT_RANGE => { split_int_assert_range(vm, &hint_data.ids_data, &hint_data.ap_tracking) @@ -468,9 +472,13 @@ impl HintProcessorLogic for BuiltinHintProcessor { hint_code::UINT256_EXPANDED_UNSIGNED_DIV_REM => { uint256_expanded_unsigned_div_rem(vm, &hint_data.ids_data, &hint_data.ap_tracking) } - hint_code::BIGINT_TO_UINT256 => { - bigint_to_uint256(vm, &hint_data.ids_data, &hint_data.ap_tracking, constants) - } + hint_code::BIGINT_TO_UINT256 => bigint_to_uint256( + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + &hint_data.identifiers, + &hint_data.accessible_scopes, + ), hint_code::IS_ZERO_PACK_V1 | hint_code::IS_ZERO_PACK_V2 => { is_zero_pack(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking) } @@ -524,7 +532,8 @@ impl HintProcessorLogic for BuiltinHintProcessor { exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + &hint_data.identifiers, + &hint_data.accessible_scopes, ), hint_code::EC_NEGATE => ec_negate_import_secp_p( vm, @@ -682,20 +691,21 @@ impl HintProcessorLogic for BuiltinHintProcessor { vm, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + &hint_data.identifiers, + &hint_data.accessible_scopes, ), hint_code::SHA256_MAIN_CONSTANT_INPUT_LENGTH => sha256_main_constant_input_length( vm, &hint_data.ids_data, &hint_data.ap_tracking, - identifiers, + &hint_data.identifiers, &hint_data.accessible_scopes, ), hint_code::SHA256_MAIN_ARBITRARY_INPUT_LENGTH => sha256_main_arbitrary_input_length( vm, &hint_data.ids_data, &hint_data.ap_tracking, - identifiers, + &hint_data.identifiers, &hint_data.accessible_scopes, ), hint_code::SHA256_INPUT => { @@ -712,21 +722,40 @@ impl HintProcessorLogic for BuiltinHintProcessor { vm, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + &hint_data.identifiers, + &hint_data.accessible_scopes, ) } hint_code::BLOCK_PERMUTATION | hint_code::BLOCK_PERMUTATION_WHITELIST_V1 => { - block_permutation_v1(vm, &hint_data.ids_data, &hint_data.ap_tracking, constants) - } - hint_code::BLOCK_PERMUTATION_WHITELIST_V2 => { - block_permutation_v2(vm, &hint_data.ids_data, &hint_data.ap_tracking, constants) - } - hint_code::CAIRO_KECCAK_FINALIZE_V1 => { - cairo_keccak_finalize_v1(vm, &hint_data.ids_data, &hint_data.ap_tracking, constants) - } - hint_code::CAIRO_KECCAK_FINALIZE_V2 => { - cairo_keccak_finalize_v2(vm, &hint_data.ids_data, &hint_data.ap_tracking, constants) + block_permutation_v1( + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + &hint_data.identifiers, + &hint_data.accessible_scopes, + ) } + hint_code::BLOCK_PERMUTATION_WHITELIST_V2 => block_permutation_v2( + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + &hint_data.identifiers, + &hint_data.accessible_scopes, + ), + hint_code::CAIRO_KECCAK_FINALIZE_V1 => cairo_keccak_finalize_v1( + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + &hint_data.identifiers, + &hint_data.accessible_scopes, + ), + hint_code::CAIRO_KECCAK_FINALIZE_V2 => cairo_keccak_finalize_v2( + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + &hint_data.identifiers, + &hint_data.accessible_scopes, + ), hint_code::FAST_EC_ADD_ASSIGN_NEW_X => fast_ec_add_assign_new_x( vm, exec_scopes, @@ -788,9 +817,13 @@ impl HintProcessorLogic for BuiltinHintProcessor { hint_code::SPLIT_INPUT_15 => { split_input(vm, &hint_data.ids_data, &hint_data.ap_tracking, 15, 5) } - hint_code::SPLIT_N_BYTES => { - split_n_bytes(vm, &hint_data.ids_data, &hint_data.ap_tracking, constants) - } + hint_code::SPLIT_N_BYTES => split_n_bytes( + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + &hint_data.identifiers, + &hint_data.accessible_scopes, + ), hint_code::SPLIT_OUTPUT_MID_LOW_HIGH => { split_output_mid_low_high(vm, &hint_data.ids_data, &hint_data.ap_tracking) } @@ -903,7 +936,8 @@ impl HintProcessorLogic for BuiltinHintProcessor { vm, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + &hint_data.identifiers, + &hint_data.accessible_scopes, ) } #[cfg(feature = "test_utils")] @@ -920,7 +954,7 @@ impl HintProcessorLogic for BuiltinHintProcessor { vm, &hint_data.ids_data, &hint_data.ap_tracking, - identifiers, + &hint_data.identifiers, &hint_data.accessible_scopes, exec_scopes, ), @@ -930,7 +964,8 @@ impl HintProcessorLogic for BuiltinHintProcessor { exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + &hint_data.identifiers, + &hint_data.accessible_scopes, ), #[cfg(feature = "cairo-0-secp-hints")] cairo0_hints::COMPUTE_IDS_HIGH_LOW => cairo0_hints::compute_ids_high_low( @@ -938,7 +973,7 @@ impl HintProcessorLogic for BuiltinHintProcessor { exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking, - identifiers, + &hint_data.identifiers, &hint_data.accessible_scopes, ), #[cfg(feature = "cairo-0-secp-hints")] @@ -947,7 +982,8 @@ impl HintProcessorLogic for BuiltinHintProcessor { exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + &hint_data.identifiers, + &hint_data.accessible_scopes, SECP256R1_P.magnitude(), ), #[cfg(feature = "cairo-0-secp-hints")] @@ -956,7 +992,8 @@ impl HintProcessorLogic for BuiltinHintProcessor { exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + &hint_data.identifiers, + &hint_data.accessible_scopes, &CAIRO_PRIME, ), #[cfg(feature = "cairo-0-secp-hints")] @@ -965,7 +1002,8 @@ impl HintProcessorLogic for BuiltinHintProcessor { exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + &hint_data.identifiers, + &hint_data.accessible_scopes, ), #[cfg(feature = "cairo-0-secp-hints")] cairo0_hints::COMPUTE_VALUE_DIV_MOD => cairo0_hints::compute_value_div_mod( @@ -973,7 +1011,8 @@ impl HintProcessorLogic for BuiltinHintProcessor { exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + &hint_data.identifiers, + &hint_data.accessible_scopes, ), #[cfg(feature = "cairo-0-secp-hints")] cairo0_hints::GENERATE_NIBBLES => cairo0_hints::generate_nibbles( @@ -981,7 +1020,8 @@ impl HintProcessorLogic for BuiltinHintProcessor { exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + &hint_data.identifiers, + &hint_data.accessible_scopes, ), #[cfg(feature = "cairo-0-secp-hints")] @@ -990,7 +1030,8 @@ impl HintProcessorLogic for BuiltinHintProcessor { exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + &hint_data.identifiers, + &hint_data.accessible_scopes, ), #[cfg(feature = "cairo-0-secp-hints")] cairo0_hints::IS_ON_CURVE_2 => cairo0_hints::is_on_curve_2( @@ -998,7 +1039,8 @@ impl HintProcessorLogic for BuiltinHintProcessor { exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + &hint_data.identifiers, + &hint_data.accessible_scopes, ), #[cfg(feature = "cairo-0-secp-hints")] cairo0_hints::SECP_R1_GET_POINT_FROM_X => cairo0_hints::r1_get_point_from_x( @@ -1006,7 +1048,8 @@ impl HintProcessorLogic for BuiltinHintProcessor { exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + &hint_data.identifiers, + &hint_data.accessible_scopes, SECP256R1_P.magnitude(), ), @@ -1016,7 +1059,8 @@ impl HintProcessorLogic for BuiltinHintProcessor { exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + &hint_data.identifiers, + &hint_data.accessible_scopes, &CAIRO_PRIME, ), @@ -1026,7 +1070,8 @@ impl HintProcessorLogic for BuiltinHintProcessor { exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + &hint_data.identifiers, + &hint_data.accessible_scopes, ), #[cfg(feature = "cairo-0-secp-hints")] cairo0_hints::SECP_REDUCE_X => cairo0_hints::reduce_x( @@ -1034,7 +1079,8 @@ impl HintProcessorLogic for BuiltinHintProcessor { exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + &hint_data.identifiers, + &hint_data.accessible_scopes, ), #[cfg(feature = "cairo-0-data-availability-hints")] super::kzg_da::WRITE_DIVMOD_SEGMENT => super::kzg_da::write_div_mod_segment( @@ -1042,7 +1088,8 @@ impl HintProcessorLogic for BuiltinHintProcessor { exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking, - constants, + &hint_data.identifiers, + &hint_data.accessible_scopes, ), code => Err(HintError::UnknownHint(code.to_string().into_boxed_str())), diff --git a/vm/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs b/vm/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs index deb73b6f7a..fe3376d301 100644 --- a/vm/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs +++ b/vm/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs @@ -1,8 +1,12 @@ -use crate::stdlib::{ - borrow::{Cow, ToOwned}, - boxed::Box, - collections::HashMap, - prelude::*, +use crate::{ + hint_processor::builtin_hint_processor::hint_utils::get_constant_from_var_name, + serde::deserialize_program::Identifier, + stdlib::{ + borrow::{Cow, ToOwned}, + boxed::Box, + collections::HashMap, + prelude::*, + }, }; use crate::{ hint_processor::{ @@ -23,21 +27,6 @@ use crate::{ }; use num_traits::ToPrimitive; -// Constants in package "starkware.cairo.common.cairo_keccak.keccak". -const BYTES_IN_WORD: &str = "starkware.cairo.common.cairo_keccak.keccak.BYTES_IN_WORD"; -const KECCAK_FULL_RATE_IN_BYTES_CAIRO_KECCAK: &str = - "starkware.cairo.common.cairo_keccak.keccak.KECCAK_FULL_RATE_IN_BYTES"; -const KECCAK_FULL_RATE_IN_BYTES_BUILTIN_KECCAK: &str = - "starkware.cairo.common.builtin_keccak.keccak.KECCAK_FULL_RATE_IN_BYTES"; - -const KECCAK_FULL_RATE_IN_BYTES: &str = "KECCAK_FULL_RATE_IN_BYTES"; - -const KECCAK_STATE_SIZE_FELTS: &str = - "starkware.cairo.common.cairo_keccak.keccak.KECCAK_STATE_SIZE_FELTS"; - -// Constants in package "starkware.cairo.common.cairo_keccak.packed_keccak". -const BLOCK_SIZE: &str = "starkware.cairo.common.cairo_keccak.packed_keccak.BLOCK_SIZE"; - /* Implements hint: %{ @@ -80,7 +69,8 @@ pub fn compare_bytes_in_word_nondet( vm: &mut VirtualMachine, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, + identifiers: &HashMap, + accessible_scopes: &[String], ) -> Result<(), HintError> { let n_bytes = get_integer_from_var_name("n_bytes", vm, ids_data, ap_tracking)?; let n_bytes = n_bytes.as_ref(); @@ -90,9 +80,8 @@ pub fn compare_bytes_in_word_nondet( // making value be 0 (if it can't convert then it's either negative, which can't be in Cairo memory // or too big, which also means n_bytes > BYTES_IN_WORD). The other option is to exctract // Felt252::from(BYTES_INTO_WORD) into a lazy_static! - let bytes_in_word = constants - .get(BYTES_IN_WORD) - .ok_or_else(|| HintError::MissingConstant(Box::new(BYTES_IN_WORD)))?; + let bytes_in_word = + get_constant_from_var_name("BYTES_IN_WORD", identifiers, accessible_scopes)?; let value = Felt252::from((n_bytes < bytes_in_word) as usize); insert_value_into_ap(vm, value) } @@ -109,15 +98,14 @@ pub fn compare_keccak_full_rate_in_bytes_nondet( vm: &mut VirtualMachine, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, + identifiers: &HashMap, + accessible_scopes: &[String], ) -> Result<(), HintError> { let n_bytes = get_integer_from_var_name("n_bytes", vm, ids_data, ap_tracking)?; let n_bytes = n_bytes.as_ref(); - let keccak_full_rate_in_bytes = constants - .get(KECCAK_FULL_RATE_IN_BYTES_CAIRO_KECCAK) - .or_else(|| constants.get(KECCAK_FULL_RATE_IN_BYTES_BUILTIN_KECCAK)) - .ok_or_else(|| HintError::MissingConstant(Box::new(KECCAK_FULL_RATE_IN_BYTES)))?; + let keccak_full_rate_in_bytes = + get_constant_from_var_name("KECCAK_FULL_RATE_IN_BYTES", identifiers, accessible_scopes)?; let value = Felt252::from((n_bytes >= keccak_full_rate_in_bytes) as usize); insert_value_into_ap(vm, value) } @@ -147,11 +135,11 @@ pub(crate) fn block_permutation_v1( vm: &mut VirtualMachine, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, + identifiers: &HashMap, + accessible_scopes: &[String], ) -> Result<(), HintError> { - let keccak_state_size_felts = constants - .get(KECCAK_STATE_SIZE_FELTS) - .ok_or_else(|| HintError::MissingConstant(Box::new(KECCAK_STATE_SIZE_FELTS)))?; + let keccak_state_size_felts = + get_constant_from_var_name("KECCAK_STATE_SIZE_FELTS", identifiers, accessible_scopes)?; if keccak_state_size_felts >= &Felt252::from(100_i32) { return Err(HintError::InvalidKeccakStateSizeFelt252s(Box::new( *keccak_state_size_felts, @@ -214,11 +202,11 @@ pub(crate) fn block_permutation_v2( vm: &mut VirtualMachine, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, + identifiers: &HashMap, + accessible_scopes: &[String], ) -> Result<(), HintError> { - let keccak_state_size_felts = constants - .get(KECCAK_STATE_SIZE_FELTS) - .ok_or_else(|| HintError::MissingConstant(Box::new(KECCAK_STATE_SIZE_FELTS)))?; + let keccak_state_size_felts = + get_constant_from_var_name("KECCAK_STATE_SIZE_FELTS", identifiers, accessible_scopes)?; if keccak_state_size_felts >= &Felt252::from(100_i32) { return Err(HintError::InvalidKeccakStateSizeFelt252s(Box::new( *keccak_state_size_felts, @@ -250,15 +238,13 @@ fn cairo_keccak_finalize( vm: &mut VirtualMachine, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, + identifiers: &HashMap, + accessible_scopes: &[String], block_size_limit: usize, ) -> Result<(), HintError> { - let keccak_state_size_felts = constants - .get(KECCAK_STATE_SIZE_FELTS) - .ok_or_else(|| HintError::MissingConstant(Box::new(KECCAK_STATE_SIZE_FELTS)))?; - let block_size = constants - .get(BLOCK_SIZE) - .ok_or_else(|| HintError::MissingConstant(Box::new(BLOCK_SIZE)))?; + let keccak_state_size_felts = + get_constant_from_var_name("KECCAK_STATE_SIZE_FELTS", identifiers, accessible_scopes)?; + let block_size = get_constant_from_var_name("BLOCK_SIZE", identifiers, accessible_scopes)?; if keccak_state_size_felts >= &Felt252::from(100_i32) { return Err(HintError::InvalidKeccakStateSizeFelt252s(Box::new( @@ -311,9 +297,17 @@ pub(crate) fn cairo_keccak_finalize_v1( vm: &mut VirtualMachine, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, + identifiers: &HashMap, + accessible_scopes: &[String], ) -> Result<(), HintError> { - cairo_keccak_finalize(vm, ids_data, ap_tracking, constants, 10) + cairo_keccak_finalize( + vm, + ids_data, + ap_tracking, + identifiers, + accessible_scopes, + 10, + ) } /* Implements hint: @@ -332,9 +326,17 @@ pub(crate) fn cairo_keccak_finalize_v2( vm: &mut VirtualMachine, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, + identifiers: &HashMap, + accessible_scopes: &[String], ) -> Result<(), HintError> { - cairo_keccak_finalize(vm, ids_data, ap_tracking, constants, 1000) + cairo_keccak_finalize( + vm, + ids_data, + ap_tracking, + identifiers, + accessible_scopes, + 1000, + ) } // Helper function to transform a vector of MaybeRelocatables into a vector diff --git a/vm/src/hint_processor/builtin_hint_processor/keccak_utils.rs b/vm/src/hint_processor/builtin_hint_processor/keccak_utils.rs index 3193105f48..15c8db6b19 100644 --- a/vm/src/hint_processor/builtin_hint_processor/keccak_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/keccak_utils.rs @@ -1,3 +1,4 @@ +use crate::serde::deserialize_program::Identifier; use crate::stdlib::{boxed::Box, cmp, collections::HashMap, prelude::*}; use crate::types::errors::math_errors::MathError; @@ -18,9 +19,7 @@ use num_integer::Integer; use num_traits::ToPrimitive; use sha3::{Digest, Keccak256}; -use super::hint_utils::insert_value_from_var_name; - -const BYTES_IN_WORD: &str = "starkware.cairo.common.builtin_keccak.keccak.BYTES_IN_WORD"; +use super::hint_utils::{get_constant_from_var_name, insert_value_from_var_name}; /* Implements hint: %{ @@ -239,17 +238,19 @@ pub fn split_n_bytes( vm: &mut VirtualMachine, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, + identifiers: &HashMap, + accessible_scopes: &[String], ) -> Result<(), HintError> { let n_bytes = get_integer_from_var_name("n_bytes", vm, ids_data, ap_tracking).and_then(|x| { x.to_u64() .ok_or_else(|| HintError::Math(MathError::Felt252ToU64Conversion(Box::new(x)))) })?; - let bytes_in_word = constants - .get(BYTES_IN_WORD) - .and_then(|x| x.to_u64()) - .ok_or_else(|| HintError::MissingConstant(Box::new(BYTES_IN_WORD)))?; + let bytes_in_word = + get_constant_from_var_name("BYTES_IN_WORD", identifiers, accessible_scopes)?; + let bytes_in_word = bytes_in_word + .to_u64() + .ok_or_else(|| MathError::Felt252ToU64Conversion(Box::new(*bytes_in_word)))?; let (high, low) = n_bytes.div_mod_floor(&bytes_in_word); insert_value_from_var_name( "n_words_to_copy", diff --git a/vm/src/hint_processor/builtin_hint_processor/kzg_da/mod.rs b/vm/src/hint_processor/builtin_hint_processor/kzg_da/mod.rs index 49bb8c348f..8a77644365 100644 --- a/vm/src/hint_processor/builtin_hint_processor/kzg_da/mod.rs +++ b/vm/src/hint_processor/builtin_hint_processor/kzg_da/mod.rs @@ -3,7 +3,7 @@ use core::str::FromStr; use super::{hint_utils::get_relocatable_from_var_name, secp::bigint_utils::BigInt3}; use crate::{ hint_processor::hint_processor_definition::HintReference, - serde::deserialize_program::ApTracking, + serde::deserialize_program::{ApTracking, Identifier}, types::relocatable::MaybeRelocatable, utils::CAIRO_PRIME, vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, @@ -44,7 +44,8 @@ pub fn write_div_mod_segment( _exec_scopes: &mut ExecutionScopes, ids_data: &HashMap, ap_tracking: &ApTracking, - _constants: &HashMap, + _identifiers: &HashMap, + _accessible_scopes: &[String], ) -> Result<(), HintError> { let a = bls_pack( &BigInt3::from_var_name("a", vm, ids_data, ap_tracking)?, diff --git a/vm/src/hint_processor/builtin_hint_processor/math_utils.rs b/vm/src/hint_processor/builtin_hint_processor/math_utils.rs index 66f88abf78..7be2657fbf 100644 --- a/vm/src/hint_processor/builtin_hint_processor/math_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/math_utils.rs @@ -37,8 +37,6 @@ use super::{ uint256_utils::Uint256, }; -const ADDR_BOUND: &str = "starkware.starknet.common.storage.ADDR_BOUND"; - //Implements hint: memory[ap] = 0 if 0 <= (ids.a % PRIME) < range_check_builtin.bound else 1 pub fn is_nn( vm: &mut VirtualMachine, @@ -570,14 +568,13 @@ pub fn is_addr_bounded( vm: &mut VirtualMachine, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, + identifiers: &HashMap, + accessible_scopes: &[String], ) -> Result<(), HintError> { let addr = get_integer_from_var_name("addr", vm, ids_data, ap_tracking)?; - let addr_bound = constants - .get(ADDR_BOUND) - .ok_or_else(|| HintError::MissingConstant(Box::new(ADDR_BOUND)))? - .to_biguint(); + let addr_bound = + get_constant_from_var_name("ADDR_BOUND", identifiers, accessible_scopes)?.to_biguint(); let lower_bound = BigUint::one() << 250_usize; let upper_bound = BigUint::one() << 251_usize; @@ -2053,7 +2050,7 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::MissingConstant(bx)) if *bx == ADDR_BOUND + Err(HintError::MissingConstant(bx)) if *bx == "ADDR_BOUND" ); } diff --git a/vm/src/hint_processor/builtin_hint_processor/mod_circuit.rs b/vm/src/hint_processor/builtin_hint_processor/mod_circuit.rs index 22fbc57d19..afbea39316 100644 --- a/vm/src/hint_processor/builtin_hint_processor/mod_circuit.rs +++ b/vm/src/hint_processor/builtin_hint_processor/mod_circuit.rs @@ -1,16 +1,17 @@ +use crate::serde::deserialize_program::Identifier; use crate::stdlib::prelude::String; +use crate::types::errors::math_errors::MathError; use crate::{ hint_processor::hint_processor_definition::HintReference, serde::deserialize_program::ApTracking, stdlib::collections::HashMap, vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, - Felt252, }; -#[cfg(not(feature = "mod_builtin"))] -use crate::{stdlib::prelude::Box, types::errors::math_errors::MathError}; use num_traits::ToPrimitive; -use super::hint_utils::{get_integer_from_var_name, get_ptr_from_var_name}; +use super::hint_utils::{ + get_constant_from_var_name, get_integer_from_var_name, get_ptr_from_var_name, +}; /* Implements Hint: %{ from starkware.cairo.lang.builtins.modulo.mod_builtin_runner import ModBuiltinRunner @@ -50,21 +51,13 @@ pub fn run_p_mod_circuit_with_large_batch_size( vm: &mut VirtualMachine, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, + identifiers: &HashMap, + accessible_scopes: &[String], ) -> Result<(), HintError> { - #[cfg(not(feature = "mod_builtin"))] - const LARGE_BATCH_SIZE_PATH: &str = - "starkware.cairo.common.modulo.run_mod_p_circuit_with_large_batch_size.BATCH_SIZE"; - #[cfg(not(feature = "mod_builtin"))] - let batch_size = constants - .get(LARGE_BATCH_SIZE_PATH) - .ok_or_else(|| HintError::MissingConstant(Box::new(LARGE_BATCH_SIZE_PATH)))?; - #[cfg(not(feature = "mod_builtin"))] + let batch_size = get_constant_from_var_name("BATCH_SIZE", identifiers, accessible_scopes)?; let batch_size = batch_size .to_usize() .ok_or_else(|| MathError::Felt252ToUsizeConversion(Box::new(*batch_size)))?; - #[cfg(feature = "mod_builtin")] - let batch_size = 8; // Hardcoded here as we are not importing from the common lib yet run_p_mod_circuit_inner(vm, ids_data, ap_tracking, batch_size) } diff --git a/vm/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs b/vm/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs index 072b4f6d88..c0de264bdf 100644 --- a/vm/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs @@ -1,14 +1,16 @@ use core::ops::Shl; +use crate::hint_processor::builtin_hint_processor::hint_utils::get_constant_from_var_name; use crate::hint_processor::builtin_hint_processor::uint_utils::{pack, split}; use crate::math_utils::signed_felt; +use crate::serde::deserialize_program::Identifier; use crate::stdlib::{borrow::Cow, boxed::Box, collections::HashMap, prelude::*}; use crate::Felt252; use crate::{ hint_processor::{ builtin_hint_processor::{ hint_utils::{get_relocatable_from_var_name, insert_value_from_var_name}, - secp::secp_utils::{bigint3_split, BASE_86}, + secp::secp_utils::bigint3_split, }, hint_processor_definition::HintReference, }, @@ -151,16 +153,15 @@ pub fn bigint_to_uint256( vm: &mut VirtualMachine, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, + identifiers: &HashMap, + accessible_scopes: &[String], ) -> Result<(), HintError> { let x_struct = get_relocatable_from_var_name("x", vm, ids_data, ap_tracking)?; let d0 = vm.get_integer(x_struct)?; let d1 = vm.get_integer((x_struct + 1_i32)?)?; let d0 = d0.as_ref(); let d1 = d1.as_ref(); - let base_86 = constants - .get(BASE_86) - .ok_or_else(|| HintError::MissingConstant(Box::new(BASE_86)))?; + let base_86 = get_constant_from_var_name("BASE", identifiers, accessible_scopes)?; let mask = pow2_const_nz(128); let low = (d0 + (d1 * base_86)).mod_floor(mask); insert_value_from_var_name("low", low, vm, ids_data, ap_tracking) diff --git a/vm/src/hint_processor/builtin_hint_processor/secp/cairo0_hints.rs b/vm/src/hint_processor/builtin_hint_processor/secp/cairo0_hints.rs index be151bdd04..6725d3b5a2 100644 --- a/vm/src/hint_processor/builtin_hint_processor/secp/cairo0_hints.rs +++ b/vm/src/hint_processor/builtin_hint_processor/secp/cairo0_hints.rs @@ -128,7 +128,8 @@ pub fn reduce_value( exec_scopes: &mut ExecutionScopes, ids_data: &HashMap, ap_tracking: &ApTracking, - _constants: &HashMap, + _identifiers: &HashMap, + _accessible_scopes: &[String], ) -> Result<(), HintError> { let x = Uint384::from_var_name("x", vm, ids_data, ap_tracking)?.pack86(); exec_scopes.insert_value("value", x.mod_floor(&SECP256R1_P)); @@ -140,7 +141,8 @@ pub fn reduce_x( exec_scopes: &mut ExecutionScopes, ids_data: &HashMap, ap_tracking: &ApTracking, - _constants: &HashMap, + _identifiers: &HashMap, + _accessible_scopes: &[String], ) -> Result<(), HintError> { let x = Uint384::from_var_name("x", vm, ids_data, ap_tracking)?.pack86(); exec_scopes.insert_value("x", x.mod_floor(&SECP256R1_P)); @@ -152,7 +154,8 @@ pub fn compute_q_mod_prime( _exec_scopes: &mut ExecutionScopes, ids_data: &HashMap, ap_tracking: &ApTracking, - _constants: &HashMap, + _identifiers: &HashMap, + _accessible_scopes: &[String], ) -> Result<(), HintError> { let val = Uint384::from_var_name("val", vm, ids_data, ap_tracking)?.pack86(); let (q, r) = val.div_mod_floor(&SECP256R1_P); @@ -196,7 +199,8 @@ pub fn r1_get_point_from_x( exec_scopes: &mut ExecutionScopes, ids_data: &HashMap, ap_tracking: &ApTracking, - _constants: &HashMap, + _identifiers: &HashMap, + _accessible_scopes: &[String], pack_prime: &BigUint, ) -> Result<(), HintError> { exec_scopes.insert_value::("SECP256R1_P", SECP256R1_P.clone()); @@ -257,7 +261,8 @@ pub fn is_on_curve_2( exec_scopes: &mut ExecutionScopes, ids_data: &HashMap, ap_tracking: &ApTracking, - _constants: &HashMap, + _identifiers: &HashMap, + _accessible_scopes: &[String], ) -> Result<(), HintError> { let y: BigInt = exec_scopes.get("y")?; let y_square_int: BigInt = exec_scopes.get("y_square_int")?; @@ -279,7 +284,8 @@ pub fn secp_double_assign_new_x( exec_scopes: &mut ExecutionScopes, ids_data: &HashMap, ap_tracking: &ApTracking, - _constants: &HashMap, + _identifiers: &HashMap, + _accessible_scopes: &[String], pack_prime: &BigUint, ) -> Result<(), HintError> { exec_scopes.insert_value::("SECP256R1_P", SECP256R1_P.clone()); @@ -309,7 +315,8 @@ pub fn generate_nibbles( exec_scopes: &mut ExecutionScopes, ids_data: &HashMap, ap_tracking: &ApTracking, - _constants: &HashMap, + _identifiers: &HashMap, + _accessible_scopes: &[String], ) -> Result<(), HintError> { let num = Uint256::from_var_name("scalar", vm, ids_data, ap_tracking)?.pack(); @@ -337,7 +344,8 @@ pub fn fast_secp_add_assign_new_y( exec_scopes: &mut ExecutionScopes, _ids_data: &HashMap, _ap_tracking: &ApTracking, - _constants: &HashMap, + _identifiers: &HashMap, + _accessible_scopes: &[String], ) -> Result<(), HintError> { //Get variables from vm scope let (slope, x, new_x, y, secp_p) = ( @@ -359,7 +367,8 @@ pub fn write_nibbles_to_mem( exec_scopes: &mut ExecutionScopes, _ids_data: &HashMap, _ap_tracking: &ApTracking, - _constants: &HashMap, + _identifiers: &HashMap, + _accessible_scopes: &[String], ) -> Result<(), HintError> { let nibbles: &mut Vec = exec_scopes.get_mut_list_ref("nibbles")?; let nibble = nibbles.pop().ok_or(HintError::EmptyNibbles)?; @@ -373,7 +382,8 @@ pub fn compute_value_div_mod( exec_scopes: &mut ExecutionScopes, _ids_data: &HashMap, _ap_tracking: &ApTracking, - _constants: &HashMap, + _identifiers: &HashMap, + _accessible_scopes: &[String], ) -> Result<(), HintError> { //Get variables from vm scope let x = exec_scopes.get_ref::("x")?; @@ -419,6 +429,7 @@ mod tests { &ids_data, &ap_tracking, &Default::default(), + &[], ) .expect("is_on_curve2() failed"); @@ -447,6 +458,7 @@ mod tests { &ids_data, &ap_tracking, &Default::default(), + &[], ) .expect("compute_q_mod_prime() failed"); @@ -559,6 +571,7 @@ mod tests { &ids_data, &ap_tracking, &constants, + &[], SECP256R1_P.magnitude(), ) .expect("calculate_value() failed"); @@ -632,6 +645,7 @@ mod tests { &ids_data, &ap_tracking, &Default::default(), + &[], ) .expect("reduce_value() failed"); @@ -688,6 +702,7 @@ mod tests { &ids_data, &ap_tracking, &Default::default(), + &[], ) .expect("x() failed"); diff --git a/vm/src/hint_processor/builtin_hint_processor/secp/signature.rs b/vm/src/hint_processor/builtin_hint_processor/secp/signature.rs index fd5951e9fb..1bdeca1ab1 100644 --- a/vm/src/hint_processor/builtin_hint_processor/secp/signature.rs +++ b/vm/src/hint_processor/builtin_hint_processor/secp/signature.rs @@ -1,8 +1,9 @@ -use crate::Felt252; +use crate::hint_processor::builtin_hint_processor::hint_utils::get_constant_from_var_name; +use crate::serde::deserialize_program::Identifier; use crate::{ any_box, hint_processor::{ - builtin_hint_processor::{hint_utils::get_integer_from_var_name, secp::secp_utils::BETA}, + builtin_hint_processor::hint_utils::get_integer_from_var_name, hint_processor_definition::HintReference, }, math_utils::{div_mod, safe_div_bigint}, @@ -106,13 +107,11 @@ pub fn get_point_from_x( exec_scopes: &mut ExecutionScopes, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, + identifiers: &HashMap, + accessible_scopes: &[String], ) -> Result<(), HintError> { exec_scopes.insert_value("SECP_P", SECP_P.clone()); - let beta = constants - .get(BETA) - .ok_or_else(|| HintError::MissingConstant(Box::new(BETA)))? - .to_bigint(); + let beta = get_constant_from_var_name("BETA", identifiers, accessible_scopes)?.to_bigint(); let x_cube_int = Uint384::from_var_name("x_cube", vm, ids_data, ap_tracking)? .pack86() From 572a08311b9aa17c43ffd015e58b59ff4cd1d78d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 10 Sep 2025 19:08:36 -0300 Subject: [PATCH 09/20] Remove local variables from Cairo program The python implementation takes the references, while our implementation doesn't allow taking references when it expects a constants. For this reason, the example doesn't work as is in our current implementation. To fix this, I changed the example to not receive the values as parameters. --- cairo_programs/bad_programs/split_felt_bad_constants.cairo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cairo_programs/bad_programs/split_felt_bad_constants.cairo b/cairo_programs/bad_programs/split_felt_bad_constants.cairo index a051291886..70291950a3 100644 --- a/cairo_programs/bad_programs/split_felt_bad_constants.cairo +++ b/cairo_programs/bad_programs/split_felt_bad_constants.cairo @@ -3,10 +3,10 @@ const MAX_LOW = 1; func main() { let value =1; - hint_func(MAX_HIGH, MAX_LOW, value); + hint_func(value); return(); } -func hint_func(MAX_HIGH: felt, MAX_LOW: felt, value: felt) -> (felt, felt) { +func hint_func(value: felt) -> (felt, felt) { alloc_locals; local low: felt; local high: felt; From 573cc47bf4bf8861416706daee25e893a80e0695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 10 Sep 2025 19:09:07 -0300 Subject: [PATCH 10/20] Properly implements the alias resolution - fix tests --- .../builtin_hint_processor/hint_utils.rs | 77 ++++++++++++++++--- vm/src/vm/errors/hint_errors.rs | 2 +- 2 files changed, 66 insertions(+), 13 deletions(-) diff --git a/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs b/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs index 2f6eca2ef5..d8e3d5f6cd 100644 --- a/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs @@ -175,22 +175,75 @@ pub fn get_reference_from_var_name<'a>( } pub fn get_constant_from_var_name<'a>( - var_name: &'static str, + var_name: &str, identifiers: &'a HashMap, accessible_scopes: &[String], ) -> Result<&'a Felt252, HintError> { - accessible_scopes - .iter() - .rev() - .find_map(|scope| { - let identifier = identifiers.get(&format!("{}.{}", scope, var_name))?; - if identifier.type_.as_ref()? == "const" { - identifier.value.as_ref() - } else { - None + for scope in accessible_scopes.iter().rev() { + let full_path = format!("{}.{}", scope, var_name); + let identifier = identifiers.get(&full_path); + + let Some(identifier) = identifier else { + continue; + }; + + let identifier_type = identifier + .type_ + .as_ref() + .ok_or_else(|| HintError::MissingConstant(Box::new(var_name.to_string())))?; + + match &identifier_type[..] { + "const" => { + return identifier + .value + .as_ref() + .ok_or_else(|| HintError::MissingConstant(Box::new(var_name.to_string()))) + } + "alias" => { + let destination = identifier + .destination + .as_ref() + .ok_or_else(|| HintError::MissingConstant(Box::new(var_name.to_string())))?; + + return get_constant_from_alias(destination, identifiers); } - }) - .ok_or_else(|| HintError::MissingConstant(Box::new(var_name))) + _ => return Err(HintError::MissingConstant(Box::new(var_name.to_string()))), + } + } + + Err(HintError::MissingConstant(Box::new(var_name.to_string()))) +} + +pub fn get_constant_from_alias<'a>( + destination: &str, + identifiers: &'a HashMap, +) -> Result<&'a Felt252, HintError> { + let identifier = identifiers + .get(destination) + .ok_or_else(|| HintError::MissingConstant(Box::new(destination.to_string())))?; + + let identifier_type = identifier + .type_ + .as_ref() + .ok_or_else(|| HintError::MissingConstant(Box::new(destination.to_string())))?; + + match &identifier_type[..] { + "const" => identifier + .value + .as_ref() + .ok_or_else(|| HintError::MissingConstant(Box::new(destination.to_string()))), + "alias" => { + let destination = identifier + .destination + .as_ref() + .ok_or_else(|| HintError::MissingConstant(Box::new(destination.to_string())))?; + + get_constant_from_alias(destination, identifiers) + } + _ => Err(HintError::MissingConstant(Box::new( + destination.to_string(), + ))), + } } #[cfg(test)] diff --git a/vm/src/vm/errors/hint_errors.rs b/vm/src/vm/errors/hint_errors.rs index 8d5f61fcb5..050a400d46 100644 --- a/vm/src/vm/errors/hint_errors.rs +++ b/vm/src/vm/errors/hint_errors.rs @@ -45,7 +45,7 @@ pub enum HintError { #[error("Hint Error: {0}")] CustomHint(Box), #[error("Missing constant: {0}")] - MissingConstant(Box<&'static str>), + MissingConstant(Box), #[error("Fail to get constants for hint execution")] FailedToGetConstant, #[error("Arc too big, {} must be <= {} and {} <= {}", (*.0).0, (*.0).1, (*.0).2, (*.0).3)] From fe3e7074f1291064aed7ebd84c5d123fb5c213ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Thu, 11 Sep 2025 13:41:52 -0300 Subject: [PATCH 11/20] Implement get_identifier_from_scoped_name --- .../builtin_hint_processor/hint_utils.rs | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs b/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs index d8e3d5f6cd..f04fe0f54d 100644 --- a/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs @@ -174,6 +174,36 @@ pub fn get_reference_from_var_name<'a>( .ok_or_else(|| HintError::UnknownIdentifier(Box::::from(var_name))) } +pub fn get_identifier_from_scoped_name<'a>( + scoped_name: &str, + identifiers: &'a HashMap, + accessible_scopes: &[String], +) -> Result<&'a Identifier, HintError> { + for scope in accessible_scopes.iter().rev() { + let full_path = format!("{}.{}", scope, scoped_name); + + if let Some(identifier) = identifiers.get(&full_path) { + return Ok(identifier); + } + + // The scoped_name can itself contain multiple components (i.e. a.b.c). + // If there is a match for at least the first component, we should + // not continue with the next scope. + if let Some(first_component) = scoped_name.split('.').next() { + if identifiers + .get(&format!("{}.{}", scope, first_component)) + .is_some() + { + break; + } + } + } + + Err(HintError::UnknownIdentifier( + scoped_name.to_string().into_boxed_str(), + )) +} + pub fn get_constant_from_var_name<'a>( var_name: &str, identifiers: &'a HashMap, @@ -386,4 +416,62 @@ mod tests { Err(HintError::IdentifierNotInteger(bx)) if bx.as_ref() == "value" ); } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn get_identifier_from_scoped_name_valid() { + let accessible_scopes = &["scope1".to_string(), "scope1.scope2".to_string()]; + + let identifier = const_identifier(5); + + let identifiers = HashMap::from([( + "scope1.scope2.constant1.constant2".to_string(), + identifier.clone(), + )]); + + assert_matches!( + get_identifier_from_scoped_name("constant1.constant2", &identifiers, accessible_scopes), + Ok(id) if id == &identifier + ); + } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn get_identifier_from_scoped_name_invalid() { + let accessible_scopes = &["scope1".to_string(), "scope1.scope2".to_string()]; + + let identifier = const_identifier(5); + + let identifiers = HashMap::from([( + "scope1.scope2.constant3.constant4".to_string(), + identifier.clone(), + )]); + + assert_matches!( + get_identifier_from_scoped_name("constant1.constant2", &identifiers, accessible_scopes), + Err(HintError::UnknownIdentifier(bx)) if bx.as_ref() == "constant1.constant2" + ); + } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn get_identifier_from_scoped_name_invalid_partial_match() { + let accessible_scopes = &["scope1".to_string(), "scope1.scope2".to_string()]; + + let identifier = const_identifier(5); + + let identifiers = HashMap::from([ + ("scope1.scope2.constant1".to_string(), identifier.clone()), + ("scope1.constant1.constant2".to_string(), identifier.clone()), + ( + "scope1.scope2.constant1.constant3".to_string(), + identifier.clone(), + ), + ]); + + assert_matches!( + get_identifier_from_scoped_name("constant1.constant2", &identifiers, accessible_scopes), + Err(HintError::UnknownIdentifier(bx)) if bx.as_ref() == "constant1.constant2" + ); + } } From 9b3505523ff4a307e407da5426016f94a144f5f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Thu, 11 Sep 2025 14:20:53 -0300 Subject: [PATCH 12/20] Improve identifier lookup --- .../cairo_keccak/keccak_hints.rs | 14 +- .../builtin_hint_processor/excess_balance.rs | 4 +- .../builtin_hint_processor/hint_utils.rs | 130 ++++++++++++------ .../builtin_hint_processor/keccak_utils.rs | 4 +- .../builtin_hint_processor/math_utils.rs | 20 +-- .../builtin_hint_processor/mod_circuit.rs | 4 +- .../secp/bigint_utils.rs | 4 +- .../secp/cairo0_hints.rs | 6 +- .../builtin_hint_processor/secp/signature.rs | 4 +- .../builtin_hint_processor/sha256_utils.rs | 6 +- .../builtin_hint_processor/uint384.rs | 7 +- vm/src/utils.rs | 12 ++ vm/src/vm/errors/hint_errors.rs | 2 + 13 files changed, 136 insertions(+), 81 deletions(-) diff --git a/vm/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs b/vm/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs index fe3376d301..645859f7c5 100644 --- a/vm/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs +++ b/vm/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs @@ -1,5 +1,5 @@ use crate::{ - hint_processor::builtin_hint_processor::hint_utils::get_constant_from_var_name, + hint_processor::builtin_hint_processor::hint_utils::get_constant_from_scoped_name, serde::deserialize_program::Identifier, stdlib::{ borrow::{Cow, ToOwned}, @@ -81,7 +81,7 @@ pub fn compare_bytes_in_word_nondet( // or too big, which also means n_bytes > BYTES_IN_WORD). The other option is to exctract // Felt252::from(BYTES_INTO_WORD) into a lazy_static! let bytes_in_word = - get_constant_from_var_name("BYTES_IN_WORD", identifiers, accessible_scopes)?; + get_constant_from_scoped_name("BYTES_IN_WORD", identifiers, accessible_scopes)?; let value = Felt252::from((n_bytes < bytes_in_word) as usize); insert_value_into_ap(vm, value) } @@ -105,7 +105,7 @@ pub fn compare_keccak_full_rate_in_bytes_nondet( let n_bytes = n_bytes.as_ref(); let keccak_full_rate_in_bytes = - get_constant_from_var_name("KECCAK_FULL_RATE_IN_BYTES", identifiers, accessible_scopes)?; + get_constant_from_scoped_name("KECCAK_FULL_RATE_IN_BYTES", identifiers, accessible_scopes)?; let value = Felt252::from((n_bytes >= keccak_full_rate_in_bytes) as usize); insert_value_into_ap(vm, value) } @@ -139,7 +139,7 @@ pub(crate) fn block_permutation_v1( accessible_scopes: &[String], ) -> Result<(), HintError> { let keccak_state_size_felts = - get_constant_from_var_name("KECCAK_STATE_SIZE_FELTS", identifiers, accessible_scopes)?; + get_constant_from_scoped_name("KECCAK_STATE_SIZE_FELTS", identifiers, accessible_scopes)?; if keccak_state_size_felts >= &Felt252::from(100_i32) { return Err(HintError::InvalidKeccakStateSizeFelt252s(Box::new( *keccak_state_size_felts, @@ -206,7 +206,7 @@ pub(crate) fn block_permutation_v2( accessible_scopes: &[String], ) -> Result<(), HintError> { let keccak_state_size_felts = - get_constant_from_var_name("KECCAK_STATE_SIZE_FELTS", identifiers, accessible_scopes)?; + get_constant_from_scoped_name("KECCAK_STATE_SIZE_FELTS", identifiers, accessible_scopes)?; if keccak_state_size_felts >= &Felt252::from(100_i32) { return Err(HintError::InvalidKeccakStateSizeFelt252s(Box::new( *keccak_state_size_felts, @@ -243,8 +243,8 @@ fn cairo_keccak_finalize( block_size_limit: usize, ) -> Result<(), HintError> { let keccak_state_size_felts = - get_constant_from_var_name("KECCAK_STATE_SIZE_FELTS", identifiers, accessible_scopes)?; - let block_size = get_constant_from_var_name("BLOCK_SIZE", identifiers, accessible_scopes)?; + get_constant_from_scoped_name("KECCAK_STATE_SIZE_FELTS", identifiers, accessible_scopes)?; + let block_size = get_constant_from_scoped_name("BLOCK_SIZE", identifiers, accessible_scopes)?; if keccak_state_size_felts >= &Felt252::from(100_i32) { return Err(HintError::InvalidKeccakStateSizeFelt252s(Box::new( diff --git a/vm/src/hint_processor/builtin_hint_processor/excess_balance.rs b/vm/src/hint_processor/builtin_hint_processor/excess_balance.rs index 247e56b944..f8fb2fb382 100644 --- a/vm/src/hint_processor/builtin_hint_processor/excess_balance.rs +++ b/vm/src/hint_processor/builtin_hint_processor/excess_balance.rs @@ -22,7 +22,7 @@ use lazy_static::lazy_static; use super::{ dict_manager::DictManager, hint_utils::{ - get_constant_from_var_name, get_integer_from_var_name, get_ptr_from_var_name, + get_constant_from_scoped_name, get_integer_from_var_name, get_ptr_from_var_name, insert_value_from_var_name, }, }; @@ -270,7 +270,7 @@ pub fn excess_balance_hint( let margin_check_type = get_integer_from_var_name("margin_check_type", vm, ids_data, ap_tracking)?; let margin_check_initial = - get_constant_from_var_name("MARGIN_CHECK_INITIAL", identifiers, accessible_scopes)?; + get_constant_from_scoped_name("MARGIN_CHECK_INITIAL", identifiers, accessible_scopes)?; let token_assets_value_d = get_integer_from_var_name("token_assets_value_d", vm, ids_data, ap_tracking)?; let account = get_integer_from_var_name("account", vm, ids_data, ap_tracking)?; diff --git a/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs b/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs index f04fe0f54d..7fdb9a1705 100644 --- a/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs @@ -1,3 +1,5 @@ +use hashbrown::HashSet; + use crate::stdlib::{boxed::Box, collections::HashMap, prelude::*}; use crate::Felt252; @@ -182,21 +184,42 @@ pub fn get_identifier_from_scoped_name<'a>( for scope in accessible_scopes.iter().rev() { let full_path = format!("{}.{}", scope, scoped_name); - if let Some(identifier) = identifiers.get(&full_path) { - return Ok(identifier); - } + let Some(mut identifier) = identifiers.get(&full_path) else { + // The scoped_name can itself contain multiple components (i.e. a.b.c). + // If there is a match for at least the first component, we should + // not continue with the next scope. + if let Some(first_component) = scoped_name.split('.').next() { + if identifiers + .get(&format!("{}.{}", scope, first_component)) + .is_some() + { + break; + } + } + + continue; + }; + + let mut visited_aliases = HashSet::new(); + visited_aliases.insert(&full_path); - // The scoped_name can itself contain multiple components (i.e. a.b.c). - // If there is a match for at least the first component, we should - // not continue with the next scope. - if let Some(first_component) = scoped_name.split('.').next() { - if identifiers - .get(&format!("{}.{}", scope, first_component)) - .is_some() - { - break; + // If the identifier is of alias type, we resolve the alias. + while identifier.type_.as_deref() == Some("alias") { + let destination = identifier + .destination + .as_ref() + .ok_or_else(|| HintError::UnknownIdentifierInternal)?; + + if !visited_aliases.insert(destination) { + return Err(HintError::CyclicAliasing); } + + identifier = identifiers.get(destination).ok_or_else(|| { + HintError::UnknownIdentifier(destination.clone().into_boxed_str()) + })?; } + + return Ok(identifier); } Err(HintError::UnknownIdentifier( @@ -204,44 +227,23 @@ pub fn get_identifier_from_scoped_name<'a>( )) } -pub fn get_constant_from_var_name<'a>( - var_name: &str, +pub fn get_constant_from_scoped_name<'a>( + scoped_name: &str, identifiers: &'a HashMap, accessible_scopes: &[String], ) -> Result<&'a Felt252, HintError> { - for scope in accessible_scopes.iter().rev() { - let full_path = format!("{}.{}", scope, var_name); - let identifier = identifiers.get(&full_path); - - let Some(identifier) = identifier else { - continue; - }; - - let identifier_type = identifier - .type_ + let identifier = get_identifier_from_scoped_name(scoped_name, identifiers, accessible_scopes)?; + + if identifier.type_.as_deref() != Some("const") { + Err(HintError::MissingConstant(Box::new( + scoped_name.to_string(), + ))) + } else { + identifier + .value .as_ref() - .ok_or_else(|| HintError::MissingConstant(Box::new(var_name.to_string())))?; - - match &identifier_type[..] { - "const" => { - return identifier - .value - .as_ref() - .ok_or_else(|| HintError::MissingConstant(Box::new(var_name.to_string()))) - } - "alias" => { - let destination = identifier - .destination - .as_ref() - .ok_or_else(|| HintError::MissingConstant(Box::new(var_name.to_string())))?; - - return get_constant_from_alias(destination, identifiers); - } - _ => return Err(HintError::MissingConstant(Box::new(var_name.to_string()))), - } + .ok_or_else(|| HintError::MissingConstant(Box::new(scoped_name.to_string()))) } - - Err(HintError::MissingConstant(Box::new(var_name.to_string()))) } pub fn get_constant_from_alias<'a>( @@ -474,4 +476,42 @@ mod tests { Err(HintError::UnknownIdentifier(bx)) if bx.as_ref() == "constant1.constant2" ); } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn get_identifier_from_scoped_name_with_alias() { + let accessible_scopes = &["scope1".to_string(), "scope1.scope2".to_string()]; + + let identifier = const_identifier(5); + let alias = alias_identifier("scope3.constant1"); + + let identifiers = HashMap::from([ + ("scope1.scope2.alias1".to_string(), alias.clone()), + ("scope3.constant1".to_string(), identifier.clone()), + ]); + + assert_matches!( + get_identifier_from_scoped_name("alias1", &identifiers, accessible_scopes), + Ok(id) if id == &identifier + ); + } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn get_identifier_from_scoped_name_with_cyclic_alias() { + let accessible_scopes = &["scope1".to_string(), "scope1.scope2".to_string()]; + + let alias1 = alias_identifier("scope3.alias2"); + let alias2 = alias_identifier("scope1.scope2.alias1"); + + let identifiers = HashMap::from([ + ("scope1.scope2.alias1".to_string(), alias1.clone()), + ("scope3.alias2".to_string(), alias2.clone()), + ]); + + assert_matches!( + get_identifier_from_scoped_name("alias1", &identifiers, accessible_scopes), + Err(HintError::CyclicAliasing) + ); + } } diff --git a/vm/src/hint_processor/builtin_hint_processor/keccak_utils.rs b/vm/src/hint_processor/builtin_hint_processor/keccak_utils.rs index 15c8db6b19..8a646d376a 100644 --- a/vm/src/hint_processor/builtin_hint_processor/keccak_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/keccak_utils.rs @@ -19,7 +19,7 @@ use num_integer::Integer; use num_traits::ToPrimitive; use sha3::{Digest, Keccak256}; -use super::hint_utils::{get_constant_from_var_name, insert_value_from_var_name}; +use super::hint_utils::{get_constant_from_scoped_name, insert_value_from_var_name}; /* Implements hint: %{ @@ -247,7 +247,7 @@ pub fn split_n_bytes( .ok_or_else(|| HintError::Math(MathError::Felt252ToU64Conversion(Box::new(x)))) })?; let bytes_in_word = - get_constant_from_var_name("BYTES_IN_WORD", identifiers, accessible_scopes)?; + get_constant_from_scoped_name("BYTES_IN_WORD", identifiers, accessible_scopes)?; let bytes_in_word = bytes_in_word .to_u64() .ok_or_else(|| MathError::Felt252ToU64Conversion(Box::new(*bytes_in_word)))?; diff --git a/vm/src/hint_processor/builtin_hint_processor/math_utils.rs b/vm/src/hint_processor/builtin_hint_processor/math_utils.rs index 7be2657fbf..d3381d5d81 100644 --- a/vm/src/hint_processor/builtin_hint_processor/math_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/math_utils.rs @@ -1,5 +1,5 @@ use crate::{ - hint_processor::builtin_hint_processor::hint_utils::get_constant_from_var_name, + hint_processor::builtin_hint_processor::hint_utils::get_constant_from_scoped_name, math_utils::signed_felt, serde::deserialize_program::Identifier, stdlib::{boxed::Box, collections::HashMap, prelude::*}, @@ -93,9 +93,9 @@ pub fn assert_le_felt( accessible_scopes: &[String], ) -> Result<(), HintError> { let prime_over_3_high = - get_constant_from_var_name("PRIME_OVER_3_HIGH", identifiers, accessible_scopes)?; + get_constant_from_scoped_name("PRIME_OVER_3_HIGH", identifiers, accessible_scopes)?; let prime_over_2_high = - get_constant_from_var_name("PRIME_OVER_2_HIGH", identifiers, accessible_scopes)?; + get_constant_from_scoped_name("PRIME_OVER_2_HIGH", identifiers, accessible_scopes)?; let a = get_integer_from_var_name("a", vm, ids_data, ap_tracking)?.to_biguint(); let b = get_integer_from_var_name("b", vm, ids_data, ap_tracking)?.to_biguint(); let range_check_ptr = get_ptr_from_var_name("range_check_ptr", vm, ids_data, ap_tracking)?; @@ -387,8 +387,8 @@ pub fn split_felt( .ok_or_else(|| HintError::AssertionFailed(msg.to_string().into_boxed_str())) }; let bound = pow2_const(128); - let max_high = get_constant_from_var_name("MAX_HIGH", identifiers, accessible_scopes)?; - let max_low = get_constant_from_var_name("MAX_LOW", identifiers, accessible_scopes)?; + let max_high = get_constant_from_scoped_name("MAX_HIGH", identifiers, accessible_scopes)?; + let max_low = get_constant_from_scoped_name("MAX_LOW", identifiers, accessible_scopes)?; assert( max_high < &bound && max_low < &bound, "assert ids.MAX_HIGH < 2**128 and ids.MAX_LOW < 2**128", @@ -521,8 +521,8 @@ pub fn assert_250_bit( accessible_scopes: &[String], ) -> Result<(), HintError> { //Declare constant values - let upper_bound = get_constant_from_var_name("UPPER_BOUND", identifiers, accessible_scopes)?; - let shift = get_constant_from_var_name("SHIFT", identifiers, accessible_scopes)?; + let upper_bound = get_constant_from_scoped_name("UPPER_BOUND", identifiers, accessible_scopes)?; + let shift = get_constant_from_scoped_name("SHIFT", identifiers, accessible_scopes)?; let value = Felt252::from(&signed_felt(get_integer_from_var_name( "value", vm, @@ -574,7 +574,7 @@ pub fn is_addr_bounded( let addr = get_integer_from_var_name("addr", vm, ids_data, ap_tracking)?; let addr_bound = - get_constant_from_var_name("ADDR_BOUND", identifiers, accessible_scopes)?.to_biguint(); + get_constant_from_scoped_name("ADDR_BOUND", identifiers, accessible_scopes)?.to_biguint(); let lower_bound = BigUint::one() << 250_usize; let upper_bound = BigUint::one() << 251_usize; @@ -2050,7 +2050,7 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::MissingConstant(bx)) if *bx == "ADDR_BOUND" + Err(HintError::UnknownIdentifier(bx)) if bx.as_ref() == "ADDR_BOUND" ); } @@ -2319,7 +2319,7 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::MissingConstant(x)) if (*x) == "MAX_HIGH" + Err(HintError::UnknownIdentifier(x)) if x.as_ref() == "MAX_HIGH" ); } diff --git a/vm/src/hint_processor/builtin_hint_processor/mod_circuit.rs b/vm/src/hint_processor/builtin_hint_processor/mod_circuit.rs index afbea39316..bc3d9763be 100644 --- a/vm/src/hint_processor/builtin_hint_processor/mod_circuit.rs +++ b/vm/src/hint_processor/builtin_hint_processor/mod_circuit.rs @@ -10,7 +10,7 @@ use crate::{ use num_traits::ToPrimitive; use super::hint_utils::{ - get_constant_from_var_name, get_integer_from_var_name, get_ptr_from_var_name, + get_constant_from_scoped_name, get_integer_from_var_name, get_ptr_from_var_name, }; /* Implements Hint: %{ @@ -54,7 +54,7 @@ pub fn run_p_mod_circuit_with_large_batch_size( identifiers: &HashMap, accessible_scopes: &[String], ) -> Result<(), HintError> { - let batch_size = get_constant_from_var_name("BATCH_SIZE", identifiers, accessible_scopes)?; + let batch_size = get_constant_from_scoped_name("BATCH_SIZE", identifiers, accessible_scopes)?; let batch_size = batch_size .to_usize() .ok_or_else(|| MathError::Felt252ToUsizeConversion(Box::new(*batch_size)))?; diff --git a/vm/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs b/vm/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs index c0de264bdf..fa9730e80c 100644 --- a/vm/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs @@ -1,6 +1,6 @@ use core::ops::Shl; -use crate::hint_processor::builtin_hint_processor::hint_utils::get_constant_from_var_name; +use crate::hint_processor::builtin_hint_processor::hint_utils::get_constant_from_scoped_name; use crate::hint_processor::builtin_hint_processor::uint_utils::{pack, split}; use crate::math_utils::signed_felt; use crate::serde::deserialize_program::Identifier; @@ -161,7 +161,7 @@ pub fn bigint_to_uint256( let d1 = vm.get_integer((x_struct + 1_i32)?)?; let d0 = d0.as_ref(); let d1 = d1.as_ref(); - let base_86 = get_constant_from_var_name("BASE", identifiers, accessible_scopes)?; + let base_86 = get_constant_from_scoped_name("BASE", identifiers, accessible_scopes)?; let mask = pow2_const_nz(128); let low = (d0 + (d1 * base_86)).mod_floor(mask); insert_value_from_var_name("low", low, vm, ids_data, ap_tracking) diff --git a/vm/src/hint_processor/builtin_hint_processor/secp/cairo0_hints.rs b/vm/src/hint_processor/builtin_hint_processor/secp/cairo0_hints.rs index 6725d3b5a2..758ba5a6a9 100644 --- a/vm/src/hint_processor/builtin_hint_processor/secp/cairo0_hints.rs +++ b/vm/src/hint_processor/builtin_hint_processor/secp/cairo0_hints.rs @@ -9,7 +9,7 @@ use crate::{ use crate::define_hint_string_map; use crate::hint_processor::builtin_hint_processor::hint_utils::{ - get_constant_from_var_name, get_integer_from_var_name, insert_value_from_var_name, + get_constant_from_scoped_name, get_integer_from_var_name, insert_value_from_var_name, }; use crate::hint_processor::builtin_hint_processor::uint256_utils::Uint256; use crate::hint_processor::hint_processor_definition::HintReference; @@ -176,8 +176,8 @@ pub fn compute_ids_high_low( ) -> Result<(), HintError> { exec_scopes.insert_value::("SECP256R1_P", SECP256R1_P.clone()); - let upper_bound = get_constant_from_var_name("UPPER_BOUND", identifiers, accessible_scopes)?; - let shift = get_constant_from_var_name("SHIFT", identifiers, accessible_scopes)?; + let upper_bound = get_constant_from_scoped_name("UPPER_BOUND", identifiers, accessible_scopes)?; + let shift = get_constant_from_scoped_name("SHIFT", identifiers, accessible_scopes)?; let value = Felt252::from(&signed_felt(get_integer_from_var_name( "value", vm, diff --git a/vm/src/hint_processor/builtin_hint_processor/secp/signature.rs b/vm/src/hint_processor/builtin_hint_processor/secp/signature.rs index 1bdeca1ab1..092a9af6c8 100644 --- a/vm/src/hint_processor/builtin_hint_processor/secp/signature.rs +++ b/vm/src/hint_processor/builtin_hint_processor/secp/signature.rs @@ -1,4 +1,4 @@ -use crate::hint_processor::builtin_hint_processor::hint_utils::get_constant_from_var_name; +use crate::hint_processor::builtin_hint_processor::hint_utils::get_constant_from_scoped_name; use crate::serde::deserialize_program::Identifier; use crate::{ any_box, @@ -111,7 +111,7 @@ pub fn get_point_from_x( accessible_scopes: &[String], ) -> Result<(), HintError> { exec_scopes.insert_value("SECP_P", SECP_P.clone()); - let beta = get_constant_from_var_name("BETA", identifiers, accessible_scopes)?.to_bigint(); + let beta = get_constant_from_scoped_name("BETA", identifiers, accessible_scopes)?.to_bigint(); let x_cube_int = Uint384::from_var_name("x_cube", vm, ids_data, ap_tracking)? .pack86() diff --git a/vm/src/hint_processor/builtin_hint_processor/sha256_utils.rs b/vm/src/hint_processor/builtin_hint_processor/sha256_utils.rs index 69beefcab8..c5aa429dc4 100644 --- a/vm/src/hint_processor/builtin_hint_processor/sha256_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/sha256_utils.rs @@ -20,7 +20,7 @@ use sha2::compress256; use crate::hint_processor::hint_processor_definition::HintReference; -use super::hint_utils::get_constant_from_var_name; +use super::hint_utils::get_constant_from_scoped_name; const SHA256_STATE_SIZE_FELTS: usize = 8; const BLOCK_SIZE: usize = 7; @@ -62,7 +62,7 @@ fn sha256_main( // The code gets the value from `ids.SHA256_INPUT_CHUNK_SIZE_FELTS` in both // constant and arbitrary input length cases. - let input_chunk_size_felts = get_constant_from_var_name( + let input_chunk_size_felts = get_constant_from_scoped_name( "SHA256_INPUT_CHUNK_SIZE_FELTS", identifiers, accessible_scopes, @@ -157,7 +157,7 @@ pub fn sha256_main_arbitrary_input_length( let iv_ptr = get_ptr_from_var_name("state", vm, ids_data, ap_tracking)?; let state_size_felt = - get_constant_from_var_name("SHA256_STATE_SIZE_FELTS", identifiers, accessible_scopes)?; + get_constant_from_scoped_name("SHA256_STATE_SIZE_FELTS", identifiers, accessible_scopes)?; let state_size = match state_size_felt.to_usize() { Some(size) if size == SHA256_STATE_SIZE_FELTS => size, diff --git a/vm/src/hint_processor/builtin_hint_processor/uint384.rs b/vm/src/hint_processor/builtin_hint_processor/uint384.rs index 5c10ba4928..af8aaaeac0 100644 --- a/vm/src/hint_processor/builtin_hint_processor/uint384.rs +++ b/vm/src/hint_processor/builtin_hint_processor/uint384.rs @@ -15,7 +15,7 @@ use crate::{ }; use super::hint_utils::{ - get_constant_from_var_name, get_integer_from_var_name, get_relocatable_from_var_name, + get_constant_from_scoped_name, get_integer_from_var_name, get_relocatable_from_var_name, insert_value_from_var_name, insert_value_into_ap, }; use super::secp::bigint_utils::Uint384; @@ -109,7 +109,8 @@ pub fn add_no_uint384_check( let a = Uint384::from_var_name("a", vm, ids_data, ap_tracking)?; let b = Uint384::from_var_name("b", vm, ids_data, ap_tracking)?; // This hint is not from the cairo commonlib, and its lib can be found under different paths, so we cant rely on a full path name - let shift = get_constant_from_var_name("SHIFT", identifiers, accessible_scopes)?.to_biguint(); + let shift = + get_constant_from_scoped_name("SHIFT", identifiers, accessible_scopes)?.to_biguint(); let sum_d0 = (a.limbs[0].as_ref().to_biguint()) + (b.limbs[0].as_ref().to_biguint()); let carry_d0 = BigUint::from((sum_d0 >= shift) as usize); @@ -547,7 +548,7 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code::ADD_NO_UINT384_CHECK), - Err(HintError::MissingConstant(bx)) if *bx == "SHIFT" + Err(HintError::UnknownIdentifier(x)) if x.as_ref() == "SHIFT" ); } diff --git a/vm/src/utils.rs b/vm/src/utils.rs index ec53804e4b..c9fc4000a9 100644 --- a/vm/src/utils.rs +++ b/vm/src/utils.rs @@ -487,6 +487,18 @@ pub mod test_utils { destination: None, } } + pub fn alias_identifier(destination: impl Into) -> Identifier { + Identifier { + pc: None, + type_: Some(String::from("alias")), + value: None, + full_name: None, + members: None, + cairo_type: None, + size: None, + destination: Some(destination.into()), + } + } macro_rules! run_hint { ($vm:expr, $ids_data:expr, $hint_code:expr, $exec_scopes:expr, $identifiers:expr, $accessible_scopes:expr) => {{ diff --git a/vm/src/vm/errors/hint_errors.rs b/vm/src/vm/errors/hint_errors.rs index 050a400d46..c11f7a1d0b 100644 --- a/vm/src/vm/errors/hint_errors.rs +++ b/vm/src/vm/errors/hint_errors.rs @@ -42,6 +42,8 @@ pub enum HintError { UnknownIdentifierInternal, #[error("Wrong identifier type")] WrongIdentifierTypeInternal, + #[error("Encountered cyclic aliasing")] + CyclicAliasing, #[error("Hint Error: {0}")] CustomHint(Box), #[error("Missing constant: {0}")] From e2dfdb26570cfd32279b8f95aebf209d6a6d9ee0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Thu, 11 Sep 2025 15:58:01 -0300 Subject: [PATCH 13/20] Remove unused function! --- .../builtin_hint_processor/hint_utils.rs | 32 ------------------- 1 file changed, 32 deletions(-) diff --git a/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs b/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs index 7fdb9a1705..a8d252c8f9 100644 --- a/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs @@ -246,38 +246,6 @@ pub fn get_constant_from_scoped_name<'a>( } } -pub fn get_constant_from_alias<'a>( - destination: &str, - identifiers: &'a HashMap, -) -> Result<&'a Felt252, HintError> { - let identifier = identifiers - .get(destination) - .ok_or_else(|| HintError::MissingConstant(Box::new(destination.to_string())))?; - - let identifier_type = identifier - .type_ - .as_ref() - .ok_or_else(|| HintError::MissingConstant(Box::new(destination.to_string())))?; - - match &identifier_type[..] { - "const" => identifier - .value - .as_ref() - .ok_or_else(|| HintError::MissingConstant(Box::new(destination.to_string()))), - "alias" => { - let destination = identifier - .destination - .as_ref() - .ok_or_else(|| HintError::MissingConstant(Box::new(destination.to_string())))?; - - get_constant_from_alias(destination, identifiers) - } - _ => Err(HintError::MissingConstant(Box::new( - destination.to_string(), - ))), - } -} - #[cfg(test)] mod tests { use super::*; From 04524d0b89c0160d0d3030f133d9a434ba6d96d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Thu, 11 Sep 2025 15:58:42 -0300 Subject: [PATCH 14/20] Use stdlib HashSet --- .../hint_processor/builtin_hint_processor/hint_utils.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs b/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs index a8d252c8f9..91d19d2025 100644 --- a/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs @@ -1,6 +1,8 @@ -use hashbrown::HashSet; - -use crate::stdlib::{boxed::Box, collections::HashMap, prelude::*}; +use crate::stdlib::{ + boxed::Box, + collections::{HashMap, HashSet}, + prelude::*, +}; use crate::Felt252; From 1225b2d4ae6bfa83060e6f2d1f16d7c58850f67c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Thu, 11 Sep 2025 16:34:49 -0300 Subject: [PATCH 15/20] Add box --- vm/src/hint_processor/builtin_hint_processor/mod_circuit.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/src/hint_processor/builtin_hint_processor/mod_circuit.rs b/vm/src/hint_processor/builtin_hint_processor/mod_circuit.rs index bc3d9763be..d7013a36c5 100644 --- a/vm/src/hint_processor/builtin_hint_processor/mod_circuit.rs +++ b/vm/src/hint_processor/builtin_hint_processor/mod_circuit.rs @@ -1,5 +1,5 @@ use crate::serde::deserialize_program::Identifier; -use crate::stdlib::prelude::String; +use crate::stdlib::prelude::{Box, String}; use crate::types::errors::math_errors::MathError; use crate::{ hint_processor::hint_processor_definition::HintReference, From d993cac576687f68e02f545bd8172ca308aa576a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Thu, 11 Sep 2025 17:46:32 -0300 Subject: [PATCH 16/20] Replace break with return for clarity --- vm/src/hint_processor/builtin_hint_processor/hint_utils.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs b/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs index 91d19d2025..66ed59ccf1 100644 --- a/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs @@ -195,7 +195,9 @@ pub fn get_identifier_from_scoped_name<'a>( .get(&format!("{}.{}", scope, first_component)) .is_some() { - break; + return Err(HintError::UnknownIdentifier( + scoped_name.to_string().into_boxed_str(), + )); } } From 43439767b973f3357776467f1fc7336e95c1e66c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Fri, 12 Sep 2025 16:29:41 -0300 Subject: [PATCH 17/20] Restore split_felt_bad_constants --- cairo_programs/bad_programs/split_felt_bad_constants.cairo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cairo_programs/bad_programs/split_felt_bad_constants.cairo b/cairo_programs/bad_programs/split_felt_bad_constants.cairo index 70291950a3..a051291886 100644 --- a/cairo_programs/bad_programs/split_felt_bad_constants.cairo +++ b/cairo_programs/bad_programs/split_felt_bad_constants.cairo @@ -3,10 +3,10 @@ const MAX_LOW = 1; func main() { let value =1; - hint_func(value); + hint_func(MAX_HIGH, MAX_LOW, value); return(); } -func hint_func(value: felt) -> (felt, felt) { +func hint_func(MAX_HIGH: felt, MAX_LOW: felt, value: felt) -> (felt, felt) { alloc_locals; local low: felt; local high: felt; From f62696e6d0d32566f3d6118fed0464f1142ae8b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Fri, 12 Sep 2025 16:30:01 -0300 Subject: [PATCH 18/20] Only take into account constants and aliases --- .../builtin_hint_processor/hint_utils.rs | 48 +++++-------------- 1 file changed, 12 insertions(+), 36 deletions(-) diff --git a/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs b/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs index 66ed59ccf1..38b1a26972 100644 --- a/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs @@ -178,29 +178,16 @@ pub fn get_reference_from_var_name<'a>( .ok_or_else(|| HintError::UnknownIdentifier(Box::::from(var_name))) } -pub fn get_identifier_from_scoped_name<'a>( +pub fn get_constant_from_scoped_name<'a>( scoped_name: &str, identifiers: &'a HashMap, accessible_scopes: &[String], -) -> Result<&'a Identifier, HintError> { +) -> Result<&'a Felt252, HintError> { + // Inner scopes override outer scopes. for scope in accessible_scopes.iter().rev() { let full_path = format!("{}.{}", scope, scoped_name); let Some(mut identifier) = identifiers.get(&full_path) else { - // The scoped_name can itself contain multiple components (i.e. a.b.c). - // If there is a match for at least the first component, we should - // not continue with the next scope. - if let Some(first_component) = scoped_name.split('.').next() { - if identifiers - .get(&format!("{}.{}", scope, first_component)) - .is_some() - { - return Err(HintError::UnknownIdentifier( - scoped_name.to_string().into_boxed_str(), - )); - } - } - continue; }; @@ -223,7 +210,15 @@ pub fn get_identifier_from_scoped_name<'a>( })?; } - return Ok(identifier); + // As are only looking for constants, we ignore any other identifiers. + if identifier.type_.as_deref() != Some("const") { + continue; + } + + return identifier + .value + .as_ref() + .ok_or_else(|| HintError::UnknownIdentifierInternal); } Err(HintError::UnknownIdentifier( @@ -231,25 +226,6 @@ pub fn get_identifier_from_scoped_name<'a>( )) } -pub fn get_constant_from_scoped_name<'a>( - scoped_name: &str, - identifiers: &'a HashMap, - accessible_scopes: &[String], -) -> Result<&'a Felt252, HintError> { - let identifier = get_identifier_from_scoped_name(scoped_name, identifiers, accessible_scopes)?; - - if identifier.type_.as_deref() != Some("const") { - Err(HintError::MissingConstant(Box::new( - scoped_name.to_string(), - ))) - } else { - identifier - .value - .as_ref() - .ok_or_else(|| HintError::MissingConstant(Box::new(scoped_name.to_string()))) - } -} - #[cfg(test)] mod tests { use super::*; From a874df7d17aefa48a228e3b4c09fa307bf8affc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Fri, 12 Sep 2025 16:50:09 -0300 Subject: [PATCH 19/20] Rename function! --- .../cairo_keccak/keccak_hints.rs | 14 +++--- .../builtin_hint_processor/excess_balance.rs | 4 +- .../builtin_hint_processor/hint_utils.rs | 49 ++++++------------- .../builtin_hint_processor/keccak_utils.rs | 4 +- .../builtin_hint_processor/math_utils.rs | 16 +++--- .../builtin_hint_processor/mod_circuit.rs | 4 +- .../secp/bigint_utils.rs | 4 +- .../secp/cairo0_hints.rs | 6 +-- .../builtin_hint_processor/secp/signature.rs | 4 +- .../builtin_hint_processor/sha256_utils.rs | 6 +-- .../builtin_hint_processor/uint384.rs | 4 +- 11 files changed, 47 insertions(+), 68 deletions(-) diff --git a/vm/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs b/vm/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs index 645859f7c5..fe3376d301 100644 --- a/vm/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs +++ b/vm/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs @@ -1,5 +1,5 @@ use crate::{ - hint_processor::builtin_hint_processor::hint_utils::get_constant_from_scoped_name, + hint_processor::builtin_hint_processor::hint_utils::get_constant_from_var_name, serde::deserialize_program::Identifier, stdlib::{ borrow::{Cow, ToOwned}, @@ -81,7 +81,7 @@ pub fn compare_bytes_in_word_nondet( // or too big, which also means n_bytes > BYTES_IN_WORD). The other option is to exctract // Felt252::from(BYTES_INTO_WORD) into a lazy_static! let bytes_in_word = - get_constant_from_scoped_name("BYTES_IN_WORD", identifiers, accessible_scopes)?; + get_constant_from_var_name("BYTES_IN_WORD", identifiers, accessible_scopes)?; let value = Felt252::from((n_bytes < bytes_in_word) as usize); insert_value_into_ap(vm, value) } @@ -105,7 +105,7 @@ pub fn compare_keccak_full_rate_in_bytes_nondet( let n_bytes = n_bytes.as_ref(); let keccak_full_rate_in_bytes = - get_constant_from_scoped_name("KECCAK_FULL_RATE_IN_BYTES", identifiers, accessible_scopes)?; + get_constant_from_var_name("KECCAK_FULL_RATE_IN_BYTES", identifiers, accessible_scopes)?; let value = Felt252::from((n_bytes >= keccak_full_rate_in_bytes) as usize); insert_value_into_ap(vm, value) } @@ -139,7 +139,7 @@ pub(crate) fn block_permutation_v1( accessible_scopes: &[String], ) -> Result<(), HintError> { let keccak_state_size_felts = - get_constant_from_scoped_name("KECCAK_STATE_SIZE_FELTS", identifiers, accessible_scopes)?; + get_constant_from_var_name("KECCAK_STATE_SIZE_FELTS", identifiers, accessible_scopes)?; if keccak_state_size_felts >= &Felt252::from(100_i32) { return Err(HintError::InvalidKeccakStateSizeFelt252s(Box::new( *keccak_state_size_felts, @@ -206,7 +206,7 @@ pub(crate) fn block_permutation_v2( accessible_scopes: &[String], ) -> Result<(), HintError> { let keccak_state_size_felts = - get_constant_from_scoped_name("KECCAK_STATE_SIZE_FELTS", identifiers, accessible_scopes)?; + get_constant_from_var_name("KECCAK_STATE_SIZE_FELTS", identifiers, accessible_scopes)?; if keccak_state_size_felts >= &Felt252::from(100_i32) { return Err(HintError::InvalidKeccakStateSizeFelt252s(Box::new( *keccak_state_size_felts, @@ -243,8 +243,8 @@ fn cairo_keccak_finalize( block_size_limit: usize, ) -> Result<(), HintError> { let keccak_state_size_felts = - get_constant_from_scoped_name("KECCAK_STATE_SIZE_FELTS", identifiers, accessible_scopes)?; - let block_size = get_constant_from_scoped_name("BLOCK_SIZE", identifiers, accessible_scopes)?; + get_constant_from_var_name("KECCAK_STATE_SIZE_FELTS", identifiers, accessible_scopes)?; + let block_size = get_constant_from_var_name("BLOCK_SIZE", identifiers, accessible_scopes)?; if keccak_state_size_felts >= &Felt252::from(100_i32) { return Err(HintError::InvalidKeccakStateSizeFelt252s(Box::new( diff --git a/vm/src/hint_processor/builtin_hint_processor/excess_balance.rs b/vm/src/hint_processor/builtin_hint_processor/excess_balance.rs index f8fb2fb382..247e56b944 100644 --- a/vm/src/hint_processor/builtin_hint_processor/excess_balance.rs +++ b/vm/src/hint_processor/builtin_hint_processor/excess_balance.rs @@ -22,7 +22,7 @@ use lazy_static::lazy_static; use super::{ dict_manager::DictManager, hint_utils::{ - get_constant_from_scoped_name, get_integer_from_var_name, get_ptr_from_var_name, + get_constant_from_var_name, get_integer_from_var_name, get_ptr_from_var_name, insert_value_from_var_name, }, }; @@ -270,7 +270,7 @@ pub fn excess_balance_hint( let margin_check_type = get_integer_from_var_name("margin_check_type", vm, ids_data, ap_tracking)?; let margin_check_initial = - get_constant_from_scoped_name("MARGIN_CHECK_INITIAL", identifiers, accessible_scopes)?; + get_constant_from_var_name("MARGIN_CHECK_INITIAL", identifiers, accessible_scopes)?; let token_assets_value_d = get_integer_from_var_name("token_assets_value_d", vm, ids_data, ap_tracking)?; let account = get_integer_from_var_name("account", vm, ids_data, ap_tracking)?; diff --git a/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs b/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs index 38b1a26972..3bb66a96fc 100644 --- a/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/hint_utils.rs @@ -178,7 +178,7 @@ pub fn get_reference_from_var_name<'a>( .ok_or_else(|| HintError::UnknownIdentifier(Box::::from(var_name))) } -pub fn get_constant_from_scoped_name<'a>( +pub fn get_constant_from_var_name<'a>( scoped_name: &str, identifiers: &'a HashMap, accessible_scopes: &[String], @@ -369,7 +369,7 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn get_identifier_from_scoped_name_valid() { + fn get_constant_from_var_name_valid() { let accessible_scopes = &["scope1".to_string(), "scope1.scope2".to_string()]; let identifier = const_identifier(5); @@ -379,15 +379,16 @@ mod tests { identifier.clone(), )]); - assert_matches!( - get_identifier_from_scoped_name("constant1.constant2", &identifiers, accessible_scopes), - Ok(id) if id == &identifier + assert_eq!( + *get_constant_from_var_name("constant1.constant2", &identifiers, accessible_scopes) + .unwrap(), + Felt252::from(5) ); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn get_identifier_from_scoped_name_invalid() { + fn get_constant_from_var_name_invalid() { let accessible_scopes = &["scope1".to_string(), "scope1.scope2".to_string()]; let identifier = const_identifier(5); @@ -398,36 +399,14 @@ mod tests { )]); assert_matches!( - get_identifier_from_scoped_name("constant1.constant2", &identifiers, accessible_scopes), - Err(HintError::UnknownIdentifier(bx)) if bx.as_ref() == "constant1.constant2" - ); - } - - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn get_identifier_from_scoped_name_invalid_partial_match() { - let accessible_scopes = &["scope1".to_string(), "scope1.scope2".to_string()]; - - let identifier = const_identifier(5); - - let identifiers = HashMap::from([ - ("scope1.scope2.constant1".to_string(), identifier.clone()), - ("scope1.constant1.constant2".to_string(), identifier.clone()), - ( - "scope1.scope2.constant1.constant3".to_string(), - identifier.clone(), - ), - ]); - - assert_matches!( - get_identifier_from_scoped_name("constant1.constant2", &identifiers, accessible_scopes), + get_constant_from_var_name("constant1.constant2", &identifiers, accessible_scopes), Err(HintError::UnknownIdentifier(bx)) if bx.as_ref() == "constant1.constant2" ); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn get_identifier_from_scoped_name_with_alias() { + fn get_constant_from_var_name_with_alias() { let accessible_scopes = &["scope1".to_string(), "scope1.scope2".to_string()]; let identifier = const_identifier(5); @@ -438,15 +417,15 @@ mod tests { ("scope3.constant1".to_string(), identifier.clone()), ]); - assert_matches!( - get_identifier_from_scoped_name("alias1", &identifiers, accessible_scopes), - Ok(id) if id == &identifier + assert_eq!( + *get_constant_from_var_name("alias1", &identifiers, accessible_scopes).unwrap(), + Felt252::from(5) ); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn get_identifier_from_scoped_name_with_cyclic_alias() { + fn get_constant_from_var_name_with_cyclic_alias() { let accessible_scopes = &["scope1".to_string(), "scope1.scope2".to_string()]; let alias1 = alias_identifier("scope3.alias2"); @@ -458,7 +437,7 @@ mod tests { ]); assert_matches!( - get_identifier_from_scoped_name("alias1", &identifiers, accessible_scopes), + get_constant_from_var_name("alias1", &identifiers, accessible_scopes), Err(HintError::CyclicAliasing) ); } diff --git a/vm/src/hint_processor/builtin_hint_processor/keccak_utils.rs b/vm/src/hint_processor/builtin_hint_processor/keccak_utils.rs index 8a646d376a..15c8db6b19 100644 --- a/vm/src/hint_processor/builtin_hint_processor/keccak_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/keccak_utils.rs @@ -19,7 +19,7 @@ use num_integer::Integer; use num_traits::ToPrimitive; use sha3::{Digest, Keccak256}; -use super::hint_utils::{get_constant_from_scoped_name, insert_value_from_var_name}; +use super::hint_utils::{get_constant_from_var_name, insert_value_from_var_name}; /* Implements hint: %{ @@ -247,7 +247,7 @@ pub fn split_n_bytes( .ok_or_else(|| HintError::Math(MathError::Felt252ToU64Conversion(Box::new(x)))) })?; let bytes_in_word = - get_constant_from_scoped_name("BYTES_IN_WORD", identifiers, accessible_scopes)?; + get_constant_from_var_name("BYTES_IN_WORD", identifiers, accessible_scopes)?; let bytes_in_word = bytes_in_word .to_u64() .ok_or_else(|| MathError::Felt252ToU64Conversion(Box::new(*bytes_in_word)))?; diff --git a/vm/src/hint_processor/builtin_hint_processor/math_utils.rs b/vm/src/hint_processor/builtin_hint_processor/math_utils.rs index d3381d5d81..9fad48b918 100644 --- a/vm/src/hint_processor/builtin_hint_processor/math_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/math_utils.rs @@ -1,5 +1,5 @@ use crate::{ - hint_processor::builtin_hint_processor::hint_utils::get_constant_from_scoped_name, + hint_processor::builtin_hint_processor::hint_utils::get_constant_from_var_name, math_utils::signed_felt, serde::deserialize_program::Identifier, stdlib::{boxed::Box, collections::HashMap, prelude::*}, @@ -93,9 +93,9 @@ pub fn assert_le_felt( accessible_scopes: &[String], ) -> Result<(), HintError> { let prime_over_3_high = - get_constant_from_scoped_name("PRIME_OVER_3_HIGH", identifiers, accessible_scopes)?; + get_constant_from_var_name("PRIME_OVER_3_HIGH", identifiers, accessible_scopes)?; let prime_over_2_high = - get_constant_from_scoped_name("PRIME_OVER_2_HIGH", identifiers, accessible_scopes)?; + get_constant_from_var_name("PRIME_OVER_2_HIGH", identifiers, accessible_scopes)?; let a = get_integer_from_var_name("a", vm, ids_data, ap_tracking)?.to_biguint(); let b = get_integer_from_var_name("b", vm, ids_data, ap_tracking)?.to_biguint(); let range_check_ptr = get_ptr_from_var_name("range_check_ptr", vm, ids_data, ap_tracking)?; @@ -387,8 +387,8 @@ pub fn split_felt( .ok_or_else(|| HintError::AssertionFailed(msg.to_string().into_boxed_str())) }; let bound = pow2_const(128); - let max_high = get_constant_from_scoped_name("MAX_HIGH", identifiers, accessible_scopes)?; - let max_low = get_constant_from_scoped_name("MAX_LOW", identifiers, accessible_scopes)?; + let max_high = get_constant_from_var_name("MAX_HIGH", identifiers, accessible_scopes)?; + let max_low = get_constant_from_var_name("MAX_LOW", identifiers, accessible_scopes)?; assert( max_high < &bound && max_low < &bound, "assert ids.MAX_HIGH < 2**128 and ids.MAX_LOW < 2**128", @@ -521,8 +521,8 @@ pub fn assert_250_bit( accessible_scopes: &[String], ) -> Result<(), HintError> { //Declare constant values - let upper_bound = get_constant_from_scoped_name("UPPER_BOUND", identifiers, accessible_scopes)?; - let shift = get_constant_from_scoped_name("SHIFT", identifiers, accessible_scopes)?; + let upper_bound = get_constant_from_var_name("UPPER_BOUND", identifiers, accessible_scopes)?; + let shift = get_constant_from_var_name("SHIFT", identifiers, accessible_scopes)?; let value = Felt252::from(&signed_felt(get_integer_from_var_name( "value", vm, @@ -574,7 +574,7 @@ pub fn is_addr_bounded( let addr = get_integer_from_var_name("addr", vm, ids_data, ap_tracking)?; let addr_bound = - get_constant_from_scoped_name("ADDR_BOUND", identifiers, accessible_scopes)?.to_biguint(); + get_constant_from_var_name("ADDR_BOUND", identifiers, accessible_scopes)?.to_biguint(); let lower_bound = BigUint::one() << 250_usize; let upper_bound = BigUint::one() << 251_usize; diff --git a/vm/src/hint_processor/builtin_hint_processor/mod_circuit.rs b/vm/src/hint_processor/builtin_hint_processor/mod_circuit.rs index d7013a36c5..93017dfd61 100644 --- a/vm/src/hint_processor/builtin_hint_processor/mod_circuit.rs +++ b/vm/src/hint_processor/builtin_hint_processor/mod_circuit.rs @@ -10,7 +10,7 @@ use crate::{ use num_traits::ToPrimitive; use super::hint_utils::{ - get_constant_from_scoped_name, get_integer_from_var_name, get_ptr_from_var_name, + get_constant_from_var_name, get_integer_from_var_name, get_ptr_from_var_name, }; /* Implements Hint: %{ @@ -54,7 +54,7 @@ pub fn run_p_mod_circuit_with_large_batch_size( identifiers: &HashMap, accessible_scopes: &[String], ) -> Result<(), HintError> { - let batch_size = get_constant_from_scoped_name("BATCH_SIZE", identifiers, accessible_scopes)?; + let batch_size = get_constant_from_var_name("BATCH_SIZE", identifiers, accessible_scopes)?; let batch_size = batch_size .to_usize() .ok_or_else(|| MathError::Felt252ToUsizeConversion(Box::new(*batch_size)))?; diff --git a/vm/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs b/vm/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs index fa9730e80c..c0de264bdf 100644 --- a/vm/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs @@ -1,6 +1,6 @@ use core::ops::Shl; -use crate::hint_processor::builtin_hint_processor::hint_utils::get_constant_from_scoped_name; +use crate::hint_processor::builtin_hint_processor::hint_utils::get_constant_from_var_name; use crate::hint_processor::builtin_hint_processor::uint_utils::{pack, split}; use crate::math_utils::signed_felt; use crate::serde::deserialize_program::Identifier; @@ -161,7 +161,7 @@ pub fn bigint_to_uint256( let d1 = vm.get_integer((x_struct + 1_i32)?)?; let d0 = d0.as_ref(); let d1 = d1.as_ref(); - let base_86 = get_constant_from_scoped_name("BASE", identifiers, accessible_scopes)?; + let base_86 = get_constant_from_var_name("BASE", identifiers, accessible_scopes)?; let mask = pow2_const_nz(128); let low = (d0 + (d1 * base_86)).mod_floor(mask); insert_value_from_var_name("low", low, vm, ids_data, ap_tracking) diff --git a/vm/src/hint_processor/builtin_hint_processor/secp/cairo0_hints.rs b/vm/src/hint_processor/builtin_hint_processor/secp/cairo0_hints.rs index 758ba5a6a9..6725d3b5a2 100644 --- a/vm/src/hint_processor/builtin_hint_processor/secp/cairo0_hints.rs +++ b/vm/src/hint_processor/builtin_hint_processor/secp/cairo0_hints.rs @@ -9,7 +9,7 @@ use crate::{ use crate::define_hint_string_map; use crate::hint_processor::builtin_hint_processor::hint_utils::{ - get_constant_from_scoped_name, get_integer_from_var_name, insert_value_from_var_name, + get_constant_from_var_name, get_integer_from_var_name, insert_value_from_var_name, }; use crate::hint_processor::builtin_hint_processor::uint256_utils::Uint256; use crate::hint_processor::hint_processor_definition::HintReference; @@ -176,8 +176,8 @@ pub fn compute_ids_high_low( ) -> Result<(), HintError> { exec_scopes.insert_value::("SECP256R1_P", SECP256R1_P.clone()); - let upper_bound = get_constant_from_scoped_name("UPPER_BOUND", identifiers, accessible_scopes)?; - let shift = get_constant_from_scoped_name("SHIFT", identifiers, accessible_scopes)?; + let upper_bound = get_constant_from_var_name("UPPER_BOUND", identifiers, accessible_scopes)?; + let shift = get_constant_from_var_name("SHIFT", identifiers, accessible_scopes)?; let value = Felt252::from(&signed_felt(get_integer_from_var_name( "value", vm, diff --git a/vm/src/hint_processor/builtin_hint_processor/secp/signature.rs b/vm/src/hint_processor/builtin_hint_processor/secp/signature.rs index 092a9af6c8..1bdeca1ab1 100644 --- a/vm/src/hint_processor/builtin_hint_processor/secp/signature.rs +++ b/vm/src/hint_processor/builtin_hint_processor/secp/signature.rs @@ -1,4 +1,4 @@ -use crate::hint_processor::builtin_hint_processor::hint_utils::get_constant_from_scoped_name; +use crate::hint_processor::builtin_hint_processor::hint_utils::get_constant_from_var_name; use crate::serde::deserialize_program::Identifier; use crate::{ any_box, @@ -111,7 +111,7 @@ pub fn get_point_from_x( accessible_scopes: &[String], ) -> Result<(), HintError> { exec_scopes.insert_value("SECP_P", SECP_P.clone()); - let beta = get_constant_from_scoped_name("BETA", identifiers, accessible_scopes)?.to_bigint(); + let beta = get_constant_from_var_name("BETA", identifiers, accessible_scopes)?.to_bigint(); let x_cube_int = Uint384::from_var_name("x_cube", vm, ids_data, ap_tracking)? .pack86() diff --git a/vm/src/hint_processor/builtin_hint_processor/sha256_utils.rs b/vm/src/hint_processor/builtin_hint_processor/sha256_utils.rs index c5aa429dc4..69beefcab8 100644 --- a/vm/src/hint_processor/builtin_hint_processor/sha256_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/sha256_utils.rs @@ -20,7 +20,7 @@ use sha2::compress256; use crate::hint_processor::hint_processor_definition::HintReference; -use super::hint_utils::get_constant_from_scoped_name; +use super::hint_utils::get_constant_from_var_name; const SHA256_STATE_SIZE_FELTS: usize = 8; const BLOCK_SIZE: usize = 7; @@ -62,7 +62,7 @@ fn sha256_main( // The code gets the value from `ids.SHA256_INPUT_CHUNK_SIZE_FELTS` in both // constant and arbitrary input length cases. - let input_chunk_size_felts = get_constant_from_scoped_name( + let input_chunk_size_felts = get_constant_from_var_name( "SHA256_INPUT_CHUNK_SIZE_FELTS", identifiers, accessible_scopes, @@ -157,7 +157,7 @@ pub fn sha256_main_arbitrary_input_length( let iv_ptr = get_ptr_from_var_name("state", vm, ids_data, ap_tracking)?; let state_size_felt = - get_constant_from_scoped_name("SHA256_STATE_SIZE_FELTS", identifiers, accessible_scopes)?; + get_constant_from_var_name("SHA256_STATE_SIZE_FELTS", identifiers, accessible_scopes)?; let state_size = match state_size_felt.to_usize() { Some(size) if size == SHA256_STATE_SIZE_FELTS => size, diff --git a/vm/src/hint_processor/builtin_hint_processor/uint384.rs b/vm/src/hint_processor/builtin_hint_processor/uint384.rs index af8aaaeac0..bf99ae0835 100644 --- a/vm/src/hint_processor/builtin_hint_processor/uint384.rs +++ b/vm/src/hint_processor/builtin_hint_processor/uint384.rs @@ -15,7 +15,7 @@ use crate::{ }; use super::hint_utils::{ - get_constant_from_scoped_name, get_integer_from_var_name, get_relocatable_from_var_name, + get_constant_from_var_name, get_integer_from_var_name, get_relocatable_from_var_name, insert_value_from_var_name, insert_value_into_ap, }; use super::secp::bigint_utils::Uint384; @@ -110,7 +110,7 @@ pub fn add_no_uint384_check( let b = Uint384::from_var_name("b", vm, ids_data, ap_tracking)?; // This hint is not from the cairo commonlib, and its lib can be found under different paths, so we cant rely on a full path name let shift = - get_constant_from_scoped_name("SHIFT", identifiers, accessible_scopes)?.to_biguint(); + get_constant_from_var_name("SHIFT", identifiers, accessible_scopes)?.to_biguint(); let sum_d0 = (a.limbs[0].as_ref().to_biguint()) + (b.limbs[0].as_ref().to_biguint()); let carry_d0 = BigUint::from((sum_d0 >= shift) as usize); From 93be705ceea6af4957e8e2e29b01073b210aadff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Fri, 12 Sep 2025 17:00:18 -0300 Subject: [PATCH 20/20] Format --- vm/src/hint_processor/builtin_hint_processor/uint384.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vm/src/hint_processor/builtin_hint_processor/uint384.rs b/vm/src/hint_processor/builtin_hint_processor/uint384.rs index bf99ae0835..ebfc9e777d 100644 --- a/vm/src/hint_processor/builtin_hint_processor/uint384.rs +++ b/vm/src/hint_processor/builtin_hint_processor/uint384.rs @@ -109,8 +109,7 @@ pub fn add_no_uint384_check( let a = Uint384::from_var_name("a", vm, ids_data, ap_tracking)?; let b = Uint384::from_var_name("b", vm, ids_data, ap_tracking)?; // This hint is not from the cairo commonlib, and its lib can be found under different paths, so we cant rely on a full path name - let shift = - get_constant_from_var_name("SHIFT", identifiers, accessible_scopes)?.to_biguint(); + let shift = get_constant_from_var_name("SHIFT", identifiers, accessible_scopes)?.to_biguint(); let sum_d0 = (a.limbs[0].as_ref().to_biguint()) + (b.limbs[0].as_ref().to_biguint()); let carry_d0 = BigUint::from((sum_d0 >= shift) as usize);