diff --git a/Cargo.lock b/Cargo.lock index da2929c9d..6a9cae1ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -230,6 +230,15 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + [[package]] name = "atty" version = "0.2.14" @@ -543,6 +552,15 @@ dependencies = [ "tikv-jemallocator", ] +[[package]] +name = "cobs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror 2.0.17", +] + [[package]] name = "colorchoice" version = "1.0.4" @@ -668,6 +686,12 @@ dependencies = [ "itertools 0.10.5", ] +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + [[package]] name = "crossbeam" version = "0.8.4" @@ -934,6 +958,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + [[package]] name = "enum-ordinalize" version = "4.3.2" @@ -1314,6 +1350,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1347,6 +1392,20 @@ version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32", + "rustc_version", + "serde", + "spin", + "stable_deref_trait", +] + [[package]] name = "heck" version = "0.5.0" @@ -1627,6 +1686,7 @@ dependencies = [ "executor", "log", "math", + "postcard", "rayon", "serde", "sha3", @@ -1699,6 +1759,15 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + [[package]] name = "log" version = "0.4.29" @@ -2030,6 +2099,19 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "postcard" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "heapless", + "serde", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -2383,6 +2465,15 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "1.1.3" @@ -2462,6 +2553,12 @@ dependencies = [ "serde_json", ] +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "sec1" version = "0.7.3" @@ -2496,6 +2593,12 @@ dependencies = [ "cc", ] +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + [[package]] name = "serde" version = "1.0.228" @@ -2643,6 +2746,15 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + [[package]] name = "spki" version = "0.7.3" @@ -2653,6 +2765,12 @@ dependencies = [ "der", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + [[package]] name = "stark" version = "0.1.0" diff --git a/Makefile b/Makefile index 81bc03a8c..4cea3c318 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ .PHONY: deps deps-linux deps-macos compile-programs-asm compile-programs-rust compile-bench \ -compile-programs clean-asm clean-rust clean-bench clean-shared clean test test-asm \ +compile-programs compile-recursion-elfs clean-asm clean-rust clean-bench clean-shared \ +clean-recursion-elfs clean test test-asm \ test-rust test-executor test-flamegraph flamegraph-prover \ test-fast test-prover test-prover-all test-disk-spill test-math-cuda test-cuda-integration \ bench-math-cuda bench-prover bench-prover-cuda build check clippy fmt lint regen-ethrex-fixtures \ @@ -46,6 +47,13 @@ BENCH_PROGRAM_DIRS := $(dir $(wildcard $(BENCH_PROGRAMS_DIR)/*/Cargo.toml)) BENCH_PROGRAMS := $(notdir $(basename $(BENCH_PROGRAM_DIRS:%/=%))) BENCH_ARTIFACTS := $(addprefix $(BENCH_ARTIFACTS_DIR)/, $(addsuffix .elf, $(BENCH_PROGRAMS))) +# Recursion smoke-test guests, in bench_vs/lambda/ (shared with bench_vs/run.sh) +# rather than executor/programs/. The recursion guest is the in-VM STARK verifier. +RECURSION_GUESTS_DIR=./bench_vs/lambda +RECURSION_ARTIFACTS_DIR=./executor/program_artifacts/recursion +RECURSION_GUESTS := empty fibonacci recursion +RECURSION_ARTIFACTS := $(addprefix $(RECURSION_ARTIFACTS_DIR)/, $(addsuffix .elf, $(RECURSION_GUESTS))) + # Override with: make ... SYSROOT_DIR=$HOME/.lambda-vm-sysroot # to install the sysroot in a user-writable location and avoid sudo. SYSROOT_DIR ?= /opt/lambda-vm-sysroot @@ -133,7 +141,12 @@ compile-programs-rust: prepare-sysroot $(RUST_ARTIFACTS) compile-bench: prepare-sysroot $(BENCH_ARTIFACTS) -compile-programs: compile-programs-asm compile-programs-rust compile-bench +compile-programs: compile-programs-asm compile-programs-rust compile-bench compile-recursion-elfs + +compile-recursion-elfs: prepare-sysroot $(RECURSION_ARTIFACTS) + +$(RECURSION_ARTIFACTS_DIR): + mkdir -p $@ $(RUST_ARTIFACTS_DIR): @@ -142,13 +155,19 @@ $(RUST_ARTIFACTS_DIR): $(BENCH_ARTIFACTS_DIR): mkdir -p $@ +# The guest .elf rules depend on FORCE so their recipe always runs: cargo already +# tracks the full dependency graph, so we let it decide what to rebuild (a fast +# no-op when nothing changed) rather than re-encode that in Make prereqs. +.PHONY: FORCE +FORCE: + # Compile rust (64-bit) # Order-only `| prepare-sysroot` so a direct `make .../foo.elf` provisions the sysroot # first (the aggregate compile-programs-rust/compile-bench targets already do, but a # bare pattern-rule invocation like `make -B .../ethrex.elf` would otherwise skip it # and fail to compile guest C dependencies). Order-only because prepare-sysroot is # .PHONY — a normal prereq would force a rebuild every time; its recipe is idempotent. -$(RUST_ARTIFACTS_DIR)/%.elf: $(RUST_PROGRAMS_DIR)/%/Cargo.toml | prepare-sysroot $(RUST_ARTIFACTS_DIR) +$(RUST_ARTIFACTS_DIR)/%.elf: FORCE | prepare-sysroot $(RUST_ARTIFACTS_DIR) cd $(RUST_PROGRAMS_DIR)/$* && \ CARGO_TARGET_DIR=$(abspath $(SHARED_TARGET_DIR)) \ CFLAGS_riscv64im_lambda_vm_elf="$(SYSROOT_CFLAGS)" \ @@ -160,7 +179,7 @@ $(RUST_ARTIFACTS_DIR)/%.elf: $(RUST_PROGRAMS_DIR)/%/Cargo.toml | prepare-sysroot cp $(SHARED_TARGET_DIR)/riscv64im-lambda-vm-elf/release/$* $@ # Compile rust benches (64-bit) -$(BENCH_ARTIFACTS_DIR)/%.elf: $(BENCH_PROGRAMS_DIR)/%/Cargo.toml | prepare-sysroot $(BENCH_ARTIFACTS_DIR) +$(BENCH_ARTIFACTS_DIR)/%.elf: FORCE | prepare-sysroot $(BENCH_ARTIFACTS_DIR) cd $(BENCH_PROGRAMS_DIR)/$* && \ CARGO_TARGET_DIR=$(abspath $(SHARED_TARGET_DIR)) \ CFLAGS_riscv64im_lambda_vm_elf="$(SYSROOT_CFLAGS)" \ @@ -171,6 +190,22 @@ $(BENCH_ARTIFACTS_DIR)/%.elf: $(BENCH_PROGRAMS_DIR)/%/Cargo.toml | prepare-sysro -Z json-target-spec cp $(SHARED_TARGET_DIR)/riscv64im-lambda-vm-elf/release/$* $@ +# Recursion-suite guests: same standard guest flags as compile-bench (std-inclusive +# build-std works for both the no_std inner guests and the std recursion verifier). +# The crate's binary is -bench; copy it to .elf so prover tests read +# prebuilt artifacts like every other program (see +# prover/src/tests/recursion_smoke_test.rs), instead of shelling out. +$(RECURSION_ARTIFACTS_DIR)/%.elf: FORCE | prepare-sysroot $(RECURSION_ARTIFACTS_DIR) + cd $(RECURSION_GUESTS_DIR)/$* && \ + CARGO_TARGET_DIR=$(abspath $(SHARED_TARGET_DIR)) \ + CFLAGS_riscv64im_lambda_vm_elf="$(SYSROOT_CFLAGS)" \ + rustup run nightly-2026-02-01 cargo build --release \ + --target $(RV64_TARGET_SPEC) \ + -Z build-std=core,alloc,std,compiler_builtins,panic_abort \ + -Z build-std-features=compiler-builtins-mem \ + -Z json-target-spec + cp $(SHARED_TARGET_DIR)/riscv64im-lambda-vm-elf/release/$*-bench $@ + clean-asm: -rm -rf $(ASM_ARTIFACTS_DIR) @@ -183,7 +218,10 @@ clean-bench: clean-shared: -rm -rf $(SHARED_TARGET_DIR) -clean: clean-asm clean-rust clean-bench clean-shared +clean-recursion-elfs: + -rm -rf $(RECURSION_ARTIFACTS_DIR) + +clean: clean-asm clean-rust clean-bench clean-shared clean-recursion-elfs test-executor: compile-programs cargo test -p executor @@ -225,8 +263,9 @@ test-fast: test-prover: cargo test -p lambda-vm-prover -# Prover tests including slow ones -test-prover-all: +# Prover tests including slow ones. The recursion smoke tests (#[ignore]d) read +# prebuilt guest ELFs from executor/program_artifacts/recursion/, so build them first. +test-prover-all: compile-recursion-elfs cargo test -p lambda-vm-prover -- --include-ignored # Prover tests with debug-checks (shows bus balance report) diff --git a/bench_vs/lambda/empty/.cargo/config.toml b/bench_vs/lambda/empty/.cargo/config.toml new file mode 100644 index 000000000..be730c3ec --- /dev/null +++ b/bench_vs/lambda/empty/.cargo/config.toml @@ -0,0 +1,6 @@ +[target.riscv64im-lambda-vm-elf] +rustflags = [ + "-C", "link-arg=-e", + "-C", "link-arg=main", + "-C", "passes=lower-atomic" +] diff --git a/bench_vs/lambda/empty/Cargo.lock b/bench_vs/lambda/empty/Cargo.lock new file mode 100644 index 000000000..11dcd8cb1 --- /dev/null +++ b/bench_vs/lambda/empty/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "empty-bench" +version = "0.1.0" diff --git a/bench_vs/lambda/empty/Cargo.toml b/bench_vs/lambda/empty/Cargo.toml new file mode 100644 index 000000000..a6e4a0530 --- /dev/null +++ b/bench_vs/lambda/empty/Cargo.toml @@ -0,0 +1,8 @@ +[workspace] + +[package] +name = "empty-bench" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/bench_vs/lambda/empty/src/main.rs b/bench_vs/lambda/empty/src/main.rs new file mode 100644 index 000000000..555cae897 --- /dev/null +++ b/bench_vs/lambda/empty/src/main.rs @@ -0,0 +1,28 @@ +#![no_std] +#![no_main] + +use core::arch::asm; +use core::panic::PanicInfo; + +const SYSCALL_HALT: u64 = 93; + +#[panic_handler] +fn panic(_info: &PanicInfo) -> ! { + loop {} +} + +fn halt() -> ! { + unsafe { + asm!( + "ecall", + in("a0") 0u64, + in("a7") SYSCALL_HALT, + options(noreturn), + ); + } +} + +#[unsafe(no_mangle)] +pub fn main() -> ! { + halt() +} diff --git a/bench_vs/lambda/recursion/.cargo/config.toml b/bench_vs/lambda/recursion/.cargo/config.toml new file mode 100644 index 000000000..f5ea686ff --- /dev/null +++ b/bench_vs/lambda/recursion/.cargo/config.toml @@ -0,0 +1,7 @@ +[target.riscv64im-lambda-vm-elf] +rustflags = [ + "-C", "link-arg=-e", + "-C", "link-arg=main", + "--cfg", "getrandom_backend=\"custom\"", + "-C", "passes=lower-atomic" +] diff --git a/bench_vs/lambda/recursion/Cargo.lock b/bench_vs/lambda/recursion/Cargo.lock new file mode 100644 index 000000000..66048ba81 --- /dev/null +++ b/bench_vs/lambda/recursion/Cargo.lock @@ -0,0 +1,1210 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cobs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror 2.0.18", +] + +[[package]] +name = "const-default" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b396d1f76d455557e1218ec8066ae14bba60b4b36ecd55577ba979f5db7ecaa" + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crypto" +version = "0.1.0" +dependencies = [ + "digest", + "math", + "rand 0.8.6", + "rand_chacha 0.3.1", + "serde", + "sha3", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "ecsm" +version = "0.1.0" +dependencies = [ + "k256", + "num-bigint", + "num-traits", +] + +[[package]] +name = "either" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "ff", + "generic-array", + "group", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "embedded-alloc" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f2de9133f68db0d4627ad69db767726c99ff8585272716708227008d3f1bddd" +dependencies = [ + "const-default", + "critical-section", + "linked_list_allocator", + "rlsf", +] + +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" + +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] +name = "executor" +version = "0.1.0" +dependencies = [ + "ecsm", + "rustc-demangle", + "thiserror 1.0.69", +] + +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "half" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32", + "rustc_version", + "serde", + "spin", + "stable_deref_trait", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "js-sys" +version = "0.3.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "k256" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +dependencies = [ + "cfg-if", + "elliptic-curve", +] + +[[package]] +name = "keccak" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lambda-vm-prover" +version = "0.1.0" +dependencies = [ + "crypto", + "ecsm", + "executor", + "log", + "math", + "serde", + "sha3", + "stark", + "sysinfo", +] + +[[package]] +name = "lambda-vm-syscalls" +version = "0.1.0" +dependencies = [ + "embedded-alloc", + "getrandom 0.2.17", + "getrandom 0.3.4", + "lazy_static", + "rand 0.9.4", + "riscv", + "thiserror 1.0.69", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "linked_list_allocator" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b23ac50abb8261cb38c6e2a7192d3302e0836dac1628f6a93b82b4fad185897" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" + +[[package]] +name = "math" +version = "0.1.0" +dependencies = [ + "getrandom 0.2.17", + "num-bigint", + "num-traits", + "rand 0.8.6", + "rayon", + "serde", + "serde_json", +] + +[[package]] +name = "memchr" +version = "2.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" + +[[package]] +name = "ntapi" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3b335231dfd352ffb0f8017f3b6027a4917f7df785ea2143d8af2adc66980ae" +dependencies = [ + "winapi", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "postcard" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "heapless", + "serde", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "rayon" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "recursion-bench" +version = "0.1.0" +dependencies = [ + "lambda-vm-prover", + "lambda-vm-syscalls", + "postcard", +] + +[[package]] +name = "riscv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05cfa3f7b30c84536a9025150d44d26b8e1cc20ddf436448d74cd9591eefb25" +dependencies = [ + "critical-section", + "embedded-hal", + "paste", + "riscv-macros", + "riscv-pac", +] + +[[package]] +name = "riscv-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d323d13972c1b104aa036bc692cd08b822c8bbf23d79a27c526095856499799" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "riscv-pac" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8188909339ccc0c68cfb5a04648313f09621e8b87dc03095454f1a11f6c5d436" + +[[package]] +name = "rlsf" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1646a59a9734b8b7a0ac51689388a60fe1625d4b956348e9de07591a1478457a" +dependencies = [ + "cfg-if", + "const-default", + "libc", + "rustversion", + "svgbobdoc", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half", + "serde", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "serde_json" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "sha3" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "stark" +version = "0.1.0" +dependencies = [ + "crypto", + "itertools", + "log", + "math", + "serde", + "serde_cbor", + "sha3", + "thiserror 1.0.69", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "svgbobdoc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2c04b93fc15d79b39c63218f15e3fdffaa4c227830686e3b7c5f41244eb3e50" +dependencies = [ + "base64", + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-width", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sysinfo" +version = "0.31.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "355dbe4f8799b304b05e1b0f05fc59b2a18d36645cf169607da45bde2f69a1be" +dependencies = [ + "core-foundation-sys", + "libc", + "memchr", + "ntapi", + "windows", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl 2.0.18", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.4+wasi-0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.118", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" +dependencies = [ + "windows-core", + "windows-targets", +] + +[[package]] +name = "windows-core" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-targets", +] + +[[package]] +name = "windows-implement" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "windows-interface" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "zerocopy" +version = "0.8.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "zeroize" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/bench_vs/lambda/recursion/Cargo.toml b/bench_vs/lambda/recursion/Cargo.toml new file mode 100644 index 000000000..511c2e848 --- /dev/null +++ b/bench_vs/lambda/recursion/Cargo.toml @@ -0,0 +1,15 @@ +[workspace] + +[package] +name = "recursion-bench" +version = "0.1.0" +edition = "2024" + +[dependencies] +# The in-VM STARK verifier. `default-features = false` drops `parallel` (no +# threads in-guest) and `sysinfo`; the prove-side code compiles but is dead-code +# eliminated since this guest only calls `verify_with_options`. A plain std guest +# (build-std includes std) — no no_std plumbing needed. +lambda-vm-prover = { path = "../../../prover", default-features = false } +lambda-vm-syscalls = { path = "../../../syscalls" } +postcard = { version = "1.0", features = ["alloc"] } diff --git a/bench_vs/lambda/recursion/src/main.rs b/bench_vs/lambda/recursion/src/main.rs new file mode 100644 index 000000000..4e7da8bef --- /dev/null +++ b/bench_vs/lambda/recursion/src/main.rs @@ -0,0 +1,33 @@ +//! Naive recursion guest: verifies an inner lambda-vm proof inside the VM. +//! +//! Private input layout (postcard-encoded): +//! `(VmProof, Vec, ProofOptions)` +//! where the `Vec` holds the inner program's ELF bytes and `ProofOptions` +//! specifies the parameters the inner prover used. Commits `[1]` on success. +//! +//! Not `no_std` (std/alloc are available — `build-std` provides them, and the +//! prover links as a normal std crate; its prove-side code is dead-code +//! eliminated since we only call `verify`). Like every other allocating guest +//! it is `#![no_main]` and uses the syscalls crate's global allocator (a large +//! `TlsfHeap`), initialized first thing in `main` — `verify` allocates far more +//! than the target's default heap provides. + +#![no_main] + +use lambda_vm_prover::{ProofOptions, VmProof}; + +#[unsafe(export_name = "main")] +pub fn main() -> i32 { + lambda_vm_syscalls::allocator::init_allocator(); + + let blob = lambda_vm_syscalls::syscalls::get_private_input(); + let (vm_proof, inner_elf, options): (VmProof, Vec, ProofOptions) = + postcard::from_bytes(&blob).expect("failed to deserialize recursion input"); + + let ok = lambda_vm_prover::verify_with_options(&vm_proof, &inner_elf, &options, None, None) + .expect("verify errored"); + assert!(ok, "inner proof failed verification"); + + lambda_vm_syscalls::syscalls::commit(&[1u8]); + 0 +} diff --git a/executor/src/vm/memory.rs b/executor/src/vm/memory.rs index 1bc4549fd..4cabb06bb 100644 --- a/executor/src/vm/memory.rs +++ b/executor/src/vm/memory.rs @@ -42,8 +42,10 @@ pub type U64HashMap = HashMap; /// The COMMIT AIR concatenates calls via the running `x254` index, so this /// is enforced as a running-total budget rather than a per-call limit. pub const MAX_PUBLIC_OUTPUT_TOTAL_SIZE: u64 = 1024 * 1024; -/// Maximum size of the private input memory region (in bytes). -pub const MAX_PRIVATE_INPUT_SIZE: u64 = 6700000; +/// Maximum size of the private input memory region (in bytes). 64 MiB so that a +/// whole `VmProof` can be passed as private input to a verifier guest (naive +/// recursion); the previous 6.7 MiB was too small to hold real proofs. +pub const MAX_PRIVATE_INPUT_SIZE: u64 = 64 * 1024 * 1024; /// Fixed high address where private input is mapped. Guest programs can read /// directly from this address (ZisK-style memory-mapped input). /// Layout: 4-byte LE length prefix at `PRIVATE_INPUT_START_INDEX`, then data at +4. diff --git a/prover/Cargo.toml b/prover/Cargo.toml index 61d2aa61a..ff6922f63 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -29,6 +29,7 @@ sha3 = { version = "0.10.8", default-features = false } env_logger = "*" criterion = { version = "0.5", default-features = false } bincode = "1" +postcard = { version = "1.0", features = ["alloc"] } tikv-jemallocator = "0.6" tikv-jemalloc-ctl = { version = "0.6", features = ["stats"] } tiny-keccak = { version = "2.0", features = ["keccak"] } diff --git a/prover/src/lib.rs b/prover/src/lib.rs index 143d1ead6..dd5da48cc 100644 --- a/prover/src/lib.rs +++ b/prover/src/lib.rs @@ -58,7 +58,9 @@ use crate::test_utils::{ create_register_air, create_shift_air, create_store_air, }; -use stark::proof::options::{GoldilocksCubicProofOptions, ProofOptions}; +// Re-exported so downstream verifier guests (e.g. the in-VM recursion guest) can +// name the proof-options type carried in their private input alongside `VmProof`. +pub use stark::proof::options::{GoldilocksCubicProofOptions, ProofOptions}; use stark::proof::stark::MultiProof; /// A run-length encoded range of contiguous zero-initialized 4KB pages. diff --git a/prover/src/tests/mod.rs b/prover/src/tests/mod.rs index 9b32e3b8c..9e650422f 100644 --- a/prover/src/tests/mod.rs +++ b/prover/src/tests/mod.rs @@ -61,6 +61,8 @@ pub mod page_tests; #[cfg(test)] pub mod prove_elfs_tests; #[cfg(test)] +pub mod recursion_smoke_test; +#[cfg(test)] pub mod register_tests; #[cfg(test)] pub mod shift_tests; diff --git a/prover/src/tests/recursion_smoke_test.rs b/prover/src/tests/recursion_smoke_test.rs new file mode 100644 index 000000000..d3050d237 --- /dev/null +++ b/prover/src/tests/recursion_smoke_test.rs @@ -0,0 +1,360 @@ +//! End-to-end naive recursion pipeline smoke tests. +//! +//! Each test: +//! 1. Proves an inner program on the host. +//! 2. Serializes `(VmProof, inner_elf, opts)` with postcard. +//! 3. Hands that as private input to the recursion guest. +//! 4. Either **proves** the recursion guest's execution and verifies the outer +//! proof (`OuterMode::Prove`), or merely **executes** the guest in-VM and +//! reads the committed marker off the trace (`OuterMode::ExecuteOnly`) — a +//! cheaper tier that skips the LDE/FRI that dominate the full pipeline. +//! +//! The guest ELFs are built by `make compile-recursion-elfs` (which the +//! `test-prover-all` make target depends on) and read from +//! `executor/program_artifacts/recursion/`, like every other program test. +//! +//! Tests are `#[ignore]`d because the outer proof runs the full STARK verifier +//! inside the VM (minutes per run, large memory footprint). + +use std::path::PathBuf; + +fn workspace_root() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .parent() + .expect("workspace root") + .to_path_buf() +} + +/// Read a recursion-suite guest ELF artifact, built by `make compile-recursion-elfs`. +fn read_guest_elf(root: &std::path::Path, name: &str) -> Vec { + let path = root.join(format!("executor/program_artifacts/recursion/{name}.elf")); + std::fs::read(&path).unwrap_or_else(|e| { + panic!( + "failed to read {} — run `make compile-recursion-elfs`: {e}", + path.display() + ) + }) +} + +/// Minimum-security FRI parameters: blowup=2, a single FRI query. Security is +/// intentionally terrible — used by the capacity-probing test, where the goal +/// is the smallest possible inner proof, not a sound one. +/// (`GoldilocksCubicProofOptions::with_blowup` derives a query count from a +/// 128-bit target, far more than we want here.) +const MIN_PROOF_OPTIONS: stark::proof::options::ProofOptions = + stark::proof::options::ProofOptions { + blowup_factor: 2, + fri_number_of_queries: 1, + coset_offset: 3, + grinding_factor: 1, + }; + +/// Prove `inner_elf` (fed `inner_input`) under `opts`, then package +/// `(proof, elf, opts)` into the postcard blob the recursion guest consumes as +/// its private input. `tag` prefixes the progress lines. Returns the inner +/// proof — callers that re-verify it on the host need it — next to the encoded +/// blob. +fn prove_inner_and_encode_blob( + tag: &str, + inner_elf: &[u8], + inner_input: &[u8], + opts: &stark::proof::options::ProofOptions, +) -> (crate::VmProof, Vec) { + eprintln!( + "[{tag}] proving inner (blowup={}, fri_queries={}) ...", + opts.blowup_factor, opts.fri_number_of_queries + ); + let inner_proof = crate::prove_with_options_and_inputs( + inner_elf, + inner_input, + opts, + &crate::MaxRowsConfig::default(), + ) + .expect("inner prove should succeed"); + + let blob = + postcard::to_allocvec(&(&inner_proof, &inner_elf, opts)).expect("postcard encode failed"); + eprintln!("[{tag}] postcard blob: {} bytes", blob.len()); + (inner_proof, blob) +} + +/// How far to take the recursion guest after it has been handed the inner +/// proof. The guest under test is the verifier either way — this only chooses +/// whether we also prove the guest's own execution. +#[derive(Clone, Copy, Debug)] +enum OuterMode { + /// Execute the guest in-VM and read the committed marker off the trace. + /// Skips the LDE blowup + FRI commit that dominate the full pipeline's + /// footprint, so it needs materially less RAM than `Prove`. + /// + /// "Less" is not "little": `Executor::run` retains a per-instruction log + /// and `Traces` materializes the full execution trace, so verifying even a + /// 1-query inner proof still needs tens of GB — it OOMs on a 36 GB box. + ExecuteOnly, + /// Prove the guest's execution and verify the outer proof on the host. The + /// full STARK verifier inside the VM — minutes per run, ~125 GB. + Prove, +} + +/// Execute the recursion guest in-VM on `blob` and return the bytes it +/// committed (the success marker the in-VM verifier emits). +fn execute_outer_and_commit(label: &str, recursion_elf_bytes: &[u8], blob: &[u8]) -> Vec { + use executor::elf::Elf; + use executor::vm::execution::Executor; + + eprintln!("[{label}] executing outer (recursion guest, in-VM verify) ..."); + let program = Elf::load(recursion_elf_bytes).expect("load recursion elf"); + let result = Executor::new(&program, blob.to_vec()) + .expect("executor new") + .run() + .expect("recursion guest execution failed (verify panicked in-VM?)"); + + let traces = crate::tables::trace_builder::Traces::from_elf_and_logs( + &program, + &result.logs, + &crate::MaxRowsConfig::default(), + blob, + #[cfg(feature = "disk-spill")] + stark::storage_mode::StorageMode::Ram, + ) + .expect("trace build"); + + eprintln!( + "[{label}] committed {} bytes: {:?} (as str: {:?})", + traces.public_output_bytes.len(), + traces.public_output_bytes, + String::from_utf8_lossy(&traces.public_output_bytes), + ); + traces.public_output_bytes +} + +/// Prove the recursion guest's execution on `blob`, verify the outer proof on +/// the host, and return the bytes the guest committed. +fn prove_outer_and_commit(label: &str, recursion_elf_bytes: &[u8], blob: &[u8]) -> Vec { + eprintln!("[{label}] proving outer (recursion guest) ..."); + let outer_proof = + crate::prove_with_inputs(recursion_elf_bytes, blob).expect("outer prove should succeed"); + eprintln!("[{label}] outer proof generated"); + + assert!( + crate::verify(&outer_proof, recursion_elf_bytes).expect("outer verify errored"), + "outer proof must verify on host" + ); + outer_proof.public_output +} + +/// Core pipeline: prove an inner program with the given options, hand the +/// proof+ELF+options to the recursion guest, then take the guest to `mode` +/// (execute-only or full prove) and assert it committed the `[1]` success +/// marker — i.e. the in-VM verifier accepted the inner proof. +fn run_recursion_pipeline_with_options( + label: &str, + inner_elf_bytes: &[u8], + inner_private_input: &[u8], + inner_proof_options: stark::proof::options::ProofOptions, + mode: OuterMode, +) { + let root = workspace_root(); + let recursion_elf_bytes = read_guest_elf(&root, "recursion"); + + let (inner_proof, blob) = prove_inner_and_encode_blob( + label, + inner_elf_bytes, + inner_private_input, + &inner_proof_options, + ); + + assert!( + crate::verify_with_options( + &inner_proof, + inner_elf_bytes, + &inner_proof_options, + None, + None + ) + .expect("inner verify errored"), + "inner proof must verify on host" + ); + assert!( + blob.len() < executor::vm::memory::MAX_PRIVATE_INPUT_SIZE as usize, + "recursion input exceeds MAX_PRIVATE_INPUT_SIZE" + ); + + let committed = match mode { + OuterMode::ExecuteOnly => execute_outer_and_commit(label, &recursion_elf_bytes, &blob), + OuterMode::Prove => prove_outer_and_commit(label, &recursion_elf_bytes, &blob), + }; + + assert_eq!( + committed, + vec![1u8], + "recursion guest must commit the [1] success marker (in-VM verify accepted)" + ); + eprintln!("[{label}] guest committed [1]: in-VM verify accepted ✓"); +} + +/// Convenience wrapper using `blowup=8` for the inner proof — the default for +/// the `empty` and `fibonacci` cases, chosen to keep outer-prove memory tractable. +fn run_recursion_pipeline( + label: &str, + inner_elf_bytes: &[u8], + inner_private_input: &[u8], + mode: OuterMode, +) { + let inner_proof_options = stark::proof::options::GoldilocksCubicProofOptions::with_blowup(8) + .expect("blowup=8 is always valid"); + run_recursion_pipeline_with_options( + label, + inner_elf_bytes, + inner_private_input, + inner_proof_options, + mode, + ); +} + +/// Reproduce the recursion guest's EXACT path on the host — decode the postcard +/// blob into `(VmProof, Vec, ProofOptions)` and call `verify_with_options`. +/// The cheapest regression guard in this file: no VM execution, just the +/// encode/decode contract plus a host verify, so it catches drift in the proof +/// format or the blob layout in seconds. Unlike the guest, a failure here +/// surfaces the actual error instead of an infinite abort loop. +#[test] +#[ignore = "needs prebuilt guest ELF (make compile-recursion-elfs)"] +fn test_recursion_blob_decodes_and_verifies_on_host() { + let root = workspace_root(); + let empty_elf_bytes = read_guest_elf(&root, "empty"); + let (_inner, blob) = + prove_inner_and_encode_blob("roundtrip", &empty_elf_bytes, &[], &MIN_PROOF_OPTIONS); + + // Decode exactly as the guest does. + let decoded: Result<(crate::VmProof, Vec, crate::ProofOptions), _> = + postcard::from_bytes(&blob); + let (vm_proof, inner_elf, options) = match decoded { + Ok(t) => t, + Err(e) => panic!("[roundtrip] postcard DECODE failed (this is the guest panic): {e}"), + }; + eprintln!( + "[roundtrip] decode ok: elf {} bytes, blowup {}", + inner_elf.len(), + options.blowup_factor + ); + + match crate::verify_with_options(&vm_proof, &inner_elf, &options, None, None) { + Ok(true) => eprintln!("[roundtrip] verify ok=true — guest path is sound"), + Ok(false) => panic!( + "[roundtrip] verify returned FALSE (guest hits assert!(ok)) — proof did not survive the postcard round-trip" + ), + Err(e) => panic!("[roundtrip] verify ERRORED (guest hits .expect): {e:?}"), + } +} + +// === Execute-only tier ======================================================== +// Mirrors the proving tests below, but stops at `OuterMode::ExecuteOnly`: the +// guest runs in-VM and we read the committed marker off the trace, skipping the +// outer STARK prove. Needs tens of GB (execution trace), not the ~125 GB the +// full outer prove wants — but still OOMs on a 36 GB box. + +/// Execute-only mirror of `test_recursion_prove_empty`: verify a `blowup=8` +/// proof of the empty program in-VM. +#[test] +#[ignore = "needs prebuilt recursion guest ELF + tens of GB RAM (execution trace)"] +fn test_recursion_execute_empty() { + let root = workspace_root(); + let empty_elf_bytes = read_guest_elf(&root, "empty"); + run_recursion_pipeline( + "recursion-exec-empty", + &empty_elf_bytes, + &[], + OuterMode::ExecuteOnly, + ); +} + +/// Execute-only mirror of `test_recursion_prove_1query`: smallest possible +/// inner proof (blowup=2, 1 query) → least guest work. +#[test] +#[ignore = "needs prebuilt recursion guest ELF + tens of GB RAM (execution trace)"] +fn test_recursion_execute_1query() { + let root = workspace_root(); + let empty_elf_bytes = read_guest_elf(&root, "empty"); + run_recursion_pipeline_with_options( + "recursion-exec-1query", + &empty_elf_bytes, + &[], + MIN_PROOF_OPTIONS, + OuterMode::ExecuteOnly, + ); +} + +/// Execute-only mirror of `test_recursion_prove`: verify a `blowup=8` proof of +/// fibonacci(10) in-VM. +#[test] +#[ignore = "needs prebuilt recursion guest ELF + tens of GB RAM (execution trace)"] +fn test_recursion_execute() { + let root = workspace_root(); + let fib_elf_bytes = read_guest_elf(&root, "fibonacci"); + + let n: u64 = 10; + let inner_private_input = n.to_le_bytes().to_vec(); + + run_recursion_pipeline( + "recursion-exec-fib", + &fib_elf_bytes, + &inner_private_input, + OuterMode::ExecuteOnly, + ); +} + +// === Full-prove tier ========================================================== + +/// Inner program: empty (halt immediately). Useful for measuring the +/// lambda-vm verifier's intrinsic recursion overhead — i.e. what it costs +/// to verify the smallest possible lambda-vm proof, with no inner workload. +#[test] +#[ignore = "slow: runs the full STARK verifier inside the VM"] +fn test_recursion_prove_empty() { + let root = workspace_root(); + let empty_elf_bytes = read_guest_elf(&root, "empty"); + run_recursion_pipeline( + "recursion-prove-empty", + &empty_elf_bytes, + &[], + OuterMode::Prove, + ); +} + +/// Inner program: empty, but with the absolute-minimum FRI parameters +/// (blowup=2, **fri_number_of_queries=1**). This is a "can the pipeline even +/// run end-to-end on a 125 GB box" experiment — security is intentionally +/// terrible. Use only for capacity probing. +#[test] +#[ignore = "slow: runs the full STARK verifier inside the VM"] +fn test_recursion_prove_1query() { + let root = workspace_root(); + let empty_elf_bytes = read_guest_elf(&root, "empty"); + + run_recursion_pipeline_with_options( + "recursion-prove-1query", + &empty_elf_bytes, + &[], + MIN_PROOF_OPTIONS, + OuterMode::Prove, + ); +} + +/// Inner program: fibonacci(10). +#[test] +#[ignore = "slow: runs the full STARK verifier inside the VM"] +fn test_recursion_prove() { + let root = workspace_root(); + let fib_elf_bytes = read_guest_elf(&root, "fibonacci"); + + let n: u64 = 10; + let inner_private_input = n.to_le_bytes().to_vec(); + + run_recursion_pipeline( + "recursion-prove-fib", + &fib_elf_bytes, + &inner_private_input, + OuterMode::Prove, + ); +} diff --git a/syscalls/src/random.rs b/syscalls/src/random.rs index ba84f795c..18a00e866 100644 --- a/syscalls/src/random.rs +++ b/syscalls/src/random.rs @@ -3,7 +3,7 @@ use std::sync::Mutex; use getrandom::Error; use lazy_static::lazy_static; use rand::Rng; -use rand::{SeedableRng, rngs::StdRng}; +use rand::{RngCore, SeedableRng, rngs::StdRng}; use crate::syscalls::print_string; @@ -31,10 +31,25 @@ pub unsafe extern "C" fn sys_rand(buf: *mut u8, len: usize) { } } +/// Custom getrandom v0.3 backend (selected via `--cfg getrandom_backend="custom"`). +/// +/// Fills `dest` with deterministic bytes from the constant-seeded `StdRng` (ChaCha20) +/// instead of panicking. This keeps weak-random consumers (e.g. `std::HashMap`'s +/// `RandomState`) working in-guest at the cost of being insecure — the seed is fixed. +/// +/// # Safety +/// +/// `dest_ptr` must be valid for writes of `len` bytes. #[unsafe(no_mangle)] unsafe extern "Rust" fn __getrandom_v03_custom( - _dest_ptr: *mut u8, - _len: usize, + dest_ptr: *mut u8, + len: usize, ) -> Result<(), Error> { - panic!("getrandom is not supported"); + print_string("getrandom called\n"); + print_string("WARNING: Using getrandom is insecure\n"); + + let mut rng = RNG.lock().unwrap(); + let dest = unsafe { core::slice::from_raw_parts_mut(dest_ptr, len) }; + rng.fill_bytes(dest); + Ok(()) }