Skip to content

Commit

Permalink
feat: Implement hints on uint384 lib (Part 1) (#960)
Browse files Browse the repository at this point in the history
* Add hint code for UINT348_UNSIGNED_DIV_REM

* Add file for uint348 files

* Add pack & split for uint348

* Move comment

* Implement uint348_unsigned_div_rem hint

* Add integration test

* Add integration test

* Add unit tests

* Add hint on split_128

* Test split_128 hint

* Add add_no_uint384_hint

* Fix hint + add tests

* Add hint code for UINT348_UNSIGNED_DIV_REM_EXPAND

* Msc fixes

* Add integration test

* Reduce Uint384_expand representation to the 3 used limbs

* Add unit test

* Add hint code for UINT384_SQRT

* Add implementation for hint on sqrt

* Integration test

* Add unit tests

* Fix missing directive

* Run cairo-format

* Add changelog entry

* Spelling

* Update src/hint_processor/builtin_hint_processor/uint384.rs

Co-authored-by: Mario Rugiero <[email protected]>

* Update src/hint_processor/builtin_hint_processor/uint384.rs

Co-authored-by: Mario Rugiero <[email protected]>

* Update src/hint_processor/builtin_hint_processor/uint384.rs

Co-authored-by: Mario Rugiero <[email protected]>

* Make hint code more readable

* fix fmt

---------

Co-authored-by: Mario Rugiero <[email protected]>
  • Loading branch information
fmoletta and Oppen authored Apr 14, 2023
1 parent 5d861c9 commit 1a188e7
Show file tree
Hide file tree
Showing 8 changed files with 1,459 additions and 1 deletion.
102 changes: 102 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,108 @@

#### Upcoming Changes

* Implement hints on uint384 lib (Part 1) [#960](https://github.com/lambdaclass/cairo-rs/pull/960)

`BuiltinHintProcessor` now supports the following hints:

```python
def split(num: int, num_bits_shift: int, length: int):
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) -> int:
limbs = (z.d0, z.d1, z.d2)
return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))

a = pack(ids.a, num_bits_shift = 128)
div = pack(ids.div, num_bits_shift = 128)
quotient, remainder = divmod(a, div)

quotient_split = split(quotient, num_bits_shift=128, length=3)
assert len(quotient_split) == 3

ids.quotient.d0 = quotient_split[0]
ids.quotient.d1 = quotient_split[1]
ids.quotient.d2 = quotient_split[2]

remainder_split = split(remainder, num_bits_shift=128, length=3)
ids.remainder.d0 = remainder_split[0]
ids.remainder.d1 = remainder_split[1]
ids.remainder.d2 = remainder_split[2]
```

```python
ids.low = ids.a & ((1<<128) - 1)
ids.high = ids.a >> 128
```

```python
sum_d0 = ids.a.d0 + ids.b.d0
ids.carry_d0 = 1 if sum_d0 >= ids.SHIFT else 0
sum_d1 = ids.a.d1 + ids.b.d1 + ids.carry_d0
ids.carry_d1 = 1 if sum_d1 >= ids.SHIFT else 0
sum_d2 = ids.a.d2 + ids.b.d2 + ids.carry_d1
ids.carry_d2 = 1 if sum_d2 >= ids.SHIFT else 0
```

```python
def split(num: int, num_bits_shift: int, length: int):
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) -> int:
limbs = (z.d0, z.d1, z.d2)
return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))

def pack2(z, num_bits_shift: int) -> int:
limbs = (z.b01, z.b23, z.b45)
return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))

a = pack(ids.a, num_bits_shift = 128)
div = pack2(ids.div, num_bits_shift = 128)
quotient, remainder = divmod(a, div)

quotient_split = split(quotient, num_bits_shift=128, length=3)
assert len(quotient_split) == 3

ids.quotient.d0 = quotient_split[0]
ids.quotient.d1 = quotient_split[1]
ids.quotient.d2 = quotient_split[2]

remainder_split = split(remainder, num_bits_shift=128, length=3)
ids.remainder.d0 = remainder_split[0]
ids.remainder.d1 = remainder_split[1]
ids.remainder.d2 = remainder_split[2]
```

```python
from starkware.python.math_utils import isqrt

def split(num: int, num_bits_shift: int, length: int):
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) -> int:
limbs = (z.d0, z.d1, z.d2)
return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))

a = pack(ids.a, num_bits_shift=128)
root = isqrt(a)
assert 0 <= root < 2 ** 192
root_split = split(root, num_bits_shift=128, length=3)
ids.root.d0 = root_split[0]
ids.root.d1 = root_split[1]
ids.root.d2 = root_split[2]
```
* Implement hint on `uint256_mul_div_mod`[#957](https://github.com/lambdaclass/cairo-rs/pull/957)

`BuiltinHintProcessor` now supports the following hint:
Expand Down
2 changes: 1 addition & 1 deletion cairo_programs/is_quad_residue_test.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@ func main{output_ptr: felt*}() {

check_quad_res(inputs, expected, 0);

return();
return ();
}
Loading

0 comments on commit 1a188e7

Please sign in to comment.