diff --git a/.github/workflows/rust_ci.yaml b/.github/workflows/rust_ci.yaml index f9da74a..104b072 100644 --- a/.github/workflows/rust_ci.yaml +++ b/.github/workflows/rust_ci.yaml @@ -98,10 +98,10 @@ jobs: - uses: taiki-e/install-action@v2 with: tool: just, cargo-udeps - - name: Install cargo-machete - run: cargo install cargo-machete - name: Install Rust stable toolchain - uses: dtolnay/rust-toolchain@stable + uses: dtolnay/rust-toolchain@nightly + - name: Install cargo-machete + run: cargo +nightly install cargo-machete - uses: Swatinem/rust-cache@v2 with: cache-on-failure: true diff --git a/Cargo.lock b/Cargo.lock index 8966d8f..0bf20f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -157,6 +157,18 @@ dependencies = [ "sha2", ] +[[package]] +name = "alloy-json-abi" +version = "0.8.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "731ea743b3d843bc657e120fb1d1e9cc94f5dab8107e35a82125a63e6420a102" +dependencies = [ + "alloy-primitives", + "alloy-sol-type-parser", + "serde", + "serde_json", +] + [[package]] name = "alloy-json-rpc" version = "0.9.2" @@ -449,7 +461,7 @@ checksum = "19cc9c7f20b90f9be1a8f71a3d8e283a43745137b0837b1a1cb13159d37cad72" dependencies = [ "alloy-sol-macro-input", "const-hex", - "heck", + "heck 0.5.0", "indexmap", "proc-macro-error2", "proc-macro2", @@ -467,22 +479,34 @@ checksum = "713b7e6dfe1cb2f55c80fb05fd22ed085a1b4e48217611365ed0ae598a74c6ac" dependencies = [ "const-hex", "dunce", - "heck", + "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.96", "syn-solidity", ] +[[package]] +name = "alloy-sol-type-parser" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1b3e9a48a6dd7bb052a111c8d93b5afc7956ed5e2cb4177793dc63bb1d2a36" +dependencies = [ + "serde", + "winnow 0.7.2", +] + [[package]] name = "alloy-sol-types" version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3b478bc9c0c4737a04cd976accde4df7eba0bdc0d90ad6ff43d58bc93cf79c1" dependencies = [ + "alloy-json-abi", "alloy-primitives", "alloy-sol-macro", "const-hex", + "serde", ] [[package]] @@ -492,7 +516,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d17722a198f33bbd25337660787aea8b8f57814febb7c746bc30407bdfc39448" dependencies = [ "alloy-json-rpc", - "base64", + "base64 0.22.1", "futures-util", "futures-utils-wasm", "serde", @@ -591,17 +615,63 @@ version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" +[[package]] +name = "ark-bn254" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" +dependencies = [ + "ark-ec 0.4.2", + "ark-ff 0.4.2", + "ark-std 0.4.0", +] + [[package]] name = "ark-bn254" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d69eab57e8d2663efa5c63135b2af4f396d66424f88954c21104125ab6b3e6bc" dependencies = [ - "ark-ec", + "ark-ec 0.5.0", "ark-ff 0.5.0", "ark-std 0.5.0", ] +[[package]] +name = "ark-crypto-primitives" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3a13b34da09176a8baba701233fdffbaa7c1b1192ce031a3da4e55ce1f1a56" +dependencies = [ + "ark-ec 0.4.2", + "ark-ff 0.4.2", + "ark-relations", + "ark-serialize 0.4.2", + "ark-snark", + "ark-std 0.4.0", + "blake2", + "derivative", + "digest 0.10.7", + "sha2", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff 0.4.2", + "ark-poly 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "hashbrown 0.13.2", + "itertools 0.10.5", + "num-traits", + "zeroize", +] + [[package]] name = "ark-ec" version = "0.5.0" @@ -610,7 +680,7 @@ checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce" dependencies = [ "ahash", "ark-ff 0.5.0", - "ark-poly", + "ark-poly 0.5.0", "ark-serialize 0.5.0", "ark-std 0.5.0", "educe", @@ -751,6 +821,34 @@ dependencies = [ "syn 2.0.96", ] +[[package]] +name = "ark-groth16" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20ceafa83848c3e390f1cbf124bc3193b3e639b3f02009e0e290809a501b95fc" +dependencies = [ + "ark-crypto-primitives", + "ark-ec 0.4.2", + "ark-ff 0.4.2", + "ark-poly 0.4.2", + "ark-relations", + "ark-serialize 0.4.2", + "ark-std 0.4.0", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "hashbrown 0.13.2", +] + [[package]] name = "ark-poly" version = "0.5.0" @@ -767,6 +865,18 @@ dependencies = [ "rayon", ] +[[package]] +name = "ark-relations" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00796b6efc05a3f48225e59cb6a2cda78881e7c390872d5786aaf112f31fb4f0" +dependencies = [ + "ark-ff 0.4.2", + "ark-std 0.4.0", + "tracing", + "tracing-subscriber 0.2.25", +] + [[package]] name = "ark-serialize" version = "0.3.0" @@ -783,6 +893,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" dependencies = [ + "ark-serialize-derive 0.4.2", "ark-std 0.4.0", "digest 0.10.7", "num-bigint", @@ -794,7 +905,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" dependencies = [ - "ark-serialize-derive", + "ark-serialize-derive 0.5.0", "ark-std 0.5.0", "arrayvec", "digest 0.10.7", @@ -802,6 +913,17 @@ dependencies = [ "rayon", ] +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "ark-serialize-derive" version = "0.5.0" @@ -813,6 +935,18 @@ dependencies = [ "syn 2.0.96", ] +[[package]] +name = "ark-snark" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84d3cc6833a335bb8a600241889ead68ee89a3cf8448081fb7694c0fe503da63" +dependencies = [ + "ark-ff 0.4.2", + "ark-relations", + "ark-serialize 0.4.2", + "ark-std 0.4.0", +] + [[package]] name = "ark-std" version = "0.3.0" @@ -952,6 +1086,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + [[package]] name = "base64" version = "0.22.1" @@ -964,13 +1104,22 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bindgen" version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ - "bitflags", + "bitflags 2.7.0", "cexpr", "clang-sys", "itertools 0.12.1", @@ -999,6 +1148,12 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.7.0" @@ -1017,6 +1172,21 @@ dependencies = [ "wyz", ] +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + [[package]] name = "block-buffer" version = "0.10.4" @@ -1038,6 +1208,42 @@ dependencies = [ "zeroize", ] +[[package]] +name = "bonsai-sdk" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e274325e6251c944fad96881a9744d82d6cee67244e284f62ebd1d4ede287bd" +dependencies = [ + "duplicate", + "maybe-async", + "reqwest", + "serde", + "thiserror 1.0.69", +] + +[[package]] +name = "borsh" +version = "1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5430e3be710b68d984d1391c854eb431a9d548640711faa54eecb1df93db91cc" +dependencies = [ + "borsh-derive", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8b668d39970baad5356d7c83a86fee3a539e6f93bf6764c97368243e17a0487" +dependencies = [ + "once_cell", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.96", +] + [[package]] name = "brotli" version = "7.0.0" @@ -1071,6 +1277,26 @@ version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" +[[package]] +name = "bytemuck" +version = "1.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + [[package]] name = "byteorder" version = "1.5.0" @@ -1112,6 +1338,38 @@ dependencies = [ "serde", ] +[[package]] +name = "camino" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver 1.0.24", + "serde", + "serde_json", + "thiserror 1.0.69", +] + [[package]] name = "cc" version = "1.2.8" @@ -1138,6 +1396,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chrono" version = "0.4.39" @@ -1187,7 +1451,7 @@ version = "4.5.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.96", @@ -1214,6 +1478,12 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "const-default" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b396d1f76d455557e1218ec8066ae14bba60b4b36ecd55577ba979f5db7ecaa" + [[package]] name = "const-hex" version = "1.14.0" @@ -1249,6 +1519,17 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + [[package]] name = "cpufeatures" version = "0.2.16" @@ -1259,13 +1540,10 @@ dependencies = [ ] [[package]] -name = "crc32fast" -version = "1.4.2" +name = "critical-section" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" -dependencies = [ - "cfg-if", -] +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" [[package]] name = "crossbeam-channel" @@ -1451,10 +1729,10 @@ dependencies = [ ] [[package]] -name = "directories" +name = "dirs" version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" dependencies = [ "dirs-sys", ] @@ -1482,12 +1760,34 @@ dependencies = [ "syn 2.0.96", ] +[[package]] +name = "docker-generate" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf673e0848ef09fa4aeeba78e681cf651c0c7d35f76ee38cec8e55bc32fa111" + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + [[package]] name = "dunce" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" +[[package]] +name = "duplicate" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de78e66ac9061e030587b2a2e75cc88f22304913c907b11307bca737141230cb" +dependencies = [ + "heck 0.4.1", + "proc-macro-error", +] + [[package]] name = "dyn-clone" version = "1.0.17" @@ -1520,12 +1820,28 @@ dependencies = [ "syn 2.0.96", ] +[[package]] +name = "eigenda-v2-struct-rust" +version = "0.1.0" +source = "git+https://github.com/bxue-l2/eigenda-v2-struct-rust?rev=1ceba2f777bc842c414d43911763581e5300e7d5#1ceba2f777bc842c414d43911763581e5300e7d5" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "alloy-sol-types", +] + [[package]] name = "either" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +[[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" @@ -1545,6 +1861,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "embedded-alloc" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f2de9133f68db0d4627ad69db767726c99ff8585272716708227008d3f1bddd" +dependencies = [ + "const-default", + "critical-section", + "linked_list_allocator", + "rlsf", +] + [[package]] name = "encoding_rs" version = "0.8.35" @@ -1671,16 +1999,6 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "flate2" -version = "1.0.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - [[package]] name = "fnv" version = "1.0.7" @@ -1699,7 +2017,28 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "foreign-types-shared", + "foreign-types-shared 0.1.1", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared 0.3.1", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", ] [[package]] @@ -1708,6 +2047,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -1836,8 +2181,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -1887,6 +2234,9 @@ name = "hashbrown" version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] [[package]] name = "hashbrown" @@ -1906,6 +2256,12 @@ dependencies = [ "serde", ] +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "heck" version = "0.5.0" @@ -1956,6 +2312,16 @@ dependencies = [ "tracing", ] +[[package]] +name = "hokulea-compute-kzg-proof" +version = "0.1.0" +dependencies = [ + "alloy-primitives", + "num", + "rust-kzg-bn254-primitives", + "rust-kzg-bn254-prover", +] + [[package]] name = "hokulea-eigenda" version = "0.1.0" @@ -1964,9 +2330,10 @@ dependencies = [ "alloy-rlp", "async-trait", "bytes", + "eigenda-v2-struct-rust", "kona-derive", "maili-protocol", - "rust-kzg-bn254", + "rust-kzg-bn254-primitives", "tracing", ] @@ -1980,7 +2347,9 @@ dependencies = [ "anyhow", "async-trait", "clap", + "eigenda-v2-struct-rust", "hokulea-client", + "hokulea-compute-kzg-proof", "hokulea-eigenda", "hokulea-proof", "kona-host", @@ -1997,7 +2366,10 @@ version = "0.1.0" dependencies = [ "alloy-primitives", "alloy-rlp", + "ark-bn254 0.5.0", + "ark-ff 0.5.0", "async-trait", + "eigenda-v2-struct-rust", "hokulea-eigenda", "kona-derive", "kona-driver", @@ -2006,6 +2378,9 @@ dependencies = [ "maili-protocol", "op-alloy-genesis", "op-alloy-rpc-types-engine", + "risc0-zkvm", + "rust-kzg-bn254-primitives", + "rust-kzg-bn254-verifier", "tracing", ] @@ -2084,6 +2459,7 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", + "webpki-roots", ] [[package]] @@ -2515,7 +2891,7 @@ dependencies = [ "serde_json", "tokio", "tracing", - "tracing-subscriber", + "tracing-subscriber 0.3.19", ] [[package]] @@ -2595,6 +2971,29 @@ dependencies = [ "syn 2.0.96", ] +[[package]] +name = "lazy-regex" +version = "3.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60c7310b93682b36b98fa7ea4de998d3463ccbebd94d935d6b48ba5b6ffa7126" +dependencies = [ + "lazy-regex-proc_macros", + "once_cell", + "regex", +] + +[[package]] +name = "lazy-regex-proc_macros" +version = "3.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ba01db5ef81e17eb10a5e0f2109d1b3a3e29bac3070fdbd7d156bf7dbd206a1" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "syn 2.0.96", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -2626,13 +3025,19 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "libm" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" + [[package]] name = "libredox" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags", + "bitflags 2.7.0", "libc", ] @@ -2749,12 +3154,47 @@ dependencies = [ "serde_json", ] +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "maybe-async" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + [[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "metal" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ecfd3296f8c56b7c1f6fbac3c71cefa9d78ce009850c45000015f206dc7fa21" +dependencies = [ + "bitflags 2.7.0", + "block", + "core-graphics-types", + "foreign-types 0.5.0", + "log", + "objc", + "paste", +] + [[package]] name = "mime" version = "0.3.17" @@ -2944,6 +3384,15 @@ dependencies = [ "smallvec", ] +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + [[package]] name = "object" version = "0.36.7" @@ -3022,9 +3471,9 @@ version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ - "bitflags", + "bitflags 2.7.0", "cfg-if", - "foreign-types", + "foreign-types 0.3.2", "libc", "once_cell", "openssl-macros", @@ -3254,6 +3703,30 @@ dependencies = [ "toml_edit", ] +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro-error-attr2" version = "2.0.0" @@ -3293,7 +3766,7 @@ checksum = "14cae93065090804185d3b75f0bf93b8eeda30c7a9b4a33d3bdb3988d6229e50" dependencies = [ "bit-set", "bit-vec", - "bitflags", + "bitflags 2.7.0", "lazy_static", "num-traits", "rand", @@ -3306,10 +3779,85 @@ dependencies = [ ] [[package]] -name = "quick-error" -version = "1.2.3" +name = "prost" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" +dependencies = [ + "anyhow", + "itertools 0.13.0", + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quinn" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef" +dependencies = [ + "bytes", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash 2.1.0", + "rustls", + "socket2", + "thiserror 2.0.11", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" +dependencies = [ + "bytes", + "getrandom", + "rand", + "ring", + "rustc-hash 2.1.0", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.11", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +checksum = "e46f3055866785f6b92bc6164b76be02ca8f2eb4b002c0354b28cf4c119e5944" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.59.0", +] [[package]] name = "quote" @@ -3392,7 +3940,7 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ - "bitflags", + "bitflags 2.7.0", ] [[package]] @@ -3441,9 +3989,10 @@ version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "encoding_rs", + "futures-channel", "futures-core", "futures-util", "h2", @@ -3462,7 +4011,10 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "quinn", + "rustls", "rustls-pemfile", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", @@ -3470,12 +4022,16 @@ dependencies = [ "system-configuration", "tokio", "tokio-native-tls", + "tokio-rustls", + "tokio-util", "tower", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", + "wasm-streams", "web-sys", + "webpki-roots", "windows-registry", ] @@ -3534,7 +4090,7 @@ dependencies = [ "alloy-eip7702 0.2.0", "alloy-primitives", "auto_impl", - "bitflags", + "bitflags 2.7.0", "bitvec", "c-kzg", "cfg-if", @@ -3578,6 +4134,191 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "risc0-binfmt" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc047ec0ec944104bf94cf55efa3a697aca63cff506cc949ec8d345c48ef0706" +dependencies = [ + "anyhow", + "borsh", + "elf", + "risc0-zkp", + "risc0-zkvm-platform", + "serde", + "tracing", +] + +[[package]] +name = "risc0-build" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2336678ab6701f737522f153050c8c688860a2db29ef8fea7a42ae0a1de614d6" +dependencies = [ + "anyhow", + "cargo_metadata", + "dirs", + "docker-generate", + "hex", + "risc0-binfmt", + "risc0-zkp", + "risc0-zkvm-platform", + "serde", + "serde_json", + "tempfile", +] + +[[package]] +name = "risc0-circuit-keccak" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cc983c81ee51af9bde296eb1b4dff73501fb436c3401d30d5548e00b2c0a354" +dependencies = [ + "anyhow", + "bytemuck", + "paste", + "risc0-binfmt", + "risc0-circuit-recursion", + "risc0-core", + "risc0-zkp", + "tracing", +] + +[[package]] +name = "risc0-circuit-recursion" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7d68e1a5344eb83553a6a465fcec5ceb4ab751e7b3b96c46a6c03b697f70856" +dependencies = [ + "anyhow", + "bytemuck", + "hex", + "metal", + "risc0-core", + "risc0-zkp", + "tracing", +] + +[[package]] +name = "risc0-circuit-rv32im" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca07c57b1b0eff21288a7b193a06b2b5943b3eceda6dafa0c087cbe0fcfcfa6" +dependencies = [ + "anyhow", + "metal", + "risc0-binfmt", + "risc0-core", + "risc0-zkp", + "risc0-zkvm-platform", + "serde", + "tracing", +] + +[[package]] +name = "risc0-core" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3ba5078ac767bb5cf35505e6d4da24eff76807fa73bb6ffb88e794654dd4dc" +dependencies = [ + "bytemuck", + "rand_core", +] + +[[package]] +name = "risc0-groth16" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2df58accff2fde7e8bad9d144ae91cdfb5d0101addd3365f013fe3e33dccd8" +dependencies = [ + "anyhow", + "ark-bn254 0.4.0", + "ark-ec 0.4.2", + "ark-groth16", + "ark-serialize 0.4.2", + "bytemuck", + "hex", + "num-bigint", + "num-traits", + "risc0-binfmt", + "risc0-zkp", + "serde", + "stability", +] + +[[package]] +name = "risc0-zkp" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e429d1cdb86a702eba04a02b3929bdd62a9a1859ec23b281ba2a8d0c6f418f" +dependencies = [ + "anyhow", + "blake2", + "borsh", + "bytemuck", + "cfg-if", + "digest 0.10.7", + "hex", + "hex-literal", + "metal", + "paste", + "rand_core", + "risc0-core", + "risc0-zkvm-platform", + "serde", + "sha2", + "tracing", +] + +[[package]] +name = "risc0-zkvm" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ecc97ec255ad47e1de41b9691a8d92fa48efb779b611d28c3a1c4b7c79abd0" +dependencies = [ + "anyhow", + "bincode", + "bonsai-sdk", + "borsh", + "bytemuck", + "bytes", + "getrandom", + "hex", + "lazy-regex", + "prost", + "risc0-binfmt", + "risc0-build", + "risc0-circuit-keccak", + "risc0-circuit-recursion", + "risc0-circuit-rv32im", + "risc0-core", + "risc0-groth16", + "risc0-zkp", + "risc0-zkvm-platform", + "rrs-lib", + "semver 1.0.24", + "serde", + "sha2", + "stability", + "tempfile", + "tracing", +] + +[[package]] +name = "risc0-zkvm-platform" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3707a298cacf4d665258b9e976d422401dcfe833f50794fa1e7c20d15ab45e7f" +dependencies = [ + "bytemuck", + "cfg-if", + "critical-section", + "embedded-alloc", + "getrandom", + "libm", + "stability", +] + [[package]] name = "rlp" version = "0.5.2" @@ -3588,6 +4329,18 @@ dependencies = [ "rustc-hex", ] +[[package]] +name = "rlsf" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222fb240c3286247ecdee6fa5341e7cdad0ffdf8e7e401d9937f2d58482a20bf" +dependencies = [ + "cfg-if", + "const-default", + "libc", + "svgbobdoc", +] + [[package]] name = "rocksdb" version = "0.22.0" @@ -3598,6 +4351,16 @@ dependencies = [ "librocksdb-sys", ] +[[package]] +name = "rrs-lib" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4382d3af3a4ebdae7f64ba6edd9114fff92c89808004c4943b393377a25d001" +dependencies = [ + "downcast-rs", + "paste", +] + [[package]] name = "ruint" version = "1.12.3" @@ -3629,29 +4392,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" [[package]] -name = "rust-kzg-bn254" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdae4058a9f604acf7023d99d931d6f30261fff93787bcfd1f1ccfc725b701c" +name = "rust-kzg-bn254-primitives" +version = "0.1.0" +source = "git+https://github.com/Layr-Labs/rust-kzg-bn254?rev=b3e532e9aad533009849755d5ad7b9578a16bfb2#b3e532e9aad533009849755d5ad7b9578a16bfb2" dependencies = [ - "ark-bn254", - "ark-ec", + "ark-bn254 0.5.0", + "ark-ec 0.5.0", "ark-ff 0.5.0", - "ark-poly", + "ark-poly 0.5.0", "ark-serialize 0.5.0", "ark-std 0.5.0", - "byteorder", + "num-traits", + "sha2", + "thiserror 2.0.11", +] + +[[package]] +name = "rust-kzg-bn254-prover" +version = "0.1.0" +source = "git+https://github.com/Layr-Labs/rust-kzg-bn254?rev=b3e532e9aad533009849755d5ad7b9578a16bfb2#b3e532e9aad533009849755d5ad7b9578a16bfb2" +dependencies = [ + "ark-bn254 0.5.0", + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-poly 0.5.0", + "ark-std 0.5.0", "crossbeam-channel", - "directories", - "hex-literal", - "num-bigint", "num-traits", "num_cpus", - "rand", "rayon", - "sha2", - "sys-info", - "ureq", + "rust-kzg-bn254-primitives", +] + +[[package]] +name = "rust-kzg-bn254-verifier" +version = "0.1.0" +source = "git+https://github.com/Layr-Labs/rust-kzg-bn254?rev=b3e532e9aad533009849755d5ad7b9578a16bfb2#b3e532e9aad533009849755d5ad7b9578a16bfb2" +dependencies = [ + "ark-bn254 0.5.0", + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "rust-kzg-bn254-primitives", ] [[package]] @@ -3702,7 +4484,7 @@ version = "0.38.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" dependencies = [ - "bitflags", + "bitflags 2.7.0", "errno", "libc", "linux-raw-sys", @@ -3715,7 +4497,6 @@ version = "0.23.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f287924602bf649d949c63dc8ac8b235fa5387d394020705b80c4eb597ce5b8" dependencies = [ - "log", "once_cell", "ring", "rustls-pki-types", @@ -3738,6 +4519,9 @@ name = "rustls-pki-types" version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" +dependencies = [ + "web-time", +] [[package]] name = "rustls-webpki" @@ -3839,7 +4623,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags", + "bitflags 2.7.0", "core-foundation", "core-foundation-sys", "libc", @@ -3870,6 +4654,9 @@ name = "semver" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" +dependencies = [ + "serde", +] [[package]] name = "semver-parser" @@ -3951,7 +4738,7 @@ version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" dependencies = [ - "base64", + "base64 0.22.1", "chrono", "hex", "serde", @@ -4094,6 +4881,16 @@ dependencies = [ "der", ] +[[package]] +name = "stability" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d904e7009df136af5297832a3ace3370cd14ff1546a232f4f185036c2736fcac" +dependencies = [ + "quote", + "syn 2.0.96", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -4127,7 +4924,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", "rustversion", @@ -4231,6 +5028,19 @@ dependencies = [ "sval_nested", ] +[[package]] +name = "svgbobdoc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2c04b93fc15d79b39c63218f15e3fdffaa4c227830686e3b7c5f41244eb3e50" +dependencies = [ + "base64 0.13.1", + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-width", +] + [[package]] name = "syn" version = "1.0.109" @@ -4285,23 +5095,13 @@ dependencies = [ "syn 2.0.96", ] -[[package]] -name = "sys-info" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b3a0d0aba8bf96a0e1ddfdc352fc53b3df7f39318c71854910c3c4b024ae52c" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "system-configuration" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags", + "bitflags 2.7.0", "core-foundation", "system-configuration-sys", ] @@ -4433,6 +5233,21 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tinyvec" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.43.0" @@ -4521,7 +5336,7 @@ checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap", "toml_datetime", - "winnow", + "winnow 0.6.24", ] [[package]] @@ -4557,6 +5372,7 @@ version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -4594,6 +5410,15 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-subscriber" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" +dependencies = [ + "tracing-core", +] + [[package]] name = "tracing-subscriber" version = "0.3.19" @@ -4656,6 +5481,12 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + [[package]] name = "unicode-xid" version = "0.2.6" @@ -4674,22 +5505,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" -[[package]] -name = "ureq" -version = "2.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" -dependencies = [ - "base64", - "flate2", - "log", - "once_cell", - "rustls", - "rustls-pki-types", - "url", - "webpki-roots", -] - [[package]] name = "url" version = "2.5.4" @@ -4864,6 +5679,19 @@ version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" +[[package]] +name = "wasm-streams" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "wasmtimer" version = "0.4.1" @@ -4888,11 +5716,21 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "webpki-roots" -version = "0.26.7" +version = "0.26.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" +checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9" dependencies = [ "rustls-pki-types", ] @@ -5106,6 +5944,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59690dea168f2198d1a3b0cac23b8063efcd11012f10ae4698f284808c8ef603" +dependencies = [ + "memchr", +] + [[package]] name = "write16" version = "1.0.0" diff --git a/Cargo.toml b/Cargo.toml index 1aef03e..640971c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ members = ["bin/*", "crates/*"] hokulea-client = { path = "bin/client", version = "0.1.0", default-features = false } hokulea-eigenda = { path = "crates/eigenda", version = "0.1.0", default-features = false } hokulea-proof = { path = "crates/proof", version = "0.1.0", default-features = false } +hokulea-compute-kzg-proof = { path = "crates/compute-kzg-proof", version = "0.1.0", default-features = false } # Kona # We use git dependencies instead of version dependencies because Kona is moving very fast right now @@ -60,16 +61,25 @@ tokio = "1.42.0" async-channel = "2.3.1" cfg-if = "1.0.0" reqwest = "0.12.12" -async-trait = "0.1.85" +async-trait = "0.1.81" linked_list_allocator = "0.10.5" bytes = "1.9.0" +num = "0.4" # General sha2 = { version = "0.10.8", default-features = false } c-kzg = { version = "2.0.0", default-features = false } anyhow = { version = "1.0.95", default-features = false } thiserror = { version = "2.0.9", default-features = false } -rust-kzg-bn254 = { version = "0.2.1", default-features = false } +rust-kzg-bn254-primitives = { git = "https://github.com/Layr-Labs/rust-kzg-bn254", rev = "b3e532e9aad533009849755d5ad7b9578a16bfb2", default-features = false } +rust-kzg-bn254-prover = { git = "https://github.com/Layr-Labs/rust-kzg-bn254", rev = "b3e532e9aad533009849755d5ad7b9578a16bfb2", default-features = false } +rust-kzg-bn254-verifier = { git = "https://github.com/Layr-Labs/rust-kzg-bn254", rev = "b3e532e9aad533009849755d5ad7b9578a16bfb2", default-features = false } + +# EigenDA v2 struct +eigenda-v2-struct-rust = { git = "https://github.com/bxue-l2/eigenda-v2-struct-rust", rev = "1ceba2f777bc842c414d43911763581e5300e7d5" } + +ark-bn254 = "0.5.0" +ark-ff = { version = "0.5.0", features = ["parallel"] } # Tracing tracing-loki = "0.2.5" @@ -93,6 +103,9 @@ revm = { version = "16.0.0", default-features = false } # K/V database rocksdb = { version = "0.22.0", default-features = false } +# ZKVM +risc0-zkvm = { version = "1.2.3", features = ["heap-embedded-alloc", "unstable"] } + [profile.dev] opt-level = 3 diff --git a/README.md b/README.md index 2ee09cc..6360d6d 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,9 @@ Hokulea is a library to provide the altda providers for a derivation pipeline built with [kona](https://github.com/anton-rs/kona) to understand eigenDA blobs, following the [kona book](https://anton-rs.github.io/kona/sdk/pipeline/providers.html#implementing-a-custom-data-availability-provider) recommendation (also see this [comment](https://github.com/anton-rs/kona/pull/862#issuecomment-2515038089)). +### Download SRS points +Hokulea host currently computes a challenge proof that validates the correctness of the eigenda blob against the provided kzg commitment. Such computation requires the host to have access to sufficient KZG SRS points. Follow the [link](https://github.com/Layr-Labs/eigenda-proxy/tree/main/resources) to download the points + ### Running against devnet First start the devnet: @@ -17,4 +20,4 @@ cd bin/client just run-client-native-against-devnet ``` -![](./hokulea.jpeg) \ No newline at end of file +![](./hokulea.jpeg) diff --git a/bin/client/Cargo.toml b/bin/client/Cargo.toml index 9f113b0..713b47f 100644 --- a/bin/client/Cargo.toml +++ b/bin/client/Cargo.toml @@ -14,4 +14,4 @@ kona-executor.workspace = true hokulea-proof.workspace = true -tracing.workspace = true +tracing.workspace = true \ No newline at end of file diff --git a/bin/client/justfile b/bin/client/justfile index b682b95..4be8657 100644 --- a/bin/client/justfile +++ b/bin/client/justfile @@ -5,13 +5,14 @@ default: @just --list # Run the client program on asterisc with the host in detached server mode. -run-client-asterisc block_number l1_rpc l1_beacon_rpc l2_rpc rollup_node_rpc verbosity='': +run-client-asterisc block_number l1_rpc l1_beacon_rpc l2_rpc rollup_node_rpc eigenda_proxy_rpc verbosity='': #!/usr/bin/env bash L1_NODE_ADDRESS="{{l1_rpc}}" L1_BEACON_ADDRESS="{{l1_beacon_rpc}}" L2_NODE_ADDRESS="{{l2_rpc}}" OP_NODE_ADDRESS="{{rollup_node_rpc}}" + EIGENDA_PROXY_ADDRESS="{{eigenda_proxy_rpc}}" HOST_BIN_PATH="./target/release/kona-host" CLIENT_BIN_PATH="./target/riscv64gc-unknown-none-elf/release-client-lto/kona" @@ -65,11 +66,12 @@ run-client-asterisc block_number l1_rpc l1_beacon_rpc l2_rpc rollup_node_rpc ver # Run the client program natively with the host program attached, against the op-devnet. run-client-native-against-devnet verbosity='' block_number='' rollup_config_path='': #!/usr/bin/env bash - L1_RPC="http://127.0.0.1:8545" - L1_BEACON_RPC="http://127.0.0.1:5052" - L2_RPC="http://127.0.0.1:9545" - ROLLUP_NODE_RPC="http://127.0.0.1:7545" - ROLLUP_CONFIG_PATH="{{justfile_directory()}}/../../optimism/.devnet/rollup.json" + L1_RPC="http://$(kurtosis port print eigenda-memstore-devnet el-1-geth-teku rpc)" + L1_BEACON_RPC="$(kurtosis port print eigenda-memstore-devnet cl-1-teku-geth http)" + L2_RPC="$(kurtosis port print eigenda-memstore-devnet op-el-1-op-geth-op-node-op-kurtosis rpc)" + ROLLUP_NODE_RPC="$(kurtosis port print eigenda-memstore-devnet op-cl-1-op-node-op-geth-op-kurtosis http)" + EIGENDA_PROXY_RPC="$(kurtosis port print eigenda-memstore-devnet da-server-op-kurtosis http)" + ROLLUP_CONFIG_PATH="{{justfile_directory()}}/../../rollup.json" if [ -z "{{block_number}}" ]; then BLOCK_NUMBER=$(cast block finalized --json --rpc-url $L2_RPC | jq -r .number | cast 2d) @@ -84,11 +86,11 @@ run-client-native-against-devnet verbosity='' block_number='' rollup_config_path fi set -x just run-client-native $BLOCK_NUMBER \ - $L1_RPC $L1_BEACON_RPC $L2_RPC $ROLLUP_NODE_RPC \ + $L1_RPC $L1_BEACON_RPC $L2_RPC $ROLLUP_NODE_RPC $EIGENDA_PROXY_RPC \ $ROLLUP_CONFIG_PATH {{verbosity}} # Run the client program natively with the host program attached. -run-client-native block_number l1_rpc l1_beacon_rpc l2_rpc rollup_node_rpc rollup_config_path='' verbosity='': +run-client-native block_number l1_rpc l1_beacon_rpc l2_rpc rollup_node_rpc eigenda_proxy_rpc rollup_config_path='' verbosity='': #!/usr/bin/env bash set -o errexit -o nounset -o pipefail @@ -96,6 +98,7 @@ run-client-native block_number l1_rpc l1_beacon_rpc l2_rpc rollup_node_rpc rollu L1_BEACON_ADDRESS="{{l1_beacon_rpc}}" L2_NODE_ADDRESS="{{l2_rpc}}" OP_NODE_ADDRESS="{{rollup_node_rpc}}" + EIGENDA_PROXY_ADDRESS="{{eigenda_proxy_rpc}}" L2_CHAIN_ID=$(cast chain-id --rpc-url $L2_NODE_ADDRESS) if [ -z "{{rollup_config_path}}" ]; then @@ -132,6 +135,7 @@ run-client-native block_number l1_rpc l1_beacon_rpc l2_rpc rollup_node_rpc rollu --l1-node-address $L1_NODE_ADDRESS \ --l1-beacon-address $L1_BEACON_ADDRESS \ --l2-node-address $L2_NODE_ADDRESS \ + --eigenda-proxy-address $EIGENDA_PROXY_ADDRESS \ --native \ --data-dir ./data \ $CHAIN_ID_OR_ROLLUP_CONFIG_ARG \ diff --git a/bin/client/src/lib.rs b/bin/client/src/lib.rs index bf5d889..7c9f536 100644 --- a/bin/client/src/lib.rs +++ b/bin/client/src/lib.rs @@ -8,6 +8,7 @@ use kona_preimage::{ }; use alloc::sync::Arc; + use core::fmt::Debug; use kona_executor::TrieDBProvider; use kona_proof::{ diff --git a/bin/host/Cargo.toml b/bin/host/Cargo.toml index 69820d0..64c6a21 100644 --- a/bin/host/Cargo.toml +++ b/bin/host/Cargo.toml @@ -8,6 +8,8 @@ edition = "2021" hokulea-proof.workspace = true hokulea-client.workspace = true hokulea-eigenda.workspace = true +hokulea-compute-kzg-proof.workspace = true +eigenda-v2-struct-rust.workspace = true # Kona kona-preimage = { workspace = true, features = ["std"] } diff --git a/bin/host/src/args.rs b/bin/host/src/args.rs new file mode 100644 index 0000000..a6172a1 --- /dev/null +++ b/bin/host/src/args.rs @@ -0,0 +1,12 @@ +use clap::Parser; + +#[derive(Parser, Debug, Clone)] +pub struct EigenDaArgs { + #[clap(flatten)] + pub kona_cfg: kona_host::HostCli, + + /// URL of the Ethereum RPC endpoint. + #[clap(long, env)] + #[arg(required = true)] + pub eigenda_proxy_address: Option, +} diff --git a/bin/host/src/eigenda_fetcher/mod.rs b/bin/host/src/eigenda_fetcher/mod.rs index a0a1dc6..bcb605d 100644 --- a/bin/host/src/eigenda_fetcher/mod.rs +++ b/bin/host/src/eigenda_fetcher/mod.rs @@ -7,15 +7,17 @@ use alloy_provider::ReqwestProvider; use alloy_rlp::Decodable; use anyhow::{anyhow, Result}; use core::panic; +use eigenda_v2_struct_rust::EigenDAV2Cert; +use hokulea_compute_kzg_proof::compute_kzg_proof; use hokulea_eigenda::BlobInfo; use hokulea_eigenda::EigenDABlobData; -use hokulea_eigenda::BYTES_PER_FIELD_ELEMENT; +use hokulea_eigenda::{BYTES_PER_FIELD_ELEMENT, PAYLOAD_ENCODING_VERSION_0}; use hokulea_proof::hint::{ExtendedHint, ExtendedHintType}; use kona_host::{blobs::OnlineBlobProvider, fetcher::Fetcher, kv::KeyValueStore}; use kona_preimage::{PreimageKey, PreimageKeyType}; use std::sync::Arc; use tokio::sync::RwLock; -use tracing::{error, trace, warn}; +use tracing::{error, info, trace}; /// The [FetcherWithEigenDASupport] struct wraps and extends kona's [Fetcher] struct with the ability /// to fetch preimages from EigenDA. @@ -84,7 +86,7 @@ where let (hint_type, _) = ExtendedHint::parse(hint)?.split(); // We route the hint to the right fetcher based on the hint type. match hint_type { - ExtendedHintType::EigenDACommitment => { + ExtendedHintType::EigenDACertV1 | ExtendedHintType::EigenDACertV2 => { self.last_eigenda_hint = Some(hint.to_string()); } _ => { @@ -121,7 +123,6 @@ where while preimage.is_none() { if let Err(e) = self.prefetch(hint).await { error!(target: "fetcher_with_eigenda_support", "Failed to prefetch hint: {e}"); - warn!(target: "fetcher_with_eigenda_support", "Retrying hint fetch: {hint}"); continue; } @@ -134,82 +135,121 @@ where /// Fetch the preimage for the given hint and insert it into the key-value store. async fn prefetch(&self, hint: &str) -> Result<()> { - trace!(target: "fetcher_with_eigenda_support", "prefetch: {hint}"); + info!(target: "fetcher_with_eigenda_support", "prefetch: {hint}"); let hint = ExtendedHint::parse(hint)?; let (hint_type, hint_data) = hint.split(); trace!(target: "fetcher_with_eigenda_support", "Fetching hint: {hint_type} {hint_data}"); - if hint_type == ExtendedHintType::EigenDACommitment { - let cert = hint_data; - trace!(target: "fetcher_with_eigenda_support", "Fetching eigenda commitment cert: {:?}", cert); - // Fetch the blob sidecar from the blob provider. - let rollup_data = self - .eigenda_blob_provider - .fetch_eigenda_blob(&cert) - .await - .map_err(|e| anyhow!("Failed to fetch eigenda blob: {e}"))?; - // Acquire a lock on the key-value store and set the preimages. - let mut kv_write_lock = self.kv_store.write().await; - - // the fourth because 0x01010000 in the beginning is metadata - let item_slice = cert.as_ref(); - let cert_blob_info = BlobInfo::decode(&mut &item_slice[4..]).unwrap(); - - // Proxy should return a cert whose data_length measured in symbol (i.e. 32 Bytes) - let blob_length = cert_blob_info.blob_header.data_length as u64; - warn!("blob length: {:?}", blob_length); - - let eigenda_blob = EigenDABlobData::encode(rollup_data.as_ref()); - - if eigenda_blob.blob.len() != blob_length as usize * BYTES_PER_FIELD_ELEMENT { - return Err( - anyhow!("data size from cert does not equal to reconstructed data codec_rollup_data_len {} blob size {}", - eigenda_blob.blob.len(), blob_length as usize * BYTES_PER_FIELD_ELEMENT)); - } + let cert = hint_data; + // Fetch the blob sidecar from the blob provider. + let rollup_data = self + .eigenda_blob_provider + .fetch_eigenda_blob(&cert) + .await + .map_err(|e| anyhow!("Failed to fetch eigenda blob: {e}"))?; + + // TODO define an error message from proxy that if the view call is wrong + // https://github.com/Layr-Labs/eigenda/blob/master/contracts/src/core/EigenDACertVerifier.sol#L165 + // then store empty byte in the kv_store + + let (eigenda_blob, blob_length_fe, mut blob_key) = match hint_type { + ExtendedHintType::EigenDACertV1 => { + // the fourth because 0x01010000 in the beginning is metadata + let item_slice = cert.as_ref(); + let cert_blob_info = BlobInfo::decode(&mut &item_slice[4..]).unwrap(); + + // Proxy should return a cert whose data_length measured in symbol (i.e. 32 Bytes) + let blob_length_fe = cert_blob_info.blob_header.data_length as usize; + + let eigenda_blob = EigenDABlobData::encode(rollup_data.as_ref(), PAYLOAD_ENCODING_VERSION_0); + + if eigenda_blob.blob.len() > blob_length_fe * BYTES_PER_FIELD_ELEMENT { + return Err( + anyhow!("data size from cert is less than locally crafted blob cert data size {} locally crafted size {}", + eigenda_blob.blob.len(), blob_length_fe * BYTES_PER_FIELD_ELEMENT)); + } + + // TODO figure out the key size, most likely dependent on smart contract parsing + let mut blob_key = [0u8; 96]; + blob_key[..32].copy_from_slice(cert_blob_info.blob_header.commitment.x.as_ref()); + blob_key[32..64].copy_from_slice(cert_blob_info.blob_header.commitment.y.as_ref()); + (eigenda_blob, blob_length_fe, blob_key) + }, + ExtendedHintType::EigenDACertV2 => { + // the fourth because 0x01010000 in the beginning is metadata + let item_slice = cert.as_ref(); + let v2_cert = EigenDAV2Cert::decode(&mut &item_slice[4..]).unwrap(); + + let blob_length_fe = v2_cert.blob_inclusion_info.blob_certificate.blob_header.commitment.length as usize; + + let eigenda_blob = EigenDABlobData::encode(rollup_data.as_ref(), PAYLOAD_ENCODING_VERSION_0); + + if eigenda_blob.blob.len() > blob_length_fe * BYTES_PER_FIELD_ELEMENT { + return Err( + anyhow!("data size from cert is less than locally crafted blob cert data size {} locally crafted size {}", + eigenda_blob.blob.len(), blob_length_fe * BYTES_PER_FIELD_ELEMENT)); + } - // Write all the field elements to the key-value store. - // The preimage oracle key for each field element is the keccak256 hash of - // `abi.encodePacked(cert.KZGCommitment, uint256(i))` + let x: [u8; 32] = v2_cert.blob_inclusion_info.blob_certificate.blob_header.commitment.commitment.x.to_be_bytes(); + let y: [u8; 32] = v2_cert.blob_inclusion_info.blob_certificate.blob_header.commitment.commitment.y.to_be_bytes(); - // TODO figure out the key size, most likely dependent on smart contract parsing - let mut blob_key = [0u8; 96]; - blob_key[..32].copy_from_slice(cert_blob_info.blob_header.commitment.x.as_ref()); - blob_key[32..64].copy_from_slice(cert_blob_info.blob_header.commitment.y.as_ref()); + let mut blob_key = [0u8; 96]; + blob_key[..32].copy_from_slice(&x); + blob_key[32..64].copy_from_slice(&y); + (eigenda_blob, blob_length_fe, blob_key) + }, + _ => panic!("Invalid hint type: {hint_type}. FetcherWithEigenDASupport.prefetch only supports EigenDACommitment hints."), + }; - trace!("cert_blob_info blob_length {:?}", blob_length); + // Acquire a lock on the key-value store and set the preimages. + let mut kv_write_lock = self.kv_store.write().await; - for i in 0..blob_length { - blob_key[88..].copy_from_slice(i.to_be_bytes().as_ref()); - let blob_key_hash = keccak256(blob_key.as_ref()); + // implementation requires eigenda_blob to be multiple of 32 + assert!(eigenda_blob.blob.len() % 32 == 0); + let fetch_num_element = (eigenda_blob.blob.len() / BYTES_PER_FIELD_ELEMENT) as u64; + // populate every field element (fe) onto database + for i in 0..blob_length_fe as u64 { + blob_key[88..].copy_from_slice(i.to_be_bytes().as_ref()); + let blob_key_hash = keccak256(blob_key.as_ref()); + + kv_write_lock.set( + PreimageKey::new(*blob_key_hash, PreimageKeyType::Keccak256).into(), + blob_key.into(), + )?; + + if i < fetch_num_element { kv_write_lock.set( - PreimageKey::new(*blob_key_hash, PreimageKeyType::Keccak256).into(), - blob_key.into(), + PreimageKey::new(*blob_key_hash, PreimageKeyType::GlobalGeneric).into(), + eigenda_blob.blob[(i as usize) << 5..(i as usize + 1) << 5].to_vec(), )?; + } else { + // empty bytes for the missing part between the re-encoded blob and claimed blob length from the header kv_write_lock.set( PreimageKey::new(*blob_key_hash, PreimageKeyType::GlobalGeneric).into(), - eigenda_blob.blob[(i as usize) << 5..(i as usize + 1) << 5].to_vec(), + vec![0u8; 32], )?; } - - // TODO proof is at the random point, but we need to figure out where to generate - // - // Write the KZG Proof as the last element, needed for ZK - //blob_key[88..].copy_from_slice((blob_length).to_be_bytes().as_ref()); - //let blob_key_hash = keccak256(blob_key.as_ref()); - - //kv_write_lock.set( - // PreimageKey::new(*blob_key_hash, PreimageKeyType::Keccak256).into(), - // blob_key.into(), - //)?; - // proof to be done - //kv_write_lock.set( - // PreimageKey::new(*blob_key_hash, PreimageKeyType::GlobalGeneric).into(), - // [1, 2, 3].to_vec(), - //)?; - } else { - panic!("Invalid hint type: {hint_type}. FetcherWithEigenDASupport.prefetch only supports EigenDACommitment hints."); } + + // Compute kzg proof for the entire blob on a deterministic random point + let kzg_proof = match compute_kzg_proof(&eigenda_blob.blob) { + Ok(p) => p, + Err(e) => return Err(anyhow!("cannot compute kzg proof {}", e)), + }; + + // Write the KZG Proof as the last element, needed for ZK + blob_key[88..].copy_from_slice((blob_length_fe as u64).to_be_bytes().as_ref()); + let blob_key_hash = keccak256(blob_key.as_ref()); + kv_write_lock.set( + PreimageKey::new(*blob_key_hash, PreimageKeyType::Keccak256).into(), + blob_key.into(), + )?; + kv_write_lock.set( + PreimageKey::new(*blob_key_hash, PreimageKeyType::GlobalGeneric).into(), + kzg_proof.to_vec(), + )?; + // We don't match against the other enum case because fetcher.prefetch is private, // so we can't make the below code compile. // TODO: do we want to change the Fetcher api to make this possible? diff --git a/bin/host/src/lib.rs b/bin/host/src/lib.rs index c10aaab..bba7f88 100644 --- a/bin/host/src/lib.rs +++ b/bin/host/src/lib.rs @@ -6,6 +6,8 @@ pub mod server; pub mod preimage; +pub mod args; + use server::PreimageServer; use kona_host::cli::HostCli; @@ -33,7 +35,10 @@ use tracing::info; /// - `Ok(exit_code)` if the client program exits successfully. /// - `Err(_)` if the client program failed to execute, was killed by a signal, or the host program /// exited first. -pub async fn start_server_and_native_client(cfg: HostCli) -> Result { +pub async fn start_server_and_native_client( + cfg: HostCli, + eigenda_proxy_address: String, +) -> Result { let hint_chan = BidirectionalChannel::new()?; let preimage_chan = BidirectionalChannel::new()?; let kv_store = cfg.construct_kv_store(); @@ -41,7 +46,7 @@ pub async fn start_server_and_native_client(cfg: HostCli) -> Result { let (l1_provider, blob_provider, l2_provider) = cfg.create_providers().await?; let eigenda_blob_provider = OnlineEigenDABlobProvider::new_http( //EIGENDA_ADDRESS.to_string(), - "http://127.0.0.1:3100".to_string(), + eigenda_proxy_address, ) .await .map_err(|e| anyhow!("Failed to load eigenda blob provider configuration: {e}"))?; diff --git a/bin/host/src/main.rs b/bin/host/src/main.rs index 25051f4..6a9f41c 100644 --- a/bin/host/src/main.rs +++ b/bin/host/src/main.rs @@ -2,20 +2,26 @@ use anyhow::Result; use clap::Parser; +use hokulea_host::args::EigenDaArgs; use hokulea_host::start_server_and_native_client; -use kona_host::{init_tracing_subscriber, start_server, HostCli}; +use kona_host::{init_tracing_subscriber, start_server}; use tracing::{error, info}; #[tokio::main(flavor = "multi_thread")] async fn main() -> Result<()> { - let cfg = HostCli::parse(); - init_tracing_subscriber(cfg.v)?; + let eigenda_args = EigenDaArgs::parse(); + init_tracing_subscriber(eigenda_args.kona_cfg.v)?; - if cfg.server { - start_server(cfg).await?; + if eigenda_args.kona_cfg.server { + start_server(eigenda_args.kona_cfg).await?; } else { - let status = match start_server_and_native_client(cfg).await { + let status = match start_server_and_native_client( + eigenda_args.kona_cfg, + eigenda_args.eigenda_proxy_address.unwrap(), + ) + .await + { Ok(status) => status, Err(e) => { error!(target: "hokulea_host", "Exited with an error: {:?}", e); diff --git a/crates/compute-kzg-proof/Cargo.toml b/crates/compute-kzg-proof/Cargo.toml new file mode 100644 index 0000000..3a1a50f --- /dev/null +++ b/crates/compute-kzg-proof/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "hokulea-compute-kzg-proof" +version = "0.1.0" +edition = "2021" + + +[dependencies] +rust-kzg-bn254-prover.workspace = true +rust-kzg-bn254-primitives.workspace = true +num.workspace = true + +alloy-primitives.workspace = true diff --git a/crates/compute-kzg-proof/README.md b/crates/compute-kzg-proof/README.md new file mode 100644 index 0000000..ffd8fa8 --- /dev/null +++ b/crates/compute-kzg-proof/README.md @@ -0,0 +1,5 @@ +# `compute-kzg-proof` + +This is the temporary crate for generating a kzg proof using eigenda blob. In the future, such proof is carried inside the blob header. Then this crate can be removed. + +This crate accesses the filesystem. It cannot be used in any fault proof or zk vm. \ No newline at end of file diff --git a/crates/compute-kzg-proof/src/compute_kzg_proof.rs b/crates/compute-kzg-proof/src/compute_kzg_proof.rs new file mode 100644 index 0000000..e3686a0 --- /dev/null +++ b/crates/compute-kzg-proof/src/compute_kzg_proof.rs @@ -0,0 +1,59 @@ +//! This is the temporary crate for generating a kzg proof using eigenda blob. In the future, +//! such proof is carried inside the blob header. Then this crate can be removed. This crate access filesystem, +//! cannot be used in any fault proof or zk vm. +extern crate alloc; +use alloc::vec::Vec; +use alloy_primitives::Bytes; +use num::BigUint; +use rust_kzg_bn254_primitives::blob::Blob; +use rust_kzg_bn254_primitives::errors::KzgError; +use rust_kzg_bn254_prover::kzg::KZG; +use rust_kzg_bn254_prover::srs::SRS; + +/// This function computes a KZG proof for a eigenDA blob +/// In the future, the eigenda blob header would contain the proof such that it does not require local computation +/// nitro code +/// could refactor in the future, such that both host and client can compute the proof +pub fn compute_kzg_proof(blob: &[u8]) -> Result { + // In the future, it might make sense to let the proxy to return kzg proof, instead of local computation + let srs = SRS::new("resources/g1.point", 268435456, 1024).unwrap(); + let mut kzg = KZG::new(); + + let input = Blob::new(blob); + let input_poly = input.to_polynomial_eval_form(); + + kzg.calculate_and_store_roots_of_unity(blob.len() as u64) + .unwrap(); + + let mut commitment_bytes = vec![0u8; 0]; + + let commitment = kzg.commit_eval_form(&input_poly, &srs)?; + + // TODO the library should have returned the bytes, or provide a helper + // for conversion. For both proof and commitment + let commitment_x_bigint: BigUint = commitment.x.into(); + let commitment_y_bigint: BigUint = commitment.y.into(); + + append_left_padded_biguint_be(&mut commitment_bytes, &commitment_x_bigint); + append_left_padded_biguint_be(&mut commitment_bytes, &commitment_y_bigint); + + let mut proof_bytes = vec![0u8; 0]; + + let proof = kzg.compute_blob_proof(&input, &commitment, &srs)?; + let proof_x_bigint: BigUint = proof.x.into(); + let proof_y_bigint: BigUint = proof.y.into(); + + append_left_padded_biguint_be(&mut proof_bytes, &proof_x_bigint); + append_left_padded_biguint_be(&mut proof_bytes, &proof_y_bigint); + + // push data into witness + Ok(proof_bytes.into()) +} + +/// This function convert a BigUint into 32Bytes vector in big endian format +pub fn append_left_padded_biguint_be(vec: &mut Vec, biguint: &BigUint) { + let bytes = biguint.to_bytes_be(); + let padding = 32 - bytes.len(); + vec.extend(std::iter::repeat_n(0, padding)); + vec.extend_from_slice(&bytes); +} diff --git a/crates/compute-kzg-proof/src/lib.rs b/crates/compute-kzg-proof/src/lib.rs new file mode 100644 index 0000000..aaebf3a --- /dev/null +++ b/crates/compute-kzg-proof/src/lib.rs @@ -0,0 +1,14 @@ +#![doc = include_str!("../README.md")] +#![warn( + missing_debug_implementations, + missing_docs, + unreachable_pub, + rustdoc::all +)] +#![deny(unused_must_use, rust_2018_idioms)] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] + +pub mod compute_kzg_proof; + +pub use compute_kzg_proof::compute_kzg_proof; diff --git a/crates/eigenda/Cargo.toml b/crates/eigenda/Cargo.toml index e40058c..88712b0 100644 --- a/crates/eigenda/Cargo.toml +++ b/crates/eigenda/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] kona-derive.workspace = true +eigenda-v2-struct-rust.workspace = true # Op Alloy alloy-primitives.workspace = true @@ -12,7 +13,7 @@ alloy-rlp.workspace = true tracing.workspace = true async-trait.workspace = true bytes.workspace = true -rust-kzg-bn254.workspace = true +rust-kzg-bn254-primitives.workspace = true maili-protocol.workspace = true [features] diff --git a/crates/eigenda/src/constant.rs b/crates/eigenda/src/constant.rs index f07d4ac..95cc723 100644 --- a/crates/eigenda/src/constant.rs +++ b/crates/eigenda/src/constant.rs @@ -1,6 +1,6 @@ /// This minimal blob encoding contains a 32 byte header = [0x00, version byte, uint32 len of data, 0x00, 0x00,...] /// followed by the encoded data [0x00, 31 bytes of data, 0x00, 31 bytes of data,...] -pub const BLOB_ENCODING_VERSION_0: u8 = 0x0; +pub const PAYLOAD_ENCODING_VERSION_0: u8 = 0x0; /// TODO: make it part of rollup config pub const STALE_GAP: u64 = 100; /// Number of fields for field element on bn254 diff --git a/crates/eigenda/src/eigenda.rs b/crates/eigenda/src/eigenda.rs index 05e7f69..07899f1 100644 --- a/crates/eigenda/src/eigenda.rs +++ b/crates/eigenda/src/eigenda.rs @@ -3,14 +3,14 @@ use crate::eigenda_blobs::EigenDABlobSource; use crate::traits::EigenDABlobProvider; -use crate::{BlobInfo, STALE_GAP}; +use crate::{BlobInfo, CertVersion}; use alloy_rlp::Decodable; use alloc::{boxed::Box, fmt::Debug}; use alloy_primitives::Bytes; use async_trait::async_trait; use kona_derive::{ - errors::{PipelineError, PipelineErrorKind}, + //errors::{PipelineError, PipelineErrorKind}, sources::EthereumDataSource, traits::{BlobProvider, ChainProvider, DataAvailabilityProvider}, types::PipelineResult, @@ -61,28 +61,54 @@ where async fn next(&mut self, block_ref: &BlockInfo) -> PipelineResult { // then acutally use ethereum da to fetch. items are Bytes let cert = self.ethereum_source.next(block_ref).await?; + //let l1_block_number = block_ref.number; - // verify if cert is too stale - let cert_blob_info = BlobInfo::decode(&mut &cert.as_ref()[4..]).unwrap(); - info!("cert_blob_info {:?}", cert_blob_info); - let rbn = cert_blob_info - .blob_verification_proof - .batch_medatada - .batch_header - .reference_block_number as u64; - let l1_block_number = block_ref.number; + let cert_version_byte = cert.as_ref()[3]; + let cert_version: CertVersion = cert_version_byte.into(); + match cert_version { + CertVersion::Version1 => { + // TODO if punctuality is checked elsewhere, then we don't need to deserialize here + let cert_blob_info = BlobInfo::decode(&mut &cert.as_ref()[4..]).unwrap(); + info!("cert_blob_info {:?}", cert_blob_info); + //let rbn = cert_blob_info + // .blob_verification_proof + // .batch_medatada + // .batch_header + // .reference_block_number as u64; - // check staleness - // TODO: this would require the op-rollup to follow the same pattern - // but passing blockId to proxy which implement the logic, - // see https://github.com/ethereum-optimism/optimism/blob/0bb2ff57c8133f1e3983820c0bf238001eca119b/op-alt-da/damgr.go#L211 - if rbn + STALE_GAP < l1_block_number { - // TODO: double check - return Err(PipelineErrorKind::Temporary(PipelineError::EndOfSource)); - } + // check staleness + // TODO: this would require the op-rollup to follow the same pattern + // but passing blockId to proxy which implement the logic, + // see https://github.com/ethereum-optimism/optimism/blob/0bb2ff57c8133f1e3983820c0bf238001eca119b/op-alt-da/damgr.go#L211 + //if rbn + STALE_GAP < l1_block_number { + // TODO: double check + // return Err(PipelineErrorKind::Temporary(PipelineError::EndOfSource)); + //} - let eigenda_blob = self.eigenda_source.next(&cert).await?; - Ok(eigenda_blob) + let eigenda_blob = self.eigenda_source.next(&cert).await?; + Ok(eigenda_blob) + } + CertVersion::Version2 => { + // TODO if punctuality is checked elsewhere, then we don't need to deserialize here + //let eigenda_v2_cert = match EigenDAV2Cert::decode(&mut &cert.as_ref()[4..]) { + // Ok(c) => c, + // Err(_e) => { + // return Err(PipelineErrorKind::Temporary(PipelineError::EndOfSource)) + // } + //}; + //let rbn = eigenda_v2_cert.batch_header_v2.reference_block_number as u64; + // check staleness + // TODO: this would require the op-rollup to follow the same pattern + // but passing blockId to proxy which implement the logic, + // see https://github.com/ethereum-optimism/optimism/blob/0bb2ff57c8133f1e3983820c0bf238001eca119b/op-alt-da/damgr.go#L211 + //if rbn + STALE_GAP < l1_block_number { + // TODO: double check + // return Err(PipelineErrorKind::Temporary(PipelineError::EndOfSource)); + //} + let eigenda_blob = self.eigenda_source.next(&cert).await?; + Ok(eigenda_blob) + } + } } fn clear(&mut self) { diff --git a/crates/eigenda/src/eigenda_blobs.rs b/crates/eigenda/src/eigenda_blobs.rs index c3c435d..62e71e3 100644 --- a/crates/eigenda/src/eigenda_blobs.rs +++ b/crates/eigenda/src/eigenda_blobs.rs @@ -1,7 +1,9 @@ //! Blob Data Source -use crate::eigenda_data::EigenDABlobData; use crate::traits::EigenDABlobProvider; +use crate::{eigenda_data::EigenDABlobData, CertVersion}; +use alloy_rlp::Decodable; +use eigenda_v2_struct_rust::EigenDAV2Cert; use alloc::vec::Vec; use alloy_primitives::Bytes; @@ -67,21 +69,31 @@ where return Ok(()); } - info!(target: "eigenda-blobsource", "going to fetch through eigenda fetcher"); - let data = self.eigenda_fetcher.get_blob(eigenda_commitment).await; + let cert_version: CertVersion = eigenda_commitment.as_ref()[3].into(); + let data = match cert_version { + CertVersion::Version1 => self.eigenda_fetcher.get_blob(eigenda_commitment).await, + CertVersion::Version2 => { + let eigenda_v2_cert = + EigenDAV2Cert::decode(&mut &eigenda_commitment.as_ref()[4..]).unwrap(); + self.eigenda_fetcher.get_blob_v2(&eigenda_v2_cert).await + } + }; + match data { Ok(data) => { self.open = true; - let new_blob = data.clone(); - // new_blob.truncate(data.len()-1); - let eigenda_blob = EigenDABlobData { blob: new_blob }; + let new_blob: Vec = data.into(); + let eigenda_blob = EigenDABlobData { + blob: new_blob.into(), + }; self.data.push(eigenda_blob); info!(target: "eigenda-blobsource", "load_blobs {:?}", self.data); Ok(()) } - Err(_) => { + Err(e) => { + error!("EigenDA blob source fetching error {}", e); self.open = true; Ok(()) } diff --git a/crates/eigenda/src/eigenda_data.rs b/crates/eigenda/src/eigenda_data.rs index d77a88b..395c598 100644 --- a/crates/eigenda/src/eigenda_data.rs +++ b/crates/eigenda/src/eigenda_data.rs @@ -1,12 +1,13 @@ -use crate::{BLOB_ENCODING_VERSION_0, BYTES_PER_FIELD_ELEMENT}; +use crate::BYTES_PER_FIELD_ELEMENT; use alloc::vec; use alloy_primitives::Bytes; use bytes::buf::Buf; use kona_derive::errors::BlobDecodingError; -use rust_kzg_bn254::helpers; +use rust_kzg_bn254_primitives::helpers; #[derive(Default, Clone, Debug)] -/// Represents the data structure for EigenDA Blob. +/// Represents the data structure for EigenDA Blob +/// intended for deriving rollup channel frame from eigenda blob pub struct EigenDABlobData { /// The calldata pub blob: Bytes, @@ -52,7 +53,7 @@ impl EigenDABlobData { /// /// The length of (header + payload) by the encode function is always multiple of 32 /// The eigenda proxy does not take such constraint. - pub fn encode(rollup_data: &[u8]) -> Self { + pub fn encode(rollup_data: &[u8], payload_encoding_version: u8) -> Self { let rollup_data_size = rollup_data.len() as u32; // encode to become raw blob @@ -68,7 +69,7 @@ impl EigenDABlobData { let mut raw_blob = vec![0u8; blob_size as usize]; - raw_blob[1] = BLOB_ENCODING_VERSION_0; + raw_blob[1] = payload_encoding_version; raw_blob[2..6].copy_from_slice(&rollup_data_size.to_be_bytes()); // encode length as uint32 @@ -84,6 +85,7 @@ impl EigenDABlobData { #[cfg(test)] mod tests { use super::*; + use crate::PAYLOAD_ENCODING_VERSION_0; use alloc::vec; use alloy_primitives::Bytes; use kona_derive::errors::BlobDecodingError; @@ -91,7 +93,7 @@ mod tests { #[test] fn test_encode_and_decode_success() { let rollup_data = vec![1, 2, 3, 4]; - let eigenda_blob = EigenDABlobData::encode(&rollup_data); + let eigenda_blob = EigenDABlobData::encode(&rollup_data, PAYLOAD_ENCODING_VERSION_0); let data_len = eigenda_blob.blob.len(); assert!(data_len % BYTES_PER_FIELD_ELEMENT == 0); @@ -103,7 +105,7 @@ mod tests { #[test] fn test_encode_and_decode_success_empty() { let rollup_data = vec![]; - let eigenda_blob = EigenDABlobData::encode(&rollup_data); + let eigenda_blob = EigenDABlobData::encode(&rollup_data, PAYLOAD_ENCODING_VERSION_0); let data_len = eigenda_blob.blob.len(); // 32 is eigenda blob header size assert!(data_len == 32); @@ -116,7 +118,7 @@ mod tests { #[test] fn test_encode_and_decode_error_invalid_length() { let rollup_data = vec![1, 2, 3, 4]; - let mut eigenda_blob = EigenDABlobData::encode(&rollup_data); + let mut eigenda_blob = EigenDABlobData::encode(&rollup_data, PAYLOAD_ENCODING_VERSION_0); eigenda_blob.blob.truncate(33); let result = eigenda_blob.decode(); assert!(result.is_err()); diff --git a/crates/eigenda/src/lib.rs b/crates/eigenda/src/lib.rs index 9219623..1d5f68b 100644 --- a/crates/eigenda/src/lib.rs +++ b/crates/eigenda/src/lib.rs @@ -30,7 +30,10 @@ pub use eigenda_data::EigenDABlobData; mod certificate; pub use certificate::BlobInfo; +mod version; +pub use version::CertVersion; + mod constant; -pub use constant::BLOB_ENCODING_VERSION_0; pub use constant::BYTES_PER_FIELD_ELEMENT; +pub use constant::PAYLOAD_ENCODING_VERSION_0; pub use constant::STALE_GAP; diff --git a/crates/eigenda/src/traits.rs b/crates/eigenda/src/traits.rs index 5fad440..2344810 100644 --- a/crates/eigenda/src/traits.rs +++ b/crates/eigenda/src/traits.rs @@ -2,7 +2,9 @@ use alloc::{boxed::Box, string::ToString}; use alloy_primitives::Bytes; use async_trait::async_trait; use core::fmt::Display; +use eigenda_v2_struct_rust::EigenDAV2Cert; use kona_derive::errors::PipelineErrorKind; +use rust_kzg_bn254_primitives::blob::Blob; /// A trait for providing EigenDA blobs. /// TODO: add explanation for why we need this to be a trait. @@ -11,9 +13,9 @@ pub trait EigenDABlobProvider { /// The error type for the [EigenDABlobProvider]. type Error: Display + ToString + Into; - /// Fetches a blob. - async fn get_blob(&mut self, cert: &Bytes) -> Result; + /// Fetches a blob with v1 cert + async fn get_blob(&mut self, cert: &Bytes) -> Result; - /// Fetches an element from a blob. - async fn get_element(&mut self, cert: &Bytes, element: &Bytes) -> Result; + /// Fetches a blob with v2 cert + async fn get_blob_v2(&mut self, cert: &EigenDAV2Cert) -> Result; } diff --git a/crates/eigenda/src/version.rs b/crates/eigenda/src/version.rs new file mode 100644 index 0000000..ca985fa --- /dev/null +++ b/crates/eigenda/src/version.rs @@ -0,0 +1,21 @@ +#[derive(Debug, PartialEq, Copy, Clone)] +/// Represents the cert version derived from rollup inbox +/// The version is needed to decode the Cert from serialiezd bytes +/// Once a valid blob is retrieved, both versions use the identical +/// logic to derive the rollup channel frame from eigenda blobs +pub enum CertVersion { + /// existing eigenda cert version + Version1, + /// lastest eigenda cert version + Version2, +} + +impl From for CertVersion { + fn from(value: u8) -> Self { + match value { + 0 => Self::Version1, + 1 => Self::Version2, + _ => panic!("unknown version"), + } + } +} diff --git a/crates/proof/Cargo.toml b/crates/proof/Cargo.toml index 0bc80b9..e000246 100644 --- a/crates/proof/Cargo.toml +++ b/crates/proof/Cargo.toml @@ -12,6 +12,13 @@ kona-derive.workspace = true hokulea-eigenda.workspace = true +eigenda-v2-struct-rust.workspace = true +rust-kzg-bn254-primitives.workspace = true +rust-kzg-bn254-verifier.workspace = true + +ark-bn254.workspace = true +ark-ff.workspace = true + # Alloy alloy-primitives.workspace = true @@ -21,6 +28,9 @@ op-alloy-genesis = { workspace = true, features = ["serde"] } alloy-rlp.workspace = true maili-protocol.workspace = true +# ZKVM +risc0-zkvm.workspace = true + tracing.workspace = true # General diff --git a/crates/proof/src/cert_validity.rs b/crates/proof/src/cert_validity.rs new file mode 100644 index 0000000..e93739e --- /dev/null +++ b/crates/proof/src/cert_validity.rs @@ -0,0 +1,44 @@ +use alloy_primitives::B256; +use eigenda_v2_struct_rust::EigenDAV2Cert; +use risc0_zkvm::is_dev_mode; +use risc0_zkvm::Receipt; + +#[derive(Debug, Clone, Default)] +pub struct CertValidity { + /// the claim about if the cert is valid + pub claimed_validity: bool, + /// a zkvm proof attesting the above result + /// in dev mode, receipt is ignored + pub receipt: Option, +} + +impl CertValidity { + /// verify if the receipt for cert is valid + /// note this is different from if the cert itself is valid as in the is_valid field + pub fn validate_cert_receipt( + &self, + eigenda_cert: &EigenDAV2Cert, + validity_call_verifier_id: B256, + ) { + if !is_dev_mode() { + use crate::journal::CertValidityJournal; + use alloy_rlp::Decodable; + use risc0_zkvm::sha::Digest; + + // if not in dev mode, the receipt must be non empty + assert!(self.receipt.is_some()); + let receipt = self.receipt.as_ref().unwrap(); + + let journal = CertValidityJournal::decode(&mut receipt.journal.bytes.as_ref()).unwrap(); + // ensure journal attests the same outcome + assert!(journal.is_valid == self.claimed_validity); + + // ensure journal contains the correct cert + assert!(journal.cert_digest == eigenda_cert.digest()); + let fpvm_image_id = Digest::from(validity_call_verifier_id.0); + + // so far, we have ensure the data is right, now verify the proof with respect to the data + assert!(self.receipt.as_ref().unwrap().verify(fpvm_image_id).is_ok()) + } + } +} diff --git a/crates/proof/src/eigenda_blob_witness.rs b/crates/proof/src/eigenda_blob_witness.rs new file mode 100644 index 0000000..b8477e0 --- /dev/null +++ b/crates/proof/src/eigenda_blob_witness.rs @@ -0,0 +1,23 @@ +extern crate alloc; +use alloc::vec::Vec; +use alloy_primitives::FixedBytes; + +use eigenda_v2_struct_rust::EigenDAV2Cert; +use rust_kzg_bn254_primitives::blob::Blob; + +use crate::cert_validity::CertValidity; + +/// stores +#[derive(Debug, Clone, Default)] +pub struct EigenDABlobWitnessData { + /// eigenda v2 cert + pub eigenda_certs: Vec, + /// blob empty if cert is invalid + pub eigenda_blobs: Vec, + /// kzg proof on Fiat Shamir points + pub kzg_proofs: Vec>, + /// indicates the validity of a cert is either true or false + /// validity contains a zk proof attesting claimed + /// validity + pub validity: Vec, +} diff --git a/crates/proof/src/eigenda_provider.rs b/crates/proof/src/eigenda_provider.rs index 5c62f23..77d65e2 100644 --- a/crates/proof/src/eigenda_provider.rs +++ b/crates/proof/src/eigenda_provider.rs @@ -7,8 +7,11 @@ use kona_preimage::{errors::PreimageOracleError, CommsClient, PreimageKey, Preim use kona_proof::errors::OracleProviderError; +use eigenda_v2_struct_rust::EigenDAV2Cert; +use rust_kzg_bn254_primitives::blob::Blob; + use crate::hint::ExtendedHintType; -use alloy_rlp::Decodable; +use alloy_rlp::{Decodable, Encodable}; use tracing::info; /// The oracle-backed EigenDA provider for the client program. @@ -29,9 +32,10 @@ impl OracleEigenDAProvider { impl EigenDABlobProvider for OracleEigenDAProvider { type Error = OracleProviderError; - async fn get_blob(&mut self, cert: &Bytes) -> Result { + /// Get V1 blobs. TODO remove in the future if not needed for testing + async fn get_blob(&mut self, cert: &Bytes) -> Result { self.oracle - .write(&ExtendedHintType::EigenDACommitment.encode_with(&[cert])) + .write(&ExtendedHintType::EigenDACertV1.encode_with(&[cert])) .await .map_err(OracleProviderError::Preimage)?; @@ -76,12 +80,13 @@ impl EigenDABlobProvider for OracleEigenDAProvider for i in 0..data_length { blob_key[88..].copy_from_slice(i.to_be_bytes().as_ref()); - let mut field_element = [0u8; 32]; - self.oracle - .get_exact( - PreimageKey::new(*keccak256(blob_key), PreimageKeyType::GlobalGeneric), - &mut field_element, - ) + //let mut field_element = [0u8; 32]; + let field_element = self + .oracle + .get(PreimageKey::new( + *keccak256(blob_key), + PreimageKeyType::GlobalGeneric, + )) .await .map_err(OracleProviderError::Preimage)?; @@ -92,35 +97,85 @@ impl EigenDABlobProvider for OracleEigenDAProvider "field elememnt is empty, breached eigenda invariant".into(), ))); } + // a field element for bn254 + assert!(field_element.len() == 32); blob[(i as usize) << 5..(i as usize + 1) << 5].copy_from_slice(field_element.as_ref()); } - info!("cert_blob_info blob {:?}", blob); + info!("cert_blob_info blob End {:?}", blob); Ok(blob.into()) } - async fn get_element(&mut self, cert: &Bytes, element: &Bytes) -> Result { + /// get_blob_v2 takes a v2 cert type as opposed to bytes stream + async fn get_blob_v2(&mut self, cert: &EigenDAV2Cert) -> Result { + let mut cert_rlp_bytes = Vec::::new(); + // rlp encode of cert + cert.encode(&mut cert_rlp_bytes); + self.oracle - .write(&ExtendedHintType::EigenDACommitment.encode_with(&[cert])) + .write(&ExtendedHintType::EigenDACertV2.encode_with(&[&cert_rlp_bytes])) .await .map_err(OracleProviderError::Preimage)?; - let cert_point_key = Bytes::copy_from_slice(&[cert.to_vec(), element.to_vec()].concat()); + let blob_length = cert + .blob_inclusion_info + .blob_certificate + .blob_header + .commitment + .length as usize; - self.oracle - .write(&ExtendedHintType::EigenDACommitment.encode_with(&[&cert_point_key])) - .await - .map_err(OracleProviderError::Preimage)?; - let data = self - .oracle - .get(PreimageKey::new( - *keccak256(cert_point_key), - PreimageKeyType::GlobalGeneric, - )) - .await - .map_err(OracleProviderError::Preimage)?; - Ok(data.into()) + // data_length measurs in field element, multiply to get num bytes + let mut blob: Vec = vec![0; blob_length * BYTES_PER_FIELD_ELEMENT]; + + // TODO: Investigate of using cert_rlp_bytes as key, instead of 96 bytes + let mut blob_key = [0u8; 96]; + + // the common key + let x: [u8; 32] = cert + .blob_inclusion_info + .blob_certificate + .blob_header + .commitment + .commitment + .x + .to_be_bytes(); + let y: [u8; 32] = cert + .blob_inclusion_info + .blob_certificate + .blob_header + .commitment + .commitment + .y + .to_be_bytes(); + + blob_key[..32].copy_from_slice(&x); + blob_key[32..64].copy_from_slice(&y); + + for i in 0..blob_length { + blob_key[88..].copy_from_slice(i.to_be_bytes().as_ref()); + + let mut field_element = [0u8; 32]; + self.oracle + .get_exact( + PreimageKey::new(*keccak256(blob_key), PreimageKeyType::GlobalGeneric), + &mut field_element, + ) + .await + .map_err(OracleProviderError::Preimage)?; + + // if field element is 0, it means the host has identified that the data + // has breached eigenda invariant, i.e cert is valid + if field_element.is_empty() { + return Err(OracleProviderError::Preimage(PreimageOracleError::Other( + "field elememnt is empty, breached eigenda invariant".into(), + ))); + } + + blob[i << 5..(i + 1) << 5].copy_from_slice(field_element.as_ref()); + } + + Ok(Blob::new(&blob)) } } diff --git a/crates/proof/src/hint.rs b/crates/proof/src/hint.rs index af453b3..b541f20 100644 --- a/crates/proof/src/hint.rs +++ b/crates/proof/src/hint.rs @@ -52,7 +52,8 @@ impl ExtendedHint { #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum ExtendedHintType { Original(HintType), - EigenDACommitment, + EigenDACertV1, + EigenDACertV2, } impl ExtendedHintType { @@ -68,7 +69,8 @@ impl TryFrom<&str> for ExtendedHintType { fn try_from(value: &str) -> Result { match value { - "eigenda-commitment" => Ok(Self::EigenDACommitment), + "eigenda-certificate-v1" => Ok(Self::EigenDACertV1), + "eigenda-certificate-v2" => Ok(Self::EigenDACertV2), _ => Ok(Self::Original(HintType::try_from(value)?)), } } @@ -77,7 +79,8 @@ impl TryFrom<&str> for ExtendedHintType { impl From for &str { fn from(value: ExtendedHintType) -> Self { match value { - ExtendedHintType::EigenDACommitment => "eigenda-commitment", + ExtendedHintType::EigenDACertV1 => "eigenda-certificate-v1", + ExtendedHintType::EigenDACertV2 => "eigenda-certificate-v2", ExtendedHintType::Original(hint_type) => hint_type.into(), } } diff --git a/crates/proof/src/journal.rs b/crates/proof/src/journal.rs new file mode 100644 index 0000000..cc815ee --- /dev/null +++ b/crates/proof/src/journal.rs @@ -0,0 +1,22 @@ +use alloy_primitives::B256; +use alloy_rlp::{RlpDecodable, RlpEncodable}; +use eigenda_v2_struct_rust::EigenDAV2Cert; + +/// CertValidityJournal is a data structure committed by zkvm guest code, that comes with +/// corresponding zk proof attesting its validity +#[derive(PartialEq, Eq, Ord, PartialOrd, Clone, Copy, Debug, RlpEncodable, RlpDecodable)] +pub struct CertValidityJournal { + /// indicate if cert is honest + pub is_valid: bool, + /// the hash digest of Cert + pub cert_digest: B256, +} + +impl CertValidityJournal { + pub fn new(is_valid: bool, cert: EigenDAV2Cert) -> Self { + Self { + is_valid, + cert_digest: cert.digest(), + } + } +} diff --git a/crates/proof/src/lib.rs b/crates/proof/src/lib.rs index 6b6084f..4f0cfeb 100644 --- a/crates/proof/src/lib.rs +++ b/crates/proof/src/lib.rs @@ -5,3 +5,11 @@ pub mod hint; pub mod pipeline; pub mod eigenda_provider; + +pub mod preloaded_eigenda_provider; + +pub mod eigenda_blob_witness; + +pub mod journal; + +pub mod cert_validity; diff --git a/crates/proof/src/preloaded_eigenda_provider.rs b/crates/proof/src/preloaded_eigenda_provider.rs new file mode 100644 index 0000000..fd67f18 --- /dev/null +++ b/crates/proof/src/preloaded_eigenda_provider.rs @@ -0,0 +1,127 @@ +use crate::eigenda_blob_witness::EigenDABlobWitnessData; +use alloy_primitives::{Bytes, FixedBytes, B256, U256}; +use ark_bn254::{Fq, G1Affine}; +use ark_ff::PrimeField; +use async_trait::async_trait; +use eigenda_v2_struct_rust::EigenDAV2Cert; +use hokulea_eigenda::EigenDABlobProvider; +use kona_preimage::errors::PreimageOracleError; +use kona_proof::errors::OracleProviderError; +use rust_kzg_bn254_primitives::blob::Blob; +use rust_kzg_bn254_verifier::batch; +use tracing::info; + +/// PreloadedEigenDABlobProvider ensures the following invariants +/// PreloadedEigenDABlobProvider implements EigenDABlobProvider +/// (P0) Validate validity proof for eigenda cert is correct, regardless if cert itself is correct +/// (P1) Given a cert is valid, then blob and the commitment in the cert must be consistent +/// (P2) Given a cert is invalid, then blob must be empty +#[derive(Clone, Debug, Default)] +pub struct PreloadedEigenDABlobProvider { + /// The tuple contains EigenDAV2Cert, Blob, isValid cert. + pub entries: Vec<(EigenDAV2Cert, Blob)>, +} + +impl From for PreloadedEigenDABlobProvider { + fn from(value: EigenDABlobWitnessData) -> Self { + let mut blobs = vec![]; + let mut proofs = vec![]; + let mut commitments = vec![]; + + let mut entries = vec![]; + + for i in 0..blobs.len() { + // always verify validity of the cert + value.validity[i].validate_cert_receipt( + &value.eigenda_certs[i], + // TODO figure out a way to pass down validity_call_verifier_id + // at minimum, this value needs to come from system config from derivation + B256::default(), + ); + + // if valid, check blob kzg integrity + if value.validity[i].claimed_validity { + blobs.push(value.eigenda_blobs[i].clone()); + proofs.push(value.kzg_proofs[i]); + let commitment = value.eigenda_certs[i] + .blob_inclusion_info + .blob_certificate + .blob_header + .commitment + .commitment; + commitments.push((commitment.x, commitment.y)); + } else { + // check (P2) if cert is not valid, the blob is only allowed to be empty + assert!(value.eigenda_blobs[i].is_empty()); + } + entries.push(( + value.eigenda_certs[i].clone(), + value.eigenda_blobs[i].clone(), + )); + } + + // check (P1) if cert is not valie, the blob must be empty, assert that commitments in the cert and blobs are consistent + assert!(batch_verify(blobs, commitments, proofs)); + + PreloadedEigenDABlobProvider { entries } + } +} + +#[async_trait] +impl EigenDABlobProvider for PreloadedEigenDABlobProvider { + // TODO investigate if create a speical error type EigenDABlobProviderError + type Error = OracleProviderError; + + /// Fetches a blob for V1 + async fn get_blob(&mut self, _cert: &Bytes) -> Result { + unimplemented!() + } + + /// Fetches a blob for V2 using preloaded data + /// Return an error if cert does not match the immeditate next item + async fn get_blob_v2(&mut self, cert: &EigenDAV2Cert) -> Result { + let (eigenda_cert, eigenda_blob) = self.entries.pop().unwrap(); + if eigenda_cert == *cert { + Ok(eigenda_blob) + } else { + Err(OracleProviderError::Preimage(PreimageOracleError::Other( + "does not contain header".into(), + ))) + } + } +} + +/// Eventually, rust-kzg-bn254 would provide a nice interface that takes +/// bytes input, so that we can remove this wrapper. For now, just include it here +pub fn batch_verify( + eigenda_blobs: Vec, + commitments: Vec<(U256, U256)>, + proofs: Vec>, +) -> bool { + info!("lib_blobs len {:?}", eigenda_blobs.len()); + // transform to rust-kzg-bn254 inputs types + // TODO should make library do the parsing the return result + let lib_blobs: Vec = eigenda_blobs; + let lib_commitments: Vec = commitments + .iter() + .map(|c| { + let a: [u8; 32] = c.0.to_be_bytes(); + let b: [u8; 32] = c.1.to_be_bytes(); + let x = Fq::from_be_bytes_mod_order(&a); + let y = Fq::from_be_bytes_mod_order(&b); + G1Affine::new(x, y) + }) + .collect(); + let lib_proofs: Vec = proofs + .iter() + .map(|p| { + let x = Fq::from_be_bytes_mod_order(&p[..32]); + let y = Fq::from_be_bytes_mod_order(&p[32..64]); + + G1Affine::new(x, y) + }) + .collect(); + + // convert all the error to false + batch::verify_blob_kzg_proof_batch(&lib_blobs, &lib_commitments, &lib_proofs).unwrap_or(false) +} diff --git a/justfile b/justfile index c245655..66a95ad 100644 --- a/justfile +++ b/justfile @@ -107,4 +107,4 @@ action-tests test_name='Test_ProgramAction' *args='': # Clean the action tests directory clean-actions: - rm -rf monorepo/ \ No newline at end of file + rm -rf monorepo/