Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(hints): Implement NewHint#63 & NewHint#65 #1047

Merged
merged 10 commits into from
Apr 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,39 @@

#### Upcoming Changes


* Implement hint on `assert_le_felt` for versions 0.6.0 and 0.8.2 [#1047](https://github.com/lambdaclass/cairo-rs/pull/1047):

`BuiltinHintProcessor` now supports the following hints:

```python

%{
from starkware.cairo.common.math_utils import assert_integer
assert_integer(ids.a)
assert_integer(ids.b)
assert (ids.a % PRIME) <= (ids.b % PRIME), \
f'a = {ids.a % PRIME} is not less than or equal to b = {ids.b % PRIME}.'
%}

```

```python

%{
from starkware.cairo.common.math_utils import assert_integer
assert_integer(ids.a)
assert_integer(ids.b)
a = ids.a % PRIME
b = ids.b % PRIME
assert a <= b, f'a = {a} is not less than or equal to b = {b}.'

ids.small_inputs = int(
a < range_check_builtin.bound and (b - a) < range_check_builtin.bound)
%}

```

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

`BuiltinHintProcessor` now supports the following hint:
Expand Down
68 changes: 68 additions & 0 deletions cairo_programs/assert_le_felt_old.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
%builtins range_check
from starkware.cairo.common.math import split_felt, assert_le, assert_nn_le

// Asserts that the unsigned integer lift (as a number in the range [0, PRIME)) of a is lower than
// or equal to that of b.
// See split_felt() for more details.
func assert_le_felt_v_0_6{range_check_ptr}(a, b) {
%{
from starkware.cairo.common.math_utils import assert_integer
assert_integer(ids.a)
assert_integer(ids.b)
assert (ids.a % PRIME) <= (ids.b % PRIME), \
f'a = {ids.a % PRIME} is not less than or equal to b = {ids.b % PRIME}.'
%}
alloc_locals;
let (local a_high, local a_low) = split_felt(a);
let (b_high, b_low) = split_felt(b);

if (a_high == b_high) {
assert_le(a_low, b_low);
return ();
}
assert_le(a_high, b_high);
return ();
}

// Asserts that the unsigned integer lift (as a number in the range [0, PRIME)) of a is lower than
// or equal to that of b.
// See split_felt() for more details.
@known_ap_change
func assert_le_felt_v_0_8{range_check_ptr}(a, b) {
alloc_locals;
local small_inputs;
%{
from starkware.cairo.common.math_utils import assert_integer
assert_integer(ids.a)
assert_integer(ids.b)
a = ids.a % PRIME
b = ids.b % PRIME
assert a <= b, f'a = {a} is not less than or equal to b = {b}.'

ids.small_inputs = int(
a < range_check_builtin.bound and (b - a) < range_check_builtin.bound)
%}
if (small_inputs != 0) {
assert_nn_le(a, b);
ap += 33;
return ();
}

let (local a_high, local a_low) = split_felt(a);
let (b_high, b_low) = split_felt(b);

if (a_high == b_high) {
assert_le(a_low, b_low);
return ();
}

assert_le(a_high, b_high);
return ();
}

func main{range_check_ptr}() {
assert_le_felt_v_0_6(7, 17);
assert_le_felt_v_0_8(6, 16);
assert_le_felt_v_0_8(5, -15);
return();
}
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,12 @@ impl HintProcessor for BuiltinHintProcessor {
hint_code::EC_RECOVER_SUB_A_B => {
ec_recover_sub_a_b(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking)
}
hint_code::ASSERT_LE_FELT_V_0_6 => {
assert_le_felt_v_0_6(vm, &hint_data.ids_data, &hint_data.ap_tracking)
}
hint_code::ASSERT_LE_FELT_V_0_8 => {
assert_le_felt_v_0_8(vm, &hint_data.ids_data, &hint_data.ap_tracking)
}
hint_code::EC_RECOVER_PRODUCT_MOD => {
ec_recover_product_mod(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking)
}
Expand Down
18 changes: 18 additions & 0 deletions src/hint_processor/builtin_hint_processor/hint_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,24 @@ memory[ids.range_check_ptr + 1], memory[ids.range_check_ptr + 0] = (
memory[ids.range_check_ptr + 3], memory[ids.range_check_ptr + 2] = (
divmod(lengths_and_indices[1][0], ids.PRIME_OVER_2_HIGH))"#;

pub const ASSERT_LE_FELT_V_0_6: &str =
"from starkware.cairo.common.math_utils import assert_integer
assert_integer(ids.a)
assert_integer(ids.b)
assert (ids.a % PRIME) <= (ids.b % PRIME), \\
f'a = {ids.a % PRIME} is not less than or equal to b = {ids.b % PRIME}.'";

pub const ASSERT_LE_FELT_V_0_8: &str =
"from starkware.cairo.common.math_utils import assert_integer
assert_integer(ids.a)
assert_integer(ids.b)
a = ids.a % PRIME
b = ids.b % PRIME
assert a <= b, f'a = {a} is not less than or equal to b = {b}.'

ids.small_inputs = int(
a < range_check_builtin.bound and (b - a) < range_check_builtin.bound)";

pub const ASSERT_LE_FELT_EXCLUDED_0: &str = "memory[ap] = 1 if excluded != 0 else 0";
pub const ASSERT_LE_FELT_EXCLUDED_1: &str = "memory[ap] = 1 if excluded != 1 else 0";
pub const ASSERT_LE_FELT_EXCLUDED_2: &str = "assert excluded == 2";
Expand Down
73 changes: 73 additions & 0 deletions src/hint_processor/builtin_hint_processor/math_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,47 @@ pub fn assert_le_felt(
Ok(())
}

pub fn assert_le_felt_v_0_6(
vm: &mut VirtualMachine,
ids_data: &HashMap<String, HintReference>,
ap_tracking: &ApTracking,
) -> 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)?;

if a.as_ref() > b.as_ref() {
return Err(HintError::NonLeFelt252(
a.clone().into_owned(),
b.clone().into_owned(),
));
}
Ok(())
}

pub fn assert_le_felt_v_0_8(
vm: &mut VirtualMachine,
ids_data: &HashMap<String, HintReference>,
ap_tracking: &ApTracking,
) -> 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)?;

if a.as_ref() > b.as_ref() {
return Err(HintError::NonLeFelt252(
a.clone().into_owned(),
b.clone().into_owned(),
));
}
let bound = vm
.get_range_check_builtin()?
._bound
.clone()
.unwrap_or_default();
let small_inputs =
Felt252::from((a.as_ref() < &bound && b.as_ref() - a.as_ref() < bound) as u8);
insert_value_from_var_name("small_inputs", small_inputs, vm, ids_data, ap_tracking)
}

pub fn assert_le_felt_excluded_2(exec_scopes: &mut ExecutionScopes) -> Result<(), HintError> {
let excluded: Felt252 = exec_scopes.get("excluded")?;

Expand Down Expand Up @@ -2001,6 +2042,38 @@ mod tests {
);
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn run_is_assert_le_felt_v_0_6_assertion_fail() {
let mut vm = vm_with_range_check!();
vm.set_fp(2);
vm.segments = segments![((1, 0), 17), ((1, 1), 7)];
//Initialize ap
//Create ids_data & hint_data
let ids_data = ids_data!["a", "b"];
//Execute the hint
assert_matches!(
run_hint!(vm, ids_data, hint_code::ASSERT_LE_FELT_V_0_6),
Err(HintError::NonLeFelt252(a, b)) if a == 17_u32.into() && b == 7_u32.into()
);
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn run_is_assert_le_felt_v_0_8_assertion_fail() {
let mut vm = vm_with_range_check!();
vm.set_fp(2);
vm.segments = segments![((1, 0), 17), ((1, 1), 7)];
//Initialize ap
//Create ids_data & hint_data
let ids_data = ids_data!["a", "b"];
//Execute the hint
assert_matches!(
run_hint!(vm, ids_data, hint_code::ASSERT_LE_FELT_V_0_8),
Err(HintError::NonLeFelt252(a, b)) if a == 17_u32.into() && b == 7_u32.into()
);
}

#[cfg(not(target_arch = "wasm32"))]
proptest! {
#[test]
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 @@ -828,6 +828,13 @@ fn cairo_run_inv_mod_p_uint512() {
run_program_simple(program_data.as_slice());
}

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

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