diff --git a/Cargo.lock b/Cargo.lock index 9567c7acc4..3b9b21955a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2565,7 +2565,7 @@ dependencies = [ [[package]] name = "stark-felt" version = "0.0.3" -source = "git+https://github.com/lambdaclass/types-rs.git?rev=c2945cfde8fe12744e934e60a2366abbd6250524#c2945cfde8fe12744e934e60a2366abbd6250524" +source = "git+https://github.com/lambdaclass/types-rs.git?rev=ea52b64a52fd832222adf400feb2dd3b4dc286a2#ea52b64a52fd832222adf400feb2dd3b4dc286a2" dependencies = [ "arbitrary", "bitvec", diff --git a/Cargo.toml b/Cargo.toml index be825903d1..e51bbe408f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,9 +25,6 @@ readme = "README.md" keywords = ["starknet", "cairo", "vm", "wasm", "no_std"] [workspace.dependencies] -felt = { package = "cairo-felt", path = "./felt", version = "0.9.0", default-features = false, features = [ - "alloc", -] } cairo-vm = { path = "./vm", version = "0.9.0", default-features = false } mimalloc = { version = "0.1.37", default-features = false } num-bigint = { version = "0.4", default-features = false, features = [ diff --git a/vm/Cargo.toml b/vm/Cargo.toml index 8626300339..35d4fa3c34 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -56,7 +56,7 @@ keccak = { workspace = true } hashbrown = { workspace = true } anyhow = { workspace = true } thiserror-no-std = { workspace = true } -stark-felt = { git = "https://github.com/lambdaclass/types-rs.git", rev = "c2945cfde8fe12744e934e60a2366abbd6250524", default-features = false, features = ["serde"] } +stark-felt = { git = "https://github.com/lambdaclass/types-rs.git", rev = "ea52b64a52fd832222adf400feb2dd3b4dc286a2", default-features = false, features = ["serde"] } # only for std num-prime = { version = "0.4.3", features = ["big-int"], optional = true } diff --git a/vm/src/hint_processor/builtin_hint_processor/blake2s_utils.rs b/vm/src/hint_processor/builtin_hint_processor/blake2s_utils.rs index c548eb90cc..0a91832aab 100644 --- a/vm/src/hint_processor/builtin_hint_processor/blake2s_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/blake2s_utils.rs @@ -40,9 +40,6 @@ fn get_maybe_relocatable_array_from_u32(array: &Vec) -> Vec Vec { - array.iter().map(MaybeRelocatable::from).collect() -} /*Helper function for the Cairo blake2s() implementation. Computes the blake2s compress function and fills the value in the right position. output_ptr should point to the middle of an instance, right after initial_state, message, t, f, @@ -184,31 +181,24 @@ pub fn blake2s_add_uint256( let data_ptr = get_ptr_from_var_name("data", vm, ids_data, ap_tracking)?; let low_addr = get_relocatable_from_var_name("low", vm, ids_data, ap_tracking)?; let high_addr = get_relocatable_from_var_name("high", vm, ids_data, ap_tracking)?; - let low = vm.get_integer(low_addr)?.into_owned(); - let high = vm.get_integer(high_addr)?.into_owned(); + let mut low = vm.get_integer(low_addr)?.into_owned(); + let mut high = vm.get_integer(high_addr)?.into_owned(); //Main logic - //Declare constant - const MASK: u32 = u32::MAX; - const B: u32 = 32; - //Convert MASK to felt - let mask = Felt252::from(MASK); //Build first batch of data - let mut inner_data = Vec::::new(); - for i in 0..4 { - inner_data.push((low >> (B * i) as usize) & mask); + let b = &Felt252::TWO.pow(32_u8).try_into().unwrap(); + let mut data = Vec::::with_capacity(8); + for _ in 0..4 { + let (q, r) = low.div_rem(b); + data.push(r.into()); + low = q; } - //Insert first batch of data - let data = get_maybe_relocatable_array_from_felt(&inner_data); - vm.load_data(data_ptr, &data).map_err(HintError::Memory)?; - //Build second batch of data - let mut inner_data = Vec::::new(); - for i in 0..4 { - inner_data.push((high >> (B * i) as usize) & mask); + for _ in 0..4 { + let (q, r) = high.div_rem(b); + data.push(r.into()); + high = q; } //Insert second batch of data - let data = get_maybe_relocatable_array_from_felt(&inner_data); - vm.load_data((data_ptr + 4)?, &data) - .map_err(HintError::Memory)?; + vm.load_data(data_ptr, &data).map_err(HintError::Memory)?; Ok(()) } @@ -227,31 +217,27 @@ pub fn blake2s_add_uint256_bigend( let data_ptr = get_ptr_from_var_name("data", vm, ids_data, ap_tracking)?; let low_addr = get_relocatable_from_var_name("low", vm, ids_data, ap_tracking)?; let high_addr = get_relocatable_from_var_name("high", vm, ids_data, ap_tracking)?; - let low = vm.get_integer(low_addr)?.into_owned(); - let high = vm.get_integer(high_addr)?.into_owned(); + let mut low = vm.get_integer(low_addr)?.into_owned(); + let mut high = vm.get_integer(high_addr)?.into_owned(); //Main logic - //Declare constant - const MASK: u32 = u32::MAX; - const B: u32 = 32; - //Convert MASK to felt - let mask = Felt252::from(MASK); + let b = &Felt252::TWO.pow(32_u8).try_into().unwrap(); + let mut data = Vec::::with_capacity(8); //Build first batch of data - let mut inner_data = Vec::::new(); - for i in 0..4 { - inner_data.push((high >> (B * (3 - i)) as usize) & mask); + for _ in 0..4 { + let (q, r) = low.div_rem(b); + data.push(r.into()); + low = q; } - //Insert first batch of data - let data = get_maybe_relocatable_array_from_felt(&inner_data); - vm.load_data(data_ptr, &data).map_err(HintError::Memory)?; //Build second batch of data - let mut inner_data = Vec::::new(); - for i in 0..4 { - inner_data.push((low >> (B * (3 - i)) as usize) & mask); + for _ in 0..4 { + let (q, r) = high.div_rem(b); + data.push(r.into()); + high = q; } + //Reverse to make big-endian + data.reverse(); //Insert second batch of data - let data = get_maybe_relocatable_array_from_felt(&inner_data); - vm.load_data((data_ptr + 4)?, &data) - .map_err(HintError::Memory)?; + vm.load_data(data_ptr, &data).map_err(HintError::Memory)?; Ok(()) } 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 e45855c4f2..bcfeec8815 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 @@ -53,19 +53,16 @@ pub fn keccak_write_args( let low = get_integer_from_var_name("low", vm, ids_data, ap_tracking)?; let high = get_integer_from_var_name("high", vm, ids_data, ap_tracking)?; - let low = low.as_ref(); - let high = high.as_ref(); - let low_args = [low & Felt252::from(u64::MAX), low >> 64_usize]; - let high_args = [high & Felt252::from(u64::MAX), high >> 64_usize]; + let bound = Felt252::TWO.pow(64_u32).try_into().unwrap(); + let (d1, d0) = low.div_rem(&bound); + let (d3, d2) = high.div_rem(&bound); + let args: Vec<_> = [d0, d1, d2, d3] + .into_iter() + .map(MaybeRelocatable::from) + .collect(); - let low_args: Vec<_> = low_args.into_iter().map(MaybeRelocatable::from).collect(); - vm.write_arg(inputs_ptr, &low_args) - .map_err(HintError::Memory)?; - - let high_args: Vec<_> = high_args.into_iter().map(MaybeRelocatable::from).collect(); - vm.write_arg((inputs_ptr + 2_i32)?, &high_args) - .map_err(HintError::Memory)?; + vm.write_arg(inputs_ptr, &args)?; Ok(()) } diff --git a/vm/src/hint_processor/builtin_hint_processor/find_element_hint.rs b/vm/src/hint_processor/builtin_hint_processor/find_element_hint.rs index e368c364c3..628772d76b 100644 --- a/vm/src/hint_processor/builtin_hint_processor/find_element_hint.rs +++ b/vm/src/hint_processor/builtin_hint_processor/find_element_hint.rs @@ -151,6 +151,7 @@ mod tests { vm::vm_core::VirtualMachine, }; use assert_matches::assert_matches; + use num_traits::Zero; #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::*; diff --git a/vm/src/hint_processor/builtin_hint_processor/garaga.rs b/vm/src/hint_processor/builtin_hint_processor/garaga.rs index c57b770a6c..37f5a33025 100644 --- a/vm/src/hint_processor/builtin_hint_processor/garaga.rs +++ b/vm/src/hint_processor/builtin_hint_processor/garaga.rs @@ -20,8 +20,7 @@ pub fn get_felt_bitlenght( ap_tracking: &ApTracking, ) -> Result<(), HintError> { let x = get_integer_from_var_name("x", vm, ids_data, ap_tracking)?; - let bit_length = x.bits() as usize; - insert_value_from_var_name("bit_length", bit_length, vm, ids_data, ap_tracking) + insert_value_from_var_name("bit_length", x.bits(), vm, ids_data, ap_tracking) } #[cfg(test)] @@ -65,8 +64,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn test_in_range() { - for i in 0..252_usize { - let x: Felt252 = Felt252::ONE << i; + for i in 0..252_u32 { + let x: Felt252 = Felt252::TWO.pow(i); let bit_length_result = run_hint(x); assert!(bit_length_result.is_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 623af820d0..02e1a53bd0 100644 --- a/vm/src/hint_processor/builtin_hint_processor/keccak_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/keccak_utils.rs @@ -82,9 +82,7 @@ pub fn unsafe_keccak( let word = vm.get_integer(word_addr)?; let n_bytes = cmp::min(16, u64_length - byte_i); - if word.as_ref() < Felt252::ZERO.as_ref() - || word.as_ref() >= &(Felt252::ONE << (8 * (n_bytes as usize))) - { + if *word >= Felt252::TWO.pow(8 * n_bytes) { return Err(HintError::InvalidWordSize(Box::new(word.into_owned()))); } @@ -192,10 +190,8 @@ pub fn split_output( num: u32, ) -> Result<(), HintError> { let output_name = format!("output{}", num); - let output_cow = get_integer_from_var_name(&output_name, vm, ids_data, ap_tracking)?; - let output = output_cow.as_ref(); - let low = output & Felt252::from(u128::MAX); - let high = output >> 128_usize; + let output = get_integer_from_var_name(&output_name, vm, ids_data, ap_tracking)?; + let (high, low) = output.div_rem(&Felt252::TWO.pow(128_u32).try_into().unwrap()); insert_value_from_var_name( &format!("output{}_high", num), high, @@ -222,9 +218,7 @@ pub fn split_input( ) -> Result<(), HintError> { let inputs_ptr = get_ptr_from_var_name("inputs", vm, ids_data, ap_tracking)?; let binding = vm.get_integer((inputs_ptr + input_key)?)?; - let input = binding.as_ref(); - let low = input & ((Felt252::ONE << (8 * exponent) as usize) - 1u64); - let high = input >> (8 * exponent) as usize; + let (high, low) = binding.div_rem(&Felt252::TWO.pow(8 * exponent).try_into().unwrap()); insert_value_from_var_name( &format!("high{}", input_key), high, @@ -279,10 +273,8 @@ pub fn split_output_mid_low_high( ) -> Result<(), HintError> { let binding = get_integer_from_var_name("output1", vm, ids_data, ap_tracking)?; let output1 = binding.as_ref(); - let output1_low = output1 & Felt252::from((1u64 << (8 * 7)) - 1u64); - let tmp = output1 >> (8_usize * 7); - let output1_high = &tmp >> 128_usize; - let output1_mid = tmp & Felt252::from(u128::MAX); + let (tmp, output1_low) = output1.div_rem(&Felt252::TWO.pow(8_u32 * 7_u32).try_into().unwrap()); + let (output1_high, output1_mid) = tmp.div_rem(&Felt252::TWO.pow(128_u64).try_into().unwrap()); insert_value_from_var_name("output1_high", output1_high, vm, ids_data, ap_tracking)?; insert_value_from_var_name("output1_mid", output1_mid, vm, ids_data, ap_tracking)?; insert_value_from_var_name("output1_low", output1_low, 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 7b7cec1f5e..b73f94aa36 100644 --- a/vm/src/hint_processor/builtin_hint_processor/math_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/math_utils.rs @@ -1,12 +1,7 @@ use crate::{ hint_processor::builtin_hint_processor::hint_utils::get_constant_from_var_name, math_utils::signed_felt, - stdlib::{ - boxed::Box, - collections::HashMap, - ops::{Shl, Shr}, - prelude::*, - }, + stdlib::{boxed::Box, collections::HashMap, prelude::*}, types::errors::math_errors::MathError, utils::{bigint_to_felt, biguint_to_felt, felt_to_bigint, felt_to_biguint}, }; @@ -72,7 +67,7 @@ pub fn is_nn_out_of_range( //Main logic (assert a is not negative and within the expected range) //let value = if (-a - 1usize).mod_floor(vm.get_prime()) < range_check_builtin._bound { let value = match &range_check_builtin._bound { - Some(bound) if Felt252::ZERO - (a + 1usize) < *bound => Felt252::ZERO, + Some(bound) if Felt252::ZERO - (a + 1u64) < *bound => Felt252::ZERO, None => Felt252::ZERO, _ => Felt252::ONE, }; @@ -415,30 +410,28 @@ pub fn split_felt( ap_tracking: &ApTracking, constants: &HashMap, ) -> Result<(), HintError> { + let assert = |b: bool, msg: &str| { + b.then_some(()) + .ok_or_else(|| HintError::AssertionFailed(msg.to_string().into_boxed_str())) + }; + let bound = Felt252::TWO.pow(128_u32); let max_high = get_constant_from_var_name("MAX_HIGH", constants)?; let max_low = get_constant_from_var_name("MAX_LOW", constants)?; - if max_high.bits() > 128 || max_low.bits() > 128 { - return Err(HintError::AssertionFailed( - "assert ids.MAX_HIGH < 2**128 and ids.MAX_LOW < 2**128" - .to_string() - .into_boxed_str(), - )); - } - if Felt252::from(-1) != max_high * (&Felt252::ONE << 128) + max_low { - return Err(HintError::AssertionFailed( - "assert PRIME - 1 == ids.MAX_HIGH * 2**128 + ids.MAX_LOW" - .to_string() - .into_boxed_str(), - )); - } + assert( + max_high < &bound && max_low < &bound, + "assert ids.MAX_HIGH < 2**128 and ids.MAX_LOW < 2**128", + )?; + assert( + Felt252::MAX == max_high * bound + max_low, + "assert PRIME - 1 == ids.MAX_HIGH * 2**128 + ids.MAX_LOW", + )?; let value = get_integer_from_var_name("value", vm, ids_data, ap_tracking)?; let value = value.as_ref(); //Main logic //assert_integer(ids.value) (done by match) // ids.low = ids.value & ((1 << 128) - 1) // ids.high = ids.value >> 128 - let low: Felt252 = value & ((Felt252::ONE.shl(128_usize)) - Felt252::ONE); - let high: Felt252 = value.shr(128_usize); + let (high, low) = value.div_rem(&bound.try_into().unwrap()); insert_value_from_var_name("high", high, vm, ids_data, ap_tracking)?; insert_value_from_var_name("low", low, vm, ids_data, ap_tracking) } @@ -455,7 +448,7 @@ pub fn sqrt( ) -> Result<(), HintError> { let mod_value = get_integer_from_var_name("value", vm, ids_data, ap_tracking)?; //This is equal to mod_value > Felt252::from(2).pow(250) - if mod_value.as_ref().shr(250_usize) > Felt252::ZERO { + if *mod_value > Felt252::TWO.pow(250_u32) { return Err(HintError::ValueOutside250BitRange(Box::new( mod_value.into_owned(), ))); @@ -482,28 +475,19 @@ pub fn signed_div_rem( let bound = get_integer_from_var_name("bound", vm, ids_data, ap_tracking)?; let builtin = vm.get_range_check_builtin()?; - match &builtin._bound { - Some(builtin_bound) - if div.is_zero() || div.as_ref() > &div_prime_by_bound(*builtin_bound)? => - { - return Err(HintError::OutOfValidRange(Box::new(( - div.into_owned(), - *builtin_bound, - )))); - } - Some(builtin_bound) if bound.as_ref() > &(builtin_bound >> 1_usize) => { - return Err(HintError::OutOfValidRange(Box::new(( - bound.into_owned(), - builtin_bound >> 1_usize, - )))); - } - None if div.is_zero() => { - return Err(HintError::OutOfValidRange(Box::new(( - div.into_owned(), - Felt252::ZERO - Felt252::ONE, - )))); - } - _ => {} + let builtin_bound = &builtin._bound.unwrap_or(Felt252::MAX); + if div.is_zero() || div.as_ref() > &div_prime_by_bound(*builtin_bound)? { + return Err(HintError::OutOfValidRange(Box::new(( + div.into_owned(), + *builtin_bound, + )))); + } + let builtin_bound_div_2 = builtin_bound.field_div(&Felt252::TWO.try_into().unwrap()); + if *bound > builtin_bound_div_2 { + return Err(HintError::OutOfValidRange(Box::new(( + bound.into_owned(), + builtin_bound_div_2, + )))); } let int_value = signed_felt(*value); @@ -712,7 +696,8 @@ pub fn is_quad_residue( if x.is_zero() || x == Felt252::ONE { insert_value_from_var_name("y", *x.as_ref(), vm, ids_data, ap_tracking) // } else if Pow::pow(felt_to_biguint(x), &(&*CAIRO_PRIME >> 1_u32)).is_one() { - } else if x.pow_felt(&(&Felt252::MAX >> 1_usize)) == Felt252::ONE { + } else if x.pow_felt(&Felt252::MAX.div_rem(&Felt252::TWO.try_into().unwrap()).0) == Felt252::ONE + { insert_value_from_var_name("y", x.sqrt().unwrap_or_default(), vm, ids_data, ap_tracking) } else { insert_value_from_var_name( @@ -753,8 +738,9 @@ pub fn a_b_bitand_1( ) -> Result<(), HintError> { let a = get_integer_from_var_name("a", vm, ids_data, ap_tracking)?; let b = get_integer_from_var_name("b", vm, ids_data, ap_tracking)?; - let a_lsb = a.as_ref() & Felt252::ONE; - let b_lsb = b.as_ref() & Felt252::ONE; + let two = Felt252::TWO.try_into().unwrap(); + let a_lsb = a.mod_floor(&two); + let b_lsb = b.mod_floor(&two); insert_value_from_var_name("a_lsb", a_lsb, vm, ids_data, ap_tracking)?; insert_value_from_var_name("b_lsb", b_lsb, vm, ids_data, ap_tracking) } @@ -794,7 +780,8 @@ pub fn split_xx( ) -> Result<(), HintError> { let xx = Uint256::from_var_name("xx", vm, ids_data, ap_tracking)?; let x_addr = get_relocatable_from_var_name("x", vm, ids_data, ap_tracking)?; - let xx: BigUint = felt_to_biguint(*xx.low) + felt_to_biguint(*xx.high << 128_usize); + let xx: BigUint = + felt_to_biguint(*xx.low) + felt_to_biguint(*xx.high * Felt252::TWO.pow(128_u32)); let mut x = xx.modpow( &(&*SPLIT_XX_PRIME + 3_u32).div_floor(&BigUint::from(8_u32)), &SPLIT_XX_PRIME, @@ -818,7 +805,6 @@ pub fn split_xx( #[cfg(test)] mod tests { use super::*; - use crate::stdlib::ops::Shl; use crate::{felt_hex, felt_str}; use core::ops::Neg; @@ -1858,7 +1844,7 @@ mod tests { assert_matches!( run_hint!(vm, ids_data, hint_code), Err(HintError::OutOfValidRange(bx)) - if *bx == (bound.unwrap(), builtin_bound >> 1_usize) + if *bx == (bound.unwrap(), builtin_bound.field_div(&Felt252::TWO.try_into().unwrap())) ) } @@ -1971,7 +1957,7 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code, &mut exec_scopes_ref!(), &constants), - Err(HintError::ValueOutside250BitRange(bx)) if *bx == Felt252::ONE.shl(251_usize) + Err(HintError::ValueOutside250BitRange(bx)) if *bx == Felt252::TWO.pow(251_u32) ); } @@ -2555,7 +2541,7 @@ mod tests { if x.is_zero() || x == Felt252::ONE { assert_eq!(vm.get_integer(Relocatable::from((1, 0))).unwrap().as_ref(), &x); - } else if x.pow_felt(&(&Felt252::MAX >> 1_usize)) == Felt252::ONE { + } else if x.pow_felt(&Felt252::MAX.field_div(&Felt252::TWO.try_into().unwrap())) == Felt252::ONE { assert_eq!(vm.get_integer(Relocatable::from((1, 0))).unwrap().into_owned(), x.sqrt().unwrap()); } else { assert_eq!(vm.get_integer(Relocatable::from((1, 0))).unwrap().into_owned(), (x.field_div(&(Felt252::from(3).try_into().unwrap())).sqrt().unwrap())); diff --git a/vm/src/hint_processor/builtin_hint_processor/pow_utils.rs b/vm/src/hint_processor/builtin_hint_processor/pow_utils.rs index ce6c5fb6da..a749f4b896 100644 --- a/vm/src/hint_processor/builtin_hint_processor/pow_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/pow_utils.rs @@ -28,7 +28,7 @@ pub fn pow( .map_err(|_| { HintError::IdentifierHasNoMember(Box::new(("prev_locs".to_string(), "exp".to_string()))) })?; - let locs_bit = prev_locs_exp.as_ref() & Felt252::ONE; + let locs_bit = prev_locs_exp.mod_floor(&Felt252::TWO.try_into().unwrap()); insert_value_from_var_name("locs", locs_bit, vm, ids_data, ap_tracking)?; Ok(()) } 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 d2e029a1d7..86f2e0d612 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 @@ -151,7 +151,8 @@ pub fn bigint_to_uint256( let base_86 = constants .get(BASE_86) .ok_or_else(|| HintError::MissingConstant(Box::new(BASE_86)))?; - let low = (d0 + (d1 * base_86)) & Felt252::from(u128::MAX); + let mask = Felt252::TWO.pow(128_u32); + let low = (d0 + (d1 * base_86)).mod_floor(&mask.try_into().expect("nonzero by construction")); insert_value_from_var_name("low", low, vm, ids_data, ap_tracking) } @@ -187,7 +188,6 @@ mod tests { BuiltinHintProcessor, HintProcessorData, }; use crate::hint_processor::hint_processor_definition::HintProcessorLogic; - use crate::stdlib::ops::Shl; use crate::stdlib::string::ToString; use crate::types::exec_scope::ExecutionScopes; use crate::{any_box, felt_str}; @@ -223,7 +223,7 @@ mod tests { ids_data, hint_code, &mut exec_scopes, - &[(BASE_86, Felt252::ONE.shl(86_usize))] + &[(BASE_86, Felt252::TWO.pow(86_u128))] .into_iter() .map(|(k, v)| (k.to_string(), v)) .collect() diff --git a/vm/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs b/vm/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs index 7a978b0f84..700c5778ea 100644 --- a/vm/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs @@ -16,7 +16,7 @@ use crate::{ }, math_utils::{ec_double_slope, line_slope}, serde::deserialize_program::ApTracking, - stdlib::{collections::HashMap, ops::BitAnd, prelude::*}, + stdlib::{collections::HashMap, prelude::*}, types::exec_scope::ExecutionScopes, vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, }; @@ -417,7 +417,7 @@ pub fn ec_mul_inner( //(ids.scalar % PRIME) % 2 let scalar = get_integer_from_var_name("scalar", vm, ids_data, ap_tracking)? .as_ref() - .bitand(&Felt252::ONE); + .mod_floor(&Felt252::TWO.try_into().expect("nonzero by construction")); insert_value_into_ap(vm, scalar) } diff --git a/vm/src/hint_processor/builtin_hint_processor/secp/secp_utils.rs b/vm/src/hint_processor/builtin_hint_processor/secp/secp_utils.rs index 480eb23c2d..49fa27a979 100644 --- a/vm/src/hint_processor/builtin_hint_processor/secp/secp_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/secp/secp_utils.rs @@ -104,7 +104,7 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn secp_split() { let mut constants = HashMap::new(); - constants.insert(BASE_86.to_string(), Felt252::ONE << 86_usize); + constants.insert(BASE_86.to_string(), Felt252::TWO.pow(86_u128)); let array_1 = bigint3_split(&BigUint::zero()); #[allow(deprecated)] diff --git a/vm/src/hint_processor/builtin_hint_processor/uint256_utils.rs b/vm/src/hint_processor/builtin_hint_processor/uint256_utils.rs index e444c75f75..540e69df02 100644 --- a/vm/src/hint_processor/builtin_hint_processor/uint256_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/uint256_utils.rs @@ -95,8 +95,8 @@ impl<'a> From<&BigUint> for Uint256<'a> { impl<'a> From for Uint256<'a> { fn from(value: Felt252) -> Self { - let low = Felt252::from(u128::MAX) & value; - let high = value >> 128_usize; + let den = Felt252::TWO.pow(128_u32); + let (high, low) = value.div_rem(&den.try_into().expect("nonzero by construction")); Self::from_values(low, high) } } @@ -120,7 +120,7 @@ pub fn uint256_add( ap_tracking: &ApTracking, low_only: bool, ) -> Result<(), HintError> { - let shift = Felt252::from(1_u32) << 128_usize; + let shift = Felt252::TWO.pow(128_u32); let a = Uint256::from_var_name("a", vm, ids_data, ap_tracking)?; let b = Uint256::from_var_name("b", vm, ids_data, ap_tracking)?; @@ -159,7 +159,7 @@ pub fn uint128_add( ids_data: &HashMap, ap_tracking: &ApTracking, ) -> Result<(), HintError> { - let shift = Felt252::from(1_u32) << 128_usize; + let shift = Felt252::TWO.pow(128_u32); let a = get_integer_from_var_name("a", vm, ids_data, ap_tracking)?; let b = get_integer_from_var_name("b", vm, ids_data, ap_tracking)?; let a = a.as_ref(); @@ -245,10 +245,10 @@ pub fn split_64( ids_data: &HashMap, ap_tracking: &ApTracking, ) -> Result<(), HintError> { + let shift = Felt252::TWO.pow(64_u32); + let a = get_integer_from_var_name("a", vm, ids_data, ap_tracking)?; - let digits = a.to_le_digits(); - let low = Felt252::from(*digits.first().unwrap_or(&0u64)); - let high = a.as_ref() >> 64_usize; + let (high, low) = a.div_rem(&shift.try_into().expect("nonzero by construction")); insert_value_from_var_name("high", high, vm, ids_data, ap_tracking)?; insert_value_from_var_name("low", low, vm, ids_data, ap_tracking) } diff --git a/vm/src/hint_processor/builtin_hint_processor/uint384.rs b/vm/src/hint_processor/builtin_hint_processor/uint384.rs index 1d157ff226..024809f262 100644 --- a/vm/src/hint_processor/builtin_hint_processor/uint384.rs +++ b/vm/src/hint_processor/builtin_hint_processor/uint384.rs @@ -80,15 +80,11 @@ pub fn uint384_split_128( ids_data: &HashMap, ap_tracking: &ApTracking, ) -> Result<(), HintError> { - let a = get_integer_from_var_name("a", vm, ids_data, ap_tracking)?.into_owned(); - insert_value_from_var_name( - "low", - a & Felt252::from(u128::MAX), - vm, - ids_data, - ap_tracking, - )?; - insert_value_from_var_name("high", a >> 128_usize, vm, ids_data, ap_tracking) + let bound = Felt252::TWO.pow(128_u32).try_into().unwrap(); + let a = get_integer_from_var_name("a", vm, ids_data, ap_tracking)?; + let (high, low) = a.div_rem(&bound); + insert_value_from_var_name("low", low, vm, ids_data, ap_tracking)?; + insert_value_from_var_name("high", high, vm, ids_data, ap_tracking) } /* Implements Hint: @@ -235,7 +231,6 @@ pub fn sub_reduced_a_and_reduced_b( mod tests { use super::*; use crate::hint_processor::builtin_hint_processor::hint_code; - use core::ops::Shl; use crate::felt_str; use crate::{ @@ -492,7 +487,7 @@ mod tests { ids_data, hint_code::ADD_NO_UINT384_CHECK, &mut exec_scopes_ref!(), - &[("path.path.path.SHIFT", Felt252::ONE.shl(128_usize))] + &[("path.path.path.SHIFT", Felt252::TWO.pow(128_u128))] .into_iter() .map(|(k, v)| (k.to_string(), v)) .collect() diff --git a/vm/src/serde/deserialize_program.rs b/vm/src/serde/deserialize_program.rs index 999c579b43..ab71c16048 100644 --- a/vm/src/serde/deserialize_program.rs +++ b/vm/src/serde/deserialize_program.rs @@ -1500,7 +1500,7 @@ mod tests { assert_matches!( felt_from_number(n), - Ok(x) if x == Some(Felt252::ONE * Felt252::from(10).pow(27)) + Ok(x) if x == Some(Felt252::ONE * Felt252::from(10).pow(27_u32)) ); } @@ -1511,7 +1511,7 @@ mod tests { assert_matches!( felt_from_number(n), - Ok(x) if x == Some(Felt252::from_dec_str("64").unwrap() * Felt252::from(10).pow(74)) + Ok(x) if x == Some(Felt252::from_dec_str("64").unwrap() * Felt252::from(10).pow(74_u32)) ); } diff --git a/vm/src/types/relocatable.rs b/vm/src/types/relocatable.rs index cc3de89cf9..b4cdc0d97e 100644 --- a/vm/src/types/relocatable.rs +++ b/vm/src/types/relocatable.rs @@ -286,9 +286,11 @@ impl MaybeRelocatable { (MaybeRelocatable::RelocatableValue(rel_a), MaybeRelocatable::Int(ref num_b)) => { Ok(MaybeRelocatable::from(( rel_a.segment_index, - (rel_a.offset - num_b).to_usize().ok_or_else(|| { - MathError::RelocatableSubFelt252NegOffset(Box::new((*rel_a, *num_b))) - })?, + (rel_a.offset as u64 - num_b) + .and_then(|x| x.to_usize()) + .ok_or_else(|| { + MathError::RelocatableSubFelt252NegOffset(Box::new((*rel_a, *num_b))) + })?, ))) } (MaybeRelocatable::Int(int), MaybeRelocatable::RelocatableValue(rel)) => { @@ -398,9 +400,9 @@ mod tests { #[cfg(feature = "std")] proptest! { #[test] - fn add_relocatable_felt(offset in any::(), ref bigint in any::<[u8; 32]>()) { + fn add_relocatable_felt(offset in any::(), ref bigint in any::<[u8; 32]>()) { let big = &Felt252::from_bytes_be(bigint).unwrap(); - let rel = Relocatable::from((0, offset)); + let rel = Relocatable::from((0, offset as usize)); let sum = (big + offset).to_usize() .map(|offset| (0, offset).into()); @@ -408,11 +410,11 @@ mod tests { } #[test] - fn add_relocatable_felt_extremes(offset in any::()) { + fn add_relocatable_felt_extremes(offset in any::()) { let big_zero = &Felt252::ZERO; let big_max = &Felt252::MAX; - let big_min = &(big_zero + (i64::MIN as usize)); - let rel = Relocatable::from((0, offset)); + let big_min = &(big_zero + (i64::MIN as u64)); + let rel = Relocatable::from((0, offset as usize)); let sum_max = (big_max + offset).to_usize() .map(|offset| (0, offset).into()); @@ -778,10 +780,10 @@ mod tests { #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn relocatable_add_int_mod_offset_exceeded_error() { assert_eq!( - relocatable!(0, 0) + &(Felt252::from(usize::MAX) + 1_usize), + relocatable!(0, 0) + &(Felt252::from(usize::MAX) + 1_u64), Err(MathError::RelocatableAddFelt252OffsetExceeded(Box::new(( relocatable!(0, 0), - Felt252::from(usize::MAX) + 1_usize + Felt252::from(usize::MAX) + 1_u64 )))) ); } @@ -888,7 +890,7 @@ mod tests { relocatable!(1, 0) + &mayberelocatable!(usize::MAX as i128 + 1), Err(MathError::RelocatableAddFelt252OffsetExceeded(Box::new(( relocatable!(1, 0), - Felt252::from(usize::MAX) + 1_usize + Felt252::from(usize::MAX) + 1_u64 )))) ); } diff --git a/vm/src/vm/runners/builtin_runner/bitwise.rs b/vm/src/vm/runners/builtin_runner/bitwise.rs index 649b7ed35a..448e222939 100644 --- a/vm/src/vm/runners/builtin_runner/bitwise.rs +++ b/vm/src/vm/runners/builtin_runner/bitwise.rs @@ -1,4 +1,5 @@ use crate::stdlib::{boxed::Box, vec::Vec}; +use crate::Felt252; use crate::{ types::{ instance_definitions::bitwise_instance_def::{ @@ -72,38 +73,43 @@ impl BitwiseBuiltinRunner { if index <= 1 { return Ok(None); } - let x_addr = Relocatable::from((address.segment_index, address.offset - index)); + let x_addr = (address - index)?; let y_addr = (x_addr + 1_usize)?; - let num_x = memory.get(&x_addr); - let num_y = memory.get(&y_addr); - if let (Some(MaybeRelocatable::Int(ref num_x)), Some(MaybeRelocatable::Int(ref num_y))) = ( - num_x.as_ref().map(|x| x.as_ref()), - num_y.as_ref().map(|x| x.as_ref()), - ) { - if num_x.bits() > self.bitwise_builtin.total_n_bits { + let (Ok(num_x), Ok(num_y)) = (memory.get_integer(x_addr), memory.get_integer(y_addr)) else { + return Ok(None); + }; + + let to_bytes = |x_addr, x: &Felt252| -> Result<[u8; 32], RunnerError> { + const LEADING_BITS: u8 = 0xf8; + let limbs = x.to_bytes_be(); + if limbs[0] & LEADING_BITS != 0 { return Err(RunnerError::IntegerBiggerThanPowerOfTwo(Box::new(( x_addr, self.bitwise_builtin.total_n_bits, - *num_x, - )))); - }; - if num_y.bits() > self.bitwise_builtin.total_n_bits { - return Err(RunnerError::IntegerBiggerThanPowerOfTwo(Box::new(( - y_addr, - self.bitwise_builtin.total_n_bits, - *num_y, + *x, )))); + } + Ok(limbs) + }; + let (limbs_x, limbs_y) = (to_bytes(x_addr, &num_x)?, to_bytes(y_addr, &num_y)?); + let mut limbs_xy = [0u8; 32]; + for (xy, (x, y)) in limbs_xy + .iter_mut() + .zip(limbs_x.into_iter().zip(limbs_y.into_iter())) + { + *xy = match index { + 2 => x & y, + 3 => x ^ y, + 4 => x | y, + _ => { + return Ok(None); + } }; - let res = match index { - 2 => Some(MaybeRelocatable::from(num_x & num_y)), - 3 => Some(MaybeRelocatable::from(num_x ^ num_y)), - 4 => Some(MaybeRelocatable::from(num_x | num_y)), - _ => None, - }; - return Ok(res); } - Ok(None) + Ok(Some(MaybeRelocatable::from( + Felt252::from_bytes_be(&limbs_xy).unwrap(), + ))) } pub fn get_memory_segment_addresses(&self) -> (usize, Option) { diff --git a/vm/src/vm/runners/builtin_runner/ec_op.rs b/vm/src/vm/runners/builtin_runner/ec_op.rs index 8acfce57b2..c62e8dffd8 100644 --- a/vm/src/vm/runners/builtin_runner/ec_op.rs +++ b/vm/src/vm/runners/builtin_runner/ec_op.rs @@ -48,7 +48,7 @@ impl EcOpBuiltinRunner { ///y^2 = x^3 + alpha * x + beta (mod p) ///or False otherwise. fn point_on_curve(x: &Felt252, y: &Felt252, alpha: &Felt252, beta: &Felt252) -> bool { - y.pow(2) == (x.pow(3) + alpha * x) + beta + y.pow(2_u32) == (x.pow(3_u32) + alpha * x) + beta } #[allow(deprecated)] @@ -122,7 +122,7 @@ impl EcOpBuiltinRunner { let alpha: Felt252 = Felt252::ONE; let beta_low: Felt252 = Felt252::from(0x609ad26c15c915c1f4cdfcb99cee9e89_u128); let beta_high: Felt252 = Felt252::from(0x6f21413efbe40de150e596d72f7a8c5_u128); - let beta: Felt252 = (beta_high << 128_usize) + beta_low; + let beta: Felt252 = (beta_high * (Felt252::ONE + Felt252::from(u128::MAX))) + beta_low; let index = address .offset diff --git a/vm/src/vm/runners/builtin_runner/keccak.rs b/vm/src/vm/runners/builtin_runner/keccak.rs index 3da3f4dd5a..a7dc684f1b 100644 --- a/vm/src/vm/runners/builtin_runner/keccak.rs +++ b/vm/src/vm/runners/builtin_runner/keccak.rs @@ -93,7 +93,7 @@ impl KeccakBuiltinRunner { KECCAK_BUILTIN_NAME, (first_input_addr + i)?, ))))?; - if num >= &(Felt252::ONE << self.state_rep[i] as usize) { + if num >= &(Felt252::TWO.pow(self.state_rep[i])) { return Err(RunnerError::IntegerBiggerThanPowerOfTwo(Box::new(( (first_input_addr + i)?, self.state_rep[i], diff --git a/vm/src/vm/runners/builtin_runner/range_check.rs b/vm/src/vm/runners/builtin_runner/range_check.rs index 35be756e90..1bee53200a 100644 --- a/vm/src/vm/runners/builtin_runner/range_check.rs +++ b/vm/src/vm/runners/builtin_runner/range_check.rs @@ -1,6 +1,5 @@ use crate::stdlib::{ cmp::{max, min}, - ops::Shl, prelude::*, }; @@ -19,6 +18,8 @@ use crate::{ }, }; +use num_traits::Zero; + use super::RANGE_CHECK_BUILTIN_NAME; // NOTE: the current implementation is based on the bound 0x10000 @@ -44,7 +45,7 @@ pub struct RangeCheckBuiltinRunner { impl RangeCheckBuiltinRunner { pub fn new(ratio: Option, n_parts: u32, included: bool) -> RangeCheckBuiltinRunner { - let bound = Felt252::ONE.shl(16 * n_parts as usize); + let bound = Felt252::TWO.pow(16 * n_parts as u128); let _bound = if n_parts != 0 && bound.is_zero() { None } else { @@ -95,7 +96,7 @@ impl RangeCheckBuiltinRunner { } else { Err(MemoryError::RangeCheckNumOutOfBounds(Box::new(( num.into_owned(), - Felt252::ONE << ((N_PARTS * INNER_RC_BOUND_SHIFT) as usize), + Felt252::TWO.pow((N_PARTS * INNER_RC_BOUND_SHIFT) as u128), )))) } }, diff --git a/vm/src/vm/vm_core.rs b/vm/src/vm/vm_core.rs index 9a495355c5..21a66fb98b 100644 --- a/vm/src/vm/vm_core.rs +++ b/vm/src/vm/vm_core.rs @@ -31,7 +31,7 @@ use super::errors::runner_errors::RunnerError; use super::errors::trace_errors::TraceError; use super::runners::builtin_runner::OUTPUT_BUILTIN_NAME; -use num_traits::ToPrimitive; +use num_traits::{ToPrimitive, Zero}; const MAX_TRACEBACK_ENTRIES: u32 = 20; diff --git a/vm/src/vm/vm_memory/memory.rs b/vm/src/vm/vm_memory/memory.rs index 96b0257be2..56d6fe0f41 100644 --- a/vm/src/vm/vm_memory/memory.rs +++ b/vm/src/vm/vm_memory/memory.rs @@ -817,7 +817,7 @@ mod memory_tests { error, Err(MemoryError::RangeCheckNumOutOfBounds(Box::new(( Felt252::from(-10), - Felt252::ONE.shl(128_usize) + Felt252::TWO.pow(128_u128) )))) ); } @@ -1562,7 +1562,7 @@ mod memory_tests { assert_eq!(cell.get_value(), &mayberelocatable!(2)); } - use core::{cmp::Ordering::*, ops::Shl}; + use core::cmp::Ordering::*; fn check_memcmp( lhs: (isize, usize),