Skip to content

Commit

Permalink
feat: impl invModPUint512 hint (#599)
Browse files Browse the repository at this point in the history
* feat: impl invModPUint512 hint

* fix: code improvements + fix pack func

* fix: inline split fn + fix integration tests

* fix: loop optimization
  • Loading branch information
MartianGreed authored Jul 29, 2024
1 parent 1259324 commit 8dc6682
Show file tree
Hide file tree
Showing 8 changed files with 322 additions and 10 deletions.
113 changes: 113 additions & 0 deletions integration_tests/BenchMarks.txt
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,117 @@
| dict_store_cast_ptr.cairo | 1904 | 240 |
---------------------------------------------------------------------------------------------------------------------------
| reduce_v1.small.cairo | 2145 | 232 |
| reduce_v1.small.cairo | 667 | 101 |
---------------------------------------------------------------------------------------------------------------------------
| set_add.small.cairo | 490 | 100 |
---------------------------------------------------------------------------------------------------------------------------
| uint256_signedNN.small.cairo | 550 | 99 |
---------------------------------------------------------------------------------------------------------------------------
| alloc.cairo | 451 | 216 |
---------------------------------------------------------------------------------------------------------------------------
| div_mod_n.small.cairo | 668 | 102 |
---------------------------------------------------------------------------------------------------------------------------
| ec.small.cairo | 4135 | 142 |
---------------------------------------------------------------------------------------------------------------------------
| keccak.starknet_with_keccak.cairo | 1893 | 109 |
---------------------------------------------------------------------------------------------------------------------------
| fib.cairo | 478 | 100 |
---------------------------------------------------------------------------------------------------------------------------
| if_reloc_equal.cairo | 458 | 99 |
---------------------------------------------------------------------------------------------------------------------------
| sqrt.small.cairo | 649 | 100 |
---------------------------------------------------------------------------------------------------------------------------
| uint256_add.small.cairo | 566 | 99 |
---------------------------------------------------------------------------------------------------------------------------
| memset.cairo | 518 | 100 |
---------------------------------------------------------------------------------------------------------------------------
| signed_div_rem.small.cairo | 561 | 99 |
---------------------------------------------------------------------------------------------------------------------------
| verify_ecdsa_signature.small.cairo | 580 | 100 |
---------------------------------------------------------------------------------------------------------------------------
| keccak_test.starknet_with_keccak.cairo| 1089 | 103 |
---------------------------------------------------------------------------------------------------------------------------
| bitwise_builtin_test.starknet_with_keccak.cairo| 1109 | 102 |
---------------------------------------------------------------------------------------------------------------------------
| cairo_keccak_finalize.starknet_with_keccak.cairo| 6272 | 139 |
---------------------------------------------------------------------------------------------------------------------------
| dict_squash.small.cairo | 622 | 104 |
---------------------------------------------------------------------------------------------------------------------------
| get_point_from_x.small.cairo | 689 | 101 |
---------------------------------------------------------------------------------------------------------------------------
| keccak_add_uint256.starknet_with_keccak.cairo| 1134 | 104 |
---------------------------------------------------------------------------------------------------------------------------
| split_felt.small.cairo | 643 | 102 |
---------------------------------------------------------------------------------------------------------------------------
| is_positive.small.cairo | 567 | 100 |
---------------------------------------------------------------------------------------------------------------------------
| reduce.small.cairo | 664 | 101 |
---------------------------------------------------------------------------------------------------------------------------
| search_sorted_lower.small.cairo | 583 | 102 |
---------------------------------------------------------------------------------------------------------------------------
| verify_zero.small.cairo | 566 | 99 |
---------------------------------------------------------------------------------------------------------------------------
| unsafe_keccak.small.cairo | 528 | 101 |
---------------------------------------------------------------------------------------------------------------------------
| unsafe_keccak_finalize.small.cairo | 488 | 103 |
---------------------------------------------------------------------------------------------------------------------------
| assert_250_bits.small.cairo | 637 | 99 |
---------------------------------------------------------------------------------------------------------------------------
| is_quad_residue.small.cairo | 657 | 119 |
---------------------------------------------------------------------------------------------------------------------------
| split_int.small.cairo | 567 | 101 |
---------------------------------------------------------------------------------------------------------------------------
| uint256_improvements.small.cairo | 652 | 118 |
---------------------------------------------------------------------------------------------------------------------------
| uint256_unsigned_div_rem.small.cairo | 712 | 102 |
---------------------------------------------------------------------------------------------------------------------------
| ecop.starknet_with_keccak.cairo | 1154 | 106 |
---------------------------------------------------------------------------------------------------------------------------
| assert_not_zero.cairo | 449 | 97 |
---------------------------------------------------------------------------------------------------------------------------
| cairo_keccak_finalize_block_size_1000.starknet_with_keccak.cairo| 6228 | 139 |
---------------------------------------------------------------------------------------------------------------------------
| usort.small.cairo | 600 | 101 |
---------------------------------------------------------------------------------------------------------------------------
| verify_zero_v2.small.cairo | 652 | 100 |
---------------------------------------------------------------------------------------------------------------------------
| uint256_sqrt.small.cairo | 755 | 102 |
---------------------------------------------------------------------------------------------------------------------------
| unsigned_div_rem.small.cairo | 645 | 101 |
---------------------------------------------------------------------------------------------------------------------------
| ecdsa_test.starknet_with_keccak.cairo | 1206 | 103 |
---------------------------------------------------------------------------------------------------------------------------
| assert_not_equal.cairo | 468 | 98 |
---------------------------------------------------------------------------------------------------------------------------
| import_secp256R1P.small.cairo | 469 | 100 |
---------------------------------------------------------------------------------------------------------------------------
| pow.small.cairo | 559 | 101 |
---------------------------------------------------------------------------------------------------------------------------
| pedersen_test.small.cairo | 468 | 98 |
---------------------------------------------------------------------------------------------------------------------------
| poseidon_test.starknet_with_keccak.cairo| 1112 | 103 |
---------------------------------------------------------------------------------------------------------------------------
| blake.starknet_with_keccak.cairo | 44100 | 371 |
---------------------------------------------------------------------------------------------------------------------------
| memcpy.cairo | 461 | 99 |
---------------------------------------------------------------------------------------------------------------------------
| split64.small.cairo | 644 | 100 |
---------------------------------------------------------------------------------------------------------------------------
| simple.cairo | 444 | 98 |
---------------------------------------------------------------------------------------------------------------------------
| dict.cairo | 502 | 100 |
---------------------------------------------------------------------------------------------------------------------------
| is_zero.small.cairo | 662 | 101 |
---------------------------------------------------------------------------------------------------------------------------
| uint256_mul_div_mod.small.cairo | 746 | 102 |
---------------------------------------------------------------------------------------------------------------------------
| factorial.cairo | 832 | 102 |
---------------------------------------------------------------------------------------------------------------------------
| blake_finalize_v2.starknet_with_keccak.cairo| 3407 | 121 |
---------------------------------------------------------------------------------------------------------------------------
| cmp.small.cairo | 733 | 102 |
---------------------------------------------------------------------------------------------------------------------------
| find_element.small.cairo | 573 | 100 |
---------------------------------------------------------------------------------------------------------------------------
| hintrefs.cairo | 468 | 99 |
===========================================================================================================================
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// The content of this file has been borrowed from LambdaClass Cairo VM in Rust
// See https://raw.githubusercontent.com/lambdaclass/cairo-vm/db7fff18c9c1312024ebf4119fcdfeba23657b12/cairo_programs/inv_mod_p_uint512.cairo

%builtins range_check

from starkware.cairo.common.uint256 import Uint256

const P_low = 201385395114098847380338600778089168199;
const P_high = 64323764613183177041862057485226039389;

struct Uint512 {
d0: felt,
d1: felt,
d2: felt,
d3: felt,
}

func inv_mod_p_uint512{range_check_ptr}(x: Uint512) -> Uint256 {
alloc_locals;
local x_inverse_mod_p: Uint256;
local p: Uint256 = Uint256(P_low, P_high);
// To whitelist
%{
def pack_512(u, num_bits_shift: int) -> int:
limbs = (u.d0, u.d1, u.d2, u.d3)
return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))
x = pack_512(ids.x, num_bits_shift = 128)
p = ids.p.low + (ids.p.high << 128)
x_inverse_mod_p = pow(x,-1, p)
x_inverse_mod_p_split = (x_inverse_mod_p & ((1 << 128) - 1), x_inverse_mod_p >> 128)
ids.x_inverse_mod_p.low = x_inverse_mod_p_split[0]
ids.x_inverse_mod_p.high = x_inverse_mod_p_split[1]
%}

return x_inverse_mod_p;
}

func main{range_check_ptr: felt}() {
let x = Uint512(101, 2, 15, 61);
let y = inv_mod_p_uint512(x);
assert y = Uint256(80275402838848031859800366538378848249, 5810892639608724280512701676461676039);
return ();
}
1 change: 1 addition & 0 deletions pkg/hintrunner/zero/hintcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ const (
uint256SubCode string = "def split(num: int, num_bits_shift: int = 128, length: int = 2):\n a = []\n for _ in range(length):\n a.append( num & ((1 << num_bits_shift) - 1) )\n num = num >> num_bits_shift\n return tuple(a)\n\ndef pack(z, num_bits_shift: int = 128) -> int:\n limbs = (z.low, z.high)\n return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))\n\na = pack(ids.a)\nb = pack(ids.b)\nres = (a - b)%2**256\nres_split = split(res)\nids.res.low = res_split[0]\nids.res.high = res_split[1]"
uint256UnsignedDivRemExpandedCode string = "a = (ids.a.high << 128) + ids.a.low\ndiv = (ids.div.b23 << 128) + ids.div.b01\nquotient, remainder = divmod(a, div)\n\nids.quotient.low = quotient & ((1 << 128) - 1)\nids.quotient.high = quotient >> 128\nids.remainder.low = remainder & ((1 << 128) - 1)\nids.remainder.high = remainder >> 128"
splitXXCode string = "PRIME = 2**255 - 19\nII = pow(2, (PRIME - 1) // 4, PRIME)\n\nxx = ids.xx.low + (ids.xx.high<<128)\nx = pow(xx, (PRIME + 3) // 8, PRIME)\nif (x * x - xx) % PRIME != 0:\n x = (x * II) % PRIME\nif x % 2 != 0:\n x = PRIME - x\nids.x.low = x & ((1<<128)-1)\nids.x.high = x >> 128"
invModPUint512Code string = "def pack_512(u, num_bits_shift: int) -> int:\n limbs = (u.d0, u.d1, u.d2, u.d3)\n return sum(limb << (num_bits_shift * i) for i, limb in enumerate(limbs))\n\nx = pack_512(ids.x, num_bits_shift = 128)\np = ids.p.low + (ids.p.high << 128)\nx_inverse_mod_p = pow(x,-1, p)\n\nx_inverse_mod_p_split = (x_inverse_mod_p & ((1 << 128) - 1), x_inverse_mod_p >> 128)\n\nids.x_inverse_mod_p.low = x_inverse_mod_p_split[0]\nids.x_inverse_mod_p.high = x_inverse_mod_p_split[1]"

// ------ Usort hints related code ------
usortBodyCode string = "from collections import defaultdict\n\ninput_ptr = ids.input\ninput_len = int(ids.input_len)\nif __usort_max_size is not None:\n assert input_len <= __usort_max_size, (\n f\"usort() can only be used with input_len<={__usort_max_size}. \"\n f\"Got: input_len={input_len}.\"\n )\n\npositions_dict = defaultdict(list)\nfor i in range(input_len):\n val = memory[input_ptr + i]\n positions_dict[val].append(i)\n\noutput = sorted(positions_dict.keys())\nids.output_len = len(output)\nids.output = segments.gen_arg(output)\nids.multiplicities = segments.gen_arg([len(positions_dict[k]) for k in output])"
Expand Down
2 changes: 2 additions & 0 deletions pkg/hintrunner/zero/zerohint.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ func GetHintFromCode(program *zero.ZeroProgram, rawHint zero.Hint) (hinter.Hinte
return createUint256UnsignedDivRemExpandedHinter(resolver)
case splitXXCode:
return createSplitXXHinter(resolver)
case invModPUint512Code:
return createInvModPUint512Hinter(resolver)
// Signature hints
case verifyECDSASignatureCode:
return createVerifyECDSASignatureHinter(resolver)
Expand Down
12 changes: 2 additions & 10 deletions pkg/hintrunner/zero/zerohint_uint256.go
Original file line number Diff line number Diff line change
Expand Up @@ -651,16 +651,8 @@ func newUint256SubHint(a, b, res hinter.ResOperander) hinter.Hinter {
return err
}

pack := func(low, high *fp.Element, numBitsShift int) big.Int {
var lowBig, highBig big.Int
low.BigInt(&lowBig)
high.BigInt(&highBig)

return *new(big.Int).Add(new(big.Int).Lsh(&highBig, uint(numBitsShift)), &lowBig)
}

a := pack(aLow, aHigh, 128)
b := pack(bLow, bHigh, 128)
a := Pack(128, aLow, aHigh)
b := Pack(128, bLow, bHigh)

modulus := new(big.Int).Lsh(big.NewInt(1), 256)
resBig := new(big.Int).Sub(&a, &b)
Expand Down
Loading

0 comments on commit 8dc6682

Please sign in to comment.