diff --git a/Cargo.lock b/Cargo.lock index f6eea84d6..c6096590f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 4 [[package]] name = "addchain" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2e69442aa5628ea6951fa33e24efe8313f4321a91bd729fc2f75bdfc858570" +checksum = "2e33f6a175ec6a9e0aca777567f9ff7c3deefc255660df887e7fa3585e9801d8" dependencies = [ "num-bigint 0.3.3", "num-integer", @@ -57,9 +57,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.21" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", "anstyle-parse", @@ -72,15 +72,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anstyle-parse" -version = "0.2.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" dependencies = [ "utf8parse", ] @@ -107,9 +107,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.100" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "ark-bn254" @@ -118,8 +118,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d69eab57e8d2663efa5c63135b2af4f396d66424f88954c21104125ab6b3e6bc" dependencies = [ "ark-ec", - "ark-ff", - "ark-std", + "ark-ff 0.5.0", + "ark-std 0.5.0", ] [[package]] @@ -129,10 +129,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce" dependencies = [ "ahash", - "ark-ff", + "ark-ff 0.5.0", "ark-poly", - "ark-serialize", - "ark-std", + "ark-serialize 0.5.0", + "ark-std 0.5.0", "educe", "fnv", "hashbrown 0.15.5", @@ -143,16 +143,36 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "digest", + "itertools 0.10.5", + "num-bigint 0.4.6", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + [[package]] name = "ark-ff" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70" dependencies = [ - "ark-ff-asm", - "ark-ff-macros", - "ark-serialize", - "ark-std", + "ark-ff-asm 0.5.0", + "ark-ff-macros 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", "arrayvec", "digest", "educe", @@ -163,6 +183,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "ark-ff-asm" version = "0.5.0" @@ -170,7 +200,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" dependencies = [ "quote", - "syn 2.0.111", + "syn 2.0.117", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint 0.4.6", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -183,7 +226,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -193,14 +236,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27" dependencies = [ "ahash", - "ark-ff", - "ark-serialize", - "ark-std", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", "educe", "fnv", "hashbrown 0.15.5", ] +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std 0.4.0", + "digest", + "num-bigint 0.4.6", +] + [[package]] name = "ark-serialize" version = "0.5.0" @@ -208,7 +262,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" dependencies = [ "ark-serialize-derive", - "ark-std", + "ark-std 0.5.0", "arrayvec", "digest", "num-bigint 0.4.6", @@ -222,7 +276,17 @@ checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", ] [[package]] @@ -255,7 +319,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -325,9 +389,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" [[package]] name = "bitvec" @@ -341,18 +405,38 @@ dependencies = [ "wyz", ] +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + +[[package]] +name = "blake2b_simd" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b79834656f71332577234b50bfc009996f7449e0c056884e6a02492ded0ca2f3" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + [[package]] name = "blake3" -version = "1.8.3" +version = "1.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2468ef7d57b3fb7e16b576e8377cdbde2320c60e1491e961d11da40fc4f02a2d" +checksum = "4d2d5991425dfd0785aed03aedcf0b321d61975c9b5b3689c774a2610ae0b51e" dependencies = [ "arrayref", "arrayvec", "cc", "cfg-if", "constant_time_eq", - "cpufeatures", + "cpufeatures 0.3.0", ] [[package]] @@ -364,24 +448,37 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bls12_381" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3c196a77437e7cc2fb515ce413a6401291578b5afc8ecb29a3c7ab957f05941" +dependencies = [ + "ff 0.12.1", + "group 0.12.1", + "pairing 0.22.0", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "bls12_381" version = "0.8.0" source = "git+https://github.com/lambdaclass/bls12_381?branch=expose-fp-struct#219174187bd78154cec35b0809799fc2c991a579" dependencies = [ "digest", - "ff", - "group", - "pairing", + "ff 0.13.1", + "group 0.13.0", + "pairing 0.23.0", "rand_core 0.6.4", "subtle", ] [[package]] name = "bumpalo" -version = "3.19.1" +version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" [[package]] name = "byte-slice-cast" @@ -409,14 +506,14 @@ checksum = "89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] name = "bytemuck" -version = "1.24.0" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" [[package]] name = "byteorder" @@ -426,9 +523,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" dependencies = [ "serde", ] @@ -447,9 +544,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.50" +version = "1.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f50d563227a1c37cc0a263f64eca3334388c01c5e4c4861a9def205c614383c" +checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1" dependencies = [ "find-msvc-tools", "shlex", @@ -463,9 +560,9 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chrono" -version = "0.4.42" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" dependencies = [ "iana-time-zone", "num-traits", @@ -514,9 +611,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.53" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" +checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" dependencies = [ "clap_builder", "clap_derive", @@ -524,26 +621,26 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.53" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ "anstream", "anstyle", - "clap_lex 0.7.6", + "clap_lex 1.1.0", "strsim", ] [[package]] name = "clap_derive" -version = "4.5.49" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -557,16 +654,16 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.6" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "cli" version = "0.1.0" dependencies = [ "bincode", - "clap 4.5.53", + "clap 4.6.0", "executor", "lambda-vm-prover", "stark", @@ -576,9 +673,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "const-oid" @@ -636,6 +733,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.5.0" @@ -678,7 +784,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.5.53", + "clap 4.6.0", "criterion-plot", "is-terminal", "itertools 0.10.5", @@ -773,12 +879,14 @@ version = "0.1.0" dependencies = [ "digest", "math", + "memmap2", "rand 0.8.5", "rand_chacha 0.3.1", "rayon", "serde", "sha2", "sha3", + "tempfile", ] [[package]] @@ -795,9 +903,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.7" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", "typenum", @@ -805,9 +913,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.21.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" dependencies = [ "darling_core", "darling_macro", @@ -815,27 +923,26 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.21.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" dependencies = [ - "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] name = "darling_macro" -version = "0.21.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ "darling_core", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -863,14 +970,25 @@ dependencies = [ [[package]] name = "deranged" -version = "0.5.5" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" dependencies = [ "powerfmt", "serde_core", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "derive_more" version = "1.0.0" @@ -889,7 +1007,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", "unicode-xid", ] @@ -913,7 +1031,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -945,7 +1063,7 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -954,6 +1072,12 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +[[package]] +name = "elf" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b" + [[package]] name = "elliptic-curve" version = "0.13.8" @@ -963,9 +1087,9 @@ dependencies = [ "base16ct", "crypto-bigint", "digest", - "ff", + "ff 0.13.1", "generic-array", - "group", + "group 0.13.0", "pem-rfc7468", "pkcs8", "rand_core 0.6.4", @@ -991,14 +1115,14 @@ checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] name = "env_filter" -version = "0.1.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" +checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" dependencies = [ "log", "regex", @@ -1006,9 +1130,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.8" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" +checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" dependencies = [ "anstream", "anstyle", @@ -1069,7 +1193,7 @@ dependencies = [ [[package]] name = "ethrex-blockchain" version = "9.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#3a4527330ae522f9a84b4bbb0e8d2ed8c8c6ebe9" +source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#9837edc102f1a191baaaa9e98d5c0574b873bc18" dependencies = [ "bytes", "ethrex-common", @@ -1081,7 +1205,7 @@ dependencies = [ "ethrex-vm", "hex", "rustc-hash", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tokio-util", "tracing", @@ -1090,7 +1214,7 @@ dependencies = [ [[package]] name = "ethrex-common" version = "9.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#3a4527330ae522f9a84b4bbb0e8d2ed8c8c6ebe9" +source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#9837edc102f1a191baaaa9e98d5c0574b873bc18" dependencies = [ "bytes", "crc32fast", @@ -1112,7 +1236,7 @@ dependencies = [ "serde_json", "sha2", "sha3", - "thiserror 2.0.17", + "thiserror 2.0.18", "tinyvec", "tracing", "url", @@ -1121,16 +1245,16 @@ dependencies = [ [[package]] name = "ethrex-crypto" version = "9.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#3a4527330ae522f9a84b4bbb0e8d2ed8c8c6ebe9" +source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#9837edc102f1a191baaaa9e98d5c0574b873bc18" dependencies = [ - "thiserror 2.0.17", + "thiserror 2.0.18", "tiny-keccak", ] [[package]] name = "ethrex-l2-common" version = "9.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#3a4527330ae522f9a84b4bbb0e8d2ed8c8c6ebe9" +source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#9837edc102f1a191baaaa9e98d5c0574b873bc18" dependencies = [ "bytes", "ethereum-types", @@ -1147,20 +1271,20 @@ dependencies = [ "serde", "serde_with", "sha3", - "thiserror 2.0.17", + "thiserror 2.0.18", "tracing", ] [[package]] name = "ethrex-levm" version = "9.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#3a4527330ae522f9a84b4bbb0e8d2ed8c8c6ebe9" +source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#9837edc102f1a191baaaa9e98d5c0574b873bc18" dependencies = [ "ark-bn254", "ark-ec", - "ark-ff", + "ark-ff 0.5.0", "bitvec", - "bls12_381", + "bls12_381 0.8.0", "bytes", "datatest-stable", "derive_more", @@ -1179,40 +1303,40 @@ dependencies = [ "sha2", "sha3", "strum", - "thiserror 2.0.17", + "thiserror 2.0.18", "walkdir", ] [[package]] name = "ethrex-metrics" version = "9.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#3a4527330ae522f9a84b4bbb0e8d2ed8c8c6ebe9" +source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#9837edc102f1a191baaaa9e98d5c0574b873bc18" dependencies = [ "ethrex-common", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", "tracing-subscriber", ] [[package]] name = "ethrex-rlp" version = "9.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#3a4527330ae522f9a84b4bbb0e8d2ed8c8c6ebe9" +source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#9837edc102f1a191baaaa9e98d5c0574b873bc18" dependencies = [ "bytes", "ethereum-types", "hex", "lazy_static", "snap", - "thiserror 2.0.17", + "thiserror 2.0.18", "tinyvec", ] [[package]] name = "ethrex-storage" version = "9.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#3a4527330ae522f9a84b4bbb0e8d2ed8c8c6ebe9" +source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#9837edc102f1a191baaaa9e98d5c0574b873bc18" dependencies = [ "anyhow", "async-trait", @@ -1229,7 +1353,7 @@ dependencies = [ "rustc-hash", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tracing", ] @@ -1237,7 +1361,7 @@ dependencies = [ [[package]] name = "ethrex-threadpool" version = "9.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#3a4527330ae522f9a84b4bbb0e8d2ed8c8c6ebe9" +source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#9837edc102f1a191baaaa9e98d5c0574b873bc18" dependencies = [ "crossbeam", ] @@ -1245,7 +1369,7 @@ dependencies = [ [[package]] name = "ethrex-trie" version = "9.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#3a4527330ae522f9a84b4bbb0e8d2ed8c8c6ebe9" +source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#9837edc102f1a191baaaa9e98d5c0574b873bc18" dependencies = [ "anyhow", "bytes", @@ -1262,14 +1386,14 @@ dependencies = [ "serde", "serde_json", "smallvec", - "thiserror 2.0.17", + "thiserror 2.0.18", "tracing", ] [[package]] name = "ethrex-vm" version = "9.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#3a4527330ae522f9a84b4bbb0e8d2ed8c8c6ebe9" +source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#9837edc102f1a191baaaa9e98d5c0574b873bc18" dependencies = [ "bincode", "bytes", @@ -1284,7 +1408,7 @@ dependencies = [ "lazy_static", "rkyv", "serde", - "thiserror 2.0.17", + "thiserror 2.0.18", "tracing", ] @@ -1318,6 +1442,17 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "bitvec", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "ff" version = "0.13.1" @@ -1348,9 +1483,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.5" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "fixed-hash" @@ -1397,46 +1532,91 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +[[package]] +name = "futures" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", + "futures-sink", +] + [[package]] name = "futures-core" -version = "0.3.31" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-executor" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" [[package]] name = "futures-macro" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] name = "futures-sink" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" [[package]] name = "futures-task" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-util" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ + "futures-channel", "futures-core", + "futures-io", "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", - "pin-utils", "slab", ] @@ -1448,9 +1628,9 @@ checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" [[package]] name = "generic-array" -version = "0.14.7" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" dependencies = [ "typenum", "version_check", @@ -1459,9 +1639,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "js-sys", @@ -1478,17 +1658,42 @@ checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", - "r-efi", + "r-efi 5.3.0", "wasip2", ] +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", + "wasip2", + "wasip3", +] + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "memuse", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "group" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff", + "ff 0.13.1", "rand_core 0.6.4", "subtle", ] @@ -1496,7 +1701,7 @@ dependencies = [ [[package]] name = "guest_program" version = "9.0.0" -source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#3a4527330ae522f9a84b4bbb0e8d2ed8c8c6ebe9" +source = "git+https://github.com/lambdaclass/ethrex.git?branch=crypto-default-features#9837edc102f1a191baaaa9e98d5c0574b873bc18" dependencies = [ "bincode", "bytes", @@ -1513,7 +1718,7 @@ dependencies = [ "serde", "serde_json", "serde_with", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -1533,6 +1738,29 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "halo2" +version = "0.1.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a23c779b38253fe1538102da44ad5bd5378495a61d2c4ee18d64eaa61ae5995" +dependencies = [ + "halo2_proofs", +] + +[[package]] +name = "halo2_proofs" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e925780549adee8364c7f2b685c753f6f3df23bde520c67416e93bf615933760" +dependencies = [ + "blake2b_simd", + "ff 0.12.1", + "group 0.12.1", + "pasta_curves 0.4.1", + "rand_core 0.6.4", + "rayon", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1604,9 +1832,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.64" +version = "0.1.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1707,6 +1935,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + [[package]] name = "ident_case" version = "1.0.1" @@ -1769,7 +2003,7 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -1785,9 +2019,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.12.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", "hashbrown 0.16.1", @@ -1859,15 +2093,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.16" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" -version = "0.2.16" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35" +checksum = "1a3546dc96b6d42c5f24902af9e2538e82e39ad350b0c766eb3fbf2d8f3d8359" dependencies = [ "jiff-static", "log", @@ -1878,25 +2112,39 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.16" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69" +checksum = "2a8c8b344124222efd714b73bb41f8b5120b27a7cc1c75593a6ff768d9d05aa4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] name = "js-sys" -version = "0.3.83" +version = "0.3.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" +checksum = "797146bb2677299a1eb6b7b50a890f4c361b29ef967addf5b2fa45dae1bb6d7d" dependencies = [ "once_cell", "wasm-bindgen", ] +[[package]] +name = "jubjub" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a575df5f985fe1cd5b2b05664ff6accfc46559032b954529fd225a2168d27b0f" +dependencies = [ + "bitvec", + "bls12_381 0.7.1", + "ff 0.12.1", + "group 0.12.1", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "k256" version = "0.13.4" @@ -1913,20 +2161,20 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" dependencies = [ - "cpufeatures", + "cpufeatures 0.2.17", ] [[package]] name = "kzg-rs" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9201effeea3fcc93b587904ae2df9ce97e433184b9d6d299e9ebc9830a546636" +checksum = "ee8b4f55c3dedcfaa8668de1dfc8469e7a32d441c28edf225ed1f566fb32977d" dependencies = [ - "ff", + "ff 0.13.1", "hex", "serde_arrays", "sha2", @@ -1938,6 +2186,7 @@ dependencies = [ name = "lambda-vm-prover" version = "0.1.0" dependencies = [ + "bincode", "criterion 0.5.1", "crypto", "env_logger", @@ -1968,7 +2217,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "018a95aa873eb49896a858dee0d925c33f3978d073c64b08dd4f2c9b35a017c6" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "num-bigint 0.4.6", "num-traits", "rand 0.8.5", @@ -1982,36 +2231,45 @@ name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.178" +version = "0.2.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" +checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" [[package]] name = "libm" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libtest-mimic" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5297962ef19edda4ce33aaa484386e0a5b3d7f2f4e037cbeee00503ef6b29d33" +checksum = "14e6ba06f0ade6e504aff834d7c34298e5155c6baca353cc6a4aaff2f9fd7f33" dependencies = [ "anstream", "anstyle", - "clap 4.5.53", + "clap 4.6.0", "escape8259", ] [[package]] name = "linux-raw-sys" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" @@ -2094,7 +2352,7 @@ name = "math" version = "0.1.0" dependencies = [ "criterion 0.5.1", - "getrandom 0.2.16", + "getrandom 0.2.17", "num-bigint 0.4.6", "num-traits", "proptest", @@ -2107,9 +2365,24 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.6" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[package]] +name = "memmap2" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" +dependencies = [ + "libc", +] + +[[package]] +name = "memuse" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +checksum = "3d97bbf43eb4f088f8ca469930cde17fa036207c9a5e02ccc5107c4e8b17c964" [[package]] name = "munge" @@ -2128,7 +2401,7 @@ checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -2163,9 +2436,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.1.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" [[package]] name = "num-integer" @@ -2187,9 +2460,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "once_cell_polyfill" @@ -2222,25 +2495,39 @@ dependencies = [ ] [[package]] -name = "p3-baby-bear" -version = "0.2.3-succinct" +name = "p3-bn254-fr" +version = "0.3.2-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7521838ecab2ddf4f7bc4ceebad06ec02414729598485c1ada516c39900820e8" +checksum = "9abf208fbfe540d6e2a6caaa2a9a345b1c8cb23ffdcdfcc6987244525d4fc821" dependencies = [ + "ff 0.13.1", "num-bigint 0.4.6", "p3-field", - "p3-mds", "p3-poseidon2", "p3-symmetric", "rand 0.8.5", "serde", ] +[[package]] +name = "p3-challenger" +version = "0.3.2-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42b725b453bbb35117a1abf0ddfd900b0676063d6e4231e0fa6bb0d76018d8ad" +dependencies = [ + "p3-field", + "p3-maybe-rayon", + "p3-symmetric", + "p3-util", + "serde", + "tracing", +] + [[package]] name = "p3-dft" -version = "0.2.3-succinct" +version = "0.3.2-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46414daedd796f1eefcdc1811c0484e4bced5729486b6eaba9521c572c76761a" +checksum = "56a1f81101bff744b7ebba7f4497e917a2c6716d6e62736e4a56e555a2d98cb7" dependencies = [ "p3-field", "p3-matrix", @@ -2251,9 +2538,9 @@ dependencies = [ [[package]] name = "p3-field" -version = "0.2.3-succinct" +version = "0.3.2-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48948a0516b349e9d1cdb95e7236a6ee010c44e68c5cc78b4b92bf1c4022a0d9" +checksum = "36459d4acb03d08097d713f336c7393990bb489ab19920d4f68658c7a5c10968" dependencies = [ "itertools 0.12.1", "num-bigint 0.4.6", @@ -2263,11 +2550,26 @@ dependencies = [ "serde", ] +[[package]] +name = "p3-koala-bear" +version = "0.3.2-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1f52bcb6be38bdc8fa6b38b3434d4eedd511f361d4249fd798c6a5ef817b40" +dependencies = [ + "num-bigint 0.4.6", + "p3-field", + "p3-mds", + "p3-poseidon2", + "p3-symmetric", + "rand 0.8.5", + "serde", +] + [[package]] name = "p3-matrix" -version = "0.2.3-succinct" +version = "0.3.2-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4de3f373589477cb735ea58e125898ed20935e03664b4614c7fac258b3c42f" +checksum = "5583e9cd136a4095a25c41a9edfdcce2dfae58ef01639317813bdbbd5b55c583" dependencies = [ "itertools 0.12.1", "p3-field", @@ -2280,15 +2582,15 @@ dependencies = [ [[package]] name = "p3-maybe-rayon" -version = "0.2.3-succinct" +version = "0.3.2-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3968ad1160310296eb04f91a5f4edfa38fe1d6b2b8cd6b5c64e6f9b7370979e" +checksum = "e524d47a49fb4265611303339c4ef970d892817b006cc330dad18afb91e411b1" [[package]] name = "p3-mds" -version = "0.2.3-succinct" +version = "0.3.2-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2356b1ed0add6d5dfbf7a338ce534a6fde827374394a52cec16a0840af6e97c9" +checksum = "4f6cb8edcb276033d43769a3725570c340d2ed6f35c3cca4cddeee07718fa376" dependencies = [ "itertools 0.12.1", "p3-dft", @@ -2301,9 +2603,9 @@ dependencies = [ [[package]] name = "p3-poseidon2" -version = "0.2.3-succinct" +version = "0.3.2-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da1eec7e1b6900581bedd95e76e1ef4975608dd55be9872c9d257a8a9651c3a" +checksum = "5a26197df2097b98ab7038d59a01e1fe1a0f545e7e04aa9436b2454b1836654f" dependencies = [ "gcd", "p3-field", @@ -2315,9 +2617,9 @@ dependencies = [ [[package]] name = "p3-symmetric" -version = "0.2.3-succinct" +version = "0.3.2-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edb439bea1d822623b41ff4b51e3309e80d13cadf8b86d16ffd5e6efb9fdc360" +checksum = "3a1d3b5202096bca57cde912fbbb9cbaedaf5ac7c42a924c7166b98709d64d21" dependencies = [ "itertools 0.12.1", "p3-field", @@ -2326,20 +2628,29 @@ dependencies = [ [[package]] name = "p3-util" -version = "0.2.3-succinct" +version = "0.3.2-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c2c2010678b9332b563eaa38364915b585c1a94b5ca61e2c7541c087ddda5c" +checksum = "ec5f0388aa6d935ca3a17444086120f393f0b2f0816010b5ff95998c1c4095e3" dependencies = [ "serde", ] +[[package]] +name = "pairing" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135590d8bdba2b31346f9cd1fb2a912329f5135e832a4f422942eb6ead8b6b3b" +dependencies = [ + "group 0.12.1", +] + [[package]] name = "pairing" version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" dependencies = [ - "group", + "group 0.13.0", ] [[package]] @@ -2367,7 +2678,37 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", +] + +[[package]] +name = "pasta_curves" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc65faf8e7313b4b1fbaa9f7ca917a0eed499a9663be71477f87993604341d8" +dependencies = [ + "blake2b_simd", + "ff 0.12.1", + "group 0.12.1", + "lazy_static", + "rand 0.8.5", + "static_assertions", + "subtle", +] + +[[package]] +name = "pasta_curves" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e57598f73cc7e1b2ac63c79c517b31a0877cd7c402cdcaa311b5208de7a095" +dependencies = [ + "blake2b_simd", + "ff 0.13.1", + "group 0.13.0", + "lazy_static", + "rand 0.8.5", + "static_assertions", + "subtle", ] [[package]] @@ -2393,15 +2734,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkcs8" @@ -2443,15 +2778,15 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.12.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f59e70c4aef1e55797c2e8fd94a4f2a973fc972cfde0e0b05f683667b0cd39dd" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "portable-atomic-util" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +checksum = "091397be61a01d4be58e7841595bd4bfedb15f1cd54977d79b8271e94ed799a3" dependencies = [ "portable-atomic", ] @@ -2480,6 +2815,16 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn 2.0.117", +] + [[package]] name = "primeorder" version = "0.13.6" @@ -2504,31 +2849,31 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ "toml_edit", ] [[package]] name = "proc-macro2" -version = "1.0.103" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] [[package]] name = "proptest" -version = "1.9.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee689443a2bd0a16ab0348b52ee43e3b2d1b1f931c8aa5c9f8de4c86fbe8c40" +checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.10.0", + "bitflags 2.11.0", "num-traits", "rand 0.9.2", "rand_chacha 0.9.0", @@ -2556,7 +2901,7 @@ checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -2576,9 +2921,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.42" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] @@ -2589,6 +2934,12 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "radium" version = "0.7.0" @@ -2622,7 +2973,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha 0.9.0", - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -2642,7 +2993,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -2651,14 +3002,14 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", ] [[package]] name = "rand_core" -version = "0.9.3" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" dependencies = [ "getrandom 0.3.4", ] @@ -2669,7 +3020,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" dependencies = [ - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -2709,14 +3060,14 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] name = "regex" -version = "1.12.2" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", @@ -2726,9 +3077,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", @@ -2737,9 +3088,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "rend" @@ -2771,14 +3122,14 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360b333c61ae24e5af3ae7c8660bd6b21ccd8200dbbc5d33c2454421e85b9c69" +checksum = "1a30e631b7f4a03dee9056b8ef6982e8ba371dd5bedb74d3ec86df4499132c70" dependencies = [ "bytecheck", "bytes", "hashbrown 0.16.1", - "indexmap 2.12.1", + "indexmap 2.13.0", "munge", "ptr_meta", "rancor", @@ -2790,13 +3141,13 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02f8cdd12b307ab69fe0acf4cd2249c7460eb89dce64a0febadf934ebb6a9e" +checksum = "8100bb34c0a1d0f907143db3149e6b4eea3c33b9ee8b189720168e818303986f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -2811,15 +3162,15 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" +checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" [[package]] name = "rustc-hash" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" [[package]] name = "rustc-hex" @@ -2827,13 +3178,22 @@ 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" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "errno", "libc", "linux-raw-sys", @@ -2860,9 +3220,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62049b2877bf12821e8f9ad256ee38fdc31db7387ec2d3b3f403024de2034aea" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "safe_arch" @@ -2896,9 +3256,9 @@ dependencies = [ [[package]] name = "schemars" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54e910108742c57a770f492731f99be216a52fadd361b06c8fb59d74ccc267d2" +checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" dependencies = [ "dyn-clone", "ref-cast", @@ -2920,6 +3280,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + [[package]] name = "serde" version = "1.0.228" @@ -2977,35 +3343,35 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] name = "serde_json" -version = "1.0.146" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "217ca874ae0207aac254aa02c957ded05585a90892cc8d87f9e5fa49669dadd8" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "itoa", "memchr", - "ryu", "serde", "serde_core", + "zmij", ] [[package]] name = "serde_with" -version = "3.16.1" +version = "3.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7" +checksum = "dd5414fad8e6907dbdd5bc441a50ae8d6e26151a03b1de04d89a5576de61d01f" dependencies = [ "base64", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.12.1", + "indexmap 2.13.0", "schemars 0.9.0", - "schemars 1.2.0", + "schemars 1.2.1", "serde_core", "serde_json", "serde_with_macros", @@ -3014,14 +3380,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.16.1" +version = "3.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52a8e3ca0ca629121f70ab50f95249e5a6f925cc0f6ffe8256c45b728875706c" +checksum = "d3db8978e608f1fe7357e211969fd9abdcae80bac1ba7a3369bb7eb6b404eb65" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -3031,7 +3397,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest", ] @@ -3078,9 +3444,91 @@ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "slab" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "slop-algebra" +version = "6.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "691beea96fd18d4881f9ca1cb4e58194dac6366f24956a2fdae00c8ee382a0c9" +dependencies = [ + "itertools 0.14.0", + "p3-field", + "serde", +] + +[[package]] +name = "slop-bn254" +version = "6.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1852499c245f7f3dec23408b4930b3ea7570ae914b9c31f12950ac539d85ee" +dependencies = [ + "ff 0.13.1", + "p3-bn254-fr", + "serde", + "slop-algebra", + "slop-challenger", + "slop-poseidon2", + "slop-symmetric", + "zkhash", +] + +[[package]] +name = "slop-challenger" +version = "6.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4349af93602f3876a3eda948a74d9d16d774c401dfe25f41a45ffd84f230bc1" +dependencies = [ + "futures", + "p3-challenger", + "serde", + "slop-algebra", + "slop-symmetric", +] + +[[package]] +name = "slop-koala-bear" +version = "6.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "574784c044d11cf9d8238dc18bce9b897bc34d0fb1daaceafd75ebb400084016" +dependencies = [ + "lazy_static", + "p3-koala-bear", + "serde", + "slop-algebra", + "slop-challenger", + "slop-poseidon2", + "slop-symmetric", +] + +[[package]] +name = "slop-poseidon2" +version = "6.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5af617970b63e8d7199204bc02996745b6c35c39f2b513a118c62c7b1a0b2f1b" +dependencies = [ + "p3-poseidon2", +] + +[[package]] +name = "slop-primitives" +version = "6.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58d82c53508f3ebff8acdabb5db2584f37686257a2549a17c977cf30cd9e24e6" +dependencies = [ + "slop-algebra", +] + +[[package]] +name = "slop-symmetric" +version = "6.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15acfa7f567ffa4f36de134492632a397c33fa6af2e48894e50978b52eeeb871" +dependencies = [ + "p3-symmetric", +] [[package]] name = "smallvec" @@ -3096,9 +3544,9 @@ checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" [[package]] name = "sp1-lib" -version = "5.2.4" +version = "6.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73b8ff343f2405d5935440e56b7aba5cee6d87303f0051974cbd6f5de502f57" +checksum = "517e820776910468611149dda66791bdb700c1b7d68b96f0ea2e604f00ad8771" dependencies = [ "bincode", "serde", @@ -3107,34 +3555,38 @@ dependencies = [ [[package]] name = "sp1-primitives" -version = "5.2.4" +version = "6.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e69a03098f827102c54c31a5e57280eb45b2c085de433b3f702e4f9e3ec1641" +checksum = "0f395525b4fc46d37136f45be264c81718a67f4409c14c547ff491a263e019e7" dependencies = [ "bincode", "blake3", - "cfg-if", + "elf", "hex", + "itertools 0.14.0", "lazy_static", "num-bigint 0.4.6", - "p3-baby-bear", - "p3-field", - "p3-poseidon2", - "p3-symmetric", "serde", "sha2", + "slop-algebra", + "slop-bn254", + "slop-challenger", + "slop-koala-bear", + "slop-poseidon2", + "slop-primitives", + "slop-symmetric", ] [[package]] name = "sp1_bls12_381" -version = "0.8.0-sp1-5.0.0" +version = "0.8.0-sp1-6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac255e1704ebcdeec5e02f6a0ebc4d2e9e6b802161938330b6810c13a610c583" +checksum = "f23e41cd36168cc2e51e5d3e35ff0c34b204d945769a65591a76286d04b51e43" dependencies = [ "cfg-if", - "ff", - "group", - "pairing", + "ff 0.13.1", + "group 0.13.0", + "pairing 0.23.0", "rand_core 0.6.4", "sp1-lib", "subtle", @@ -3172,11 +3624,13 @@ dependencies = [ "itertools 0.11.0", "log", "math", + "memmap2", "rayon", "serde", "serde-wasm-bindgen", "serde_cbor", "sha3", + "tempfile", "test-log", "thiserror 1.0.69", "wasm-bindgen", @@ -3213,7 +3667,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -3235,9 +3689,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.111" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", @@ -3252,7 +3706,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -3263,12 +3717,12 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.23.0" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.2", "once_cell", "rustix", "windows-sys", @@ -3293,7 +3747,7 @@ checksum = "be35209fd0781c5401458ab66e4f98accf63553e8fae7425503e92fdd319783b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -3313,11 +3767,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.17", + "thiserror-impl 2.0.18", ] [[package]] @@ -3328,18 +3782,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] name = "thiserror-impl" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -3384,9 +3838,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.45" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9e442fc33d7fdb45aa9bfeb312c095964abdf596f7567261062b2a7107aaabd" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa", @@ -3399,15 +3853,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b36ee98fd31ec7426d599183e8fe26932a8dc1fb76ddb6214d05493377d34ca" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" -version = "0.2.25" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e552d1249bf61ac2a52db88179fd0673def1e1ad8243a00d9ec9ed71fee3dd" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" dependencies = [ "num-conv", "time-core", @@ -3444,9 +3898,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" dependencies = [ "tinyvec_macros", ] @@ -3459,9 +3913,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.49.0" +version = "1.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" dependencies = [ "pin-project-lite", ] @@ -3482,20 +3936,20 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.5+spec-1.1.0" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" -version = "0.23.10+spec-1.0.0" +version = "0.25.9+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +checksum = "da053d28fe57e2c9d21b48261e14e7b4c8b670b54d2c684847b91feaf4c7dac5" dependencies = [ - "indexmap 2.12.1", + "indexmap 2.13.0", "toml_datetime", "toml_parser", "winnow", @@ -3503,9 +3957,9 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.6+spec-1.1.0" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +checksum = "39ca317ebc49f06bd748bfba29533eac9485569dc9bf80b849024b025e814fb9" dependencies = [ "winnow", ] @@ -3530,7 +3984,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -3556,9 +4010,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.22" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" dependencies = [ "matchers", "nu-ansi-term", @@ -3598,15 +4052,15 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-segmentation" -version = "1.12.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" [[package]] name = "unicode-xid" @@ -3641,9 +4095,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.19.0" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" +checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" dependencies = [ "js-sys", "wasm-bindgen", @@ -3688,18 +4142,27 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.1+wasi-0.2.4" +version = "1.0.2+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" dependencies = [ "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.106" +version = "0.2.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" +checksum = "7dc0882f7b5bb01ae8c5215a1230832694481c1a4be062fd410e12ea3da5b631" dependencies = [ "cfg-if", "once_cell", @@ -3710,9 +4173,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.106" +version = "0.2.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" +checksum = "75973d3066e01d035dbedaad2864c398df42f8dd7b1ea057c35b8407c015b537" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3720,31 +4183,65 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.106" +version = "0.2.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" +checksum = "91af5e4be765819e0bcfee7322c14374dc821e35e72fa663a830bbc7dc199eac" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.106" +version = "0.2.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +checksum = "c9bf0406a78f02f336bf1e451799cca198e8acde4ffa278f0fb20487b150a633" dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap 2.13.0", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags 2.11.0", + "hashbrown 0.15.5", + "indexmap 2.13.0", + "semver", +] + [[package]] name = "web-sys" -version = "0.3.83" +version = "0.3.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" +checksum = "749466a37ee189057f54748b200186b59a03417a117267baf3fd89cecc9fb837" dependencies = [ "js-sys", "wasm-bindgen", @@ -3812,7 +4309,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -3823,7 +4320,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -3861,18 +4358,100 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.14" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" dependencies = [ "memchr", ] [[package]] name = "wit-bindgen" -version = "0.46.0" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck", + "indexmap 2.13.0", + "prettyplease", + "syn 2.0.117", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.117", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags 2.11.0", + "indexmap 2.13.0", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap 2.13.0", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] [[package]] name = "writeable" @@ -3914,28 +4493,28 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.31" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.31" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -3955,7 +4534,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", "synstructure", ] @@ -3976,7 +4555,7 @@ checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", ] [[package]] @@ -4009,5 +4588,38 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.117", +] + +[[package]] +name = "zkhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4352d1081da6922701401cdd4cbf29a2723feb4cfabb5771f6fee8e9276da1c7" +dependencies = [ + "ark-ff 0.4.2", + "ark-std 0.4.0", + "bitvec", + "blake2", + "bls12_381 0.7.1", + "byteorder", + "cfg-if", + "group 0.12.1", + "group 0.13.0", + "halo2", + "hex", + "jubjub", + "lazy_static", + "pasta_curves 0.5.1", + "rand 0.8.5", + "serde", + "sha2", + "sha3", + "subtle", ] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/bin/cli/Cargo.toml b/bin/cli/Cargo.toml index 4bfcb7956..ccac011f8 100644 --- a/bin/cli/Cargo.toml +++ b/bin/cli/Cargo.toml @@ -13,5 +13,7 @@ tikv-jemallocator = "0.6" tikv-jemalloc-ctl = { version = "0.6", features = ["stats"], optional = true } [features] +default = ["disk-spill"] jemalloc-stats = ["dep:tikv-jemalloc-ctl"] +disk-spill = ["prover/disk-spill"] instruments = ["prover/instruments"] diff --git a/bin/cli/src/main.rs b/bin/cli/src/main.rs index 725f0de5f..a6716eeca 100644 --- a/bin/cli/src/main.rs +++ b/bin/cli/src/main.rs @@ -123,6 +123,10 @@ enum Commands { /// Print timing breakdown #[arg(long)] time: bool, + + /// Maximum rows per table chunk (power of 2). Smaller = less memory, more chunks. + #[arg(long)] + max_rows: Option, }, /// Verify a proof bundle @@ -155,7 +159,8 @@ fn main() -> ExitCode { output, blowup, time, - } => cmd_prove(elf, output, blowup, time), + max_rows, + } => cmd_prove(elf, output, blowup, time, max_rows), Commands::Verify { proof, elf, @@ -249,7 +254,13 @@ fn cmd_execute(elf_path: PathBuf, flamegraph_path: Option) -> ExitCode ExitCode::SUCCESS } -fn cmd_prove(elf_path: PathBuf, output_path: PathBuf, blowup: Option, time: bool) -> ExitCode { +fn cmd_prove( + elf_path: PathBuf, + output_path: PathBuf, + blowup: Option, + time: bool, + max_rows: Option, +) -> ExitCode { eprintln!("Reading ELF file..."); let elf_data = match std::fs::read(&elf_path) { Ok(data) => data, @@ -262,6 +273,28 @@ fn cmd_prove(elf_path: PathBuf, output_path: PathBuf, blowup: Option, time: #[cfg(feature = "jemalloc-stats")] let tracker = heap_tracker::HeapTracker::start(); + if cfg!(feature = "disk-spill") { + eprintln!("Disk-spill: enabled"); + } + + let max_rows_config = match max_rows { + Some(mr) => { + eprintln!("Max rows per chunk: {mr}"); + prover::MaxRowsConfig { + cpu: mr, + memw: mr, + memw_aligned: mr, + dvrm: mr, + mul: mr, + lt: mr, + shift: mr, + load: mr, + branch: mr, + } + } + None => prover::MaxRowsConfig::default(), + }; + let start = Instant::now(); let proof = match blowup { Some(b) => { @@ -276,11 +309,13 @@ fn cmd_prove(elf_path: PathBuf, output_path: PathBuf, blowup: Option, time: "Generating proof (blowup={b}, queries={})...", opts.fri_number_of_queries ); - prover::prove_with_options(&elf_data, &opts, &Default::default()) + prover::prove_with_options(&elf_data, &opts, &max_rows_config) } None => { + let opts = + GoldilocksCubicProofOptions::with_blowup(2).expect("blowup=2 is always valid"); eprintln!("Generating proof..."); - prover::prove(&elf_data) + prover::prove_with_options(&elf_data, &opts, &max_rows_config) } }; let prove_elapsed = start.elapsed(); diff --git a/crypto/crypto/Cargo.toml b/crypto/crypto/Cargo.toml index ff91bae63..d0dffb64c 100644 --- a/crypto/crypto/Cargo.toml +++ b/crypto/crypto/Cargo.toml @@ -18,6 +18,8 @@ serde = { version = "1.0", default-features = false, features = [ rayon = { version = "1.8.0", optional = true } rand = { version = "0.8.5", default-features = false } rand_chacha = { version = "0.3.1", default-features = false } +memmap2 = { version = "0.9", optional = true } +tempfile = { version = "3", optional = true } [dev-dependencies] math = { path = "../math", features = ["test-utils"] } @@ -31,4 +33,5 @@ asm = ["sha3/asm"] std = ["math/std", "sha3/std", "serde?/std"] serde = ["dep:serde"] parallel = ["dep:rayon"] +disk-spill = ["std", "dep:memmap2", "dep:tempfile"] alloc = [] \ No newline at end of file diff --git a/crypto/crypto/src/merkle_tree/merkle.rs b/crypto/crypto/src/merkle_tree/merkle.rs index 55fa49a83..9f5f68876 100644 --- a/crypto/crypto/src/merkle_tree/merkle.rs +++ b/crypto/crypto/src/merkle_tree/merkle.rs @@ -22,6 +22,19 @@ impl Display for Error { #[cfg(feature = "std")] impl std::error::Error for Error {} +/// File-backed mmap storage for Merkle tree nodes. +/// +/// After `spill_nodes_to_disk()`, the heap `Vec` is freed and all +/// node access goes through this mmap. The OS manages page eviction under +/// memory pressure — file-backed pages are evictable without swap. +#[cfg(feature = "disk-spill")] +pub(crate) struct MmapNodeBacking { + mmap: memmap2::Mmap, + _file: std::fs::File, + node_count: usize, + node_size: usize, +} + /// The struct for the Merkle tree, consisting of the root and the nodes. /// A typical tree would look like this /// root @@ -31,11 +44,29 @@ impl std::error::Error for Error {} /// leaf 1 leaf 2 leaf 3 leaf 4 /// The bottom leafs correspond to the hashes of the elements, while each upper /// layer contains the hash of the concatenation of the daughter nodes. -#[derive(Clone)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct MerkleTree { pub root: B::Node, nodes: Vec, + #[cfg(feature = "disk-spill")] + #[cfg_attr(feature = "serde", serde(skip))] + mmap_backing: Option, +} + +impl Clone for MerkleTree { + fn clone(&self) -> Self { + #[cfg(feature = "disk-spill")] + assert!( + self.mmap_backing.is_none(), + "cannot clone a spilled MerkleTree — nodes have been freed; use Arc instead" + ); + Self { + root: self.root.clone(), + nodes: self.nodes.clone(), + #[cfg(feature = "disk-spill")] + mmap_backing: None, + } + } } const ROOT: usize = 0; @@ -78,14 +109,46 @@ where Some(MerkleTree { root: nodes[ROOT].clone(), nodes, + #[cfg(feature = "disk-spill")] + mmap_backing: None, }) } + /// Total number of nodes in the tree (inner + leaves). + #[inline] + fn node_count(&self) -> usize { + #[cfg(feature = "disk-spill")] + if let Some(ref backing) = self.mmap_backing { + return backing.node_count; + } + self.nodes.len() + } + + /// Access a node by index, returning a reference. + /// + /// Returns `None` if `idx` is out of bounds. + #[inline] + fn node_get(&self, idx: usize) -> Option<&B::Node> { + #[cfg(feature = "disk-spill")] + if let Some(ref backing) = self.mmap_backing { + if idx < backing.node_count { + // SAFETY: B::Node is Copy (required by spill_nodes_to_disk's where clause). + // The mmap contains node_count × node_size contiguous bytes written from + // identical Node values on the same machine. The mmap base is page-aligned + // and node_size divides into page size for all concrete Node types ([u8; 32/64]). + let ptr = unsafe { backing.mmap.as_ptr().add(idx * backing.node_size) }; + return Some(unsafe { &*(ptr as *const B::Node) }); + } + return None; + } + self.nodes.get(idx) + } + /// Returns a Merkle proof for the element/s at position pos /// For example, give me an inclusion proof for the 3rd element in the /// Merkle tree pub fn get_proof_by_pos(&self, pos: usize) -> Option> { - let pos = pos + self.nodes.len() / 2; + let pos = pos + self.node_count() / 2; let Ok(merkle_path) = self.build_merkle_path(pos) else { return None; }; @@ -101,12 +164,12 @@ where /// Returns the Merkle path for the element/s for the leaf at position pos fn build_merkle_path(&self, pos: usize) -> Result, Error> { // Pre-allocate based on tree depth (log2 of tree size) - let tree_depth = (self.nodes.len() + 1).ilog2() as usize; + let tree_depth = (self.node_count() + 1).ilog2() as usize; let mut merkle_path = Vec::with_capacity(tree_depth); let mut pos = pos; while pos != ROOT { - let Some(node) = self.nodes.get(sibling_index(pos)) else { + let Some(node) = self.node_get(sibling_index(pos)) else { // out of bounds, exit returning the current merkle_path return Err(Error::OutOfBounds); }; @@ -141,7 +204,7 @@ where return Err(Error::EmptyPositionList); } - let num_leaves = (self.nodes.len() + 1).div_ceil(2); + let num_leaves = (self.node_count() + 1).div_ceil(2); // Validate all positions are within bounds for &pos in pos_list { @@ -154,7 +217,7 @@ where // of the leaves. let leaf_positions = pos_list .iter() - .map(|pos| pos + self.nodes.len() / 2) + .map(|pos| pos + self.node_count() / 2) .collect::>(); // We get the positions of the nodes for the batch proof. let batch_auth_path_positions = self.get_batch_auth_path_positions(&leaf_positions); @@ -162,7 +225,11 @@ where // We get the nodes for the batch proof. let batch_auth_path_nodes = batch_auth_path_positions .iter() - .map(|pos| self.nodes[*pos].clone()) + .map(|pos| { + self.node_get(*pos) + .expect("batch auth path position in bounds") + .clone() + }) .collect(); Ok(BatchProof { @@ -188,7 +255,7 @@ where let mut obtainable: BTreeSet = leaf_positions.iter().cloned().collect(); // Number of levels in tree - let num_levels = (self.nodes.len() + 1).ilog2(); + let num_levels = (self.node_count() + 1).ilog2(); // Iter lefevel-by-level from leaves to root. for _ in 0..num_levels - 1 { @@ -217,4 +284,58 @@ where // This makes the proof ordered from bottom (nodes closer to leaves) to top (nodes loser to root). auth_path_set.into_iter().rev().collect() } + + /// Write tree nodes to a temp file, mmap it read-only, and free the heap Vec. + /// + /// After this call, all node access methods read from the mmap transparently. + /// The OS can evict mmap pages under memory pressure since they're file-backed. + /// + /// Requires `B::Node: Copy` to ensure nodes have a trivial byte representation + /// suitable for raw serialization and mmap casting. + /// + /// Note: the concrete `Node` type is `[u8; 32]` (Keccak hash), which has no + /// padding bytes. The raw byte round-trip is therefore well-defined. + #[cfg(feature = "disk-spill")] + pub fn spill_nodes_to_disk(&mut self) -> std::io::Result<()> + where + B::Node: Copy, + { + use std::io::Write; + + if self.nodes.is_empty() { + return Ok(()); + } + + let node_size = core::mem::size_of::(); + let node_count = self.nodes.len(); + let total_bytes = node_count * node_size; + + let file = tempfile::tempfile()?; + file.set_len(total_bytes as u64)?; + { + let mut writer = std::io::BufWriter::new(&file); + // SAFETY: B::Node is Copy, so its in-memory representation is a + // valid byte sequence. The Vec is contiguous. + let bytes = unsafe { + core::slice::from_raw_parts(self.nodes.as_ptr() as *const u8, total_bytes) + }; + writer.write_all(bytes)?; + writer.flush()?; + } + + // SAFETY: We own the file exclusively; it won't be modified externally. + let mmap = unsafe { memmap2::MmapOptions::new().map(&file)? }; + + // Free the heap allocation + self.nodes = Vec::new(); + + self.mmap_backing = Some(MmapNodeBacking { + mmap, + _file: file, + node_count, + node_size, + }); + + Ok(()) + } } diff --git a/crypto/math/src/field/element.rs b/crypto/math/src/field/element.rs index 9c2ac3258..fb2019df4 100644 --- a/crypto/math/src/field/element.rs +++ b/crypto/math/src/field/element.rs @@ -40,6 +40,7 @@ use super::traits::{IsPrimeField, IsSubFieldOf, LegendreSymbol}; /// A field element with operations algorithms defined in `F` #[allow(clippy::derived_hash_with_manual_eq)] +#[repr(transparent)] #[derive(Debug, Clone, Hash, Copy)] pub struct FieldElement { value: F::BaseType, diff --git a/crypto/stark/Cargo.toml b/crypto/stark/Cargo.toml index 53b205996..d1f29c6b8 100644 --- a/crypto/stark/Cargo.toml +++ b/crypto/stark/Cargo.toml @@ -22,6 +22,10 @@ itertools = "0.11.0" # Parallelization crates rayon = { version = "1.8.0", optional = true } +# Disk-spill: mmap LDE data to reduce heap memory during proving +memmap2 = { version = "0.9", optional = true } +tempfile = { version = "3", optional = true } + # wasm wasm-bindgen = { version = "0.2", optional = true } serde-wasm-bindgen = { version = "0.5", optional = true } @@ -40,6 +44,7 @@ instruments = [] # This enab debug-checks = [] # Enables validate_trace + bus balance report in prover parallel = ["dep:rayon", "crypto/parallel"] wasm = ["dep:wasm-bindgen", "dep:serde-wasm-bindgen", "dep:web-sys"] +disk-spill = ["dep:memmap2", "dep:tempfile", "crypto/disk-spill"] [package.metadata.wasm-pack.profile.dev] diff --git a/crypto/stark/src/prover.rs b/crypto/stark/src/prover.rs index 50af95525..c30111c63 100644 --- a/crypto/stark/src/prover.rs +++ b/crypto/stark/src/prover.rs @@ -1532,6 +1532,17 @@ pub trait IsStarkProver< twiddle_caches.push(twiddles); } + // Spill all main trace tables to mmap before allocating pool buffers. + // This frees the heap-allocated main trace data (~120 cols × N rows × 8 bytes each), + // making room for the LDE pool buffers which are much larger (blowup_factor × N). + #[cfg(feature = "disk-spill")] + for (_, trace, _) in air_trace_pairs.iter_mut() { + trace + .main_table + .spill_to_disk() + .map_err(|e| ProvingError::WrongParameter(format!("disk-spill early main: {e}")))?; + } + // Allocate K independent LDE column buffer pool sets for parallel table processing. let k = table_parallelism().min(num_airs).max(1); let mut pool_sets: Vec> = (0..k) @@ -1559,6 +1570,13 @@ pub trait IsStarkProver< let mut main_commits: Vec> = Vec::with_capacity(num_airs); + // Spilled LDE trace tables: one per AIR, populated during Phase A (main) and Phase C (aux). + // In Rounds 2-4 these replace the reconstruct_round1 flow — LDE data is read from mmap + // instead of being recomputed from the trace. + #[cfg(feature = "disk-spill")] + let mut spilled_ldes: Vec>> = + (0..num_airs).map(|_| None).collect(); + for chunk_start in (0..num_airs).step_by(k) { let chunk_end = (chunk_start + k).min(num_airs); let chunk_size = chunk_end - chunk_start; @@ -1591,16 +1609,71 @@ pub trait IsStarkProver< .collect(); // Sequential: append roots to shared transcript (Fiat-Shamir ordering) - for result in chunk_results { + #[allow(unused_variables, unused_mut)] + for (j, result) in chunk_results.into_iter().enumerate() { let (tree, root, pre_tree, pre_root, n_pre) = result?; if let Some(ref pre_r) = pre_root { transcript.append_bytes(pre_r); } transcript.append_bytes(&root); + + // Spill the main LDE columns from the pool to a temp-file mmap before + // the pool is overwritten by the next chunk. Also spill Merkle tree nodes + // to disk — they remain accessible through mmap for Rounds 2-4 openings. + #[cfg(feature = "disk-spill")] + { + let idx = chunk_start + j; + let (air, trace, _) = &air_trace_pairs[idx]; + let num_main_cols = trace.num_main_columns; + let spilled = LDETraceTable::spill_main_from_pool( + &pool_sets[j].main, + num_main_cols, + air.step_size(), + domains[idx].blowup_factor, + ) + .map_err(|e| { + ProvingError::WrongParameter(format!( + "disk-spill main LDE table {idx}: {e}" + )) + })?; + spilled_ldes[idx] = Some(spilled); + } + + #[allow(unused_mut)] + let mut main_tree = Arc::new(tree); + #[cfg(feature = "disk-spill")] + { + Arc::get_mut(&mut main_tree) + .expect("sole Arc owner") + .spill_nodes_to_disk() + .map_err(|e| { + ProvingError::WrongParameter(format!( + "disk-spill main Merkle tree: {e}" + )) + })?; + } + + let precomputed_tree = pre_tree.map(|t| { + let mut arc = Arc::new(t); + #[cfg(feature = "disk-spill")] + { + Arc::get_mut(&mut arc) + .expect("sole Arc owner") + .spill_nodes_to_disk() + .map_err(|e| { + ProvingError::WrongParameter(format!( + "disk-spill precomputed Merkle tree: {e}" + )) + }) + .unwrap(); + } + arc + }); + main_commits.push(MainCommitData { - main_tree: Arc::new(tree), + main_tree, main_root: root, - precomputed_tree: pre_tree.map(Arc::new), + precomputed_tree, precomputed_root: pre_root, num_precomputed_cols: n_pre, }); @@ -1610,6 +1683,18 @@ pub trait IsStarkProver< #[cfg(feature = "instruments")] let main_commits_elapsed = phase_start.elapsed(); + // Re-spill main traces that were rehydrated by extract_columns_main_into + // during Phase A. After Phase A the pool holds the LDE data (already + // snapshotted to mmap above), so the original trace data is no longer + // needed in heap — push it back to mmap to free RAM for aux trace building. + #[cfg(feature = "disk-spill")] + for (_, trace, _) in air_trace_pairs.iter_mut() { + trace + .main_table + .spill_to_disk() + .map_err(|e| ProvingError::WrongParameter(format!("disk-spill late main: {e}")))?; + } + // ===================================================================== // Round 1, Phase B: Sample shared LogUp challenges // ===================================================================== @@ -1723,11 +1808,43 @@ pub trait IsStarkProver< .collect(); // Sequential: append aux roots to forked transcripts + #[allow(unused_variables)] for (j, result) in chunk_aux.into_iter().enumerate() { - let (aux_tree, aux_root) = result?; + #[allow(unused_mut)] + let (mut aux_tree, aux_root) = result?; if let Some(ref root) = aux_root { table_transcripts[chunk_start + j].append_bytes(root); } + + // Spill aux LDE columns from pool and aux Merkle tree nodes to disk. + #[cfg(feature = "disk-spill")] + { + let idx = chunk_start + j; + let (air, trace, _) = &air_trace_pairs[idx]; + if air.has_aux_trace() { + let num_aux_cols = trace.num_aux_columns; + if let Some(ref mut spilled) = spilled_ldes[idx] { + spilled + .add_aux_from_pool(&pool_sets[j].aux, num_aux_cols) + .map_err(|e| { + ProvingError::WrongParameter(format!( + "disk-spill aux LDE table {idx}: {e}" + )) + })?; + } + } + if let Some(ref mut tree_arc) = aux_tree { + Arc::get_mut(tree_arc) + .expect("sole Arc owner") + .spill_nodes_to_disk() + .map_err(|e| { + ProvingError::WrongParameter(format!( + "disk-spill aux Merkle tree {idx}: {e}" + )) + })?; + } + } + aux_results.push((aux_tree, aux_root)); } } @@ -1774,6 +1891,10 @@ pub trait IsStarkProver< // ===================================================================== // Each chunk of K tables is processed in parallel. Each worker gets its // own pool set and transcript fork. Pool sets are reused across chunks. + // + // disk-spill path: LDE data is read from mmap-backed spilled_ldes instead + // of being recomputed via reconstruct_round1. This avoids the peak memory + // spike of holding both the trace and its LDE in RAM simultaneously. #[cfg(feature = "instruments")] let phase_start = Instant::now(); @@ -1786,104 +1907,192 @@ pub trait IsStarkProver< )> = Vec::with_capacity(num_airs); let mut proofs = Vec::with_capacity(num_airs); - for chunk_start in (0..num_airs).step_by(k) { - let chunk_end = (chunk_start + k).min(num_airs); - let chunk_size = chunk_end - chunk_start; - let chunk_transcripts = &mut table_transcripts[chunk_start..chunk_end]; + // ----- disk-spill path: read from spilled LDEs ----- + #[cfg(feature = "disk-spill")] + { + for idx in 0..num_airs { + let (air, _trace, pub_inputs) = &air_trace_pairs[idx]; + let metadata = &metadatas[idx]; + let domain = &domains[idx]; + let table_transcript = &mut table_transcripts[idx]; - #[cfg(feature = "parallel")] - let iter = pool_sets[..chunk_size] - .par_iter_mut() - .zip(chunk_transcripts.par_iter_mut()) - .enumerate(); - #[cfg(not(feature = "parallel"))] - let iter = pool_sets[..chunk_size] - .iter_mut() - .zip(chunk_transcripts.iter_mut()) - .enumerate(); + #[cfg(feature = "instruments")] + let table_start = Instant::now(); + + // Take the spilled LDE (mmap-backed) — no LDE recomputation needed + let lde_trace = spilled_ldes[idx] + .take() + .expect("spilled LDE must exist for every AIR"); + + // Build Round1 from the spilled LDE + stored Merkle trees + let main = Round1CommitmentData:: { + lde_trace_merkle_tree: Arc::clone(&metadata.main_merkle_tree), + lde_trace_merkle_root: metadata.main_merkle_root, + precomputed_merkle_tree: metadata + .precomputed_merkle_tree + .as_ref() + .map(Arc::clone), + precomputed_merkle_root: metadata.precomputed_merkle_root, + num_precomputed_cols: metadata.num_precomputed_cols, + }; + + let aux = if air.has_aux_trace() { + Some(Round1CommitmentData:: { + lde_trace_merkle_tree: Arc::clone( + metadata + .aux_merkle_tree + .as_ref() + .expect("aux tree must exist when has_aux_trace"), + ), + lde_trace_merkle_root: metadata + .aux_merkle_root + .expect("aux root must exist when has_aux_trace"), + precomputed_merkle_tree: None, + precomputed_merkle_root: None, + num_precomputed_cols: 0, + }) + } else { + None + }; + + let round_1_result = Round1 { + lde_trace, + main, + aux, + rap_challenges: metadata.rap_challenges.clone(), + bus_public_inputs: metadata.bus_public_inputs.clone(), + }; + + if let Some(ref bpi) = round_1_result.bus_public_inputs { + table_transcript.append_field_element(&bpi.table_contribution); + } - let chunk_results: Vec> = iter - .map(|(j, (pool, table_transcript))| { - let idx = chunk_start + j; - let (air, trace, pub_inputs) = &air_trace_pairs[idx]; - let metadata = &metadatas[idx]; - let domain = &domains[idx]; - let twiddles = &twiddle_caches[idx]; + let proof = Self::prove_rounds_2_to_4( + *air, + *pub_inputs, + &round_1_result, + table_transcript, + domain, + )?; - #[cfg(feature = "instruments")] - let table_start = Instant::now(); + #[cfg(feature = "instruments")] + { + let sub_ops = crate::instruments::take_round_sub_ops().unwrap_or_default(); + table_timings.push(( + air.name().to_string(), + air_trace_pairs[idx].1.num_rows(), + table_start.elapsed(), + sub_ops, + )); + } - #[cfg(feature = "instruments")] - let lde_start = Instant::now(); - let round_1_result = Self::reconstruct_round1( - *air, - *trace, - domain, - metadata, - twiddles, - &mut pool.main, - &mut pool.aux, - )?; - #[cfg(feature = "instruments")] - let lde_dur = lde_start.elapsed(); + proofs.push(proof); + } + } - if let Some(ref bpi) = round_1_result.bus_public_inputs { - table_transcript.append_field_element(&bpi.table_contribution); - } + // ----- non-disk-spill path: reconstruct LDE from trace (original flow) ----- + #[cfg(not(feature = "disk-spill"))] + { + for chunk_start in (0..num_airs).step_by(k) { + let chunk_end = (chunk_start + k).min(num_airs); + let chunk_size = chunk_end - chunk_start; + + let chunk_transcripts = &mut table_transcripts[chunk_start..chunk_end]; + + #[cfg(feature = "parallel")] + let iter = pool_sets[..chunk_size] + .par_iter_mut() + .zip(chunk_transcripts.par_iter_mut()) + .enumerate(); + #[cfg(not(feature = "parallel"))] + let iter = pool_sets[..chunk_size] + .iter_mut() + .zip(chunk_transcripts.iter_mut()) + .enumerate(); + + let chunk_results: Vec> = iter + .map(|(j, (pool, table_transcript))| { + let idx = chunk_start + j; + let (air, trace, pub_inputs) = &air_trace_pairs[idx]; + let metadata = &metadatas[idx]; + let domain = &domains[idx]; + let twiddles = &twiddle_caches[idx]; - let proof = Self::prove_rounds_2_to_4( - *air, - *pub_inputs, - &round_1_result, - table_transcript, - domain, - )?; + #[cfg(feature = "instruments")] + let table_start = Instant::now(); - // Collect per-table sub-op timing via TLS. - // Both the store (inside prove_rounds_2_to_4) and this take run on the - // same rayon worker thread, so sub-ops are valid in both sequential and - // parallel mode. - #[cfg(feature = "instruments")] - let table_timing = { - let mut sub_ops = - crate::instruments::take_round_sub_ops().unwrap_or_default(); - sub_ops.trace_lde += lde_dur; - ( - air.name().to_string(), - trace.num_rows(), - table_start.elapsed(), - sub_ops, - ) - }; + #[cfg(feature = "instruments")] + let lde_start = Instant::now(); + let round_1_result = Self::reconstruct_round1( + *air, + *trace, + domain, + metadata, + twiddles, + &mut pool.main, + &mut pool.aux, + )?; + #[cfg(feature = "instruments")] + let lde_dur = lde_start.elapsed(); - // Return column Vecs to pool (zero-copy move back) - let (main_cols, aux_cols) = round_1_result.lde_trace.into_columns(); - for (slot, col) in pool.main.iter_mut().zip(main_cols) { - *slot = col; - } - for (slot, col) in pool.aux.iter_mut().zip(aux_cols) { - *slot = col; - } + if let Some(ref bpi) = round_1_result.bus_public_inputs { + table_transcript.append_field_element(&bpi.table_contribution); + } + let proof = Self::prove_rounds_2_to_4( + *air, + *pub_inputs, + &round_1_result, + table_transcript, + domain, + )?; + + // Collect per-table sub-op timing via TLS. + // Both the store (inside prove_rounds_2_to_4) and this take run on the + // same rayon worker thread, so sub-ops are valid in both sequential and + // parallel mode. + #[cfg(feature = "instruments")] + let table_timing = { + let mut sub_ops = + crate::instruments::take_round_sub_ops().unwrap_or_default(); + sub_ops.trace_lde += lde_dur; + ( + air.name().to_string(), + trace.num_rows(), + table_start.elapsed(), + sub_ops, + ) + }; + + // Return column Vecs to pool (zero-copy move back) + let (main_cols, aux_cols) = round_1_result.lde_trace.into_columns(); + for (slot, col) in pool.main.iter_mut().zip(main_cols) { + *slot = col; + } + for (slot, col) in pool.aux.iter_mut().zip(aux_cols) { + *slot = col; + } + + #[cfg(feature = "instruments")] + return Ok((proof, table_timing)); + #[cfg(not(feature = "instruments"))] + Ok(proof) + }) + .collect(); + + for result in chunk_results { #[cfg(feature = "instruments")] - return Ok((proof, table_timing)); + { + let (proof, timing) = result?; + proofs.push(proof); + table_timings.push(timing); + } #[cfg(not(feature = "instruments"))] - Ok(proof) - }) - .collect(); - - for result in chunk_results { - #[cfg(feature = "instruments")] - { - let (proof, timing) = result?; - proofs.push(proof); - table_timings.push(timing); + proofs.push(result?); } - #[cfg(not(feature = "instruments"))] - proofs.push(result?); } - } + } // end #[cfg(not(feature = "disk-spill"))] #[cfg(feature = "instruments")] { diff --git a/crypto/stark/src/table.rs b/crypto/stark/src/table.rs index 4a946f2ad..14d1634c1 100644 --- a/crypto/stark/src/table.rs +++ b/crypto/stark/src/table.rs @@ -6,6 +6,60 @@ use math::field::{ #[cfg(feature = "parallel")] use rayon::prelude::*; +/// Mmap-backed storage for a spilled Table. +/// +/// The table data is written row-major to a temp file and mmapped back. +/// Access goes through pointer arithmetic on the mmap, matching the +/// original `data[row * width + col]` layout. +#[cfg(feature = "disk-spill")] +pub(crate) struct TableMmapBacking { + mmap: memmap2::Mmap, + _file: std::fs::File, + width: usize, + height: usize, + elem_size: usize, +} + +// Manual trait impls so Table can keep its derive macros. +// Spilled tables should not be cloned during proving. +#[cfg(feature = "disk-spill")] +impl Clone for TableMmapBacking { + fn clone(&self) -> Self { + panic!("TableMmapBacking cannot be cloned — spilled tables should not be cloned") + } +} + +#[cfg(feature = "disk-spill")] +impl Default for TableMmapBacking { + fn default() -> Self { + panic!("TableMmapBacking has no default — use None") + } +} + +#[cfg(feature = "disk-spill")] +impl std::fmt::Debug for TableMmapBacking { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("TableMmapBacking") + .field("width", &self.width) + .field("height", &self.height) + .field("elem_size", &self.elem_size) + .finish() + } +} + +#[cfg(feature = "disk-spill")] +impl PartialEq for TableMmapBacking { + fn eq(&self, other: &Self) -> bool { + self.width == other.width + && self.height == other.height + && self.elem_size == other.elem_size + && self.mmap[..] == other.mmap[..] + } +} + +#[cfg(feature = "disk-spill")] +impl Eq for TableMmapBacking {} + /// A two-dimensional Table holding field elements, arranged in a row-major order. /// This is the basic underlying data structure used for any two-dimensional component in the /// the STARK protocol implementation, such as the `TraceTable` and the `EvaluationFrame`. @@ -17,6 +71,9 @@ pub struct Table { pub data: Vec>, pub width: usize, pub height: usize, + #[cfg(feature = "disk-spill")] + #[serde(skip)] + pub(crate) mmap_backing: Option, } impl Table { @@ -29,6 +86,8 @@ impl Table { data: Vec::new(), width, height: 0, + #[cfg(feature = "disk-spill")] + mmap_backing: None, }; } @@ -40,6 +99,8 @@ impl Table { data, width, height, + #[cfg(feature = "disk-spill")] + mmap_backing: None, } } @@ -65,8 +126,57 @@ impl Table { Self::new(data, width) } + /// Creates a Table instance by borrowing column data without consuming it. + /// + /// Same transpose logic as [`from_columns`], but the column Vecs are NOT consumed — + /// the caller retains them. This is used for LDE buffer reuse where the pool + /// retains the column buffers for the next table. + pub fn from_columns_borrowed(columns: &[Vec>]) -> Self { + if columns.is_empty() { + return Self::new(Vec::new(), 0); + } + let height = columns[0].len(); + + debug_assert!(columns.iter().all(|c| c.len() == height)); + + let width = columns.len(); + let mut data = Vec::with_capacity(width * height); + + for row_idx in 0..height { + for column in columns.iter() { + data.push(column[row_idx].clone()); + } + } + + Self::new(data, width) + } + + /// Returns a vector of vectors of field elements representing the table rows + pub fn rows(&self) -> Vec>> { + (0..self.height) + .map(|row_idx| self.get_row(row_idx).to_vec()) + .collect() + } + /// Given a row index, returns a reference to that row as a slice of field elements. pub fn get_row(&self, row_idx: usize) -> &[FieldElement] { + #[cfg(feature = "disk-spill")] + if let Some(ref backing) = self.mmap_backing { + debug_assert!( + row_idx < backing.height, + "Table::get_row out of bounds: row={row_idx}, height={}", + backing.height + ); + let offset = row_idx * backing.width * backing.elem_size; + // SAFETY: Row-major layout means width elements are contiguous. + // Same repr(transparent) + page-aligned guarantees as get(). + return unsafe { + std::slice::from_raw_parts( + backing.mmap.as_ptr().add(offset) as *const FieldElement, + backing.width, + ) + }; + } let row_offset = row_idx * self.width; &self.data[row_offset..row_offset + self.width] } @@ -77,12 +187,18 @@ impl Table { (0..self.width) .map(|col_idx| { (0..self.height) - .map(|row_idx| self.data[row_idx * self.width + col_idx].clone()) + .map(|row_idx| self.get(row_idx, col_idx).clone()) .collect() }) .collect() } + pub fn get_column(&self, col_idx: usize) -> Vec> { + (0..self.height) + .map(|row_idx| self.get(row_idx, col_idx).clone()) + .collect() + } + /// Extract columns directly into pre-allocated output buffers. /// /// Each `output[col_idx]` is cleared and filled with the column data. @@ -99,17 +215,34 @@ impl Table { let iter = output[..self.width].par_iter_mut().enumerate(); #[cfg(not(feature = "parallel"))] let iter = output[..self.width].iter_mut().enumerate(); + // Use get() which transparently reads from mmap or data Vec iter.for_each(|(col_idx, buf)| { buf.clear(); buf.reserve(self.height.saturating_sub(buf.capacity())); for row_idx in 0..self.height { - buf.push(self.data[row_idx * self.width + col_idx].clone()); + buf.push(self.get(row_idx, col_idx).clone()); } }); } /// Given row and column indexes, returns the stored field element in that position of the table. + #[inline] pub fn get(&self, row: usize, col: usize) -> &FieldElement { + #[cfg(feature = "disk-spill")] + if let Some(ref backing) = self.mmap_backing { + debug_assert!( + row < backing.height && col < backing.width, + "Table::get out of bounds: row={row}, col={col}, height={}, width={}", + backing.height, + backing.width + ); + // Row-major layout: offset = (row * width + col) * elem_size + let offset = (row * backing.width + col) * backing.elem_size; + // SAFETY: FieldElement is #[repr(transparent)] over F::BaseType. + // The mmap is page-aligned and elements are contiguously packed. + // The data was written from identical types on the same machine. + return unsafe { &*(backing.mmap.as_ptr().add(offset) as *const FieldElement) }; + } let idx = row * self.width + col; &self.data[idx] } @@ -119,6 +252,63 @@ impl Table { self.data[idx] = value; } + /// Returns true if this table's data has been spilled to disk via mmap. + pub fn is_spilled(&self) -> bool { + #[cfg(feature = "disk-spill")] + { + self.mmap_backing.is_some() + } + #[cfg(not(feature = "disk-spill"))] + { + false + } + } + + /// Spill the table's row-major data to a temp file and mmap it back. + /// Frees the heap `data` Vec while preserving access through `get()`, + /// `get_row()`, `columns()`, and `extract_columns_into()`. + /// + /// No-op if the table is empty or already spilled. + #[cfg(feature = "disk-spill")] + pub fn spill_to_disk(&mut self) -> std::io::Result<()> { + use std::io::Write; + + if self.data.is_empty() || self.mmap_backing.is_some() { + return Ok(()); + } + + let elem_size = std::mem::size_of::>(); + let total_bytes = self.data.len() * elem_size; + + let file = tempfile::tempfile()?; + file.set_len(total_bytes as u64)?; + { + let mut writer = std::io::BufWriter::new(&file); + // SAFETY: FieldElement is #[repr(transparent)] over F::BaseType. + // The Vec has the same byte layout as a contiguous array. + let bytes: &[u8] = + unsafe { std::slice::from_raw_parts(self.data.as_ptr() as *const u8, total_bytes) }; + writer.write_all(bytes)?; + writer.flush()?; + } + + // SAFETY: We own the file exclusively. + let mmap = unsafe { memmap2::MmapOptions::new().map(&file)? }; + + self.mmap_backing = Some(TableMmapBacking { + mmap, + _file: file, + width: self.width, + height: self.height, + elem_size, + }); + + // Free heap allocation + self.data = Vec::new(); + + Ok(()) + } + /// Given a step size, converts the given table into a `Frame`. /// Clones row data into owned Vecs (only used by verifier on small OOD tables). pub fn into_frame(&self, main_trace_columns: usize, step_size: usize) -> Frame { @@ -176,3 +366,81 @@ where &self.aux_data[row][col] } } + +#[cfg(all(test, feature = "disk-spill"))] +mod disk_spill_tests { + use super::*; + use math::field::goldilocks::GoldilocksField; + + type F = GoldilocksField; + + /// Create a Table, spill it to disk, and verify that `get()` and `get_row()` + /// return the same values as before the spill. + #[test] + fn test_table_spill_roundtrip() { + let width = 4; + let height = 8; + let data: Vec> = (0..width * height) + .map(|i| FieldElement::::from(i as u64)) + .collect(); + + let mut table = Table::new(data.clone(), width); + assert!(!table.is_spilled()); + + // Snapshot values before spill + let pre_spill: Vec>> = (0..height) + .map(|r| (0..width).map(|c| *table.get(r, c)).collect()) + .collect(); + + table.spill_to_disk().expect("spill_to_disk failed"); + assert!(table.is_spilled()); + assert!( + table.data.is_empty(), + "heap data should be freed after spill" + ); + + // Verify get() returns the same values + for (r, pre_row) in pre_spill.iter().enumerate() { + for (c, pre_val) in pre_row.iter().enumerate() { + assert_eq!(table.get(r, c), pre_val, "mismatch at ({r}, {c})"); + } + } + + // Verify get_row() returns the same values + for (r, pre_row) in pre_spill.iter().enumerate() { + let row = table.get_row(r); + assert_eq!(row.len(), width); + for (c, pre_val) in pre_row.iter().enumerate() { + assert_eq!(&row[c], pre_val, "get_row mismatch at ({r}, {c})"); + } + } + } + + /// Spilling an empty table is a no-op. + #[test] + fn test_table_spill_empty_is_noop() { + let mut table = Table::::new(Vec::new(), 0); + table + .spill_to_disk() + .expect("spill_to_disk on empty table failed"); + assert!(!table.is_spilled()); + } + + /// Spilling twice is idempotent (second call is a no-op). + #[test] + fn test_table_spill_idempotent() { + let data: Vec> = + (0..16).map(|i| FieldElement::::from(i as u64)).collect(); + let mut table = Table::new(data, 4); + + table.spill_to_disk().expect("first spill failed"); + assert!(table.is_spilled()); + + table.spill_to_disk().expect("second spill should be no-op"); + assert!(table.is_spilled()); + + // Still readable + assert_eq!(table.get(0, 0), &FieldElement::::from(0u64)); + assert_eq!(table.get(3, 3), &FieldElement::::from(15u64)); + } +} diff --git a/crypto/stark/src/trace.rs b/crypto/stark/src/trace.rs index 0025c22ea..9be025378 100644 --- a/crypto/stark/src/trace.rs +++ b/crypto/stark/src/trace.rs @@ -1,3 +1,6 @@ +#[cfg(all(feature = "disk-spill", feature = "wasm"))] +compile_error!("disk-spill and wasm features are mutually exclusive"); + use crate::domain::Domain; use crate::table::Table; use itertools::Itertools; @@ -150,6 +153,15 @@ where self.num_aux_columns = num_aux_columns; } + /// Spill the main trace data to disk via mmap. + /// After this call, `main_table.data` is freed but all accessors + /// (`get_main`, `columns_main`, `extract_columns_main_into`) continue + /// to work transparently through mmap. + #[cfg(feature = "disk-spill")] + pub fn spill_main_to_disk(&mut self) -> std::io::Result<()> { + self.main_table.spill_to_disk() + } + pub fn compute_trace_polys_main(&self) -> Vec>> where S: IsFFTField + IsSubFieldOf, @@ -201,6 +213,35 @@ where pub(crate) aux_columns: Vec>>, pub(crate) lde_step_size: usize, pub(crate) blowup_factor: usize, + /// When `disk-spill` is enabled and data has been spilled to disk, + /// this holds the mmap backing. Access methods read from here instead + /// of `main_columns`/`aux_columns` (which are empty after spill). + #[cfg(feature = "disk-spill")] + pub(crate) mmap_backing: Option, +} + +/// File-backed mmap storage for LDE column data. +/// +/// Columns are stored in separate files for main and aux (since they may be +/// spilled at different times during Phase A and Phase B of proving). +/// Each file has column-major layout: +/// ```text +/// [col_0][col_1]...[col_N] +/// ``` +/// Each column occupies `num_rows * elem_size` contiguous bytes. +/// Elements are stored as their native in-memory representation, +/// which is valid because `FieldElement` is `#[repr(transparent)]`. +#[cfg(feature = "disk-spill")] +pub(crate) struct MmapBacking { + main_mmap: memmap2::Mmap, + _main_file: std::fs::File, + aux_mmap: Option, + _aux_file: Option, + num_rows: usize, + num_main_cols: usize, + num_aux_cols: usize, + main_elem_size: usize, + aux_elem_size: usize, } impl LDETraceTable @@ -223,24 +264,39 @@ where aux_columns, lde_step_size, blowup_factor, + #[cfg(feature = "disk-spill")] + mmap_backing: None, } } /// Consume self and return the owned column vectors. + /// When mmap-backed (disk-spill), returns empty Vecs since columns were freed. #[allow(clippy::type_complexity)] pub fn into_columns(self) -> (Vec>>, Vec>>) { (self.main_columns, self.aux_columns) } pub fn num_main_cols(&self) -> usize { + #[cfg(feature = "disk-spill")] + if let Some(ref backing) = self.mmap_backing { + return backing.num_main_cols; + } self.main_columns.len() } pub fn num_aux_cols(&self) -> usize { + #[cfg(feature = "disk-spill")] + if let Some(ref backing) = self.mmap_backing { + return backing.num_aux_cols; + } self.aux_columns.len() } pub fn num_rows(&self) -> usize { + #[cfg(feature = "disk-spill")] + if let Some(ref backing) = self.mmap_backing { + return backing.num_rows; + } if self.main_columns.is_empty() { 0 } else { @@ -251,21 +307,51 @@ where /// Get a single main-trace element by (row, col). #[inline] pub fn get_main(&self, row: usize, col: usize) -> &FieldElement { + #[cfg(feature = "disk-spill")] + if let Some(ref backing) = self.mmap_backing { + debug_assert!( + row < backing.num_rows && col < backing.num_main_cols, + "get_main out of bounds: row={row}, col={col}, num_rows={}, num_main_cols={}", + backing.num_rows, + backing.num_main_cols + ); + let offset = (col * backing.num_rows + row) * backing.main_elem_size; + // SAFETY: FieldElement is #[repr(transparent)] over F::BaseType. + // The mmap is page-aligned and elements are contiguously packed at + // multiples of main_elem_size, so alignment is satisfied. + // The data was written from identical types on the same machine. + return unsafe { &*(backing.main_mmap.as_ptr().add(offset) as *const FieldElement) }; + } &self.main_columns[col][row] } /// Get a single aux-trace element by (row, col). #[inline] pub fn get_aux(&self, row: usize, col: usize) -> &FieldElement { + #[cfg(feature = "disk-spill")] + if let Some(ref backing) = self.mmap_backing { + debug_assert!( + row < backing.num_rows && col < backing.num_aux_cols, + "get_aux out of bounds: row={row}, col={col}, num_rows={}, num_aux_cols={}", + backing.num_rows, + backing.num_aux_cols + ); + let aux_mmap = backing + .aux_mmap + .as_ref() + .expect("aux mmap must exist when accessing aux columns"); + let offset = (col * backing.num_rows + row) * backing.aux_elem_size; + // SAFETY: Same as get_main — repr(transparent) + page-aligned mmap. + return unsafe { &*(aux_mmap.as_ptr().add(offset) as *const FieldElement) }; + } &self.aux_columns[col][row] } /// Gather a full main-trace row into an owned Vec. /// Used by `open_trace_polys` (called ~30 times per table, allocation is negligible). pub fn gather_main_row(&self, row_idx: usize) -> Vec> { - self.main_columns - .iter() - .map(|col| col[row_idx].clone()) + (0..self.num_main_cols()) + .map(|col| self.get_main(row_idx, col).clone()) .collect() } @@ -277,17 +363,15 @@ where col_start: usize, col_end: usize, ) -> Vec> { - self.main_columns[col_start..col_end] - .iter() - .map(|col| col[row_idx].clone()) + (col_start..col_end) + .map(|col| self.get_main(row_idx, col).clone()) .collect() } /// Gather a full aux-trace row into an owned Vec. pub fn gather_aux_row(&self, row_idx: usize) -> Vec> { - self.aux_columns - .iter() - .map(|col| col[row_idx].clone()) + (0..self.num_aux_cols()) + .map(|col| self.get_aux(row_idx, col).clone()) .collect() } @@ -300,6 +384,121 @@ where pub fn step_to_row(&self, step: usize) -> usize { self.lde_step_size * step } + + /// Write pool column data to a temp file, mmap it, and return an mmap-backed + /// LDETraceTable. The pool buffers are NOT consumed — they keep their capacity + /// for reuse by the next chunk. + /// + /// This is used during Phase A to snapshot the main LDE columns from the pool + /// before the pool is overwritten by the next chunk. + #[cfg(feature = "disk-spill")] + pub fn spill_main_from_pool( + main_pool: &[Vec>], + num_main_cols: usize, + trace_step_size: usize, + blowup_factor: usize, + ) -> std::io::Result { + let num_rows = if num_main_cols > 0 { + main_pool[0].len() + } else { + 0 + }; + + let main_elem_size = std::mem::size_of::>(); + let (main_mmap, main_file) = + Self::write_pool_columns_to_mmap(&main_pool[..num_main_cols], main_elem_size)?; + + let lde_step_size = trace_step_size * blowup_factor; + let aux_elem_size = std::mem::size_of::>(); + + Ok(Self { + main_columns: Vec::new(), + aux_columns: Vec::new(), + lde_step_size, + blowup_factor, + mmap_backing: Some(MmapBacking { + main_mmap, + _main_file: main_file, + aux_mmap: None, + _aux_file: None, + num_rows, + num_main_cols, + num_aux_cols: 0, + main_elem_size, + aux_elem_size, + }), + }) + } + + /// Add aux LDE columns from the pool to an already-spilled LDETraceTable. + /// + /// Used during Phase B to attach aux data to a table whose main LDE was + /// already spilled in Phase A. + #[cfg(feature = "disk-spill")] + pub fn add_aux_from_pool( + &mut self, + aux_pool: &[Vec>], + num_aux_cols: usize, + ) -> std::io::Result<()> { + if num_aux_cols == 0 { + return Ok(()); + } + + let aux_elem_size = std::mem::size_of::>(); + let (aux_mmap, aux_file) = + Self::write_pool_columns_to_mmap(&aux_pool[..num_aux_cols], aux_elem_size)?; + + let backing = self + .mmap_backing + .as_mut() + .expect("add_aux_from_pool requires main already spilled"); + backing.aux_mmap = Some(aux_mmap); + backing._aux_file = Some(aux_file); + backing.num_aux_cols = num_aux_cols; + + Ok(()) + } + + /// Write borrowed pool columns to a temp file and mmap them. + /// Does NOT consume the pool — columns keep their capacity. + /// + /// Note: the concrete element types are `FieldElement` (8 bytes, + /// `#[repr(transparent)]` over `u64`) and `FieldElement` + /// (24 bytes, `#[repr(transparent)]` over `[u64; 3]`). Neither has padding, + /// so the raw byte round-trip is well-defined. + #[cfg(feature = "disk-spill")] + fn write_pool_columns_to_mmap( + columns: &[Vec], + elem_size: usize, + ) -> std::io::Result<(memmap2::Mmap, std::fs::File)> { + use std::io::Write; + + let num_cols = columns.len(); + let num_rows = if num_cols > 0 { columns[0].len() } else { 0 }; + debug_assert!( + columns.iter().all(|c| c.len() == num_rows), + "all columns must have the same length" + ); + let total_bytes = (num_cols * num_rows * elem_size) as u64; + + let file = tempfile::tempfile()?; + file.set_len(total_bytes)?; + { + let mut writer = std::io::BufWriter::new(&file); + for col in columns { + // SAFETY: FieldElement is #[repr(transparent)] over BaseType, + // so the Vec has the same byte layout as a contiguous array. + let bytes: &[u8] = unsafe { + std::slice::from_raw_parts(col.as_ptr() as *const u8, col.len() * elem_size) + }; + writer.write_all(bytes)?; + } + writer.flush()?; + } + // SAFETY: We own the file exclusively. + let mmap = unsafe { memmap2::MmapOptions::new().map(&file)? }; + Ok((mmap, file)) + } } /// Given a slice of trace polynomials, an evaluation point `x`, the frame offsets @@ -487,6 +686,103 @@ where Table::new(table_data, table_width) } +#[cfg(all(test, feature = "disk-spill"))] +mod disk_spill_tests { + use super::*; + use math::field::extensions_goldilocks::Degree3GoldilocksExtensionField; + use math::field::goldilocks::GoldilocksField; + + type F = GoldilocksField; + type E = Degree3GoldilocksExtensionField; + + /// Spill main LDE columns from a simulated pool, then verify `get_main()` + /// returns the correct values from the mmap backing. + #[test] + fn test_lde_spill_main_roundtrip() { + let num_cols = 3; + let num_rows = 16; + + // Simulate pool: column-major Vec> + let pool: Vec>> = (0..num_cols) + .map(|c| { + (0..num_rows) + .map(|r| FieldElement::::from((c * num_rows + r) as u64)) + .collect() + }) + .collect(); + + let lde = LDETraceTable::::spill_main_from_pool( + &pool, num_cols, /*trace_step_size=*/ 1, /*blowup_factor=*/ 1, + ) + .expect("spill_main_from_pool failed"); + + assert_eq!(lde.num_main_cols(), num_cols); + assert_eq!(lde.num_rows(), num_rows); + assert!( + lde.main_columns.is_empty(), + "main_columns should be empty after spill" + ); + + // Verify every element + for (c, pool_col) in pool.iter().enumerate() { + for (r, pool_val) in pool_col.iter().enumerate() { + assert_eq!( + lde.get_main(r, c), + pool_val, + "mismatch at (row={r}, col={c})" + ); + } + } + } + + /// Spill main + aux LDE columns and verify both are accessible. + #[test] + fn test_lde_spill_main_and_aux_roundtrip() { + let num_main = 2; + let num_aux = 2; + let num_rows = 8; + + let main_pool: Vec>> = (0..num_main) + .map(|c| { + (0..num_rows) + .map(|r| FieldElement::::from((c * num_rows + r) as u64)) + .collect() + }) + .collect(); + + let aux_pool: Vec>> = (0..num_aux) + .map(|c| { + (0..num_rows) + .map(|r| FieldElement::::from((100 + c * num_rows + r) as u64)) + .collect() + }) + .collect(); + + let mut lde = LDETraceTable::::spill_main_from_pool(&main_pool, num_main, 1, 1) + .expect("spill_main_from_pool failed"); + + lde.add_aux_from_pool(&aux_pool, num_aux) + .expect("add_aux_from_pool failed"); + + assert_eq!(lde.num_main_cols(), num_main); + assert_eq!(lde.num_aux_cols(), num_aux); + + // Verify main + for (c, main_col) in main_pool.iter().enumerate() { + for (r, main_val) in main_col.iter().enumerate() { + assert_eq!(lde.get_main(r, c), main_val); + } + } + + // Verify aux + for (c, aux_col) in aux_pool.iter().enumerate() { + for (r, aux_val) in aux_col.iter().enumerate() { + assert_eq!(lde.get_aux(r, c), aux_val); + } + } + } +} + pub fn columns2rows(columns: Vec>) -> Vec> where F: Clone, diff --git a/executor/programs/asm/fib_iterative_128M.s b/executor/programs/asm/fib_iterative_128M.s new file mode 100644 index 000000000..b7eb30470 --- /dev/null +++ b/executor/programs/asm/fib_iterative_128M.s @@ -0,0 +1,24 @@ + .attribute 5, "rv64i2p1_m2p0" + .globl main +main: + # Iterative Fibonacci - pure register arithmetic + # ~128M steps + # + # Loop body: 5 instructions per iteration + # 25600000 iterations × 5 = 128000000 + setup/teardown + + li t0, 0 # a = fib(0) = 0 + li t1, 1 # b = fib(1) = 1 + li a0, 25600000 # iteration count + +.loop: + add t2, t0, t1 # t2 = a + b + mv t0, t1 # a = b + mv t1, t2 # b = t2 + addi a0, a0, -1 # n-- + bnez a0, .loop # loop if n != 0 + + mv a0, t1 # result = b + li a0, 0 + li a7, 93 + ecall # halt with result in a0 diff --git a/executor/programs/asm/fib_iterative_16M.s b/executor/programs/asm/fib_iterative_16M.s new file mode 100644 index 000000000..1ede85aaf --- /dev/null +++ b/executor/programs/asm/fib_iterative_16M.s @@ -0,0 +1,24 @@ + .attribute 5, "rv64i2p1_m2p0" + .globl main +main: + # Iterative Fibonacci - pure register arithmetic + # ~16M steps + # + # Loop body: 5 instructions per iteration + # 3200000 iterations × 5 = 16000000 + setup/teardown + + li t0, 0 # a = fib(0) = 0 + li t1, 1 # b = fib(1) = 1 + li a0, 3200000 # iteration count + +.loop: + add t2, t0, t1 # t2 = a + b + mv t0, t1 # a = b + mv t1, t2 # b = t2 + addi a0, a0, -1 # n-- + bnez a0, .loop # loop if n != 0 + + mv a0, t1 # result = b + li a0, 0 + li a7, 93 + ecall # halt with result in a0 diff --git a/executor/programs/asm/fib_iterative_2M.s b/executor/programs/asm/fib_iterative_2M.s index e224db769..96cdf68e2 100644 --- a/executor/programs/asm/fib_iterative_2M.s +++ b/executor/programs/asm/fib_iterative_2M.s @@ -5,11 +5,11 @@ main: # ~2M steps # # Loop body: 5 instructions per iteration - # 399999 iterations × 5 = 1999995 + 4 setup/teardown = 1999999 + # 400000 iterations × 5 = 2000000 + 4 setup/teardown ≈ 2000004 li t0, 0 # a = fib(0) = 0 li t1, 1 # b = fib(1) = 1 - li a0, 399999 # iteration count + li a0, 400000 # iteration count .loop: add t2, t0, t1 # t2 = a + b @@ -19,5 +19,6 @@ main: bnez a0, .loop # loop if n != 0 mv a0, t1 # result = b + li a0, 0 li a7, 93 ecall # halt with result in a0 diff --git a/executor/programs/asm/fib_iterative_32M.s b/executor/programs/asm/fib_iterative_32M.s new file mode 100644 index 000000000..df6644193 --- /dev/null +++ b/executor/programs/asm/fib_iterative_32M.s @@ -0,0 +1,24 @@ + .attribute 5, "rv64i2p1_m2p0" + .globl main +main: + # Iterative Fibonacci - pure register arithmetic + # ~32M steps + # + # Loop body: 5 instructions per iteration + # 6400000 iterations × 5 = 32000000 + setup/teardown + + li t0, 0 # a = fib(0) = 0 + li t1, 1 # b = fib(1) = 1 + li a0, 6400000 # iteration count + +.loop: + add t2, t0, t1 # t2 = a + b + mv t0, t1 # a = b + mv t1, t2 # b = t2 + addi a0, a0, -1 # n-- + bnez a0, .loop # loop if n != 0 + + mv a0, t1 # result = b + li a0, 0 + li a7, 93 + ecall # halt with result in a0 diff --git a/executor/programs/asm/fib_iterative_64M.s b/executor/programs/asm/fib_iterative_64M.s new file mode 100644 index 000000000..af232577b --- /dev/null +++ b/executor/programs/asm/fib_iterative_64M.s @@ -0,0 +1,24 @@ + .attribute 5, "rv64i2p1_m2p0" + .globl main +main: + # Iterative Fibonacci - pure register arithmetic + # ~64M steps + # + # Loop body: 5 instructions per iteration + # 12800000 iterations × 5 = 64000000 + setup/teardown + + li t0, 0 # a = fib(0) = 0 + li t1, 1 # b = fib(1) = 1 + li a0, 12800000 # iteration count + +.loop: + add t2, t0, t1 # t2 = a + b + mv t0, t1 # a = b + mv t1, t2 # b = t2 + addi a0, a0, -1 # n-- + bnez a0, .loop # loop if n != 0 + + mv a0, t1 # result = b + li a0, 0 + li a7, 93 + ecall # halt with result in a0 diff --git a/prover/Cargo.toml b/prover/Cargo.toml index dac711002..ed8e7e77f 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -7,6 +7,7 @@ edition = "2024" default = ["parallel"] parallel = ["stark/parallel", "math/parallel", "crypto/parallel", "dep:rayon"] debug-checks = ["stark/debug-checks"] +disk-spill = ["stark/disk-spill"] instruments = ["stark/instruments"] [dependencies] @@ -20,6 +21,7 @@ rayon = { version = "1.8.0", optional = true } [dev-dependencies] env_logger = "*" criterion = { version = "0.5", default-features = false } +bincode = "1" [[bench]] name = "vm_prover_benchmark" diff --git a/prover/src/lib.rs b/prover/src/lib.rs index 2a9d2c912..972cacab7 100644 --- a/prover/src/lib.rs +++ b/prover/src/lib.rs @@ -498,10 +498,16 @@ pub fn prove_with_options( // Page tables are derived from the prover's MemoryState (all accessed pages). let mut traces = Traces::from_elf_and_logs(&program, &result.logs, max_rows)?; + drop(result); + + #[cfg(feature = "disk-spill")] + traces + .spill_all_main_to_disk() + .map_err(|e| Error::Prover(format!("disk-spill traces: {e}")))?; + #[cfg(feature = "instruments")] let trace_build_elapsed = phase_start.elapsed(); - // Phase 3: AIR construction #[cfg(feature = "instruments")] let phase_start = std::time::Instant::now(); diff --git a/prover/src/tables/trace_builder.rs b/prover/src/tables/trace_builder.rs index 6ed876682..d03e96e2b 100644 --- a/prover/src/tables/trace_builder.rs +++ b/prover/src/tables/trace_builder.rs @@ -1577,6 +1577,28 @@ fn chunk_and_generate( } } +#[cfg(feature = "disk-spill")] +fn chunk_generate_and_spill( + ops: &[T], + max_rows: usize, + generate: impl Fn(&[T]) -> TraceTable, +) -> Result>, Error> { + let op_chunks: Vec<&[T]> = if ops.is_empty() { + vec![&[][..]] + } else { + ops.chunks(max_rows).collect() + }; + let mut tables = Vec::with_capacity(op_chunks.len()); + for chunk in op_chunks { + let mut t = generate(chunk); + t.main_table + .spill_to_disk() + .map_err(|e| Error::Prover(format!("disk-spill trace: {e}")))?; + tables.push(t); + } + Ok(tables) +} + impl Traces { /// Returns the number of chunks for each split table. pub fn table_counts(&self) -> crate::TableCounts { @@ -1593,6 +1615,54 @@ impl Traces { } } + /// Spill all trace table main columns to disk. + /// + /// Frees RAM by memory-mapping the main trace data for every table. + /// This is a no-op for tables that are already spilled or empty. + #[cfg(feature = "disk-spill")] + pub fn spill_all_main_to_disk(&mut self) -> Result<(), Error> { + let spill = |t: &mut TraceTable| { + t.main_table + .spill_to_disk() + .map_err(|e| Error::Prover(format!("disk-spill trace: {e}"))) + }; + + for t in &mut self.cpus { + spill(t)?; + } + spill(&mut self.bitwise)?; + for t in &mut self.lts { + spill(t)?; + } + for t in &mut self.shifts { + spill(t)?; + } + for t in &mut self.memws { + spill(t)?; + } + for t in &mut self.loads { + spill(t)?; + } + spill(&mut self.decode)?; + for t in &mut self.muls { + spill(t)?; + } + for t in &mut self.dvrms { + spill(t)?; + } + for t in &mut self.pages { + spill(t)?; + } + spill(&mut self.register)?; + for t in &mut self.branches { + spill(t)?; + } + spill(&mut self.halt)?; + spill(&mut self.commit)?; + + Ok(()) + } + /// Extract page configurations from ELF only (deterministic from binary). /// /// Returns PageConfigs for pages covered by ELF segments, with their @@ -1819,13 +1889,33 @@ impl Traces { lt_ops.extend(collect_lt_from_memw_aligned(&memw_aligned_ops)); // ===================================================================== - // PHASE 4: All → Bitwise lookups + // PHASE 4+5: Interleaved bitwise flush, trace generation, and drops + // + // Strategy: generate the bitwise table early, then flush bitwise ops + // from each source group in turn, dropping large op vecs as soon as + // their traces are generated to minimise peak RSS. // ===================================================================== - bitwise_ops.extend(collect_bitwise_from_lt(<_ops)); - bitwise_ops.extend(collect_bitwise_from_mul(&mul_ops)); - bitwise_ops.extend(collect_bitwise_from_dvrm(&dvrm_ops)); - bitwise_ops.extend(collect_bitwise_from_branch(&branch_ops)); - bitwise_ops.extend(shift::collect_bitwise_from_shift(&shift_ops)); + + // Dispatch macro: uses disk-spill variant when the feature is enabled. + macro_rules! gen_traces { + ($ops:expr, $max:expr, $gen:expr) => {{ + #[cfg(feature = "disk-spill")] + { + chunk_generate_and_spill($ops, $max, $gen)? + } + #[cfg(not(feature = "disk-spill"))] + { + chunk_and_generate($ops, $max, $gen) + } + }}; + } + + // --- Generate bitwise table (empty multiplicities first) --- + let mut bitwise_table = bitwise::generate_bitwise_trace(); + + // --- Flush: CPU ops + commit + page + memw_aligned + padding bitwise --- + // bitwise_ops was populated during Phase 2 (CPU, LOAD, COMMIT lookups) + // plus page IS_BYTE, memw_aligned, and padding IS_BYTE — flush all of them now. bitwise_ops.extend(collect_bitwise_from_memw_aligned(&memw_aligned_ops)); // PAGE tables do IS_BYTE lookups for init and fini values (C1, C2) bitwise_ops.extend(collect_bitwise_from_page(elf, &memory_state)); @@ -1835,7 +1925,6 @@ impl Traces { .filter(|op| !op.end) .map(|op| op.value) .collect(); - // COMMIT table sends IsByte and IsHalfword lookups bitwise_ops.extend(collect_bitwise_from_commit(&commit_ops)); // CPU padding rows send IS_BYTE with all-zero values. @@ -1846,11 +1935,10 @@ impl Traces { .sum(); bitwise_ops.extend(collect_byte_check_ops_for_padding(num_padding_rows)); - // ===================================================================== - // PHASE 5: Generate final traces (parallelized) - // ===================================================================== + bitwise::update_multiplicities(&mut bitwise_table, &bitwise_ops); + drop(bitwise_ops); - // Extract halt timestamp from the last ECALL instruction + // --- Extract halt timestamp (needs cpu_ops) --- let halt_op = cpu_ops .iter() .rev() @@ -1858,45 +1946,15 @@ impl Traces { .ok_or(Error::MissingHaltEcall)?; let halt_timestamp = halt_op.timestamp; - let cpus = chunk_and_generate(&cpu_ops, max_rows.cpu, cpu::generate_cpu_trace); - let memws = chunk_and_generate(&memw_ops, max_rows.memw, memw::generate_memw_trace); - let memw_aligneds = chunk_and_generate( - &memw_aligned_ops, - max_rows.memw_aligned, - memw_aligned::generate_memw_aligned_trace, - ); - let loads = chunk_and_generate(&load_ops, max_rows.load, load::generate_load_trace); - let lts = chunk_and_generate(<_ops, max_rows.lt, lt::generate_lt_trace); - let shifts = chunk_and_generate(&shift_ops, max_rows.shift, shift::generate_shift_trace); - let muls = chunk_and_generate(&mul_ops, max_rows.mul, mul::generate_mul_trace); - let dvrms = chunk_and_generate(&dvrm_ops, max_rows.dvrm, dvrm::generate_dvrm_trace); - let branches = - chunk_and_generate(&branch_ops, max_rows.branch, branch::generate_branch_trace); - - let mut bitwise = bitwise::generate_bitwise_trace(); - bitwise::update_multiplicities(&mut bitwise, &bitwise_ops); + // --- Generate COMMIT + PAGE + REGISTER + HALT traces --- + let commit_trace = commit::generate_commit_trace(&commit_ops); + drop(commit_ops); - // Update DECODE multiplicities - // Each CPU operation looks up the DECODE table once - // Padding rows also look up pc=1 (the CPU padding entry) - // When CPU is split, each chunk pads independently - let mut decode = decode_trace; - let pc_to_row = decode_pc_to_row; - let num_padding_rows: usize = cpu_ops - .chunks(max_rows.cpu) - .map(|chunk| chunk.len().next_power_of_two().max(4) - chunk.len()) - .sum(); - let mut decode_lookups: Vec = cpu_ops.iter().map(|op| op.decode.pc).collect(); - decode_lookups.extend(std::iter::repeat_n(cpu::CPU_PADDING_PC, num_padding_rows)); - decode::update_multiplicities(&mut decode, &pc_to_row, &decode_lookups); + let (pages, page_configs, register_trace, halt_trace); // Prepare register final state before scope (needs register_state ownership) let register_final_state = register_state.to_final_state_map(); - // Generate remaining traces in parallel (page, register, halt, commit). - // chunk_and_generate already handled cpu, lt, memw, load, mul, dvrm, branch above. - let commit_trace = commit::generate_commit_trace(&commit_ops); - let (pages, page_configs, register_trace, halt_trace); #[cfg(feature = "parallel")] { let ((pages_val, register_val), halt_val) = rayon::join( @@ -1929,9 +1987,79 @@ impl Traces { halt_trace = halt::generate_halt_trace(halt_timestamp); } + // --- Generate MEMW + MEMW_ALIGNED traces + drop ops --- + let memws = gen_traces!(&memw_ops, max_rows.memw, memw::generate_memw_trace); + drop(memw_ops); + + let memw_aligneds = gen_traces!( + &memw_aligned_ops, + max_rows.memw_aligned, + memw_aligned::generate_memw_aligned_trace + ); + drop(memw_aligned_ops); + + // --- Flush LT bitwise + generate LT traces + drop lt_ops --- + let lt_bitwise = collect_bitwise_from_lt(<_ops); + bitwise::update_multiplicities(&mut bitwise_table, <_bitwise); + drop(lt_bitwise); + + let lts = gen_traces!(<_ops, max_rows.lt, lt::generate_lt_trace); + drop(lt_ops); + + // --- Flush remaining bitwise (mul, dvrm, branch, shift) --- + let mul_bitwise = collect_bitwise_from_mul(&mul_ops); + bitwise::update_multiplicities(&mut bitwise_table, &mul_bitwise); + drop(mul_bitwise); + + let dvrm_bitwise = collect_bitwise_from_dvrm(&dvrm_ops); + bitwise::update_multiplicities(&mut bitwise_table, &dvrm_bitwise); + drop(dvrm_bitwise); + + let branch_bitwise = collect_bitwise_from_branch(&branch_ops); + bitwise::update_multiplicities(&mut bitwise_table, &branch_bitwise); + drop(branch_bitwise); + + let shift_bitwise = shift::collect_bitwise_from_shift(&shift_ops); + bitwise::update_multiplicities(&mut bitwise_table, &shift_bitwise); + drop(shift_bitwise); + + // --- Generate remaining traces (CPU, LOAD, SHIFT, MUL, DVRM, BRANCH) --- + + // Update DECODE multiplicities + // Each CPU operation looks up the DECODE table once + // Padding rows also look up pc=1 (the CPU padding entry) + // When CPU is split, each chunk pads independently + let mut decode = decode_trace; + let pc_to_row = decode_pc_to_row; + let num_padding_rows: usize = cpu_ops + .chunks(max_rows.cpu) + .map(|chunk| chunk.len().next_power_of_two().max(4) - chunk.len()) + .sum(); + let mut decode_lookups: Vec = cpu_ops.iter().map(|op| op.decode.pc).collect(); + decode_lookups.extend(std::iter::repeat_n(cpu::CPU_PADDING_PC, num_padding_rows)); + decode::update_multiplicities(&mut decode, &pc_to_row, &decode_lookups); + + let cpus = gen_traces!(&cpu_ops, max_rows.cpu, cpu::generate_cpu_trace); + drop(cpu_ops); + + let loads = gen_traces!(&load_ops, max_rows.load, load::generate_load_trace); + drop(load_ops); + + let shifts = gen_traces!(&shift_ops, max_rows.shift, shift::generate_shift_trace); + drop(shift_ops); + + let muls = gen_traces!(&mul_ops, max_rows.mul, mul::generate_mul_trace); + drop(mul_ops); + + let dvrms = gen_traces!(&dvrm_ops, max_rows.dvrm, dvrm::generate_dvrm_trace); + drop(dvrm_ops); + + let branches = gen_traces!(&branch_ops, max_rows.branch, branch::generate_branch_trace); + drop(branch_ops); + Ok(Traces { cpus, - bitwise, + bitwise: bitwise_table, lts, shifts, memws, diff --git a/prover/src/tests/disk_spill_tests.rs b/prover/src/tests/disk_spill_tests.rs new file mode 100644 index 000000000..3b8d14cbe --- /dev/null +++ b/prover/src/tests/disk_spill_tests.rs @@ -0,0 +1,119 @@ +//! Tests for the `disk-spill` feature. +//! +//! Verifies that proving and verification produce correct results when main +//! traces, LDE columns, and Merkle tree nodes are spilled to disk via mmap. + +use crate::VmProof; +use crate::tables::MaxRowsConfig; +use crate::test_utils::asm_elf_bytes; + +/// Prove + verify a small program end-to-end with disk-spill enabled. +/// This exercises the full pipeline: trace generation, main-trace spill, +/// LDE spill, Merkle-tree spill, and verification. +#[test] +fn test_disk_spill_prove_and_verify_small() { + let elf_bytes = asm_elf_bytes("sub"); + let result = crate::prove_and_verify(&elf_bytes); + assert!( + result.is_ok(), + "prove_and_verify failed: {:?}", + result.err() + ); + assert!(result.unwrap(), "verification returned false"); +} + +/// Prove + verify with `MaxRowsConfig::small()` (2^5 = 32 rows per chunk) +/// to force many chunks. This ensures disk-spill works across chunk boundaries +/// where pool buffers are reused and main traces are spilled per-chunk. +#[test] +fn test_disk_spill_prove_and_verify_with_chunks() { + let elf_bytes = asm_elf_bytes("sub"); + let proof_options = stark::proof::options::GoldilocksCubicProofOptions::with_blowup(2) + .expect("blowup=2 is always valid"); + let vm_proof = crate::prove_with_options(&elf_bytes, &proof_options, &MaxRowsConfig::small()); + assert!( + vm_proof.is_ok(), + "prove_with_options failed: {:?}", + vm_proof.err() + ); + let vm_proof = vm_proof.unwrap(); + + let ok = crate::verify_with_options(&vm_proof, &elf_bytes, &proof_options); + assert!(ok.is_ok(), "verify_with_options failed: {:?}", ok.err()); + assert!(ok.unwrap(), "verification returned false"); +} + +/// Prove, serialize with bincode, deserialize, then verify. +/// This reproduces the exact CLI path: prove → write → read → verify. +#[test] +fn test_disk_spill_serialization_roundtrip() { + let elf_bytes = asm_elf_bytes("sub"); + let proof = crate::prove(&elf_bytes).expect("prove failed"); + + let bytes = bincode::serialize(&proof).expect("serialize failed"); + eprintln!("Proof serialized: {} bytes", bytes.len()); + + let proof2: VmProof = bincode::deserialize(&bytes).expect("deserialize failed"); + let valid = crate::verify(&proof2, &elf_bytes).expect("verify failed"); + assert!(valid, "verification failed after serialization roundtrip"); +} + +/// Print struct sizes to verify memory analysis +#[test] +fn test_print_struct_sizes() { + use std::mem::size_of; + eprintln!( + "CpuOperation: {} bytes", + size_of::() + ); + eprintln!( + "MemwOperation: {} bytes", + size_of::() + ); + eprintln!( + "LtOperation: {} bytes", + size_of::() + ); + eprintln!( + "BranchOperation: {} bytes", + size_of::() + ); + eprintln!( + "BitwiseOperation: {} bytes", + size_of::() + ); + eprintln!( + "ShiftOperation: {} bytes", + size_of::() + ); +} + +/// Test prove+verify with a larger program (2M instructions). +/// This catches bugs that only manifest at scale (multiple chunks, larger tables). +#[test] +fn test_disk_spill_prove_and_verify_2m() { + let _ = env_logger::builder().is_test(true).try_init(); + let elf_bytes = asm_elf_bytes("fib_iterative_2M"); + let result = crate::prove_and_verify(&elf_bytes).expect("prove_and_verify failed"); + assert!(result, "verification returned false for fib_iterative_2M"); +} + +/// Same as above but with small chunks (MaxRowsConfig::small()). +#[test] +fn test_disk_spill_serialization_roundtrip_chunked() { + let elf_bytes = asm_elf_bytes("sub"); + let opts = stark::proof::options::GoldilocksCubicProofOptions::with_blowup(2) + .expect("blowup=2 is always valid"); + let proof = crate::prove_with_options(&elf_bytes, &opts, &MaxRowsConfig::small()) + .expect("prove failed"); + + let bytes = bincode::serialize(&proof).expect("serialize failed"); + eprintln!("Chunked proof serialized: {} bytes", bytes.len()); + + let proof2: VmProof = bincode::deserialize(&bytes).expect("deserialize failed"); + let valid = crate::verify_with_options(&proof2, &elf_bytes, &opts).expect("verify failed"); + assert!( + valid, + "verification failed after serialization roundtrip (chunked)" + ); +} diff --git a/prover/src/tests/mod.rs b/prover/src/tests/mod.rs index 957845c95..338ba8c87 100644 --- a/prover/src/tests/mod.rs +++ b/prover/src/tests/mod.rs @@ -14,6 +14,8 @@ pub mod constraints_tests; pub mod cpu_tests; #[cfg(test)] pub mod decode_tests; +#[cfg(all(test, feature = "disk-spill"))] +pub mod disk_spill_tests; #[cfg(test)] pub mod dvrm_tests; #[cfg(test)]