diff --git a/CHANGELOG.md b/CHANGELOG.md index b187626e7c..efcc30649a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -84,6 +84,28 @@ * Remove duplicated tests in cairo_run_test * BREAKING CHANGE: `MemorySegmentManager.get_memory_holes` now also receives the amount of builtins in the vm. Signature is now `pub fn get_memory_holes(&self, builtin_count: usize) -> Result` +* Add missing hints `NewHint#35` and `NewHint#36` [#975](https://github.com/lambdaclass/cairo-rs/issues/975) + + `BuiltinHintProcessor` now supports the following hint: + + ```python + from starkware.cairo.common.cairo_secp.secp_utils import pack + from starkware.cairo.common.math_utils import as_int + from starkware.python.math_utils import div_mod, safe_div + + p = pack(ids.P, PRIME) + x = pack(ids.x, PRIME) + as_int(ids.x.d3, PRIME) * ids.BASE ** 3 + as_int(ids.x.d4, PRIME) * ids.BASE ** 4 + y = pack(ids.y, PRIME) + + value = res = div_mod(x, y, p) + ``` + + ```python + k = safe_div(res * y - x, p) + value = k if k > 0 else 0 - k + ids.flag = 1 if k > 0 else 0 + ``` + * Add missing hint on uint256_improvements lib [#1025](https://github.com/lambdaclass/cairo-rs/pull/1025): `BuiltinHintProcessor` now supports the following hint: diff --git a/cairo_programs/bigint.cairo b/cairo_programs/bigint.cairo new file mode 100644 index 0000000000..81cd3b866d --- /dev/null +++ b/cairo_programs/bigint.cairo @@ -0,0 +1,91 @@ +%builtins range_check + +from starkware.cairo.common.cairo_secp.bigint import ( + BigInt3, + UnreducedBigInt3, + UnreducedBigInt5, + nondet_bigint3, + bigint_mul, +) +from starkware.cairo.common.cairo_secp.constants import BASE + +func bigint_mul_u(x: UnreducedBigInt3, y: BigInt3) -> (res: UnreducedBigInt5) { + return ( + UnreducedBigInt5( + d0=x.d0 * y.d0, + d1=x.d0 * y.d1 + x.d1 * y.d0, + d2=x.d0 * y.d2 + x.d1 * y.d1 + x.d2 * y.d0, + d3=x.d1 * y.d2 + x.d2 * y.d1, + d4=x.d2 * y.d2 + ), + ); +} + +// Returns (x / y) % P +func bigint_div_mod{range_check_ptr}(x: UnreducedBigInt5, y: UnreducedBigInt3, P: BigInt3) -> ( + res: BigInt3 +) { + alloc_locals; + local flag; + %{ + from starkware.cairo.common.cairo_secp.secp_utils import pack + from starkware.cairo.common.math_utils import as_int + from starkware.python.math_utils import div_mod, safe_div + + p = pack(ids.P, PRIME) + x = pack(ids.x, PRIME) + as_int(ids.x.d3, PRIME) * ids.BASE ** 3 + as_int(ids.x.d4, PRIME) * ids.BASE ** 4 + y = pack(ids.y, PRIME) + + value = res = div_mod(x, y, p) + %} + let (res) = nondet_bigint3(); + + %{ + k = safe_div(res * y - x, p) + value = k if k > 0 else 0 - k + ids.flag = 1 if k > 0 else 0 + %} + let (k) = nondet_bigint3(); + let (res_y) = bigint_mul_u(y, res); + let (k_p) = bigint_mul(k, P); + + tempvar carry1 = (res_y.d0 - (2 * flag - 1) * k_p.d0 - x.d0) / BASE; + assert [range_check_ptr + 0] = carry1 + 2 ** 127; + + tempvar carry2 = (res_y.d1 - (2 * flag - 1) * k_p.d1 - x.d1 + carry1) / BASE; + assert [range_check_ptr + 1] = carry2 + 2 ** 127; + + tempvar carry3 = (res_y.d2 - (2 * flag - 1) * k_p.d2 - x.d2 + carry2) / BASE; + assert [range_check_ptr + 2] = carry3 + 2 ** 127; + + tempvar carry4 = (res_y.d3 - (2 * flag - 1) * k_p.d3 - x.d3 + carry3) / BASE; + assert [range_check_ptr + 3] = carry4 + 2 ** 127; + + assert res_y.d4 - (2 * flag - 1) * k_p.d4 - x.d4 + carry4 = 0; + let range_check_ptr = range_check_ptr + 4; + + return (res=res); +} + +// Check val = 0 mod n? +func verify_urbigint5_zero{range_check_ptr}(val: UnreducedBigInt5, n: BigInt3) { + let (res) = bigint_div_mod(val, UnreducedBigInt3(1, 0, 0), n); + assert res.d0 = 0; + assert res.d1 = 0; + assert res.d2 = 0; + return (); +} + +func main{range_check_ptr: felt}() { + let x = UnreducedBigInt5(0x38a23ca66202c8c2a72277, 0x6730e765376ff17ea8385, 0xca1ad489ab60ea581e6c1, 0, 0); + let y = UnreducedBigInt3(0x20a4b46d3c5e24cda81f22, 0x967bf895824330d4273d0, 0x541e10c21560da25ada4c); + let p = BigInt3(0x8a03bbfd25e8cd0364141, 0x3ffffffffffaeabb739abd, 0xfffffffffffffffffffff); + + let (actual : BigInt3) = bigint_div_mod(x, y, p); + + assert actual.d0 = 39016122801346771958523117; + assert actual.d1 = 70716674902939638702535965; + assert actual.d2 = 18303064213085914713888892; + + return (); +} diff --git a/src/hint_processor/builtin_hint_processor/bigint.rs b/src/hint_processor/builtin_hint_processor/bigint.rs new file mode 100644 index 0000000000..3194b75fa2 --- /dev/null +++ b/src/hint_processor/builtin_hint_processor/bigint.rs @@ -0,0 +1,225 @@ +use crate::hint_processor::builtin_hint_processor::secp::bigint_utils::BigInt5; +use crate::hint_processor::builtin_hint_processor::secp::secp_utils::BASE; +use crate::math_utils::{div_mod, safe_div_bigint}; +use crate::stdlib::collections::HashMap; +use crate::stdlib::prelude::String; +use crate::types::exec_scope::ExecutionScopes; +use crate::{ + hint_processor::{ + builtin_hint_processor::secp::{bigint_utils::BigInt3, secp_utils::pack}, + hint_processor_definition::HintReference, + }, + serde::deserialize_program::ApTracking, + vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, +}; +use felt::Felt252; +use num_bigint::BigInt; +use num_bigint::ToBigInt; +use num_traits::{One, Signed, Zero}; + +use super::hint_utils::insert_value_from_var_name; + +/// Implements hint: +/// ```python +/// from starkware.cairo.common.cairo_secp.secp_utils import pack +/// from starkware.cairo.common.math_utils import as_int +/// from starkware.python.math_utils import div_mod, safe_div +/// +/// p = pack(ids.P, PRIME) +/// x = pack(ids.x, PRIME) + as_int(ids.x.d3, PRIME) * ids.BASE ** 3 + as_int(ids.x.d4, PRIME) * ids.BASE ** 4 +/// y = pack(ids.y, PRIME) +/// +/// value = res = div_mod(x, y, p) +/// ``` +pub fn bigint_pack_div_mod_hint( + vm: &mut VirtualMachine, + exec_scopes: &mut ExecutionScopes, + ids_data: &HashMap, + ap_tracking: &ApTracking, +) -> Result<(), HintError> { + let p: BigInt = pack(BigInt3::from_var_name("P", vm, ids_data, ap_tracking)?); + + let x: BigInt = { + let x_bigint5 = BigInt5::from_var_name("x", vm, ids_data, ap_tracking)?; + let x_lower = BigInt3 { + d0: x_bigint5.d0, + d1: x_bigint5.d1, + d2: x_bigint5.d2, + }; + let d3 = x_bigint5.d3.as_ref().to_biguint().to_bigint().unwrap(); + let d4 = x_bigint5.d4.as_ref().to_biguint().to_bigint().unwrap(); + pack(x_lower) + d3 * BigInt::from(BASE.pow(3)) + d4 * BigInt::from(BASE.pow(4)) + }; + let y: BigInt = pack(BigInt3::from_var_name("y", vm, ids_data, ap_tracking)?); + + let res = div_mod(&x, &y, &p); + exec_scopes.insert_value("res", res.clone()); + exec_scopes.insert_value("value", res); + exec_scopes.insert_value("x", x); + exec_scopes.insert_value("y", y); + exec_scopes.insert_value("p", p); + + Ok(()) +} + +/// Implements hint: +/// ```python +/// k = safe_div(res * y - x, p) +/// value = k if k > 0 else 0 - k +/// ids.flag = 1 if k > 0 else 0 +/// ``` +pub fn bigint_safe_div_hint( + vm: &mut VirtualMachine, + exec_scopes: &mut ExecutionScopes, + ids_data: &HashMap, + ap_tracking: &ApTracking, +) -> Result<(), HintError> { + let res = exec_scopes.get::("res")?; + let y = exec_scopes.get::("y")?; + let x = exec_scopes.get::("x")?; + let p = exec_scopes.get::("p")?; + + let k = safe_div_bigint(&(res * y - x), &p)?; + let (value, flag) = if k.is_positive() { + (k.clone(), Felt252::one()) + } else { + (-k.clone(), Felt252::zero()) + }; + + exec_scopes.insert_value("k", k); + exec_scopes.insert_value("value", value); + insert_value_from_var_name("flag", flag, vm, ids_data, ap_tracking)?; + + Ok(()) +} + +#[cfg(test)] +mod test { + use crate::any_box; + use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor; + use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; + use crate::hint_processor::builtin_hint_processor::hint_code; + use crate::hint_processor::hint_processor_definition::HintProcessor; + use crate::hint_processor::hint_processor_definition::HintReference; + use crate::stdlib::collections::HashMap; + use crate::types::exec_scope::ExecutionScopes; + use crate::types::relocatable::MaybeRelocatable; + use crate::utils::test_utils::*; + use crate::vm::errors::memory_errors::MemoryError; + use crate::vm::vm_core::VirtualMachine; + use crate::vm::vm_memory::{memory::Memory, memory_segments::MemorySegmentManager}; + use assert_matches::assert_matches; + use num_bigint::BigInt; + + #[cfg(target_arch = "wasm32")] + use wasm_bindgen_test::*; + + /// Input: + /// x = UnreducedBigInt5(0x38a23ca66202c8c2a72277, 0x6730e765376ff17ea8385, 0xca1ad489ab60ea581e6c1, 0, 0); + /// y = UnreducedBigInt3(0x20a4b46d3c5e24cda81f22, 0x967bf895824330d4273d0, 0x541e10c21560da25ada4c); + /// p = BigInt3(0x8a03bbfd25e8cd0364141, 0x3ffffffffffaeabb739abd, 0xfffffffffffffffffffff); + /// expected: value = res = 109567829260688255124154626727441144629993228404337546799996747905569082729709 (py int) + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn test_bigint_pack_div_mod_hint() { + // Prepare the VM context: + let ids_data = non_continuous_ids_data![ + ("x", 0), // located at `fp + 0`. + ("y", 5), // located at `fp + 5`. + ("P", 8) // located at `fp + 8`. + ]; + + let mut vm = vm!(); + vm.run_context.fp = 0; + add_segments!(vm, 11); // Alloc space for `ids.x`, `ids.y` and `ids.p`. + vm.segments = segments![ + ((1, 0), 0x38a23ca66202c8c2a72277_i128), // x.d0 + ((1, 1), 0x6730e765376ff17ea8385_i128), // x.d1 + ((1, 2), 0xca1ad489ab60ea581e6c1_i128), // x.d2 + ((1, 3), 0_i128), // x.d3 + ((1, 4), 0_i128), // x.d4 + ((1, 5), 0x20a4b46d3c5e24cda81f22_i128), // y.d0 + ((1, 6), 0x967bf895824330d4273d0_i128), // y.d1 + ((1, 7), 0x541e10c21560da25ada4c_i128), // y.d2 + ((1, 8), 0x8a03bbfd25e8cd0364141_i128), // P.id0 + ((1, 9), 0x3ffffffffffaeabb739abd_i128), // P.id1 + ((1, 10), 0xfffffffffffffffffffff_i128), // P.id2 + ]; + + let mut exec_scopes = ExecutionScopes::new(); + assert_matches!( + run_hint!( + vm, + ids_data, + hint_code::BIGINT_PACK_DIV_MOD, + &mut exec_scopes + ), + Ok(()) + ); + + let expected = bigint_str!( + "109567829260688255124154626727441144629993228404337546799996747905569082729709" + ); + assert_matches!(exec_scopes.get::("res"), Ok(x) if x == expected); + assert_matches!(exec_scopes.get::("value"), Ok(x) if x == expected); + assert_matches!(exec_scopes.get::("y"), Ok(x) if x == bigint_str!("38047400353360331012910998489219098987968251547384484838080352663220422975266")); + assert_matches!(exec_scopes.get::("x"), Ok(x) if x == bigint_str!("91414600319290532004473480113251693728834511388719905794310982800988866814583")); + assert_matches!(exec_scopes.get::("p"), Ok(x) if x == bigint_str!("115792089237316195423570985008687907852837564279074904382605163141518161494337")); + } + + /// Input: + /// res = 109567829260688255124154626727441144629993228404337546799996747905569082729709 + /// y = 38047400353360331012910998489219098987968251547384484838080352663220422975266 + /// x = 91414600319290532004473480113251693728834511388719905794310982800988866814583 + /// p = 115792089237316195423570985008687907852837564279074904382605163141518161494337 + /// Output: + /// k = 36002209591245282109880156842267569109802494162594623391338581162816748840003 + /// value = 36002209591245282109880156842267569109802494162594623391338581162816748840003 + /// ids.flag = 1 + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn test_bigint_safe_div_hint() { + let mut exec_scopes = ExecutionScopes::new(); + exec_scopes.insert_value( + "res", + bigint_str!( + "109567829260688255124154626727441144629993228404337546799996747905569082729709" + ), + ); + exec_scopes.insert_value( + "x", + bigint_str!( + "91414600319290532004473480113251693728834511388719905794310982800988866814583" + ), + ); + exec_scopes.insert_value( + "y", + bigint_str!( + "38047400353360331012910998489219098987968251547384484838080352663220422975266" + ), + ); + exec_scopes.insert_value( + "p", + bigint_str!( + "115792089237316195423570985008687907852837564279074904382605163141518161494337" + ), + ); + + let mut vm = vm!(); + let ids_data = non_continuous_ids_data![("flag", 0)]; + vm.run_context.fp = 0; + add_segments!(vm, 2); // Alloc space for `flag` + + assert_matches!( + run_hint!(vm, ids_data, hint_code::BIGINT_SAFE_DIV, &mut exec_scopes), + Ok(()) + ); + assert_matches!(exec_scopes.get::("k"), Ok(x) if x == bigint_str!("36002209591245282109880156842267569109802494162594623391338581162816748840003")); + assert_matches!(exec_scopes.get::("value"), Ok(x) if x == bigint_str!("36002209591245282109880156842267569109802494162594623391338581162816748840003")); + + check_memory![vm.segments.memory, ((1, 0), 1)]; + // let flag_result = get_integer_from_var_name("flag", vm, ids_data, ap_tracking); + // assert!(flag_result.is_ok()); + // assert_eq!(flag_result.unwrap().as_ref(), Felt252::one()); + } +} 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 1a97515a0c..4099a99dc1 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 @@ -1,6 +1,7 @@ use crate::{ hint_processor::{ builtin_hint_processor::{ + bigint::{bigint_pack_div_mod_hint, bigint_safe_div_hint}, blake2s_utils::{ blake2s_add_uint256, blake2s_add_uint256_bigend, compute_blake2s, finalize_blake2s, }, @@ -386,6 +387,15 @@ impl HintProcessor for BuiltinHintProcessor { hint_code::GET_FELT_BIT_LENGTH => { get_felt_bitlenght(vm, &hint_data.ids_data, &hint_data.ap_tracking) } + hint_code::BIGINT_PACK_DIV_MOD => bigint_pack_div_mod_hint( + vm, + exec_scopes, + &hint_data.ids_data, + &hint_data.ap_tracking, + ), + hint_code::BIGINT_SAFE_DIV => { + bigint_safe_div_hint(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking) + } hint_code::DIV_MOD_N_PACKED_DIVMOD_EXTERNAL_N => div_mod_n_packed_external_n( vm, exec_scopes, diff --git a/src/hint_processor/builtin_hint_processor/hint_code.rs b/src/hint_processor/builtin_hint_processor/hint_code.rs index 3beb2b5e32..f50e5f606d 100644 --- a/src/hint_processor/builtin_hint_processor/hint_code.rs +++ b/src/hint_processor/builtin_hint_processor/hint_code.rs @@ -505,6 +505,20 @@ pub const DIV_MOD_N_SAFE_DIV: &str = r#"value = k = safe_div(res * b - a, N)"#; pub const GET_FELT_BIT_LENGTH: &str = r#"x = ids.x ids.bit_length = x.bit_length()"#; +pub const BIGINT_PACK_DIV_MOD: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import pack +from starkware.cairo.common.math_utils import as_int +from starkware.python.math_utils import div_mod, safe_div + +p = pack(ids.P, PRIME) +x = pack(ids.x, PRIME) + as_int(ids.x.d3, PRIME) * ids.BASE ** 3 + as_int(ids.x.d4, PRIME) * ids.BASE ** 4 +y = pack(ids.y, PRIME) + +value = res = div_mod(x, y, p)"#; + +pub const BIGINT_SAFE_DIV: &str = r#"k = safe_div(res * y - x, p) +value = k if k > 0 else 0 - k +ids.flag = 1 if k > 0 else 0"#; + pub const DIV_MOD_N_SAFE_DIV_PLUS_ONE: &str = r#"value = k_plus_one = safe_div(res * b - a, N) + 1"#; diff --git a/src/hint_processor/builtin_hint_processor/mod.rs b/src/hint_processor/builtin_hint_processor/mod.rs index 4e60529ec6..864a4052a0 100644 --- a/src/hint_processor/builtin_hint_processor/mod.rs +++ b/src/hint_processor/builtin_hint_processor/mod.rs @@ -1,3 +1,4 @@ +pub mod bigint; pub mod blake2s_hash; pub mod blake2s_utils; pub mod builtin_hint_processor_definition; 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 d27c8007be..f1847b1923 100644 --- a/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs +++ b/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs @@ -54,6 +54,50 @@ impl BigInt3<'_> { } } +#[derive(Debug, PartialEq)] +pub(crate) struct BigInt5<'a> { + pub d0: Cow<'a, Felt252>, + pub d1: Cow<'a, Felt252>, + pub d2: Cow<'a, Felt252>, + pub d3: Cow<'a, Felt252>, + pub d4: Cow<'a, Felt252>, +} + +impl BigInt5<'_> { + pub(crate) fn from_base_addr<'a>( + addr: Relocatable, + name: &str, + vm: &'a VirtualMachine, + ) -> Result, HintError> { + Ok(BigInt5 { + d0: vm.get_integer(addr).map_err(|_| { + HintError::IdentifierHasNoMember(name.to_string(), "d0".to_string()) + })?, + d1: vm.get_integer((addr + 1)?).map_err(|_| { + HintError::IdentifierHasNoMember(name.to_string(), "d1".to_string()) + })?, + d2: vm.get_integer((addr + 2)?).map_err(|_| { + HintError::IdentifierHasNoMember(name.to_string(), "d2".to_string()) + })?, + d3: vm.get_integer((addr + 3)?).map_err(|_| { + HintError::IdentifierHasNoMember(name.to_string(), "d3".to_string()) + })?, + d4: vm.get_integer((addr + 4)?).map_err(|_| { + HintError::IdentifierHasNoMember(name.to_string(), "d4".to_string()) + })?, + }) + } + + pub(crate) fn from_var_name<'a>( + name: &str, + vm: &'a VirtualMachine, + ids_data: &HashMap, + ap_tracking: &ApTracking, + ) -> Result, HintError> { + let base_addr = get_relocatable_from_var_name(name, vm, ids_data, ap_tracking)?; + BigInt5::from_base_addr(base_addr, name, vm) + } +} /* Implements hint: %{ @@ -231,6 +275,25 @@ mod tests { assert_eq!(x.d2.as_ref(), &Felt252::from(3)); } + #[test] + fn get_bigint5_from_base_addr_ok() { + //BigInt3(1,2,3, 4, 5) + let mut vm = vm!(); + vm.segments = segments![ + ((0, 0), 1), + ((0, 1), 2), + ((0, 2), 3), + ((0, 3), 4), + ((0, 4), 5) + ]; + let x = BigInt5::from_base_addr((0, 0).into(), "x", &vm).unwrap(); + assert_eq!(x.d0.as_ref(), &Felt252::one()); + assert_eq!(x.d1.as_ref(), &Felt252::from(2)); + assert_eq!(x.d2.as_ref(), &Felt252::from(3)); + assert_eq!(x.d3.as_ref(), &Felt252::from(4)); + assert_eq!(x.d4.as_ref(), &Felt252::from(5)); + } + #[test] fn get_bigint3_from_base_addr_missing_member() { //BigInt3(1,2,x) @@ -240,6 +303,14 @@ mod tests { assert_matches!(r, Err(HintError::IdentifierHasNoMember(x, y)) if x == "x" && y == "d2") } + #[test] + fn get_bigint5_from_base_addr_missing_member() { + let mut vm = vm!(); + vm.segments = segments![((0, 0), 1), ((0, 1), 2), ((0, 2), 3), ((0, 3), 4),]; + let r = BigInt5::from_base_addr((0, 0).into(), "x", &vm); + assert_matches!(r, Err(HintError::IdentifierHasNoMember(x, y)) if x == "x" && y == "d4") + } + #[test] fn get_bigint3_from_var_name_ok() { //BigInt3(1,2,3) @@ -253,6 +324,27 @@ mod tests { assert_eq!(x.d2.as_ref(), &Felt252::from(3)); } + #[test] + fn get_bigint5_from_var_name_ok() { + // BigInt5(1,2,3,4,5) + let mut vm = vm!(); + vm.set_fp(1); + vm.segments = segments![ + ((1, 0), 1), + ((1, 1), 2), + ((1, 2), 3), + ((1, 3), 4), + ((1, 4), 5) + ]; + let ids_data = ids_data!["x"]; + let x = BigInt5::from_var_name("x", &vm, &ids_data, &ApTracking::default()).unwrap(); + assert_eq!(x.d0.as_ref(), &Felt252::one()); + assert_eq!(x.d1.as_ref(), &Felt252::from(2)); + assert_eq!(x.d2.as_ref(), &Felt252::from(3)); + assert_eq!(x.d3.as_ref(), &Felt252::from(4)); + assert_eq!(x.d4.as_ref(), &Felt252::from(5)); + } + #[test] fn get_bigint3_from_var_name_missing_member() { //BigInt3(1,2,x) @@ -264,6 +356,17 @@ mod tests { assert_matches!(r, Err(HintError::IdentifierHasNoMember(x, y)) if x == "x" && y == "d2") } + #[test] + fn get_bigint5_from_var_name_missing_member() { + //BigInt5(1,2,3,4,x) + let mut vm = vm!(); + vm.set_fp(1); + vm.segments = segments![((1, 0), 1), ((1, 1), 2), ((1, 2), 3), ((1, 3), 4)]; + let ids_data = ids_data!["x"]; + let r = BigInt5::from_var_name("x", &vm, &ids_data, &ApTracking::default()); + assert_matches!(r, Err(HintError::IdentifierHasNoMember(x, y)) if x == "x" && y == "d4") + } + #[test] fn get_bigint3_from_var_name_invalid_reference() { let mut vm = vm!(); @@ -273,6 +376,22 @@ mod tests { assert_matches!(r, Err(HintError::UnknownIdentifier(x)) if x == "x") } + #[test] + fn get_bigint5_from_var_name_invalid_reference() { + let mut vm = vm!(); + // Will fail because fp was not set to 1. + vm.segments = segments![ + ((1, 0), 1), + ((1, 1), 2), + ((1, 2), 3), + ((1, 3), 4), + ((1, 4), 5) + ]; + let ids_data = ids_data!["x"]; + let r = BigInt5::from_var_name("x", &vm, &ids_data, &ApTracking::default()); + assert_matches!(r, Err(HintError::UnknownIdentifier(x)) if x == "x") + } + #[test] fn run_hi_max_bitlen_ok() { let hint_code = diff --git a/src/tests/cairo_run_test.rs b/src/tests/cairo_run_test.rs index 412c185db3..9fea2f38dd 100644 --- a/src/tests/cairo_run_test.rs +++ b/src/tests/cairo_run_test.rs @@ -758,6 +758,13 @@ fn garaga() { run_program_simple(program_data.as_slice()); } +#[test] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +fn cairo_run_bigint_div_mod() { + let program_data = include_bytes!("../../cairo_programs/bigint.json"); + run_program_simple(program_data.as_slice()); +} + #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn div_mod_n() {