Skip to content

Commit

Permalink
feat(hints): add NewHint#53 (#1050)
Browse files Browse the repository at this point in the history
* Add NewHint#53

* Update changelog
  • Loading branch information
MegaRedHand authored Apr 26, 2023
1 parent 33690df commit 2181256
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 19 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,15 @@
%}
```

* Add missing hint on vrf.json lib [#1050](https://github.com/lambdaclass/cairo-rs/pull/1050):

`BuiltinHintProcessor` now supports the following hint:

```python
sum_low = ids.a.low + ids.b.low
ids.carry_low = 1 if sum_low >= ids.SHIFT else 0
```

* Add missing hint on uint256_improvements lib [#1016](https://github.com/lambdaclass/cairo-rs/pull/1016):

`BuiltinHintProcessor` now supports the following hint:
Expand Down
9 changes: 0 additions & 9 deletions cairo_programs/fq.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -155,18 +155,9 @@ namespace fq {
alloc_locals;
local res: Uint256;
local carry_low: felt;
// unused. added to use UINT256_ADD
local carry_high: felt;
// this hint is not implemented:
// %{
// sum_low = ids.a.low + ids.b.low
// ids.carry_low = 1 if sum_low >= ids.SHIFT else 0
// %}
%{
sum_low = ids.a.low + ids.b.low
ids.carry_low = 1 if sum_low >= ids.SHIFT else 0
sum_high = ids.a.high + ids.b.high + ids.carry_low
ids.carry_high = 1 if sum_high >= ids.SHIFT else 0
%}
// changed hint, no carry_high
assert carry_low * carry_low = carry_low;
Expand Down
25 changes: 25 additions & 0 deletions cairo_programs/fq_test.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,30 @@

from cairo_programs.fq import fq, Uint256, Uint512

func test_add{range_check_ptr}() {
let a = Uint256(346, 0);
let b = Uint256(213, 0);

let res = fq.add(a, b);

assert res = Uint256(559, 0);

let a = Uint256(
154693353187447763037373048681595478410, 49972746532502551770198072697358847685
);
let b = Uint256(
103510830969771876705678198448587782120, 321696934602460025966614305804515599536
);

let res = fq.add(a, b);

assert res = Uint256(
258204184157219639743051247130183260530, 371669681134962577736812378501874447221
);

return ();
}

func test_u512_unsigned_div_rem{range_check_ptr}() {
let x = Uint512(26362362, 32523523, 135525, 15521);
let div = Uint256(1, 0);
Expand Down Expand Up @@ -58,6 +82,7 @@ func test_div{range_check_ptr}() {
}

func main{range_check_ptr}() {
test_add();
test_u512_unsigned_div_rem();
test_div();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,12 @@ impl HintProcessor for BuiltinHintProcessor {
hint_code::DICT_SQUASH_UPDATE_PTR => {
dict_squash_update_ptr(vm, exec_scopes, &hint_data.ids_data, &hint_data.ap_tracking)
}
hint_code::UINT256_ADD => uint256_add(vm, &hint_data.ids_data, &hint_data.ap_tracking),
hint_code::UINT256_ADD => {
uint256_add(vm, &hint_data.ids_data, &hint_data.ap_tracking, false)
}
hint_code::UINT256_ADD_LOW => {
uint256_add(vm, &hint_data.ids_data, &hint_data.ap_tracking, true)
}
hint_code::UINT128_ADD => uint128_add(vm, &hint_data.ids_data, &hint_data.ap_tracking),
hint_code::UINT256_SUB => uint256_sub(vm, &hint_data.ids_data, &hint_data.ap_tracking),
hint_code::SPLIT_64 => split_64(vm, &hint_data.ids_data, &hint_data.ap_tracking),
Expand Down
4 changes: 4 additions & 0 deletions src/hint_processor/builtin_hint_processor/hint_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,9 @@ ids.carry_low = 1 if sum_low >= ids.SHIFT else 0
sum_high = ids.a.high + ids.b.high + ids.carry_low
ids.carry_high = 1 if sum_high >= ids.SHIFT else 0"#;

pub const UINT256_ADD_LOW: &str = r#"sum_low = ids.a.low + ids.b.low
ids.carry_low = 1 if sum_low >= ids.SHIFT else 0"#;

pub const UINT128_ADD: &str = r#"res = ids.a + ids.b
ids.carry = 1 if res >= ids.SHIFT else 0"#;

Expand Down Expand Up @@ -1153,6 +1156,7 @@ from starkware.python.math_utils import div_mod, safe_div
a = pack(ids.a, PRIME)
b = pack(ids.b, PRIME)
value = res = a - b"#;

pub const EC_RECOVER_PRODUCT_MOD: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import pack
from starkware.python.math_utils import div_mod, safe_div
Expand Down
48 changes: 40 additions & 8 deletions src/hint_processor/builtin_hint_processor/uint256_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,38 +100,48 @@ impl<'a> From<Felt252> for Uint256<'a> {
}

/*
Implements hint:
Implements hints:
%{
sum_low = ids.a.low + ids.b.low
ids.carry_low = 1 if sum_low >= ids.SHIFT else 0
sum_high = ids.a.high + ids.b.high + ids.carry_low
ids.carry_high = 1 if sum_high >= ids.SHIFT else 0
%}
%{
sum_low = ids.a.low + ids.b.low
ids.carry_low = 1 if sum_low >= ids.SHIFT else 0
%}
*/
pub fn uint256_add(
vm: &mut VirtualMachine,
ids_data: &HashMap<String, HintReference>,
ap_tracking: &ApTracking,
low_only: bool,
) -> Result<(), HintError> {
let shift = Felt252::new(1_u32) << 128_u32;

let a = Uint256::from_var_name("a", vm, ids_data, ap_tracking)?;
let b = Uint256::from_var_name("b", vm, ids_data, ap_tracking)?;
let a_low = a.low.as_ref();
let a_high = a.high.as_ref();
let b_low = b.low.as_ref();
let b_high = b.high.as_ref();

// Main logic
// sum_low = ids.a.low + ids.b.low
// ids.carry_low = 1 if sum_low >= ids.SHIFT else 0
// sum_high = ids.a.high + ids.b.high + ids.carry_low
// ids.carry_high = 1 if sum_high >= ids.SHIFT else 0

let carry_low = Felt252::from((a_low + b_low >= shift) as u8);
let carry_high = Felt252::from((a_high + b_high + &carry_low >= shift) as u8);

insert_value_from_var_name("carry_high", carry_high, vm, ids_data, ap_tracking)?;
if !low_only {
let a_high = a.high.as_ref();
let b_high = b.high.as_ref();

// Main logic
// sum_high = ids.a.high + ids.b.high + ids.carry_low
// ids.carry_high = 1 if sum_high >= ids.SHIFT else 0
let carry_high = Felt252::from((a_high + b_high + &carry_low >= shift) as u8);

insert_value_from_var_name("carry_high", carry_high, vm, ids_data, ap_tracking)?;
}

insert_value_from_var_name("carry_low", carry_low, vm, ids_data, ap_tracking)
}

Expand Down Expand Up @@ -508,6 +518,28 @@ mod tests {
check_memory![vm.segments.memory, ((1, 12), 0), ((1, 13), 1)];
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn run_uint256_add_low_only_ok() {
let hint_code =
"sum_low = ids.a.low + ids.b.low\nids.carry_low = 1 if sum_low >= ids.SHIFT else 0";
let mut vm = vm_with_range_check!();
//Initialize fp
vm.run_context.fp = 10;
//Create hint_data
let ids_data = non_continuous_ids_data![("a", -6), ("b", -4), ("carry_low", 2)];
vm.segments = segments![
((1, 4), 2),
((1, 5), 3),
((1, 6), 4),
((1, 7), ("340282366920938463463374607431768211455", 10))
];
//Execute the hint
assert_matches!(run_hint!(vm, ids_data, hint_code), Ok(()));
//Check hint memory inserts
check_memory![vm.segments.memory, ((1, 12), 0)];
}

#[test]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn run_uint128_add_ok() {
Expand Down
2 changes: 1 addition & 1 deletion src/tests/cairo_run_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,7 @@ fn assert_le_felt_old() {
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn cairo_run_fq_test() {
let program_data = include_bytes!("../../cairo_programs/fq_test.json");
run_program_simple_with_memory_holes(program_data.as_slice(), 122);
run_program_simple_with_memory_holes(program_data.as_slice(), 120);
}

#[test]
Expand Down

0 comments on commit 2181256

Please sign in to comment.