From ce36cf7f55e84ef983f8d3b8c80fe66ccce02f80 Mon Sep 17 00:00:00 2001 From: fmoletta <99273364+fmoletta@users.noreply.github.com> Date: Tue, 25 Apr 2023 21:34:42 +0300 Subject: [PATCH] feat(hints): Implement NewHint#40 (#1038) * Add test * Ignore builtin segments in get_memory_holes * Improve test * Add memory holes check for cairo_run_test tests * Fix broken condition * Make memory_holes check optional & customizable * Fix bounds * Add a test with deliberately created memory holes * Fix test value * Remove duplicated tests + add memory hole value to some tests * Add memory holes value + remove duplicated tests + fix typo * Fix test values * Add changelog entry * Link PR in Changelog * Mark breaking change in changelog * fmt * Fix test value * Fix codecov-patch diff * Add hint code * Add integration test * Add untracked file * Add changelog entry * Rename hint * Fix test * Fix test * Add hint code + hint impl + unit test * fmt * Add integration test * Add changelog entry * Implement hint + add tests * Add changelog entry * Remove indent from hint string * Add wasm import * Fix prev hint + implement new hint * Add tests * Add changelog entry * Update CHANGELOG.md * Update CHANGELOG.md * Fix Pr numbers * Update src/hint_processor/builtin_hint_processor/ec_recover.rs Co-authored-by: Mario Rugiero * Fix changelog --------- Co-authored-by: Mario Rugiero --- CHANGELOG.md | 32 ++++++++----- cairo_programs/ec_recover.cairo | 11 ++++- .../builtin_hint_processor_definition.rs | 6 ++- .../builtin_hint_processor/ec_recover.rs | 45 ++++++++++++++++++- .../builtin_hint_processor/hint_code.rs | 2 + 5 files changed, 80 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4317283c44..957c6f9dac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,17 +2,22 @@ #### Upcoming Changes -<<<<<<< HEAD +* Implement hint on ec_recover.json whitelist [#1038](https://github.com/lambdaclass/cairo-rs/pull/1038): + + `BuiltinHintProcessor` now supports the following hint: + + ```python + %{ + value = k = product // m + %} + ``` + * Implement hint on ec_recover.json whitelist [#1037](https://github.com/lambdaclass/cairo-rs/pull/1037): -======= -* Implement hint for `starkware.cairo.common.cairo_keccak.keccak.finalize_keccak` as described by whitelist `starknet/security/whitelists/cairo_keccak.json` [#1041](https://github.com/lambdaclass/cairo-rs/pull/1041) ->>>>>>> 50c90d944bc090578824bb50bed1b1ada5a5fbc0 `BuiltinHintProcessor` now supports the following hint: ```python %{ -<<<<<<< HEAD from starkware.cairo.common.cairo_secp.secp_utils import pack from starkware.python.math_utils import div_mod, safe_div @@ -22,7 +27,16 @@ m = pack(ids.m, PRIME) value = res = product % m -======= + + %} + ``` + +* Implement hint for `starkware.cairo.common.cairo_keccak.keccak.finalize_keccak` as described by whitelist `starknet/security/whitelists/cairo_keccak.json` [#1041](https://github.com/lambdaclass/cairo-rs/pull/1041) + + `BuiltinHintProcessor` now supports the following hint: + + ```python + %{ # Add dummy pairs of input and output. _keccak_state_size_felts = int(ids.KECCAK_STATE_SIZE_FELTS) _block_size = int(ids.BLOCK_SIZE) @@ -31,7 +45,6 @@ inp = [0] * _keccak_state_size_felts padding = (inp + keccak_func(inp)) * _block_size segments.write_arg(ids.keccak_ptr_end, padding) ->>>>>>> 50c90d944bc090578824bb50bed1b1ada5a5fbc0 %} ``` @@ -68,8 +81,6 @@ %} ``` -<<<<<<< HEAD -======= * Implement hints on field_arithmetic lib (Part 2) [#1004](https://github.com/lambdaclass/cairo-rs/pull/1004) `BuiltinHintProcessor` now supports the following hint: @@ -128,7 +139,6 @@ ids.x_inverse_mod_p.high = x_inverse_mod_p_split[1] ``` ->>>>>>> fb731257da6fc2842abff103fccab964ae87bb38 * BREAKING CHANGE: Fix `CairoRunner::get_memory_holes` [#1027](https://github.com/lambdaclass/cairo-rs/pull/1027): * Skip builtin segements when counting memory holes @@ -869,4 +879,4 @@ * `pub fn from_vm_error(runner: &CairoRunner, error: VirtualMachineError, pc: usize) -> Self` is now `pub fn from_vm_error(runner: &CairoRunner, vm: &VirtualMachine, error: VirtualMachineError) -> Self` * `pub fn get_location(pc: &usize, runner: &CairoRunner) -> Option` is now `pub fn get_location(pc: usize, runner: &CairoRunner) -> Option` * `pub fn decode_instruction(encoded_instr: i64, mut imm: Option) -> Result` is now `pub fn decode_instruction(encoded_instr: i64, mut imm: Option<&BigInt>) -> Result` - * `VmExcepion` field's string format now mirror their cairo-lang conterparts. + * `VmExcepion` field's string format now mirror their cairo-lang conterparts. \ No newline at end of file diff --git a/cairo_programs/ec_recover.cairo b/cairo_programs/ec_recover.cairo index b5b630861c..d33d058d13 100644 --- a/cairo_programs/ec_recover.cairo +++ b/cairo_programs/ec_recover.cairo @@ -43,7 +43,7 @@ func test_sub_a_b_hint{range_check_ptr: felt}() { return(); } -func test_product_mod_hint{range_check_ptr: felt}() { +func test_product_hints{range_check_ptr: felt}() { tempvar a = BigInt3(60, 0, 0); tempvar b = BigInt3(2, 0, 0); @@ -64,12 +64,19 @@ func test_product_mod_hint{range_check_ptr: felt}() { let (res) = nondet_bigint3(); assert res = BigInt3(20,0,0); + %{ + value = k = product // m + %} + + let (k) = nondet_bigint3(); + assert k = BigInt3(1,0,0); + return(); } func main{range_check_ptr: felt}() { test_div_mod_n_packed_hint(); test_sub_a_b_hint(); - test_product_mod_hint(); + test_product_hints(); return(); } 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 cc98ead843..f4acf50ad1 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,5 +1,8 @@ use super::{ - ec_recover::{ec_recover_divmod_n_packed, ec_recover_product_mod, ec_recover_sub_a_b}, + ec_recover::{ + ec_recover_divmod_n_packed, ec_recover_product_div_m, ec_recover_product_mod, + ec_recover_sub_a_b, + }, field_arithmetic::uint384_div, vrf::{fq::uint512_unsigned_div_rem, inv_mod_p_uint512::inv_mod_p_uint512}, }; @@ -606,6 +609,7 @@ impl HintProcessor for BuiltinHintProcessor { hint_code::EC_RECOVER_PRODUCT_MOD => { ec_recover_product_mod(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking) } + hint_code::EC_RECOVER_PRODUCT_DIV_M => ec_recover_product_div_m(exec_scopes), #[cfg(feature = "skip_next_instruction_hint")] hint_code::SKIP_NEXT_INSTRUCTION => skip_next_instruction(vm), code => Err(HintError::UnknownHint(code.to_string())), diff --git a/src/hint_processor/builtin_hint_processor/ec_recover.rs b/src/hint_processor/builtin_hint_processor/ec_recover.rs index acaa0f1a50..f2b7b1e12c 100644 --- a/src/hint_processor/builtin_hint_processor/ec_recover.rs +++ b/src/hint_processor/builtin_hint_processor/ec_recover.rs @@ -10,6 +10,7 @@ use crate::{ types::exec_scope::ExecutionScopes, vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, }; +use num_bigint::BigInt; /* Implements Hint: %{ @@ -87,13 +88,28 @@ pub fn ec_recover_product_mod( let m = bigint3_pack(BigInt3::from_var_name("m", vm, ids_data, ap_tracking)?); let product = a * b; - exec_scopes.insert_value("product", product.clone()); let value = product.mod_floor(&m); + exec_scopes.insert_value("product", product); + exec_scopes.insert_value("m", m); exec_scopes.insert_value("value", value.clone()); exec_scopes.insert_value("res", value); Ok(()) } +/* Implements Hint: +%{ + value = k = product // m +%} + */ +pub fn ec_recover_product_div_m(exec_scopes: &mut ExecutionScopes) -> Result<(), HintError> { + let product: &BigInt = exec_scopes.get_ref("product")?; + let m: &BigInt = exec_scopes.get_ref("m")?; + let value = product.div_floor(m); + exec_scopes.insert_value("k", value.clone()); + exec_scopes.insert_value("value", value); + Ok(()) +} + #[cfg(test)] mod tests { use num_bigint::BigInt; @@ -226,8 +242,33 @@ mod tests { [ ("value", BigInt::from(20)), ("res", BigInt::from(20)), - ("product", BigInt::from(120)) + ("product", BigInt::from(120)), + ("m", BigInt::from(100)) ] ); } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn run_ec_recover_product_div_m_ok() { + let mut vm = vm!(); + let mut exec_scopes = ExecutionScopes::new(); + exec_scopes.insert_value("product", BigInt::from(250)); + exec_scopes.insert_value("m", BigInt::from(100)); + + let ids_data = ids_data!["none"]; + + assert!(run_hint!( + vm, + ids_data, + hint_code::EC_RECOVER_PRODUCT_DIV_M, + &mut exec_scopes + ) + .is_ok()); + + check_scope!( + &exec_scopes, + [("value", BigInt::from(2)), ("k", BigInt::from(2))] + ); + } } diff --git a/src/hint_processor/builtin_hint_processor/hint_code.rs b/src/hint_processor/builtin_hint_processor/hint_code.rs index f2e2e23ea3..e266922592 100644 --- a/src/hint_processor/builtin_hint_processor/hint_code.rs +++ b/src/hint_processor/builtin_hint_processor/hint_code.rs @@ -1044,5 +1044,7 @@ product = a * b m = pack(ids.m, PRIME) value = res = product % m"#; + +pub const EC_RECOVER_PRODUCT_DIV_M: &str = "value = k = product // m"; #[cfg(feature = "skip_next_instruction_hint")] pub const SKIP_NEXT_INSTRUCTION: &str = "skip_next_instruction()";