Skip to content

Commit

Permalink
Add range_check96 builtin (#1698)
Browse files Browse the repository at this point in the history
* Admit both types of range_check in range_check_builtin_runner

* Add range_check96 to layout + make bound a constant

* Clippy

* Add specialized constructors & remove n_parts field from instance def

* Add changelog entry

* fmt

* Use const generic to differentiate between RangeCheck and RangeCheck96

* Fix

* fmt

* Update relocated ptr values to account for added segment

* Fix
  • Loading branch information
fmoletta authored Apr 9, 2024
1 parent 15f9dc0 commit ca3b8ab
Show file tree
Hide file tree
Showing 15 changed files with 279 additions and 227 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

#### Upcoming Changes

* feat(BREAKING): Add range_check96 builtin[#1698](https://github.com/lambdaclass/cairo-vm/pull/1698)
* Add the new `range_check96` builtin to the `all_cairo` layout.
* `RangeCheckBuiltinRunner` changes:
* Remove field `n_parts`, replacing it with const generic `N_PARTS`.
* Remome `n_parts` argument form method `new`.
* Remove field `_bound`, replacing it with public method `bound`.
* Add public methods `name` & `n_parts`.

* feat(BREAKING): Add mod builtin [#1673](https://github.com/lambdaclass/cairo-vm/pull/1673)

Main Changes:
Expand Down
1 change: 1 addition & 0 deletions cairo1-run/src/cairo_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ fn create_entry_code(
BuiltinName::keccak
| BuiltinName::ecdsa
| BuiltinName::output
| BuiltinName::range_check96
| BuiltinName::add_mod
| BuiltinName::mul_mod => return fp_loc,
};
Expand Down
66 changes: 20 additions & 46 deletions fuzzer/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

63 changes: 20 additions & 43 deletions vm/src/hint_processor/builtin_hint_processor/math_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,9 @@ pub fn is_nn(
ap_tracking: &ApTracking,
) -> Result<(), HintError> {
let a = get_integer_from_var_name("a", vm, ids_data, ap_tracking)?;
let range_check_builtin = vm.get_range_check_builtin()?;
let range_check_bound = vm.get_range_check_builtin()?.bound();
//Main logic (assert a is not negative and within the expected range)
let value = match &range_check_builtin._bound {
Some(bound) if a.as_ref() >= bound => Felt252::ONE,
_ => Felt252::ZERO,
};
insert_value_into_ap(vm, value)
insert_value_into_ap(vm, Felt252::from(a.as_ref() >= range_check_bound))
}

//Implements hint: memory[ap] = 0 if 0 <= ((-ids.a - 1) % PRIME) < range_check_builtin.bound else 1
Expand All @@ -62,15 +58,9 @@ pub fn is_nn_out_of_range(
) -> Result<(), HintError> {
let a = get_integer_from_var_name("a", vm, ids_data, ap_tracking)?;
let a = a.as_ref();
let range_check_builtin = vm.get_range_check_builtin()?;
let range_check_bound = vm.get_range_check_builtin()?.bound();
//Main logic (assert a is not negative and within the expected range)
//let value = if (-a - 1usize).mod_floor(vm.get_prime()) < range_check_builtin._bound {
let value = match &range_check_builtin._bound {
Some(bound) if Felt252::ZERO - (a + 1u64) < *bound => Felt252::ZERO,
None => Felt252::ZERO,
_ => Felt252::ONE,
};
insert_value_into_ap(vm, value)
insert_value_into_ap(vm, Felt252::from(-(a + 1) >= *range_check_bound))
}
/* Implements hint:from starkware.cairo.common.math_utils import assert_integer
%{
Expand Down Expand Up @@ -178,8 +168,8 @@ pub fn assert_le_felt_v_0_8(
if a > b {
return Err(HintError::NonLeFelt252(Box::new((*a, *b))));
}
let bound = vm.get_range_check_builtin()?._bound.unwrap_or_default();
let small_inputs = Felt252::from((a < &bound && b - a < bound) as u8);
let bound = vm.get_range_check_builtin()?.bound();
let small_inputs = Felt252::from((a < bound && b - a < *bound) as u8);
insert_value_from_var_name("small_inputs", small_inputs, vm, ids_data, ap_tracking)
}

Expand Down Expand Up @@ -292,9 +282,10 @@ pub fn assert_nn(
let range_check_builtin = vm.get_range_check_builtin()?;
// assert 0 <= ids.a % PRIME < range_check_builtin.bound
// as prime > 0, a % prime will always be > 0
match &range_check_builtin._bound {
Some(bound) if a.as_ref() >= bound => Err(HintError::AssertNNValueOutOfRange(Box::new(a))),
_ => Ok(()),
if a.as_ref() >= range_check_builtin.bound() {
Err(HintError::AssertNNValueOutOfRange(Box::new(a)))
} else {
Ok(())
}
}

Expand Down Expand Up @@ -372,12 +363,9 @@ pub fn is_positive(
// Avoid using abs so we don't allocate a new BigInt
let (sign, abs_value) = value_as_int.into_parts();
//Main logic (assert a is positive)
match &range_check_builtin._bound {
Some(bound) if abs_value > bound.to_biguint() => {
return Err(HintError::ValueOutsideValidRange(Box::new(value)))
}
_ => {}
};
if abs_value >= range_check_builtin.bound().to_biguint() {
return Err(HintError::ValueOutsideValidRange(Box::new(value)));
}

let result = Felt252::from((sign == Sign::Plus) as u8);
insert_value_from_var_name("is_positive", result, vm, ids_data, ap_tracking)
Expand Down Expand Up @@ -460,7 +448,7 @@ pub fn signed_div_rem(
let bound = get_integer_from_var_name("bound", vm, ids_data, ap_tracking)?;
let builtin = vm.get_range_check_builtin()?;

let builtin_bound = &builtin._bound.unwrap_or(Felt252::MAX);
let builtin_bound = builtin.bound();
if div.is_zero() || div.as_ref() > &div_prime_by_bound(*builtin_bound)? {
return Err(HintError::OutOfValidRange(Box::new((div, *builtin_bound))));
}
Expand Down Expand Up @@ -511,22 +499,11 @@ pub fn unsigned_div_rem(
) -> Result<(), HintError> {
let div = get_integer_from_var_name("div", vm, ids_data, ap_tracking)?;
let value = get_integer_from_var_name("value", vm, ids_data, ap_tracking)?;
let builtin = vm.get_range_check_builtin()?;
let builtin_bound = vm.get_range_check_builtin()?.bound();

// Main logic
match &builtin._bound {
Some(builtin_bound)
if div.is_zero() || div.as_ref() > &div_prime_by_bound(*builtin_bound)? =>
{
return Err(HintError::OutOfValidRange(Box::new((div, *builtin_bound))));
}
None if div.is_zero() => {
return Err(HintError::OutOfValidRange(Box::new((
div,
Felt252::ZERO - Felt252::ONE,
))));
}
_ => {}
if div.is_zero() || div.as_ref() > &div_prime_by_bound(*builtin_bound)? {
return Err(HintError::OutOfValidRange(Box::new((div, *builtin_bound))));
}

let (q, r) = value.div_rem(&(div).try_into().map_err(|_| MathError::DividedByZero)?);
Expand Down Expand Up @@ -1807,17 +1784,17 @@ mod tests {
//Initialize fp
vm.run_context.fp = 6;
//Insert ids into memory
let bound = vm.get_range_check_builtin().unwrap()._bound;
let bound = vm.get_range_check_builtin().unwrap().bound();
vm.segments = segments![((1, 3), (5)), ((1, 4), 10)];
vm.insert_value((1, 5).into(), bound.unwrap()).unwrap();
vm.insert_value((1, 5).into(), bound).unwrap();
//Create ids
let ids_data = ids_data!["r", "biased_q", "range_check_ptr", "div", "value", "bound"];
//Execute the hint
let builtin_bound = felt_str!("340282366920938463463374607431768211456");
assert_matches!(
run_hint!(vm, ids_data, hint_code),
Err(HintError::OutOfValidRange(bx))
if *bx == (bound.unwrap(), builtin_bound.field_div(&Felt252::TWO.try_into().unwrap()))
if *bx == (*bound, builtin_bound.field_div(&Felt252::TWO.try_into().unwrap()))
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,7 @@ pub fn squash_dict(
let ptr_diff = get_integer_from_var_name("ptr_diff", vm, ids_data, ap_tracking)?;
let n_accesses = get_integer_from_var_name("n_accesses", vm, ids_data, ap_tracking)?;
//Get range_check_builtin
let range_check_builtin = vm.get_range_check_builtin()?;
let range_check_bound = range_check_builtin._bound;
let range_check_bound = *vm.get_range_check_builtin()?.bound();
//Main Logic
let ptr_diff = ptr_diff
.to_usize()
Expand Down Expand Up @@ -284,7 +283,7 @@ pub fn squash_dict(
keys.sort();
keys.reverse();
//Are the keys used bigger than the range_check bound.
let big_keys = if keys[0] >= range_check_bound.unwrap() {
let big_keys = if keys[0] >= range_check_bound {
Felt252::ONE
} else {
Felt252::ZERO
Expand Down
3 changes: 3 additions & 0 deletions vm/src/serde/deserialize_program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::{
sync::Arc,
},
utils::CAIRO_PRIME,
vm::runners::builtin_runner::RANGE_CHECK_96_BUILTIN_NAME,
};

use crate::utils::PRIME_STR;
Expand Down Expand Up @@ -56,6 +57,7 @@ pub enum BuiltinName {
ec_op,
poseidon,
segment_arena,
range_check96,
add_mod,
mul_mod,
}
Expand All @@ -72,6 +74,7 @@ impl BuiltinName {
BuiltinName::ec_op => EC_OP_BUILTIN_NAME,
BuiltinName::poseidon => POSEIDON_BUILTIN_NAME,
BuiltinName::segment_arena => SEGMENT_ARENA_BUILTIN_NAME,
BuiltinName::range_check96 => RANGE_CHECK_96_BUILTIN_NAME,
BuiltinName::add_mod => ADD_MOD_BUILTIN_NAME,
BuiltinName::mul_mod => MUL_MOD_BUILTIN_NAME,
}
Expand Down
Loading

0 comments on commit ca3b8ab

Please sign in to comment.