diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index b7b3835..f88dfd8 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -6,37 +6,40 @@ jobs: main: runs-on: ubuntu-latest steps: - - name: Checkout Repository - uses: actions/checkout@v3 - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.9' # Specify the Python version you need - # - name: Cache Python environment - # uses: actions/cache@v3 - # with: - # path: | - # ~/.cache/pip - # venv - # key: ${{ runner.os }}-python-${{ hashFiles('**/requirements.txt') }} - # restore-keys: | - # ${{ runner.os }}-python- - - name: Install Dependencies - run: | - make setup - - - name: Check python formatting - run: source venv/bin/activate && ./tools/make/python_format_check.sh - - name: Check cairo Formatting - run: | - source venv/bin/activate && ./tools/make/cairo_format_check.sh - - name: Compile cairo files - run: source venv/bin/activate && make build - - name: Run Cairo tests - env: - RPC_URL_MAINNET: ${{ secrets.RPC_URL_MAINNET }} - RPC_URL: ${{ secrets.RPC_URL }} - run: source ./tools/make/cairo_tests.sh - - name: Run MPT tests - run: source ./tools/make/fuzzer.sh tests/fuzzing/mpt.cairo --ci + - name: Checkout Repository + uses: actions/checkout@v3 + + - name: Set up python + uses: actions/setup-python@v4 + with: + python-version: "3.9" + + - name: Install Dependencies + run: | + make setup + + - name: Check python formatting + run: source venv/bin/activate && ./tools/make/python_format_check.sh + + - name: Check cairo Formatting + run: | + source venv/bin/activate && ./tools/make/cairo_format_check.sh + + - name: Check rust Formatting + run: | + cargo fmt --check + + - name: Compile cairo files + run: source venv/bin/activate && make build + + - name: Run cairo tests + env: + RPC_URL_MAINNET: ${{ secrets.RPC_URL_MAINNET }} + RPC_URL: ${{ secrets.RPC_URL }} + run: source ./tools/make/cairo_tests.sh + + - name: Run cairo_vm hints tests + run: cargo test --release -- --show-output + + - name: Run mpt tests + run: source ./tools/make/fuzzer.sh tests/fuzzing/mpt.cairo --ci diff --git a/.gitignore b/.gitignore index 9c619db..142eb44 100644 --- a/.gitignore +++ b/.gitignore @@ -30,4 +30,6 @@ src/.DS_Store solidity-verifier/lib/* *.log -!tests/fuzzing/fixtures/*.json \ No newline at end of file +!tests/fuzzing/fixtures/*.json + +target \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..264e348 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1231 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "anstream" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" + +[[package]] +name = "anstyle-parse" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "anyhow" +version = "1.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37bf3594c4c988a53154954629820791dde498571819ae4ca50ca811e060cc95" + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std", + "digest", + "num-bigint", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "bincode" +version = "2.0.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f11ea1a0346b94ef188834a65c068a03aec181c94896d481d7a0a40d85b0ce95" +dependencies = [ + "serde", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cairo-vm" +version = "1.0.1" +source = "git+https://github.com/lambdaclass/cairo-vm?rev=3fb0344ce038b3a68cae897c403d1f561cfe8da7#3fb0344ce038b3a68cae897c403d1f561cfe8da7" +dependencies = [ + "anyhow", + "bincode", + "bitvec", + "clap", + "generic-array", + "hashbrown 0.14.5", + "hex", + "keccak", + "lazy_static", + "nom", + "num-bigint", + "num-integer", + "num-prime", + "num-traits", + "rand", + "rust_decimal", + "serde", + "serde_json", + "sha2", + "sha3", + "starknet-crypto 0.6.2", + "starknet-types-core", + "thiserror-no-std", + "wasm-bindgen", + "zip", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.82", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + +[[package]] +name = "colorchoice" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" + +[[package]] +name = "cpufeatures" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "eth_essentials_cairo_vm_hints" +version = "0.1.0" +dependencies = [ + "bincode", + "cairo-vm", + "clap", + "hex", + "num-bigint", + "num-traits", + "rand", + "sha3", + "starknet-crypto 0.7.2", + "starknet-types-core", + "thiserror", + "tiny-keccak", +] + +[[package]] +name = "flate2" +version = "1.0.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "foldhash" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", + "serde", +] + +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lambdaworks-crypto" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbc2a4da0d9e52ccfe6306801a112e81a8fc0c76aa3e4449fefeda7fef72bb34" +dependencies = [ + "lambdaworks-math", + "serde", + "sha2", + "sha3", +] + +[[package]] +name = "lambdaworks-math" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1bd2632acbd9957afc5aeec07ad39f078ae38656654043bf16e046fa2730e23" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] +name = "libc" +version = "0.2.161" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +dependencies = [ + "hashbrown 0.15.0", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", + "rand", + "serde", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-modular" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a5fe11d4135c3bcdf3a95b18b194afa9608a5f6ff034f5d857bc9a27fb0119" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-prime" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e238432a7881ec7164503ccc516c014bf009be7984cde1ba56837862543bdec3" +dependencies = [ + "bitvec", + "either", + "lru", + "num-bigint", + "num-integer", + "num-modular", + "num-traits", + "rand", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "rust_decimal" +version = "1.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555" +dependencies = [ + "arrayvec", + "num-traits", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "serde" +version = "1.0.211" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ac55e59090389fb9f0dd9e0f3c09615afed1d19094284d0b200441f13550793" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.211" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54be4f245ce16bc58d57ef2716271d0d4519e0f6defa147f6e081005bcb278ff" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.82", +] + +[[package]] +name = "serde_json" +version = "1.0.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "starknet-crypto" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e2c30c01e8eb0fc913c4ee3cf676389fffc1d1182bfe5bb9670e4e72e968064" +dependencies = [ + "crypto-bigint", + "hex", + "hmac", + "num-bigint", + "num-integer", + "num-traits", + "rfc6979", + "sha2", + "starknet-crypto-codegen", + "starknet-curve 0.4.2", + "starknet-ff", + "zeroize", +] + +[[package]] +name = "starknet-crypto" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a5064173a8e8d2675e67744fd07f310de44573924b6b7af225a6bdd8102913" +dependencies = [ + "crypto-bigint", + "hex", + "hmac", + "num-bigint", + "num-integer", + "num-traits", + "rfc6979", + "sha2", + "starknet-curve 0.5.1", + "starknet-types-core", + "zeroize", +] + +[[package]] +name = "starknet-crypto-codegen" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbc159a1934c7be9761c237333a57febe060ace2bc9e3b337a59a37af206d19f" +dependencies = [ + "starknet-curve 0.4.2", + "starknet-ff", + "syn 2.0.82", +] + +[[package]] +name = "starknet-curve" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1c383518bb312751e4be80f53e8644034aa99a0afb29d7ac41b89a997db875b" +dependencies = [ + "starknet-ff", +] + +[[package]] +name = "starknet-curve" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcde6bd74269b8161948190ace6cf069ef20ac6e79cd2ba09b320efa7500b6de" +dependencies = [ + "starknet-types-core", +] + +[[package]] +name = "starknet-ff" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abf1b44ec5b18d87c1ae5f54590ca9d0699ef4dd5b2ffa66fc97f24613ec585" +dependencies = [ + "ark-ff", + "crypto-bigint", + "getrandom", + "hex", +] + +[[package]] +name = "starknet-types-core" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa1b9e01ccb217ab6d475c5cda05dbb22c30029f7bb52b192a010a00d77a3d74" +dependencies = [ + "lambdaworks-crypto", + "lambdaworks-math", + "num-bigint", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83540f837a8afc019423a8edb95b52a8effe46957ee402287f4292fae35be021" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "thiserror" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.82", +] + +[[package]] +name = "thiserror-impl-no-std" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58e6318948b519ba6dc2b442a6d0b904ebfb8d411a3ad3e07843615a72249758" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "thiserror-no-std" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3ad459d94dd517257cc96add8a43190ee620011bb6e6cdc82dafd97dfafafea" +dependencies = [ + "thiserror-impl-no-std", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.82", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.82", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.82", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.82", +] + +[[package]] +name = "zip" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "byteorder", + "crc32fast", + "crossbeam-utils", + "flate2", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..31c4c6f --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,19 @@ +[workspace] +resolver = "2" + +members = ["cairo_vm_hints"] + + +[workspace.dependencies] +bincode = { version = "2.0.0-rc.3", default-features = false, features = ["serde"] } +cairo-vm = { git = "https://github.com/lambdaclass/cairo-vm", rev = "3fb0344ce038b3a68cae897c403d1f561cfe8da7", features = ["extensive_hints", "clap", "std"] } +clap = { version = "4.3.10", features = ["derive"] } +rand = "0.8" +sha3 = "0.10.8" +starknet-types-core = "0.1.7" +thiserror = "1.0.64" +num-bigint = "0.4.6" +num-traits = "0.2.19" +tiny-keccak = { version = "2.0.2", features = ["keccak"] } +hex = "0.4.3" +starknet-crypto = "0.7.2" \ No newline at end of file diff --git a/cairo_vm_hints/.gitignore b/cairo_vm_hints/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/cairo_vm_hints/.gitignore @@ -0,0 +1 @@ +/target diff --git a/cairo_vm_hints/Cargo.lock b/cairo_vm_hints/Cargo.lock new file mode 100644 index 0000000..9553922 --- /dev/null +++ b/cairo_vm_hints/Cargo.lock @@ -0,0 +1,1230 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "anstream" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" + +[[package]] +name = "anstyle-parse" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "anyhow" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std", + "digest", + "num-bigint", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "bincode" +version = "2.0.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f11ea1a0346b94ef188834a65c068a03aec181c94896d481d7a0a40d85b0ce95" +dependencies = [ + "serde", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cairo-vm" +version = "1.0.1" +source = "git+https://github.com/lambdaclass/cairo-vm?rev=3fb0344ce038b3a68cae897c403d1f561cfe8da7#3fb0344ce038b3a68cae897c403d1f561cfe8da7" +dependencies = [ + "anyhow", + "bincode", + "bitvec", + "clap", + "generic-array", + "hashbrown 0.14.5", + "hex", + "keccak", + "lazy_static", + "nom", + "num-bigint", + "num-integer", + "num-prime", + "num-traits", + "rand", + "rust_decimal", + "serde", + "serde_json", + "sha2", + "sha3", + "starknet-crypto 0.6.2", + "starknet-types-core", + "thiserror-no-std", + "wasm-bindgen", + "zip", +] + +[[package]] +name = "cairo_vm_hints" +version = "0.1.0" +dependencies = [ + "bincode", + "cairo-vm", + "clap", + "hex", + "num-bigint", + "num-traits", + "rand", + "starknet-crypto 0.7.2", + "starknet-types-core", + "thiserror", + "tiny-keccak", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + +[[package]] +name = "colorchoice" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" + +[[package]] +name = "cpufeatures" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "flate2" +version = "1.0.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "foldhash" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", + "serde", +] + +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lambdaworks-crypto" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbc2a4da0d9e52ccfe6306801a112e81a8fc0c76aa3e4449fefeda7fef72bb34" +dependencies = [ + "lambdaworks-math", + "serde", + "sha2", + "sha3", +] + +[[package]] +name = "lambdaworks-math" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1bd2632acbd9957afc5aeec07ad39f078ae38656654043bf16e046fa2730e23" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] +name = "libc" +version = "0.2.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +dependencies = [ + "hashbrown 0.15.0", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", + "rand", + "serde", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-modular" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a5fe11d4135c3bcdf3a95b18b194afa9608a5f6ff034f5d857bc9a27fb0119" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-prime" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e238432a7881ec7164503ccc516c014bf009be7984cde1ba56837862543bdec3" +dependencies = [ + "bitvec", + "either", + "lru", + "num-bigint", + "num-integer", + "num-modular", + "num-traits", + "rand", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "rust_decimal" +version = "1.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555" +dependencies = [ + "arrayvec", + "num-traits", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "serde" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "serde_json" +version = "1.0.128" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "starknet-crypto" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e2c30c01e8eb0fc913c4ee3cf676389fffc1d1182bfe5bb9670e4e72e968064" +dependencies = [ + "crypto-bigint", + "hex", + "hmac", + "num-bigint", + "num-integer", + "num-traits", + "rfc6979", + "sha2", + "starknet-crypto-codegen", + "starknet-curve 0.4.2", + "starknet-ff", + "zeroize", +] + +[[package]] +name = "starknet-crypto" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a5064173a8e8d2675e67744fd07f310de44573924b6b7af225a6bdd8102913" +dependencies = [ + "crypto-bigint", + "hex", + "hmac", + "num-bigint", + "num-integer", + "num-traits", + "rfc6979", + "sha2", + "starknet-curve 0.5.1", + "starknet-types-core", + "zeroize", +] + +[[package]] +name = "starknet-crypto-codegen" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbc159a1934c7be9761c237333a57febe060ace2bc9e3b337a59a37af206d19f" +dependencies = [ + "starknet-curve 0.4.2", + "starknet-ff", + "syn 2.0.79", +] + +[[package]] +name = "starknet-curve" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1c383518bb312751e4be80f53e8644034aa99a0afb29d7ac41b89a997db875b" +dependencies = [ + "starknet-ff", +] + +[[package]] +name = "starknet-curve" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcde6bd74269b8161948190ace6cf069ef20ac6e79cd2ba09b320efa7500b6de" +dependencies = [ + "starknet-types-core", +] + +[[package]] +name = "starknet-ff" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abf1b44ec5b18d87c1ae5f54590ca9d0699ef4dd5b2ffa66fc97f24613ec585" +dependencies = [ + "ark-ff", + "crypto-bigint", + "getrandom", + "hex", +] + +[[package]] +name = "starknet-types-core" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa1b9e01ccb217ab6d475c5cda05dbb22c30029f7bb52b192a010a00d77a3d74" +dependencies = [ + "lambdaworks-crypto", + "lambdaworks-math", + "num-bigint", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "thiserror" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "thiserror-impl-no-std" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58e6318948b519ba6dc2b442a6d0b904ebfb8d411a3ad3e07843615a72249758" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "thiserror-no-std" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3ad459d94dd517257cc96add8a43190ee620011bb6e6cdc82dafd97dfafafea" +dependencies = [ + "thiserror-impl-no-std", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.79", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "zip" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "byteorder", + "crc32fast", + "crossbeam-utils", + "flate2", +] diff --git a/cairo_vm_hints/Cargo.toml b/cairo_vm_hints/Cargo.toml new file mode 100644 index 0000000..680bf79 --- /dev/null +++ b/cairo_vm_hints/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "eth_essentials_cairo_vm_hints" +version = "0.1.0" +edition = "2021" + +[dependencies] +bincode.workspace = true +cairo-vm.workspace = true +clap.workspace = true +rand.workspace = true +sha3.workspace = true +starknet-types-core.workspace = true +thiserror.workspace = true +num-bigint.workspace = true +num-traits.workspace = true +tiny-keccak.workspace = true +hex.workspace = true +starknet-crypto.workspace = true diff --git a/cairo_vm_hints/TODO.txt b/cairo_vm_hints/TODO.txt new file mode 100644 index 0000000..a0376c1 --- /dev/null +++ b/cairo_vm_hints/TODO.txt @@ -0,0 +1,88 @@ +TODO + +lib/block_header.cairo:36 +lib/block_header.cairo:87 +lib/mmr.cairo:282 +lib/mpt:172 +lib/mpt:214 +lib/mpt:256 +lib/mpt:673 +lib/rlp_little.cairo:50 +lib/rlp_little.cairo:103 +lib/rlp_little.cairo:107 +lib/rlp_little.cairo:116 +lib/rlp_little.cairo:130 +lib/rlp_little.cairo:135 +lib/rlp_little.cairo:395 +lib/rlp_little.cairo:416 +lib/rlp_little.cairo:424 +lib/rlp_little.cairo:444 +lib/rlp_little.cairo:459 +lib/rlp_little.cairo:564 +lib/rlp_little.cairo:604 +lib/rlp_little.cairo:610 +lib/rlp_little.cairo:638 +lib/utils:cairo:29 +lib/utils:cairo:191 +lib/utils:cairo:238 +lib/utils:cairo:386 +lib/utils:cairo:392 +lib/utils:cairo:411 +lib/utils:cairo:428 +lib/utils:cairo:434 +lib/utils:cairo:475 +lib/utils:cairo:502 +lib/utils:cairo:532 +lib/utils:cairo:565 +lib/utils:cairo:601 +lib/utils:cairo:640 +tests/cairo_programs/bit_length.cairo:7 +tests/cairo_programs/dw_hack_test.cairo:27 +tests/cairo_programs/dw_hack_test.cairo:38 +tests/cairo_programs/dw_hack_test.cairo:58 +tests/cairo_programs/dw_hack_test.cairo:69 +tests/cairo_programs/dw_hack_test.cairo:89 +tests/cairo_programs/dw_hack_test.cairo:100 +tests/cairo_programs/encode_packed_256_256_test.cairo:19 +tests/cairo_programs/extract_block_number_test.cairo:12 +tests/cairo_programs/extract_block_number_test.cairo:47 +tests/cairo_programs/extract_bytes_test.cairo:15 +tests/cairo_programs/extract_bytes_test.cairo:26 +tests/cairo_programs/extract_bytes_test.cairo:76 +tests/cairo_programs/extract_bytes_test.cairo:98 +tests/cairo_programs/extract_bytes_test.cairo:193 +tests/cairo_programs/extract_bytes_test.cairo:210 +tests/cairo_programs/extract_state_root_test.cairo:13 +tests/cairo_programs/extract_state_root_test.cairo:48 +tests/cairo_programs/height_test.cairo:24 +tests/cairo_programs/mpt_prove_EOA_test.cairo:26 +tests/cairo_programs/mpt_prove_EOA_test.cairo:142 +tests/cairo_programs/peaks_test.cairo:32 +tests/cairo_programs/peaks_test.cairo:98 +tests/cairo_programs/peaks_test.cairo:143 +tests/cairo_programs/reverse_uint256.cairo:20 +tests/cairo_programs/reverse_uint256.cairo:65 +tests/cairo_programs/reverse_uint256.cairo:75 +tests/cairo_programs/reverse_uint256.cairo:86 +tests/cairo_programs/reverse_uint256.cairo:93 +tests/fuzzing/mpt.cairo:18 +tests/fuzzing/mpt.cairo:50 + +DONE + +lib/mmr.cairo:102 +lib/mmr.cairo:144 +lib/mmr.cairo:237 +lib/utils:cairo:305 +lib/utils:cairo:333 +tests/cairo_programs/construct_mmr_test.cairo:59 +tests/cairo_programs/is_valid_mmr_size.cairo:10 +tests/cairo_programs/is_valid_mmr_size.cairo:29 +tests/cairo_programs/is_valid_mmr_size.cairo:48 +tests/cairo_programs/is_valid_mmr_size.cairo:57 +tests/cairo_programs/is_valid_mmr_size.cairo:72 + +DONE TEST + +tests/cairo_programs/is_valid_mmr_size.cairo +tests/cairo_programs/bit_length.cairo \ No newline at end of file diff --git a/cairo_vm_hints/src/hint_processor/mod.rs b/cairo_vm_hints/src/hint_processor/mod.rs new file mode 100644 index 0000000..5bd01bf --- /dev/null +++ b/cairo_vm_hints/src/hint_processor/mod.rs @@ -0,0 +1,109 @@ +use crate::hints; +use cairo_vm::{ + hint_processor::{ + builtin_hint_processor::builtin_hint_processor_definition::{ + BuiltinHintProcessor, HintFunc, HintProcessorData, + }, + hint_processor_definition::HintExtension, + hint_processor_definition::HintProcessorLogic, + }, + types::exec_scope::ExecutionScopes, + vm::{ + errors::hint_errors::HintError, runners::cairo_runner::ResourceTracker, + vm_core::VirtualMachine, + }, + Felt252, +}; +use starknet_types_core::felt::Felt; +use std::collections::HashMap; +use std::{any::Any, rc::Rc}; + +#[derive(Default)] +pub struct CustomHintProcessor; + +impl CustomHintProcessor { + pub fn new() -> Self { + Self {} + } +} + +impl HintProcessorLogic for CustomHintProcessor { + fn execute_hint( + &mut self, + vm: &mut VirtualMachine, + exec_scopes: &mut ExecutionScopes, + hint_data: &Box, + constants: &HashMap, + ) -> Result<(), HintError> { + let hint_data = hint_data + .downcast_ref::() + .ok_or(HintError::WrongHintData)?; + + hints::run_hint(vm, exec_scopes, hint_data, constants) + } +} + +impl ResourceTracker for CustomHintProcessor {} + +pub struct ExtendedHintProcessor { + custom_hint_processor: CustomHintProcessor, + builtin_hint_processor: BuiltinHintProcessor, +} + +impl Default for ExtendedHintProcessor { + fn default() -> Self { + Self::new() + } +} + +impl ExtendedHintProcessor { + pub fn new() -> Self { + Self { + custom_hint_processor: CustomHintProcessor {}, + builtin_hint_processor: BuiltinHintProcessor::new_empty(), + } + } + + pub fn add_hint(&mut self, hint_code: String, hint_func: Rc) { + self.builtin_hint_processor + .extra_hints + .insert(hint_code, hint_func); + } +} + +impl HintProcessorLogic for ExtendedHintProcessor { + fn execute_hint( + &mut self, + _vm: &mut VirtualMachine, + _exec_scopes: &mut ExecutionScopes, + _hint_data: &Box, + _constants: &HashMap, + ) -> Result<(), HintError> { + unreachable!(); + } + + fn execute_hint_extensive( + &mut self, + vm: &mut VirtualMachine, + exec_scopes: &mut ExecutionScopes, + hint_data: &Box, + constants: &HashMap, + ) -> Result { + match self.custom_hint_processor.execute_hint_extensive( + vm, + exec_scopes, + hint_data, + constants, + ) { + Err(HintError::UnknownHint(_)) => {} + result => { + return result; + } + } + + self.builtin_hint_processor + .execute_hint_extensive(vm, exec_scopes, hint_data, constants) + } +} + +impl ResourceTracker for ExtendedHintProcessor {} diff --git a/cairo_vm_hints/src/hints/lib/bit_length.rs b/cairo_vm_hints/src/hints/lib/bit_length.rs new file mode 100644 index 0000000..5a76ebb --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/bit_length.rs @@ -0,0 +1,43 @@ +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{ + get_integer_from_var_name, insert_value_from_var_name, +}; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::types::relocatable::MaybeRelocatable; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use std::collections::HashMap; + +const HINT_BIT_LENGTH: &str = "ids.bit_length = ids.x.bit_length()"; + +fn hint_bit_length( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let x = get_integer_from_var_name("x", vm, &hint_data.ids_data, &hint_data.ap_tracking)?; + insert_value_from_var_name( + "bit_length", + MaybeRelocatable::Int(x.bits().into()), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + Ok(()) +} + +pub fn run_hint( + vm: &mut VirtualMachine, + exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + constants: &HashMap, +) -> Result<(), HintError> { + match hint_data.code.as_str() { + HINT_BIT_LENGTH => hint_bit_length(vm, exec_scope, hint_data, constants), + _ => Err(HintError::UnknownHint( + hint_data.code.to_string().into_boxed_str(), + )), + } +} diff --git a/cairo_vm_hints/src/hints/lib/block_header/mod.rs b/cairo_vm_hints/src/hints/lib/block_header/mod.rs new file mode 100644 index 0000000..5636111 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/block_header/mod.rs @@ -0,0 +1,46 @@ +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{ + get_integer_from_var_name, insert_value_into_ap, +}; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::types::relocatable::MaybeRelocatable; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use std::cmp::Ordering; +use std::collections::HashMap; + +const HINT_RLP_BIGINT_SIZE: &str = "memory[ap] = 1 if ids.byte <= 127 else 0"; + +const FELT_127: Felt252 = Felt252::from_hex_unchecked("0x7F"); + +fn hint_rlp_bigint_size( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + match get_integer_from_var_name("byte", vm, &hint_data.ids_data, &hint_data.ap_tracking)? + .cmp(&FELT_127) + { + Ordering::Less | Ordering::Equal => { + insert_value_into_ap(vm, MaybeRelocatable::Int(Felt252::ONE))? + } + Ordering::Greater => insert_value_into_ap(vm, MaybeRelocatable::Int(Felt252::ZERO))?, + }; + + Ok(()) +} + +pub fn run_hint( + vm: &mut VirtualMachine, + exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + constants: &HashMap, +) -> Result<(), HintError> { + match hint_data.code.as_str() { + HINT_RLP_BIGINT_SIZE => hint_rlp_bigint_size(vm, exec_scope, hint_data, constants), + _ => Err(HintError::UnknownHint( + hint_data.code.to_string().into_boxed_str(), + )), + } +} diff --git a/cairo_vm_hints/src/hints/lib/mmr/bit_length.rs b/cairo_vm_hints/src/hints/lib/mmr/bit_length.rs new file mode 100644 index 0000000..567dbd0 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/mmr/bit_length.rs @@ -0,0 +1,29 @@ +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{ + get_integer_from_var_name, insert_value_from_var_name, +}; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::types::relocatable::MaybeRelocatable; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use std::collections::HashMap; + +pub const MMR_BIT_LENGTH: &str = "ids.bit_length = ids.mmr_len.bit_length()"; + +pub fn mmr_bit_length( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let x = get_integer_from_var_name("mmr_len", vm, &hint_data.ids_data, &hint_data.ap_tracking)?; + insert_value_from_var_name( + "bit_length", + MaybeRelocatable::Int(x.bits().into()), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + Ok(()) +} diff --git a/cairo_vm_hints/src/hints/lib/mmr/left_child.rs b/cairo_vm_hints/src/hints/lib/mmr/left_child.rs new file mode 100644 index 0000000..833f9d2 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/mmr/left_child.rs @@ -0,0 +1,43 @@ +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{ + get_integer_from_var_name, insert_value_from_var_name, +}; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::types::relocatable::MaybeRelocatable; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use starknet_types_core::felt::Felt; +use std::collections::HashMap; + +pub const MMR_LEFT_CHILD: &str = "ids.in_mmr = 1 if ids.left_child <= ids.mmr_len else 0"; + +pub fn mmr_left_child( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let left_child = get_integer_from_var_name( + "left_child", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + let mmr_len = + get_integer_from_var_name("mmr_len", vm, &hint_data.ids_data, &hint_data.ap_tracking)?; + + let in_mmr = if left_child <= mmr_len { + Felt::ONE + } else { + Felt::ZERO + }; + insert_value_from_var_name( + "in_mmr", + MaybeRelocatable::Int(in_mmr), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + Ok(()) +} diff --git a/cairo_vm_hints/src/hints/lib/mmr/mod.rs b/cairo_vm_hints/src/hints/lib/mmr/mod.rs new file mode 100644 index 0000000..5a82dc2 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/mmr/mod.rs @@ -0,0 +1,33 @@ +use cairo_vm::{ + hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData, + types::exec_scope::ExecutionScopes, + vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, + Felt252, +}; +use std::collections::HashMap; + +mod bit_length; +mod left_child; +mod peak_values; + +pub fn run_hint( + vm: &mut VirtualMachine, + exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + constants: &HashMap, +) -> Result<(), HintError> { + match hint_data.code.as_str() { + bit_length::MMR_BIT_LENGTH => { + bit_length::mmr_bit_length(vm, exec_scope, hint_data, constants) + } + left_child::MMR_LEFT_CHILD => { + left_child::mmr_left_child(vm, exec_scope, hint_data, constants) + } + peak_values::HINT_IS_POSITION_IN_MMR_ARRAY => { + peak_values::hint_is_position_in_mmr_array(vm, exec_scope, hint_data, constants) + } + _ => Err(HintError::UnknownHint( + hint_data.code.to_string().into_boxed_str(), + )), + } +} diff --git a/cairo_vm_hints/src/hints/lib/mmr/peak_values.rs b/cairo_vm_hints/src/hints/lib/mmr/peak_values.rs new file mode 100644 index 0000000..424b19f --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/mmr/peak_values.rs @@ -0,0 +1,44 @@ +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{ + get_integer_from_var_name, insert_value_from_var_name, +}; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::types::relocatable::MaybeRelocatable; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use starknet_types_core::felt::Felt; +use std::collections::HashMap; + +pub const HINT_IS_POSITION_IN_MMR_ARRAY: &str = + "ids.is_position_in_mmr_array= 1 if ids.position > ids.mmr_offset else 0"; + +pub fn hint_is_position_in_mmr_array( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let position = + get_integer_from_var_name("position", vm, &hint_data.ids_data, &hint_data.ap_tracking)?; + let mmr_offset = get_integer_from_var_name( + "mmr_offset", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + let is_position_in_mmr_array = if position > mmr_offset { + Felt::ONE + } else { + Felt::ZERO + }; + insert_value_from_var_name( + "is_position_in_mmr_array", + MaybeRelocatable::Int(is_position_in_mmr_array), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + Ok(()) +} diff --git a/cairo_vm_hints/src/hints/lib/mod.rs b/cairo_vm_hints/src/hints/lib/mod.rs new file mode 100644 index 0000000..786e25e --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/mod.rs @@ -0,0 +1,40 @@ +use cairo_vm::{ + hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData, + types::exec_scope::ExecutionScopes, + vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, + Felt252, +}; +use std::collections::HashMap; + +mod bit_length; +mod block_header; +mod mmr; +mod mpt; +mod rlp_little; +mod utils; + +pub fn run_hint( + vm: &mut VirtualMachine, + exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + constants: &HashMap, +) -> Result<(), HintError> { + let hints = [ + bit_length::run_hint, + block_header::run_hint, + mmr::run_hint, + mpt::run_hint, + rlp_little::run_hint, + utils::run_hint, + ]; + + for hint in hints.iter() { + let res = hint(vm, exec_scope, hint_data, constants); + if !matches!(res, Err(HintError::UnknownHint(_))) { + return res; + } + } + Err(HintError::UnknownHint( + hint_data.code.to_string().into_boxed_str(), + )) +} diff --git a/cairo_vm_hints/src/hints/lib/mpt/mod.rs b/cairo_vm_hints/src/hints/lib/mpt/mod.rs new file mode 100644 index 0000000..19693dc --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/mpt/mod.rs @@ -0,0 +1,221 @@ +const FELT_0: Felt252 = Felt252::ZERO; +const FELT_127: Felt252 = Felt252::from_hex_unchecked("0x7f"); +const FELT_128: Felt252 = Felt252::from_hex_unchecked("0x80"); +const FELT_183: Felt252 = Felt252::from_hex_unchecked("0xB7"); +const FELT_184: Felt252 = Felt252::from_hex_unchecked("0xB8"); +const FELT_191: Felt252 = Felt252::from_hex_unchecked("0xBF"); +const FELT_192: Felt252 = Felt252::from_hex_unchecked("0xC0"); +const FELT_247: Felt252 = Felt252::from_hex_unchecked("0xF7"); +const FELT_248: Felt252 = Felt252::from_hex_unchecked("0xF8"); +const FELT_255: Felt252 = Felt252::from_hex_unchecked("0xFF"); + +/// Check if the value indicates a single byte (0x00 to 0x7f). +fn is_single_byte(value: Felt252) -> bool { + FELT_0 <= value && value <= FELT_127 +} + +/// Check if the value indicates a short string (0x80 to 0xb7). +fn is_short_string(value: Felt252) -> bool { + FELT_128 <= value && value <= FELT_183 +} + +/// Check if the value indicates a long string (0xb8 to 0xbf). +fn is_long_string(value: Felt252) -> bool { + FELT_184 <= value && value <= FELT_191 +} + +/// Check if the value indicates a short list (0xc0 to 0xf7). +fn is_short_list(value: Felt252) -> bool { + FELT_192 <= value && value <= FELT_247 +} + +/// Check if the value indicates a long list (0xf8 to 0xff). +fn is_long_list(value: Felt252) -> bool { + FELT_248 <= value && value <= FELT_255 +} + +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{ + get_integer_from_var_name, insert_value_from_var_name, +}; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::types::relocatable::MaybeRelocatable; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use std::collections::HashMap; + +const HINT_LONG_SHORT_LIST: &str = "from tools.py.hints import is_short_list, is_long_list\nif is_short_list(ids.list_prefix):\n ids.long_short_list = 0\nelif is_long_list(ids.list_prefix):\n ids.long_short_list = 1\nelse:\n raise ValueError(f\"Invalid list prefix: {hex(ids.list_prefix)}. Not a recognized list type.\")"; + +fn hint_long_short_list( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let list_prefix = get_integer_from_var_name( + "list_prefix", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + match list_prefix { + value if is_short_list(value) => insert_value_from_var_name( + "long_short_list", + MaybeRelocatable::Int(Felt252::ZERO), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ), + value if is_long_list(value) => insert_value_from_var_name( + "long_short_list", + MaybeRelocatable::Int(Felt252::ONE), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ), + value => Err(HintError::InvalidValue(Box::new(( + "Invalid list prefix. Not a recognized list type.", + value, + Felt252::ZERO, + )))), + } +} + +const HINT_FIRST_ITEM_TYPE: &str = "from tools.py.hints import is_single_byte, is_short_string\nif is_single_byte(ids.first_item_prefix):\n ids.first_item_type = 0\nelif is_short_string(ids.first_item_prefix):\n ids.first_item_type = 1\nelse:\n raise ValueError(f\"Unsupported first item prefix: {hex(ids.first_item_prefix)}.\")"; + +fn hint_first_item_type( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let first_item_prefix = get_integer_from_var_name( + "first_item_prefix", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + match first_item_prefix { + value if is_single_byte(value) => insert_value_from_var_name( + "first_item_type", + MaybeRelocatable::Int(Felt252::ZERO), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ), + value if is_short_string(value) => insert_value_from_var_name( + "first_item_type", + MaybeRelocatable::Int(Felt252::ONE), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ), + value => Err(HintError::InvalidValue(Box::new(( + "Unsupported first item prefix", + value, + Felt252::ZERO, + )))), + } +} + +const HINT_SECOND_ITEM_TYPE: &str = "from tools.py.hints import is_single_byte, is_short_string, is_long_string\nif is_single_byte(ids.second_item_prefix):\n ids.second_item_type = 0\nelif is_short_string(ids.second_item_prefix):\n ids.second_item_type = 1\nelif is_long_string(ids.second_item_prefix):\n ids.second_item_type = 2\nelse:\n raise ValueError(f\"Unsupported second item prefix: {hex(ids.second_item_prefix)}.\")"; + +fn hint_second_item_type( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let second_item_prefix = get_integer_from_var_name( + "second_item_prefix", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + match second_item_prefix { + value if is_single_byte(value) => insert_value_from_var_name( + "second_item_type", + MaybeRelocatable::Int(Felt252::ZERO), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ), + value if is_short_string(value) => insert_value_from_var_name( + "second_item_type", + MaybeRelocatable::Int(Felt252::ONE), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ), + value if is_long_string(value) => insert_value_from_var_name( + "second_item_type", + MaybeRelocatable::Int(Felt252::TWO), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ), + value => Err(HintError::InvalidValue(Box::new(( + "Unsupported second item prefix", + value, + Felt252::ZERO, + )))), + } +} + +const HINT_ITEM_TYPE: &str = "from tools.py.hints import is_single_byte, is_short_string\nif is_single_byte(ids.item_prefix):\n ids.item_type = 0\nelif is_short_string(ids.item_prefix):\n ids.item_type = 1\nelse:\n raise ValueError(f\"Unsupported item prefix: {hex(ids.item_prefix)} for a branch node. Should be single byte or short string only.\")"; + +fn hint_item_type( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let item_prefix = get_integer_from_var_name( + "item_prefix", + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + )?; + + match item_prefix { + value if is_single_byte(value) => insert_value_from_var_name( + "item_type", + MaybeRelocatable::Int(Felt252::ZERO), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ), + value if is_short_string(value) => insert_value_from_var_name( + "item_type", + MaybeRelocatable::Int(Felt252::ONE), + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ), + value => Err(HintError::InvalidValue(Box::new(( + "Unsupported item prefix for a branch node. Should be single byte or short string only.", + value, + Felt252::ZERO, + )))), + } +} + +pub fn run_hint( + vm: &mut VirtualMachine, + exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + constants: &HashMap, +) -> Result<(), HintError> { + match hint_data.code.as_str() { + HINT_LONG_SHORT_LIST => hint_long_short_list(vm, exec_scope, hint_data, constants), + HINT_FIRST_ITEM_TYPE => hint_first_item_type(vm, exec_scope, hint_data, constants), + HINT_SECOND_ITEM_TYPE => hint_second_item_type(vm, exec_scope, hint_data, constants), + HINT_ITEM_TYPE => hint_item_type(vm, exec_scope, hint_data, constants), + _ => Err(HintError::UnknownHint( + hint_data.code.to_string().into_boxed_str(), + )), + } +} diff --git a/cairo_vm_hints/src/hints/lib/rlp_little/assert.rs b/cairo_vm_hints/src/hints/lib/rlp_little/assert.rs new file mode 100644 index 0000000..18ad553 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/rlp_little/assert.rs @@ -0,0 +1,50 @@ +use crate::utils; +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::types::relocatable::MaybeRelocatable; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use std::collections::HashMap; + +pub const HINT_EXPECTED_LEADING_ZEROES: &str = "assert ids.res == expected_leading_zeroes, f\"Expected {expected_leading_zeroes} but got {ids.res}\""; + +pub fn hint_expected_leading_zeroes( + vm: &mut VirtualMachine, + exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let res: Felt252 = utils::get_value("res", vm, hint_data)?; + let expected_leading_zeroes: Felt252 = exec_scope.get("expected_leading_zeroes")?; + + if expected_leading_zeroes.ne(&res) { + Err(HintError::AssertNotEqualFail(Box::new(( + MaybeRelocatable::Int(expected_leading_zeroes), + MaybeRelocatable::Int(res), + )))) + } else { + Ok(()) + } +} + +pub const HINT_EXPECTED_NIBBLE: &str = "assert ids.extracted_nibble_at_pos == expected_nibble, f\"extracted_nibble_at_pos={ids.extracted_nibble_at_pos} expected_nibble={expected_nibble}\""; + +pub fn hint_expected_nibble( + vm: &mut VirtualMachine, + exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let extracted_nibble_at_pos: Felt252 = + utils::get_value("extracted_nibble_at_pos", vm, hint_data)?; + let expected_nibble: Felt252 = exec_scope.get("expected_nibble")?; + + if extracted_nibble_at_pos.ne(&expected_nibble) { + Err(HintError::AssertNotEqualFail(Box::new(( + MaybeRelocatable::Int(extracted_nibble_at_pos), + MaybeRelocatable::Int(expected_nibble), + )))) + } else { + Ok(()) + } +} diff --git a/cairo_vm_hints/src/hints/lib/rlp_little/divmod.rs b/cairo_vm_hints/src/hints/lib/rlp_little/divmod.rs new file mode 100644 index 0000000..55e076b --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/rlp_little/divmod.rs @@ -0,0 +1,36 @@ +use crate::utils; +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::types::relocatable::Relocatable; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use starknet_types_core::felt::NonZeroFelt; +use std::collections::HashMap; + +pub const HINT_POW_CUT: &str = + "ids.q, ids.r = divmod(memory[ids.array + ids.start_word + ids.i], ids.pow_cut)"; + +pub fn hint_pow_cut( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let array: usize = utils::get_value("array", vm, hint_data)? + .try_into() + .unwrap(); + let start_word: usize = utils::get_value("start_word", vm, hint_data)? + .try_into() + .unwrap(); + let i: usize = utils::get_value("i", vm, hint_data)?.try_into().unwrap(); + let pow_cut: Felt252 = utils::get_value("pow_cut", vm, hint_data)?; + + let value: Felt252 = *vm.get_integer(Relocatable { + segment_index: isize::default(), + offset: array + start_word + i, + })?; + + let (q, r) = value.div_rem(&NonZeroFelt::try_from(pow_cut).unwrap()); + utils::write_value("q", q, vm, hint_data)?; + utils::write_value("r", r, vm, hint_data) +} diff --git a/cairo_vm_hints/src/hints/lib/rlp_little/leading_zeros.rs b/cairo_vm_hints/src/hints/lib/rlp_little/leading_zeros.rs new file mode 100644 index 0000000..99c4a21 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/rlp_little/leading_zeros.rs @@ -0,0 +1,75 @@ +use crate::utils; +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use std::collections::HashMap; + +pub const HINT_EXPECTED_LEADING_ZEROES: &str = "from tools.py.utils import parse_int_to_bytes, count_leading_zero_nibbles_from_hex\nreversed_hex = parse_int_to_bytes(ids.x.low + (2 ** 128) * ids.x.high)[::-1].hex()\nexpected_leading_zeroes = count_leading_zero_nibbles_from_hex(reversed_hex[1:] if ids.cut_nibble == 1 else reversed_hex)"; + +pub fn hint_expected_leading_zeroes( + vm: &mut VirtualMachine, + exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let x_low: u128 = utils::get_value("x.low", vm, hint_data)? + .try_into() + .unwrap(); + let x_high: u128 = utils::get_value("x.high", vm, hint_data)? + .try_into() + .unwrap(); + let cut_nibble = utils::get_value("cut_nibble", vm, hint_data)?; + + let reversed_hex = hex::encode([x_low.to_be_bytes(), x_high.to_be_bytes()].concat()) + .bytes() + .rev() + .collect::>(); + + // Calculate expected leading zeroes, optionally skipping the first nibble + let hex_to_check = if cut_nibble == Felt252::ONE { + reversed_hex[1..].to_vec() + } else { + reversed_hex + }; + let expected_leading_zeroes: Felt252 = hex_to_check + .into_iter() + .take_while(|c| *c == b'0') + .count() + .into(); + exec_scope.insert_value("expected_leading_zeroes", expected_leading_zeroes); + + Ok(()) +} + +pub const HINT_EXPECTED_NIBBLE: &str = "key_hex = ids.key_leading_zeroes_nibbles * '0' + hex(ids.key.low + (2 ** 128) * ids.key.high)[2:]\nexpected_nibble = int(key_hex[ids.nibble_index + ids.key_leading_zeroes_nibbles], 16)"; + +pub fn hint_expected_nibble( + vm: &mut VirtualMachine, + exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let key_low: u128 = utils::get_value("key.low", vm, hint_data)? + .try_into() + .unwrap(); + let key_high: u128 = utils::get_value("key.high", vm, hint_data)? + .try_into() + .unwrap(); + let key_leading_zeroes_nibbles: usize = + utils::get_value("key_leading_zeroes_nibbles", vm, hint_data)? + .try_into() + .unwrap(); + let nibble_index: usize = utils::get_value("nibble_index", vm, hint_data)? + .try_into() + .unwrap(); + + let hex = hex::encode([key_low.to_be_bytes(), key_high.to_be_bytes()].concat()); + let nibble_char = format!("{:0width$}{}", "", hex, width = key_leading_zeroes_nibbles) + .chars() + .nth(nibble_index + key_leading_zeroes_nibbles) + .unwrap(); + exec_scope.insert_value("expected_nibble", nibble_char.to_digit(16).unwrap()); + + Ok(()) +} diff --git a/cairo_vm_hints/src/hints/lib/rlp_little/mod.rs b/cairo_vm_hints/src/hints/lib/rlp_little/mod.rs new file mode 100644 index 0000000..7ad2be4 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/rlp_little/mod.rs @@ -0,0 +1,50 @@ +use std::collections::HashMap; + +use cairo_vm::{ + hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData, + types::exec_scope::ExecutionScopes, + vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, + Felt252, +}; + +mod assert; +mod divmod; +mod leading_zeros; +mod nibbles; + +pub fn run_hint( + vm: &mut VirtualMachine, + exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + constants: &HashMap, +) -> Result<(), HintError> { + match hint_data.code.as_str() { + assert::HINT_EXPECTED_LEADING_ZEROES => { + assert::hint_expected_leading_zeroes(vm, exec_scope, hint_data, constants) + } + assert::HINT_EXPECTED_NIBBLE => { + assert::hint_expected_nibble(vm, exec_scope, hint_data, constants) + } + divmod::HINT_POW_CUT => divmod::hint_pow_cut(vm, exec_scope, hint_data, constants), + leading_zeros::HINT_EXPECTED_LEADING_ZEROES => { + leading_zeros::hint_expected_leading_zeroes(vm, exec_scope, hint_data, constants) + } + leading_zeros::HINT_EXPECTED_NIBBLE => { + leading_zeros::hint_expected_nibble(vm, exec_scope, hint_data, constants) + } + nibbles::HINT_IS_ZERO => nibbles::hint_is_zero(vm, exec_scope, hint_data, constants), + nibbles::HINT_NIBBLE_FROM_LOW => { + nibbles::hint_nibble_from_low(vm, exec_scope, hint_data, constants) + } + nibbles::HINT_NEEDS_NEXT_WORD => { + nibbles::hint_needs_next_word(vm, exec_scope, hint_data, constants) + } + nibbles::HINT_NEEDS_NEXT_WORD_ENDING => { + nibbles::hint_needs_next_word_ending(vm, exec_scope, hint_data, constants) + } + nibbles::HINT_WORDS_LOOP => nibbles::hint_words_loop(vm, exec_scope, hint_data, constants), + _ => Err(HintError::UnknownHint( + hint_data.code.to_string().into_boxed_str(), + )), + } +} diff --git a/cairo_vm_hints/src/hints/lib/rlp_little/nibbles.rs b/cairo_vm_hints/src/hints/lib/rlp_little/nibbles.rs new file mode 100644 index 0000000..dbcb08e --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/rlp_little/nibbles.rs @@ -0,0 +1,125 @@ +use crate::utils; +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::insert_value_into_ap; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use std::cmp::Ordering; +use std::collections::HashMap; + +const FELT_31: Felt252 = Felt252::from_hex_unchecked("0x1F"); +const FELT_32: Felt252 = Felt252::from_hex_unchecked("0x20"); +const FELT_63: Felt252 = Felt252::from_hex_unchecked("0x3F"); + +pub const HINT_IS_ZERO: &str = + "ids.is_zero = 1 if ids.nibble_index <= (ids.key_leading_zeroes_nibbles - 1) else 0"; + +pub fn hint_is_zero( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let nibble_index: Felt252 = utils::get_value("nibble_index", vm, hint_data)?; + let key_leading_zeroes_nibbles: Felt252 = + utils::get_value("key_leading_zeroes_nibbles", vm, hint_data)?; + + utils::write_value( + "is_zero", + match nibble_index.cmp(&key_leading_zeroes_nibbles) { + Ordering::Less | Ordering::Equal => Felt252::ONE, + Ordering::Greater => Felt252::ZERO, + }, + vm, + hint_data, + ) +} + +pub const HINT_NIBBLE_FROM_LOW: &str = + "ids.get_nibble_from_low = 1 if (0 <= ids.nibble_index <= 31 and ids.key_nibbles <= 32) or (32 <= ids.nibble_index <= 63 and ids.key_nibbles > 32) else 0"; + +pub fn hint_nibble_from_low( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let nibble_index: Felt252 = utils::get_value("nibble_index", vm, hint_data)?; + let key_nibbles: Felt252 = utils::get_value("key_nibbles", vm, hint_data)?; + + let get_nibble_from_low = + if (Felt252::ZERO <= nibble_index && nibble_index <= FELT_31 && key_nibbles <= FELT_32) + || (FELT_32 <= nibble_index && nibble_index <= FELT_63 && key_nibbles > FELT_32) + { + Felt252::ONE + } else { + Felt252::ZERO + }; + + utils::write_value("get_nibble_from_low", get_nibble_from_low, vm, hint_data) +} + +pub const HINT_NEEDS_NEXT_WORD: &str = + "ids.needs_next_word = 1 if ids.n_bytes > ids.avl_bytes_in_word else 0"; + +pub fn hint_needs_next_word( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let n_bytes: Felt252 = utils::get_value("n_bytes", vm, hint_data)?; + let avl_bytes_in_word: Felt252 = utils::get_value("avl_bytes_in_word", vm, hint_data)?; + + let needs_next_word = if n_bytes > avl_bytes_in_word { + Felt252::ONE + } else { + Felt252::ZERO + }; + + utils::write_value("needs_next_word", needs_next_word, vm, hint_data) +} + +pub const HINT_NEEDS_NEXT_WORD_ENDING: &str = + "ids.needs_next_word = 1 if ids.n_ending_bytes > ids.avl_bytes_in_word else 0"; + +pub fn hint_needs_next_word_ending( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let n_ending_bytes: Felt252 = utils::get_value("n_ending_bytes", vm, hint_data)?; + let avl_bytes_in_word: Felt252 = utils::get_value("avl_bytes_in_word", vm, hint_data)?; + + let needs_next_word = if n_ending_bytes > avl_bytes_in_word { + Felt252::ONE + } else { + Felt252::ZERO + }; + + utils::write_value("needs_next_word", needs_next_word, vm, hint_data) +} + +pub const HINT_WORDS_LOOP: &str = + "memory[ap] = 1 if (ids.n_words_to_handle_in_loop - ids.n_words_handled) == 0 else 0"; + +pub fn hint_words_loop( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let n_words_to_handle_in_loop: Felt252 = + utils::get_value("n_words_to_handle_in_loop", vm, hint_data)?; + let n_words_handled: Felt252 = utils::get_value("n_words_handled", vm, hint_data)?; + + insert_value_into_ap( + vm, + if n_words_to_handle_in_loop == n_words_handled { + Felt252::ONE + } else { + Felt252::ZERO + }, + ) +} diff --git a/cairo_vm_hints/src/hints/lib/utils/assert.rs b/cairo_vm_hints/src/hints/lib/utils/assert.rs new file mode 100644 index 0000000..c76a8fc --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/utils/assert.rs @@ -0,0 +1,43 @@ +use crate::utils; +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::get_constant_from_var_name; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use std::collections::HashMap; + +pub const HINT_ASSERT_INTEGER_DIV32: &str = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.DIV_32)\nif not (0 < ids.DIV_32 <= PRIME):\n raise ValueError(f'div={hex(ids.DIV_32)} is out of the valid range.')"; + +pub fn hint_assert_integer_div32( + _vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + _hint_data: &HintProcessorData, + constants: &HashMap, +) -> Result<(), HintError> { + let div_32: Felt252 = *get_constant_from_var_name("DIV_32", constants)?; + let prime: Felt252 = *get_constant_from_var_name("PRIME", constants)?; + + if Felt252::ZERO < div_32 && div_32 <= prime { + Err(HintError::AssertNNValueOutOfRange(Box::new(prime))) + } else { + Ok(()) + } +} + +pub const HINT_ASSERT_INTEGER_DIV: &str = "from starkware.cairo.common.math_utils import assert_integer\nassert_integer(ids.div)\nif not (0 < ids.div <= PRIME):\n raise ValueError(f'div={hex(ids.div)} is out of the valid range.')"; + +pub fn hint_assert_integer_div( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + constants: &HashMap, +) -> Result<(), HintError> { + let div: Felt252 = utils::get_value("div", vm, hint_data)?; + let prime: Felt252 = *get_constant_from_var_name("PRIME", constants)?; + + if Felt252::ZERO < div && div <= prime { + Err(HintError::AssertNNValueOutOfRange(Box::new(prime))) + } else { + Ok(()) + } +} diff --git a/cairo_vm_hints/src/hints/lib/utils/carry.rs b/cairo_vm_hints/src/hints/lib/utils/carry.rs new file mode 100644 index 0000000..74355d3 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/utils/carry.rs @@ -0,0 +1,46 @@ +use crate::utils; +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use num_bigint::BigUint; +use std::collections::HashMap; + +pub const HINT_CARRY: &str = "sum_low = ids.a.low + ids.b.low\nids.carry_low = 1 if sum_low >= ids.SHIFT else 0\nsum_high = ids.a.high + ids.b.high + ids.carry_low\nids.carry_high = 1 if sum_high >= ids.SHIFT else 0"; + +pub fn hint_carry( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let a_low: BigUint = utils::get_value("a.low", vm, hint_data)?.to_biguint(); + let a_high: BigUint = utils::get_value("a.high", vm, hint_data)?.to_biguint(); + let b_low: BigUint = utils::get_value("b.low", vm, hint_data)?.to_biguint(); + let b_high: BigUint = utils::get_value("b.high", vm, hint_data)?.to_biguint(); + let shift: BigUint = utils::get_value("SHIFT", vm, hint_data)?.to_biguint(); + + utils::write_value( + "carry_low", + if a_low + b_low >= shift { + Felt252::ONE + } else { + Felt252::ZERO + }, + vm, + hint_data, + )?; + + utils::write_value( + "carry_high", + if a_high + b_high >= shift { + Felt252::ONE + } else { + Felt252::ZERO + }, + vm, + hint_data, + )?; + + Ok(()) +} diff --git a/cairo_vm_hints/src/hints/lib/utils/divmod.rs b/cairo_vm_hints/src/hints/lib/utils/divmod.rs new file mode 100644 index 0000000..2836154 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/utils/divmod.rs @@ -0,0 +1,57 @@ +use crate::utils; +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::get_constant_from_var_name; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use starknet_types_core::felt::NonZeroFelt; +use std::collections::HashMap; + +const FELT_8: Felt252 = Felt252::from_hex_unchecked("0x08"); + +pub const HINT_VALUE_DIV32: &str = "ids.q, ids.r = divmod(ids.value, ids.DIV_32)"; + +pub fn hint_value_div32( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + constants: &HashMap, +) -> Result<(), HintError> { + let value: Felt252 = utils::get_value("value", vm, hint_data)?; + let div_32: Felt252 = *get_constant_from_var_name("DIV_32", constants)?; + + let (q, r) = value.div_rem(&NonZeroFelt::try_from(div_32).unwrap()); + utils::write_value("q", q, vm, hint_data)?; + utils::write_value("r", r, vm, hint_data) +} + +pub const HINT_VALUE_8: &str = "ids.q, ids.r = divmod(ids.value, 8)"; + +pub fn hint_value_8( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let value: Felt252 = utils::get_value("value", vm, hint_data)?; + + let (q, r) = value.div_rem(&NonZeroFelt::try_from(FELT_8).unwrap()); + utils::write_value("q", q, vm, hint_data)?; + utils::write_value("r", r, vm, hint_data) +} + +pub const HINT_VALUE_DIV: &str = "ids.q, ids.r = divmod(ids.value, ids.div)"; + +pub fn hint_value_div( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let value: Felt252 = utils::get_value("value", vm, hint_data)?; + let div: Felt252 = utils::get_value("div", vm, hint_data)?; + + let (q, r) = value.div_rem(&NonZeroFelt::try_from(div).unwrap()); + utils::write_value("q", q, vm, hint_data)?; + utils::write_value("r", r, vm, hint_data) +} diff --git a/cairo_vm_hints/src/hints/lib/utils/mod.rs b/cairo_vm_hints/src/hints/lib/utils/mod.rs new file mode 100644 index 0000000..7750c47 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/utils/mod.rs @@ -0,0 +1,46 @@ +use std::collections::HashMap; + +use cairo_vm::{ + hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData, + types::exec_scope::ExecutionScopes, + vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, + Felt252, +}; + +mod assert; +mod carry; +mod divmod; +mod trailing_zeroes; +mod write; + +pub fn run_hint( + vm: &mut VirtualMachine, + exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + constants: &HashMap, +) -> Result<(), HintError> { + match hint_data.code.as_str() { + assert::HINT_ASSERT_INTEGER_DIV32 => { + assert::hint_assert_integer_div32(vm, exec_scope, hint_data, constants) + } + assert::HINT_ASSERT_INTEGER_DIV => { + assert::hint_assert_integer_div(vm, exec_scope, hint_data, constants) + } + carry::HINT_CARRY => carry::hint_carry(vm, exec_scope, hint_data, constants), + divmod::HINT_VALUE_DIV32 => divmod::hint_value_div32(vm, exec_scope, hint_data, constants), + divmod::HINT_VALUE_8 => divmod::hint_value_8(vm, exec_scope, hint_data, constants), + divmod::HINT_VALUE_DIV => divmod::hint_value_div(vm, exec_scope, hint_data, constants), + trailing_zeroes::HINT_TRAILING_ZEROES_BYTES => { + trailing_zeroes::hint_trailing_zeroes_bytes(vm, exec_scope, hint_data, constants) + } + write::HINT_WRITE_2 => write::hint_write_2(vm, exec_scope, hint_data, constants), + write::HINT_WRITE_3 => write::hint_write_3(vm, exec_scope, hint_data, constants), + write::HINT_WRITE_4 => write::hint_write_4(vm, exec_scope, hint_data, constants), + write::HINT_WRITE_5 => write::hint_write_5(vm, exec_scope, hint_data, constants), + write::HINT_WRITE_6 => write::hint_write_6(vm, exec_scope, hint_data, constants), + write::HINT_WRITE_7 => write::hint_write_7(vm, exec_scope, hint_data, constants), + _ => Err(HintError::UnknownHint( + hint_data.code.to_string().into_boxed_str(), + )), + } +} diff --git a/cairo_vm_hints/src/hints/lib/utils/trailing_zeroes.rs b/cairo_vm_hints/src/hints/lib/utils/trailing_zeroes.rs new file mode 100644 index 0000000..2f5f501 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/utils/trailing_zeroes.rs @@ -0,0 +1,27 @@ +use crate::utils; +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use std::collections::HashMap; + +pub const HINT_TRAILING_ZEROES_BYTES: &str = "from tools.py.utils import count_trailing_zero_bytes_from_int\nids.trailing_zeroes_bytes = count_trailing_zero_bytes_from_int(ids.x)"; + +pub fn hint_trailing_zeroes_bytes( + vm: &mut VirtualMachine, + exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let x: Felt252 = utils::get_value("x", vm, hint_data)?; + let reversed_hex = hex::encode(x.to_bytes_be()) + .bytes() + .rev() + .collect::>(); + + let trailing_zeroes_bytes: usize = reversed_hex.into_iter().take_while(|c| *c == b'0').count(); + + exec_scope.insert_value("trailing_zeroes_bytes", trailing_zeroes_bytes / 2); + + Ok(()) +} diff --git a/cairo_vm_hints/src/hints/lib/utils/write.rs b/cairo_vm_hints/src/hints/lib/utils/write.rs new file mode 100644 index 0000000..1308095 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/utils/write.rs @@ -0,0 +1,158 @@ +use crate::utils; +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::types::relocatable::MaybeRelocatable; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use std::collections::HashMap; + +pub const HINT_WRITE_2: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 2, memory, ap)"; + +pub fn hint_write_2( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let word: Felt252 = utils::get_value("word", vm, hint_data)?; + let ap = vm.get_ap(); + for (idx, byte) in word + .to_bytes_be() + .into_iter() + .rev() + .take(2) + .rev() + .enumerate() + { + println!("2 {}", byte); + vm.insert_value((ap + idx)?, MaybeRelocatable::Int(byte.into())) + .map_err(HintError::Memory)?; + } + + Ok(()) +} + +pub const HINT_WRITE_3: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 3, memory, ap)"; + +pub fn hint_write_3( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let word: Felt252 = utils::get_value("word", vm, hint_data)?; + let ap = vm.get_ap(); + for (idx, byte) in word + .to_bytes_be() + .into_iter() + .rev() + .take(3) + .rev() + .enumerate() + { + vm.insert_value((ap + idx)?, MaybeRelocatable::Int(byte.into())) + .map_err(HintError::Memory)?; + } + + Ok(()) +} + +pub const HINT_WRITE_4: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 4, memory, ap)"; + +pub fn hint_write_4( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let word: Felt252 = utils::get_value("word", vm, hint_data)?; + let ap = vm.get_ap(); + for (idx, byte) in word + .to_bytes_be() + .into_iter() + .rev() + .take(4) + .rev() + .enumerate() + { + vm.insert_value((ap + idx)?, MaybeRelocatable::Int(byte.into())) + .map_err(HintError::Memory)?; + } + + Ok(()) +} + +pub const HINT_WRITE_5: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 5, memory, ap)"; + +pub fn hint_write_5( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let word: Felt252 = utils::get_value("word", vm, hint_data)?; + let ap = vm.get_ap(); + for (idx, byte) in word + .to_bytes_be() + .into_iter() + .rev() + .take(5) + .rev() + .enumerate() + { + vm.insert_value((ap + idx)?, MaybeRelocatable::Int(byte.into())) + .map_err(HintError::Memory)?; + } + + Ok(()) +} + +pub const HINT_WRITE_6: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 6, memory, ap)"; + +pub fn hint_write_6( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let word: Felt252 = utils::get_value("word", vm, hint_data)?; + let ap = vm.get_ap(); + for (idx, byte) in word + .to_bytes_be() + .into_iter() + .rev() + .take(6) + .rev() + .enumerate() + { + vm.insert_value((ap + idx)?, MaybeRelocatable::Int(byte.into())) + .map_err(HintError::Memory)?; + } + + Ok(()) +} + +pub const HINT_WRITE_7: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 7, memory, ap)"; + +pub fn hint_write_7( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let word: Felt252 = utils::get_value("word", vm, hint_data)?; + let ap = vm.get_ap(); + for (idx, byte) in word + .to_bytes_be() + .into_iter() + .rev() + .take(7) + .rev() + .enumerate() + { + vm.insert_value((ap + idx)?, MaybeRelocatable::Int(byte.into())) + .map_err(HintError::Memory)?; + } + + Ok(()) +} diff --git a/cairo_vm_hints/src/hints/mod.rs b/cairo_vm_hints/src/hints/mod.rs new file mode 100644 index 0000000..1d0d075 --- /dev/null +++ b/cairo_vm_hints/src/hints/mod.rs @@ -0,0 +1,29 @@ +use cairo_vm::{ + hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData, + types::exec_scope::ExecutionScopes, + vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, + Felt252, +}; +use std::collections::HashMap; + +mod lib; +mod tests; + +pub fn run_hint( + vm: &mut VirtualMachine, + exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + constants: &HashMap, +) -> Result<(), HintError> { + let hints = [lib::run_hint, tests::run_hint]; + + for hint in hints.iter() { + let res = hint(vm, exec_scope, hint_data, constants); + if !matches!(res, Err(HintError::UnknownHint(_))) { + return res; + } + } + Err(HintError::UnknownHint( + hint_data.code.to_string().into_boxed_str(), + )) +} diff --git a/cairo_vm_hints/src/hints/tests/construct_mmr.rs b/cairo_vm_hints/src/hints/tests/construct_mmr.rs new file mode 100644 index 0000000..db24852 --- /dev/null +++ b/cairo_vm_hints/src/hints/tests/construct_mmr.rs @@ -0,0 +1,205 @@ +use crate::mmr::{Keccak, Mmr, Poseidon}; +use crate::utils::{split_u256, write_struct, write_value, write_vector}; +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::types::relocatable::MaybeRelocatable; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use num_bigint::{BigUint, RandBigInt}; +use num_traits::{Num, One}; +use rand::{thread_rng, Rng}; +use std::collections::HashMap; + +pub const TEST_CONSTRUCT_MMR: &str = "import random +from tools.py.mmr import get_peaks, MMR, PoseidonHasher, KeccakHasher +STARK_PRIME = 3618502788666131213697322783095070105623107215331596699973092056135872020481 + +def split_128(a): + \"\"\"Takes in value, returns uint256-ish tuple.\"\"\" + return [a & ((1 << 128) - 1), a >> 128] +def from_uint256(a): + \"\"\"Takes in uint256-ish tuple, returns value.\"\"\" + return a[0] + (a[1] << 128) +def write_uint256_array(ptr, array): + counter = 0 + for uint in array: + memory[ptr._reference_value+counter] = uint[0] + memory[ptr._reference_value+counter+1] = uint[1] + counter += 2 + +previous_n_values= random.randint(1, 200) +n_values_to_append=random.randint(1, 200) +ids.n_values_to_append=n_values_to_append; + +# Initialize random values to be appended to the new MMR. +poseidon_hash_array = [random.randint(0, STARK_PRIME-1) for _ in range(n_values_to_append)] +keccak_hash_array = [split_128(random.randint(0, 2**256-1)) for _ in range(n_values_to_append)] +segments.write_arg(ids.poseidon_hash_array, poseidon_hash_array) +write_uint256_array(ids.keccak_hash_array, keccak_hash_array) + + +# Initialize MMR objects +mmr_poseidon = MMR(PoseidonHasher()) +mmr_keccak = MMR(KeccakHasher()) + +# Initialize previous values +previous_values_poseidon = [random.randint(0, STARK_PRIME-1) for _ in range(previous_n_values)] +previous_values_keccak = [random.randint(0, 2**256-1) for _ in range(previous_n_values)] + +# Fill MMRs with previous values +for elem in previous_values_poseidon: + _= mmr_poseidon.add(elem) +for elem in previous_values_keccak: + _= mmr_keccak.add(elem) + +# Write the previous MMR size to the Cairo memory. +ids.mmr_offset=len(mmr_poseidon.pos_hash) + +# Get the previous peaks and write them to the Cairo memory. +previous_peaks_poseidon = [mmr_poseidon.pos_hash[peak_position] for peak_position in get_peaks(len(mmr_poseidon.pos_hash))] +previous_peaks_keccak = [split_128(mmr_keccak.pos_hash[peak_position]) for peak_position in get_peaks(len(mmr_keccak.pos_hash))] +segments.write_arg(ids.previous_peaks_values_poseidon, previous_peaks_poseidon) +write_uint256_array(ids.previous_peaks_values_keccak, previous_peaks_keccak) + +# Write the previous MMR root to the Cairo memory. +ids.mmr_last_root_poseidon = mmr_poseidon.get_root() +ids.mmr_last_root_keccak.low, ids.mmr_last_root_keccak.high = split_128(mmr_keccak.get_root()) + +# Fill MMRs with new values, in reversed order to match the Cairo code. (construct_mmr() appends the values starting from the last index of the array) +for new_elem in reversed(poseidon_hash_array): + _= mmr_poseidon.add(new_elem) +for new_elem in reversed(keccak_hash_array): + _= mmr_keccak.add(from_uint256(new_elem)) + +# Write the expected new MMR roots and length to the Cairo memory. +ids.expected_new_root_poseidon = mmr_poseidon.get_root() +ids.expected_new_root_keccak.low, ids.expected_new_root_keccak.high = split_128(mmr_keccak.get_root()) +ids.expected_new_len = len(mmr_poseidon.pos_hash)"; + +pub fn test_construct_mmr( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let stark_prime = BigUint::from_str_radix( + "3618502788666131213697322783095070105623107215331596699973092056135872020481", + 10, + ) + .unwrap(); + let two_pow_256 = BigUint::from_str_radix( + "115792089237316195423570985008687907853269984665640564039457584007913129639936", + 10, + ) + .unwrap(); + + let mut rng = thread_rng(); + + let previous_n_values = rng.gen_range(1..=200); + let n_values_to_append = rng.gen_range(1..=200); + write_value("n_values_to_append", n_values_to_append, vm, hint_data)?; + + let poseidon_hash_array = (0..n_values_to_append) + .map(|_| rng.gen_biguint_range(&BigUint::one(), &stark_prime)) + .collect::>(); + let keccak_hash_array = (0..n_values_to_append) + .map(|_| rng.gen_biguint_range(&BigUint::one(), &two_pow_256)) + .collect::>(); + + write_vector( + "poseidon_hash_array", + &poseidon_hash_array + .iter() + .map(|x| MaybeRelocatable::Int(x.into())) + .collect::>(), + vm, + hint_data, + )?; + write_vector( + "keccak_hash_array", + &keccak_hash_array + .iter() + .flat_map(split_u256) + .map(|x| MaybeRelocatable::Int(x.into())) + .collect::>(), + vm, + hint_data, + )?; + + let mut mmr_poseidon = Mmr::::new(); + let mut mmr_keccak = Mmr::::new(); + + (0..previous_n_values) + .map(|_| rng.gen_biguint_range(&BigUint::one(), &stark_prime)) + .for_each(|x| mmr_poseidon.append(x)); + + (0..previous_n_values) + .map(|_| rng.gen_biguint_range(&BigUint::one(), &two_pow_256)) + .for_each(|x| mmr_keccak.append(x)); + + write_value("mmr_offset", mmr_poseidon.size(), vm, hint_data)?; + + let previous_peaks_poseidon = mmr_poseidon.retrieve_nodes(mmr_poseidon.get_peaks()); + let previous_peaks_keccak = mmr_keccak.retrieve_nodes(mmr_keccak.get_peaks()); + + write_vector( + "previous_peaks_values_poseidon", + &previous_peaks_poseidon + .iter() + .map(|x| MaybeRelocatable::Int(x.into())) + .collect::>(), + vm, + hint_data, + )?; + write_vector( + "previous_peaks_values_keccak", + &previous_peaks_keccak + .iter() + .flat_map(split_u256) + .map(|x| MaybeRelocatable::Int(x.into())) + .collect::>(), + vm, + hint_data, + )?; + write_value( + "mmr_last_root_poseidon", + MaybeRelocatable::Int(mmr_poseidon.get_root().into()), + vm, + hint_data, + )?; + write_struct( + "mmr_last_root_keccak", + &split_u256(&mmr_keccak.get_root()) + .iter() + .map(|x| MaybeRelocatable::Int(x.into())) + .collect::>(), + vm, + hint_data, + )?; + + for elem in poseidon_hash_array.iter().rev() { + mmr_poseidon.append(elem.clone()); + } + for elem in keccak_hash_array.iter().rev() { + mmr_keccak.append(elem.clone()); + } + + write_value( + "expected_new_root_poseidon", + MaybeRelocatable::Int(mmr_poseidon.get_root().into()), + vm, + hint_data, + )?; + write_struct( + "expected_new_root_keccak", + &split_u256(&mmr_keccak.get_root()) + .iter() + .map(|x| MaybeRelocatable::Int(x.into())) + .collect::>(), + vm, + hint_data, + )?; + write_value("expected_new_len", mmr_keccak.size(), vm, hint_data)?; + + Ok(()) +} diff --git a/cairo_vm_hints/src/hints/tests/dw_hack.rs b/cairo_vm_hints/src/hints/tests/dw_hack.rs new file mode 100644 index 0000000..e3813c2 --- /dev/null +++ b/cairo_vm_hints/src/hints/tests/dw_hack.rs @@ -0,0 +1,77 @@ +use crate::utils::{get_value, write_value}; +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::types::relocatable::MaybeRelocatable; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use std::collections::HashMap; + +pub const HINT_BIT_LENGTH_ASSIGN_140: &str = "ids.bit_length = 140"; + +pub fn hint_bit_length_assign_140( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + write_value( + "bit_length", + MaybeRelocatable::Int(Felt252::from_hex_unchecked("0x8C")), + vm, + hint_data, + )?; + + Ok(()) +} + +pub const HINT_BIT_LENGTH_ASSIGN_NEGATIVE_ONE: &str = "ids.bit_length = -1"; + +pub fn hint_bit_length_assign_negative_one( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + write_value( + "bit_length", + MaybeRelocatable::Int(Felt252::ZERO - Felt252::ONE), + vm, + hint_data, + )?; + + Ok(()) +} + +pub const HINT_BIT_LENGTH_ASSIGN_2500: &str = "ids.bit_length = 2500"; + +pub fn hint_bit_length_assign_2500( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + write_value( + "bit_length", + MaybeRelocatable::Int(Felt252::from_hex_unchecked("0x9C4")), + vm, + hint_data, + )?; + + Ok(()) +} + +pub const HINT_PRINT_NS: &str = "print(\"N\", ids.N, \"n\", ids.n)"; + +pub fn hint_print_ns( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + println!( + "N: {}, n: {}", + get_value("N", vm, hint_data)?, + get_value("n", vm, hint_data)? + ); + Ok(()) +} diff --git a/cairo_vm_hints/src/hints/tests/encode_packed_256.rs b/cairo_vm_hints/src/hints/tests/encode_packed_256.rs new file mode 100644 index 0000000..8ae2c5b --- /dev/null +++ b/cairo_vm_hints/src/hints/tests/encode_packed_256.rs @@ -0,0 +1,98 @@ +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::types::relocatable::MaybeRelocatable; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use rand::Rng; +use sha3::Digest; +use sha3::Keccak256; +use std::collections::HashMap; + +use crate::utils::{write_value, write_vector}; + +fn get_random() -> [u8; 32] { + let mut rng = rand::thread_rng(); + let mut arr = [0u8; 32]; + rng.fill(&mut arr); + arr +} + +fn split_128(value: [u8; 32]) -> ([u8; 16], [u8; 16]) { + let mut lower = [0u8; 16]; + let mut upper = [0u8; 16]; + + lower.copy_from_slice(&value[0..16]); + upper.copy_from_slice(&value[16..32]); + + (lower, upper) +} + +fn keccak(x: &[u8; 32], y: &[u8; 32]) -> [u8; 32] { + let mut hasher = Keccak256::new(); + hasher.update(x); + hasher.update(y); + hasher.finalize().into() +} + +pub const HINT_GENERATE_TEST_VECTOR: &str = "import sha3\nimport random\nfrom web3 import Web3\ndef split_128(a):\n \"\"\"Takes in value, returns uint256-ish tuple.\"\"\"\n return [a & ((1 << 128) - 1), a >> 128]\ndef write_uint256_array(ptr, array):\n counter = 0\n for uint in array:\n memory[ptr._reference_value+counter] = uint[0]\n memory[ptr._reference_value+counter+1] = uint[1]\n counter += 2\ndef generate_n_bit_random(n):\n return random.randint(2**(n-1), 2**n - 1)\n\n# Implementation of solitidy keccak256(encodedPacked(x, y)) in python.\ndef encode_packed_256_256(x_y):\n return int(Web3.solidityKeccak([\"uint256\", \"uint256\"], [x_y[0], x_y[1]]).hex(), 16)\n# Another implementation that uses sha3 directly and should be equal. \ndef keccak_256_256(x_y):\n k=sha3.keccak_256()\n k.update(x_y[0].to_bytes(32, 'big'))\n k.update(x_y[1].to_bytes(32, 'big'))\n return int.from_bytes(k.digest(), 'big')\n\n# Build Test vector [[x_1, y_1], [x_2, y_2], ..., [x_len, y_len]].\n\n# 256 random pairs of numbers, each pair having two random numbers of 1-256 bits.\nx_y_list = [[generate_n_bit_random(random.randint(1, 256)), generate_n_bit_random(random.randint(1, 256))] for _ in range(256)]\n# Adds 256 more pairs of equal bit length to the test vector.\nx_y_list += [[generate_n_bit_random(i), generate_n_bit_random(i)] for i in range(1,257)]\n\nkeccak_output_list = [encode_packed_256_256(x_y) for x_y in x_y_list]\nkeccak_result_list = [keccak_256_256(x_y) for x_y in x_y_list]\n\n# Sanity check on keccak implementations.\nassert all([keccak_output_list[i] == keccak_result_list[i] for i in range(len(keccak_output_list))])\n\n\n# Prepare x_array and y_array :\nx_array_split = [split_128(x_y[0]) for x_y in x_y_list]\ny_array_split = [split_128(x_y[1]) for x_y in x_y_list]\n# Write x_array : \nwrite_uint256_array(ids.x_array, x_array_split)\n# Write y_array :\nwrite_uint256_array(ids.y_array, y_array_split)\n\n# Prepare keccak_result_array :\nkeccak_result_list_split = [split_128(keccak_result) for keccak_result in keccak_result_list]\n# Write keccak_result_array :\nwrite_uint256_array(ids.keccak_result_array, keccak_result_list_split)\n\n# Write len :\nids.len = len(keccak_result_list)"; + +pub fn hint_generate_test_vector( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let (x_list, y_list): (Vec<[u8; 32]>, Vec<[u8; 32]>) = + (0..512).map(|_| (get_random(), get_random())).unzip(); + + let keccak_result_list: Vec<[u8; 32]> = x_list + .iter() + .zip(y_list.iter()) + .map(|(x, y)| keccak(x, y)) + .collect(); + + let x_array: Vec = x_list + .into_iter() + .flat_map(|x| { + let (xl, xh) = split_128(x); + [ + MaybeRelocatable::Int(Felt252::from_bytes_be_slice(&xh)), + MaybeRelocatable::Int(Felt252::from_bytes_be_slice(&xl)), + ] + }) + .collect(); + write_vector("x_array", &x_array, vm, hint_data)?; + + let y_array: Vec = y_list + .into_iter() + .flat_map(|x| { + let (xl, xh) = split_128(x); + [ + MaybeRelocatable::Int(Felt252::from_bytes_be_slice(&xh)), + MaybeRelocatable::Int(Felt252::from_bytes_be_slice(&xl)), + ] + }) + .collect(); + write_vector("y_array", &y_array, vm, hint_data)?; + + let keccak_result_array: Vec = keccak_result_list + .into_iter() + .flat_map(|x| { + let (xl, xh) = split_128(x); + [ + MaybeRelocatable::Int(Felt252::from_bytes_be_slice(&xh)), + MaybeRelocatable::Int(Felt252::from_bytes_be_slice(&xl)), + ] + }) + .collect(); + write_vector("keccak_result_array", &keccak_result_array, vm, hint_data)?; + + write_value( + "len", + MaybeRelocatable::Int(Felt252::from(keccak_result_array.len() / 2)), + vm, + hint_data, + )?; + + Ok(()) +} diff --git a/cairo_vm_hints/src/hints/tests/mmr_size_generate.rs b/cairo_vm_hints/src/hints/tests/mmr_size_generate.rs new file mode 100644 index 0000000..d25d6ea --- /dev/null +++ b/cairo_vm_hints/src/hints/tests/mmr_size_generate.rs @@ -0,0 +1,97 @@ +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::types::relocatable::MaybeRelocatable; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use rand::{thread_rng, Rng}; +use starknet_types_core::felt::Felt; +use std::collections::{HashMap, HashSet}; + +use crate::utils::{get_value, write_vector}; + +fn is_valid_mmr_size(mut mmr_size: u64) -> bool { + if mmr_size == 0 { + return false; + } + let max_height = Felt::from(mmr_size).bits() as u32; + for height in (0..=max_height).rev() { + let node_count = 2u64.pow(height + 1) - 1; + if node_count <= mmr_size { + mmr_size -= node_count; + } + } + mmr_size == 0 +} + +pub const HINT_GENERATE_RANDOM: &str = "from tools.py.mmr import is_valid_mmr_size\nimport random\nprint(f\"Testing is_valid_mmr_size against python implementation with {ids.num_sizes} random sizes in [0, 20000000)...\")\nsizes_to_test = random.sample(range(0, 20000000), ids.num_sizes)\nexpected_output = [is_valid_mmr_size(size) for size in sizes_to_test]\nsegments.write_arg(ids.expected_output, expected_output)\nsegments.write_arg(ids.input_array, sizes_to_test)"; + +pub fn hint_generate_random( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + // let ids_data = &hint_data.ids_data; + // let ap_tracking = &hint_data.ap_tracking; + // let a = get_integer_from_var_name("x", vm, ids_data, ap_tracking)?; + // vm.segments.write_arg(vm.seg, arg) + let num_sizes: u64 = get_value("num_sizes", vm, hint_data)?.try_into().unwrap(); + + println!( + "Testing is_valid_mmr_size against python implementation with {} random sizes in [0, 20000000)...", + num_sizes + ); + + let mut rng = thread_rng(); + let mut input_array = vec![]; + let mut expected_output = vec![]; + for _ in 0..num_sizes { + let x = rng.gen_range(0..20000000); + input_array.push(MaybeRelocatable::Int(x.into())); + let y = is_valid_mmr_size(x); + expected_output.push(MaybeRelocatable::Int(y.into())); + } + + write_vector("input_array", &input_array, vm, hint_data)?; + write_vector("expected_output", &expected_output, vm, hint_data)?; + + Ok(()) +} + +pub const HINT_GENERATE_SEQUENTIAL: &str = "print(f\"Testing is_valid_mmr_size by creating the mmr for all sizes in [0, {ids.num_elems})...\")\nfrom tools.py.mmr import MMR\nmmr = MMR()\nvalid_mmr_sizes =set()\nfor i in range(ids.num_elems):\n mmr.add(i)\n valid_mmr_sizes.add(len(mmr.pos_hash))\n\nexpected_output = [size in valid_mmr_sizes for size in range(0, len(mmr.pos_hash) + 1)]\nsegments.write_arg(ids.expected_output, expected_output)\nsegments.write_arg(ids.input_array, list(range(0, len(mmr.pos_hash) + 1)))"; + +pub fn hint_generate_sequential( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + // let ids_data = &hint_data.ids_data; + // let ap_tracking = &hint_data.ap_tracking; + // let a = get_integer_from_var_name("x", vm, ids_data, ap_tracking)?; + // vm.segments.write_arg(vm.seg, arg) + let num_elems: u64 = get_value("num_elems", vm, hint_data)?.try_into().unwrap(); + + println!( + "Testing is_valid_mmr_size by creating the mmr for all sizes in [0, {})...", + num_elems + ); + + let mut valid_mmr_sizes = HashSet::new(); + let mut mmr_size = 0; + for leaf_count in 1..=num_elems { + mmr_size = 2 * leaf_count - (leaf_count.count_ones() as u64); + valid_mmr_sizes.insert(mmr_size); + } + let expected_output = (0..=mmr_size) + .map(|i| MaybeRelocatable::Int(valid_mmr_sizes.contains(&i).into())) + .collect::>(); + let input_array = (0..=mmr_size) + .map(|x| MaybeRelocatable::Int(x.into())) + .collect::>(); + + write_vector("input_array", &input_array, vm, hint_data)?; + write_vector("expected_output", &expected_output, vm, hint_data)?; + + Ok(()) +} diff --git a/cairo_vm_hints/src/hints/tests/mod.rs b/cairo_vm_hints/src/hints/tests/mod.rs new file mode 100644 index 0000000..528f77d --- /dev/null +++ b/cairo_vm_hints/src/hints/tests/mod.rs @@ -0,0 +1,52 @@ +use cairo_vm::{ + hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData, + types::exec_scope::ExecutionScopes, + vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, + Felt252, +}; +use std::collections::HashMap; + +mod construct_mmr; +mod dw_hack; +mod encode_packed_256; +mod mmr_size_generate; +mod print; + +pub fn run_hint( + vm: &mut VirtualMachine, + exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + constants: &HashMap, +) -> Result<(), HintError> { + match hint_data.code.as_str() { + construct_mmr::TEST_CONSTRUCT_MMR => { + construct_mmr::test_construct_mmr(vm, exec_scope, hint_data, constants) + } + dw_hack::HINT_BIT_LENGTH_ASSIGN_140 => { + dw_hack::hint_bit_length_assign_140(vm, exec_scope, hint_data, constants) + } + dw_hack::HINT_BIT_LENGTH_ASSIGN_NEGATIVE_ONE => { + dw_hack::hint_bit_length_assign_negative_one(vm, exec_scope, hint_data, constants) + } + dw_hack::HINT_BIT_LENGTH_ASSIGN_2500 => { + dw_hack::hint_bit_length_assign_2500(vm, exec_scope, hint_data, constants) + } + dw_hack::HINT_PRINT_NS => dw_hack::hint_print_ns(vm, exec_scope, hint_data, constants), + encode_packed_256::HINT_GENERATE_TEST_VECTOR => { + encode_packed_256::hint_generate_test_vector(vm, exec_scope, hint_data, constants) + } + mmr_size_generate::HINT_GENERATE_RANDOM => { + mmr_size_generate::hint_generate_random(vm, exec_scope, hint_data, constants) + } + mmr_size_generate::HINT_GENERATE_SEQUENTIAL => { + mmr_size_generate::hint_generate_sequential(vm, exec_scope, hint_data, constants) + } + print::HINT_PRINT_BREAKLINE => { + print::hint_print_breakline(vm, exec_scope, hint_data, constants) + } + print::HINT_PRINT_PASS => print::hint_print_pass(vm, exec_scope, hint_data, constants), + _ => Err(HintError::UnknownHint( + hint_data.code.to_string().into_boxed_str(), + )), + } +} diff --git a/cairo_vm_hints/src/hints/tests/print.rs b/cairo_vm_hints/src/hints/tests/print.rs new file mode 100644 index 0000000..ac437b2 --- /dev/null +++ b/cairo_vm_hints/src/hints/tests/print.rs @@ -0,0 +1,29 @@ +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; +use cairo_vm::types::exec_scope::ExecutionScopes; +use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}; +use cairo_vm::Felt252; +use std::collections::HashMap; + +pub const HINT_PRINT_BREAKLINE: &str = "print('\\n')"; + +pub fn hint_print_breakline( + _vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + _hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + println!("\n"); + Ok(()) +} + +pub const HINT_PRINT_PASS: &str = "print(f\"\\tPass!\\n\\n\")"; + +pub fn hint_print_pass( + _vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + _hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + println!("\tPass!\n\n"); + Ok(()) +} diff --git a/cairo_vm_hints/src/lib.rs b/cairo_vm_hints/src/lib.rs new file mode 100644 index 0000000..b7c9b04 --- /dev/null +++ b/cairo_vm_hints/src/lib.rs @@ -0,0 +1,9 @@ +pub mod hint_processor; +pub mod hints; +pub mod mmr; +pub mod utils; + +pub use hint_processor::{CustomHintProcessor, ExtendedHintProcessor}; + +#[cfg(test)] +pub mod tests; diff --git a/cairo_vm_hints/src/main.rs b/cairo_vm_hints/src/main.rs new file mode 100644 index 0000000..99226f9 --- /dev/null +++ b/cairo_vm_hints/src/main.rs @@ -0,0 +1,294 @@ +#![deny(warnings)] +#![forbid(unsafe_code)] +pub mod hint_processor; +pub mod hints; +pub mod mmr; +pub mod utils; + +use bincode::enc::write::Writer; +use cairo_vm::air_public_input::PublicInputError; +use cairo_vm::cairo_run::{self, EncodeTraceError}; +use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor; +// TODO +// #[cfg(feature = "with_tracer")] +// use cairo_vm::serde::deserialize_program::DebugInfo; +use cairo_vm::types::layout::CairoLayoutParams; +use cairo_vm::types::layout_name::LayoutName; +use cairo_vm::vm::errors::cairo_run_errors::CairoRunError; +use cairo_vm::vm::errors::trace_errors::TraceError; +use cairo_vm::vm::errors::vm_errors::VirtualMachineError; +use cairo_vm::vm::runners::cairo_pie::CairoPie; +// #[cfg(feature = "with_tracer")] +// use cairo_vm::vm::runners::cairo_runner::CairoRunner; +use cairo_vm::vm::runners::cairo_runner::RunResources; +use hint_processor::ExtendedHintProcessor; +// #[cfg(feature = "with_tracer")] +// use cairo_vm_tracer::error::trace_data_errors::TraceDataError; +// #[cfg(feature = "with_tracer")] +// use cairo_vm_tracer::tracer::run_tracer; +use clap::{Parser, ValueHint}; +use std::io::{self, Write}; +use std::path::{Path, PathBuf}; +use thiserror::Error; + +// #[cfg(feature = "with_mimalloc")] +// use mimalloc::MiMalloc; + +// #[cfg(feature = "with_mimalloc")] +// #[global_allocator] +// static ALLOC: MiMalloc = MiMalloc; + +#[derive(Parser, Debug)] +#[clap(author, version, about, long_about = None)] +struct Args { + #[clap(value_parser, value_hint=ValueHint::FilePath)] + filename: PathBuf, + #[clap(long = "trace_file", value_parser)] + trace_file: Option, + #[structopt(long = "print_output")] + print_output: bool, + #[structopt(long = "entrypoint", default_value = "main")] + entrypoint: String, + #[structopt(long = "memory_file")] + memory_file: Option, + /// When using dynamic layout, it's parameters must be specified through a layout params file. + #[clap(long = "layout", default_value = "plain", value_enum)] + layout: LayoutName, + /// Required when using with dynamic layout. + /// Ignored otherwise. + #[clap(long = "cairo_layout_params_file", required_if_eq("layout", "dynamic"))] + cairo_layout_params_file: Option, + #[structopt(long = "proof_mode")] + proof_mode: bool, + #[structopt(long = "secure_run")] + secure_run: Option, + #[clap(long = "air_public_input", requires = "proof_mode")] + air_public_input: Option, + #[clap( + long = "air_private_input", + requires_all = ["proof_mode", "trace_file", "memory_file"] + )] + air_private_input: Option, + #[clap( + long = "cairo_pie_output", + // We need to add these air_private_input & air_public_input or else + // passing cairo_pie_output + either of these without proof_mode will not fail + conflicts_with_all = ["proof_mode", "air_private_input", "air_public_input"] + )] + cairo_pie_output: Option, + #[structopt(long = "allow_missing_builtins")] + allow_missing_builtins: Option, + #[structopt(long = "tracer")] + // #[cfg(feature = "with_tracer")] + // tracer: bool, + #[structopt( + long = "run_from_cairo_pie", + // We need to add these air_private_input & air_public_input or else + // passing run_from_cairo_pie + either of these without proof_mode will not fail + conflicts_with_all = ["proof_mode", "air_private_input", "air_public_input"] + )] + run_from_cairo_pie: bool, +} + +#[derive(Debug, Error)] +enum Error { + #[error("Invalid arguments")] + Cli(#[from] clap::Error), + #[error("Failed to interact with the file system")] + IO(#[from] std::io::Error), + #[error("The cairo program execution failed")] + Runner(#[from] CairoRunError), + #[error(transparent)] + EncodeTrace(#[from] EncodeTraceError), + #[error(transparent)] + VirtualMachine(#[from] VirtualMachineError), + #[error(transparent)] + Trace(#[from] TraceError), + #[error(transparent)] + PublicInput(#[from] PublicInputError), + // #[error(transparent)] + // #[cfg(feature = "with_tracer")] + // TraceData(#[from] TraceDataError), +} + +struct FileWriter { + buf_writer: io::BufWriter, + bytes_written: usize, +} + +impl Writer for FileWriter { + fn write(&mut self, bytes: &[u8]) -> Result<(), bincode::error::EncodeError> { + self.buf_writer + .write_all(bytes) + .map_err(|e| bincode::error::EncodeError::Io { + inner: e, + index: self.bytes_written, + })?; + + self.bytes_written += bytes.len(); + + Ok(()) + } +} + +impl FileWriter { + fn new(buf_writer: io::BufWriter) -> Self { + Self { + buf_writer, + bytes_written: 0, + } + } + + fn flush(&mut self) -> io::Result<()> { + self.buf_writer.flush() + } +} + +// #[cfg(feature = "with_tracer")] +// fn start_tracer(cairo_runner: &CairoRunner) -> Result<(), TraceDataError> { +// let relocation_table = cairo_runner +// .vm +// .relocate_segments() +// .map_err(TraceDataError::FailedToGetRelocationTable)?; +// let instruction_locations = cairo_runner +// .get_program() +// .get_relocated_instruction_locations(relocation_table.as_ref()); +// let debug_info = instruction_locations.map(DebugInfo::new); + +// let relocated_trace = cairo_runner +// .relocated_trace +// .clone() +// .ok_or(TraceDataError::FailedToGetRelocatedTrace)?; + +// run_tracer( +// cairo_runner.get_program().clone(), +// cairo_runner.relocated_memory.clone(), +// relocated_trace.clone(), +// 1, +// debug_info, +// )?; +// Ok(()) +// } + +fn run(args: impl Iterator) -> Result<(), Error> { + let args = Args::try_parse_from(args)?; + + let trace_enabled = args.trace_file.is_some() || args.air_public_input.is_some(); + + let cairo_layout_params = match args.cairo_layout_params_file { + Some(file) => Some(CairoLayoutParams::from_file(&file)?), + None => None, + }; + + let cairo_run_config = cairo_run::CairoRunConfig { + entrypoint: &args.entrypoint, + trace_enabled, + relocate_mem: args.memory_file.is_some() || args.air_public_input.is_some(), + layout: args.layout, + proof_mode: args.proof_mode, + secure_run: args.secure_run, + allow_missing_builtins: args.allow_missing_builtins, + dynamic_layout_params: cairo_layout_params, + ..Default::default() + }; + + let mut cairo_runner = match if args.run_from_cairo_pie { + let pie = CairoPie::read_zip_file(&args.filename)?; + let mut hint_processor = BuiltinHintProcessor::new( + Default::default(), + RunResources::new(pie.execution_resources.n_steps), + ); + cairo_run::cairo_run_pie(&pie, &cairo_run_config, &mut hint_processor) + } else { + let program_content = std::fs::read(args.filename).map_err(Error::IO)?; + let mut hint_processor = ExtendedHintProcessor::new(); + cairo_run::cairo_run(&program_content, &cairo_run_config, &mut hint_processor) + } { + Ok(runner) => runner, + Err(error) => { + eprintln!("{error}"); + return Err(Error::Runner(error)); + } + }; + + if args.print_output { + let mut output_buffer = "Program Output:\n".to_string(); + cairo_runner.vm.write_output(&mut output_buffer)?; + print!("{output_buffer}"); + } + + if let Some(ref trace_path) = args.trace_file { + let relocated_trace = cairo_runner + .relocated_trace + .as_ref() + .ok_or(Error::Trace(TraceError::TraceNotRelocated))?; + + let trace_file = std::fs::File::create(trace_path)?; + let mut trace_writer = + FileWriter::new(io::BufWriter::with_capacity(3 * 1024 * 1024, trace_file)); + + cairo_run::write_encoded_trace(relocated_trace, &mut trace_writer)?; + trace_writer.flush()?; + } + + if let Some(ref memory_path) = args.memory_file { + let memory_file = std::fs::File::create(memory_path)?; + let mut memory_writer = + FileWriter::new(io::BufWriter::with_capacity(5 * 1024 * 1024, memory_file)); + + cairo_run::write_encoded_memory(&cairo_runner.relocated_memory, &mut memory_writer)?; + memory_writer.flush()?; + } + + if let Some(file_path) = args.air_public_input { + let json = cairo_runner.get_air_public_input()?.serialize_json()?; + std::fs::write(file_path, json)?; + } + + // #[cfg(feature = "with_tracer")] + // if args.tracer { + // start_tracer(&cairo_runner)?; + // } + + if let (Some(file_path), Some(ref trace_file), Some(ref memory_file)) = + (args.air_private_input, args.trace_file, args.memory_file) + { + // Get absolute paths of trace_file & memory_file + let trace_path = trace_file + .as_path() + .canonicalize() + .unwrap_or(trace_file.clone()) + .to_string_lossy() + .to_string(); + let memory_path = memory_file + .as_path() + .canonicalize() + .unwrap_or(memory_file.clone()) + .to_string_lossy() + .to_string(); + + let json = cairo_runner + .get_air_private_input() + .to_serializable(trace_path, memory_path) + .serialize_json() + .map_err(PublicInputError::Serde)?; + std::fs::write(file_path, json)?; + } + + if let Some(ref file_name) = args.cairo_pie_output { + let file_path = Path::new(file_name); + cairo_runner + .get_cairo_pie() + .map_err(CairoRunError::Runner)? + .write_zip_file(file_path)? + } + + Ok(()) +} + +fn main() -> Result<(), Error> { + match run(std::env::args()) { + Err(Error::Cli(err)) => err.exit(), + other => other, + } +} diff --git a/cairo_vm_hints/src/mmr.rs b/cairo_vm_hints/src/mmr.rs new file mode 100644 index 0000000..06ae142 --- /dev/null +++ b/cairo_vm_hints/src/mmr.rs @@ -0,0 +1,122 @@ +use num_bigint::BigUint; +use starknet_crypto::poseidon_hash; +use tiny_keccak::{Hasher as KeccakTrait, Keccak as KeccakHasher}; + +pub trait Hasher { + fn new() -> Self; + fn hash(&self, x: &BigUint, y: &BigUint) -> BigUint; +} + +pub struct Keccak; +impl Hasher for Keccak { + fn new() -> Self { + Self + } + + fn hash(&self, x: &BigUint, y: &BigUint) -> BigUint { + let mut keccak = KeccakHasher::v256(); + + let mut result: Vec = Vec::new(); + + let hex_x = format!("{:0>64}", x.to_str_radix(16)); + let bytes_x = hex::decode(hex_x).unwrap(); + result.extend(bytes_x); + + let hex_y = format!("{:0>64}", y.to_str_radix(16)); + let bytes_y = hex::decode(hex_y).unwrap(); + result.extend(bytes_y); + + keccak.update(&result); + + let mut output = [0u8; 32]; + keccak.finalize(&mut output); + BigUint::from_bytes_be(&output) + } +} + +pub struct Poseidon; +impl Hasher for Poseidon { + fn new() -> Self { + Self + } + + fn hash(&self, x: &BigUint, y: &BigUint) -> BigUint { + poseidon_hash(x.into(), y.into()).to_biguint() + } +} + +#[derive(Debug)] +pub struct Mmr { + hasher: H, + nodes: Vec, + leaf_count: usize, +} + +impl Default for Mmr { + fn default() -> Self { + Self::new() + } +} + +impl Mmr { + pub fn new() -> Mmr { + Mmr { + hasher: H::new(), + nodes: vec![], + leaf_count: 0, + } + } + + pub fn get_root(&self) -> BigUint { + let mut peaks = self.retrieve_nodes(self.get_peaks()); + let mut hash = peaks.pop().unwrap(); + peaks + .iter() + .rev() + .for_each(|x| hash = self.hasher.hash(x, &hash)); + self.hasher.hash(&self.size().into(), &hash) + } + + pub fn size(&self) -> usize { + self.nodes.len() + } + + pub fn get_peaks(&self) -> Vec { + let mut peaks = vec![]; + let mut node_count = self.nodes.len(); + if node_count == 0 { + return vec![]; + } + let height = node_count.ilog2() + 1; + let mut offset = 0; + for h in (1..=height).rev() { + let subtree_size = 2_usize.pow(h) - 1; + if subtree_size <= node_count { + node_count -= subtree_size; + offset += subtree_size; + peaks.push(offset); + } + } + assert!(node_count == 0, "Invalid node count"); + peaks + } + + pub fn append(&mut self, element: BigUint) { + let peaks = self.retrieve_nodes(self.get_peaks()); + let no_merged_peaks = self.leaf_count.trailing_ones(); + self.leaf_count += 1; + self.nodes.push(element.clone()); + let mut last_node = element; + for peak in peaks.iter().rev().take(no_merged_peaks as usize) { + last_node = self.hasher.hash(peak, &last_node); + self.nodes.push(last_node.clone()); + } + } + + pub fn retrieve_nodes(&self, indices: Vec) -> Vec { + indices + .iter() + .map(|index| self.nodes[*index - 1].clone()) + .collect() + } +} diff --git a/cairo_vm_hints/src/tests/construct_mmr.rs b/cairo_vm_hints/src/tests/construct_mmr.rs new file mode 100644 index 0000000..9b4e484 --- /dev/null +++ b/cairo_vm_hints/src/tests/construct_mmr.rs @@ -0,0 +1,12 @@ +use super::run_cairo_program; + +#[test] +fn test() { + let cairo_runner = run_cairo_program(include_bytes!( + "../../../build/compiled_cairo_files/construct_mmr_test.json" + )) + .unwrap(); + + let execution_resources = cairo_runner.get_execution_resources().unwrap(); + println!("n_steps: {}", execution_resources.n_steps) +} diff --git a/cairo_vm_hints/src/tests/dw_hack.rs b/cairo_vm_hints/src/tests/dw_hack.rs new file mode 100644 index 0000000..2785369 --- /dev/null +++ b/cairo_vm_hints/src/tests/dw_hack.rs @@ -0,0 +1,12 @@ +use super::run_cairo_program; + +#[test] +fn test() { + let cairo_runner = run_cairo_program(include_bytes!( + "../../../build/compiled_cairo_files/dw_hack_test.json" + )) + .unwrap(); + + let execution_resources = cairo_runner.get_execution_resources().unwrap(); + println!("n_steps: {}", execution_resources.n_steps) +} diff --git a/cairo_vm_hints/src/tests/encode_packed_256.rs b/cairo_vm_hints/src/tests/encode_packed_256.rs new file mode 100644 index 0000000..b4e6dc1 --- /dev/null +++ b/cairo_vm_hints/src/tests/encode_packed_256.rs @@ -0,0 +1,12 @@ +use super::run_cairo_program; + +#[test] +fn test() { + let cairo_runner = run_cairo_program(include_bytes!( + "../../../build/compiled_cairo_files/encode_packed_256_256_test.json" + )) + .unwrap(); + + let execution_resources = cairo_runner.get_execution_resources().unwrap(); + println!("n_steps: {}", execution_resources.n_steps) +} diff --git a/cairo_vm_hints/src/tests/is_valid_mmr_size.rs b/cairo_vm_hints/src/tests/is_valid_mmr_size.rs new file mode 100644 index 0000000..4d4315b --- /dev/null +++ b/cairo_vm_hints/src/tests/is_valid_mmr_size.rs @@ -0,0 +1,12 @@ +use super::run_cairo_program; + +#[test] +fn test() { + let cairo_runner = run_cairo_program(include_bytes!( + "../../../build/compiled_cairo_files/is_valid_mmr_size.json" + )) + .unwrap(); + + let execution_resources = cairo_runner.get_execution_resources().unwrap(); + println!("n_steps: {}", execution_resources.n_steps) +} diff --git a/cairo_vm_hints/src/tests/mod.rs b/cairo_vm_hints/src/tests/mod.rs new file mode 100644 index 0000000..a5e8657 --- /dev/null +++ b/cairo_vm_hints/src/tests/mod.rs @@ -0,0 +1,24 @@ +pub mod construct_mmr; +pub mod dw_hack; +pub mod encode_packed_256; +pub mod is_valid_mmr_size; + +use crate::ExtendedHintProcessor; +use cairo_vm::{ + cairo_run, + vm::{errors::cairo_run_errors::CairoRunError, runners::cairo_runner::CairoRunner}, +}; + +pub fn run_cairo_program(program_content: &[u8]) -> Result { + let cairo_run_config = cairo_run::CairoRunConfig { + layout: cairo_vm::types::layout_name::LayoutName::all_cairo, + allow_missing_builtins: Some(true), + ..Default::default() + }; + + Ok(cairo_run::cairo_run( + program_content, + &cairo_run_config, + &mut ExtendedHintProcessor::new(), + )?) +} diff --git a/cairo_vm_hints/src/utils.rs b/cairo_vm_hints/src/utils.rs new file mode 100644 index 0000000..88ef751 --- /dev/null +++ b/cairo_vm_hints/src/utils.rs @@ -0,0 +1,69 @@ +use cairo_vm::{ + hint_processor::builtin_hint_processor::{ + builtin_hint_processor_definition::HintProcessorData, + hint_utils::{ + get_integer_from_var_name, get_ptr_from_var_name, get_relocatable_from_var_name, + insert_value_from_var_name, + }, + }, + types::relocatable::MaybeRelocatable, + vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, + Felt252, +}; +use num_bigint::BigUint; + +pub fn split_u256(number: &BigUint) -> [BigUint; 2] { + let mut iter = number.to_bytes_le().into_iter(); + let low = &iter.by_ref().take(16).collect::>(); + let high = &iter.collect::>(); + [BigUint::from_bytes_le(low), BigUint::from_bytes_le(high)] +} + +pub fn write_value( + var_name: &str, + value: impl Into, + vm: &mut VirtualMachine, + hint_data: &HintProcessorData, +) -> Result<(), HintError> { + insert_value_from_var_name( + var_name, + value, + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + ) +} + +pub fn write_struct( + var_name: &str, + values: &[MaybeRelocatable], + vm: &mut VirtualMachine, + hint_data: &HintProcessorData, +) -> Result<(), HintError> { + vm.segments.load_data( + get_relocatable_from_var_name(var_name, vm, &hint_data.ids_data, &hint_data.ap_tracking)?, + values, + )?; + Ok(()) +} + +pub fn write_vector( + var_name: &str, + vector: &[MaybeRelocatable], + vm: &mut VirtualMachine, + hint_data: &HintProcessorData, +) -> Result<(), HintError> { + vm.segments.load_data( + get_ptr_from_var_name(var_name, vm, &hint_data.ids_data, &hint_data.ap_tracking)?, + vector, + )?; + Ok(()) +} + +pub fn get_value( + var_name: &str, + vm: &mut VirtualMachine, + hint_data: &HintProcessorData, +) -> Result { + get_integer_from_var_name(var_name, vm, &hint_data.ids_data, &hint_data.ap_tracking) +} diff --git a/lib/mmr.cairo b/lib/mmr.cairo index 40697d9..029991c 100644 --- a/lib/mmr.cairo +++ b/lib/mmr.cairo @@ -234,7 +234,7 @@ func left_child_jump_until_inside_mmr{range_check_ptr, pow2_array: felt*, mmr_le ) -> felt { alloc_locals; local in_mmr; - %{ ids.in_mmr = 1 if ids.left_child<=ids.mmr_len else 0 %} + %{ ids.in_mmr = 1 if ids.left_child <= ids.mmr_len else 0 %} if (in_mmr != 0) { // Ensure left_child <= mmr_len diff --git a/lib/rlp_little.cairo b/lib/rlp_little.cairo index c9ca35f..eedd608 100644 --- a/lib/rlp_little.cairo +++ b/lib/rlp_little.cairo @@ -560,15 +560,15 @@ func extract_n_bytes_from_le_64_chunks_array{range_check_ptr}( if (n_words == 1) { local needs_next_word: felt; - local avl_bytes_in_first_word = 8 - start_offset; - %{ ids.needs_next_word = 1 if ids.n_bytes > ids.avl_bytes_in_first_word else 0 %} + local avl_bytes_in_word = 8 - start_offset; + %{ ids.needs_next_word = 1 if ids.n_bytes > ids.avl_bytes_in_word else 0 %} if (needs_next_word == 0) { // %{ print(f"current_word={hex(ids.current_word)}") %} let (_, last_word) = felt_divmod(current_word, pow2_array[8 * n_ending_bytes]); assert res[0] = last_word; return (res, 1); } else { - // %{ print(f"needs next word, avl_bytes_in_first_word={ids.avl_bytes_in_first_word}") %} + // %{ print(f"needs next word, avl_bytes_in_word={ids.avl_bytes_in_word}") %} // %{ print(f"current_word={hex(ids.current_word)}") %} let (_, last_word) = felt_divmod( diff --git a/tests/cairo_programs/dw_hack_test.cairo b/tests/cairo_programs/dw_hack_test.cairo index b930bdd..35bd5c8 100644 --- a/tests/cairo_programs/dw_hack_test.cairo +++ b/tests/cairo_programs/dw_hack_test.cairo @@ -24,10 +24,7 @@ func main{range_check_ptr}() { func compute_height_pre_alloc_pow2_hack0{range_check_ptr, pow2_array: felt*}(x: felt) -> felt { alloc_locals; local bit_length; - %{ - x = ids.x - ids.bit_length = 140 - %} + %{ ids.bit_length = 140 %} // Computes N=2^bit_length and n=2^(bit_length-1) // x is supposed to verify n = 2^(b-1) <= x < N = 2^bit_length <=> x has bit_length bits @@ -55,10 +52,7 @@ func compute_height_pre_alloc_pow2_hack0{range_check_ptr, pow2_array: felt*}(x: func compute_height_pre_alloc_pow2_hack1{range_check_ptr, pow2_array: felt*}(x: felt) -> felt { alloc_locals; local bit_length; - %{ - x = ids.x - ids.bit_length = -1 - %} + %{ ids.bit_length = -1 %} // Computes N=2^bit_length and n=2^(bit_length-1) // x is supposed to verify n = 2^(b-1) <= x < N = 2^bit_length <=> x has bit_length bits @@ -86,10 +80,7 @@ func compute_height_pre_alloc_pow2_hack1{range_check_ptr, pow2_array: felt*}(x: func compute_height_pre_alloc_pow2_hack2{range_check_ptr, pow2_array: felt*}(x: felt) -> felt { alloc_locals; local bit_length; - %{ - x = ids.x - ids.bit_length = 2500 - %} + %{ ids.bit_length = 2500 %} // Computes N=2^bit_length and n=2^(bit_length-1) // x is supposed to verify n = 2^(b-1) <= x < N = 2^bit_length <=> x has bit_length bits