diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a028ea8f6..07bb1d3860 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ #### Upcoming Changes + * fix: Fix felt sqrt and Signed impl [#1150](https://github.com/lambdaclass/cairo-rs/pull/1150) * BREAKING: Fix `Felt252` methods `abs`, `signum`, `is_positive`, `is_negative` and `sqrt` @@ -21,7 +22,8 @@ * Fix implementation of `InitSquashData` and `ShouldSkipSquashLoop` -* Add more hints to `Cairo1HintProcessor` [#1143](https://github.com/lambdaclass/cairo-rs/pull/1143) +* Add more hints to `Cairo1HintProcessor` [#1171](https://github.com/lambdaclass/cairo-rs/pull/1171) + [#1143](https://github.com/lambdaclass/cairo-rs/pull/1143) * `Cairo1HintProcessor` can now run the following hints: * Felt252DictEntryInit @@ -32,6 +34,7 @@ * GetCurrentAccessIndex * ShouldContinueSquashLoop * FieldSqrt + * Uint512DivMod * Add some small considerations regarding Cairo 1 programs [#1144](https://github.com/lambdaclass/cairo-rs/pull/1144): diff --git a/Cargo.lock b/Cargo.lock index fca048f77c..7707324fcf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -275,8 +275,6 @@ dependencies = [ "num-bigint", "num-integer", "num-traits 0.2.15", - "proptest", - "rstest", "serde", ] @@ -289,13 +287,14 @@ dependencies = [ "num-integer", "num-traits 0.2.15", "proptest", + "rstest", "serde", ] [[package]] name = "cairo-lang-casm" version = "1.0.0-rc0" -source = "git+https://github.com/starkware-libs/cairo.git?rev=44fdeb26231f5022f2441bf89018272460c4e326#44fdeb26231f5022f2441bf89018272460c4e326" +source = "git+https://github.com/starkware-libs/cairo.git?rev=4afacfd574de1121d61dea28f8c73e1516c7e07d#4afacfd574de1121d61dea28f8c73e1516c7e07d" dependencies = [ "cairo-lang-utils", "indoc", @@ -308,7 +307,7 @@ dependencies = [ [[package]] name = "cairo-lang-compiler" version = "1.0.0-rc0" -source = "git+https://github.com/starkware-libs/cairo.git?rev=44fdeb26231f5022f2441bf89018272460c4e326#44fdeb26231f5022f2441bf89018272460c4e326" +source = "git+https://github.com/starkware-libs/cairo.git?rev=4afacfd574de1121d61dea28f8c73e1516c7e07d#4afacfd574de1121d61dea28f8c73e1516c7e07d" dependencies = [ "anyhow", "cairo-lang-defs", @@ -333,12 +332,12 @@ dependencies = [ [[package]] name = "cairo-lang-debug" version = "1.0.0-rc0" -source = "git+https://github.com/starkware-libs/cairo.git?rev=44fdeb26231f5022f2441bf89018272460c4e326#44fdeb26231f5022f2441bf89018272460c4e326" +source = "git+https://github.com/starkware-libs/cairo.git?rev=4afacfd574de1121d61dea28f8c73e1516c7e07d#4afacfd574de1121d61dea28f8c73e1516c7e07d" [[package]] name = "cairo-lang-defs" version = "1.0.0-rc0" -source = "git+https://github.com/starkware-libs/cairo.git?rev=44fdeb26231f5022f2441bf89018272460c4e326#44fdeb26231f5022f2441bf89018272460c4e326" +source = "git+https://github.com/starkware-libs/cairo.git?rev=4afacfd574de1121d61dea28f8c73e1516c7e07d#4afacfd574de1121d61dea28f8c73e1516c7e07d" dependencies = [ "cairo-lang-debug", "cairo-lang-diagnostics", @@ -355,7 +354,7 @@ dependencies = [ [[package]] name = "cairo-lang-diagnostics" version = "1.0.0-rc0" -source = "git+https://github.com/starkware-libs/cairo.git?rev=44fdeb26231f5022f2441bf89018272460c4e326#44fdeb26231f5022f2441bf89018272460c4e326" +source = "git+https://github.com/starkware-libs/cairo.git?rev=4afacfd574de1121d61dea28f8c73e1516c7e07d#4afacfd574de1121d61dea28f8c73e1516c7e07d" dependencies = [ "cairo-lang-filesystem", "cairo-lang-utils", @@ -366,7 +365,7 @@ dependencies = [ [[package]] name = "cairo-lang-eq-solver" version = "1.0.0-rc0" -source = "git+https://github.com/starkware-libs/cairo.git?rev=44fdeb26231f5022f2441bf89018272460c4e326#44fdeb26231f5022f2441bf89018272460c4e326" +source = "git+https://github.com/starkware-libs/cairo.git?rev=4afacfd574de1121d61dea28f8c73e1516c7e07d#4afacfd574de1121d61dea28f8c73e1516c7e07d" dependencies = [ "cairo-lang-utils", "good_lp", @@ -377,7 +376,7 @@ dependencies = [ [[package]] name = "cairo-lang-filesystem" version = "1.0.0-rc0" -source = "git+https://github.com/starkware-libs/cairo.git?rev=44fdeb26231f5022f2441bf89018272460c4e326#44fdeb26231f5022f2441bf89018272460c4e326" +source = "git+https://github.com/starkware-libs/cairo.git?rev=4afacfd574de1121d61dea28f8c73e1516c7e07d#4afacfd574de1121d61dea28f8c73e1516c7e07d" dependencies = [ "cairo-lang-debug", "cairo-lang-utils", @@ -390,7 +389,7 @@ dependencies = [ [[package]] name = "cairo-lang-lowering" version = "1.0.0-rc0" -source = "git+https://github.com/starkware-libs/cairo.git?rev=44fdeb26231f5022f2441bf89018272460c4e326#44fdeb26231f5022f2441bf89018272460c4e326" +source = "git+https://github.com/starkware-libs/cairo.git?rev=4afacfd574de1121d61dea28f8c73e1516c7e07d#4afacfd574de1121d61dea28f8c73e1516c7e07d" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", @@ -414,7 +413,7 @@ dependencies = [ [[package]] name = "cairo-lang-parser" version = "1.0.0-rc0" -source = "git+https://github.com/starkware-libs/cairo.git?rev=44fdeb26231f5022f2441bf89018272460c4e326#44fdeb26231f5022f2441bf89018272460c4e326" +source = "git+https://github.com/starkware-libs/cairo.git?rev=4afacfd574de1121d61dea28f8c73e1516c7e07d#4afacfd574de1121d61dea28f8c73e1516c7e07d" dependencies = [ "cairo-lang-diagnostics", "cairo-lang-filesystem", @@ -434,7 +433,7 @@ dependencies = [ [[package]] name = "cairo-lang-plugins" version = "1.0.0-rc0" -source = "git+https://github.com/starkware-libs/cairo.git?rev=44fdeb26231f5022f2441bf89018272460c4e326#44fdeb26231f5022f2441bf89018272460c4e326" +source = "git+https://github.com/starkware-libs/cairo.git?rev=4afacfd574de1121d61dea28f8c73e1516c7e07d#4afacfd574de1121d61dea28f8c73e1516c7e07d" dependencies = [ "cairo-lang-defs", "cairo-lang-diagnostics", @@ -452,7 +451,7 @@ dependencies = [ [[package]] name = "cairo-lang-proc-macros" version = "1.0.0-rc0" -source = "git+https://github.com/starkware-libs/cairo.git?rev=44fdeb26231f5022f2441bf89018272460c4e326#44fdeb26231f5022f2441bf89018272460c4e326" +source = "git+https://github.com/starkware-libs/cairo.git?rev=4afacfd574de1121d61dea28f8c73e1516c7e07d#4afacfd574de1121d61dea28f8c73e1516c7e07d" dependencies = [ "cairo-lang-debug", "quote", @@ -462,7 +461,7 @@ dependencies = [ [[package]] name = "cairo-lang-project" version = "1.0.0-rc0" -source = "git+https://github.com/starkware-libs/cairo.git?rev=44fdeb26231f5022f2441bf89018272460c4e326#44fdeb26231f5022f2441bf89018272460c4e326" +source = "git+https://github.com/starkware-libs/cairo.git?rev=4afacfd574de1121d61dea28f8c73e1516c7e07d#4afacfd574de1121d61dea28f8c73e1516c7e07d" dependencies = [ "cairo-lang-filesystem", "serde", @@ -474,7 +473,7 @@ dependencies = [ [[package]] name = "cairo-lang-semantic" version = "1.0.0-rc0" -source = "git+https://github.com/starkware-libs/cairo.git?rev=44fdeb26231f5022f2441bf89018272460c4e326#44fdeb26231f5022f2441bf89018272460c4e326" +source = "git+https://github.com/starkware-libs/cairo.git?rev=4afacfd574de1121d61dea28f8c73e1516c7e07d#4afacfd574de1121d61dea28f8c73e1516c7e07d" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", @@ -496,7 +495,7 @@ dependencies = [ [[package]] name = "cairo-lang-sierra" version = "1.0.0-rc0" -source = "git+https://github.com/starkware-libs/cairo.git?rev=44fdeb26231f5022f2441bf89018272460c4e326#44fdeb26231f5022f2441bf89018272460c4e326" +source = "git+https://github.com/starkware-libs/cairo.git?rev=4afacfd574de1121d61dea28f8c73e1516c7e07d#4afacfd574de1121d61dea28f8c73e1516c7e07d" dependencies = [ "cairo-lang-utils", "const-fnv1a-hash", @@ -518,7 +517,7 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-ap-change" version = "1.0.0-rc0" -source = "git+https://github.com/starkware-libs/cairo.git?rev=44fdeb26231f5022f2441bf89018272460c4e326#44fdeb26231f5022f2441bf89018272460c4e326" +source = "git+https://github.com/starkware-libs/cairo.git?rev=4afacfd574de1121d61dea28f8c73e1516c7e07d#4afacfd574de1121d61dea28f8c73e1516c7e07d" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", @@ -530,7 +529,7 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-gas" version = "1.0.0-rc0" -source = "git+https://github.com/starkware-libs/cairo.git?rev=44fdeb26231f5022f2441bf89018272460c4e326#44fdeb26231f5022f2441bf89018272460c4e326" +source = "git+https://github.com/starkware-libs/cairo.git?rev=4afacfd574de1121d61dea28f8c73e1516c7e07d#4afacfd574de1121d61dea28f8c73e1516c7e07d" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", @@ -542,7 +541,7 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-generator" version = "1.0.0-rc0" -source = "git+https://github.com/starkware-libs/cairo.git?rev=44fdeb26231f5022f2441bf89018272460c4e326#44fdeb26231f5022f2441bf89018272460c4e326" +source = "git+https://github.com/starkware-libs/cairo.git?rev=4afacfd574de1121d61dea28f8c73e1516c7e07d#4afacfd574de1121d61dea28f8c73e1516c7e07d" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", @@ -567,7 +566,7 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-to-casm" version = "1.0.0-rc0" -source = "git+https://github.com/starkware-libs/cairo.git?rev=44fdeb26231f5022f2441bf89018272460c4e326#44fdeb26231f5022f2441bf89018272460c4e326" +source = "git+https://github.com/starkware-libs/cairo.git?rev=4afacfd574de1121d61dea28f8c73e1516c7e07d#4afacfd574de1121d61dea28f8c73e1516c7e07d" dependencies = [ "anyhow", "assert_matches", @@ -589,7 +588,7 @@ dependencies = [ [[package]] name = "cairo-lang-starknet" version = "1.0.0-rc0" -source = "git+https://github.com/starkware-libs/cairo.git?rev=44fdeb26231f5022f2441bf89018272460c4e326#44fdeb26231f5022f2441bf89018272460c4e326" +source = "git+https://github.com/starkware-libs/cairo.git?rev=4afacfd574de1121d61dea28f8c73e1516c7e07d#4afacfd574de1121d61dea28f8c73e1516c7e07d" dependencies = [ "anyhow", "cairo-felt 0.3.0-rc1", @@ -629,7 +628,7 @@ dependencies = [ [[package]] name = "cairo-lang-syntax" version = "1.0.0-rc0" -source = "git+https://github.com/starkware-libs/cairo.git?rev=44fdeb26231f5022f2441bf89018272460c4e326#44fdeb26231f5022f2441bf89018272460c4e326" +source = "git+https://github.com/starkware-libs/cairo.git?rev=4afacfd574de1121d61dea28f8c73e1516c7e07d#4afacfd574de1121d61dea28f8c73e1516c7e07d" dependencies = [ "cairo-lang-debug", "cairo-lang-filesystem", @@ -645,7 +644,7 @@ dependencies = [ [[package]] name = "cairo-lang-syntax-codegen" version = "1.0.0-rc0" -source = "git+https://github.com/starkware-libs/cairo.git?rev=44fdeb26231f5022f2441bf89018272460c4e326#44fdeb26231f5022f2441bf89018272460c4e326" +source = "git+https://github.com/starkware-libs/cairo.git?rev=4afacfd574de1121d61dea28f8c73e1516c7e07d#4afacfd574de1121d61dea28f8c73e1516c7e07d" dependencies = [ "cairo-lang-utils", "genco", @@ -656,7 +655,7 @@ dependencies = [ [[package]] name = "cairo-lang-utils" version = "1.0.0-rc0" -source = "git+https://github.com/starkware-libs/cairo.git?rev=44fdeb26231f5022f2441bf89018272460c4e326#44fdeb26231f5022f2441bf89018272460c4e326" +source = "git+https://github.com/starkware-libs/cairo.git?rev=4afacfd574de1121d61dea28f8c73e1516c7e07d#4afacfd574de1121d61dea28f8c73e1516c7e07d" dependencies = [ "env_logger", "indexmap", diff --git a/Cargo.toml b/Cargo.toml index 32e167232b..a981005731 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -83,8 +83,8 @@ felt = { package = "cairo-felt", path = "./felt", version = "0.4.0", default-fea bitvec = { version = "1", default-features = false, features = ["alloc"] } # Dependencies for cairo-1-hints feature -cairo-lang-starknet = { git = "https://github.com/starkware-libs/cairo.git", rev = "44fdeb26231f5022f2441bf89018272460c4e326", optional = true} -cairo-lang-casm = { git = "https://github.com/starkware-libs/cairo.git", rev = "44fdeb26231f5022f2441bf89018272460c4e326", optional = true } +cairo-lang-starknet = { git = "https://github.com/starkware-libs/cairo.git", rev = "4afacfd574de1121d61dea28f8c73e1516c7e07d", optional = true} +cairo-lang-casm = { git = "https://github.com/starkware-libs/cairo.git", rev = "4afacfd574de1121d61dea28f8c73e1516c7e07d", optional = true } # TODO: check these dependencies for wasm compatibility ark-ff = {version = "0.4.0-alpha.7", default-features = false, optional = true} diff --git a/cairo_programs/cairo-1-contracts/uint512_div_mod.cairo b/cairo_programs/cairo-1-contracts/uint512_div_mod.cairo new file mode 100644 index 0000000000..d119a6cf5d --- /dev/null +++ b/cairo_programs/cairo-1-contracts/uint512_div_mod.cairo @@ -0,0 +1,26 @@ +#[contract] +mod UintDivMod { + +use integer::{u512, u512_safe_div_rem_by_u256}; + + #[external] + fn div_mod() -> () { + let zero = u512 { limb0: 0, limb1: 0, limb2: 0, limb3: 0 }; + let one = u512 { limb0: 1, limb1: 0, limb2: 0, limb3: 0 }; + + let (q, r) = u512_safe_div_rem_by_u256(zero, integer::u256_as_non_zero(1)); + assert(q == zero, '0 / 1 != 0'); + assert(r == 0, '0 % 1 != 0'); + + let (q, r) = u512_safe_div_rem_by_u256(one, integer::u256_as_non_zero(1)); + assert(q == one, '1 / 1 != 1'); + assert(r == 0, '1 % 1 != 0'); + + let two = u512 {limb0: 0, limb1: 0, limb2: 0, limb3: 2}; + let (q, r) = u512_safe_div_rem_by_u256(two, integer::u256_as_non_zero(1)); + assert(q == two, '2/1 != 2'); + assert(r == 0, '2/1 != 0'); + + return (); + } +} diff --git a/src/hint_processor/cairo_1_hint_processor/hint_processor.rs b/src/hint_processor/cairo_1_hint_processor/hint_processor.rs index c436dd823b..b02cc46403 100644 --- a/src/hint_processor/cairo_1_hint_processor/hint_processor.rs +++ b/src/hint_processor/cairo_1_hint_processor/hint_processor.rs @@ -4,10 +4,9 @@ use crate::any_box; use crate::felt::{felt_str, Felt252}; use crate::hint_processor::cairo_1_hint_processor::dict_manager::DictSquashExecScope; use crate::hint_processor::hint_processor_definition::HintReference; -use crate::types::relocatable::Relocatable; - use crate::stdlib::collections::HashMap; use crate::stdlib::prelude::*; +use crate::types::relocatable::Relocatable; use crate::{ hint_processor::hint_processor_definition::HintProcessor, types::exec_scope::ExecutionScopes, @@ -27,6 +26,7 @@ use core::ops::Mul; use num_bigint::BigUint; use num_integer::Integer; use num_traits::{cast::ToPrimitive, Zero}; +use std::ops::Shl; /// Execution scope for constant memory allocation. struct MemoryExecScope { @@ -232,6 +232,25 @@ impl Cairo1HintProcessor { high, low, })) => self.wide_mul_128(vm, lhs, rhs, high, low), + + Hint::Core(CoreHintBase::Core(CoreHint::Uint512DivModByUint256 { + dividend0, + dividend1, + dividend2, + dividend3, + divisor0, + divisor1, + quotient0, + quotient1, + quotient2, + quotient3, + remainder0, + remainder1, + })) => self.uint512_div_mod( + vm, dividend0, dividend1, dividend2, dividend3, divisor0, divisor1, quotient0, + quotient1, quotient2, quotient3, remainder0, remainder1, + ), + hint => Err(HintError::UnknownHint(hint.to_string())), } } @@ -600,6 +619,70 @@ impl Cairo1HintProcessor { Ok(()) } + #[allow(clippy::too_many_arguments)] + fn uint512_div_mod( + &self, + vm: &mut VirtualMachine, + dividend0: &ResOperand, + dividend1: &ResOperand, + dividend2: &ResOperand, + dividend3: &ResOperand, + divisor0: &ResOperand, + divisor1: &ResOperand, + quotient0: &CellRef, + quotient1: &CellRef, + quotient2: &CellRef, + quotient3: &CellRef, + remainder0: &CellRef, + remainder1: &CellRef, + ) -> Result<(), HintError> { + let pow_2_128 = BigUint::from(u128::MAX) + 1u32; + let dividend0 = res_operand_get_val(vm, dividend0)?.to_biguint(); + let dividend1 = res_operand_get_val(vm, dividend1)?.to_biguint(); + let dividend2 = res_operand_get_val(vm, dividend2)?.to_biguint(); + let dividend3 = res_operand_get_val(vm, dividend3)?.to_biguint(); + let divisor0 = res_operand_get_val(vm, divisor0)?.to_biguint(); + let divisor1 = res_operand_get_val(vm, divisor1)?.to_biguint(); + let dividend: BigUint = + dividend0 + dividend1.shl(128) + dividend2.shl(256) + dividend3.shl(384); + let divisor = divisor0 + divisor1.shl(128); + let (quotient, remainder) = dividend.div_rem(&divisor); + let (quotient, limb0) = quotient.div_rem(&pow_2_128); + + vm.insert_value( + cell_ref_to_relocatable(quotient0, vm)?, + Felt252::from(limb0), + )?; + + let (quotient, limb1) = quotient.div_rem(&pow_2_128); + vm.insert_value( + cell_ref_to_relocatable(quotient1, vm)?, + Felt252::from(limb1), + )?; + let (limb3, limb2) = quotient.div_rem(&pow_2_128); + + vm.insert_value( + cell_ref_to_relocatable(quotient2, vm)?, + Felt252::from(limb2), + )?; + vm.insert_value( + cell_ref_to_relocatable(quotient3, vm)?, + Felt252::from(limb3), + )?; + let (limb1, limb0) = remainder.div_rem(&pow_2_128); + + vm.insert_value( + cell_ref_to_relocatable(remainder0, vm)?, + Felt252::from(limb0), + )?; + vm.insert_value( + cell_ref_to_relocatable(remainder1, vm)?, + Felt252::from(limb1), + )?; + + Ok(()) + } + #[allow(clippy::too_many_arguments)] fn uint256_square_root( &self, diff --git a/src/tests/cairo_1_run_from_entrypoint_tests.rs b/src/tests/cairo_1_run_from_entrypoint_tests.rs index 35ad3dc2ad..7ebe11db17 100644 --- a/src/tests/cairo_1_run_from_entrypoint_tests.rs +++ b/src/tests/cairo_1_run_from_entrypoint_tests.rs @@ -534,3 +534,18 @@ fn field_sqrt_test() { let program_data = include_bytes!("../../cairo_programs/cairo-1-contracts/field_sqrt.casm"); run_cairo_1_entrypoint(program_data.as_slice(), 0, &[], &[10.into()]); } +#[test] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +fn uint512_div_mod_test() { + let program_data = + include_bytes!("../../cairo_programs/cairo-1-contracts/uint512_div_mod.casm"); + run_cairo_1_entrypoint( + program_data.as_slice(), + 0, + &[], + // that property should be 1 (true) if + // the implementation is correct and + // false otherwise. + &[], + ); +}