From 52682e56a3f0918772d27c1f8705453da0e87b68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s?= <47506558+MegaRedHand@users.noreply.github.com> Date: Wed, 22 Mar 2023 11:08:04 -0300 Subject: [PATCH 1/6] Use `$crate` instead of name literal on macro (#917) --- felt/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/felt/src/lib.rs b/felt/src/lib.rs index a447955ab4..5de8d18faa 100644 --- a/felt/src/lib.rs +++ b/felt/src/lib.rs @@ -95,10 +95,10 @@ pub(crate) trait FeltOps { #[macro_export] macro_rules! felt_str { ($val: expr) => { - felt::Felt252::parse_bytes($val.as_bytes(), 10_u32).expect("Couldn't parse bytes") + $crate::Felt252::parse_bytes($val.as_bytes(), 10_u32).expect("Couldn't parse bytes") }; ($val: expr, $opt: expr) => { - felt::Felt252::parse_bytes($val.as_bytes(), $opt as u32).expect("Couldn't parse bytes") + $crate::Felt252::parse_bytes($val.as_bytes(), $opt as u32).expect("Couldn't parse bytes") }; } From 77fe09ebbf72710935b455b1c5ff56b0bad7a4b8 Mon Sep 17 00:00:00 2001 From: Mario Rugiero Date: Wed, 22 Mar 2023 12:24:54 -0300 Subject: [PATCH 2/6] Several fixes to `ExecutionResources` operators (#916) - Implements `SubAssign` and `MulAssign`; - Uses union rather than intersection for `Sub`; - Uses references rather than ownership transfer. --- src/vm/runners/cairo_runner.rs | 68 +++++++++++++++++----------------- 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/src/vm/runners/cairo_runner.rs b/src/vm/runners/cairo_runner.rs index a62d3671a6..5c453ff784 100644 --- a/src/vm/runners/cairo_runner.rs +++ b/src/vm/runners/cairo_runner.rs @@ -1,7 +1,7 @@ use crate::stdlib::{ any::Any, collections::{HashMap, HashSet}, - ops::{Add, AddAssign, Mul, Sub}, + ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign}, prelude::*, }; @@ -1100,50 +1100,48 @@ impl AddAssign<&ExecutionResources> for ExecutionResources { } } -impl Sub for ExecutionResources { +impl Sub<&ExecutionResources> for &ExecutionResources { type Output = ExecutionResources; - fn sub(self, rhs: ExecutionResources) -> ExecutionResources { - let mut builtin_instance_counter_union: HashMap = HashMap::new(); - - self.builtin_instance_counter - .keys() - .filter(|k| rhs.builtin_instance_counter.contains_key(*k)) - .for_each(|k| { - builtin_instance_counter_union.insert( - k.to_string(), - self.builtin_instance_counter - .get(k) - .unwrap() - .saturating_sub(*rhs.builtin_instance_counter.get(k).unwrap()), - ); - }); + fn sub(self, rhs: &ExecutionResources) -> ExecutionResources { + let mut new = self.clone(); + new.sub_assign(rhs); + new + } +} - ExecutionResources { - n_steps: self.n_steps.saturating_sub(rhs.n_steps), - n_memory_holes: self.n_memory_holes.saturating_sub(rhs.n_memory_holes), - builtin_instance_counter: builtin_instance_counter_union, +impl SubAssign<&ExecutionResources> for ExecutionResources { + fn sub_assign(&mut self, rhs: &ExecutionResources) { + self.n_steps -= rhs.n_steps; + self.n_memory_holes -= rhs.n_memory_holes; + for (k, v) in rhs.builtin_instance_counter.iter() { + // FIXME: remove k's clone, use &'static str + let entry = self.builtin_instance_counter.entry(k.clone()).or_insert(0); + *entry = (*entry).saturating_sub(*v); } } } -impl Mul for ExecutionResources { +impl Mul for &ExecutionResources { type Output = ExecutionResources; fn mul(self, rhs: usize) -> ExecutionResources { - let mut total_builtin_instance_counter = self.builtin_instance_counter.clone(); + let mut new = self.clone(); + new.mul_assign(rhs); + new + } +} - for (_builtin_name, counter) in total_builtin_instance_counter.iter_mut() { +impl MulAssign for ExecutionResources { + fn mul_assign(&mut self, rhs: usize) { + self.n_steps *= rhs; + self.n_memory_holes *= rhs; + for (_builtin_name, counter) in self.builtin_instance_counter.iter_mut() { *counter *= rhs; } - - ExecutionResources { - n_steps: rhs * self.n_steps, - n_memory_holes: rhs * self.n_memory_holes, - builtin_instance_counter: total_builtin_instance_counter, - } } } + #[cfg(test)] mod tests { use super::*; @@ -4521,7 +4519,7 @@ mod tests { fn execution_resources_sub() { let (execution_resources_1, execution_resources_2) = setup_execution_resources(); - let combined_resources = execution_resources_1 - execution_resources_2; + let combined_resources = &execution_resources_1 - &execution_resources_2; assert_eq!(combined_resources.n_steps, 0); assert_eq!(combined_resources.n_memory_holes, 0); @@ -4532,7 +4530,7 @@ mod tests { .unwrap(), &0 ); - assert!(!combined_resources + assert!(combined_resources .builtin_instance_counter .contains_key(RANGE_CHECK_BUILTIN_NAME)); } @@ -4684,7 +4682,7 @@ mod tests { }; assert_eq!( - execution_resources_1 * 2, + &execution_resources_1 * 2, ExecutionResources { n_steps: 1600, n_memory_holes: 0, @@ -4702,7 +4700,7 @@ mod tests { }; assert_eq!( - execution_resources_2 * 8, + &execution_resources_2 * 8, ExecutionResources { n_steps: 4360, n_memory_holes: 0, @@ -4717,7 +4715,7 @@ mod tests { }; assert_eq!( - execution_resources_3 * 18, + &execution_resources_3 * 18, ExecutionResources { n_steps: 756, n_memory_holes: 0, From cc55445823439d604625aa7c4de057481eaf814c Mon Sep 17 00:00:00 2001 From: fmoletta <99273364+fmoletta@users.noreply.github.com> Date: Mon, 27 Mar 2023 16:24:49 +0300 Subject: [PATCH 3/6] Remove builtin names from `VirtualMachine.builtin_runners` (#921) * Remove name from Vm.builtin_runners * Fix tests * Fix tests, add FIXMes * Clippy * Remove clone --- .../builtin_hint_processor/signature.rs | 19 +- src/serde/deserialize_program.rs | 2 +- src/utils.rs | 5 +- src/vm/runners/cairo_runner.rs | 346 +++++++----------- src/vm/security.rs | 6 +- src/vm/vm_core.rs | 90 ++--- 6 files changed, 175 insertions(+), 293 deletions(-) diff --git a/src/hint_processor/builtin_hint_processor/signature.rs b/src/hint_processor/builtin_hint_processor/signature.rs index 9aa273bba7..9526dd9803 100644 --- a/src/hint_processor/builtin_hint_processor/signature.rs +++ b/src/hint_processor/builtin_hint_processor/signature.rs @@ -44,7 +44,6 @@ pub fn verify_ecdsa_signature( #[cfg(test)] mod tests { use super::*; - use crate::vm::runners::builtin_runner::SIGNATURE_BUILTIN_NAME; use crate::vm::vm_memory::memory_segments::MemorySegmentManager; use crate::{ any_box, @@ -75,10 +74,8 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn verify_ecdsa_signature_valid() { let mut vm = vm!(); - vm.builtin_runners = vec![( - SIGNATURE_BUILTIN_NAME, - SignatureBuiltinRunner::new(&EcdsaInstanceDef::default(), true).into(), - )]; + vm.builtin_runners = + vec![SignatureBuiltinRunner::new(&EcdsaInstanceDef::default(), true).into()]; vm.segments = segments![ ((1, 0), (0, 0)), ( @@ -104,10 +101,8 @@ mod tests { #[test] fn verify_ecdsa_signature_invalid_ecdsa_ptr() { let mut vm = vm!(); - vm.builtin_runners = vec![( - SIGNATURE_BUILTIN_NAME, - SignatureBuiltinRunner::new(&EcdsaInstanceDef::default(), true).into(), - )]; + vm.builtin_runners = + vec![SignatureBuiltinRunner::new(&EcdsaInstanceDef::default(), true).into()]; vm.segments = segments![ ((1, 0), (3, 0)), ( @@ -133,10 +128,8 @@ mod tests { #[test] fn verify_ecdsa_signature_invalid_input_cell() { let mut vm = vm!(); - vm.builtin_runners = vec![( - SIGNATURE_BUILTIN_NAME, - SignatureBuiltinRunner::new(&EcdsaInstanceDef::default(), true).into(), - )]; + vm.builtin_runners = + vec![SignatureBuiltinRunner::new(&EcdsaInstanceDef::default(), true).into()]; vm.segments = segments![ ((1, 0), (0, 3)), ( diff --git a/src/serde/deserialize_program.rs b/src/serde/deserialize_program.rs index c15119db0b..a40fea018e 100644 --- a/src/serde/deserialize_program.rs +++ b/src/serde/deserialize_program.rs @@ -17,7 +17,7 @@ use serde::{de, de::MapAccess, de::SeqAccess, Deserialize, Deserializer, Seriali use serde_json::Number; // This enum is used to deserialize program builtins into &str and catch non-valid names -#[derive(Serialize, Deserialize, Debug, PartialEq, Copy, Clone, Eq)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Copy, Clone, Eq, Hash)] #[allow(non_camel_case_types)] pub enum BuiltinName { output, diff --git a/src/utils.rs b/src/utils.rs index e9b63b5195..3bfcca3968 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -214,10 +214,7 @@ pub mod test_utils { macro_rules! vm_with_range_check { () => {{ let mut vm = VirtualMachine::new(false); - vm.builtin_runners = vec![( - "range_check", - RangeCheckBuiltinRunner::new(8, 8, true).into(), - )]; + vm.builtin_runners = vec![RangeCheckBuiltinRunner::new(8, 8, true).into()]; vm }}; } diff --git a/src/vm/runners/cairo_runner.rs b/src/vm/runners/cairo_runner.rs index 5c453ff784..07dcd68fe4 100644 --- a/src/vm/runners/cairo_runner.rs +++ b/src/vm/runners/cairo_runner.rs @@ -141,104 +141,71 @@ impl CairoRunner { if !is_subsequence(&self.program.builtins, &builtin_ordered_list) { return Err(RunnerError::DisorderedBuiltins); }; - let mut builtin_runners = Vec::<(&'static str, BuiltinRunner)>::new(); + let mut program_builtins: HashSet<&BuiltinName> = self.program.builtins.iter().collect(); + let mut builtin_runners = Vec::::new(); if self.layout.builtins.output { - let included = self.program.builtins.contains(&BuiltinName::output); + let included = program_builtins.remove(&BuiltinName::output); if included || self.proof_mode { - builtin_runners.push(( - BuiltinName::output.name(), - OutputBuiltinRunner::new(included).into(), - )); + builtin_runners.push(OutputBuiltinRunner::new(included).into()); } } if let Some(instance_def) = self.layout.builtins.pedersen.as_ref() { - let included = self.program.builtins.contains(&BuiltinName::pedersen); + let included = program_builtins.remove(&BuiltinName::pedersen); if included || self.proof_mode { - builtin_runners.push(( - BuiltinName::pedersen.name(), - HashBuiltinRunner::new(instance_def.ratio, included).into(), - )); + builtin_runners.push(HashBuiltinRunner::new(instance_def.ratio, included).into()); } } if let Some(instance_def) = self.layout.builtins.range_check.as_ref() { - let included = self.program.builtins.contains(&BuiltinName::range_check); + let included = program_builtins.remove(&BuiltinName::range_check); if included || self.proof_mode { - builtin_runners.push(( - BuiltinName::range_check.name(), + builtin_runners.push( RangeCheckBuiltinRunner::new( instance_def.ratio, instance_def.n_parts, included, ) .into(), - )); + ); } } if let Some(instance_def) = self.layout.builtins.ecdsa.as_ref() { - let included = self.program.builtins.contains(&BuiltinName::ecdsa); + let included = program_builtins.remove(&BuiltinName::ecdsa); if included || self.proof_mode { - builtin_runners.push(( - BuiltinName::ecdsa.name(), - SignatureBuiltinRunner::new(instance_def, included).into(), - )); + builtin_runners.push(SignatureBuiltinRunner::new(instance_def, included).into()); } } if let Some(instance_def) = self.layout.builtins.bitwise.as_ref() { - let included = self.program.builtins.contains(&BuiltinName::bitwise); + let included = program_builtins.remove(&BuiltinName::bitwise); if included || self.proof_mode { - builtin_runners.push(( - BuiltinName::bitwise.name(), - BitwiseBuiltinRunner::new(instance_def, included).into(), - )); + builtin_runners.push(BitwiseBuiltinRunner::new(instance_def, included).into()); } } if let Some(instance_def) = self.layout.builtins.ec_op.as_ref() { - let included = self.program.builtins.contains(&BuiltinName::ec_op); + let included = program_builtins.remove(&BuiltinName::ec_op); if included || self.proof_mode { - builtin_runners.push(( - BuiltinName::ec_op.name(), - EcOpBuiltinRunner::new(instance_def, included).into(), - )); + builtin_runners.push(EcOpBuiltinRunner::new(instance_def, included).into()); } } if let Some(instance_def) = self.layout.builtins.keccak.as_ref() { - let included = self.program.builtins.contains(&BuiltinName::keccak); + let included = program_builtins.remove(&BuiltinName::keccak); if included || self.proof_mode { - builtin_runners.push(( - BuiltinName::keccak.name(), - KeccakBuiltinRunner::new(instance_def, included).into(), - )); + builtin_runners.push(KeccakBuiltinRunner::new(instance_def, included).into()); } } - let inserted_builtins = builtin_runners - .iter() - .map(|x| x.0) - .collect::>(); - let program_builtins = self - .program - .builtins - .iter() - .map(|builtin_name| builtin_name.name()) - .collect::>(); - // Get the builtins that belong to the program but weren't inserted (those who dont belong to the instance) - if !program_builtins.is_subset(&inserted_builtins) { + if !program_builtins.is_empty() { return Err(RunnerError::NoBuiltinForInstance( - program_builtins - .difference(&inserted_builtins) - .copied() - .collect(), + program_builtins.iter().map(|n| n.name()).collect(), self.layout._name.clone(), )); } - drop(inserted_builtins); vm.builtin_runners = builtin_runners; Ok(()) @@ -261,29 +228,26 @@ impl CairoRunner { match name { BuiltinName::pedersen => vm .builtin_runners - .push((name.name(), HashBuiltinRunner::new(32, true).into())), + .push(HashBuiltinRunner::new(32, true).into()), BuiltinName::range_check => vm .builtin_runners - .push((name.name(), RangeCheckBuiltinRunner::new(1, 8, true).into())), + .push(RangeCheckBuiltinRunner::new(1, 8, true).into()), BuiltinName::output => vm .builtin_runners - .push((name.name(), OutputBuiltinRunner::new(true).into())), - BuiltinName::ecdsa => vm.builtin_runners.push(( - name.name(), - SignatureBuiltinRunner::new(&EcdsaInstanceDef::new(1), true).into(), - )), - BuiltinName::bitwise => vm.builtin_runners.push(( - name.name(), - BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(1), true).into(), - )), - BuiltinName::ec_op => vm.builtin_runners.push(( - name.name(), - EcOpBuiltinRunner::new(&EcOpInstanceDef::new(1), true).into(), - )), - BuiltinName::keccak => vm.builtin_runners.push(( - name.name(), - EcOpBuiltinRunner::new(&EcOpInstanceDef::new(1), true).into(), - )), + .push(OutputBuiltinRunner::new(true).into()), + BuiltinName::ecdsa => vm + .builtin_runners + .push(SignatureBuiltinRunner::new(&EcdsaInstanceDef::new(1), true).into()), + BuiltinName::bitwise => vm + .builtin_runners + .push(BitwiseBuiltinRunner::new(&BitwiseInstanceDef::new(1), true).into()), + BuiltinName::ec_op => vm + .builtin_runners + .push(EcOpBuiltinRunner::new(&EcOpInstanceDef::new(1), true).into()), + // FIXME: Use keccak here once 0.11 Keccak fixes are merged + BuiltinName::keccak => vm + .builtin_runners + .push(EcOpBuiltinRunner::new(&EcOpInstanceDef::new(1), true).into()), } } @@ -309,7 +273,7 @@ impl CairoRunner { None => Some(vm.segments.add()), }; self.execution_base = Some(vm.segments.add()); - for (_key, builtin_runner) in vm.builtin_runners.iter_mut() { + for builtin_runner in vm.builtin_runners.iter_mut() { builtin_runner.initialize_segments(&mut vm.segments); } } @@ -382,7 +346,7 @@ impl CairoRunner { vm: &mut VirtualMachine, ) -> Result { let mut stack = Vec::new(); - for (_name, builtin_runner) in vm.builtin_runners.iter() { + for builtin_runner in vm.builtin_runners.iter() { stack.append(&mut builtin_runner.initial_stack()); } //Different process if proof_mode is enabled @@ -432,7 +396,7 @@ impl CairoRunner { vm.run_context.pc = *self.initial_pc.as_ref().ok_or(RunnerError::NoPC)?; vm.run_context.ap = self.initial_ap.as_ref().ok_or(RunnerError::NoAP)?.offset; vm.run_context.fp = self.initial_fp.as_ref().ok_or(RunnerError::NoFP)?.offset; - for (_, builtin) in vm.builtin_runners.iter() { + for builtin in vm.builtin_runners.iter() { builtin.add_validation_rule(&mut vm.segments.memory); } @@ -585,7 +549,7 @@ impl CairoRunner { match limits { Some((mut rc_min, mut rc_max)) => { - for (_, runner) in &vm.builtin_runners { + for runner in &vm.builtin_runners { let (runner_min, runner_max) = match runner.get_range_check_usage(&vm.segments.memory) { Some(x) => x, @@ -611,7 +575,7 @@ impl CairoRunner { }; let mut rc_units_used_by_builtins = 0; - for (_, builtin_runner) in &vm.builtin_runners { + for builtin_runner in &vm.builtin_runners { rc_units_used_by_builtins += builtin_runner.get_used_perm_range_check_units(vm)?; } @@ -646,7 +610,7 @@ impl CairoRunner { }; let mut used_units_by_builtins = 0; - for (_, builtin_runner) in &vm.builtin_runners { + for builtin_runner in &vm.builtin_runners { let used_units = builtin_runner.get_used_diluted_check_units( diluted_pool_instance.spacing, diluted_pool_instance.n_bits, @@ -772,7 +736,7 @@ impl CairoRunner { ) -> Result, RunnerError> { let mut builtin_segment_info = Vec::new(); - for (_, builtin) in &vm.builtin_runners { + for builtin in &vm.builtin_runners { let (index, stop_ptr) = builtin.get_memory_segment_addresses(); builtin_segment_info.push(( @@ -795,9 +759,9 @@ impl CairoRunner { let n_memory_holes = self.get_memory_holes(vm)?; let mut builtin_instance_counter = HashMap::new(); - for (builtin_name, builtin_runner) in &vm.builtin_runners { + for builtin_runner in &vm.builtin_runners { builtin_instance_counter.insert( - builtin_name.to_string(), + builtin_runner.name().to_string(), builtin_runner.get_used_instances(&vm.segments)?, ); } @@ -849,7 +813,7 @@ impl CairoRunner { } vm.segments .finalize(None, exec_base.segment_index as usize, Some(&public_memory)); - for (_, builtin_runner) in vm.builtin_runners.iter() { + for builtin_runner in vm.builtin_runners.iter() { let (_, size) = builtin_runner .get_used_cells_and_allocated_size(vm) .map_err(RunnerError::FinalizeSegements)?; @@ -893,9 +857,7 @@ impl CairoRunner { pub fn check_used_cells(&self, vm: &VirtualMachine) -> Result<(), VirtualMachineError> { vm.builtin_runners .iter() - .map(|(_builtin_runner_name, builtin_runner)| { - builtin_runner.get_used_cells_and_allocated_size(vm) - }) + .map(|builtin_runner| builtin_runner.get_used_cells_and_allocated_size(vm)) .collect::, MemoryError>>()?; self.check_range_check_usage(vm)?; self.check_memory_usage(vm)?; @@ -910,9 +872,7 @@ impl CairoRunner { let builtins_memory_units: usize = vm .builtin_runners .iter() - .map(|(_builtin_runner_name, builtin_runner)| { - builtin_runner.get_allocated_memory_units(vm) - }) + .map(|builtin_runner| builtin_runner.get_allocated_memory_units(vm)) .collect::, MemoryError>>()? .iter() .sum(); @@ -979,7 +939,7 @@ impl CairoRunner { return Err(RunnerError::ReadReturnValuesNoEndRun); } let mut pointer = vm.get_ap(); - for (_, builtin_runner) in vm.builtin_runners.iter_mut().rev() { + for builtin_runner in vm.builtin_runners.iter_mut().rev() { let new_pointer = builtin_runner.final_stack(&vm.segments, pointer)?; pointer = new_pointer; } @@ -1002,18 +962,15 @@ impl CairoRunner { Ok(()) } + //NOTE: No longer needed in 0.11 /// Add (or replace if already present) a custom hash builtin. Returns a Relocatable /// with the new builtin base as the segment index. pub fn add_additional_hash_builtin(&self, vm: &mut VirtualMachine) -> Relocatable { - // Remove the custom hash runner if it was already present. - vm.builtin_runners - .retain(|(name, _)| name != &"hash_builtin"); - // Create, initialize and insert the new custom hash runner. let mut builtin: BuiltinRunner = HashBuiltinRunner::new(32, true).into(); builtin.initialize_segments(&mut vm.segments); let segment_index = builtin.base() as isize; - vm.builtin_runners.push(("hash_builtin", builtin)); + vm.builtin_runners.push(builtin); Relocatable { segment_index, @@ -1029,15 +986,15 @@ impl CairoRunner { stack_ptr: Relocatable, ) -> Result { let mut stack_ptr = Relocatable::from(&stack_ptr); - for (_, runner) in - vm.builtin_runners - .iter_mut() - .rev() - .filter(|(builtin_name, _builtin_runner)| { - self.get_program_builtins() - .iter() - .any(|bn| bn.name() == *builtin_name) - }) + for runner in vm + .builtin_runners + .iter_mut() + .rev() + .filter(|builtin_runner| { + self.get_program_builtins() + .iter() + .any(|bn| bn.name() == builtin_runner.name()) + }) { stack_ptr = runner.final_stack(&vm.segments, stack_ptr)? } @@ -1147,8 +1104,8 @@ mod tests { use super::*; use crate::stdlib::collections::{HashMap, HashSet}; use crate::vm::runners::builtin_runner::{ - BITWISE_BUILTIN_NAME, EC_OP_BUILTIN_NAME, HASH_BUILTIN_NAME, KECCAK_BUILTIN_NAME, - OUTPUT_BUILTIN_NAME, RANGE_CHECK_BUILTIN_NAME, SIGNATURE_BUILTIN_NAME, + BITWISE_BUILTIN_NAME, EC_OP_BUILTIN_NAME, HASH_BUILTIN_NAME, OUTPUT_BUILTIN_NAME, + RANGE_CHECK_BUILTIN_NAME, SIGNATURE_BUILTIN_NAME, }; use crate::vm::vm_memory::memory::MemoryCell; use crate::vm::vm_memory::memory_segments::MemorySegmentManager; @@ -1190,7 +1147,7 @@ mod tests { let mut builtin_runner: BuiltinRunner = OutputBuiltinRunner::new(true).into(); builtin_runner.initialize_segments(&mut vm.segments); - (BuiltinName::output.name(), builtin_runner) + builtin_runner }]; vm.segments.segment_used_sizes = Some(vec![4, 12]); vm.segments.memory = memory![((0, 0), 0), ((0, 1), 1), ((0, 2), 1)]; @@ -1250,8 +1207,8 @@ mod tests { offset: 0, }) ); - assert_eq!(vm.builtin_runners[0].0, OUTPUT_BUILTIN_NAME); - assert_eq!(vm.builtin_runners[0].1.base(), 7); + assert_eq!(vm.builtin_runners[0].name(), OUTPUT_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[0].base(), 7); assert_eq!(vm.segments.num_segments(), 8); } @@ -1279,8 +1236,8 @@ mod tests { offset: 0 }) ); - assert_eq!(vm.builtin_runners[0].0, OUTPUT_BUILTIN_NAME); - assert_eq!(vm.builtin_runners[0].1.base(), 2); + assert_eq!(vm.builtin_runners[0].name(), OUTPUT_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[0].base(), 2); assert_eq!(vm.segments.num_segments(), 3); } @@ -1525,8 +1482,8 @@ mod tests { cairo_runner.initialize_builtins(&mut vm).unwrap(); cairo_runner.initialize_segments(&mut vm, None); vm.segments = segments![((2, 0), 23), ((2, 1), 233)]; - assert_eq!(vm.builtin_runners[0].0, RANGE_CHECK_BUILTIN_NAME); - assert_eq!(vm.builtin_runners[0].1.base(), 2); + assert_eq!(vm.builtin_runners[0].name(), RANGE_CHECK_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[0].base(), 2); cairo_runner.initialize_vm(&mut vm).unwrap(); assert!(vm .segments @@ -1959,8 +1916,8 @@ mod tests { ] ); //Check the range_check builtin segment - assert_eq!(vm.builtin_runners[0].0, RANGE_CHECK_BUILTIN_NAME); - assert_eq!(vm.builtin_runners[0].1.base(), 2); + assert_eq!(vm.builtin_runners[0].name(), RANGE_CHECK_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[0].base(), 2); check_memory!( vm.segments.memory, @@ -2077,8 +2034,8 @@ mod tests { ] ); //Check that the output to be printed is correct - assert_eq!(vm.builtin_runners[0].0, OUTPUT_BUILTIN_NAME); - assert_eq!(vm.builtin_runners[0].1.base(), 2); + assert_eq!(vm.builtin_runners[0].name(), OUTPUT_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[0].base(), 2); check_memory!(vm.segments.memory, ((2, 0), 1), ((2, 1), 17)); assert!(vm .segments @@ -2221,8 +2178,8 @@ mod tests { ] ); //Check the range_check builtin segment - assert_eq!(vm.builtin_runners[1].0, RANGE_CHECK_BUILTIN_NAME); - assert_eq!(vm.builtin_runners[1].1.base(), 3); + assert_eq!(vm.builtin_runners[1].name(), RANGE_CHECK_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[1].base(), 3); check_memory!( vm.segments.memory, @@ -2236,8 +2193,8 @@ mod tests { .is_none()); //Check the output segment - assert_eq!(vm.builtin_runners[0].0, OUTPUT_BUILTIN_NAME); - assert_eq!(vm.builtin_runners[0].1.base(), 2); + assert_eq!(vm.builtin_runners[0].name(), OUTPUT_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[0].base(), 2); check_memory!(vm.segments.memory, ((2, 0), 7)); assert!(vm @@ -2676,8 +2633,8 @@ mod tests { let mut vm = vm!(); cairo_runner.initialize_builtins(&mut vm).unwrap(); cairo_runner.initialize_segments(&mut vm, None); - assert_eq!(vm.builtin_runners[0].0, OUTPUT_BUILTIN_NAME); - assert_eq!(vm.builtin_runners[0].1.base(), 2); + assert_eq!(vm.builtin_runners[0].name(), OUTPUT_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[0].base(), 2); vm.segments = segments![((2, 0), 1), ((2, 1), 2)]; vm.segments.segment_used_sizes = Some(vec![0, 0, 2]); @@ -2794,8 +2751,8 @@ mod tests { let mut vm = vm!(); cairo_runner.initialize_builtins(&mut vm).unwrap(); cairo_runner.initialize_segments(&mut vm, None); - assert_eq!(vm.builtin_runners[0].0, OUTPUT_BUILTIN_NAME); - assert_eq!(vm.builtin_runners[0].1.base(), 2); + assert_eq!(vm.builtin_runners[0].name(), OUTPUT_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[0].base(), 2); vm.segments = segments![( (2, 0), ( @@ -2885,11 +2842,11 @@ mod tests { let cairo_runner = cairo_runner!(program); let mut vm = vm!(); cairo_runner.initialize_builtins(&mut vm).unwrap(); - assert_eq!(vm.builtin_runners[0].0, OUTPUT_BUILTIN_NAME); - assert_eq!(vm.builtin_runners[1].0, HASH_BUILTIN_NAME); - assert_eq!(vm.builtin_runners[2].0, RANGE_CHECK_BUILTIN_NAME); - assert_eq!(vm.builtin_runners[3].0, BITWISE_BUILTIN_NAME); - assert_eq!(vm.builtin_runners[4].0, EC_OP_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[0].name(), OUTPUT_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[1].name(), HASH_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[2].name(), RANGE_CHECK_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[3].name(), BITWISE_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[4].name(), EC_OP_BUILTIN_NAME); } #[test] @@ -3210,7 +3167,7 @@ mod tests { let mut builtin_runner: BuiltinRunner = OutputBuiltinRunner::new(true).into(); builtin_runner.initialize_segments(&mut vm.segments); - (BuiltinName::output.name(), builtin_runner) + builtin_runner }]; vm.segments.segment_used_sizes = Some(vec![4]); assert_eq!(cairo_runner.get_memory_holes(&vm), Ok(0)); @@ -3230,7 +3187,7 @@ mod tests { let mut builtin_runner: BuiltinRunner = OutputBuiltinRunner::new(true).into(); builtin_runner.initialize_segments(&mut vm.segments); - (BuiltinName::output.name(), builtin_runner) + builtin_runner }]; vm.segments.segment_used_sizes = Some(vec![4, 4]); assert_eq!(cairo_runner.get_memory_holes(&vm), Ok(2)); @@ -3295,10 +3252,8 @@ mod tests { let mut vm = vm!(); vm.current_step = 8192; - vm.builtin_runners = vec![( - BuiltinName::bitwise.name(), - BitwiseBuiltinRunner::new(&BitwiseInstanceDef::default(), true).into(), - )]; + vm.builtin_runners = + vec![BitwiseBuiltinRunner::new(&BitwiseInstanceDef::default(), true).into()]; assert_matches!(cairo_runner.check_diluted_check_usage(&vm), Ok(())); } @@ -3385,10 +3340,7 @@ mod tests { let cairo_runner = cairo_runner!(program); let mut vm = vm!(); - vm.builtin_runners = vec![( - BuiltinName::output.name(), - BuiltinRunner::Output(OutputBuiltinRunner::new(true)), - )]; + vm.builtin_runners = vec![BuiltinRunner::Output(OutputBuiltinRunner::new(true))]; assert_eq!( cairo_runner.get_builtin_segments_info(&vm), Err(RunnerError::NoStopPointer(BuiltinName::output.name())), @@ -3448,7 +3400,7 @@ mod tests { let mut builtin = OutputBuiltinRunner::new(true); builtin.initialize_segments(&mut vm.segments); - (BuiltinName::output.name(), BuiltinRunner::Output(builtin)) + BuiltinRunner::Output(builtin) }]; assert_eq!( cairo_runner.get_execution_resources(&vm), @@ -3693,10 +3645,7 @@ mod tests { vm.segments.memory.data = vec![vec![Some(MemoryCell::new(mayberelocatable!( 0x80FF_8000_0530u64 )))]]; - vm.builtin_runners = vec![( - RANGE_CHECK_BUILTIN_NAME, - RangeCheckBuiltinRunner::new(12, 5, true).into(), - )]; + vm.builtin_runners = vec![RangeCheckBuiltinRunner::new(12, 5, true).into()]; assert_matches!( cairo_runner.get_perm_range_check_limits(&vm), @@ -3750,10 +3699,7 @@ mod tests { let cairo_runner = cairo_runner!(program); let mut vm = vm!(); - vm.builtin_runners = vec![( - RANGE_CHECK_BUILTIN_NAME, - RangeCheckBuiltinRunner::new(8, 8, true).into(), - )]; + vm.builtin_runners = vec![RangeCheckBuiltinRunner::new(8, 8, true).into()]; vm.segments.memory.data = vec![vec![Some(MemoryCell::new(mayberelocatable!( 0x80FF_8000_0530u64 )))]]; @@ -3820,10 +3766,7 @@ mod tests { let cairo_runner = cairo_runner!(program); let mut vm = vm!(); - vm.builtin_runners = vec![( - RANGE_CHECK_BUILTIN_NAME, - RangeCheckBuiltinRunner::new(8, 8, true).into(), - )]; + vm.builtin_runners = vec![RangeCheckBuiltinRunner::new(8, 8, true).into()]; vm.segments.memory.data = vec![vec![Some(MemoryCell::new(mayberelocatable!( 0x80FF_8000_0530u64 )))]]; @@ -3854,7 +3797,7 @@ mod tests { let mut builtin_runner: BuiltinRunner = OutputBuiltinRunner::new(true).into(); builtin_runner.initialize_segments(&mut vm.segments); - (BuiltinName::output.name(), builtin_runner) + builtin_runner }]; vm.segments.segment_used_sizes = Some(vec![4, 12]); vm.trace = Some(vec![]); @@ -3898,13 +3841,14 @@ mod tests { let given_output = vm.get_builtin_runners(); - assert_eq!(given_output[0].0, HASH_BUILTIN_NAME); - assert_eq!(given_output[1].0, RANGE_CHECK_BUILTIN_NAME); - assert_eq!(given_output[2].0, OUTPUT_BUILTIN_NAME); - assert_eq!(given_output[3].0, SIGNATURE_BUILTIN_NAME); - assert_eq!(given_output[4].0, BITWISE_BUILTIN_NAME); - assert_eq!(given_output[5].0, EC_OP_BUILTIN_NAME); - assert_eq!(given_output[6].0, KECCAK_BUILTIN_NAME); + assert_eq!(given_output[0].name(), HASH_BUILTIN_NAME); + assert_eq!(given_output[1].name(), RANGE_CHECK_BUILTIN_NAME); + assert_eq!(given_output[2].name(), OUTPUT_BUILTIN_NAME); + assert_eq!(given_output[3].name(), SIGNATURE_BUILTIN_NAME); + assert_eq!(given_output[4].name(), BITWISE_BUILTIN_NAME); + assert_eq!(given_output[5].name(), EC_OP_BUILTIN_NAME); + // FIXME: Uncomment once 0.11 Keccak fixes are merged + // assert_eq!(given_output[6].name(), KECCAK_BUILTIN_NAME); } #[test] @@ -3925,13 +3869,14 @@ mod tests { let given_output = vm.get_builtin_runners(); - assert_eq!(given_output[0].0, HASH_BUILTIN_NAME); - assert_eq!(given_output[1].0, RANGE_CHECK_BUILTIN_NAME); - assert_eq!(given_output[2].0, SIGNATURE_BUILTIN_NAME); - assert_eq!(given_output[3].0, OUTPUT_BUILTIN_NAME); - assert_eq!(given_output[4].0, BITWISE_BUILTIN_NAME); - assert_eq!(given_output[5].0, EC_OP_BUILTIN_NAME); - assert_eq!(given_output[6].0, KECCAK_BUILTIN_NAME); + assert_eq!(given_output[0].name(), HASH_BUILTIN_NAME); + assert_eq!(given_output[1].name(), RANGE_CHECK_BUILTIN_NAME); + assert_eq!(given_output[2].name(), SIGNATURE_BUILTIN_NAME); + assert_eq!(given_output[3].name(), OUTPUT_BUILTIN_NAME); + assert_eq!(given_output[4].name(), BITWISE_BUILTIN_NAME); + assert_eq!(given_output[5].name(), EC_OP_BUILTIN_NAME); + // FIXME: Uncomment once 0.11 Keccak fixes are merged + // assert_eq!(given_output[6].name(), KECCAK_BUILTIN_NAME); } #[test] @@ -3948,13 +3893,14 @@ mod tests { let builtin_runners = vm.get_builtin_runners(); - assert_eq!(builtin_runners[0].0, HASH_BUILTIN_NAME); - assert_eq!(builtin_runners[1].0, RANGE_CHECK_BUILTIN_NAME); - assert_eq!(builtin_runners[2].0, OUTPUT_BUILTIN_NAME); - assert_eq!(builtin_runners[3].0, SIGNATURE_BUILTIN_NAME); - assert_eq!(builtin_runners[4].0, BITWISE_BUILTIN_NAME); - assert_eq!(builtin_runners[5].0, EC_OP_BUILTIN_NAME); - assert_eq!(builtin_runners[6].0, KECCAK_BUILTIN_NAME); + assert_eq!(builtin_runners[0].name(), HASH_BUILTIN_NAME); + assert_eq!(builtin_runners[1].name(), RANGE_CHECK_BUILTIN_NAME); + assert_eq!(builtin_runners[2].name(), OUTPUT_BUILTIN_NAME); + assert_eq!(builtin_runners[3].name(), SIGNATURE_BUILTIN_NAME); + assert_eq!(builtin_runners[4].name(), BITWISE_BUILTIN_NAME); + assert_eq!(builtin_runners[5].name(), EC_OP_BUILTIN_NAME); + // FIXME: Uncomment once 0.11 Keccak fixes are merged + // assert_eq!(builtin_runners[6].name(), KECCAK_BUILTIN_NAME); assert_eq!( cairo_runner.program_base, @@ -4241,8 +4187,7 @@ mod tests { cairo_runner.segments_finalized = false; let mut vm = vm!(); let output_builtin = OutputBuiltinRunner::new(true); - vm.builtin_runners - .push((BuiltinName::output.name(), output_builtin.into())); + vm.builtin_runners.push(output_builtin.into()); vm.segments.memory.data = vec![ vec![], vec![Some(MemoryCell::new(MaybeRelocatable::from((0, 0))))], @@ -4252,7 +4197,7 @@ mod tests { vm.segments.segment_used_sizes = Some(vec![0, 1, 0]); //Check values written by first call to segments.finalize() assert_eq!(cairo_runner.read_return_values(&mut vm), Ok(())); - let output_builtin = match &vm.builtin_runners[0].1 { + let output_builtin = match &vm.builtin_runners[0] { BuiltinRunner::Output(runner) => runner, _ => unreachable!(), }; @@ -4272,8 +4217,7 @@ mod tests { cairo_runner.segments_finalized = false; let mut vm = vm!(); let output_builtin = OutputBuiltinRunner::new(true); - vm.builtin_runners - .push((BuiltinName::output.name(), output_builtin.into())); + vm.builtin_runners.push(output_builtin.into()); vm.segments.memory.data = vec![ vec![Some(MemoryCell::new(MaybeRelocatable::from((0, 0))))], vec![Some(MemoryCell::new(MaybeRelocatable::from((0, 1))))], @@ -4283,7 +4227,7 @@ mod tests { vm.segments.segment_used_sizes = Some(vec![1, 1, 0]); //Check values written by first call to segments.finalize() assert_eq!(cairo_runner.read_return_values(&mut vm), Ok(())); - let output_builtin = match &vm.builtin_runners[0].1 { + let output_builtin = match &vm.builtin_runners[0] { BuiltinRunner::Output(runner) => runner, _ => unreachable!(), }; @@ -4304,10 +4248,8 @@ mod tests { let mut vm = vm!(); let output_builtin = OutputBuiltinRunner::new(true); let bitwise_builtin = BitwiseBuiltinRunner::new(&BitwiseInstanceDef::default(), true); - vm.builtin_runners - .push((BuiltinName::output.name(), output_builtin.into())); - vm.builtin_runners - .push((BuiltinName::bitwise.name(), bitwise_builtin.into())); + vm.builtin_runners.push(output_builtin.into()); + vm.builtin_runners.push(bitwise_builtin.into()); cairo_runner.initialize_segments(&mut vm, None); vm.segments.memory.data = vec![ vec![Some(MemoryCell::new(MaybeRelocatable::from((0, 0))))], @@ -4322,13 +4264,13 @@ mod tests { vm.segments.segment_used_sizes = Some(vec![0, 2, 0, 5]); //Check values written by first call to segments.finalize() assert_eq!(cairo_runner.read_return_values(&mut vm), Ok(())); - let output_builtin = match &vm.builtin_runners[0].1 { + let output_builtin = match &vm.builtin_runners[0] { BuiltinRunner::Output(runner) => runner, _ => unreachable!(), }; assert_eq!(output_builtin.stop_ptr, Some(0)); assert_eq!(cairo_runner.read_return_values(&mut vm), Ok(())); - let bitwise_builtin = match &vm.builtin_runners[1].1 { + let bitwise_builtin = match &vm.builtin_runners[1] { BuiltinRunner::Bitwise(runner) => runner, _ => unreachable!(), }; @@ -4347,12 +4289,11 @@ mod tests { cairo_runner.add_additional_hash_builtin(&mut vm); assert_eq!(vm.builtin_runners.len(), num_builtins + 1); - let (key, value) = vm + let builtin = vm .builtin_runners .last() .expect("missing last builtin runner"); - assert_eq!(key, &"hash_builtin"); - match value { + match builtin { BuiltinRunner::Hash(builtin) => { assert_eq!(builtin.base(), 0); assert_eq!(builtin.ratio(), 32); @@ -4362,35 +4303,6 @@ mod tests { } } - /// Test that add_additional_hash_builtin() replaces the created runner if called multiple - /// times. - #[test] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn add_additional_hash_builtin_replace() { - let program = program!(); - let cairo_runner = cairo_runner!(program); - let mut vm = vm!(); - - let num_builtins = vm.builtin_runners.len(); - cairo_runner.add_additional_hash_builtin(&mut vm); - cairo_runner.add_additional_hash_builtin(&mut vm); - assert_eq!(vm.builtin_runners.len(), num_builtins + 1); - - let (key, value) = vm - .builtin_runners - .last() - .expect("missing last builtin runner"); - assert_eq!(key, &"hash_builtin"); - match value { - BuiltinRunner::Hash(builtin) => { - assert_eq!(builtin.base(), 1); - assert_eq!(builtin.ratio(), 32); - assert!(builtin.included); - } - _ => unreachable!(), - } - } - #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn run_from_entrypoint_custom_program_test() { diff --git a/src/vm/security.rs b/src/vm/security.rs index 1032751fd6..3f8fdbfa7a 100644 --- a/src/vm/security.rs +++ b/src/vm/security.rs @@ -72,7 +72,7 @@ pub fn verify_secure_runner( } } } - for (_, builtin) in vm.builtin_runners.iter() { + for builtin in vm.builtin_runners.iter() { builtin.run_security_checks(vm)?; } @@ -152,7 +152,7 @@ mod test { let mut runner = cairo_runner!(program); let mut vm = vm!(); runner.initialize(&mut vm).unwrap(); - vm.builtin_runners[0].1.set_stop_ptr(0); + vm.builtin_runners[0].set_stop_ptr(0); vm.segments.memory = memory![((2, 0), 1)]; vm.segments.segment_used_sizes = Some(vec![0, 0, 0, 0]); @@ -174,7 +174,7 @@ mod test { runner .end_run(false, false, &mut vm, &mut hint_processor) .unwrap(); - vm.builtin_runners[0].1.set_stop_ptr(1); + vm.builtin_runners[0].set_stop_ptr(1); vm.segments.memory = memory![((2, 0), 1)]; vm.segments.segment_used_sizes = Some(vec![0, 0, 1, 0]); diff --git a/src/vm/vm_core.rs b/src/vm/vm_core.rs index c11aa613a7..4449d1bd56 100644 --- a/src/vm/vm_core.rs +++ b/src/vm/vm_core.rs @@ -28,9 +28,7 @@ use felt::Felt252; use num_traits::{ToPrimitive, Zero}; use super::errors::trace_errors::TraceError; -use super::runners::builtin_runner::{ - OUTPUT_BUILTIN_NAME, RANGE_CHECK_BUILTIN_NAME, SIGNATURE_BUILTIN_NAME, -}; +use super::runners::builtin_runner::OUTPUT_BUILTIN_NAME; const MAX_TRACEBACK_ENTRIES: u32 = 20; @@ -84,7 +82,7 @@ pub struct HintData { pub struct VirtualMachine { pub(crate) run_context: RunContext, - pub(crate) builtin_runners: Vec<(&'static str, BuiltinRunner)>, + pub(crate) builtin_runners: Vec, pub(crate) segments: MemorySegmentManager, pub(crate) trace: Option>, pub(crate) current_step: usize, @@ -309,7 +307,7 @@ impl VirtualMachine { &self, address: Relocatable, ) -> Result, VirtualMachineError> { - for (_, builtin) in self.builtin_runners.iter() { + for builtin in self.builtin_runners.iter() { if builtin.base() as isize == address.segment_index { match builtin.deduce_memory_cell(address, &self.segments.memory) { Ok(maybe_reloc) => return Ok(maybe_reloc), @@ -647,7 +645,7 @@ impl VirtualMachine { ///Makes sure that all assigned memory cells are consistent with their auto deduction rules. pub fn verify_auto_deductions(&self) -> Result<(), VirtualMachineError> { - for (name, builtin) in self.builtin_runners.iter() { + for builtin in self.builtin_runners.iter() { let index: usize = builtin.base(); for (offset, value) in self.segments.memory.data[index].iter().enumerate() { if let Some(deduced_memory_cell) = builtin @@ -660,7 +658,7 @@ impl VirtualMachine { let value = value.as_ref().map(|x| x.get_value()); if Some(&deduced_memory_cell) != value && value.is_some() { return Err(VirtualMachineError::InconsistentAutoDeduction( - name, + builtin.name(), deduced_memory_cell, value.cloned(), )); @@ -811,12 +809,12 @@ impl VirtualMachine { } /// Returns a reference to the vector with all builtins present in the virtual machine - pub fn get_builtin_runners(&self) -> &Vec<(&'static str, BuiltinRunner)> { + pub fn get_builtin_runners(&self) -> &Vec { &self.builtin_runners } /// Returns a mutable reference to the vector with all builtins present in the virtual machine - pub fn get_builtin_runners_as_mut(&mut self) -> &mut Vec<(&'static str, BuiltinRunner)> { + pub fn get_builtin_runners_as_mut(&mut self) -> &mut Vec { &mut self.builtin_runners } @@ -878,12 +876,10 @@ impl VirtualMachine { } pub fn get_range_check_builtin(&self) -> Result<&RangeCheckBuiltinRunner, VirtualMachineError> { - for (name, builtin) in &self.builtin_runners { - if name == &String::from(RANGE_CHECK_BUILTIN_NAME) { - if let BuiltinRunner::RangeCheck(range_check_builtin) = builtin { - return Ok(range_check_builtin); - }; - } + for builtin in &self.builtin_runners { + if let BuiltinRunner::RangeCheck(range_check_builtin) = builtin { + return Ok(range_check_builtin); + }; } Err(VirtualMachineError::NoRangeCheckBuiltin) } @@ -891,12 +887,10 @@ impl VirtualMachine { pub fn get_signature_builtin( &mut self, ) -> Result<&mut SignatureBuiltinRunner, VirtualMachineError> { - for (name, builtin) in self.get_builtin_runners_as_mut() { - if name == &SIGNATURE_BUILTIN_NAME { - if let BuiltinRunner::Signature(signature_builtin) = builtin { - return Ok(signature_builtin); - }; - } + for builtin in self.get_builtin_runners_as_mut() { + if let BuiltinRunner::Signature(signature_builtin) = builtin { + return Ok(signature_builtin); + }; } Err(VirtualMachineError::NoSignatureBuiltin) @@ -957,10 +951,10 @@ impl VirtualMachine { &mut self, writer: &mut impl core::fmt::Write, ) -> Result<(), VirtualMachineError> { - let (_, builtin) = match self + let builtin = match self .builtin_runners .iter() - .find(|(k, _)| k == &OUTPUT_BUILTIN_NAME) + .find(|b| b.name() == OUTPUT_BUILTIN_NAME) { Some(x) => x, _ => return Ok(()), @@ -1019,7 +1013,7 @@ impl VirtualMachine { pub struct VirtualMachineBuilder { pub(crate) run_context: RunContext, - pub(crate) builtin_runners: Vec<(&'static str, BuiltinRunner)>, + pub(crate) builtin_runners: Vec, pub(crate) segments: MemorySegmentManager, pub(crate) trace: Option>, pub(crate) current_step: usize, @@ -1057,10 +1051,7 @@ impl VirtualMachineBuilder { self } - pub fn builtin_runners( - mut self, - builtin_runners: Vec<(&'static str, BuiltinRunner)>, - ) -> VirtualMachineBuilder { + pub fn builtin_runners(mut self, builtin_runners: Vec) -> VirtualMachineBuilder { self.builtin_runners = builtin_runners; self } @@ -3240,7 +3231,7 @@ mod tests { fn deduce_memory_cell_pedersen_builtin_valid() { let mut vm = vm!(); let builtin = HashBuiltinRunner::new(8, true); - vm.builtin_runners.push((HASH_BUILTIN_NAME, builtin.into())); + vm.builtin_runners.push(builtin.into()); vm.segments = segments![((0, 3), 32), ((0, 4), 72), ((0, 5), 0)]; assert_matches!( vm.deduce_memory_cell(Relocatable::from((0, 5))), @@ -3293,7 +3284,7 @@ mod tests { let mut builtin = HashBuiltinRunner::new(8, true); builtin.base = 3; let mut vm = vm!(); - vm.builtin_runners.push((HASH_BUILTIN_NAME, builtin.into())); + vm.builtin_runners.push(builtin.into()); run_context!(vm, 0, 13, 12); //Insert values into memory (excluding those from the program segment (instructions)) @@ -3342,8 +3333,7 @@ mod tests { fn deduce_memory_cell_bitwise_builtin_valid_and() { let mut vm = vm!(); let builtin = BitwiseBuiltinRunner::new(&BitwiseInstanceDef::default(), true); - vm.builtin_runners - .push((BITWISE_BUILTIN_NAME, builtin.into())); + vm.builtin_runners.push(builtin.into()); vm.segments = segments![((0, 5), 10), ((0, 6), 12), ((0, 7), 0)]; assert_matches!( vm.deduce_memory_cell(Relocatable::from((0, 7))), @@ -3385,8 +3375,7 @@ mod tests { builtin.base = 2; let mut vm = vm!(); - vm.builtin_runners - .push((BITWISE_BUILTIN_NAME, builtin.into())); + vm.builtin_runners.push(builtin.into()); run_context!(vm, 0, 9, 8); //Insert values into memory (excluding those from the program segment (instructions)) @@ -3424,8 +3413,7 @@ mod tests { fn deduce_memory_cell_ec_op_builtin_valid() { let mut vm = vm!(); let builtin = EcOpBuiltinRunner::new(&EcOpInstanceDef::default(), true); - vm.builtin_runners - .push((EC_OP_BUILTIN_NAME, builtin.into())); + vm.builtin_runners.push(builtin.into()); vm.segments = segments![ ( @@ -3496,8 +3484,7 @@ mod tests { let mut builtin = EcOpBuiltinRunner::new(&EcOpInstanceDef::default(), true); builtin.base = 3; let mut vm = vm!(); - vm.builtin_runners - .push((EC_OP_BUILTIN_NAME, builtin.into())); + vm.builtin_runners.push(builtin.into()); vm.segments = segments![ ( (3, 0), @@ -3545,8 +3532,7 @@ mod tests { let mut builtin = EcOpBuiltinRunner::new(&EcOpInstanceDef::default(), true); builtin.base = 3; let mut vm = vm!(); - vm.builtin_runners - .push((EC_OP_BUILTIN_NAME, builtin.into())); + vm.builtin_runners.push(builtin.into()); vm.segments = segments![ ( (3, 0), @@ -3621,8 +3607,7 @@ mod tests { let mut builtin = BitwiseBuiltinRunner::new(&BitwiseInstanceDef::default(), true); builtin.base = 2; let mut vm = vm!(); - vm.builtin_runners - .push((BITWISE_BUILTIN_NAME, builtin.into())); + vm.builtin_runners.push(builtin.into()); vm.segments = segments![((2, 0), 12), ((2, 1), 10)]; assert_matches!(vm.verify_auto_deductions(), Ok(())); } @@ -3686,7 +3671,7 @@ mod tests { let mut builtin = HashBuiltinRunner::new(8, true); builtin.base = 3; let mut vm = vm!(); - vm.builtin_runners.push((HASH_BUILTIN_NAME, builtin.into())); + vm.builtin_runners.push(builtin.into()); vm.segments = segments![((3, 0), 32), ((3, 1), 72)]; assert_matches!(vm.verify_auto_deductions(), Ok(())); } @@ -3820,15 +3805,13 @@ mod tests { let mut vm = vm!(); let hash_builtin = HashBuiltinRunner::new(8, true); let bitwise_builtin = BitwiseBuiltinRunner::new(&BitwiseInstanceDef::default(), true); - vm.builtin_runners - .push((HASH_BUILTIN_NAME, hash_builtin.into())); - vm.builtin_runners - .push((BITWISE_BUILTIN_NAME, bitwise_builtin.into())); + vm.builtin_runners.push(hash_builtin.into()); + vm.builtin_runners.push(bitwise_builtin.into()); let builtins = vm.get_builtin_runners(); - assert_eq!(builtins[0].0, HASH_BUILTIN_NAME); - assert_eq!(builtins[1].0, BITWISE_BUILTIN_NAME); + assert_eq!(builtins[0].name(), HASH_BUILTIN_NAME); + assert_eq!(builtins[1].name(), BITWISE_BUILTIN_NAME); } #[test] @@ -4268,10 +4251,7 @@ mod tests { let virtual_machine_builder: VirtualMachineBuilder = VirtualMachineBuilder::default() .run_finished(true) .current_step(12) - .builtin_runners(vec![( - "string", - BuiltinRunner::from(HashBuiltinRunner::new(12, true)), - )]) + .builtin_runners(vec![BuiltinRunner::from(HashBuiltinRunner::new(12, true))]) .run_context(RunContext { pc: Relocatable::from((0, 0)), ap: 18, @@ -4315,8 +4295,8 @@ mod tests { .builtin_runners .get(0) .unwrap() - .0, - "string" + .name(), + "pedersen" ); assert_eq!(virtual_machine_from_builder.run_context.ap, 18,); assert_eq!( From 4eae1b2afa3efec65bf13798330838937b7029ae Mon Sep 17 00:00:00 2001 From: fmoletta <99273364+fmoletta@users.noreply.github.com> Date: Mon, 27 Mar 2023 16:26:57 +0300 Subject: [PATCH 4/6] Remove unused struct `HintData` (#920) * Remove unused struct HintData * Fix typo --- src/vm/vm_core.rs | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/src/vm/vm_core.rs b/src/vm/vm_core.rs index 4449d1bd56..3485541233 100644 --- a/src/vm/vm_core.rs +++ b/src/vm/vm_core.rs @@ -2,7 +2,6 @@ use crate::stdlib::{any::Any, borrow::Cow, collections::HashMap, prelude::*}; use crate::{ hint_processor::hint_processor_definition::HintProcessor, - serde::deserialize_program::ApTracking, types::{ errors::math_errors::MathError, exec_scope::ExecutionScopes, @@ -72,14 +71,6 @@ impl DeducedOperands { } } -#[derive(Clone, Debug)] -pub struct HintData { - pub hint_code: String, - //Maps the name of the variable to its reference id - pub ids: HashMap, - pub ap_tracking_data: ApTracking, -} - pub struct VirtualMachine { pub(crate) run_context: RunContext, pub(crate) builtin_runners: Vec, @@ -93,20 +84,6 @@ pub struct VirtualMachine { pub(crate) hooks: crate::vm::hooks::Hooks, } -impl HintData { - pub fn new( - hint_code: &str, - ids: HashMap, - ap_tracking_data: ApTracking, - ) -> HintData { - HintData { - hint_code: hint_code.to_string(), - ids, - ap_tracking_data, - } - } -} - impl VirtualMachine { pub fn new(trace_enabled: bool) -> VirtualMachine { let run_context = RunContext { @@ -158,7 +135,7 @@ impl VirtualMachine { instruction: &Instruction, operands: &Operands, ) -> Result<(), VirtualMachineError> { - let new_fpset: usize = match instruction.fp_update { + let new_fp_offset: usize = match instruction.fp_update { FpUpdate::APPlus2 => self.run_context.ap + 2, FpUpdate::Dst => match operands.dst { MaybeRelocatable::RelocatableValue(ref rel) => rel.offset, @@ -168,7 +145,7 @@ impl VirtualMachine { }, FpUpdate::Regular => return Ok(()), }; - self.run_context.fp = new_fpset; + self.run_context.fp = new_fp_offset; Ok(()) } From e21192ed8cc7648cefa1befd7318a9bf476e5103 Mon Sep 17 00:00:00 2001 From: fmoletta <99273364+fmoletta@users.noreply.github.com> Date: Mon, 27 Mar 2023 16:27:36 +0300 Subject: [PATCH 5/6] Fix cairo constants being used in hints that import python constants (#919) * Use python constant * Fix tests * Use python constant SECP_P in field_utils * Stop using cairo constants in slipt fn * Use constant for N * Replace SEC_P with appropiate const * Fix tests * Update old hint code in comment --- .../builtin_hint_processor_definition.rs | 84 ++---- .../builtin_hint_processor/math_utils.rs | 30 ++- .../secp/bigint_utils.rs | 3 +- .../builtin_hint_processor/secp/ec_utils.rs | 244 ++---------------- .../secp/field_utils.rs | 213 ++------------- .../builtin_hint_processor/secp/secp_utils.rs | 54 ++-- .../builtin_hint_processor/secp/signature.rs | 167 +++--------- 7 files changed, 156 insertions(+), 639 deletions(-) diff --git a/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs b/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs index 40abaeddd9..f45fc40054 100644 --- a/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs +++ b/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs @@ -237,23 +237,13 @@ impl HintProcessor for BuiltinHintProcessor { hint_code::BLAKE2S_COMPUTE => { compute_blake2s(vm, &hint_data.ids_data, &hint_data.ap_tracking) } - hint_code::VERIFY_ZERO => { - verify_zero(vm, &hint_data.ids_data, &hint_data.ap_tracking, constants) + hint_code::VERIFY_ZERO => verify_zero(vm, &hint_data.ids_data, &hint_data.ap_tracking), + hint_code::NONDET_BIGINT3 => { + nondet_bigint3(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking) + } + hint_code::REDUCE => { + reduce(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking) } - hint_code::NONDET_BIGINT3 => nondet_bigint3( - vm, - exec_scopes, - &hint_data.ids_data, - &hint_data.ap_tracking, - constants, - ), - hint_code::REDUCE => reduce( - vm, - exec_scopes, - &hint_data.ids_data, - &hint_data.ap_tracking, - constants, - ), hint_code::BLAKE2S_FINALIZE => { finalize_blake2s(vm, &hint_data.ids_data, &hint_data.ap_tracking) } @@ -334,25 +324,18 @@ impl HintProcessor for BuiltinHintProcessor { hint_code::BIGINT_TO_UINT256 => { bigint_to_uint256(vm, &hint_data.ids_data, &hint_data.ap_tracking, constants) } - hint_code::IS_ZERO_PACK => is_zero_pack( - vm, - exec_scopes, - &hint_data.ids_data, - &hint_data.ap_tracking, - constants, - ), - hint_code::IS_ZERO_NONDET => is_zero_nondet(vm, exec_scopes), - hint_code::IS_ZERO_ASSIGN_SCOPE_VARS => { - is_zero_assign_scope_variables(exec_scopes, constants) + hint_code::IS_ZERO_PACK => { + is_zero_pack(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking) } + hint_code::IS_ZERO_NONDET => is_zero_nondet(vm, exec_scopes), + hint_code::IS_ZERO_ASSIGN_SCOPE_VARS => is_zero_assign_scope_variables(exec_scopes), hint_code::DIV_MOD_N_PACKED_DIVMOD => div_mod_n_packed_divmod( vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking, - constants, ), - hint_code::DIV_MOD_N_SAFE_DIV => div_mod_n_safe_div(exec_scopes, constants), + hint_code::DIV_MOD_N_SAFE_DIV => div_mod_n_safe_div(exec_scopes), hint_code::GET_POINT_FROM_X => get_point_from_x( vm, exec_scopes, @@ -360,35 +343,19 @@ impl HintProcessor for BuiltinHintProcessor { &hint_data.ap_tracking, constants, ), - hint_code::EC_NEGATE => ec_negate( - vm, - exec_scopes, - &hint_data.ids_data, - &hint_data.ap_tracking, - constants, - ), - hint_code::EC_DOUBLE_SCOPE => compute_doubling_slope( - vm, - exec_scopes, - &hint_data.ids_data, - &hint_data.ap_tracking, - constants, - ), - hint_code::COMPUTE_SLOPE => compute_slope( - vm, - exec_scopes, - &hint_data.ids_data, - &hint_data.ap_tracking, - constants, - ), - hint_code::EC_DOUBLE_ASSIGN_NEW_X => ec_double_assign_new_x( - vm, - exec_scopes, - &hint_data.ids_data, - &hint_data.ap_tracking, - constants, - ), - hint_code::EC_DOUBLE_ASSIGN_NEW_Y => ec_double_assign_new_y(exec_scopes, constants), + hint_code::EC_NEGATE => { + ec_negate(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking) + } + hint_code::EC_DOUBLE_SCOPE => { + compute_doubling_slope(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking) + } + hint_code::COMPUTE_SLOPE => { + compute_slope(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking) + } + hint_code::EC_DOUBLE_ASSIGN_NEW_X => { + ec_double_assign_new_x(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking) + } + hint_code::EC_DOUBLE_ASSIGN_NEW_Y => ec_double_assign_new_y(exec_scopes), hint_code::KECCAK_WRITE_ARGS => { keccak_write_args(vm, &hint_data.ids_data, &hint_data.ap_tracking) } @@ -424,9 +391,8 @@ impl HintProcessor for BuiltinHintProcessor { exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking, - constants, ), - hint_code::FAST_EC_ADD_ASSIGN_NEW_Y => fast_ec_add_assign_new_y(exec_scopes, constants), + hint_code::FAST_EC_ADD_ASSIGN_NEW_Y => fast_ec_add_assign_new_y(exec_scopes), hint_code::EC_MUL_INNER => { ec_mul_inner(vm, &hint_data.ids_data, &hint_data.ap_tracking) } diff --git a/src/hint_processor/builtin_hint_processor/math_utils.rs b/src/hint_processor/builtin_hint_processor/math_utils.rs index 8f91a97b60..d439668097 100644 --- a/src/hint_processor/builtin_hint_processor/math_utils.rs +++ b/src/hint_processor/builtin_hint_processor/math_utils.rs @@ -65,15 +65,29 @@ pub fn is_nn_out_of_range( }; insert_value_into_ap(vm, value) } -//Implements hint:from starkware.cairo.common.math_utils import assert_integer -// assert_integer(ids.a) -// assert_integer(ids.b) -// a = ids.a % PRIME -// b = ids.b % PRIME -// assert a <= b, f'a = {a} is not less than or equal to b = {b}.' -// ids.small_inputs = int( -// a < range_check_builtin.bound and (b - a) < range_check_builtin.bound) +/* Implements hint:from starkware.cairo.common.math_utils import assert_integer +%{ + import itertools + from starkware.cairo.common.math_utils import assert_integer + assert_integer(ids.a) + assert_integer(ids.b) + a = ids.a % PRIME + b = ids.b % PRIME + assert a <= b, f'a = {a} is not less than or equal to b = {b}.' + + # Find an arc less than PRIME / 3, and another less than PRIME / 2. + lengths_and_indices = [(a, 0), (b - a, 1), (PRIME - 1 - b, 2)] + lengths_and_indices.sort() + assert lengths_and_indices[0][0] <= PRIME // 3 and lengths_and_indices[1][0] <= PRIME // 2 + excluded = lengths_and_indices[2][1] + + memory[ids.range_check_ptr + 1], memory[ids.range_check_ptr + 0] = ( + divmod(lengths_and_indices[0][0], ids.PRIME_OVER_3_HIGH)) + memory[ids.range_check_ptr + 3], memory[ids.range_check_ptr + 2] = ( + divmod(lengths_and_indices[1][0], ids.PRIME_OVER_2_HIGH)) +%} +*/ pub fn assert_le_felt( vm: &mut VirtualMachine, exec_scopes: &mut ExecutionScopes, diff --git a/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs b/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs index c97dbf63f9..cdba93b806 100644 --- a/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs +++ b/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs @@ -66,14 +66,13 @@ pub fn nondet_bigint3( exec_scopes: &mut ExecutionScopes, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, ) -> Result<(), HintError> { let res_reloc = get_relocatable_from_var_name("res", vm, ids_data, ap_tracking)?; let value = exec_scopes .get_ref::("value")? .to_biguint() .ok_or(HintError::BigIntToBigUintFail)?; - let arg: Vec = split(&value, constants)? + let arg: Vec = split(&value)? .into_iter() .map(|n| MaybeRelocatable::from(Felt252::new(n))) .collect(); diff --git a/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs b/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs index c7711bfce0..cd41607005 100644 --- a/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs +++ b/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs @@ -1,15 +1,11 @@ -use crate::stdlib::{ - collections::HashMap, - ops::{BitAnd, Shl}, - prelude::*, -}; +use crate::stdlib::{collections::HashMap, ops::BitAnd, prelude::*}; use crate::{ hint_processor::{ builtin_hint_processor::{ hint_utils::{ get_integer_from_var_name, get_relocatable_from_var_name, insert_value_into_ap, }, - secp::secp_utils::{pack, SECP_REM}, + secp::secp_utils::pack, }, hint_processor_definition::HintReference, }, @@ -23,7 +19,7 @@ use num_bigint::BigInt; use num_integer::Integer; use num_traits::{One, Zero}; -use super::bigint_utils::BigInt3; +use super::{bigint_utils::BigInt3, secp_utils::SECP_P}; #[derive(Debug, PartialEq)] struct EcPoint<'a> { @@ -61,21 +57,12 @@ pub fn ec_negate( exec_scopes: &mut ExecutionScopes, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, ) -> Result<(), HintError> { - #[allow(deprecated)] - let secp_p = num_bigint::BigInt::one().shl(256u32) - - constants - .get(SECP_REM) - .ok_or(HintError::MissingConstant(SECP_REM))? - .clone() - .to_bigint(); - //ids.point let point_y = (get_relocatable_from_var_name("point", vm, ids_data, ap_tracking)? + 3i32)?; let y_bigint3 = BigInt3::from_base_addr(point_y, "point.y", vm)?; let y = pack(y_bigint3); - let value = (-y).mod_floor(&secp_p); + let value = (-y).mod_floor(&SECP_P); exec_scopes.insert_value("value", value); Ok(()) } @@ -97,19 +84,11 @@ pub fn compute_doubling_slope( exec_scopes: &mut ExecutionScopes, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, ) -> Result<(), HintError> { - #[allow(deprecated)] - let secp_p = num_bigint::BigInt::one().shl(256usize) - - constants - .get(SECP_REM) - .ok_or(HintError::MissingConstant(SECP_REM))? - .to_bigint(); - //ids.point let point = EcPoint::from_var_name("point", vm, ids_data, ap_tracking)?; - let value = ec_double_slope(&(pack(point.x), pack(point.y)), &BigInt::zero(), &secp_p); + let value = ec_double_slope(&(pack(point.x), pack(point.y)), &BigInt::zero(), &SECP_P); exec_scopes.insert_value("value", value.clone()); exec_scopes.insert_value("slope", value); Ok(()) @@ -134,15 +113,7 @@ pub fn compute_slope( exec_scopes: &mut ExecutionScopes, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, ) -> Result<(), HintError> { - #[allow(deprecated)] - let secp_p = BigInt::one().shl(256usize) - - constants - .get(SECP_REM) - .ok_or(HintError::MissingConstant(SECP_REM))? - .to_bigint(); - //ids.point0 let point0 = EcPoint::from_var_name("point0", vm, ids_data, ap_tracking)?; //ids.point1 @@ -151,7 +122,7 @@ pub fn compute_slope( let value = line_slope( &(pack(point0.x), pack(point0.y)), &(pack(point1.x), pack(point1.y)), - &secp_p, + &SECP_P, ); exec_scopes.insert_value("value", value.clone()); exec_scopes.insert_value("slope", value); @@ -175,15 +146,7 @@ pub fn ec_double_assign_new_x( exec_scopes: &mut ExecutionScopes, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, ) -> Result<(), HintError> { - #[allow(deprecated)] - let secp_p = BigInt::one().shl(256usize) - - constants - .get(SECP_REM) - .ok_or(HintError::MissingConstant(SECP_REM))? - .to_bigint(); - //ids.slope let slope = BigInt3::from_var_name("slope", vm, ids_data, ap_tracking)?; //ids.point @@ -193,7 +156,7 @@ pub fn ec_double_assign_new_x( let x = pack(point.x); let y = pack(point.y); - let value = (slope.pow(2) - (&x << 1u32)).mod_floor(&secp_p); + let value = (slope.pow(2) - (&x << 1u32)).mod_floor(&SECP_P); //Assign variables to vm scope exec_scopes.insert_value("slope", slope); @@ -208,17 +171,7 @@ pub fn ec_double_assign_new_x( Implements hint: %{ value = new_y = (slope * (x - new_x) - y) % SECP_P %} */ -pub fn ec_double_assign_new_y( - exec_scopes: &mut ExecutionScopes, - constants: &HashMap, -) -> Result<(), HintError> { - #[allow(deprecated)] - let secp_p = BigInt::one().shl(256usize) - - constants - .get(SECP_REM) - .ok_or(HintError::MissingConstant(SECP_REM))? - .to_bigint(); - +pub fn ec_double_assign_new_y(exec_scopes: &mut ExecutionScopes) -> Result<(), HintError> { //Get variables from vm scope let (slope, x, new_x, y) = ( exec_scopes.get::("slope")?, @@ -227,7 +180,7 @@ pub fn ec_double_assign_new_y( exec_scopes.get::("y")?, ); - let value = (slope * (x - new_x) - y).mod_floor(&secp_p); + let value = (slope * (x - new_x) - y).mod_floor(&SECP_P); exec_scopes.insert_value("value", value.clone()); exec_scopes.insert_value("new_y", value); Ok(()) @@ -251,15 +204,7 @@ pub fn fast_ec_add_assign_new_x( exec_scopes: &mut ExecutionScopes, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, ) -> Result<(), HintError> { - #[allow(deprecated)] - let secp_p = BigInt::one().shl(256usize) - - constants - .get(SECP_REM) - .ok_or(HintError::MissingConstant(SECP_REM))? - .to_bigint(); - //ids.slope let slope = BigInt3::from_var_name("slope", vm, ids_data, ap_tracking)?; //ids.point0 @@ -272,7 +217,7 @@ pub fn fast_ec_add_assign_new_x( let x1 = pack(point1.x); let y0 = pack(point0.y); - let value = (&slope * &slope - &x0 - &x1).mod_floor(&secp_p); + let value = (&slope * &slope - &x0 - &x1).mod_floor(&SECP_P); //Assign variables to vm scope exec_scopes.insert_value("slope", slope); exec_scopes.insert_value("x0", x0); @@ -287,17 +232,7 @@ pub fn fast_ec_add_assign_new_x( Implements hint: %{ value = new_y = (slope * (x0 - new_x) - y0) % SECP_P %} */ -pub fn fast_ec_add_assign_new_y( - exec_scopes: &mut ExecutionScopes, - constants: &HashMap, -) -> Result<(), HintError> { - #[allow(deprecated)] - let secp_p = BigInt::one().shl(256usize) - - constants - .get(SECP_REM) - .ok_or(HintError::MissingConstant(SECP_REM))? - .to_bigint(); - +pub fn fast_ec_add_assign_new_y(exec_scopes: &mut ExecutionScopes) -> Result<(), HintError> { //Get variables from vm scope let (slope, x0, new_x, y0) = ( exec_scopes.get::("slope")?, @@ -305,7 +240,7 @@ pub fn fast_ec_add_assign_new_y( exec_scopes.get::("new_x")?, exec_scopes.get::("y0")?, ); - let value = (slope * (x0 - new_x) - y0).mod_floor(&secp_p); + let value = (slope * (x0 - new_x) - y0).mod_floor(&SECP_P); exec_scopes.insert_value("value", value.clone()); exec_scopes.insert_value("new_y", value); @@ -369,28 +304,7 @@ mod tests { let ids_data = ids_data!["point"]; let mut exec_scopes = ExecutionScopes::new(); //Execute the hint - assert_matches!( - run_hint!( - vm, - ids_data, - hint_code, - &mut exec_scopes, - &[( - SECP_REM, - Felt252::one().shl(32_u32) - + Felt252::one().shl(9_u32) - + Felt252::one().shl(8_u32) - + Felt252::one().shl(7_u32) - + Felt252::one().shl(6_u32) - + Felt252::one().shl(4_u32) - + Felt252::one() - )] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() - ), - Ok(()) - ); + assert_matches!(run_hint!(vm, ids_data, hint_code, &mut exec_scopes), Ok(())); //Check 'value' is defined in the vm scope assert_matches!( exec_scopes.get::("value"), @@ -421,28 +335,7 @@ mod tests { let mut exec_scopes = ExecutionScopes::new(); //Execute the hint - assert_matches!( - run_hint!( - vm, - ids_data, - hint_code, - &mut exec_scopes, - &[( - SECP_REM, - Felt252::one().shl(32_u32) - + Felt252::one().shl(9_u32) - + Felt252::one().shl(8_u32) - + Felt252::one().shl(7_u32) - + Felt252::one().shl(6_u32) - + Felt252::one().shl(4_u32) - + Felt252::one() - )] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() - ), - Ok(()) - ); + assert_matches!(run_hint!(vm, ids_data, hint_code, &mut exec_scopes), Ok(())); check_scope!( &exec_scopes, [ @@ -493,28 +386,7 @@ mod tests { let mut exec_scopes = ExecutionScopes::new(); //Execute the hint - assert_matches!( - run_hint!( - vm, - ids_data, - hint_code, - &mut exec_scopes, - &[( - SECP_REM, - Felt252::one().shl(32_u32) - + Felt252::one().shl(9_u32) - + Felt252::one().shl(8_u32) - + Felt252::one().shl(7_u32) - + Felt252::one().shl(6_u32) - + Felt252::one().shl(4_u32) - + Felt252::one() - )] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() - ), - Ok(()) - ); + assert_matches!(run_hint!(vm, ids_data, hint_code, &mut exec_scopes), Ok(())); check_scope!( &exec_scopes, [ @@ -562,28 +434,7 @@ mod tests { let mut exec_scopes = ExecutionScopes::new(); //Execute the hint - assert_matches!( - run_hint!( - vm, - ids_data, - hint_code, - &mut exec_scopes, - &[( - SECP_REM, - Felt252::one().shl(32_u32) - + Felt252::one().shl(9_u32) - + Felt252::one().shl(8_u32) - + Felt252::one().shl(7_u32) - + Felt252::one().shl(6_u32) - + Felt252::one().shl(4_u32) - + Felt252::one() - )] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() - ), - Ok(()) - ); + assert_matches!(run_hint!(vm, ids_data, hint_code, &mut exec_scopes), Ok(())); check_scope!( &exec_scopes, @@ -647,25 +498,7 @@ mod tests { ]; //Execute the hint assert_matches!( - run_hint!( - vm, - HashMap::new(), - hint_code, - &mut exec_scopes, - &[( - SECP_REM, - Felt252::one().shl(32_u32) - + Felt252::one().shl(9_u32) - + Felt252::one().shl(8_u32) - + Felt252::one().shl(7_u32) - + Felt252::one().shl(6_u32) - + Felt252::one().shl(4_u32) - + Felt252::one() - )] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() - ), + run_hint!(vm, HashMap::new(), hint_code, &mut exec_scopes), Ok(()) ); @@ -724,28 +557,7 @@ mod tests { let mut exec_scopes = ExecutionScopes::new(); //Execute the hint - assert_matches!( - run_hint!( - vm, - ids_data, - hint_code, - &mut exec_scopes, - &[( - SECP_REM, - Felt252::one().shl(32_u32) - + Felt252::one().shl(9_u32) - + Felt252::one().shl(8_u32) - + Felt252::one().shl(7_u32) - + Felt252::one().shl(6_u32) - + Felt252::one().shl(4_u32) - + Felt252::one() - )] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() - ), - Ok(()) - ); + assert_matches!(run_hint!(vm, ids_data, hint_code, &mut exec_scopes), Ok(())); check_scope!( &exec_scopes, @@ -797,25 +609,7 @@ mod tests { //Execute the hint assert_matches!( - run_hint!( - vm, - HashMap::new(), - hint_code, - &mut exec_scopes, - &[( - SECP_REM, - Felt252::one().shl(32_u32) - + Felt252::one().shl(9_u32) - + Felt252::one().shl(8_u32) - + Felt252::one().shl(7_u32) - + Felt252::one().shl(6_u32) - + Felt252::one().shl(4_u32) - + Felt252::one() - )] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() - ), + run_hint!(vm, HashMap::new(), hint_code, &mut exec_scopes), Ok(()) ); diff --git a/src/hint_processor/builtin_hint_processor/secp/field_utils.rs b/src/hint_processor/builtin_hint_processor/secp/field_utils.rs index a4472985b6..da4080c388 100644 --- a/src/hint_processor/builtin_hint_processor/secp/field_utils.rs +++ b/src/hint_processor/builtin_hint_processor/secp/field_utils.rs @@ -1,11 +1,8 @@ -use crate::stdlib::{collections::HashMap, ops::Shl, prelude::*}; +use crate::stdlib::{collections::HashMap, prelude::*}; use crate::{ hint_processor::{ - builtin_hint_processor::{ - hint_utils::{insert_value_from_var_name, insert_value_into_ap}, - secp::secp_utils::SECP_REM, - }, + builtin_hint_processor::hint_utils::{insert_value_from_var_name, insert_value_into_ap}, hint_processor_definition::HintReference, }, math_utils::div_mod, @@ -18,6 +15,7 @@ use num_bigint::BigInt; use num_integer::Integer; use num_traits::{One, Zero}; +use super::secp_utils::SECP_P; use super::{bigint_utils::BigInt3, secp_utils::pack}; /* @@ -34,17 +32,9 @@ pub fn verify_zero( vm: &mut VirtualMachine, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, ) -> Result<(), HintError> { - #[allow(deprecated)] - let secp_p = BigInt::one().shl(256_u32) - - constants - .get(SECP_REM) - .ok_or(HintError::MissingConstant(SECP_REM))? - .to_bigint(); - let val = pack(BigInt3::from_var_name("val", vm, ids_data, ap_tracking)?); - let (q, r) = val.div_rem(&secp_p); + let (q, r) = val.div_rem(&SECP_P); if !r.is_zero() { return Err(HintError::SecpVerifyZero(val)); } @@ -65,17 +55,9 @@ pub fn reduce( exec_scopes: &mut ExecutionScopes, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, ) -> Result<(), HintError> { - #[allow(deprecated)] - let secp_p = num_bigint::BigInt::one().shl(256_u32) - - constants - .get(SECP_REM) - .ok_or(HintError::MissingConstant(SECP_REM))? - .to_bigint(); - let value = pack(BigInt3::from_var_name("x", vm, ids_data, ap_tracking)?); - exec_scopes.insert_value("value", value.mod_floor(&secp_p)); + exec_scopes.insert_value("value", value.mod_floor(&SECP_P)); Ok(()) } @@ -92,17 +74,9 @@ pub fn is_zero_pack( exec_scopes: &mut ExecutionScopes, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, ) -> Result<(), HintError> { - #[allow(deprecated)] - let secp_p = BigInt::one().shl(256_u32) - - constants - .get(SECP_REM) - .ok_or(HintError::MissingConstant(SECP_REM))? - .to_bigint(); - let x_packed = pack(BigInt3::from_var_name("x", vm, ids_data, ap_tracking)?); - let x = x_packed.mod_floor(&secp_p); + let x = x_packed.mod_floor(&SECP_P); exec_scopes.insert_value("x", x); Ok(()) } @@ -139,21 +113,11 @@ Implements hint: value = x_inv = div_mod(1, x, SECP_P) %} */ -pub fn is_zero_assign_scope_variables( - exec_scopes: &mut ExecutionScopes, - constants: &HashMap, -) -> Result<(), HintError> { - #[allow(deprecated)] - let secp_p = BigInt::one().shl(256_u32) - - constants - .get(SECP_REM) - .ok_or(HintError::MissingConstant(SECP_REM))? - .to_bigint(); - +pub fn is_zero_assign_scope_variables(exec_scopes: &mut ExecutionScopes) -> Result<(), HintError> { //Get `x` variable from vm scope let x = exec_scopes.get::("x")?; - let value = div_mod(&BigInt::one(), &x, &secp_p); + let value = div_mod(&BigInt::one(), &x, &SECP_P); exec_scopes.insert_value("value", value.clone()); exec_scopes.insert_value("x_inv", value); Ok(()) @@ -199,25 +163,7 @@ mod tests { vm.segments = segments![((1, 4), 0), ((1, 5), 0), ((1, 6), 0)]; //Execute the hint assert_matches!( - run_hint!( - vm, - ids_data, - hint_code, - exec_scopes_ref!(), - &[( - SECP_REM, - Felt252::one().shl(32_u32) - + Felt252::one().shl(9_u32) - + Felt252::one().shl(8_u32) - + Felt252::one().shl(7_u32) - + Felt252::one().shl(6_u32) - + Felt252::one().shl(4_u32) - + Felt252::one() - )] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() - ), + run_hint!(vm, ids_data, hint_code, exec_scopes_ref!()), Ok(()) ); //Check hint memory inserts @@ -242,20 +188,7 @@ mod tests { vm, ids_data, hint_code, - exec_scopes_ref!(), - &[( - SECP_REM, - Felt252::one().shl(32_u32) - + Felt252::one().shl(9_u32) - + Felt252::one().shl(8_u32) - + Felt252::one().shl(7_u32) - + Felt252::one().shl(6_u32) - + Felt252::one().shl(4_u32) - + Felt252::one() - )] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() + exec_scopes_ref!() ), Err(HintError::SecpVerifyZero(x)) if x == bigint_str!( "897946605976106752944343961220884287276604954404454400" @@ -282,20 +215,7 @@ mod tests { vm, ids_data, hint_code, - exec_scopes_ref!(), - &[( - SECP_REM, - Felt252::one().shl(32_u32) - + Felt252::one().shl(9_u32) - + Felt252::one().shl(8_u32) - + Felt252::one().shl(7_u32) - + Felt252::one().shl(6_u32) - + Felt252::one().shl(4_u32) - + Felt252::one() - )] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() + exec_scopes_ref!() ), Err(HintError::Memory( MemoryError::InconsistentMemory( @@ -331,28 +251,7 @@ mod tests { let mut exec_scopes = ExecutionScopes::new(); //Execute the hint - assert_matches!( - run_hint!( - vm, - ids_data, - hint_code, - &mut exec_scopes, - &[( - SECP_REM, - Felt252::one().shl(32_u32) - + Felt252::one().shl(9_u32) - + Felt252::one().shl(8_u32) - + Felt252::one().shl(7_u32) - + Felt252::one().shl(6_u32) - + Felt252::one().shl(4_u32) - + Felt252::one() - )] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() - ), - Ok(()) - ); + assert_matches!(run_hint!(vm, ids_data, hint_code, &mut exec_scopes), Ok(())); //Check 'value' is defined in the vm scope assert_matches!( @@ -382,20 +281,7 @@ mod tests { vm, ids_data, hint_code, - exec_scopes_ref!(), - &[( - SECP_REM, - Felt252::one().shl(32_u32) - + Felt252::one().shl(9_u32) - + Felt252::one().shl(8_u32) - + Felt252::one().shl(7_u32) - + Felt252::one().shl(6_u32) - + Felt252::one().shl(4_u32) - + Felt252::one() - )] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() + exec_scopes_ref!() ), Err(HintError::IdentifierHasNoMember(x, y )) if x == "x" && y == "d0" @@ -423,28 +309,7 @@ mod tests { let mut exec_scopes = ExecutionScopes::new(); //Execute the hint - assert_matches!( - run_hint!( - vm, - ids_data, - hint_code, - &mut exec_scopes, - &[( - SECP_REM, - Felt252::one().shl(32_u32) - + Felt252::one().shl(9_u32) - + Felt252::one().shl(8_u32) - + Felt252::one().shl(7_u32) - + Felt252::one().shl(6_u32) - + Felt252::one().shl(4_u32) - + Felt252::one() - )] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() - ), - Ok(()) - ); + assert_matches!(run_hint!(vm, ids_data, hint_code, &mut exec_scopes), Ok(())); //Check 'x' is defined in the vm scope check_scope!( @@ -478,20 +343,7 @@ mod tests { vm, ids_data, hint_code, - exec_scopes_ref!(), - &[( - SECP_REM, - Felt252::one().shl(32_u32) - + Felt252::one().shl(9_u32) - + Felt252::one().shl(8_u32) - + Felt252::one().shl(7_u32) - + Felt252::one().shl(6_u32) - + Felt252::one().shl(4_u32) - + Felt252::one() - )] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() + exec_scopes_ref!() ), Err(HintError::IdentifierHasNoMember(x, y )) if x == "x" && y == "d0" @@ -620,25 +472,7 @@ mod tests { ); //Execute the hint assert_matches!( - run_hint!( - vm, - HashMap::new(), - hint_code, - &mut exec_scopes, - &[( - SECP_REM, - Felt252::one().shl(32_u32) - + Felt252::one().shl(9_u32) - + Felt252::one().shl(8_u32) - + Felt252::one().shl(7_u32) - + Felt252::one().shl(6_u32) - + Felt252::one().shl(4_u32) - + Felt252::one() - )] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() - ), + run_hint!(vm, HashMap::new(), hint_code, &mut exec_scopes), Ok(()) ); @@ -671,20 +505,7 @@ mod tests { vm, HashMap::new(), hint_code, - exec_scopes_ref!(), - &[( - SECP_REM, - Felt252::one().shl(32_u32) - + Felt252::one().shl(9_u32) - + Felt252::one().shl(8_u32) - + Felt252::one().shl(7_u32) - + Felt252::one().shl(6_u32) - + Felt252::one().shl(4_u32) - + Felt252::one() - )] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() + exec_scopes_ref!() ), Err(HintError::VariableNotInScopeError(x)) if x == *"x".to_string() ); diff --git a/src/hint_processor/builtin_hint_processor/secp/secp_utils.rs b/src/hint_processor/builtin_hint_processor/secp/secp_utils.rs index e2613998bf..fc0411bc13 100644 --- a/src/hint_processor/builtin_hint_processor/secp/secp_utils.rs +++ b/src/hint_processor/builtin_hint_processor/secp/secp_utils.rs @@ -1,8 +1,11 @@ -use crate::stdlib::{collections::HashMap, ops::Shl, prelude::*}; +use core::str::FromStr; + +use crate::stdlib::{ops::Shl, prelude::*}; use crate::vm::errors::hint_errors::HintError; -use felt::Felt252; +use lazy_static::lazy_static; +use num_bigint::{BigInt, BigUint}; use num_traits::Zero; use super::bigint_utils::BigInt3; @@ -17,27 +20,39 @@ pub const P0: &str = "starkware.cairo.common.cairo_secp.constants.P0"; pub const P1: &str = "starkware.cairo.common.cairo_secp.constants.P1"; pub const P2: &str = "starkware.cairo.common.cairo_secp.constants.P2"; pub const SECP_REM: &str = "starkware.cairo.common.cairo_secp.constants.SECP_REM"; +// Constants in package "starkware.cairo.common.cairo_secp.secp_utils" +lazy_static! { + //SECP_P = 2**256 - 2**32 - 2**9 - 2**8 - 2**7 - 2**6 - 2**4 - 1 + pub(crate) static ref SECP_P: BigInt = BigInt::from_str( + "115792089237316195423570985008687907853269984665640564039457584007908834671663" + ) + .unwrap(); + // BASE = 2**86 + pub(crate) static ref BASE: BigUint = BigUint::from_str( + "77371252455336267181195264" + ).unwrap(); + + // Convenience constant BASE - 1 + pub(crate) static ref BASE_MINUS_ONE: BigUint = BigUint::from_str( + "77371252455336267181195263" + ).unwrap(); + // N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 + pub(crate) static ref N: BigInt = BigInt::from_str( + "115792089237316195423570985008687907852837564279074904382605163141518161494337" + ) +.unwrap(); +} /* Takes a 256-bit integer and returns its canonical representation as: d0 + BASE * d1 + BASE**2 * d2, where BASE = 2**86. */ -pub fn split( - integer: &num_bigint::BigUint, - constants: &HashMap, -) -> Result<[num_bigint::BigUint; 3], HintError> { - #[allow(deprecated)] - let base_86_max = constants - .get(BASE_86) - .ok_or(HintError::MissingConstant(BASE_86))? - .to_biguint() - - 1_u32; - +pub fn split(integer: &num_bigint::BigUint) -> Result<[num_bigint::BigUint; 3], HintError> { let mut canonical_repr: [num_bigint::BigUint; 3] = Default::default(); let mut num = integer.clone(); for item in &mut canonical_repr { - *item = &num & &base_86_max; + *item = &num & &*BASE_MINUS_ONE; num >>= 86_usize; } @@ -65,13 +80,13 @@ pub(crate) fn pack(num: BigInt3) -> num_bigint::BigInt { #[cfg(test)] mod tests { use super::*; - use crate::stdlib::{borrow::Cow, string::ToString}; + use crate::stdlib::{borrow::Cow, collections::HashMap, string::ToString}; use crate::utils::test_utils::*; use assert_matches::assert_matches; - use felt::felt_str; + use felt::{felt_str, Felt252}; use num_bigint::BigUint; - use num_traits::One; + use num_traits::One; #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::*; @@ -81,20 +96,18 @@ mod tests { let mut constants = HashMap::new(); constants.insert(BASE_86.to_string(), Felt252::one() << 86_usize); - let array_1 = split(&BigUint::zero(), &constants); + let array_1 = split(&BigUint::zero()); #[allow(deprecated)] let array_2 = split( &bigint!(999992) .to_biguint() .expect("Couldn't convert to BigUint"), - &constants, ); #[allow(deprecated)] let array_3 = split( &bigint_str!("7737125245533626718119526477371252455336267181195264773712524553362") .to_biguint() .expect("Couldn't convert to BigUint"), - &constants, ); //TODO, Check SecpSplitutOfRange limit #[allow(deprecated)] @@ -104,7 +117,6 @@ mod tests { ) .to_biguint() .expect("Couldn't convert to BigUint"), - &constants, ); assert_matches!( diff --git a/src/hint_processor/builtin_hint_processor/secp/signature.rs b/src/hint_processor/builtin_hint_processor/secp/signature.rs index 7a84441921..1f65e56e85 100644 --- a/src/hint_processor/builtin_hint_processor/secp/signature.rs +++ b/src/hint_processor/builtin_hint_processor/secp/signature.rs @@ -1,14 +1,10 @@ -use crate::stdlib::{ - collections::HashMap, - ops::{Shl, Shr}, - prelude::*, -}; +use crate::stdlib::{collections::HashMap, ops::Shr, prelude::*}; use crate::{ hint_processor::{ builtin_hint_processor::{ hint_utils::get_integer_from_var_name, - secp::secp_utils::{pack, BASE_86, BETA, N0, N1, N2, SECP_REM}, + secp::secp_utils::{pack, BETA}, }, hint_processor_definition::HintReference, }, @@ -21,9 +17,11 @@ use crate::{ use felt::Felt252; use num_bigint::BigInt; use num_integer::Integer; -use num_traits::One; -use super::bigint_utils::BigInt3; +use super::{ + bigint_utils::BigInt3, + secp_utils::{N, SECP_P}, +}; /* Implements hint: from starkware.cairo.common.cairo_secp.secp_utils import N, pack @@ -38,34 +36,11 @@ pub fn div_mod_n_packed_divmod( exec_scopes: &mut ExecutionScopes, ids_data: &HashMap, ap_tracking: &ApTracking, - constants: &HashMap, ) -> Result<(), HintError> { let a = pack(BigInt3::from_var_name("a", vm, ids_data, ap_tracking)?); let b = pack(BigInt3::from_var_name("b", vm, ids_data, ap_tracking)?); - #[allow(deprecated)] - let n = { - let base = constants - .get(BASE_86) - .ok_or(HintError::MissingConstant(BASE_86))? - .to_bigint(); - let n0 = constants - .get(N0) - .ok_or(HintError::MissingConstant(N0))? - .to_bigint(); - let n1 = constants - .get(N1) - .ok_or(HintError::MissingConstant(N1))? - .to_bigint(); - let n2 = constants - .get(N2) - .ok_or(HintError::MissingConstant(N2))? - .to_bigint(); - - (n2 * &base * &base) | (n1 * base) | n0 - }; - - let value = div_mod(&a, &b, &n); + let value = div_mod(&a, &b, &N); exec_scopes.insert_value("a", a); exec_scopes.insert_value("b", b); exec_scopes.insert_value("value", value.clone()); @@ -75,42 +50,32 @@ pub fn div_mod_n_packed_divmod( // Implements hint: // value = k = safe_div(res * b - a, N) -pub fn div_mod_n_safe_div( - exec_scopes: &mut ExecutionScopes, - constants: &HashMap, -) -> Result<(), HintError> { +pub fn div_mod_n_safe_div(exec_scopes: &mut ExecutionScopes) -> Result<(), HintError> { let a = exec_scopes.get_ref::("a")?; let b = exec_scopes.get_ref::("b")?; let res = exec_scopes.get_ref::("res")?; - #[allow(deprecated)] - let n = { - let base = constants - .get(BASE_86) - .ok_or(HintError::MissingConstant(BASE_86))? - .to_bigint(); - let n0 = constants - .get(N0) - .ok_or(HintError::MissingConstant(N0))? - .to_bigint(); - let n1 = constants - .get(N1) - .ok_or(HintError::MissingConstant(N1))? - .to_bigint(); - let n2 = constants - .get(N2) - .ok_or(HintError::MissingConstant(N2))? - .to_bigint(); - - n2 * &base * &base + n1 * base + n0 - }; - - let value = safe_div_bigint(&(res * b - a), &n)?; + let value = safe_div_bigint(&(res * b - a), &N)?; exec_scopes.insert_value("value", value); Ok(()) } +/* Implements hint: +%{ + from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack + + x_cube_int = pack(ids.x_cube, PRIME) % SECP_P + y_square_int = (x_cube_int + ids.BETA) % SECP_P + y = pow(y_square_int, (SECP_P + 1) // 4, SECP_P) + + # We need to decide whether to take y or SECP_P - y. + if ids.v % 2 == y % 2: + value = y + else: + value = (-y) % SECP_P +%} +*/ pub fn get_point_from_x( vm: &mut VirtualMachine, exec_scopes: &mut ExecutionScopes, @@ -123,25 +88,17 @@ pub fn get_point_from_x( .get(BETA) .ok_or(HintError::MissingConstant(BETA))? .to_bigint(); - #[allow(deprecated)] - let secp_p = BigInt::one().shl(256_u32) - - constants - .get(SECP_REM) - .ok_or(HintError::MissingConstant(SECP_REM))? - .to_bigint(); let x_cube_int = - pack(BigInt3::from_var_name("x_cube", vm, ids_data, ap_tracking)?).mod_floor(&secp_p); - //.mod_floor(&BigInt::from_biguint(num_bigint::Sign::Plus, secp_p.clone())) - //.to_biguint().ok_or(VirtualMachineError::BigIntToBigUintFail)?; - let y_cube_int = (x_cube_int + beta).mod_floor(&secp_p); + pack(BigInt3::from_var_name("x_cube", vm, ids_data, ap_tracking)?).mod_floor(&SECP_P); + let y_cube_int = (x_cube_int + beta).mod_floor(&SECP_P); // Divide by 4 - let mut y = y_cube_int.modpow(&(&secp_p + 1_u32).shr(2_u32), &secp_p); + let mut y = y_cube_int.modpow(&(&*SECP_P + 1_u32).shr(2_u32), &SECP_P); #[allow(deprecated)] let v = get_integer_from_var_name("v", vm, ids_data, ap_tracking)?.to_biguint(); if v.is_even() != y.is_even() { - y = &secp_p - y; + y = &*SECP_P - y; } exec_scopes.insert_value("value", y); Ok(()) @@ -150,7 +107,6 @@ pub fn get_point_from_x( #[cfg(test)] mod tests { use super::*; - use crate::stdlib::ops::Shl; use crate::stdlib::string::ToString; use crate::types::errors::math_errors::MathError; use crate::vm::vm_memory::memory_segments::MemorySegmentManager; @@ -168,7 +124,7 @@ mod tests { vm::{errors::memory_errors::MemoryError, vm_memory::memory::Memory}, }; use assert_matches::assert_matches; - use num_traits::Zero; + use num_traits::{One, Zero}; #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::*; @@ -190,20 +146,8 @@ mod tests { vm.run_context.fp = 3; let ids_data = non_continuous_ids_data![("a", -3), ("b", 0)]; let mut exec_scopes = ExecutionScopes::new(); - let constants = [ - (BASE_86, Felt252::one().shl(86_u32)), - (N0, Felt252::new(10428087374290690730508609u128)), - (N1, Felt252::new(77371252455330678278691517u128)), - (N2, Felt252::new(19342813113834066795298815u128)), - ] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect(); - assert_matches!( - run_hint!(vm, ids_data, hint_code, &mut exec_scopes, &constants), - Ok(()) - ); - assert_matches!(div_mod_n_safe_div(&mut exec_scopes, &constants), Ok(())); + assert_matches!(run_hint!(vm, ids_data, hint_code, &mut exec_scopes), Ok(())); + assert_matches!(div_mod_n_safe_div(&mut exec_scopes), Ok(())); } #[test] @@ -217,15 +161,6 @@ mod tests { assert_matches!( div_mod_n_safe_div( &mut exec_scopes, - &[ - (BASE_86, Felt252::one().shl(86_u32)), - (N0, Felt252::new(10428087374290690730508609u128)), - (N1, Felt252::new(77371252455330678278691517u128)), - (N2, Felt252::new(19342813113834066795298815u128)), - ] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() ), Err( HintError::Math(MathError::SafeDivFailBigInt( @@ -255,22 +190,10 @@ mod tests { ids_data, hint_code, exec_scopes_ref!(), - &[ - (BETA, Felt252::new(7)), - ( - SECP_REM, - Felt252::one().shl(32_u32) - + Felt252::one().shl(9_u32) - + Felt252::one().shl(8_u32) - + Felt252::one().shl(7_u32) - + Felt252::one().shl(6_u32) - + Felt252::one().shl(4_u32) - + Felt252::one() - ), - ] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() + &[(BETA, Felt252::new(7)),] + .into_iter() + .map(|(k, v)| (k.to_string(), v)) + .collect() ), Ok(()) ) @@ -297,22 +220,10 @@ mod tests { ids_data, hint_code, &mut exec_scopes, - &[ - (BETA, Felt252::new(7)), - ( - SECP_REM, - Felt252::one().shl(32_u32) - + Felt252::one().shl(9_u32) - + Felt252::one().shl(8_u32) - + Felt252::one().shl(7_u32) - + Felt252::one().shl(6_u32) - + Felt252::one().shl(4_u32) - + Felt252::one() - ), - ] - .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .collect() + &[(BETA, Felt252::new(7)),] + .into_iter() + .map(|(k, v)| (k.to_string(), v)) + .collect() ), Ok(()) ); From 6e5340ac5ce0ab3106bb7827c63be403e78b5690 Mon Sep 17 00:00:00 2001 From: Mario Rugiero Date: Mon, 27 Mar 2023 10:28:24 -0300 Subject: [PATCH 6/6] Derive Deserialize for ExecutionResources (#922) --- src/vm/runners/cairo_runner.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vm/runners/cairo_runner.rs b/src/vm/runners/cairo_runner.rs index 07dcd68fe4..a8714e69d4 100644 --- a/src/vm/runners/cairo_runner.rs +++ b/src/vm/runners/cairo_runner.rs @@ -45,6 +45,7 @@ use crate::{ use felt::Felt252; use num_integer::div_rem; use num_traits::Zero; +use serde::Deserialize; use super::builtin_runner::KeccakBuiltinRunner; @@ -1012,7 +1013,7 @@ pub struct SegmentInfo { //* ExecutionResources //* ---------------------- -#[derive(Clone, Debug, Eq, PartialEq, Default)] +#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)] pub struct ExecutionResources { pub n_steps: usize, pub n_memory_holes: usize,