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..3fc5cb5 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1252 @@ +# 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 = "cairo_vm_hints" +version = "0.1.0" +dependencies = [ + "bincode", + "cairo-vm", + "clap", + "hex", + "linkme", + "num-bigint", + "num-traits", + "rand", + "sha3", + "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.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 = "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 = "linkme" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70fe496a7af8c406f877635cbf3cd6a9fac9d6f443f58691cd8afe6ce0971af4" +dependencies = [ + "linkme-impl", +] + +[[package]] +name = "linkme-impl" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b01f197a15988fb5b2ec0a5a9800c97e70771499c456ad757d63b3c5e9b96e75" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.82", +] + +[[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..25e0c1e --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,20 @@ +[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" +linkme = "0.3.29" \ No newline at end of file diff --git a/cairo_vm_hints/Cargo.toml b/cairo_vm_hints/Cargo.toml index c2acfb5..e6a0af7 100644 --- a/cairo_vm_hints/Cargo.toml +++ b/cairo_vm_hints/Cargo.toml @@ -4,14 +4,16 @@ version = "0.1.0" edition = "2021" [dependencies] -cairo-vm = { git = "https://github.com/lambdaclass/cairo-vm", rev = "3fb0344ce038b3a68cae897c403d1f561cfe8da7", features = ["extensive_hints", "clap", "std"] } -starknet-types-core = "0.1.7" -thiserror = "1.0.64" -clap = { version = "4.3.10", features = ["derive"] } -bincode = { version = "2.0.0-rc.3", default-features = false, features = ["serde"] } -rand = "0.8" -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 +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 +linkme.workspace = true diff --git a/cairo_vm_hints/src/hint_processor.rs b/cairo_vm_hints/src/hint_processor.rs index 10472b5..c0550d2 100644 --- a/cairo_vm_hints/src/hint_processor.rs +++ b/cairo_vm_hints/src/hint_processor.rs @@ -1,21 +1,4 @@ -use crate::hints::{ - bit_length_mmr::{bit_length_mmr, BIT_LENGTH_MMR}, - bit_length_x::{bit_length_x, BIT_LENGTH_X}, - mmr_left_child::{mmr_left_child, MMR_LEFT_CHILD}, - test_construct_mmr::{test_construct_mmr, TEST_CONSTRUCT_MMR}, - test_is_valid_mmr_size_generate_random::{ - test_is_valid_mmr_size_generate_random, TEST_IS_VALID_MMR_SIZE_GENERATE_RANDOM, - }, - test_is_valid_mmr_size_generate_sequential::{ - test_is_valid_mmr_size_generate_sequential, TEST_IS_VALID_MMR_SIZE_GENERATE_SEQUENTIAL, - }, - test_is_valid_mmr_size_print_1::{ - test_is_valid_mmr_size_print_1, TEST_IS_VALID_MMR_SIZE_PRINT_1, - }, - test_is_valid_mmr_size_print_2::{ - test_is_valid_mmr_size_print_2, TEST_IS_VALID_MMR_SIZE_PRINT_2, - }, -}; +use crate::hints::run_hint; use cairo_vm::{ hint_processor::{ builtin_hint_processor::builtin_hint_processor_definition::{ @@ -44,35 +27,6 @@ impl CustomHintProcessor { } } -fn run_hint( - vm: &mut VirtualMachine, - exec_scope: &mut ExecutionScopes, - hint_data: &HintProcessorData, - constants: &HashMap, -) -> Result<(), HintError> { - match hint_data.code.as_str() { - TEST_IS_VALID_MMR_SIZE_PRINT_1 => { - test_is_valid_mmr_size_print_1(vm, exec_scope, hint_data, constants) - } - TEST_IS_VALID_MMR_SIZE_PRINT_2 => { - test_is_valid_mmr_size_print_2(vm, exec_scope, hint_data, constants) - } - TEST_IS_VALID_MMR_SIZE_GENERATE_SEQUENTIAL => { - test_is_valid_mmr_size_generate_sequential(vm, exec_scope, hint_data, constants) - } - TEST_IS_VALID_MMR_SIZE_GENERATE_RANDOM => { - test_is_valid_mmr_size_generate_random(vm, exec_scope, hint_data, constants) - } - BIT_LENGTH_X => bit_length_x(vm, exec_scope, hint_data, constants), - BIT_LENGTH_MMR => bit_length_mmr(vm, exec_scope, hint_data, constants), - TEST_CONSTRUCT_MMR => test_construct_mmr(vm, exec_scope, hint_data, constants), - MMR_LEFT_CHILD => mmr_left_child(vm, exec_scope, hint_data, constants), - _ => Err(HintError::UnknownHint( - hint_data.code.to_string().into_boxed_str(), - )), - } -} - impl HintProcessorLogic for CustomHintProcessor { fn execute_hint( &mut self, diff --git a/cairo_vm_hints/src/hints/bit_length_x.rs b/cairo_vm_hints/src/hints/lib/bit_length.rs similarity index 78% rename from cairo_vm_hints/src/hints/bit_length_x.rs rename to cairo_vm_hints/src/hints/lib/bit_length.rs index 4e5c63e..8d06fe7 100644 --- a/cairo_vm_hints/src/hints/bit_length_x.rs +++ b/cairo_vm_hints/src/hints/lib/bit_length.rs @@ -1,3 +1,4 @@ +use crate::hints::{Hint, HINTS}; 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, @@ -6,11 +7,12 @@ 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 linkme::distributed_slice; use std::collections::HashMap; -pub const BIT_LENGTH_X: &str = "ids.bit_length = ids.x.bit_length()"; +const HINT_BIT_LENGTH: &str = "ids.bit_length = ids.x.bit_length()"; -pub fn bit_length_x( +fn hint_bit_length( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -27,3 +29,6 @@ pub fn bit_length_x( Ok(()) } + +#[distributed_slice(HINTS)] +static _HINT_BIT_LENGTH: Hint = (HINT_BIT_LENGTH, hint_bit_length); 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..5419c36 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/block_header/mod.rs @@ -0,0 +1,37 @@ +use crate::hints::{Hint, HINTS}; +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 linkme::distributed_slice; +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(()) +} + +#[distributed_slice(HINTS)] +static _HINT_RLP_BIGINT_SIZE: Hint = (HINT_RLP_BIGINT_SIZE, hint_rlp_bigint_size); diff --git a/cairo_vm_hints/src/hints/bit_length_mmr.rs b/cairo_vm_hints/src/hints/lib/mmr/bit_length.rs similarity index 79% rename from cairo_vm_hints/src/hints/bit_length_mmr.rs rename to cairo_vm_hints/src/hints/lib/mmr/bit_length.rs index 51ace2b..9b61cdf 100644 --- a/cairo_vm_hints/src/hints/bit_length_mmr.rs +++ b/cairo_vm_hints/src/hints/lib/mmr/bit_length.rs @@ -1,3 +1,4 @@ +use crate::hints::{Hint, HINTS}; 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, @@ -6,11 +7,12 @@ 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 linkme::distributed_slice; use std::collections::HashMap; -pub const BIT_LENGTH_MMR: &str = "ids.bit_length = ids.mmr_len.bit_length()"; +const MMR_LEFT_CHILD: &str = "ids.bit_length = ids.mmr_len.bit_length()"; -pub fn bit_length_mmr( +fn mmr_left_child( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -27,3 +29,6 @@ pub fn bit_length_mmr( Ok(()) } + +#[distributed_slice(HINTS)] +static _MMR_LEFT_CHILD: Hint = (MMR_LEFT_CHILD, mmr_left_child); diff --git a/cairo_vm_hints/src/hints/mmr_left_child.rs b/cairo_vm_hints/src/hints/lib/mmr/left_child.rs similarity index 82% rename from cairo_vm_hints/src/hints/mmr_left_child.rs rename to cairo_vm_hints/src/hints/lib/mmr/left_child.rs index 673058c..940b81f 100644 --- a/cairo_vm_hints/src/hints/mmr_left_child.rs +++ b/cairo_vm_hints/src/hints/lib/mmr/left_child.rs @@ -1,3 +1,4 @@ +use crate::hints::{Hint, HINTS}; 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, @@ -6,12 +7,13 @@ 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 linkme::distributed_slice; 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"; +const MMR_LEFT_CHILD: &str = "ids.in_mmr = 1 if ids.left_child<=ids.mmr_len else 0"; -pub fn mmr_left_child( +fn mmr_left_child( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -41,3 +43,6 @@ pub fn mmr_left_child( Ok(()) } + +#[distributed_slice(HINTS)] +static _MMR_LEFT_CHILD: Hint = (MMR_LEFT_CHILD, mmr_left_child); 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..25f605e --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/mmr/mod.rs @@ -0,0 +1,2 @@ +mod bit_length; +mod left_child; 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..7f2e53b --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/mod.rs @@ -0,0 +1,6 @@ +mod bit_length; +mod block_header; +mod mmr; +mod mpt; +mod rlp_little; +mod utils; 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..0d9c247 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/mpt/mod.rs @@ -0,0 +1,217 @@ +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 crate::hints::{Hint, HINTS}; +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 linkme::distributed_slice; +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, + )))), + } +} +#[distributed_slice(HINTS)] +static _HIT_LONG_SHORT_LIST: Hint = (HINT_LONG_SHORT_LIST, hint_long_short_list); + +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, + )))), + } +} + +#[distributed_slice(HINTS)] +static _HINT_FIRST_ITEM_TYPE: Hint = (HINT_FIRST_ITEM_TYPE, hint_first_item_type); + +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, + )))), + } +} + +#[distributed_slice(HINTS)] +static _HINT_SECOND_ITEM_TYPE: Hint = (HINT_SECOND_ITEM_TYPE, hint_second_item_type); + +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, + )))), + } +} + +#[distributed_slice(HINTS)] +static _HINT_ITEM_TYPE: Hint = (HINT_ITEM_TYPE, hint_item_type); 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..032ae08 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/rlp_little/assert.rs @@ -0,0 +1,59 @@ +use crate::hints::{Hint, HINTS}; +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 linkme::distributed_slice; +use std::collections::HashMap; + +const HINT_EXPECTED_LEADING_ZEROES: &str = "assert ids.res == expected_leading_zeroes, f\"Expected {expected_leading_zeroes} but got {ids.res}\""; + +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(()) + } +} + +#[distributed_slice(HINTS)] +static _HINT_EXPECTED_LEADING_ZEROS: Hint = + (HINT_EXPECTED_LEADING_ZEROES, hint_expected_leading_zeroes); + +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}\""; + +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(()) + } +} + +#[distributed_slice(HINTS)] +static _HINT_EXPECTED_NIBBLE: Hint = (HINT_EXPECTED_NIBBLE, hint_expected_nibble); 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..189c38b --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/rlp_little/divmod.rs @@ -0,0 +1,41 @@ +use crate::hints::{Hint, HINTS}; +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 linkme::distributed_slice; +use starknet_types_core::felt::NonZeroFelt; +use std::collections::HashMap; + +const HINT_POW_CUT: &str = + "ids.q, ids.r = divmod(memory[ids.array + ids.start_word + ids.i], ids.pow_cut)"; + +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) +} + +#[distributed_slice(HINTS)] +static _HINT_POW_CUT: Hint = (HINT_POW_CUT, hint_pow_cut); 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..e884021 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/rlp_little/leading_zeros.rs @@ -0,0 +1,84 @@ +use crate::hints::{Hint, HINTS}; +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 linkme::distributed_slice; +use std::collections::HashMap; + +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)"; + +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(()) +} + +#[distributed_slice(HINTS)] +static _HINT_EXPECTED_LEADING_ZEROES: Hint = + (HINT_EXPECTED_LEADING_ZEROES, hint_expected_leading_zeroes); + +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)"; + +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(()) +} + +#[distributed_slice(HINTS)] +static _HINT_EXPECTED_NIBBLE: Hint = (HINT_EXPECTED_NIBBLE, hint_expected_nibble); 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..5f0cdb9 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/rlp_little/mod.rs @@ -0,0 +1,4 @@ +mod assert; +mod divmod; +mod leading_zeros; +mod nibbles; 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..af5c7d1 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/rlp_little/nibbles.rs @@ -0,0 +1,143 @@ +use crate::hints::{Hint, HINTS}; +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 linkme::distributed_slice; +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"); + +const HINT_IS_ZERO: &str = + "ids.is_zero = 1 if ids.nibble_index <= (ids.key_leading_zeroes_nibbles - 1) else 0"; + +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, + ) +} + +#[distributed_slice(HINTS)] +static _HINT_IS_ZERO: Hint = (HINT_IS_ZERO, hint_is_zero); + +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"; + +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) +} + +#[distributed_slice(HINTS)] +static _HINT_NIBBLE_FROM_LOW: Hint = (HINT_NIBBLE_FROM_LOW, hint_nibble_from_low); + +const HINT_NEEDS_NEXT_WORD: &str = + "ids.needs_next_word = 1 if ids.n_bytes > ids.avl_bytes_in_word else 0"; + +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) +} + +#[distributed_slice(HINTS)] +static _HINT_NEEDS_NEXT_WORD: Hint = (HINT_NEEDS_NEXT_WORD, hint_needs_next_word); + +const HINT_NEEDS_NEXT_WORD_ENDING: &str = + "ids.needs_next_word = 1 if ids.n_ending_bytes > ids.avl_bytes_in_word else 0"; + +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) +} + +#[distributed_slice(HINTS)] +static _HINT_NEEDS_NEXT_WORD_ENDING: Hint = + (HINT_NEEDS_NEXT_WORD_ENDING, hint_needs_next_word_ending); + +const HINT_WORDS_LOOP: &str = + "memory[ap] = 1 if (ids.n_words_to_handle_in_loop - ids.n_words_handled) == 0 else 0"; + +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 + }, + ) +} + +#[distributed_slice(HINTS)] +static _HINT_WORDS_LOOP: Hint = (HINT_WORDS_LOOP, hint_words_loop); 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..b0d9abb --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/utils/assert.rs @@ -0,0 +1,51 @@ +use crate::hints::{Hint, HINTS}; +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 linkme::distributed_slice; +use std::collections::HashMap; + +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.')"; + +fn hint_assert_integer_div32( + vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + constants: &HashMap, +) -> Result<(), HintError> { + let div_32: Felt252 = utils::get_value("DIV_32", vm, hint_data)?; + 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(()) + } +} + +#[distributed_slice(HINTS)] +static _HINT_ASSERT_INTEGER_DIV32: Hint = (HINT_ASSERT_INTEGER_DIV32, hint_assert_integer_div32); + +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.')"; + +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(()) + } +} + +#[distributed_slice(HINTS)] +static _HINT_ASSERT_INTEGER_DIV: Hint = (HINT_ASSERT_INTEGER_DIV, hint_assert_integer_div); 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..b92135d --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/utils/carry.rs @@ -0,0 +1,51 @@ +use crate::hints::{Hint, HINTS}; +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 linkme::distributed_slice; +use num_bigint::BigUint; +use std::collections::HashMap; + +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"; + +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(()) +} + +#[distributed_slice(HINTS)] +static _HINT_CARRY: Hint = (HINT_CARRY, hint_carry); 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..dec8418 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/utils/divmod.rs @@ -0,0 +1,67 @@ +use crate::hints::{Hint, HINTS}; +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 linkme::distributed_slice; +use starknet_types_core::felt::NonZeroFelt; +use std::collections::HashMap; + +const FELT_8: Felt252 = Felt252::from_hex_unchecked("0x08"); + +const HINT_VALUE_DIV32: &str = "ids.q, ids.r = divmod(ids.value, ids.DIV_32)"; + +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 = utils::get_value("DIV_32", vm, hint_data)?; + + 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) +} + +#[distributed_slice(HINTS)] +static _HINT_VALUE_DIV32: Hint = (HINT_VALUE_DIV32, hint_value_div32); + +const HINT_VALUE_8: &str = "ids.q, ids.r = divmod(ids.value, 8)"; + +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) +} + +#[distributed_slice(HINTS)] +static _HINT_VALUE_8: Hint = (HINT_VALUE_8, hint_value_8); + +const HINT_VALUE_DIV: &str = "ids.q, ids.r = divmod(ids.value, ids.div)"; + +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) +} + +#[distributed_slice(HINTS)] +static _HINT_VALUE_DIV: Hint = (HINT_VALUE_DIV, hint_value_div); 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..fe867e3 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/utils/mod.rs @@ -0,0 +1,5 @@ +mod assert; +mod carry; +mod divmod; +mod trailing_zeroes; +mod write; 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..94c53b6 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/utils/trailing_zeroes.rs @@ -0,0 +1,32 @@ +use crate::hints::{Hint, HINTS}; +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 linkme::distributed_slice; +use std::collections::HashMap; + +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)"; + +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(()) +} + +#[distributed_slice(HINTS)] +static _HINT_TRAILING_ZEROES_BYTES: Hint = (HINT_TRAILING_ZEROES_BYTES, hint_trailing_zeroes_bytes); 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..22935c4 --- /dev/null +++ b/cairo_vm_hints/src/hints/lib/utils/write.rs @@ -0,0 +1,135 @@ +use crate::hints::{Hint, HINTS}; +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 linkme::distributed_slice; +use std::collections::HashMap; + +const HINT_WRITE_2: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 2, memory, ap)"; + +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().take(2).enumerate() { + vm.insert_value((ap + idx)?, MaybeRelocatable::Int(byte.into())) + .map_err(HintError::Memory)?; + } + + Ok(()) +} + +#[distributed_slice(HINTS)] +static _HINT_WRITE_2: Hint = (HINT_WRITE_2, hint_write_2); + +const HINT_WRITE_3: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 3, memory, ap)"; + +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().take(3).enumerate() { + vm.insert_value((ap + idx)?, MaybeRelocatable::Int(byte.into())) + .map_err(HintError::Memory)?; + } + + Ok(()) +} + +#[distributed_slice(HINTS)] +static _HINT_WRITE_3: Hint = (HINT_WRITE_3, hint_write_3); + +const HINT_WRITE_4: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 4, memory, ap)"; + +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().take(4).enumerate() { + vm.insert_value((ap + idx)?, MaybeRelocatable::Int(byte.into())) + .map_err(HintError::Memory)?; + } + + Ok(()) +} + +#[distributed_slice(HINTS)] +static _HINT_WRITE_4: Hint = (HINT_WRITE_4, hint_write_4); + +const HINT_WRITE_5: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 5, memory, ap)"; + +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().take(5).enumerate() { + vm.insert_value((ap + idx)?, MaybeRelocatable::Int(byte.into())) + .map_err(HintError::Memory)?; + } + + Ok(()) +} + +#[distributed_slice(HINTS)] +static _HINT_WRITE_5: Hint = (HINT_WRITE_5, hint_write_5); + +const HINT_WRITE_6: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 6, memory, ap)"; + +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().take(6).enumerate() { + vm.insert_value((ap + idx)?, MaybeRelocatable::Int(byte.into())) + .map_err(HintError::Memory)?; + } + + Ok(()) +} + +#[distributed_slice(HINTS)] +static _HINT_WRITE_6: Hint = (HINT_WRITE_6, hint_write_6); + +const HINT_WRITE_7: &str = "from tools.py.hints import write_word_to_memory\nwrite_word_to_memory(ids.word, 7, memory, ap)"; + +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().take(7).enumerate() { + vm.insert_value((ap + idx)?, MaybeRelocatable::Int(byte.into())) + .map_err(HintError::Memory)?; + } + + Ok(()) +} + +#[distributed_slice(HINTS)] +static _HINT_WRITE_7: Hint = (HINT_WRITE_7, hint_write_7); diff --git a/cairo_vm_hints/src/hints/mod.rs b/cairo_vm_hints/src/hints/mod.rs index 96dc618..597a831 100644 --- a/cairo_vm_hints/src/hints/mod.rs +++ b/cairo_vm_hints/src/hints/mod.rs @@ -1,8 +1,38 @@ -pub mod bit_length_mmr; -pub mod bit_length_x; -pub mod mmr_left_child; -pub mod test_construct_mmr; -pub mod test_is_valid_mmr_size_generate_random; -pub mod test_is_valid_mmr_size_generate_sequential; -pub mod test_is_valid_mmr_size_print_1; -pub mod test_is_valid_mmr_size_print_2; +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 linkme::distributed_slice; +use std::collections::HashMap; + +mod lib; +mod tests; + +type Hint = ( + &'static str, + fn( + vm: &mut VirtualMachine, + exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + constants: &HashMap, + ) -> Result<(), HintError>, +); + +#[distributed_slice] +pub static HINTS: [Hint]; + +pub fn run_hint( + vm: &mut VirtualMachine, + exec_scope: &mut ExecutionScopes, + hint_data: &HintProcessorData, + constants: &HashMap, +) -> Result<(), HintError> { + for (hint_str, hint_func) in HINTS { + if hint_data.code == *hint_str { + return hint_func(vm, exec_scope, hint_data, constants); + } + } + Err(HintError::UnknownHint(hint_data.code.as_str().into())) +} diff --git a/cairo_vm_hints/src/hints/test_is_valid_mmr_size_generate_random.rs b/cairo_vm_hints/src/hints/test_is_valid_mmr_size_generate_random.rs deleted file mode 100644 index 91a5053..0000000 --- a/cairo_vm_hints/src/hints/test_is_valid_mmr_size_generate_random.rs +++ /dev/null @@ -1,84 +0,0 @@ -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, get_ptr_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 rand::{thread_rng, Rng}; -use starknet_types_core::felt::Felt; -use std::collections::HashMap; - -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 TEST_IS_VALID_MMR_SIZE_GENERATE_RANDOM: &str = "from tools.py.mmr import is_valid_mmr_size -import random -print(f\"Testing is_valid_mmr_size against python implementation with {ids.num_sizes} random sizes in [0, 20000000)...\") -sizes_to_test = random.sample(range(0, 20000000), ids.num_sizes) -expected_output = [is_valid_mmr_size(size) for size in sizes_to_test] -segments.write_arg(ids.expected_output, expected_output) -segments.write_arg(ids.input_array, sizes_to_test)"; - -pub fn test_is_valid_mmr_size_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_integer_from_var_name("num_sizes", vm, &hint_data.ids_data, &hint_data.ap_tracking)? - .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())); - } - - let expected_output_ptr = get_ptr_from_var_name( - "expected_output", - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - )?; - - let input_array_ptr = get_ptr_from_var_name( - "input_array", - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - )?; - - vm.segments.load_data(input_array_ptr, &input_array)?; - vm.segments - .load_data(expected_output_ptr, &expected_output)?; - - Ok(()) -} diff --git a/cairo_vm_hints/src/hints/test_is_valid_mmr_size_generate_sequential.rs b/cairo_vm_hints/src/hints/test_is_valid_mmr_size_generate_sequential.rs deleted file mode 100644 index f3e458a..0000000 --- a/cairo_vm_hints/src/hints/test_is_valid_mmr_size_generate_sequential.rs +++ /dev/null @@ -1,77 +0,0 @@ -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, get_ptr_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, HashSet}; - -pub const TEST_IS_VALID_MMR_SIZE_GENERATE_SEQUENTIAL: &str = "print(f\"Testing is_valid_mmr_size by creating the mmr for all sizes in [0, {ids.num_elems})...\") -from tools.py.mmr import MMR -mmr = MMR() -valid_mmr_sizes = set() -for i in range(ids.num_elems): - mmr.add(i) - valid_mmr_sizes.add(len(mmr.pos_hash)) - -expected_output = [size in valid_mmr_sizes for size in range(0, len(mmr.pos_hash) + 1)] -for out, inp in zip(expected_output, range(0, len(mmr.pos_hash) + 1)): - print(out, inp) -segments.write_arg(ids.expected_output, expected_output) -segments.write_arg(ids.input_array, list(range(0, len(mmr.pos_hash) + 1)))"; - -pub fn test_is_valid_mmr_size_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_integer_from_var_name("num_elems", vm, &hint_data.ids_data, &hint_data.ap_tracking)? - .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::>(); - - let expected_output_ptr = get_ptr_from_var_name( - "expected_output", - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - )?; - - let input_array_ptr = get_ptr_from_var_name( - "input_array", - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - )?; - - vm.segments.load_data(input_array_ptr, &input_array)?; - vm.segments - .load_data(expected_output_ptr, &expected_output)?; - - Ok(()) -} diff --git a/cairo_vm_hints/src/hints/test_is_valid_mmr_size_print_1.rs b/cairo_vm_hints/src/hints/test_is_valid_mmr_size_print_1.rs deleted file mode 100644 index b18c0d4..0000000 --- a/cairo_vm_hints/src/hints/test_is_valid_mmr_size_print_1.rs +++ /dev/null @@ -1,17 +0,0 @@ -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 TEST_IS_VALID_MMR_SIZE_PRINT_1: &str = "print('\\n')"; - -pub fn test_is_valid_mmr_size_print_1( - _vm: &mut VirtualMachine, - _exec_scope: &mut ExecutionScopes, - _hint_data: &HintProcessorData, - _constants: &HashMap, -) -> Result<(), HintError> { - println!("\n"); - Ok(()) -} diff --git a/cairo_vm_hints/src/hints/test_is_valid_mmr_size_print_2.rs b/cairo_vm_hints/src/hints/test_is_valid_mmr_size_print_2.rs deleted file mode 100644 index 287b775..0000000 --- a/cairo_vm_hints/src/hints/test_is_valid_mmr_size_print_2.rs +++ /dev/null @@ -1,17 +0,0 @@ -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 TEST_IS_VALID_MMR_SIZE_PRINT_2: &str = "print(f\"\\tPass!\\n\\n\")"; - -pub fn test_is_valid_mmr_size_print_2( - _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/hints/test_construct_mmr.rs b/cairo_vm_hints/src/hints/tests/construct_mmr.rs similarity index 68% rename from cairo_vm_hints/src/hints/test_construct_mmr.rs rename to cairo_vm_hints/src/hints/tests/construct_mmr.rs index faea0fa..bb37511 100644 --- a/cairo_vm_hints/src/hints/test_construct_mmr.rs +++ b/cairo_vm_hints/src/hints/tests/construct_mmr.rs @@ -1,18 +1,18 @@ -use crate::mmr::{Hasher, Keccak, Mmr, Poseidon}; +use crate::hints::{Hint, HINTS}; +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::hint_processor::builtin_hint_processor::hint_utils::{ - get_ptr_from_var_name, get_relocatable_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 linkme::distributed_slice; 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 +const TEST_CONSTRUCT_MMR: &str = "import random from tools.py.mmr import get_peaks, MMR, PoseidonHasher, KeccakHasher STARK_PRIME = 3618502788666131213697322783095070105623107215331596699973092056135872020481 @@ -78,14 +78,7 @@ 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)"; -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 test_construct_mmr( +fn test_construct_mmr( vm: &mut VirtualMachine, _exec_scope: &mut ExecutionScopes, hint_data: &HintProcessorData, @@ -106,13 +99,7 @@ pub fn test_construct_mmr( let previous_n_values = rng.gen_range(1..=200); let n_values_to_append = rng.gen_range(1..=200); - insert_value_from_var_name( - "n_values_to_append", - n_values_to_append, - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - )?; + 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)) @@ -121,31 +108,24 @@ pub fn test_construct_mmr( .map(|_| rng.gen_biguint_range(&BigUint::one(), &two_pow_256)) .collect::>(); - vm.segments.load_data( - get_ptr_from_var_name( - "poseidon_hash_array", - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - )?, + write_vector( + "poseidon_hash_array", &poseidon_hash_array .iter() .map(|x| MaybeRelocatable::Int(x.into())) .collect::>(), + vm, + hint_data, )?; - vm.segments.load_data( - get_ptr_from_var_name( - "keccak_hash_array", - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - )?, + write_vector( + "keccak_hash_array", &keccak_hash_array .iter() - .map(|x| split_u256(x)) - .flatten() + .flat_map(split_u256) .map(|x| MaybeRelocatable::Int(x.into())) .collect::>(), + vm, + hint_data, )?; let mut mmr_poseidon = Mmr::::new(); @@ -159,63 +139,44 @@ pub fn test_construct_mmr( .map(|_| rng.gen_biguint_range(&BigUint::one(), &two_pow_256)) .for_each(|x| mmr_keccak.append(x)); - insert_value_from_var_name( - "mmr_offset", - mmr_poseidon.size(), - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - )?; + 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()); - vm.segments.load_data( - get_ptr_from_var_name( - "previous_peaks_values_poseidon", - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - )?, + write_vector( + "previous_peaks_values_poseidon", &previous_peaks_poseidon .iter() .map(|x| MaybeRelocatable::Int(x.into())) .collect::>(), + vm, + hint_data, )?; - - vm.segments.load_data( - get_ptr_from_var_name( - "previous_peaks_values_keccak", - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - )?, + write_vector( + "previous_peaks_values_keccak", &previous_peaks_keccak .iter() - .map(|x| split_u256(&x)) - .flatten() + .flat_map(split_u256) .map(|x| MaybeRelocatable::Int(x.into())) .collect::>(), + vm, + hint_data, )?; - - insert_value_from_var_name( + write_value( "mmr_last_root_poseidon", - MaybeRelocatable::Int(mmr_poseidon.get_root().try_into().unwrap()), + MaybeRelocatable::Int(mmr_poseidon.get_root().into()), vm, - &hint_data.ids_data, - &hint_data.ap_tracking, + hint_data, )?; - vm.segments.load_data( - get_relocatable_from_var_name( - "mmr_last_root_keccak", - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - )?, + write_struct( + "mmr_last_root_keccak", &split_u256(&mmr_keccak.get_root()) .iter() - .map(|x| MaybeRelocatable::Int(x.try_into().unwrap())) + .map(|x| MaybeRelocatable::Int(x.into())) .collect::>(), + vm, + hint_data, )?; for elem in poseidon_hash_array.iter().rev() { @@ -225,32 +186,25 @@ pub fn test_construct_mmr( mmr_keccak.append(elem.clone()); } - insert_value_from_var_name( + write_value( "expected_new_root_poseidon", - MaybeRelocatable::Int(mmr_poseidon.get_root().try_into().unwrap()), + MaybeRelocatable::Int(mmr_poseidon.get_root().into()), vm, - &hint_data.ids_data, - &hint_data.ap_tracking, + hint_data, )?; - vm.segments.load_data( - get_relocatable_from_var_name( - "expected_new_root_keccak", - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - )?, + write_struct( + "expected_new_root_keccak", &split_u256(&mmr_keccak.get_root()) .iter() - .map(|x| MaybeRelocatable::Int(x.try_into().unwrap())) + .map(|x| MaybeRelocatable::Int(x.into())) .collect::>(), - )?; - insert_value_from_var_name( - "expected_new_len", - mmr_keccak.size(), vm, - &hint_data.ids_data, - &hint_data.ap_tracking, + hint_data, )?; + write_value("expected_new_len", mmr_keccak.size(), vm, hint_data)?; Ok(()) } + +#[distributed_slice(HINTS)] +static _TEST_CONSTRUCT_MMR: Hint = (TEST_CONSTRUCT_MMR, test_construct_mmr); 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..6bfea04 --- /dev/null +++ b/cairo_vm_hints/src/hints/tests/dw_hack.rs @@ -0,0 +1,95 @@ +use crate::hints::{Hint, HINTS}; +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 linkme::distributed_slice; +use std::collections::HashMap; + +const HINT_BIT_LENGTH_ASSIGN_140: &str = "ids.bit_length = 140"; + +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(()) +} + +#[distributed_slice(HINTS)] +static _HINT_BIT_LENGTH_ASSIGN_140: Hint = (HINT_BIT_LENGTH_ASSIGN_140, hint_bit_length_assign_140); + +const HINT_BIT_LENGTH_ASSIGN_NEGATIVE_ONE: &str = "ids.bit_length = -1"; + +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(()) +} + +#[distributed_slice(HINTS)] +static _HINT_BIT_LENGTH_ASSIGN_NEGATIVE_ONE: Hint = ( + HINT_BIT_LENGTH_ASSIGN_NEGATIVE_ONE, + hint_bit_length_assign_negative_one, +); + +const HINT_BIT_LENGTH_ASSIGN_2500: &str = "ids.bit_length = 2500"; + +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(()) +} + +#[distributed_slice(HINTS)] +static _HINT_BIT_LENGTH_ASSIGN_2500: Hint = + (HINT_BIT_LENGTH_ASSIGN_2500, hint_bit_length_assign_2500); + +const HINT_PRINT_NS: &str = "print(\"N\", ids.N, \"n\", ids.n)"; + +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(()) +} + +#[distributed_slice(HINTS)] +static _HINT_PRINT_NS: Hint = (HINT_PRINT_NS, hint_print_ns); 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..4fa4221 --- /dev/null +++ b/cairo_vm_hints/src/hints/tests/encode_packed_256.rs @@ -0,0 +1,103 @@ +use crate::hints::{Hint, HINTS}; +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 linkme::distributed_slice; +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() +} + +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)"; + +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(()) +} + +#[distributed_slice(HINTS)] +static _HINT_GENERATE_TEST_VECTOR: Hint = (HINT_GENERATE_TEST_VECTOR, hint_generate_test_vector); 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..610ade5 --- /dev/null +++ b/cairo_vm_hints/src/hints/tests/mmr_size_generate.rs @@ -0,0 +1,105 @@ +use crate::hints::{Hint, HINTS}; +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 linkme::distributed_slice; +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 +} + +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)"; + +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(()) +} + +#[distributed_slice(HINTS)] +static _HINT_GENERATE_RANDOM: Hint = (HINT_GENERATE_RANDOM, hint_generate_random); + +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)))"; + +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(()) +} + +#[distributed_slice(HINTS)] +static _HINT_GENERATE_SEQUENTIAL: Hint = (HINT_GENERATE_SEQUENTIAL, hint_generate_sequential); 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..02e63ff --- /dev/null +++ b/cairo_vm_hints/src/hints/tests/mod.rs @@ -0,0 +1,5 @@ +mod construct_mmr; +mod dw_hack; +mod encode_packed_256; +mod mmr_size_generate; +mod print; 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..59c150f --- /dev/null +++ b/cairo_vm_hints/src/hints/tests/print.rs @@ -0,0 +1,37 @@ +use crate::hints::{Hint, HINTS}; +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 linkme::distributed_slice; +use std::collections::HashMap; + +const HINT_PRINT_BREAKLINE: &str = "print('\\n')"; + +fn hint_print_breakline( + _vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + _hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + println!("\n"); + Ok(()) +} + +#[distributed_slice(HINTS)] +static _HINT_PRINT_BREAKLINE: Hint = (HINT_PRINT_BREAKLINE, hint_print_breakline); + +const HINT_PRINT_PASS: &str = "print(f\"\\tPass!\\n\\n\")"; + +fn hint_print_pass( + _vm: &mut VirtualMachine, + _exec_scope: &mut ExecutionScopes, + _hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + println!("\tPass!\n\n"); + Ok(()) +} + +#[distributed_slice(HINTS)] +static _HINT_PRINT_PASS: Hint = (HINT_PRINT_PASS, hint_print_pass); diff --git a/cairo_vm_hints/src/lib.rs b/cairo_vm_hints/src/lib.rs index cc8b8af..728f163 100644 --- a/cairo_vm_hints/src/lib.rs +++ b/cairo_vm_hints/src/lib.rs @@ -1,3 +1,10 @@ pub mod hint_processor; pub mod hints; pub mod mmr; +pub mod utils; + +pub use hint_processor::{CustomHintProcessor, ExtendedHintProcessor}; +pub use hints::run_hint; + +#[cfg(test)] +pub mod tests; diff --git a/cairo_vm_hints/src/mmr.rs b/cairo_vm_hints/src/mmr.rs index 37477cf..06ae142 100644 --- a/cairo_vm_hints/src/mmr.rs +++ b/cairo_vm_hints/src/mmr.rs @@ -41,7 +41,7 @@ impl Hasher for Poseidon { } fn hash(&self, x: &BigUint, y: &BigUint) -> BigUint { - poseidon_hash(x.try_into().unwrap(), y.try_into().unwrap()).to_biguint() + poseidon_hash(x.into(), y.into()).to_biguint() } } @@ -52,6 +52,12 @@ pub struct Mmr { leaf_count: usize, } +impl Default for Mmr { + fn default() -> Self { + Self::new() + } +} + impl Mmr { pub fn new() -> Mmr { Mmr { @@ -102,7 +108,7 @@ impl Mmr { 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); + last_node = self.hasher.hash(peak, &last_node); self.nodes.push(last_node.clone()); } } 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/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