Skip to content

Commit

Permalink
feat(hints): Implement NewHint#37 (#1032)
Browse files Browse the repository at this point in the history
* 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

* fmt

* Remove indent from hint string

* Add wasm import
  • Loading branch information
fmoletta authored Apr 24, 2023
1 parent 3be76c4 commit 2eec112
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 0 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

#### Upcoming Changes

* Implement hint on ec_recover.json whitelist [#1032](https://github.com/lambdaclass/cairo-rs/pull/1032):

`BuiltinHintProcessor` now supports the following hint:

```python
%{
from starkware.cairo.common.cairo_secp.secp_utils import pack
from starkware.python.math_utils import div_mod, safe_div

N = pack(ids.n, PRIME)
x = pack(ids.x, PRIME) % N
s = pack(ids.s, PRIME) % N,
value = res = div_mod(x, s, N)
%}
```

* Implement hints on field_arithmetic lib (Part 2) [#1004](https://github.com/lambdaclass/cairo-rs/pull/1004)

`BuiltinHintProcessor` now supports the following hint:
Expand Down
27 changes: 27 additions & 0 deletions cairo_programs/ec_recover.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
%builtins range_check
from starkware.cairo.common.cairo_secp.bigint import BigInt3, nondet_bigint3

func test_div_mod_n_packed_hint{range_check_ptr: felt}() {

tempvar n = BigInt3(177, 0, 0);
tempvar x = BigInt3(25, 0, 0);
tempvar s = BigInt3(5, 0, 0);
%{
from starkware.cairo.common.cairo_secp.secp_utils import pack
from starkware.python.math_utils import div_mod, safe_div
N = pack(ids.n, PRIME)
x = pack(ids.x, PRIME) % N
s = pack(ids.s, PRIME) % N
value = res = div_mod(x, s, N)
%}

let (res) = nondet_bigint3();
assert res = BigInt3(5,0,0);
return();
}

func main{range_check_ptr: felt}() {
test_div_mod_n_packed_hint();
return();
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ use felt::Felt252;
#[cfg(feature = "skip_next_instruction_hint")]
use crate::hint_processor::builtin_hint_processor::skip_next_instruction::skip_next_instruction;

use super::ec_recover::ec_recover_divmod_n_packed;
use super::field_arithmetic::uint384_div;
use super::vrf::inv_mod_p_uint512::inv_mod_p_uint512;

Expand Down Expand Up @@ -585,6 +586,12 @@ impl HintProcessor for BuiltinHintProcessor {
inv_mod_p_uint512(vm, &hint_data.ids_data, &hint_data.ap_tracking)
}
hint_code::DI_BIT => di_bit(vm, &hint_data.ids_data, &hint_data.ap_tracking),
hint_code::EC_RECOVER_DIV_MOD_N_PACKED => ec_recover_divmod_n_packed(
vm,
exec_scopes,
&hint_data.ids_data,
&hint_data.ap_tracking,
),
#[cfg(feature = "skip_next_instruction_hint")]
hint_code::SKIP_NEXT_INSTRUCTION => skip_next_instruction(vm),
code => Err(HintError::UnknownHint(code.to_string())),
Expand Down
102 changes: 102 additions & 0 deletions src/hint_processor/builtin_hint_processor/ec_recover.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
use super::secp::{bigint_utils::BigInt3, secp_utils::pack};
use crate::stdlib::{collections::HashMap, prelude::*};
use crate::{
hint_processor::hint_processor_definition::HintReference,
math_utils::div_mod,
serde::deserialize_program::ApTracking,
types::exec_scope::ExecutionScopes,
vm::{errors::hint_errors::HintError, vm_core::VirtualMachine},
};
use num_integer::Integer;

/* Implements Hint:
%{
from starkware.cairo.common.cairo_secp.secp_utils import pack
from starkware.python.math_utils import div_mod, safe_div
N = pack(ids.n, PRIME)
x = pack(ids.x, PRIME) % N
s = pack(ids.s, PRIME) % N,
value = res = div_mod(x, s, N)
%}
*/
pub fn ec_recover_divmod_n_packed(
vm: &mut VirtualMachine,
exec_scopes: &mut ExecutionScopes,
ids_data: &HashMap<String, HintReference>,
ap_tracking: &ApTracking,
) -> Result<(), HintError> {
let n = pack(BigInt3::from_var_name("n", vm, ids_data, ap_tracking)?);
let x = pack(BigInt3::from_var_name("x", vm, ids_data, ap_tracking)?).mod_floor(&n);
let s = pack(BigInt3::from_var_name("s", vm, ids_data, ap_tracking)?).mod_floor(&n);

let value = div_mod(&x, &s, &n);
exec_scopes.insert_value("value", value.clone());
exec_scopes.insert_value("res", value);
Ok(())
}

#[cfg(test)]
mod tests {
use num_bigint::BigInt;

use super::*;
use crate::hint_processor::builtin_hint_processor::hint_code;
use crate::hint_processor::hint_processor_definition::HintReference;
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;
use crate::vm::vm_memory::memory_segments::MemorySegmentManager;
use crate::{
any_box,
hint_processor::{
builtin_hint_processor::builtin_hint_processor_definition::{
BuiltinHintProcessor, HintProcessorData,
},
hint_processor_definition::HintProcessor,
},
types::{exec_scope::ExecutionScopes, relocatable::MaybeRelocatable},
};

#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::*;

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn run_ec_recover_divmod_n_packed_ok() {
let mut vm = vm!();
let mut exec_scopes = ExecutionScopes::new();

vm.run_context.fp = 8;
let ids_data = non_continuous_ids_data![("n", -8), ("x", -5), ("s", -2)];

vm.segments = segments![
//n
((1, 0), 177),
((1, 1), 0),
((1, 2), 0),
//x
((1, 3), 25),
((1, 4), 0),
((1, 5), 0),
//s
((1, 6), 5),
((1, 7), 0),
((1, 8), 0)
];

assert!(run_hint!(
vm,
ids_data,
hint_code::EC_RECOVER_DIV_MOD_N_PACKED,
&mut exec_scopes
)
.is_ok());

check_scope!(
&exec_scopes,
[("value", BigInt::from(5)), ("res", BigInt::from(5))]
);
}
}
6 changes: 6 additions & 0 deletions src/hint_processor/builtin_hint_processor/hint_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,12 @@ ids.x_inverse_mod_p.high = x_inverse_mod_p_split[1]";

pub const DI_BIT: &str =
r#"ids.dibit = ((ids.scalar_u >> ids.m) & 1) + 2 * ((ids.scalar_v >> ids.m) & 1)"#;
pub const EC_RECOVER_DIV_MOD_N_PACKED: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import pack
from starkware.python.math_utils import div_mod, safe_div
N = pack(ids.n, PRIME)
x = pack(ids.x, PRIME) % N
s = pack(ids.s, PRIME) % N
value = res = div_mod(x, s, N)"#;
#[cfg(feature = "skip_next_instruction_hint")]
pub const SKIP_NEXT_INSTRUCTION: &str = "skip_next_instruction()";
1 change: 1 addition & 0 deletions src/hint_processor/builtin_hint_processor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod builtin_hint_processor_definition;
pub mod cairo_keccak;
pub mod dict_hint_utils;
pub mod dict_manager;
pub mod ec_recover;
pub mod ec_utils;
pub mod field_arithmetic;
pub mod find_element_hint;
Expand Down
7 changes: 7 additions & 0 deletions src/tests/cairo_run_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,13 @@ fn memory_holes() {
run_program_simple_with_memory_holes(program_data.as_slice(), 5)
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn ec_recover() {
let program_data = include_bytes!("../../cairo_programs/ec_recover.json");
run_program_simple(program_data.as_slice());
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn cairo_run_inv_mod_p_uint512() {
Expand Down

0 comments on commit 2eec112

Please sign in to comment.