Skip to content

Commit

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

* Update changelog

* Add test for missing members

* Remove derive

* Refactor insertion of Uint256

* Remove duplicated import
  • Loading branch information
MegaRedHand authored Apr 20, 2023
1 parent 03d57d3 commit f470b0e
Show file tree
Hide file tree
Showing 5 changed files with 285 additions and 39 deletions.
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,30 @@

#### Upcoming Changes

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

`BuiltinHintProcessor` now supports the following hint:

```python
def split(num: int, num_bits_shift: int = 128, length: int = 2):
a = []
for _ in range(length):
a.append( num & ((1 << num_bits_shift) - 1) )
num = num >> num_bits_shift
return tuple(a)

def pack(z, num_bits_shift: int = 128) -> int:
limbs = (z.low, z.high)
return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))

a = pack(ids.a)
b = pack(ids.b)
res = (a - b)%2**256
res_split = split(res)
ids.res.low = res_split[0]
ids.res.high = res_split[1]
```

* Add methor `Program::data_len(&self) -> usize` to get the number of data cells in a given program [#1022](https://github.com/lambdaclass/cairo-rs/pull/1022)

* Add missing hint on uint256_improvements lib [#1013](https://github.com/lambdaclass/cairo-rs/pull/1013):
Expand Down
22 changes: 22 additions & 0 deletions cairo_programs/uint256_improvements.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,30 @@ func test_udiv_expanded{range_check_ptr}() {
return ();
}

func test_uint256_sub{range_check_ptr}() {
let x = Uint256(421, 5135);
let y = Uint256(787, 968);

// Compute x - y
let (res, sign) = uint256_sub(x, y);

assert res = Uint256(340282366920938463463374607431768211090, 4166);
// x - y >= 0
assert sign = 1;

// Compute y - x
let (res, sign) = uint256_sub(y, x);

assert res = Uint256(366, 340282366920938463463374607431768207289);
// y - x < 0
assert sign = 0;

return ();
}

func main{range_check_ptr}() {
test_udiv_expanded();
test_uint256_sub();

return ();
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,9 @@ use crate::{
squash_dict_inner_next_key, squash_dict_inner_skip_loop,
squash_dict_inner_used_accesses_assert,
},
uint256_utils::uint256_expanded_unsigned_div_rem,
uint256_utils::{
split_64, uint256_add, uint256_mul_div_mod, uint256_signed_nn, uint256_sqrt,
uint256_unsigned_div_rem,
split_64, uint256_add, uint256_expanded_unsigned_div_rem, uint256_mul_div_mod,
uint256_signed_nn, uint256_sqrt, uint256_sub, uint256_unsigned_div_rem,
},
uint384::{
add_no_uint384_check, uint384_signed_nn, uint384_split_128, uint384_sqrt,
Expand Down Expand Up @@ -336,6 +335,7 @@ impl HintProcessor for BuiltinHintProcessor {
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_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),
hint_code::UINT256_SQRT => {
uint256_sqrt(vm, &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 @@ -283,6 +283,24 @@ 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_SUB: &str = r#"def split(num: int, num_bits_shift: int = 128, length: int = 2):
a = []
for _ in range(length):
a.append( num & ((1 << num_bits_shift) - 1) )
num = num >> num_bits_shift
return tuple(a)
def pack(z, num_bits_shift: int = 128) -> int:
limbs = (z.low, z.high)
return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))
a = pack(ids.a)
b = pack(ids.b)
res = (a - b)%2**256
res_split = split(res)
ids.res.low = res_split[0]
ids.res.high = res_split[1]"#;

pub const UINT256_SQRT: &str = r#"from starkware.python.math_utils import isqrt
n = (ids.n.high << 128) + ids.n.low
root = isqrt(n)
Expand Down
Loading

1 comment on commit f470b0e

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.30.

Benchmark suite Current: f470b0e Previous: 03d57d3 Ratio
parse program 25401849 ns/iter (± 1278901) 18993010 ns/iter (± 279302) 1.34
build runner 16547983 ns/iter (± 649456) 11163234 ns/iter (± 24499) 1.48

This comment was automatically generated by workflow using github-action-benchmark.

CC: @unbalancedparentheses

Please sign in to comment.