From ef0ee41bce3379d084ce5d930383b5502eee6646 Mon Sep 17 00:00:00 2001 From: greged93 <82421016+greged93@users.noreply.github.com> Date: Fri, 12 Jan 2024 16:12:25 +0100 Subject: [PATCH 1/7] dev: bump cairo 1 compiler dep to 2.4 (#1530) * bump cairo 1 compiler dep to 2.4 * changelog * update compiler to 2.4.2 * bump compiler to 2.4.2 in Makefile * fix incorrect offset in program --- CHANGELOG.md | 2 + Cargo.lock | 118 ++++++++++-------- Cargo.toml | 14 +-- Makefile | 2 +- cairo1-run/Makefile | 3 +- cairo1-run/src/main.rs | 7 +- .../cairo_1_run_from_entrypoint_tests.rs | 2 +- 7 files changed, 82 insertions(+), 66 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1f9aa3816..ddc963ad6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ #### Upcoming Changes +* dev: bump cairo 1 compiler dep to 2.4 [#1530](https://github.com/lambdaclass/cairo-vm/pull/1530) + #### [1.0.0-rc0] - 2024-1-5 * feat: Use `ProjectivePoint` from types-rs in ec_op builtin impl [#1532](https://github.com/lambdaclass/cairo-vm/pull/1532) diff --git a/Cargo.lock b/Cargo.lock index e98ee2cd91..7b162d25f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -284,9 +284,9 @@ dependencies = [ [[package]] name = "cairo-lang-casm" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cca7891c0df31a87740acbcda3f3c04e6516e283b67842386873f3a181fd91" +checksum = "24abd6752c41f3d2276fba63fa0434875ccf6e7cbcdebfebc790db1201eb0892" dependencies = [ "cairo-lang-utils", "indoc", @@ -301,9 +301,9 @@ dependencies = [ [[package]] name = "cairo-lang-compiler" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8c4bd031bf62046af88e75b86f419ad7e2317c3b7ee26cbad367f2ff2f2bfa4" +checksum = "5699f44b183ddc2982976efdd72bbdfafc13a64f9593b44eb86f8a335f3b90da" dependencies = [ "anyhow", "cairo-lang-defs", @@ -311,7 +311,6 @@ dependencies = [ "cairo-lang-filesystem", "cairo-lang-lowering", "cairo-lang-parser", - "cairo-lang-plugins", "cairo-lang-project", "cairo-lang-semantic", "cairo-lang-sierra", @@ -325,18 +324,18 @@ dependencies = [ [[package]] name = "cairo-lang-debug" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "954529b40c914ff089bd06b4cdfa3b51f39fb8769a6f9af92ba745e4a1300bd4" +checksum = "0a52b381fab22b723818692fa93aafc2e1490a79a4c8bd856e8996f1253f16a8" dependencies = [ "cairo-lang-utils", ] [[package]] name = "cairo-lang-defs" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2ab80b21943392da07b2ee54f1f7e15ac783ea1567ed27bd4682774713f7ee" +checksum = "9d436dcaa5a3ea69f60b990036d23dc3e54adc623c14cff824cb1230f974ce44" dependencies = [ "cairo-lang-debug", "cairo-lang-diagnostics", @@ -351,9 +350,9 @@ dependencies = [ [[package]] name = "cairo-lang-diagnostics" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07052c58dc014904bfecc6fb253a0461bbdcdd3ac41f1385ac9fba5ef9a0da61" +checksum = "07771c7268044b6a7be828a4f4938bb823944efe6668a974bf5e52a6801ef366" dependencies = [ "cairo-lang-debug", "cairo-lang-filesystem", @@ -363,9 +362,9 @@ dependencies = [ [[package]] name = "cairo-lang-eq-solver" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac351e6a4af689df90119d95d8fa9441b8ad1b2eef6f4868ed7a1c1808f786c" +checksum = "53fc8c224c0aaadc01c961fac234e8d8d3563a8fbb8544186a69969765a0c2a5" dependencies = [ "cairo-lang-utils", "good_lp", @@ -373,9 +372,9 @@ dependencies = [ [[package]] name = "cairo-lang-filesystem" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77f253875f0503f13d2a15e303db4f77a932a84600787a496938d0daf687945d" +checksum = "d62a519bd68f158cd1b5ee2f1f1dc2aa916a8dcb14914444846d39ff8fb33789" dependencies = [ "cairo-lang-debug", "cairo-lang-utils", @@ -387,9 +386,9 @@ dependencies = [ [[package]] name = "cairo-lang-lowering" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aa602a50c7d216beb4c261036b024b24f90ce6724d623f1b23f56076584473c" +checksum = "989744e09f351ff24a0bc076dba8e3420ab957b99edc46acde58a484ebb09ed9" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", @@ -408,13 +407,14 @@ dependencies = [ "num-traits 0.2.17", "once_cell", "salsa", + "smol_str", ] [[package]] name = "cairo-lang-parser" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b25e847ef219635b837cbfd8eed797a7aa6a4b01e1775065cff67b1d5bfda1fe" +checksum = "7be5b262ae2d11b4d5783a8b66d8e31cbeab45bb4e14d6ddb13ba280e9c41824" dependencies = [ "cairo-lang-diagnostics", "cairo-lang-filesystem", @@ -432,9 +432,9 @@ dependencies = [ [[package]] name = "cairo-lang-plugins" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c109f0b788a95bb86cff0e3917e1ce7d75210020fc53904d2a5e3ba54728adb" +checksum = "ebcfe1e269ab2027bad187d9c61c7e1e324374c722b75f3a7d7fba77c977f8ca" dependencies = [ "cairo-lang-defs", "cairo-lang-diagnostics", @@ -451,9 +451,9 @@ dependencies = [ [[package]] name = "cairo-lang-proc-macros" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2bbbfe1934e11fe3cce4f23cdccd22341ed63af5d76e593234288dd4ba06f56" +checksum = "f9bc4f93f28bda29d879acb9b9e26b32108591225a507ffb5aff9bbf58524c4f" dependencies = [ "cairo-lang-debug", "quote", @@ -462,9 +462,9 @@ dependencies = [ [[package]] name = "cairo-lang-project" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2ba814a9dd17b1341204d8e7bb67775aadebc5138a475bdf176dff0f11999cb" +checksum = "b3d490a3d00dd45228c1691c390f177449b45a907a2cb4b3ad8f305faea82a0c" dependencies = [ "cairo-lang-filesystem", "cairo-lang-utils", @@ -476,19 +476,21 @@ dependencies = [ [[package]] name = "cairo-lang-semantic" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19678648e0efec3f837c0d75b6071bc2afe5c4bc611e177381478c023b72a74c" +checksum = "4bcc25adf813972129dcac6c7d87026d47644f3d4e975c042d27e1166a2a0489" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", "cairo-lang-diagnostics", "cairo-lang-filesystem", "cairo-lang-parser", + "cairo-lang-plugins", "cairo-lang-proc-macros", "cairo-lang-syntax", "cairo-lang-utils", "id-arena", + "indoc", "itertools 0.11.0", "num-bigint", "num-traits 0.2.17", @@ -499,9 +501,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b7d09f0b7461701a9ba5d7a2260551b5026cd8f6efc6ca9ca270f6c0a6fd23" +checksum = "8cc9571dbb143e33979fc02d38bbb4d7b608d6f53cde585b08551bbedfb0c217" dependencies = [ "anyhow", "cairo-lang-utils", @@ -516,6 +518,7 @@ dependencies = [ "regex", "salsa", "serde", + "serde_json", "sha3", "smol_str", "thiserror", @@ -523,9 +526,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-ap-change" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e66740bcfadb365d488ff9c334f68cb4cb6a6cb9666ae12109fc6eee7371116" +checksum = "16894bfe0072f82b549e4b2be42c7dc8f0611ac5049dfb069b95b10c51ec7cb5" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", @@ -537,9 +540,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-gas" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac27c07af11fcdc9546a9c55c1463cb871fb5b7af1daa3cdf31cfb0872da3d88" +checksum = "71fbc8baef18b3c315d3fb7a0cf59f0ee14df5cefc7dd147598248cdb7b2252d" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", @@ -551,9 +554,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-generator" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456cd75547a127b8f4088216a419d317c753c6b9188e944846bf3a5193c14797" +checksum = "75700bf5fd1c1cdd8ca29af338c65de8b03c905472f9bdce22b3034f3f3755d9" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", @@ -565,6 +568,7 @@ dependencies = [ "cairo-lang-sierra", "cairo-lang-syntax", "cairo-lang-utils", + "indexmap 2.1.0", "itertools 0.11.0", "num-bigint", "once_cell", @@ -574,9 +578,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-to-casm" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da74c7c4a2df66b961a982396e0f5221d6594266aed48c76d8c22d5b0d96af5d" +checksum = "f0bc8edaf95bdb9577c6b801c36b24538ec08042e1d74b98fc08d50621427061" dependencies = [ "assert_matches", "cairo-felt", @@ -595,9 +599,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-type-size" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7fdf2dbda71f1ed4e4020914e7494ad32db84dbc75cc8dbf05c06caef678fc8" +checksum = "50b028f3e06e150005e82b07500d4ea509ee8350f841d5645fbcf00bb49c4537" dependencies = [ "cairo-lang-sierra", "cairo-lang-utils", @@ -605,9 +609,9 @@ dependencies = [ [[package]] name = "cairo-lang-starknet" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9217e979f11980609d13d3a5adea8438ec9345709ddfebca975cc9cd1f85201e" +checksum = "4f55ffe2cbd277b6f3040e23bde028ae0b68e8e4910a9dd1c2f78ed668974d2a" dependencies = [ "anyhow", "cairo-felt", @@ -636,14 +640,15 @@ dependencies = [ "serde_json", "sha3", "smol_str", + "starknet-crypto", "thiserror", ] [[package]] name = "cairo-lang-syntax" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d461d88e09ba7055822eb42d6b2c2ea38a4eaa5b9e4196d8f63db48c563fb56" +checksum = "c6d745c72ac1cef893239d36bc749742d2622136ffc1434a2c70b07096d02de0" dependencies = [ "cairo-lang-debug", "cairo-lang-filesystem", @@ -657,9 +662,9 @@ dependencies = [ [[package]] name = "cairo-lang-syntax-codegen" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9615745282c0c0d3a255c2ac2665a18ae1d163c54285014d85dacda2d5e53637" +checksum = "f7c9f119185b736b5318325e7a0fc1378b706116c1c558e1ced1bdf55367813b" dependencies = [ "genco", "xshell", @@ -667,9 +672,9 @@ dependencies = [ [[package]] name = "cairo-lang-utils" -version = "2.3.1" +version = "2.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15edcd2fba78af9b753614885464c9b5bf6041b7decba46587c2b0babc4197ac" +checksum = "343ac08a5b9d34c9f4bbac7249453a31edad4cf4ff54487197cc344f8293dc4f" dependencies = [ "indexmap 2.1.0", "itertools 0.11.0", @@ -1923,7 +1928,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ "once_cell", - "toml_edit", + "toml_edit 0.19.15", ] [[package]] @@ -2605,14 +2610,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.8" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.21.0", ] [[package]] @@ -2629,6 +2634,17 @@ name = "toml_edit" version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.1.0", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" dependencies = [ "indexmap 2.1.0", "serde", diff --git a/Cargo.toml b/Cargo.toml index c7e3269d38..426e992ca6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,14 +63,14 @@ thiserror-no-std = { version = "2.0.2", default-features = false } bitvec = { version = "1", default-features = false, features = ["alloc"] } # Dependencies for cairo-1-hints feature -cairo-lang-starknet = { version = "2.3.1", default-features = false } -cairo-lang-casm = { version = "2.3.1", default-features = false } +cairo-lang-starknet = { version = "2.4.2", default-features = false } +cairo-lang-casm = { version = "2.4.2", default-features = false } -cairo-lang-compiler = { version = "2.3.1", default-features = false } -cairo-lang-sierra-to-casm = { version = "2.3.1", default-features = false } -cairo-lang-sierra = { version = "2.3.1", default-features = false } -cairo-lang-runner = { version = "2.3.1", default-features = false } -cairo-lang-utils = { version = "2.3.1", default-features = false } +cairo-lang-compiler = { version = "2.4.2", default-features = false } +cairo-lang-sierra-to-casm = { version = "2.4.2", default-features = false } +cairo-lang-sierra = { version = "2.4.2", default-features = false } +cairo-lang-runner = { version = "2.4.2", default-features = false } +cairo-lang-utils = { version = "2.4.2", default-features = false } # TODO: check these dependencies for wasm compatibility ark-ff = { version = "0.4.2", default-features = false } diff --git a/Makefile b/Makefile index bf17e6743a..97944aae8e 100644 --- a/Makefile +++ b/Makefile @@ -164,7 +164,7 @@ $(CAIRO_2_CONTRACTS_TEST_DIR)/%.casm: $(CAIRO_2_CONTRACTS_TEST_DIR)/%.sierra # ====================== CAIRO_2_REPO_DIR = cairo2 -CAIRO_2_VERSION = 2.1.0-rc1 +CAIRO_2_VERSION = 2.4.2 build-cairo-2-compiler-macos: @if [ ! -d "$(CAIRO_2_REPO_DIR)" ]; then \ diff --git a/cairo1-run/Makefile b/cairo1-run/Makefile index 337cf3a53e..26b9b9341a 100644 --- a/cairo1-run/Makefile +++ b/cairo1-run/Makefile @@ -15,7 +15,7 @@ MEMORY:=$(patsubst $(CAIRO_1_FOLDER)/%.cairo, $(CAIRO_1_FOLDER)/%.memory, $(CAIR deps: git clone https://github.com/starkware-libs/cairo.git \ && cd cairo \ - && git checkout v2.3.1 \ + && git checkout v2.4.2 \ && cd .. \ && mv cairo/corelib/ . \ && rm -rf cairo/ @@ -30,4 +30,3 @@ clean: rm -rf cairo rm -rf ../cairo_programs/cairo-1-programs/*.memory rm -rf ../cairo_programs/cairo-1-programs/*.trace - diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index 2518d2af6e..0b4056ea7b 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -176,9 +176,8 @@ fn run(args: impl Iterator) -> Result, Erro replace_ids: true, ..CompilerConfig::default() }; - let sierra_program = (*compile_cairo_project_at_path(&args.filename, compiler_config) - .map_err(|err| Error::SierraCompilation(err.to_string()))?) - .clone(); + let sierra_program = compile_cairo_project_at_path(&args.filename, compiler_config) + .map_err(|err| Error::SierraCompilation(err.to_string()))?; let metadata_config = Some(Default::default()); @@ -577,7 +576,7 @@ fn create_metadata( metadata_config: Option, ) -> Result { if let Some(metadata_config) = metadata_config { - calc_metadata(sierra_program, metadata_config, false).map_err(|err| match err { + calc_metadata(sierra_program, metadata_config).map_err(|err| match err { MetadataError::ApChangeError(_) => VirtualMachineError::Unexpected, MetadataError::CostError(_) => VirtualMachineError::Unexpected, }) diff --git a/vm/src/tests/cairo_1_run_from_entrypoint_tests.rs b/vm/src/tests/cairo_1_run_from_entrypoint_tests.rs index c424dfec5e..4c5bf3fd50 100644 --- a/vm/src/tests/cairo_1_run_from_entrypoint_tests.rs +++ b/vm/src/tests/cairo_1_run_from_entrypoint_tests.rs @@ -39,7 +39,7 @@ fn test_uint256_div_mod_hint() { run_cairo_1_entrypoint( program_data.as_slice(), - 107, + 104, &[36_usize.into(), 2_usize.into()], &[Felt252::from(18_usize)], ); From 8b9aabe90c190beda5d3796fc7d1ef5bb1afb1ff Mon Sep 17 00:00:00 2001 From: Pedro Fontana Date: Mon, 15 Jan 2024 11:50:19 -0300 Subject: [PATCH 2/7] Remove flamegraph from cargo deps (#1554) * Remove cargo-deps from make deps * Restore Makefile * Remove Flamegraph from cargo deps * Comment lines --- Makefile | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 97944aae8e..47f0f36e23 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ ifndef PROPTEST_CASES endif .PHONY: build-cairo-1-compiler build-cairo-1-compiler-macos build-cairo-2-compiler build-cairo-2-compiler-macos \ - deps deps-macos cargo-deps build run check test clippy coverage benchmark flamegraph \ + deps deps-macos cargo-deps build run check test clippy coverage benchmark \ compare_benchmarks_deps compare_benchmarks docs clean \ compare_vm_output compare_trace_memory compare_trace compare_memory \ compare_trace_memory_proof compare_all_proof compare_trace_proof compare_memory_proof compare_air_public_input \ @@ -183,7 +183,8 @@ build-cairo-2-compiler: cargo-deps: cargo install --version 0.3.1 iai-callgrind-runner cargo install --version 1.1.0 cargo-criterion - cargo install --version 0.6.1 flamegraph + # Temporarily removed due to version issues. Installing cargo flamegraph pumps an error in rust 1.70 + # cargo install --version 0.6.1 flamegraph cargo install --version 1.14.0 hyperfine cargo install --version 0.9.49 cargo-nextest cargo install --version 0.5.9 cargo-llvm-cov @@ -269,8 +270,9 @@ benchmark-action: cairo_bench_programs iai-benchmark-action: cairo_bench_programs cargo bench --bench iai_benchmark -flamegraph: - cargo flamegraph --root --bench criterion_benchmark -- --bench +# Temporarily removed due to version issues. Installing cargo flamegraph pumps an error in rust 1.70 +# flamegraph: +# cargo flamegraph --root --bench criterion_benchmark -- --bench compare_benchmarks: cairo_bench_programs cd bench && ./run_benchmarks.sh From e1ddf6195f48ffd6a7845b5d2296c3c9b533d7ea Mon Sep 17 00:00:00 2001 From: fmoletta <99273364+fmoletta@users.noreply.github.com> Date: Mon, 15 Jan 2024 17:31:42 +0200 Subject: [PATCH 3/7] Update proof_programs symlinks (#1555) --- cairo_programs/proof_programs/_keccak_alternative_hint.cairo | 1 + cairo_programs/proof_programs/assert_le_felt_old.cairo | 1 + cairo_programs/proof_programs/bigint.cairo | 1 + cairo_programs/proof_programs/bitand_hint.cairo | 1 + .../proof_programs/cairo_finalize_keccak_block_size_1000.cairo | 1 + cairo_programs/proof_programs/chained_ec_op.cairo | 1 + cairo_programs/proof_programs/common_signature.cairo | 1 + cairo_programs/proof_programs/compute_doubling_slope_v2.cairo | 1 + cairo_programs/proof_programs/compute_slope_v2.cairo | 1 + cairo_programs/proof_programs/dict_store_cast_ptr.cairo | 1 + cairo_programs/proof_programs/div_mod_n.cairo | 1 + cairo_programs/proof_programs/ec_double_assign_new_x_v3.cairo | 1 + cairo_programs/proof_programs/ec_double_slope.cairo | 1 + cairo_programs/proof_programs/ec_double_v4.cairo | 1 + cairo_programs/proof_programs/ec_negate.cairo | 1 + cairo_programs/proof_programs/ec_op.cairo | 1 + cairo_programs/proof_programs/ec_recover.cairo | 1 + cairo_programs/proof_programs/ed25519_ec.cairo | 1 + cairo_programs/proof_programs/ed25519_field.cairo | 1 + cairo_programs/proof_programs/efficient_secp256r1_ec.cairo | 1 + cairo_programs/proof_programs/example_blake2s.cairo | 1 + cairo_programs/proof_programs/example_program.cairo | 1 + cairo_programs/proof_programs/fast_ec_add_v2.cairo | 1 + cairo_programs/proof_programs/fast_ec_add_v3.cairo | 1 + cairo_programs/proof_programs/field_arithmetic.cairo | 1 + cairo_programs/proof_programs/finalize_blake2s_v2_hint.cairo | 1 + cairo_programs/proof_programs/fq.cairo | 1 + cairo_programs/proof_programs/fq_test.cairo | 1 + cairo_programs/proof_programs/garaga.cairo | 1 + cairo_programs/proof_programs/highest_bitlen.cairo | 1 + cairo_programs/proof_programs/if_reloc_equal.cairo | 1 + cairo_programs/proof_programs/inv_mod_p_uint512.cairo | 1 + cairo_programs/proof_programs/is_quad_residue_test.cairo | 1 + cairo_programs/proof_programs/is_zero.cairo | 1 + cairo_programs/proof_programs/is_zero_pack.cairo | 1 + cairo_programs/proof_programs/keccak_builtin.cairo | 1 + cairo_programs/proof_programs/keccak_uint256.cairo | 1 + cairo_programs/proof_programs/memory_holes.cairo | 1 + cairo_programs/proof_programs/mul_s_inv.cairo | 1 + cairo_programs/proof_programs/multiplicative_inverse.cairo | 1 + cairo_programs/proof_programs/n_bit.cairo | 1 + cairo_programs/proof_programs/nondet_bigint3_v2.cairo | 1 + cairo_programs/proof_programs/normalize_address.cairo | 1 + cairo_programs/proof_programs/packed_sha256_test.cairo | 1 + cairo_programs/proof_programs/poseidon_builtin.cairo | 1 + cairo_programs/proof_programs/poseidon_hash.cairo | 1 + cairo_programs/proof_programs/poseidon_multirun.cairo | 1 + cairo_programs/proof_programs/recover_y.cairo | 1 + cairo_programs/proof_programs/reduce.cairo | 1 + .../proof_programs/relocate_temporary_segment_append.cairo | 1 + .../proof_programs/relocate_temporary_segment_into_new.cairo | 1 + cairo_programs/proof_programs/secp256r1_div_mod_n.cairo | 1 + cairo_programs/proof_programs/secp256r1_fast_ec_add.cairo | 1 + cairo_programs/proof_programs/secp256r1_slope.cairo | 1 + cairo_programs/proof_programs/sha256_test.cairo | 1 + cairo_programs/proof_programs/split_xx_hint.cairo | 1 + cairo_programs/proof_programs/uint256_improvements.cairo | 1 + cairo_programs/proof_programs/uint384.cairo | 1 + cairo_programs/proof_programs/uint384_extension.cairo | 1 + cairo_programs/proof_programs/uint384_extension_test.cairo | 1 + cairo_programs/proof_programs/uint384_test.cairo | 1 + 61 files changed, 61 insertions(+) create mode 120000 cairo_programs/proof_programs/_keccak_alternative_hint.cairo create mode 120000 cairo_programs/proof_programs/assert_le_felt_old.cairo create mode 120000 cairo_programs/proof_programs/bigint.cairo create mode 120000 cairo_programs/proof_programs/bitand_hint.cairo create mode 120000 cairo_programs/proof_programs/cairo_finalize_keccak_block_size_1000.cairo create mode 120000 cairo_programs/proof_programs/chained_ec_op.cairo create mode 120000 cairo_programs/proof_programs/common_signature.cairo create mode 120000 cairo_programs/proof_programs/compute_doubling_slope_v2.cairo create mode 120000 cairo_programs/proof_programs/compute_slope_v2.cairo create mode 120000 cairo_programs/proof_programs/dict_store_cast_ptr.cairo create mode 120000 cairo_programs/proof_programs/div_mod_n.cairo create mode 120000 cairo_programs/proof_programs/ec_double_assign_new_x_v3.cairo create mode 120000 cairo_programs/proof_programs/ec_double_slope.cairo create mode 120000 cairo_programs/proof_programs/ec_double_v4.cairo create mode 120000 cairo_programs/proof_programs/ec_negate.cairo create mode 120000 cairo_programs/proof_programs/ec_op.cairo create mode 120000 cairo_programs/proof_programs/ec_recover.cairo create mode 120000 cairo_programs/proof_programs/ed25519_ec.cairo create mode 120000 cairo_programs/proof_programs/ed25519_field.cairo create mode 120000 cairo_programs/proof_programs/efficient_secp256r1_ec.cairo create mode 120000 cairo_programs/proof_programs/example_blake2s.cairo create mode 120000 cairo_programs/proof_programs/example_program.cairo create mode 120000 cairo_programs/proof_programs/fast_ec_add_v2.cairo create mode 120000 cairo_programs/proof_programs/fast_ec_add_v3.cairo create mode 120000 cairo_programs/proof_programs/field_arithmetic.cairo create mode 120000 cairo_programs/proof_programs/finalize_blake2s_v2_hint.cairo create mode 120000 cairo_programs/proof_programs/fq.cairo create mode 120000 cairo_programs/proof_programs/fq_test.cairo create mode 120000 cairo_programs/proof_programs/garaga.cairo create mode 120000 cairo_programs/proof_programs/highest_bitlen.cairo create mode 120000 cairo_programs/proof_programs/if_reloc_equal.cairo create mode 120000 cairo_programs/proof_programs/inv_mod_p_uint512.cairo create mode 120000 cairo_programs/proof_programs/is_quad_residue_test.cairo create mode 120000 cairo_programs/proof_programs/is_zero.cairo create mode 120000 cairo_programs/proof_programs/is_zero_pack.cairo create mode 120000 cairo_programs/proof_programs/keccak_builtin.cairo create mode 120000 cairo_programs/proof_programs/keccak_uint256.cairo create mode 120000 cairo_programs/proof_programs/memory_holes.cairo create mode 120000 cairo_programs/proof_programs/mul_s_inv.cairo create mode 120000 cairo_programs/proof_programs/multiplicative_inverse.cairo create mode 120000 cairo_programs/proof_programs/n_bit.cairo create mode 120000 cairo_programs/proof_programs/nondet_bigint3_v2.cairo create mode 120000 cairo_programs/proof_programs/normalize_address.cairo create mode 120000 cairo_programs/proof_programs/packed_sha256_test.cairo create mode 120000 cairo_programs/proof_programs/poseidon_builtin.cairo create mode 120000 cairo_programs/proof_programs/poseidon_hash.cairo create mode 120000 cairo_programs/proof_programs/poseidon_multirun.cairo create mode 120000 cairo_programs/proof_programs/recover_y.cairo create mode 120000 cairo_programs/proof_programs/reduce.cairo create mode 120000 cairo_programs/proof_programs/relocate_temporary_segment_append.cairo create mode 120000 cairo_programs/proof_programs/relocate_temporary_segment_into_new.cairo create mode 120000 cairo_programs/proof_programs/secp256r1_div_mod_n.cairo create mode 120000 cairo_programs/proof_programs/secp256r1_fast_ec_add.cairo create mode 120000 cairo_programs/proof_programs/secp256r1_slope.cairo create mode 120000 cairo_programs/proof_programs/sha256_test.cairo create mode 120000 cairo_programs/proof_programs/split_xx_hint.cairo create mode 120000 cairo_programs/proof_programs/uint256_improvements.cairo create mode 120000 cairo_programs/proof_programs/uint384.cairo create mode 120000 cairo_programs/proof_programs/uint384_extension.cairo create mode 120000 cairo_programs/proof_programs/uint384_extension_test.cairo create mode 120000 cairo_programs/proof_programs/uint384_test.cairo diff --git a/cairo_programs/proof_programs/_keccak_alternative_hint.cairo b/cairo_programs/proof_programs/_keccak_alternative_hint.cairo new file mode 120000 index 0000000000..188837a642 --- /dev/null +++ b/cairo_programs/proof_programs/_keccak_alternative_hint.cairo @@ -0,0 +1 @@ +../_keccak_alternative_hint.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/assert_le_felt_old.cairo b/cairo_programs/proof_programs/assert_le_felt_old.cairo new file mode 120000 index 0000000000..578084defe --- /dev/null +++ b/cairo_programs/proof_programs/assert_le_felt_old.cairo @@ -0,0 +1 @@ +../assert_le_felt_old.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/bigint.cairo b/cairo_programs/proof_programs/bigint.cairo new file mode 120000 index 0000000000..81d408cee4 --- /dev/null +++ b/cairo_programs/proof_programs/bigint.cairo @@ -0,0 +1 @@ +../bigint.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/bitand_hint.cairo b/cairo_programs/proof_programs/bitand_hint.cairo new file mode 120000 index 0000000000..1ba1561a2d --- /dev/null +++ b/cairo_programs/proof_programs/bitand_hint.cairo @@ -0,0 +1 @@ +../bitand_hint.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/cairo_finalize_keccak_block_size_1000.cairo b/cairo_programs/proof_programs/cairo_finalize_keccak_block_size_1000.cairo new file mode 120000 index 0000000000..69fa41ec38 --- /dev/null +++ b/cairo_programs/proof_programs/cairo_finalize_keccak_block_size_1000.cairo @@ -0,0 +1 @@ +../cairo_finalize_keccak_block_size_1000.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/chained_ec_op.cairo b/cairo_programs/proof_programs/chained_ec_op.cairo new file mode 120000 index 0000000000..562981744b --- /dev/null +++ b/cairo_programs/proof_programs/chained_ec_op.cairo @@ -0,0 +1 @@ +../chained_ec_op.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/common_signature.cairo b/cairo_programs/proof_programs/common_signature.cairo new file mode 120000 index 0000000000..9a92f8aa35 --- /dev/null +++ b/cairo_programs/proof_programs/common_signature.cairo @@ -0,0 +1 @@ +../common_signature.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/compute_doubling_slope_v2.cairo b/cairo_programs/proof_programs/compute_doubling_slope_v2.cairo new file mode 120000 index 0000000000..e3400f66cb --- /dev/null +++ b/cairo_programs/proof_programs/compute_doubling_slope_v2.cairo @@ -0,0 +1 @@ +../compute_doubling_slope_v2.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/compute_slope_v2.cairo b/cairo_programs/proof_programs/compute_slope_v2.cairo new file mode 120000 index 0000000000..99e22890e9 --- /dev/null +++ b/cairo_programs/proof_programs/compute_slope_v2.cairo @@ -0,0 +1 @@ +../compute_slope_v2.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/dict_store_cast_ptr.cairo b/cairo_programs/proof_programs/dict_store_cast_ptr.cairo new file mode 120000 index 0000000000..8d1e6a7409 --- /dev/null +++ b/cairo_programs/proof_programs/dict_store_cast_ptr.cairo @@ -0,0 +1 @@ +../dict_store_cast_ptr.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/div_mod_n.cairo b/cairo_programs/proof_programs/div_mod_n.cairo new file mode 120000 index 0000000000..e262b1292a --- /dev/null +++ b/cairo_programs/proof_programs/div_mod_n.cairo @@ -0,0 +1 @@ +../div_mod_n.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/ec_double_assign_new_x_v3.cairo b/cairo_programs/proof_programs/ec_double_assign_new_x_v3.cairo new file mode 120000 index 0000000000..8a7e7d4150 --- /dev/null +++ b/cairo_programs/proof_programs/ec_double_assign_new_x_v3.cairo @@ -0,0 +1 @@ +../ec_double_assign_new_x_v3.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/ec_double_slope.cairo b/cairo_programs/proof_programs/ec_double_slope.cairo new file mode 120000 index 0000000000..ff9fbd912f --- /dev/null +++ b/cairo_programs/proof_programs/ec_double_slope.cairo @@ -0,0 +1 @@ +../ec_double_slope.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/ec_double_v4.cairo b/cairo_programs/proof_programs/ec_double_v4.cairo new file mode 120000 index 0000000000..ec8291916a --- /dev/null +++ b/cairo_programs/proof_programs/ec_double_v4.cairo @@ -0,0 +1 @@ +../ec_double_v4.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/ec_negate.cairo b/cairo_programs/proof_programs/ec_negate.cairo new file mode 120000 index 0000000000..c8a8af8d5c --- /dev/null +++ b/cairo_programs/proof_programs/ec_negate.cairo @@ -0,0 +1 @@ +../ec_negate.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/ec_op.cairo b/cairo_programs/proof_programs/ec_op.cairo new file mode 120000 index 0000000000..ed20b661af --- /dev/null +++ b/cairo_programs/proof_programs/ec_op.cairo @@ -0,0 +1 @@ +../ec_op.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/ec_recover.cairo b/cairo_programs/proof_programs/ec_recover.cairo new file mode 120000 index 0000000000..a0629529c6 --- /dev/null +++ b/cairo_programs/proof_programs/ec_recover.cairo @@ -0,0 +1 @@ +../ec_recover.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/ed25519_ec.cairo b/cairo_programs/proof_programs/ed25519_ec.cairo new file mode 120000 index 0000000000..d60a0f17c4 --- /dev/null +++ b/cairo_programs/proof_programs/ed25519_ec.cairo @@ -0,0 +1 @@ +../ed25519_ec.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/ed25519_field.cairo b/cairo_programs/proof_programs/ed25519_field.cairo new file mode 120000 index 0000000000..55fb9bae0e --- /dev/null +++ b/cairo_programs/proof_programs/ed25519_field.cairo @@ -0,0 +1 @@ +../ed25519_field.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/efficient_secp256r1_ec.cairo b/cairo_programs/proof_programs/efficient_secp256r1_ec.cairo new file mode 120000 index 0000000000..cd0e2fb3f9 --- /dev/null +++ b/cairo_programs/proof_programs/efficient_secp256r1_ec.cairo @@ -0,0 +1 @@ +../efficient_secp256r1_ec.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/example_blake2s.cairo b/cairo_programs/proof_programs/example_blake2s.cairo new file mode 120000 index 0000000000..77d4b53f0f --- /dev/null +++ b/cairo_programs/proof_programs/example_blake2s.cairo @@ -0,0 +1 @@ +../example_blake2s.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/example_program.cairo b/cairo_programs/proof_programs/example_program.cairo new file mode 120000 index 0000000000..9bf1899363 --- /dev/null +++ b/cairo_programs/proof_programs/example_program.cairo @@ -0,0 +1 @@ +../example_program.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/fast_ec_add_v2.cairo b/cairo_programs/proof_programs/fast_ec_add_v2.cairo new file mode 120000 index 0000000000..a6012da8d3 --- /dev/null +++ b/cairo_programs/proof_programs/fast_ec_add_v2.cairo @@ -0,0 +1 @@ +../fast_ec_add_v2.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/fast_ec_add_v3.cairo b/cairo_programs/proof_programs/fast_ec_add_v3.cairo new file mode 120000 index 0000000000..ed334949da --- /dev/null +++ b/cairo_programs/proof_programs/fast_ec_add_v3.cairo @@ -0,0 +1 @@ +../fast_ec_add_v3.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/field_arithmetic.cairo b/cairo_programs/proof_programs/field_arithmetic.cairo new file mode 120000 index 0000000000..2ad65272a2 --- /dev/null +++ b/cairo_programs/proof_programs/field_arithmetic.cairo @@ -0,0 +1 @@ +../field_arithmetic.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/finalize_blake2s_v2_hint.cairo b/cairo_programs/proof_programs/finalize_blake2s_v2_hint.cairo new file mode 120000 index 0000000000..36ff9954b3 --- /dev/null +++ b/cairo_programs/proof_programs/finalize_blake2s_v2_hint.cairo @@ -0,0 +1 @@ +../finalize_blake2s_v2_hint.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/fq.cairo b/cairo_programs/proof_programs/fq.cairo new file mode 120000 index 0000000000..d67bd7ebd5 --- /dev/null +++ b/cairo_programs/proof_programs/fq.cairo @@ -0,0 +1 @@ +../fq.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/fq_test.cairo b/cairo_programs/proof_programs/fq_test.cairo new file mode 120000 index 0000000000..7d8b5f7573 --- /dev/null +++ b/cairo_programs/proof_programs/fq_test.cairo @@ -0,0 +1 @@ +../fq_test.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/garaga.cairo b/cairo_programs/proof_programs/garaga.cairo new file mode 120000 index 0000000000..2c29bb6184 --- /dev/null +++ b/cairo_programs/proof_programs/garaga.cairo @@ -0,0 +1 @@ +../garaga.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/highest_bitlen.cairo b/cairo_programs/proof_programs/highest_bitlen.cairo new file mode 120000 index 0000000000..1b72bcb0b6 --- /dev/null +++ b/cairo_programs/proof_programs/highest_bitlen.cairo @@ -0,0 +1 @@ +../highest_bitlen.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/if_reloc_equal.cairo b/cairo_programs/proof_programs/if_reloc_equal.cairo new file mode 120000 index 0000000000..bec0afd84d --- /dev/null +++ b/cairo_programs/proof_programs/if_reloc_equal.cairo @@ -0,0 +1 @@ +../if_reloc_equal.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/inv_mod_p_uint512.cairo b/cairo_programs/proof_programs/inv_mod_p_uint512.cairo new file mode 120000 index 0000000000..cc8662e6db --- /dev/null +++ b/cairo_programs/proof_programs/inv_mod_p_uint512.cairo @@ -0,0 +1 @@ +../inv_mod_p_uint512.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/is_quad_residue_test.cairo b/cairo_programs/proof_programs/is_quad_residue_test.cairo new file mode 120000 index 0000000000..1ea92a4976 --- /dev/null +++ b/cairo_programs/proof_programs/is_quad_residue_test.cairo @@ -0,0 +1 @@ +../is_quad_residue_test.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/is_zero.cairo b/cairo_programs/proof_programs/is_zero.cairo new file mode 120000 index 0000000000..c564d75006 --- /dev/null +++ b/cairo_programs/proof_programs/is_zero.cairo @@ -0,0 +1 @@ +../is_zero.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/is_zero_pack.cairo b/cairo_programs/proof_programs/is_zero_pack.cairo new file mode 120000 index 0000000000..afa37d803c --- /dev/null +++ b/cairo_programs/proof_programs/is_zero_pack.cairo @@ -0,0 +1 @@ +../is_zero_pack.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/keccak_builtin.cairo b/cairo_programs/proof_programs/keccak_builtin.cairo new file mode 120000 index 0000000000..71b14b43ff --- /dev/null +++ b/cairo_programs/proof_programs/keccak_builtin.cairo @@ -0,0 +1 @@ +../keccak_builtin.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/keccak_uint256.cairo b/cairo_programs/proof_programs/keccak_uint256.cairo new file mode 120000 index 0000000000..a2da091a09 --- /dev/null +++ b/cairo_programs/proof_programs/keccak_uint256.cairo @@ -0,0 +1 @@ +../keccak_uint256.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/memory_holes.cairo b/cairo_programs/proof_programs/memory_holes.cairo new file mode 120000 index 0000000000..e1fadbb4fb --- /dev/null +++ b/cairo_programs/proof_programs/memory_holes.cairo @@ -0,0 +1 @@ +../memory_holes.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/mul_s_inv.cairo b/cairo_programs/proof_programs/mul_s_inv.cairo new file mode 120000 index 0000000000..e1a7cd0deb --- /dev/null +++ b/cairo_programs/proof_programs/mul_s_inv.cairo @@ -0,0 +1 @@ +../mul_s_inv.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/multiplicative_inverse.cairo b/cairo_programs/proof_programs/multiplicative_inverse.cairo new file mode 120000 index 0000000000..e281f13e2d --- /dev/null +++ b/cairo_programs/proof_programs/multiplicative_inverse.cairo @@ -0,0 +1 @@ +../multiplicative_inverse.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/n_bit.cairo b/cairo_programs/proof_programs/n_bit.cairo new file mode 120000 index 0000000000..49b68729a0 --- /dev/null +++ b/cairo_programs/proof_programs/n_bit.cairo @@ -0,0 +1 @@ +../n_bit.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/nondet_bigint3_v2.cairo b/cairo_programs/proof_programs/nondet_bigint3_v2.cairo new file mode 120000 index 0000000000..62d24de45b --- /dev/null +++ b/cairo_programs/proof_programs/nondet_bigint3_v2.cairo @@ -0,0 +1 @@ +../nondet_bigint3_v2.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/normalize_address.cairo b/cairo_programs/proof_programs/normalize_address.cairo new file mode 120000 index 0000000000..52b57a98f6 --- /dev/null +++ b/cairo_programs/proof_programs/normalize_address.cairo @@ -0,0 +1 @@ +../normalize_address.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/packed_sha256_test.cairo b/cairo_programs/proof_programs/packed_sha256_test.cairo new file mode 120000 index 0000000000..dfb0a9b318 --- /dev/null +++ b/cairo_programs/proof_programs/packed_sha256_test.cairo @@ -0,0 +1 @@ +../packed_sha256_test.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/poseidon_builtin.cairo b/cairo_programs/proof_programs/poseidon_builtin.cairo new file mode 120000 index 0000000000..bc4fb83e23 --- /dev/null +++ b/cairo_programs/proof_programs/poseidon_builtin.cairo @@ -0,0 +1 @@ +../poseidon_builtin.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/poseidon_hash.cairo b/cairo_programs/proof_programs/poseidon_hash.cairo new file mode 120000 index 0000000000..190a72caae --- /dev/null +++ b/cairo_programs/proof_programs/poseidon_hash.cairo @@ -0,0 +1 @@ +../poseidon_hash.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/poseidon_multirun.cairo b/cairo_programs/proof_programs/poseidon_multirun.cairo new file mode 120000 index 0000000000..30c32a782d --- /dev/null +++ b/cairo_programs/proof_programs/poseidon_multirun.cairo @@ -0,0 +1 @@ +../poseidon_multirun.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/recover_y.cairo b/cairo_programs/proof_programs/recover_y.cairo new file mode 120000 index 0000000000..4fdd3f9e3d --- /dev/null +++ b/cairo_programs/proof_programs/recover_y.cairo @@ -0,0 +1 @@ +../recover_y.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/reduce.cairo b/cairo_programs/proof_programs/reduce.cairo new file mode 120000 index 0000000000..42dbc59c35 --- /dev/null +++ b/cairo_programs/proof_programs/reduce.cairo @@ -0,0 +1 @@ +../reduce.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/relocate_temporary_segment_append.cairo b/cairo_programs/proof_programs/relocate_temporary_segment_append.cairo new file mode 120000 index 0000000000..1f0e8ac7cf --- /dev/null +++ b/cairo_programs/proof_programs/relocate_temporary_segment_append.cairo @@ -0,0 +1 @@ +../relocate_temporary_segment_append.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/relocate_temporary_segment_into_new.cairo b/cairo_programs/proof_programs/relocate_temporary_segment_into_new.cairo new file mode 120000 index 0000000000..02d22be9c6 --- /dev/null +++ b/cairo_programs/proof_programs/relocate_temporary_segment_into_new.cairo @@ -0,0 +1 @@ +../relocate_temporary_segment_into_new.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/secp256r1_div_mod_n.cairo b/cairo_programs/proof_programs/secp256r1_div_mod_n.cairo new file mode 120000 index 0000000000..2049ea105b --- /dev/null +++ b/cairo_programs/proof_programs/secp256r1_div_mod_n.cairo @@ -0,0 +1 @@ +../secp256r1_div_mod_n.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/secp256r1_fast_ec_add.cairo b/cairo_programs/proof_programs/secp256r1_fast_ec_add.cairo new file mode 120000 index 0000000000..9e8a00dff3 --- /dev/null +++ b/cairo_programs/proof_programs/secp256r1_fast_ec_add.cairo @@ -0,0 +1 @@ +../secp256r1_fast_ec_add.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/secp256r1_slope.cairo b/cairo_programs/proof_programs/secp256r1_slope.cairo new file mode 120000 index 0000000000..7e44c983fa --- /dev/null +++ b/cairo_programs/proof_programs/secp256r1_slope.cairo @@ -0,0 +1 @@ +../secp256r1_slope.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/sha256_test.cairo b/cairo_programs/proof_programs/sha256_test.cairo new file mode 120000 index 0000000000..63f8a51ea5 --- /dev/null +++ b/cairo_programs/proof_programs/sha256_test.cairo @@ -0,0 +1 @@ +../sha256_test.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/split_xx_hint.cairo b/cairo_programs/proof_programs/split_xx_hint.cairo new file mode 120000 index 0000000000..a816a67cf3 --- /dev/null +++ b/cairo_programs/proof_programs/split_xx_hint.cairo @@ -0,0 +1 @@ +../split_xx_hint.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/uint256_improvements.cairo b/cairo_programs/proof_programs/uint256_improvements.cairo new file mode 120000 index 0000000000..d44d558e6d --- /dev/null +++ b/cairo_programs/proof_programs/uint256_improvements.cairo @@ -0,0 +1 @@ +../uint256_improvements.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/uint384.cairo b/cairo_programs/proof_programs/uint384.cairo new file mode 120000 index 0000000000..1bf594c3ae --- /dev/null +++ b/cairo_programs/proof_programs/uint384.cairo @@ -0,0 +1 @@ +../uint384.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/uint384_extension.cairo b/cairo_programs/proof_programs/uint384_extension.cairo new file mode 120000 index 0000000000..aa817df393 --- /dev/null +++ b/cairo_programs/proof_programs/uint384_extension.cairo @@ -0,0 +1 @@ +../uint384_extension.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/uint384_extension_test.cairo b/cairo_programs/proof_programs/uint384_extension_test.cairo new file mode 120000 index 0000000000..74fd0c8187 --- /dev/null +++ b/cairo_programs/proof_programs/uint384_extension_test.cairo @@ -0,0 +1 @@ +../uint384_extension_test.cairo \ No newline at end of file diff --git a/cairo_programs/proof_programs/uint384_test.cairo b/cairo_programs/proof_programs/uint384_test.cairo new file mode 120000 index 0000000000..d956e6dae8 --- /dev/null +++ b/cairo_programs/proof_programs/uint384_test.cairo @@ -0,0 +1 @@ +../uint384_test.cairo \ No newline at end of file From 9fc9c6ef8ae164acaec5dc205e54e3c3508258c7 Mon Sep 17 00:00:00 2001 From: fmoletta <99273364+fmoletta@users.noreply.github.com> Date: Mon, 15 Jan 2024 17:54:25 +0200 Subject: [PATCH 4/7] Add `proof_mode` flag to `cairo1-run` (#1537) * Add proof_mode flag to cairo1-run * Add Changelog entry * Clippy * clippy --------- Co-authored-by: Mario Rugiero --- CHANGELOG.md | 4 ++ cairo1-run/src/main.rs | 126 ++++++++++++++++++++++++++++------------- 2 files changed, 92 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ddc963ad6e..d17d848d28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ #### Upcoming Changes +* feat: Add `proof_mode` flag to `cairo1-run` [#1537] (https://github.com/lambdaclass/cairo-vm/pull/1537) + * The cairo1-run crate no longer compiles and executes in proof_mode by default + * Add flag `proof_mode` to cairo1-run crate. Activating this flag will enable proof_mode compilation and execution + * dev: bump cairo 1 compiler dep to 2.4 [#1530](https://github.com/lambdaclass/cairo-vm/pull/1530) #### [1.0.0-rc0] - 2024-1-5 diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index 0b4056ea7b..1231f7d69c 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -77,6 +77,8 @@ struct Args { memory_file: Option, #[clap(long = "layout", default_value = "plain", value_parser=validate_layout)] layout: String, + #[clap(long = "proof_mode", value_parser)] + proof_mode: bool, } fn validate_layout(value: &str) -> Result { @@ -201,29 +203,34 @@ fn run(args: impl Iterator) -> Result, Erro &type_sizes, main_func, initial_gas, + args.proof_mode, )?; - println!("Compiling with proof mode and running ..."); - - // This information can be useful for the users using the prover. - println!("Builtins used: {:?}", builtins); - - // Prepare "canonical" proof mode instructions. These are usually added by the compiler in cairo 0 - let mut ctx = casm! {}; - casm_extend! {ctx, - call rel 4; - jmp rel 0; - }; - let proof_mode_header = ctx.instructions; - // Get the user program instructions let program_instructions = casm_program.instructions.iter(); // This footer is used by lib funcs let libfunc_footer = create_code_footer(); - // This is the program we are actually proving - // With embedded proof mode, cairo1 header and the libfunc footer + let proof_mode_header = if args.proof_mode { + println!("Compiling with proof mode and running ..."); + + // This information can be useful for the users using the prover. + println!("Builtins used: {:?}", builtins); + + // Prepare "canonical" proof mode instructions. These are usually added by the compiler in cairo 0 + let mut ctx = casm! {}; + casm_extend! {ctx, + call rel 4; + jmp rel 0; + }; + ctx.instructions + } else { + casm! {}.instructions + }; + + // This is the program we are actually running/proving + // With (embedded proof mode), cairo1 header and the libfunc footer let instructions = chain!( proof_mode_header.iter(), entry_code.iter(), @@ -243,36 +250,59 @@ fn run(args: impl Iterator) -> Result, Erro let data_len = data.len(); - let starting_pc = 0; - - let program = Program::new_for_proof( - builtins, - data, - starting_pc, - // Proof mode is on top - // jmp rel 0 is on PC == 2 - 2, - program_hints, - ReferenceManager { - references: Vec::new(), - }, - HashMap::new(), - vec![], - None, - )?; + let program = if args.proof_mode { + Program::new_for_proof( + builtins, + data, + 0, + // Proof mode is on top + // jmp rel 0 is on PC == 2 + 2, + program_hints, + ReferenceManager { + references: Vec::new(), + }, + HashMap::new(), + vec![], + None, + )? + } else { + Program::new( + builtins, + data, + Some(0), + program_hints, + ReferenceManager { + references: Vec::new(), + }, + HashMap::new(), + vec![], + None, + )? + }; - let mut runner = CairoRunner::new_v2(&program, &args.layout, RunnerMode::ProofModeCairo1)?; + let runner_mode = if args.proof_mode { + RunnerMode::ProofModeCairo1 + } else { + RunnerMode::ExecutionMode + }; + + let mut runner = CairoRunner::new_v2(&program, &args.layout, runner_mode)?; let mut vm = VirtualMachine::new(args.trace_file.is_some()); let end = runner.initialize(&mut vm)?; additional_initialization(&mut vm, data_len)?; - // Run it until the infinite loop + // Run it until the end/ infinite loop in proof_mode runner.run_until_pc(end, &mut vm, &mut hint_processor)?; - // Then pad it to the power of 2 - runner.run_until_next_power_of_2(&mut vm, &mut hint_processor)?; + if args.proof_mode { + // Then pad it to the power of 2 + runner.run_until_next_power_of_2(&mut vm, &mut hint_processor)?; + } else { + runner.end_run(true, false, &mut vm, &mut hint_processor)?; + } // Fetch return type data let return_type_id = main_func @@ -464,6 +494,7 @@ fn create_entry_code( type_sizes: &UnorderedHashMap, func: &Function, initial_gas: usize, + proof_mode: bool, ) -> Result<(Vec, Vec), Error> { let mut ctx = casm! {}; // The builtins in the formatting expected by the runner. @@ -496,8 +527,11 @@ fn create_entry_code( let ty_size = type_sizes[ty]; let generic_ty = &info.long_id.generic_id; if let Some(offset) = builtin_offset.get(generic_ty) { - // Everything is off by 2 due to the proof mode header - let offset = offset + 2; + let mut offset = *offset; + if proof_mode { + // Everything is off by 2 due to the proof mode header + offset += 2; + } casm_extend! {ctx, [ap + 0] = [fp - offset], ap++; } @@ -660,6 +694,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/fibonacci.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/fibonacci.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_fibonacci_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(89)]); @@ -667,6 +702,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/factorial.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/factorial.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_factorial_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(3628800)]); @@ -674,6 +710,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/array_get.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/array_get.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_array_get_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(3)]); @@ -681,6 +718,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/enum_flow.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/enum_flow.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_enum_flow_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(300)]); @@ -688,6 +726,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/enum_match.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/enum_match.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_enum_match_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(10), MaybeRelocatable::from(felt_str("3618502788666131213697322783095070105623107215331596699973092056135872020471"))]); @@ -695,6 +734,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/hello.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/hello.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_hello_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(1), MaybeRelocatable::from(1234)]); @@ -702,6 +742,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/ops.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/ops.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_ops_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(6)]); @@ -709,6 +750,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/print.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/print.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_print_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![]); @@ -716,6 +758,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/recursion.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/recursion.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_recursion_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(felt_str("1154076154663935037074198317650845438095734251249125412074882362667803016453"))]); @@ -723,6 +766,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/sample.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/sample.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_sample_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(felt_str("5050"))]); @@ -730,6 +774,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/poseidon.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/poseidon.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_poseidon_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(felt_str("1099385018355113290651252669115094675591288647745213771718157553170111442461"))]); @@ -737,6 +782,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/poseidon_pedersen.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/poseidon_pedersen.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_poseidon_pedersen_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(felt_str("1036257840396636296853154602823055519264738423488122322497453114874087006398"))]); @@ -744,6 +790,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/pedersen_example.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/pedersen_example.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_pedersen_example_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(felt_str("1089549915800264549621536909767699778745926517555586332772759280702396009108"))]); @@ -751,6 +798,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/simple.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/simple.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_simple_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(1)]); @@ -758,6 +806,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/simple_struct.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/simple_struct.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_simple_struct_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(100)]); @@ -765,6 +814,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] fn test_run_dictionaries(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(1024)]); From 352e8a8cb8addc267d8ae59073b6447fd8517c81 Mon Sep 17 00:00:00 2001 From: fmoletta <99273364+fmoletta@users.noreply.github.com> Date: Mon, 15 Jan 2024 19:08:00 +0200 Subject: [PATCH 5/7] Implement air_private_input (#1552) * Implement get_air_private_input for RangeCheck; * Implement air_private_input for Bitwise; * Implement air_private_input for Hash * Update proof_programs symlinks * Add EcOp priv input variant * Implement air_private_input for EcOp * Implement air_private_input for Poseidon & Signature * Implement air_private_input for Keccak * Add AirPrivateInput serialization * Remove unwrap * Add targets to compare private inputs against python vm * Add separate script to compare private inputs * Ignore & Clean output files * Fix target * Fix + fmt * Fetch absolute paths in cli and remove feature-gate * Fix ecdsa private input * Add no-std import * Add Chaneglog entry * Update README * Add cli tests * Add case to cli test * Fix conditional * Add no-std import * fmt * fix * Remove unwraps * Add tests so coverage doesnt sink * Fix test * Fix test * Fix test * Fix symlink * Remove broken file --------- Co-authored-by: Mario Rugiero --- .gitignore | 1 + CHANGELOG.md | 2 + Makefile | 20 ++- README.md | 2 + cairo-vm-cli/src/main.rs | 89 ++++++++++- fuzzer/Cargo.lock | 2 +- vm/src/air_private_input.rs | 142 ++++++++++++++++++ vm/src/lib.rs | 1 + vm/src/tests/air_private_input_comparator.py | 26 ++++ vm/src/tests/compare_vm_state.sh | 14 ++ vm/src/types/relocatable.rs | 9 ++ vm/src/vm/runners/builtin_runner/bitwise.rs | 70 +++++++++ vm/src/vm/runners/builtin_runner/ec_op.rs | 57 +++++++ vm/src/vm/runners/builtin_runner/hash.rs | 64 ++++++++ vm/src/vm/runners/builtin_runner/keccak.rs | 78 ++++++++++ vm/src/vm/runners/builtin_runner/mod.rs | 15 ++ vm/src/vm/runners/builtin_runner/output.rs | 9 ++ vm/src/vm/runners/builtin_runner/poseidon.rs | 65 ++++++++ .../vm/runners/builtin_runner/range_check.rs | 46 +++++- .../runners/builtin_runner/segment_arena.rs | 9 ++ vm/src/vm/runners/builtin_runner/signature.rs | 44 ++++++ vm/src/vm/runners/cairo_runner.rs | 54 +++++++ 22 files changed, 801 insertions(+), 18 deletions(-) create mode 100644 vm/src/air_private_input.rs create mode 100755 vm/src/tests/air_private_input_comparator.py diff --git a/.gitignore b/.gitignore index 98e6148071..a6f4053583 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ **/*.trace **/*.memory **/*.air_public_input +**/*.air_private_input **/*.swp bench/results .python-version diff --git a/CHANGELOG.md b/CHANGELOG.md index d17d848d28..8306723148 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ #### Upcoming Changes +* feat: Implement air_private_input [#1552](https://github.com/lambdaclass/cairo-vm/pull/1552) + * feat: Add `proof_mode` flag to `cairo1-run` [#1537] (https://github.com/lambdaclass/cairo-vm/pull/1537) * The cairo1-run crate no longer compiles and executes in proof_mode by default * Add flag `proof_mode` to cairo1-run crate. Activating this flag will enable proof_mode compilation and execution diff --git a/Makefile b/Makefile index 47f0f36e23..e39d995130 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ endif deps deps-macos cargo-deps build run check test clippy coverage benchmark \ compare_benchmarks_deps compare_benchmarks docs clean \ compare_vm_output compare_trace_memory compare_trace compare_memory \ - compare_trace_memory_proof compare_all_proof compare_trace_proof compare_memory_proof compare_air_public_input \ + compare_trace_memory_proof compare_all_proof compare_trace_proof compare_memory_proof compare_air_public_input compare_air_private_input\ cairo_bench_programs cairo_proof_programs cairo_test_programs cairo_1_test_contracts cairo_2_test_contracts \ cairo_trace cairo-vm_trace cairo_proof_trace cairo-vm_proof_trace \ fuzzer-deps fuzzer-run-cairo-compiled fuzzer-run-hint-diff build-cairo-lang hint-accountant \ @@ -37,10 +37,12 @@ COMPILED_PROOF_TESTS:=$(patsubst $(TEST_PROOF_DIR)/%.cairo, $(TEST_PROOF_DIR)/%. CAIRO_MEM_PROOF:=$(patsubst $(TEST_PROOF_DIR)/%.json, $(TEST_PROOF_DIR)/%.memory, $(COMPILED_PROOF_TESTS)) CAIRO_TRACE_PROOF:=$(patsubst $(TEST_PROOF_DIR)/%.json, $(TEST_PROOF_DIR)/%.trace, $(COMPILED_PROOF_TESTS)) CAIRO_AIR_PUBLIC_INPUT:=$(patsubst $(TEST_PROOF_DIR)/%.json, $(TEST_PROOF_DIR)/%.air_public_input, $(COMPILED_PROOF_TESTS)) +CAIRO_AIR_PRIVATE_INPUT:=$(patsubst $(TEST_PROOF_DIR)/%.json, $(TEST_PROOF_DIR)/%.air_private_input, $(COMPILED_PROOF_TESTS)) CAIRO_RS_MEM_PROOF:=$(patsubst $(TEST_PROOF_DIR)/%.json, $(TEST_PROOF_DIR)/%.rs.memory, $(COMPILED_PROOF_TESTS)) CAIRO_RS_TRACE_PROOF:=$(patsubst $(TEST_PROOF_DIR)/%.json, $(TEST_PROOF_DIR)/%.rs.trace, $(COMPILED_PROOF_TESTS)) CAIRO_RS_AIR_PUBLIC_INPUT:=$(patsubst $(TEST_PROOF_DIR)/%.json, $(TEST_PROOF_DIR)/%.rs.air_public_input, $(COMPILED_PROOF_TESTS)) +CAIRO_RS_AIR_PRIVATE_INPUT:=$(patsubst $(TEST_PROOF_DIR)/%.json, $(TEST_PROOF_DIR)/%.rs.air_private_input, $(COMPILED_PROOF_TESTS)) PROOF_BENCH_DIR=cairo_programs/benchmarks PROOF_BENCH_FILES:=$(wildcard $(PROOF_BENCH_DIR)/*.cairo) @@ -49,11 +51,11 @@ PROOF_COMPILED_BENCHES:=$(patsubst $(PROOF_BENCH_DIR)/%.cairo, $(PROOF_BENCH_DIR $(TEST_PROOF_DIR)/%.json: $(TEST_PROOF_DIR)/%.cairo cairo-compile --cairo_path="$(TEST_PROOF_DIR):$(PROOF_BENCH_DIR)" $< --output $@ --proof_mode -$(TEST_PROOF_DIR)/%.rs.trace $(TEST_PROOF_DIR)/%.rs.memory $(TEST_PROOF_DIR)/%.rs.air_public_input: $(TEST_PROOF_DIR)/%.json $(RELBIN) - cargo llvm-cov run -p cairo-vm-cli --release --no-report -- --layout starknet_with_keccak --proof_mode $< --trace_file $@ --memory_file $(@D)/$(*F).rs.memory --air_public_input $(@D)/$(*F).rs.air_public_input +$(TEST_PROOF_DIR)/%.rs.trace $(TEST_PROOF_DIR)/%.rs.memory $(TEST_PROOF_DIR)/%.rs.air_public_input $(TEST_PROOF_DIR)/%.rs.air_private_input: $(TEST_PROOF_DIR)/%.json $(RELBIN) + cargo llvm-cov run -p cairo-vm-cli --release --no-report -- --layout starknet_with_keccak --proof_mode $< --trace_file $(@D)/$(*F).rs.trace --memory_file $(@D)/$(*F).rs.memory --air_public_input $(@D)/$(*F).rs.air_public_input --air_private_input $(@D)/$(*F).rs.air_private_input -$(TEST_PROOF_DIR)/%.trace $(TEST_PROOF_DIR)/%.memory $(TEST_PROOF_DIR)/%.air_public_input: $(TEST_PROOF_DIR)/%.json - cairo-run --layout starknet_with_keccak --proof_mode --program $< --trace_file $(@D)/$(*F).trace --air_public_input $(@D)/$(*F).air_public_input --memory_file $(@D)/$(*F).memory +$(TEST_PROOF_DIR)/%.trace $(TEST_PROOF_DIR)/%.memory $(TEST_PROOF_DIR)/%.air_public_input $(TEST_PROOF_DIR)/%.air_private_input: $(TEST_PROOF_DIR)/%.json + cairo-run --layout starknet_with_keccak --proof_mode --program $< --trace_file $(@D)/$(*F).trace --air_public_input $(@D)/$(*F).air_public_input --memory_file $(@D)/$(*F).memory --air_private_input $(@D)/$(*F).air_private_input $(PROOF_BENCH_DIR)/%.json: $(PROOF_BENCH_DIR)/%.cairo cairo-compile --cairo_path="$(TEST_PROOF_DIR):$(PROOF_BENCH_DIR)" $< --output $@ --proof_mode @@ -289,8 +291,8 @@ compare_memory: $(CAIRO_RS_MEM) $(CAIRO_MEM) compare_trace_memory_proof: $(COMPILED_PROOF_TESTS) $(CAIRO_RS_TRACE_PROOF) $(CAIRO_TRACE_PROOF) $(CAIRO_RS_MEM_PROOF) $(CAIRO_MEM_PROOF) cd vm/src/tests; ./compare_vm_state.sh trace memory proof_mode -compare_all_proof: $(COMPILED_PROOF_TESTS) $(CAIRO_RS_TRACE_PROOF) $(CAIRO_TRACE_PROOF) $(CAIRO_RS_MEM_PROOF) $(CAIRO_MEM_PROOF) $(CAIRO_RS_AIR_PUBLIC_INPUT) $(CAIRO_AIR_PUBLIC_INPUT) - cd vm/src/tests; ./compare_vm_state.sh trace memory proof_mode air_public_input +compare_all_proof: $(COMPILED_PROOF_TESTS) $(CAIRO_RS_TRACE_PROOF) $(CAIRO_TRACE_PROOF) $(CAIRO_RS_MEM_PROOF) $(CAIRO_MEM_PROOF) $(CAIRO_RS_AIR_PUBLIC_INPUT) $(CAIRO_AIR_PUBLIC_INPUT) $(CAIRO_RS_AIR_PRIVATE_INPUT) $(CAIRO_AIR_PRIVATE_INPUT) + cd vm/src/tests; ./compare_vm_state.sh trace memory proof_mode air_public_input air_private_input compare_trace_proof: $(CAIRO_RS_TRACE_PROOF) $(CAIRO_TRACE_PROOF) cd vm/src/tests; ./compare_vm_state.sh trace proof_mode @@ -301,6 +303,9 @@ compare_memory_proof: $(CAIRO_RS_MEM_PROOF) $(CAIRO_MEM_PROOF) compare_air_public_input: $(CAIRO_RS_AIR_PUBLIC_INPUT) $(CAIRO_AIR_PUBLIC_INPUT) cd vm/src/tests; ./compare_vm_state.sh memory proof_mode air_public_input +compare_air_private_input: $(CAIRO_RS_AIR_PRIVATE_INPUT) $(CAIRO_AIR_PRIVATE_INPUT) + cd vm/src/tests; ./compare_vm_state.sh memory proof_mode air_private_input + # Run with nightly enable the `doc_cfg` feature wich let us provide clear explaination about which parts of the code are behind a feature flag docs: RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --verbose --release --locked --no-deps --all-features --open @@ -318,6 +323,7 @@ clean: rm -f $(TEST_PROOF_DIR)/*.memory rm -f $(TEST_PROOF_DIR)/*.trace rm -f $(TEST_PROOF_DIR)/*.air_public_input + rm -f $(TEST_PROOF_DIR)/*.air_private_input rm -rf cairo-vm-env rm -rf cairo-vm-pypy-env rm -rf cairo diff --git a/README.md b/README.md index 52c2dd4043..1e45ad3f50 100644 --- a/README.md +++ b/README.md @@ -173,6 +173,8 @@ The cairo-vm-cli supports the following optional arguments: - `--air_public_input `: Receives the name of a file and outputs the AIR public inputs into it. Can only be used if proof_mode is also enabled. +- `--air_private_input `: Receives the name of a file and outputs the AIR private inputs into it. Can only be used if proof_mode, trace_file & memory_file are also enabled. + For example, to obtain the air public inputs from a fibonacci program run, we can run : ```bash diff --git a/cairo-vm-cli/src/main.rs b/cairo-vm-cli/src/main.rs index 6bfd81db4c..a24ef7bb92 100644 --- a/cairo-vm-cli/src/main.rs +++ b/cairo-vm-cli/src/main.rs @@ -40,6 +40,8 @@ struct Args { secure_run: Option, #[clap(long = "air_public_input")] air_public_input: Option, + #[clap(long = "air_private_input")] + air_private_input: Option, } fn validate_layout(value: &str) -> Result { @@ -119,6 +121,30 @@ fn run(args: impl Iterator) -> Result<(), Error> { return Err(Error::Cli(error)); } + if args.air_private_input.is_some() && !args.proof_mode { + let error = Args::command().error( + clap::error::ErrorKind::ArgumentConflict, + "--air_private_input can only be used in proof_mode.", + ); + return Err(Error::Cli(error)); + } + + if args.air_private_input.is_some() && args.trace_file.is_none() { + let error = Args::command().error( + clap::error::ErrorKind::ArgumentConflict, + "--trace_file must be set when --air_private_input is set.", + ); + return Err(Error::Cli(error)); + } + + if args.air_private_input.is_some() && args.memory_file.is_none() { + let error = Args::command().error( + clap::error::ErrorKind::ArgumentConflict, + "--memory_file must be set when --air_private_input is set.", + ); + return Err(Error::Cli(error)); + } + let trace_enabled = args.trace_file.is_some() || args.air_public_input.is_some(); let mut hint_executor = BuiltinHintProcessor::new_empty(); let cairo_run_config = cairo_run::CairoRunConfig { @@ -148,7 +174,7 @@ fn run(args: impl Iterator) -> Result<(), Error> { print!("{output_buffer}"); } - if let Some(trace_path) = args.trace_file { + if let Some(ref trace_path) = args.trace_file { let relocated_trace = cairo_runner .relocated_trace .as_ref() @@ -162,7 +188,7 @@ fn run(args: impl Iterator) -> Result<(), Error> { trace_writer.flush()?; } - if let Some(memory_path) = args.memory_file { + if let Some(ref memory_path) = args.memory_file { let memory_file = std::fs::File::create(memory_path)?; let mut memory_writer = FileWriter::new(io::BufWriter::with_capacity(5 * 1024 * 1024, memory_file)); @@ -176,6 +202,31 @@ fn run(args: impl Iterator) -> Result<(), Error> { std::fs::write(file_path, json)?; } + if let (Some(file_path), Some(ref trace_file), Some(ref memory_file)) = + (args.air_private_input, args.trace_file, args.memory_file) + { + // Get absolute paths of trace_file & memory_file + let trace_path = trace_file + .as_path() + .canonicalize() + .unwrap_or(trace_file.clone()) + .to_string_lossy() + .to_string(); + let memory_path = memory_file + .as_path() + .canonicalize() + .unwrap_or(memory_file.clone()) + .to_string_lossy() + .to_string(); + + let json = cairo_runner + .get_air_private_input(&vm) + .to_serializable(trace_path, memory_path) + .serialize_json() + .map_err(PublicInputError::Serde)?; + std::fs::write(file_path, json)?; + } + Ok(()) } @@ -212,6 +263,27 @@ mod tests { assert_matches!(run(args), Err(Error::Cli(_))); } + #[rstest] + #[case(["cairo-vm-cli", "../cairo_programs/fibonacci.json", "--air_private_input", "/dev/null", "--proof_mode", "--memory_file", "/dev/null"].as_slice())] + fn test_run_air_private_input_no_trace(#[case] args: &[&str]) { + let args = args.iter().cloned().map(String::from); + assert_matches!(run(args), Err(Error::Cli(_))); + } + + #[rstest] + #[case(["cairo-vm-cli", "../cairo_programs/fibonacci.json", "--air_private_input", "/dev/null", "--proof_mode", "--trace_file", "/dev/null"].as_slice())] + fn test_run_air_private_input_no_memory(#[case] args: &[&str]) { + let args = args.iter().cloned().map(String::from); + assert_matches!(run(args), Err(Error::Cli(_))); + } + + #[rstest] + #[case(["cairo-vm-cli", "../cairo_programs/fibonacci.json", "--air_private_input", "/dev/null", "--trace_file", "/dev/null", "--memory_file", "/dev/null"].as_slice())] + fn test_run_air_private_input_no_proof(#[case] args: &[&str]) { + let args = args.iter().cloned().map(String::from); + assert_matches!(run(args), Err(Error::Cli(_))); + } + #[rstest] fn test_run_ok( #[values(None, @@ -234,16 +306,17 @@ mod tests { #[values(false, true)] print_output: bool, #[values(false, true)] entrypoint: bool, #[values(false, true)] air_public_input: bool, + #[values(false, true)] air_private_input: bool, ) { let mut args = vec!["cairo-vm-cli".to_string()]; if let Some(layout) = layout { args.extend_from_slice(&["--layout".to_string(), layout.to_string()]); } if air_public_input { - args.extend_from_slice(&[ - "--air_public_input".to_string(), - "air_input.pub".to_string(), - ]); + args.extend_from_slice(&["--air_public_input".to_string(), "/dev/null".to_string()]); + } + if air_private_input { + args.extend_from_slice(&["--air_private_input".to_string(), "/dev/null".to_string()]); } if proof_mode { trace_file = true; @@ -266,7 +339,9 @@ mod tests { } args.push("../cairo_programs/proof_programs/fibonacci.json".to_string()); - if air_public_input && !proof_mode { + if air_public_input && !proof_mode + || (air_private_input && (!proof_mode || !trace_file || !memory_file)) + { assert_matches!(run(args.into_iter()), Err(_)); } else { assert_matches!(run(args.into_iter()), Ok(_)); diff --git a/fuzzer/Cargo.lock b/fuzzer/Cargo.lock index 5d9996922c..236551e8c5 100644 --- a/fuzzer/Cargo.lock +++ b/fuzzer/Cargo.lock @@ -160,7 +160,7 @@ checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "cairo-vm" -version = "0.9.1" +version = "1.0.0-rc0" dependencies = [ "anyhow", "arbitrary", diff --git a/vm/src/air_private_input.rs b/vm/src/air_private_input.rs new file mode 100644 index 0000000000..4ea30d0d44 --- /dev/null +++ b/vm/src/air_private_input.rs @@ -0,0 +1,142 @@ +use crate::{ + stdlib::{ + collections::HashMap, + prelude::{String, Vec}, + }, + vm::runners::builtin_runner::{ + BITWISE_BUILTIN_NAME, EC_OP_BUILTIN_NAME, HASH_BUILTIN_NAME, KECCAK_BUILTIN_NAME, + POSEIDON_BUILTIN_NAME, RANGE_CHECK_BUILTIN_NAME, SIGNATURE_BUILTIN_NAME, + }, +}; +use serde::{Deserialize, Serialize}; + +use crate::Felt252; + +// Serializable format, matches the file output of the python implementation +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] +pub struct AirPrivateInputSerializable { + trace_path: String, + memory_path: String, + pedersen: Vec, + range_check: Vec, + ecdsa: Vec, + bitwise: Vec, + ec_op: Vec, + keccak: Vec, + poseidon: Vec, +} + +// Contains only builtin public inputs, useful for library users +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct AirPrivateInput(pub HashMap<&'static str, Vec>); + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] +#[serde(untagged)] +pub enum PrivateInput { + Value(PrivateInputValue), + Pair(PrivateInputPair), + EcOp(PrivateInputEcOp), + PoseidonState(PrivateInputPoseidonState), + KeccakState(PrivateInputKeccakState), + Signature(PrivateInputSignature), +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] +pub struct PrivateInputValue { + pub index: usize, + pub value: Felt252, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] +pub struct PrivateInputPair { + pub index: usize, + pub x: Felt252, + pub y: Felt252, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] +pub struct PrivateInputEcOp { + pub index: usize, + pub p_x: Felt252, + pub p_y: Felt252, + pub m: Felt252, + pub q_x: Felt252, + pub q_y: Felt252, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] +pub struct PrivateInputPoseidonState { + pub index: usize, + pub input_s0: Felt252, + pub input_s1: Felt252, + pub input_s2: Felt252, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] +pub struct PrivateInputKeccakState { + pub index: usize, + pub input_s0: Felt252, + pub input_s1: Felt252, + pub input_s2: Felt252, + pub input_s3: Felt252, + pub input_s4: Felt252, + pub input_s5: Felt252, + pub input_s6: Felt252, + pub input_s7: Felt252, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] +pub struct PrivateInputSignature { + pub index: usize, + pub pubkey: Felt252, + pub msg: Felt252, + pub signature_input: SignatureInput, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] +pub struct SignatureInput { + pub r: Felt252, + pub w: Felt252, +} + +impl AirPrivateInput { + pub fn to_serializable( + &self, + trace_path: String, + memory_path: String, + ) -> AirPrivateInputSerializable { + AirPrivateInputSerializable { + trace_path, + memory_path, + pedersen: self.0.get(HASH_BUILTIN_NAME).cloned().unwrap_or_default(), + range_check: self + .0 + .get(RANGE_CHECK_BUILTIN_NAME) + .cloned() + .unwrap_or_default(), + ecdsa: self + .0 + .get(SIGNATURE_BUILTIN_NAME) + .cloned() + .unwrap_or_default(), + bitwise: self + .0 + .get(BITWISE_BUILTIN_NAME) + .cloned() + .unwrap_or_default(), + ec_op: self.0.get(EC_OP_BUILTIN_NAME).cloned().unwrap_or_default(), + keccak: self.0.get(KECCAK_BUILTIN_NAME).cloned().unwrap_or_default(), + poseidon: self + .0 + .get(POSEIDON_BUILTIN_NAME) + .cloned() + .unwrap_or_default(), + } + } +} + +impl AirPrivateInputSerializable { + pub fn serialize_json(&self) -> Result { + serde_json::to_string_pretty(&self) + } +} diff --git a/vm/src/lib.rs b/vm/src/lib.rs index a1138650a7..88415c121c 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -53,6 +53,7 @@ pub mod stdlib { pub use crate::without_std::*; } +pub mod air_private_input; pub mod air_public_input; pub mod cairo_run; pub mod hint_processor; diff --git a/vm/src/tests/air_private_input_comparator.py b/vm/src/tests/air_private_input_comparator.py new file mode 100755 index 0000000000..92ebf987f3 --- /dev/null +++ b/vm/src/tests/air_private_input_comparator.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 + +import sys +import json + + +filename1 = sys.argv[1] +filename2 = sys.argv[2] + +with open(filename1, 'r') as cairo_lang_input_file, open(filename2, 'r') as cairo_vm_input_file: + cairo_lang_input = json.load(cairo_lang_input_file) + cairo_vm_input = json.load(cairo_vm_input_file) + # The trace_path & memory_path fields contain the path of each file which will differ + # as we use a different extension to differentiate between python & rust vm outputs + cairo_lang_input["trace_path"] = "" + cairo_lang_input["memory_path"] = "" + + cairo_vm_input["trace_path"] = "" + cairo_vm_input["memory_path"] = "" + + if cairo_lang_input == cairo_vm_input: + + print(f"Comparison succesful for {filename1} vs {filename2}") + else: + print(f"Comparison unsuccesful for {filename1} vs {filename2}") + exit(1) diff --git a/vm/src/tests/compare_vm_state.sh b/vm/src/tests/compare_vm_state.sh index a4ad23b0ab..24388d20bf 100755 --- a/vm/src/tests/compare_vm_state.sh +++ b/vm/src/tests/compare_vm_state.sh @@ -9,6 +9,7 @@ exit_code=0 trace=false memory=false air_public_input=false +air_private_input=false passed_tests=0 failed_tests=0 @@ -26,6 +27,9 @@ for i in $@; do "air_public_input") air_public_input=true echo "Requested air_public_input comparison" ;; + "air_private_input") air_private_input=true + echo "Requested air_private_input comparison" + ;; *) ;; esac @@ -76,6 +80,16 @@ for file in $(ls $tests_path | grep .cairo$ | sed -E 's/\.cairo$//'); do passed_tests=$((passed_tests + 1)) fi fi + + if $air_private_input; then + if ! ./air_private_input_comparator.py $path_file.air_private_input $path_file.rs.air_private_input; then + echo "Air Private Input differs for $file" + exit_code=1 + failed_tests=$((failed_tests + 1)) + else + passed_tests=$((passed_tests + 1)) + fi + fi done if test $failed_tests != 0; then diff --git a/vm/src/types/relocatable.rs b/vm/src/types/relocatable.rs index 353be453ae..e903b1670c 100644 --- a/vm/src/types/relocatable.rs +++ b/vm/src/types/relocatable.rs @@ -320,6 +320,7 @@ impl MaybeRelocatable { } } + // TODO: Check if its more performant to use get_int instead /// Returns a reference to the inner value if it is a Felt252, returns None otherwise. pub fn get_int_ref(&self) -> Option<&Felt252> { match self { @@ -328,6 +329,14 @@ impl MaybeRelocatable { } } + /// Returns the inner value if it is a Felt252, returns None otherwise. + pub fn get_int(&self) -> Option { + match self { + MaybeRelocatable::Int(num) => Some(*num), + MaybeRelocatable::RelocatableValue(_) => None, + } + } + /// Returns the inner value if it is a Relocatable, returns None otherwise. pub fn get_relocatable(&self) -> Option { match self { diff --git a/vm/src/vm/runners/builtin_runner/bitwise.rs b/vm/src/vm/runners/builtin_runner/bitwise.rs index fea49fa89a..825aab3942 100644 --- a/vm/src/vm/runners/builtin_runner/bitwise.rs +++ b/vm/src/vm/runners/builtin_runner/bitwise.rs @@ -1,3 +1,4 @@ +use crate::air_private_input::{PrivateInput, PrivateInputPair}; use crate::stdlib::{boxed::Box, vec::Vec}; use crate::Felt252; use crate::{ @@ -191,6 +192,30 @@ impl BitwiseBuiltinRunner { let used_cells = self.get_used_cells(segments)?; Ok(div_ceil(used_cells, self.cells_per_instance as usize)) } + + pub fn air_private_input(&self, memory: &Memory) -> Vec { + let mut private_inputs = vec![]; + if let Some(segment) = memory.data.get(self.base) { + let segment_len = segment.len(); + for (index, off) in (0..segment_len) + .step_by(CELLS_PER_BITWISE as usize) + .enumerate() + { + // Add the input cells of each bitwise instance to the private inputs + if let (Ok(x), Ok(y)) = ( + memory.get_integer((self.base as isize, off).into()), + memory.get_integer((self.base as isize, off + 1).into()), + ) { + private_inputs.push(PrivateInput::Pair(PrivateInputPair { + index, + x: *x, + y: *y, + })) + } + } + } + private_inputs + } } #[cfg(test)] @@ -594,4 +619,49 @@ mod tests { )); assert_eq!(builtin.get_used_diluted_check_units(50, 25), 250); } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn get_air_private_input() { + let builtin: BuiltinRunner = + BitwiseBuiltinRunner::new(&BitwiseInstanceDef::default(), true).into(); + + let memory = memory![ + ((0, 0), 0), + ((0, 1), 1), + ((0, 2), 2), + ((0, 3), 3), + ((0, 4), 4), + ((0, 5), 5), + ((0, 6), 6), + ((0, 7), 7), + ((0, 8), 8), + ((0, 9), 9), + ((0, 10), 10), + ((0, 11), 11), + ((0, 12), 12), + ((0, 13), 13), + ((0, 14), 14) + ]; + assert_eq!( + builtin.air_private_input(&memory), + (vec![ + PrivateInput::Pair(PrivateInputPair { + index: 0, + x: 0.into(), + y: 1.into() + }), + PrivateInput::Pair(PrivateInputPair { + index: 1, + x: 5.into(), + y: 6.into() + }), + PrivateInput::Pair(PrivateInputPair { + index: 2, + x: 10.into(), + y: 11.into() + }), + ]), + ); + } } diff --git a/vm/src/vm/runners/builtin_runner/ec_op.rs b/vm/src/vm/runners/builtin_runner/ec_op.rs index 938cd390fb..c824f0153d 100644 --- a/vm/src/vm/runners/builtin_runner/ec_op.rs +++ b/vm/src/vm/runners/builtin_runner/ec_op.rs @@ -1,3 +1,4 @@ +use crate::air_private_input::{PrivateInput, PrivateInputEcOp}; use crate::stdlib::{borrow::Cow, prelude::*}; use crate::stdlib::{cell::RefCell, collections::HashMap}; use crate::types::instance_definitions::ec_op_instance_def::{ @@ -260,6 +261,36 @@ impl EcOpBuiltinRunner { m = {m:?}\n Q = {q:?}.") } + + pub fn air_private_input(&self, memory: &Memory) -> Vec { + let mut private_inputs = vec![]; + if let Some(segment) = memory.data.get(self.base) { + let segment_len = segment.len(); + for (index, off) in (0..segment_len) + .step_by(CELLS_PER_EC_OP as usize) + .enumerate() + { + // Add the input cells of each ec_op instance to the private inputs + if let (Ok(p_x), Ok(p_y), Ok(q_x), Ok(q_y), Ok(m)) = ( + memory.get_integer((self.base as isize, off).into()), + memory.get_integer((self.base as isize, off + 1).into()), + memory.get_integer((self.base as isize, off + 2).into()), + memory.get_integer((self.base as isize, off + 3).into()), + memory.get_integer((self.base as isize, off + 4).into()), + ) { + private_inputs.push(PrivateInput::EcOp(PrivateInputEcOp { + index, + p_x: *p_x, + p_y: *p_y, + m: *m, + q_x: *q_x, + q_y: *q_y, + })) + } + } + } + private_inputs + } } #[cfg(test)] @@ -959,4 +990,30 @@ mod tests { Ok(_) => panic!("Expected run to fail"), } } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn get_air_private_input() { + let builtin: BuiltinRunner = + EcOpBuiltinRunner::new(&EcOpInstanceDef::default(), true).into(); + + let memory = memory![ + ((0, 0), 0), + ((0, 1), 1), + ((0, 2), 2), + ((0, 3), 3), + ((0, 4), 4) + ]; + assert_eq!( + builtin.air_private_input(&memory), + (vec![PrivateInput::EcOp(PrivateInputEcOp { + index: 0, + p_x: 0.into(), + p_y: 1.into(), + m: 4.into(), + q_x: 2.into(), + q_y: 3.into(), + })]) + ); + } } diff --git a/vm/src/vm/runners/builtin_runner/hash.rs b/vm/src/vm/runners/builtin_runner/hash.rs index 555f71f473..f8e8fbe333 100644 --- a/vm/src/vm/runners/builtin_runner/hash.rs +++ b/vm/src/vm/runners/builtin_runner/hash.rs @@ -1,3 +1,4 @@ +use crate::air_private_input::{PrivateInput, PrivateInputPair}; use crate::stdlib::{cell::RefCell, prelude::*}; use crate::types::errors::math_errors::MathError; use crate::types::instance_definitions::pedersen_instance_def::{ @@ -187,6 +188,30 @@ impl HashBuiltinRunner { } BuiltinAdditionalData::Hash(verified_addresses) } + + pub fn air_private_input(&self, memory: &Memory) -> Vec { + let mut private_inputs = vec![]; + if let Some(segment) = memory.data.get(self.base) { + let segment_len = segment.len(); + for (index, off) in (0..segment_len) + .step_by(CELLS_PER_HASH as usize) + .enumerate() + { + // Add the input cells of each hash instance to the private inputs + if let (Ok(x), Ok(y)) = ( + memory.get_integer((self.base as isize, off).into()), + memory.get_integer((self.base as isize, off + 1).into()), + ) { + private_inputs.push(PrivateInput::Pair(PrivateInputPair { + index, + x: *x, + y: *y, + })) + } + } + } + private_inputs + } } #[cfg(test)] @@ -547,4 +572,43 @@ mod tests { BuiltinAdditionalData::Hash(verified_addresses) ) } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn get_air_private_input() { + let builtin: BuiltinRunner = HashBuiltinRunner::new(None, true).into(); + + let memory = memory![ + ((0, 0), 0), + ((0, 1), 1), + ((0, 2), 2), + ((0, 3), 3), + ((0, 4), 4), + ((0, 5), 5), + ((0, 6), 6), + ((0, 7), 7), + ((0, 8), 8), + ((0, 9), 9) + ]; + assert_eq!( + builtin.air_private_input(&memory), + (vec![ + PrivateInput::Pair(PrivateInputPair { + index: 0, + x: 0.into(), + y: 1.into() + }), + PrivateInput::Pair(PrivateInputPair { + index: 1, + x: 3.into(), + y: 4.into() + }), + PrivateInput::Pair(PrivateInputPair { + index: 2, + x: 6.into(), + y: 7.into() + }), + ]), + ); + } } diff --git a/vm/src/vm/runners/builtin_runner/keccak.rs b/vm/src/vm/runners/builtin_runner/keccak.rs index cf5c1868db..3eed4a61b6 100644 --- a/vm/src/vm/runners/builtin_runner/keccak.rs +++ b/vm/src/vm/runners/builtin_runner/keccak.rs @@ -1,3 +1,4 @@ +use crate::air_private_input::{PrivateInput, PrivateInputKeccakState}; use crate::math_utils::safe_div_usize; use crate::stdlib::{cell::RefCell, collections::HashMap, prelude::*}; use crate::types::instance_definitions::keccak_instance_def::KeccakInstanceDef; @@ -220,6 +221,51 @@ impl KeccakBuiltinRunner { keccak::f1600(&mut keccak_input); Ok(keccak_input.iter().flat_map(|x| x.to_le_bytes()).collect()) } + + pub fn air_private_input(&self, memory: &Memory) -> Vec { + let mut private_inputs = vec![]; + if let Some(segment) = memory.data.get(self.base) { + let segment_len = segment.len(); + for (index, off) in (0..segment_len) + .step_by(self.cells_per_instance as usize) + .enumerate() + { + // Add the input cells of each keccak instance to the private inputs + if let ( + Ok(input_s0), + Ok(input_s1), + Ok(input_s2), + Ok(input_s3), + Ok(input_s4), + Ok(input_s5), + Ok(input_s6), + Ok(input_s7), + ) = ( + memory.get_integer((self.base as isize, off).into()), + memory.get_integer((self.base as isize, off + 1).into()), + memory.get_integer((self.base as isize, off + 2).into()), + memory.get_integer((self.base as isize, off + 3).into()), + memory.get_integer((self.base as isize, off + 4).into()), + memory.get_integer((self.base as isize, off + 5).into()), + memory.get_integer((self.base as isize, off + 6).into()), + memory.get_integer((self.base as isize, off + 7).into()), + ) { + private_inputs.push(PrivateInput::KeccakState(PrivateInputKeccakState { + index, + input_s0: *input_s0, + input_s1: *input_s1, + input_s2: *input_s2, + input_s3: *input_s3, + input_s4: *input_s4, + input_s5: *input_s5, + input_s6: *input_s6, + input_s7: *input_s7, + })) + } + } + } + private_inputs + } } #[cfg(test)] @@ -680,4 +726,36 @@ mod tests { let output_bytes = KeccakBuiltinRunner::keccak_f(input_bytes); assert_eq!(output_bytes, Ok(expected_output_bytes.to_vec())); } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn get_air_private_input() { + let builtin: BuiltinRunner = + KeccakBuiltinRunner::new(&KeccakInstanceDef::default(), true).into(); + + let memory = memory![ + ((0, 0), 0), + ((0, 1), 1), + ((0, 2), 2), + ((0, 3), 3), + ((0, 4), 4), + ((0, 5), 5), + ((0, 6), 6), + ((0, 7), 7) + ]; + assert_eq!( + builtin.air_private_input(&memory), + (vec![PrivateInput::KeccakState(PrivateInputKeccakState { + index: 0, + input_s0: 0.into(), + input_s1: 1.into(), + input_s2: 2.into(), + input_s3: 3.into(), + input_s4: 4.into(), + input_s5: 5.into(), + input_s6: 6.into(), + input_s7: 7.into() + }),]), + ); + } } diff --git a/vm/src/vm/runners/builtin_runner/mod.rs b/vm/src/vm/runners/builtin_runner/mod.rs index 4b27c80eb4..99778c6333 100644 --- a/vm/src/vm/runners/builtin_runner/mod.rs +++ b/vm/src/vm/runners/builtin_runner/mod.rs @@ -1,3 +1,4 @@ +use crate::air_private_input::PrivateInput; use crate::math_utils::safe_div_usize; use crate::stdlib::prelude::*; use crate::types::relocatable::{MaybeRelocatable, Relocatable}; @@ -483,6 +484,20 @@ impl BuiltinRunner { } } + // Returns information about the builtin that should be added to the AIR private input. + pub fn air_private_input(&self, memory: &Memory) -> Vec { + match self { + BuiltinRunner::RangeCheck(builtin) => builtin.air_private_input(memory), + BuiltinRunner::Bitwise(builtin) => builtin.air_private_input(memory), + BuiltinRunner::Hash(builtin) => builtin.air_private_input(memory), + BuiltinRunner::EcOp(builtin) => builtin.air_private_input(memory), + BuiltinRunner::Poseidon(builtin) => builtin.air_private_input(memory), + BuiltinRunner::Signature(builtin) => builtin.air_private_input(memory), + BuiltinRunner::Keccak(builtin) => builtin.air_private_input(memory), + _ => vec![], + } + } + #[cfg(test)] pub(crate) fn set_stop_ptr(&mut self, stop_ptr: usize) { match self { diff --git a/vm/src/vm/runners/builtin_runner/output.rs b/vm/src/vm/runners/builtin_runner/output.rs index 75fce41506..1e3bfe3ad4 100644 --- a/vm/src/vm/runners/builtin_runner/output.rs +++ b/vm/src/vm/runners/builtin_runner/output.rs @@ -450,4 +450,13 @@ mod tests { }) ) } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn get_air_private_input() { + let builtin: BuiltinRunner = OutputBuiltinRunner::new(true).into(); + + let memory = memory![((0, 0), 0), ((0, 1), 1), ((0, 2), 2), ((0, 3), 3)]; + assert!(builtin.air_private_input(&memory).is_empty()); + } } diff --git a/vm/src/vm/runners/builtin_runner/poseidon.rs b/vm/src/vm/runners/builtin_runner/poseidon.rs index 75c809cd7f..a668ba324b 100644 --- a/vm/src/vm/runners/builtin_runner/poseidon.rs +++ b/vm/src/vm/runners/builtin_runner/poseidon.rs @@ -1,3 +1,4 @@ +use crate::air_private_input::{PrivateInput, PrivateInputPoseidonState}; use crate::stdlib::{cell::RefCell, collections::HashMap, prelude::*}; use crate::types::errors::math_errors::MathError; use crate::types::instance_definitions::poseidon_instance_def::{ @@ -163,6 +164,32 @@ impl PoseidonBuiltinRunner { Ok(pointer) } } + + pub fn air_private_input(&self, memory: &Memory) -> Vec { + let mut private_inputs = vec![]; + if let Some(segment) = memory.data.get(self.base) { + let segment_len = segment.len(); + for (index, off) in (0..segment_len) + .step_by(CELLS_PER_POSEIDON as usize) + .enumerate() + { + // Add the input cells of each poseidon instance to the private inputs + if let (Ok(input_s0), Ok(input_s1), Ok(input_s2)) = ( + memory.get_integer((self.base as isize, off).into()), + memory.get_integer((self.base as isize, off + 1).into()), + memory.get_integer((self.base as isize, off + 2).into()), + ) { + private_inputs.push(PrivateInput::PoseidonState(PrivateInputPoseidonState { + index, + input_s0: *input_s0, + input_s1: *input_s1, + input_s2: *input_s2, + })) + } + } + } + private_inputs + } } #[cfg(test)] @@ -410,4 +437,42 @@ mod tests { Ok(None) ); } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn get_air_private_input() { + let builtin: BuiltinRunner = PoseidonBuiltinRunner::new(None, true).into(); + + let memory = memory![ + ((0, 0), 0), + ((0, 1), 1), + ((0, 2), 2), + ((0, 3), 3), + ((0, 4), 4), + ((0, 5), 5), + ((0, 6), 6), + ((0, 7), 7), + ((0, 8), 8), + ((0, 9), 9), + ((0, 10), 10), + ((0, 11), 11) + ]; + assert_eq!( + builtin.air_private_input(&memory), + (vec![ + PrivateInput::PoseidonState(PrivateInputPoseidonState { + index: 0, + input_s0: 0.into(), + input_s1: 1.into(), + input_s2: 2.into(), + }), + PrivateInput::PoseidonState(PrivateInputPoseidonState { + index: 1, + input_s0: 6.into(), + input_s1: 7.into(), + input_s2: 8.into(), + }), + ]), + ); + } } diff --git a/vm/src/vm/runners/builtin_runner/range_check.rs b/vm/src/vm/runners/builtin_runner/range_check.rs index 1bee53200a..ba07f6f253 100644 --- a/vm/src/vm/runners/builtin_runner/range_check.rs +++ b/vm/src/vm/runners/builtin_runner/range_check.rs @@ -1,6 +1,9 @@ -use crate::stdlib::{ - cmp::{max, min}, - prelude::*, +use crate::{ + air_private_input::{PrivateInput, PrivateInputValue}, + stdlib::{ + cmp::{max, min}, + prelude::*, + }, }; use crate::Felt252; @@ -192,6 +195,18 @@ impl RangeCheckBuiltinRunner { Ok(pointer) } } + + pub fn air_private_input(&self, memory: &Memory) -> Vec { + let mut private_inputs = vec![]; + if let Some(segment) = memory.data.get(self.base) { + for (index, val) in segment.iter().enumerate() { + if let Some(value) = val.as_ref().and_then(|cell| cell.get_value().get_int()) { + private_inputs.push(PrivateInput::Value(PrivateInputValue { index, value })) + } + } + } + private_inputs + } } #[cfg(test)] @@ -588,4 +603,29 @@ mod tests { vm.segments.segment_used_sizes = Some(vec![1]); assert_eq!(builtin_runner.get_used_perm_range_check_units(&vm), Ok(8)); } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn get_air_private_input() { + let builtin: BuiltinRunner = RangeCheckBuiltinRunner::new(None, 4, true).into(); + + let memory = memory![((0, 0), 0), ((0, 1), 1), ((0, 2), 2)]; + assert_eq!( + builtin.air_private_input(&memory), + (vec![ + PrivateInput::Value(PrivateInputValue { + index: 0, + value: 0.into(), + }), + PrivateInput::Value(PrivateInputValue { + index: 1, + value: 1.into(), + }), + PrivateInput::Value(PrivateInputValue { + index: 2, + value: 2.into(), + }), + ]), + ); + } } diff --git a/vm/src/vm/runners/builtin_runner/segment_arena.rs b/vm/src/vm/runners/builtin_runner/segment_arena.rs index fd8bd75599..82c9e72aea 100644 --- a/vm/src/vm/runners/builtin_runner/segment_arena.rs +++ b/vm/src/vm/runners/builtin_runner/segment_arena.rs @@ -496,4 +496,13 @@ mod tests { let builtin: BuiltinRunner = SegmentArenaBuiltinRunner::new(true).into(); assert_eq!(builtin.instances_per_component(), 1) } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn get_air_private_input() { + let builtin: BuiltinRunner = SegmentArenaBuiltinRunner::new(true).into(); + + let memory = memory![((0, 0), 0), ((0, 1), 1), ((0, 2), 2), ((0, 3), 3)]; + assert!(builtin.air_private_input(&memory).is_empty()); + } } diff --git a/vm/src/vm/runners/builtin_runner/signature.rs b/vm/src/vm/runners/builtin_runner/signature.rs index f5d256103a..d854afa05a 100644 --- a/vm/src/vm/runners/builtin_runner/signature.rs +++ b/vm/src/vm/runners/builtin_runner/signature.rs @@ -1,6 +1,9 @@ +use crate::air_private_input::{PrivateInput, PrivateInputSignature, SignatureInput}; +use crate::math_utils::div_mod; use crate::stdlib::{cell::RefCell, collections::HashMap, prelude::*, rc::Rc}; use crate::types::errors::math_errors::MathError; +use crate::types::instance_definitions::ecdsa_instance_def::CELLS_PER_SIGNATURE; use crate::vm::runners::cairo_pie::BuiltinAdditionalData; use crate::Felt252; use crate::{ @@ -16,9 +19,20 @@ use crate::{ }, }, }; +use lazy_static::lazy_static; +use num_bigint::{BigInt, Sign}; use num_integer::div_ceil; +use num_traits::{Num, One}; use starknet_crypto::{verify, FieldElement, Signature}; +lazy_static! { + static ref EC_ORDER: BigInt = BigInt::from_str_radix( + "3618502788666131213697322783095070105526743751716087489154079457884512865583", + 10 + ) + .unwrap(); +} + use super::SIGNATURE_BUILTIN_NAME; #[derive(Debug, Clone)] @@ -227,6 +241,36 @@ impl SignatureBuiltinRunner { .collect(); BuiltinAdditionalData::Signature(signatures) } + + pub fn air_private_input(&self, memory: &Memory) -> Vec { + let mut private_inputs = vec![]; + for (addr, signature) in self.signatures.borrow().iter() { + if let (Ok(pubkey), Ok(msg)) = (memory.get_integer(*addr), memory.get_integer(addr + 1)) + { + private_inputs.push(PrivateInput::Signature(PrivateInputSignature { + index: addr + .offset + .saturating_sub(self.base) + .checked_div(CELLS_PER_SIGNATURE as usize) + .unwrap_or_default(), + pubkey: *pubkey, + msg: *msg, + signature_input: SignatureInput { + r: Felt252::from_bytes_be(&signature.r.to_bytes_be()), + w: Felt252::from( + &div_mod( + &BigInt::one(), + &BigInt::from_bytes_be(Sign::Plus, &signature.s.to_bytes_be()), + &EC_ORDER, + ) + .unwrap_or_default(), + ), + }, + })) + } + } + private_inputs + } } #[cfg(test)] diff --git a/vm/src/vm/runners/cairo_runner.rs b/vm/src/vm/runners/cairo_runner.rs index 57b72fe8b7..11cc89dc3c 100644 --- a/vm/src/vm/runners/cairo_runner.rs +++ b/vm/src/vm/runners/cairo_runner.rs @@ -1,4 +1,5 @@ use crate::{ + air_private_input::AirPrivateInput, air_public_input::{PublicInput, PublicInputError}, stdlib::{ any::Any, @@ -1408,6 +1409,17 @@ impl CairoRunner { .ok_or(PublicInputError::NoRangeCheckLimits)?, ) } + + pub fn get_air_private_input(&self, vm: &VirtualMachine) -> AirPrivateInput { + let mut private_inputs = HashMap::new(); + for builtin in vm.builtin_runners.iter() { + private_inputs.insert( + builtin.name(), + builtin.air_private_input(&vm.segments.memory), + ); + } + AirPrivateInput(private_inputs) + } } #[derive(Clone, Debug, Eq, PartialEq)] @@ -1510,6 +1522,7 @@ impl MulAssign for ExecutionResources { #[cfg(test)] mod tests { use super::*; + use crate::air_private_input::{PrivateInput, PrivateInputSignature, SignatureInput}; use crate::cairo_run::{cairo_run, CairoRunConfig}; use crate::stdlib::collections::{HashMap, HashSet}; use crate::vm::runners::builtin_runner::{ @@ -5435,4 +5448,45 @@ mod tests { // segment sizes vm.segments.segment_sizes = HashMap::from([(0, 0), (1, 2), (2, 0), (3, 0)]); } + + #[test] + fn get_air_private_input() { + let program_content = + include_bytes!("../../../../cairo_programs/proof_programs/common_signature.json"); + let (runner, vm) = crate::cairo_run::cairo_run( + program_content, + &CairoRunConfig { + proof_mode: true, + layout: "all_cairo", + ..Default::default() + }, + &mut BuiltinHintProcessor::new_empty(), + ) + .unwrap(); + let air_private_input = runner.get_air_private_input(&vm); + assert!(air_private_input.0[HASH_BUILTIN_NAME].is_empty()); + assert!(air_private_input.0[RANGE_CHECK_BUILTIN_NAME].is_empty()); + assert!(air_private_input.0[BITWISE_BUILTIN_NAME].is_empty()); + assert!(air_private_input.0[EC_OP_BUILTIN_NAME].is_empty()); + assert!(air_private_input.0[KECCAK_BUILTIN_NAME].is_empty()); + assert!(air_private_input.0[POSEIDON_BUILTIN_NAME].is_empty()); + assert_eq!( + air_private_input.0[SIGNATURE_BUILTIN_NAME], + vec![PrivateInput::Signature(PrivateInputSignature { + index: 0, + pubkey: felt_hex!( + "0x3d60886c2353d93ec2862e91e23036cd9999a534481166e5a616a983070434d" + ), + msg: felt_hex!("0xa9e"), + signature_input: SignatureInput { + r: felt_hex!( + "0x6d2e2e00dfceffd6a375db04764da249a5a1534c7584738dfe01cb3944a33ee" + ), + w: felt_hex!( + "0x396362a34ff391372fca63f691e27753ce8f0c2271a614cbd240e1dc1596b28" + ) + } + })] + ); + } } From 4568a409dd777deb5710c91e2facae07c753ef8f Mon Sep 17 00:00:00 2001 From: fmoletta <99273364+fmoletta@users.noreply.github.com> Date: Mon, 15 Jan 2024 20:37:01 +0200 Subject: [PATCH 6/7] Add `air_public_input` flag to cairo1-run (#1539) * Add proof_mode flag to cairo1-run * Add Changelog entry * Clippy * clippy * Add `air_public_input` flag * Progress * Update builtins stop ptrs when running cairo 1 * Change visibility * Change visibility * Fix * Fix trace not enables * Build execution public memory * Handle EcOp case * Fix typo * Use cleaner solution * Fix * Improve comments * Add changelog entry * Move logic inside vm --- CHANGELOG.md | 2 + cairo1-run/src/main.rs | 106 ++++++++++++++++++++++++++++-------- vm/src/types/relocatable.rs | 4 +- vm/src/vm/vm_core.rs | 17 ++++++ 4 files changed, 104 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8306723148..0554308098 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ #### Upcoming Changes +* feat: Add `air_public_input` flag to `cairo1-run` [#1539] (https://github.com/lambdaclass/cairo-vm/pull/1539) + * feat: Implement air_private_input [#1552](https://github.com/lambdaclass/cairo-vm/pull/1552) * feat: Add `proof_mode` flag to `cairo1-run` [#1537] (https://github.com/lambdaclass/cairo-vm/pull/1537) diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index 1231f7d69c..f593f5e190 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -47,6 +47,10 @@ use cairo_vm::vm::errors::memory_errors::MemoryError; use cairo_vm::vm::errors::runner_errors::RunnerError; use cairo_vm::vm::errors::trace_errors::TraceError; use cairo_vm::vm::errors::vm_errors::VirtualMachineError; +use cairo_vm::vm::runners::builtin_runner::{ + BITWISE_BUILTIN_NAME, EC_OP_BUILTIN_NAME, HASH_BUILTIN_NAME, OUTPUT_BUILTIN_NAME, + POSEIDON_BUILTIN_NAME, RANGE_CHECK_BUILTIN_NAME, SIGNATURE_BUILTIN_NAME, +}; use cairo_vm::vm::runners::cairo_runner::RunnerMode; use cairo_vm::{ serde::deserialize_program::ReferenceManager, @@ -79,6 +83,8 @@ struct Args { layout: String, #[clap(long = "proof_mode", value_parser)] proof_mode: bool, + #[clap(long = "air_public_input", value_parser)] + air_public_input: Option, } fn validate_layout(value: &str) -> Result { @@ -173,6 +179,13 @@ impl FileWriter { fn run(args: impl Iterator) -> Result, Error> { let args = Args::try_parse_from(args)?; + if args.air_public_input.is_some() && !args.proof_mode { + let error = Args::command().error( + clap::error::ErrorKind::ArgumentConflict, + "--air_public_input can only be used in proof_mode.", + ); + return Err(Error::Cli(error)); + } let compiler_config = CompilerConfig { replace_ids: true, @@ -289,20 +302,14 @@ fn run(args: impl Iterator) -> Result, Erro let mut runner = CairoRunner::new_v2(&program, &args.layout, runner_mode)?; - let mut vm = VirtualMachine::new(args.trace_file.is_some()); + let mut vm = VirtualMachine::new(args.trace_file.is_some() || args.air_public_input.is_some()); let end = runner.initialize(&mut vm)?; additional_initialization(&mut vm, data_len)?; // Run it until the end/ infinite loop in proof_mode runner.run_until_pc(end, &mut vm, &mut hint_processor)?; - - if args.proof_mode { - // Then pad it to the power of 2 - runner.run_until_next_power_of_2(&mut vm, &mut hint_processor)?; - } else { - runner.end_run(true, false, &mut vm, &mut hint_processor)?; - } + runner.end_run(false, false, &mut vm, &mut hint_processor)?; // Fetch return type data let return_type_id = main_func @@ -351,8 +358,59 @@ fn run(args: impl Iterator) -> Result, Erro } } + // Set stop pointers for builtins so we can obtain the air public input + if args.air_public_input.is_some() { + // Cairo 1 programs have other return values aside from the used builtin's final pointers, so we need to hand-pick them + let ret_types_sizes = main_func + .signature + .ret_types + .iter() + .map(|id| type_sizes.get(id).cloned().unwrap_or_default()); + let ret_types_and_sizes = main_func + .signature + .ret_types + .iter() + .zip(ret_types_sizes.clone()); + + let full_ret_types_size: i16 = ret_types_sizes.sum(); + let mut stack_pointer = (vm.get_ap() - (full_ret_types_size as usize).saturating_sub(1)) + .map_err(VirtualMachineError::Math)?; + + // Calculate the stack_ptr for each return builtin in the return values + let mut builtin_name_to_stack_pointer = HashMap::new(); + for (id, size) in ret_types_and_sizes { + if let Some(ref name) = id.debug_name { + let builtin_name = match &*name.to_string() { + "RangeCheck" => RANGE_CHECK_BUILTIN_NAME, + "Poseidon" => POSEIDON_BUILTIN_NAME, + "EcOp" => EC_OP_BUILTIN_NAME, + "Bitwise" => BITWISE_BUILTIN_NAME, + "Pedersen" => HASH_BUILTIN_NAME, + "Output" => OUTPUT_BUILTIN_NAME, + "Ecdsa" => SIGNATURE_BUILTIN_NAME, + _ => { + stack_pointer.offset += size as usize; + continue; + } + }; + builtin_name_to_stack_pointer.insert(builtin_name, stack_pointer); + } + stack_pointer.offset += size as usize; + } + // Set stop pointer for each builtin + vm.builtins_final_stack_from_stack_pointer_dict(&builtin_name_to_stack_pointer)?; + + // Build execution public memory + runner.finalize_segments(&mut vm)?; + } + runner.relocate(&mut vm, true)?; + if let Some(file_path) = args.air_public_input { + let json = runner.get_air_public_input(&vm)?.serialize_json()?; + std::fs::write(file_path, json)?; + } + if let Some(trace_path) = args.trace_file { let relocated_trace = runner .relocated_trace @@ -694,7 +752,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/fibonacci.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/fibonacci.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/fibonacci.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_fibonacci_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(89)]); @@ -702,7 +760,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/factorial.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/factorial.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/factorial.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_factorial_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(3628800)]); @@ -710,7 +768,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/array_get.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/array_get.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/array_get.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_array_get_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(3)]); @@ -718,7 +776,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/enum_flow.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/enum_flow.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/enum_flow.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_enum_flow_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(300)]); @@ -726,7 +784,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/enum_match.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/enum_match.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/enum_match.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_enum_match_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(10), MaybeRelocatable::from(felt_str("3618502788666131213697322783095070105623107215331596699973092056135872020471"))]); @@ -734,7 +792,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/hello.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/hello.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/hello.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_hello_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(1), MaybeRelocatable::from(1234)]); @@ -742,7 +800,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/ops.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/ops.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/ops.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_ops_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(6)]); @@ -750,7 +808,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/print.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/print.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/print.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_print_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![]); @@ -758,7 +816,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/recursion.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/recursion.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/recursion.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_recursion_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(felt_str("1154076154663935037074198317650845438095734251249125412074882362667803016453"))]); @@ -766,7 +824,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/sample.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/sample.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/sample.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_sample_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(felt_str("5050"))]); @@ -774,7 +832,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/poseidon.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/poseidon.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/poseidon.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_poseidon_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(felt_str("1099385018355113290651252669115094675591288647745213771718157553170111442461"))]); @@ -782,7 +840,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/poseidon_pedersen.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/poseidon_pedersen.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/poseidon_pedersen.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_poseidon_pedersen_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(felt_str("1036257840396636296853154602823055519264738423488122322497453114874087006398"))]); @@ -790,7 +848,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/pedersen_example.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/pedersen_example.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/pedersen_example.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_pedersen_example_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(felt_str("1089549915800264549621536909767699778745926517555586332772759280702396009108"))]); @@ -798,7 +856,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/simple.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/simple.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/simple.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_simple_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(1)]); @@ -806,7 +864,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/simple_struct.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/simple_struct.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/simple_struct.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_simple_struct_ok(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(100)]); @@ -814,7 +872,7 @@ mod tests { #[rstest] #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo"].as_slice())] - #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/dictionaries.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null"].as_slice())] fn test_run_dictionaries(#[case] args: &[&str]) { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(1024)]); diff --git a/vm/src/types/relocatable.rs b/vm/src/types/relocatable.rs index e903b1670c..4bac0bba46 100644 --- a/vm/src/types/relocatable.rs +++ b/vm/src/types/relocatable.rs @@ -15,7 +15,9 @@ use serde::{Deserialize, Serialize}; use arbitrary::Arbitrary; #[cfg_attr(all(feature = "arbitrary", feature = "std"), derive(Arbitrary))] -#[derive(Eq, Ord, Hash, PartialEq, PartialOrd, Clone, Copy, Debug, Serialize, Deserialize)] +#[derive( + Eq, Ord, Hash, PartialEq, PartialOrd, Clone, Copy, Debug, Serialize, Deserialize, Default, +)] pub struct Relocatable { pub segment_index: isize, pub offset: usize, diff --git a/vm/src/vm/vm_core.rs b/vm/src/vm/vm_core.rs index 98b0c32904..2a634de1a8 100644 --- a/vm/src/vm/vm_core.rs +++ b/vm/src/vm/vm_core.rs @@ -1077,6 +1077,23 @@ impl VirtualMachine { }) .collect() } + + #[doc(hidden)] + pub fn builtins_final_stack_from_stack_pointer_dict( + &mut self, + builtin_name_to_stack_pointer: &HashMap<&'static str, Relocatable>, + ) -> Result<(), RunnerError> { + for builtin in self.builtin_runners.iter_mut() { + builtin.final_stack( + &self.segments, + builtin_name_to_stack_pointer + .get(builtin.name()) + .cloned() + .unwrap_or_default(), + )?; + } + Ok(()) + } } pub struct VirtualMachineBuilder { From 1a78237b32c9489e120c4c920bff548bf2a83b89 Mon Sep 17 00:00:00 2001 From: fmoletta <99273364+fmoletta@users.noreply.github.com> Date: Mon, 15 Jan 2024 23:36:00 +0200 Subject: [PATCH 7/7] Add `args` flag to `cairo1-run` (#1551) * Add proof_mode flag to cairo1-run * Add Changelog entry * Clippy * clippy * Add `air_public_input` flag * Progress * Update builtins stop ptrs when running cairo 1 * Change visibility * Change visibility * Fix * Fix trace not enables * Build execution public memory * Handle EcOp case * Fix typo * Use cleaner solution * Fix * Improve comments * Add changelog entry * Add args flag * Handle arguments * Handle arg size & add tests * Parse array arguments * Fix language * reorder * Add changelog entry * Move programs with args to an inner folder * Fix README example * Apply input arguments fix from cairo_lang * Add test * Fix tests --- CHANGELOG.md | 2 + cairo1-run/README.md | 21 +- cairo1-run/src/main.rs | 214 +++++++++++++++--- .../with_input/array_input_sum.cairo | 5 + .../with_input/branching.cairo | 7 + .../cairo-1-programs/with_input/tensor.cairo | 9 + vm/src/vm/vm_core.rs | 4 +- 7 files changed, 225 insertions(+), 37 deletions(-) create mode 100644 cairo_programs/cairo-1-programs/with_input/array_input_sum.cairo create mode 100644 cairo_programs/cairo-1-programs/with_input/branching.cairo create mode 100644 cairo_programs/cairo-1-programs/with_input/tensor.cairo diff --git a/CHANGELOG.md b/CHANGELOG.md index 0554308098..e4a343a8e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ #### Upcoming Changes +* feat: Add `args` flag to `cairo1-run` [#15551] (https://github.com/lambdaclass/cairo-vm/pull/15551) + * feat: Add `air_public_input` flag to `cairo1-run` [#1539] (https://github.com/lambdaclass/cairo-vm/pull/1539) * feat: Implement air_private_input [#1552](https://github.com/lambdaclass/cairo-vm/pull/1552) diff --git a/cairo1-run/README.md b/cairo1-run/README.md index 95be3b5ecb..dfa835af8c 100644 --- a/cairo1-run/README.md +++ b/cairo1-run/README.md @@ -5,9 +5,10 @@ A cairo-vm crate to run Cairo 1 Programs Once you are inside the `./cairo1-run` folder, use the CLI with the following commands To install the required dependencies(cairo corelib) run + ```bash make deps -``` +``` Now that you have the dependencies necessary to run the tests, you can run: @@ -16,16 +17,32 @@ make test ``` To execute a cairo 1 program + ```bash cargo run ../cairo_programs/cairo-1-programs/fibonacci.cairo ``` Arguments to generate the trace and memory files + ```bash cargo run ../cairo_programs/cairo-1-programs/fibonacci.cairo --trace_file ../cairo_programs/cairo-1-programs/fibonacci.trace --memory_file ../cairo_programs/cairo-1-programs/fibonacci.memory ``` +To pass arguments to `main` + +* Separate arguments with a whitespace inbetween +* In order to pass arrays, wrap array values between brackets + +Example: + +```bash + +cargo run ../cairo_programs/cairo-1-programs/with_input/array_input_sum.cairo --layout all_cairo --args '2 [1 2 3 4] 0 [9 8]' + +``` + To execute all the cairo 1 programs inside `../cairo_programs/cairo-1-programs/` and generate the corresponding trace and the memory files + ```bash make run -``` +``` diff --git a/cairo1-run/src/main.rs b/cairo1-run/src/main.rs index f593f5e190..24e8dc8df6 100644 --- a/cairo1-run/src/main.rs +++ b/cairo1-run/src/main.rs @@ -4,6 +4,7 @@ use cairo_lang_casm::casm; use cairo_lang_casm::casm_extend; use cairo_lang_casm::hints::Hint; use cairo_lang_casm::instructions::Instruction; +use cairo_lang_compiler::db; use cairo_lang_compiler::{compile_cairo_project_at_path, CompilerConfig}; use cairo_lang_sierra::extensions::bitwise::BitwiseType; use cairo_lang_sierra::extensions::core::{CoreLibfunc, CoreType}; @@ -30,6 +31,7 @@ use cairo_lang_sierra_to_casm::metadata::MetadataComputationConfig; use cairo_lang_sierra_to_casm::metadata::MetadataError; use cairo_lang_sierra_to_casm::{compiler::compile, metadata::calc_metadata}; use cairo_lang_sierra_type_size::get_type_size_map; +use cairo_lang_utils::extract_matches; use cairo_lang_utils::ordered_hash_map::OrderedHashMap; use cairo_lang_utils::unordered_hash_map::UnorderedHashMap; use cairo_vm::air_public_input::PublicInputError; @@ -85,6 +87,54 @@ struct Args { proof_mode: bool, #[clap(long = "air_public_input", value_parser)] air_public_input: Option, + // Arguments should be spaced, with array elements placed between brackets + // For example " --args '1 2 [1 2 3]'" will yield 3 arguments, with the last one being an array of 3 elements + #[clap(long = "args", default_value = "", value_parser=process_args)] + args: FuncArgs, +} + +#[derive(Debug, Clone)] +enum FuncArg { + Array(Vec), + Single(Felt252), +} + +#[derive(Debug, Clone, Default)] +struct FuncArgs(Vec); + +fn process_args(value: &str) -> Result { + if value.is_empty() { + return Ok(FuncArgs::default()); + } + let mut args = Vec::new(); + let mut input = value.split(' '); + while let Some(value) = input.next() { + // First argument in an array + if value.starts_with('[') { + let mut array_arg = + vec![Felt252::from_dec_str(value.strip_prefix('[').unwrap()).unwrap()]; + // Process following args in array + let mut array_end = false; + while !array_end { + if let Some(value) = input.next() { + // Last arg in array + if value.ends_with(']') { + array_arg + .push(Felt252::from_dec_str(value.strip_suffix(']').unwrap()).unwrap()); + array_end = true; + } else { + array_arg.push(Felt252::from_dec_str(value).unwrap()) + } + } + } + // Finalize array + args.push(FuncArg::Array(array_arg)) + } else { + // Single argument + args.push(FuncArg::Single(Felt252::from_dec_str(value).unwrap())) + } + } + Ok(FuncArgs(args)) } fn validate_layout(value: &str) -> Result { @@ -142,6 +192,13 @@ enum Error { NoInfoForType(ConcreteTypeId), #[error("Failed to extract return values from VM")] FailedToExtractReturnValues, + #[error("Function expects arguments of size {expected} and received {actual} instead.")] + ArgumentsSizeMismatch { expected: i16, actual: i16 }, + #[error("Function param {param_index} only partially contains argument {arg_index}.")] + ArgumentUnaligned { + param_index: usize, + arg_index: usize, + }, } pub struct FileWriter { @@ -217,6 +274,7 @@ fn run(args: impl Iterator) -> Result, Erro main_func, initial_gas, args.proof_mode, + &args.args.0, )?; // Get the user program instructions @@ -301,7 +359,6 @@ fn run(args: impl Iterator) -> Result, Erro }; let mut runner = CairoRunner::new_v2(&program, &args.layout, runner_mode)?; - let mut vm = VirtualMachine::new(args.trace_file.is_some() || args.air_public_input.is_some()); let end = runner.initialize(&mut vm)?; @@ -332,7 +389,7 @@ fn run(args: impl Iterator) -> Result, Erro { // Check the failure flag (aka first return value) if return_values.first() != Some(&MaybeRelocatable::from(0)) { - // In case of failure, extract the error from teh return values (aka last two values) + // In case of failure, extract the error from the return values (aka last two values) let panic_data_end = return_values .last() .ok_or(Error::FailedToExtractReturnValues)? @@ -553,13 +610,36 @@ fn create_entry_code( func: &Function, initial_gas: usize, proof_mode: bool, + args: &Vec, ) -> Result<(Vec, Vec), Error> { let mut ctx = casm! {}; // The builtins in the formatting expected by the runner. let (builtins, builtin_offset) = get_function_builtins(func); // Load all vecs to memory. + // Load all array args content to memory. + let mut array_args_data = vec![]; let mut ap_offset: i16 = 0; - let after_vecs_offset = ap_offset; + for arg in args { + let FuncArg::Array(values) = arg else { continue }; + array_args_data.push(ap_offset); + casm_extend! {ctx, + %{ memory[ap + 0] = segments.add() %} + ap += 1; + } + for (i, v) in values.iter().enumerate() { + let arr_at = (i + 1) as i16; + casm_extend! {ctx, + [ap + 0] = (v.to_bigint()); + [ap + 0] = [[ap - arr_at] + (i as i16)], ap++; + }; + } + ap_offset += (1 + values.len()) as i16; + } + let mut array_args_data_iter = array_args_data.iter(); + let after_arrays_data_offset = ap_offset; + let mut arg_iter = args.iter().enumerate(); + let mut param_index = 0; + let mut expected_arguments_size = 0; if func.signature.param_types.iter().any(|ty| { get_info(sierra_program_registry, ty) .map(|x| x.long_id.generic_id == SegmentArenaType::ID) @@ -582,7 +662,6 @@ fn create_entry_code( for ty in func.signature.param_types.iter() { let info = get_info(sierra_program_registry, ty) .ok_or_else(|| Error::NoInfoForType(ty.clone()))?; - let ty_size = type_sizes[ty]; let generic_ty = &info.long_id.generic_id; if let Some(offset) = builtin_offset.get(generic_ty) { let mut offset = *offset; @@ -593,50 +672,71 @@ fn create_entry_code( casm_extend! {ctx, [ap + 0] = [fp - offset], ap++; } + ap_offset += 1; } else if generic_ty == &SystemType::ID { casm_extend! {ctx, %{ memory[ap + 0] = segments.add() %} ap += 1; } + ap_offset += 1; } else if generic_ty == &GasBuiltinType::ID { casm_extend! {ctx, [ap + 0] = initial_gas, ap++; } + ap_offset += 1; } else if generic_ty == &SegmentArenaType::ID { - let offset = -ap_offset + after_vecs_offset; + let offset = -ap_offset + after_arrays_data_offset; casm_extend! {ctx, [ap + 0] = [ap + offset] + 3, ap++; } - // This code should be re enabled to make the programs work with arguments - - // } else if let Some(Arg::Array(_)) = arg_iter.peek() { - // let values = extract_matches!(arg_iter.next().unwrap(), Arg::Array); - // let offset = -ap_offset + vecs.pop().unwrap(); - // expected_arguments_size += 1; - // casm_extend! {ctx, - // [ap + 0] = [ap + (offset)], ap++; - // [ap + 0] = [ap - 1] + (values.len()), ap++; - // } - // } else { - // let arg_size = ty_size; - // expected_arguments_size += arg_size as usize; - // for _ in 0..arg_size { - // if let Some(value) = arg_iter.next() { - // let value = extract_matches!(value, Arg::Value); - // casm_extend! {ctx, - // [ap + 0] = (value.to_bigint()), ap++; - // } - // } - // } + ap_offset += 1; + } else { + let ty_size = type_sizes[ty]; + let param_ap_offset_end = ap_offset + ty_size; + expected_arguments_size += ty_size; + while ap_offset < param_ap_offset_end { + let Some((arg_index, arg)) = arg_iter.next() else { + break; + }; + match arg { + FuncArg::Single(value) => { + casm_extend! {ctx, + [ap + 0] = (value.to_bigint()), ap++; + } + ap_offset += 1; + } + FuncArg::Array(values) => { + let offset = -ap_offset + array_args_data_iter.next().unwrap(); + casm_extend! {ctx, + [ap + 0] = [ap + (offset)], ap++; + [ap + 0] = [ap - 1] + (values.len()), ap++; + } + ap_offset += 2; + if ap_offset > param_ap_offset_end { + return Err(Error::ArgumentUnaligned { + param_index, + arg_index, + }); + } + } + } + } + param_index += 1; }; - ap_offset += ty_size; } - // if expected_arguments_size != args.len() { - // return Err(RunnerError::ArgumentsSizeMismatch { - // expected: expected_arguments_size, - // actual: args.len(), - // }); - // } + let actual_args_size = args + .iter() + .map(|arg| match arg { + FuncArg::Single(_) => 1, + FuncArg::Array(_) => 2, + }) + .sum::(); + if expected_arguments_size != actual_args_size { + return Err(Error::ArgumentsSizeMismatch { + expected: expected_arguments_size, + actual: actual_args_size, + }); + } let before_final_call = ctx.current_code_offset; let final_call_size = 3; @@ -877,4 +977,52 @@ mod tests { let args = args.iter().cloned().map(String::from); assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(1024)]); } + + #[rstest] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/branching.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--args", "0"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/branching.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "0"].as_slice())] + fn test_run_branching_0(#[case] args: &[&str]) { + let args = args.iter().cloned().map(String::from); + assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(1)]); + } + + #[rstest] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/branching.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--args", "17"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/branching.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "96"].as_slice())] + fn test_run_branching_not_0(#[case] args: &[&str]) { + let args = args.iter().cloned().map(String::from); + assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(0)]); + } + + #[rstest] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/branching.cairo", "--layout", "all_cairo"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/branching.cairo", "--layout", "all_cairo", "--proof_mode"].as_slice())] + fn test_run_branching_no_args(#[case] args: &[&str]) { + let args = args.iter().cloned().map(String::from); + assert_matches!(run(args), Err(Error::ArgumentsSizeMismatch { expected, actual }) if expected == 1 && actual == 0); + } + + #[rstest] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/branching.cairo", "--layout", "all_cairo","--args", "1 2 3"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/branching.cairo", "--layout", "all_cairo", "--proof_mode", "--args", "1 2 3"].as_slice())] + fn test_run_branching_too_many_args(#[case] args: &[&str]) { + let args = args.iter().cloned().map(String::from); + assert_matches!(run(args), Err(Error::ArgumentsSizeMismatch { expected, actual }) if expected == 1 && actual == 3); + } + + #[rstest] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/array_input_sum.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--args", "2 [1 2 3 4] 0 [9 8]"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/array_input_sum.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "2 [1 2 3 4] 0 [9 8]"].as_slice())] + fn test_array_input_sum(#[case] args: &[&str]) { + let args = args.iter().cloned().map(String::from); + assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(12)]); + } + + #[rstest] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/tensor.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--args", "[2 2] [1 2 3 4]"].as_slice())] + #[case(["cairo1-run", "../cairo_programs/cairo-1-programs/with_input/tensor.cairo", "--trace_file", "/dev/null", "--memory_file", "/dev/null", "--layout", "all_cairo", "--proof_mode", "--air_public_input", "/dev/null", "--args", "[2 2] [1 2 3 4]"].as_slice())] + fn test_tensor(#[case] args: &[&str]) { + let args = args.iter().cloned().map(String::from); + assert_matches!(run(args), Ok(res) if res == vec![MaybeRelocatable::from(1)]); + } } diff --git a/cairo_programs/cairo-1-programs/with_input/array_input_sum.cairo b/cairo_programs/cairo-1-programs/with_input/array_input_sum.cairo new file mode 100644 index 0000000000..1c75b21549 --- /dev/null +++ b/cairo_programs/cairo-1-programs/with_input/array_input_sum.cairo @@ -0,0 +1,5 @@ +use array::ArrayTrait; + +fn main(index_a: u32, array_a: Array, index_b: u32, array_b: Array) -> u32 { + *array_a.at(index_a) + *array_b.at(index_b) +} diff --git a/cairo_programs/cairo-1-programs/with_input/branching.cairo b/cairo_programs/cairo-1-programs/with_input/branching.cairo new file mode 100644 index 0000000000..639763b849 --- /dev/null +++ b/cairo_programs/cairo-1-programs/with_input/branching.cairo @@ -0,0 +1,7 @@ +fn main(argc: u32) -> u8 { + if argc == 0 { + 1_u8 + } else { + 0_u8 + } +} diff --git a/cairo_programs/cairo-1-programs/with_input/tensor.cairo b/cairo_programs/cairo-1-programs/with_input/tensor.cairo new file mode 100644 index 0000000000..6d35b905d5 --- /dev/null +++ b/cairo_programs/cairo-1-programs/with_input/tensor.cairo @@ -0,0 +1,9 @@ +#[derive(Copy, Drop)] +struct Tensor { + shape: Span, + data: Span +} + +fn main(tensor: Tensor) -> u32 { + *tensor.data.at(0) +} diff --git a/vm/src/vm/vm_core.rs b/vm/src/vm/vm_core.rs index 2a634de1a8..38be9b1281 100644 --- a/vm/src/vm/vm_core.rs +++ b/vm/src/vm/vm_core.rs @@ -78,8 +78,8 @@ impl DeducedOperands { pub struct VirtualMachine { pub(crate) run_context: RunContext, - pub(crate) builtin_runners: Vec, - pub(crate) segments: MemorySegmentManager, + pub builtin_runners: Vec, + pub segments: MemorySegmentManager, pub(crate) trace: Option>, pub(crate) current_step: usize, pub(crate) rc_limits: Option<(isize, isize)>,