diff --git a/.github/workflows/plonky2x.yml b/.github/workflows/plonky2x.yml index 6694a0107..31cb29027 100644 --- a/.github/workflows/plonky2x.yml +++ b/.github/workflows/plonky2x.yml @@ -12,7 +12,7 @@ on: branches: - "**" -jobs: +jobs: test: name: CI Test Suite runs-on: buildjet-32vcpu-ubuntu-2204 @@ -31,22 +31,22 @@ jobs: ~/.cargo/git/db/ target/ ~/.rustup/ - key: test-rust-nightly-2023-08-24-${{ hashFiles('**/Cargo.toml') }} - restore-keys: rust-nightly-2023-08-24- + key: test-rust-nightly-2024-01-25-${{ hashFiles('**/Cargo.toml') }} + restore-keys: rust-nightly-2024-01-25- - name: Install nightly toolchain id: rustc-toolchain uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: nightly-2023-08-24 + toolchain: nightly-2024-01-25 override: true - name: Run cargo test uses: actions-rs/cargo@v1 with: command: test - args: --release --features "ci" + args: --release --features "ci" env: RUST_LOG: 1 RUST_BACKTRACE: 1 @@ -58,7 +58,7 @@ jobs: steps: - name: Checkout sources uses: actions/checkout@v2 - + - name: rust-cache uses: buildjet/cache@v3 with: @@ -69,15 +69,15 @@ jobs: ~/.cargo/git/db/ target/ ~/.rustup/ - key: clippy-rust-nightly-2023-08-24-${{ hashFiles('**/Cargo.toml') }} - restore-keys: rust-nightly-2023-08-24- + key: clippy-rust-nightly-2024-01-25-${{ hashFiles('**/Cargo.toml') }} + restore-keys: rust-nightly-2024-01-25- - name: Install nightly toolchain id: rustc-toolchain uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: nightly-2023-08-24 + toolchain: nightly-2024-01-25 override: true components: rustfmt, clippy @@ -95,4 +95,4 @@ jobs: command: clippy args: --all-features --all-targets -- -D warnings -A incomplete-features env: - CARGO_INCREMENTAL: 1 \ No newline at end of file + CARGO_INCREMENTAL: 1 diff --git a/Cargo.lock b/Cargo.lock index 19de32bd0..b2115475f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -147,9 +147,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.5" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" +checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" dependencies = [ "anstyle", "anstyle-parse", @@ -161,9 +161,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anstyle-parse" @@ -379,14 +379,13 @@ dependencies = [ [[package]] name = "auto_impl" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +checksum = "823b8bb275161044e2ac7a25879cb3e2480cb403e3943022c7c769c599b756aa" dependencies = [ - "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] @@ -472,9 +471,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "bitvec" @@ -605,15 +604,15 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "9f13690e35a5e4ace198e7beea2895d29f3a9cc55015fcebe6336bd2010af9eb" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", "serde", - "windows-targets 0.48.5", + "windows-targets 0.52.0", ] [[package]] @@ -628,9 +627,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.15" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c12ed66a79a555082f595f7eb980d08669de95009dd4b3d61168c573ebe38fc9" +checksum = "80c21025abd42669a92efc996ef13cfb2c5c627858421ea58d5c3b331a6c134f" dependencies = [ "clap_builder", "clap_derive", @@ -638,21 +637,21 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.15" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4645eab3431e5a8403a96bea02506a8b35d28cd0f0330977dd5d22f9c84f43" +checksum = "458bf1f341769dfcf849846f65dffdf9146daa56bcd2a47cb4e1de9915567c99" dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.11.0", ] [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" dependencies = [ "heck", "proc-macro2", @@ -662,9 +661,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "coins-bip32" @@ -726,9 +725,9 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "const-hex" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5104de16b218eddf8e34ffe2f86f74bfa4e61e95a1b89732fccf6325efd0557" +checksum = "18d59688ad0945eaf6b84cb44fedbe93484c81b48970e98f09db8a22832d7961" dependencies = [ "cfg-if", "cpufeatures", @@ -874,7 +873,7 @@ dependencies = [ [[package]] name = "curta" version = "0.1.0" -source = "git+https://github.com/succinctlabs/curta.git#ebbd97c0f4f91bfa792fa5746e1d3f5334316189" +source = "git+https://github.com/succinctlabs/curta.git#fd41b0fa761e8f57ebfb8475245d5d5a0b3eb225" dependencies = [ "anyhow", "bincode", @@ -893,9 +892,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.1.1" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +checksum = "f711ade317dd348950a9910f81c5947e3d8907ebd2b83f76203ff1807e6a2bc2" dependencies = [ "cfg-if", "cpufeatures", @@ -921,9 +920,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.3" +version = "0.20.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +checksum = "fc5d6b04b3fd0ba9926f945895de7d806260a2d7431ba82e7edaecb043c4c6b8" dependencies = [ "darling_core", "darling_macro", @@ -931,23 +930,23 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.3" +version = "0.20.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +checksum = "04e48a959bcd5c761246f5d090ebc2fbf7b9cd527a492b07a67510c108f1e7e3" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn 2.0.48", ] [[package]] name = "darling_macro" -version = "0.20.3" +version = "0.20.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +checksum = "1d1545d67a2149e1d93b7e5c7752dce5a7426eb5d1357ddcfd89336b94444f77" dependencies = [ "darling_core", "quote", @@ -1111,9 +1110,9 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ "curve25519-dalek", "ed25519", @@ -1200,9 +1199,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ "humantime", "is-terminal", @@ -1299,9 +1298,9 @@ dependencies = [ [[package]] name = "ethers" -version = "2.0.11" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5344eea9b20effb5efeaad29418215c4d27017639fd1f908260f59cbbd226e" +checksum = "6c7cd562832e2ff584fa844cd2f6e5d4f35bbe11b28c7c9b8df957b2e1d0c701" dependencies = [ "ethers-addressbook", "ethers-contract", @@ -1315,9 +1314,9 @@ dependencies = [ [[package]] name = "ethers-addressbook" -version = "2.0.12" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bf35eb7d2e2092ad41f584951e08ec7c077b142dba29c4f1b8f52d2efddc49c" +checksum = "35dc9a249c066d17e8947ff52a4116406163cf92c7f0763cb8c001760b26403f" dependencies = [ "ethers-core", "once_cell", @@ -1327,9 +1326,9 @@ dependencies = [ [[package]] name = "ethers-contract" -version = "2.0.11" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0111ead599d17a7bff6985fd5756f39ca7033edc79a31b23026a8d5d64fa95cd" +checksum = "43304317c7f776876e47f2f637859f6d0701c1ec7930a150f169d5fbe7d76f5a" dependencies = [ "const-hex", "ethers-contract-abigen", @@ -1346,9 +1345,9 @@ dependencies = [ [[package]] name = "ethers-contract-abigen" -version = "2.0.12" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbdfb952aafd385b31d316ed80d7b76215ce09743c172966d840e96924427e0c" +checksum = "f9f96502317bf34f6d71a3e3d270defaa9485d754d789e15a8e04a84161c95eb" dependencies = [ "Inflector", "const-hex", @@ -1370,9 +1369,9 @@ dependencies = [ [[package]] name = "ethers-contract-derive" -version = "2.0.12" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7465c814a2ecd0de0442160da13584205d1cdc08f4717a6511cad455bd5d7dc4" +checksum = "452ff6b0a64507ce8d67ffd48b1da3b42f03680dcf5382244e9c93822cbbf5de" dependencies = [ "Inflector", "const-hex", @@ -1386,9 +1385,9 @@ dependencies = [ [[package]] name = "ethers-core" -version = "2.0.12" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "918b1a9ba585ea61022647def2f27c29ba19f6d2a4a4c8f68a9ae97fd5769737" +checksum = "aab3cef6cc1c9fd7f787043c81ad3052eff2b96a3878ef1526aa446311bdbfc9" dependencies = [ "arrayvec", "bytes", @@ -1416,9 +1415,9 @@ dependencies = [ [[package]] name = "ethers-etherscan" -version = "2.0.12" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "facabf8551b4d1a3c08cb935e7fca187804b6c2525cc0dafb8e5a6dd453a24de" +checksum = "16d45b981f5fa769e1d0343ebc2a44cfa88c9bc312eb681b676318b40cef6fb1" dependencies = [ "chrono", "ethers-core", @@ -1432,9 +1431,9 @@ dependencies = [ [[package]] name = "ethers-middleware" -version = "2.0.11" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "681ece6eb1d10f7cf4f873059a77c04ff1de4f35c63dd7bccde8f438374fcb93" +checksum = "145211f34342487ef83a597c1e69f0d3e01512217a7c72cc8a25931854c7dca0" dependencies = [ "async-trait", "auto_impl", @@ -1459,9 +1458,9 @@ dependencies = [ [[package]] name = "ethers-providers" -version = "2.0.11" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25d6c0c9455d93d4990c06e049abf9b30daf148cf461ee939c11d88907c60816" +checksum = "fb6b15393996e3b8a78ef1332d6483c11d839042c17be58decc92fa8b1c3508a" dependencies = [ "async-trait", "auto_impl", @@ -1496,9 +1495,9 @@ dependencies = [ [[package]] name = "ethers-signers" -version = "2.0.11" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb1b714e227bbd2d8c53528adb580b203009728b17d0d0e4119353aa9bc5532" +checksum = "b3b125a103b56aef008af5d5fb48191984aa326b50bfd2557d231dc499833de3" dependencies = [ "async-trait", "coins-bip32", @@ -1515,9 +1514,9 @@ dependencies = [ [[package]] name = "ethers-solc" -version = "2.0.12" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2e46e3ec8ef0c986145901fa9864205dc4dcee701f9846be2d56112d34bdea" +checksum = "d21df08582e0a43005018a858cc9b465c5fff9cf4056651be64f844e57d1f55f" dependencies = [ "cfg-if", "const-hex", @@ -1547,9 +1546,9 @@ dependencies = [ [[package]] name = "eyre" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" dependencies = [ "indenter", "once_cell", @@ -1603,9 +1602,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.5" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" +checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" [[package]] name = "fixed-hash" @@ -1869,9 +1868,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.23" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b553656127a00601c8ae5590fcfdc118e4083a7924b6cf4ffc1ea4b99dc429d7" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" dependencies = [ "bytes", "fnv", @@ -1879,7 +1878,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.1.0", + "indexmap 2.2.2", "slab", "tokio", "tokio-util", @@ -1929,9 +1928,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "d0c62115964e08cb8039170eb33c1d0e2388a256930279edca206fff675f82c3" [[package]] name = "hex" @@ -2059,9 +2058,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.59" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -2153,9 +2152,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.1.0" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520" dependencies = [ "equivalent", "hashbrown 0.14.3", @@ -2192,7 +2191,7 @@ version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi 0.3.5", "rustix", "windows-sys 0.52.0", ] @@ -2223,18 +2222,18 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.66" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" dependencies = [ "wasm-bindgen", ] @@ -2269,9 +2268,9 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ "cpufeatures", ] @@ -2322,9 +2321,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.152" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libm" @@ -2338,16 +2337,16 @@ version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "libc", "redox_syscall", ] [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" @@ -2389,9 +2388,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", ] @@ -2470,29 +2469,34 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" dependencies = [ "num-traits", "rand", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-iter" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" dependencies = [ "autocfg", "num-integer", @@ -2513,9 +2517,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", "libm", @@ -2527,7 +2531,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi 0.3.5", "libc", ] @@ -2546,7 +2550,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" dependencies = [ - "proc-macro-crate 3.0.0", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 2.0.48", @@ -2594,11 +2598,11 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.62" +version = "0.10.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" +checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "cfg-if", "foreign-types", "libc", @@ -2626,9 +2630,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.98" +version = "0.9.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" +checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" dependencies = [ "cc", "libc", @@ -2753,9 +2757,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.6" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" +checksum = "219c0dcc30b6a27553f9cc242972b67f75b60eb0db71f0b5462f38b058c41546" dependencies = [ "memchr", "thiserror", @@ -2769,7 +2773,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.1.0", + "indexmap 2.2.2", ] [[package]] @@ -2835,18 +2839,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" dependencies = [ "proc-macro2", "quote", @@ -2877,9 +2881,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" +checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" [[package]] name = "platforms" @@ -2890,7 +2894,7 @@ checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" [[package]] name = "plonky2" version = "0.1.4" -source = "git+https://github.com/mir-protocol/plonky2.git?rev=2d36559d#2d36559dad7adaff46631f31c7e6b24b80096eee" +source = "git+https://github.com/mir-protocol/plonky2.git?rev=d2598bd#d2598bded0cb24d36b0a9900e8ffd104c470831b" dependencies = [ "ahash", "anyhow", @@ -2901,7 +2905,7 @@ dependencies = [ "log", "num", "plonky2_field", - "plonky2_maybe_rayon 0.1.1 (git+https://github.com/mir-protocol/plonky2.git?rev=2d36559d)", + "plonky2_maybe_rayon 0.1.1 (git+https://github.com/mir-protocol/plonky2.git?rev=d2598bd)", "plonky2_util", "rand", "rand_chacha", @@ -2909,12 +2913,13 @@ dependencies = [ "serde_json", "static_assertions", "unroll", + "web-time", ] [[package]] name = "plonky2_field" version = "0.1.1" -source = "git+https://github.com/mir-protocol/plonky2.git?rev=2d36559d#2d36559dad7adaff46631f31c7e6b24b80096eee" +source = "git+https://github.com/mir-protocol/plonky2.git?rev=d2598bd#d2598bded0cb24d36b0a9900e8ffd104c470831b" dependencies = [ "anyhow", "itertools 0.11.0", @@ -2938,7 +2943,7 @@ dependencies = [ [[package]] name = "plonky2_maybe_rayon" version = "0.1.1" -source = "git+https://github.com/mir-protocol/plonky2.git?rev=2d36559d#2d36559dad7adaff46631f31c7e6b24b80096eee" +source = "git+https://github.com/mir-protocol/plonky2.git?rev=d2598bd#d2598bded0cb24d36b0a9900e8ffd104c470831b" dependencies = [ "rayon", ] @@ -2946,7 +2951,7 @@ dependencies = [ [[package]] name = "plonky2_util" version = "0.1.1" -source = "git+https://github.com/mir-protocol/plonky2.git?rev=2d36559d#2d36559dad7adaff46631f31c7e6b24b80096eee" +source = "git+https://github.com/mir-protocol/plonky2.git?rev=d2598bd#d2598bded0cb24d36b0a9900e8ffd104c470831b" [[package]] name = "plonky2x" @@ -2964,7 +2969,7 @@ dependencies = [ "digest 0.10.7", "dotenv", "ed25519-dalek", - "env_logger 0.10.1", + "env_logger 0.10.2", "ethers", "ff", "futures", @@ -2986,7 +2991,7 @@ dependencies = [ "sha256", "tokio", "tracing", - "uuid 1.6.1", + "uuid 1.7.0", ] [[package]] @@ -3071,11 +3076,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b2685dd208a3771337d8d386a89840f0f43cd68be8dae90a5f8c2384effc9cd" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ - "toml_edit 0.21.0", + "toml_edit 0.21.1", ] [[package]] @@ -3104,9 +3109,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -3119,7 +3124,7 @@ checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.4.1", + "bitflags 2.4.2", "lazy_static", "num-traits", "rand", @@ -3193,9 +3198,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" dependencies = [ "either", "rayon-core", @@ -3203,9 +3208,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -3233,9 +3238,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", @@ -3245,9 +3250,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" dependencies = [ "aho-corasick", "memchr", @@ -3268,9 +3273,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" -version = "0.11.23" +version = "0.11.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" dependencies = [ "base64 0.21.7", "bytes", @@ -3296,6 +3301,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", "system-configuration", "tokio", "tokio-native-tls", @@ -3441,11 +3447,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.28" +version = "0.38.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "errno", "libc", "linux-raw-sys", @@ -3497,7 +3503,7 @@ dependencies = [ "alloy-sol-types", "clap", "dotenv", - "env_logger 0.10.1", + "env_logger 0.10.2", "ethers", "hex", "log", @@ -3683,18 +3689,18 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.195" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", @@ -3703,9 +3709,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.111" +version = "1.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" dependencies = [ "itoa", "ryu", @@ -3744,15 +3750,15 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.4.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" +checksum = "1b0ed1662c5a68664f45b76d18deb0e234aff37207086803165c961eb695e981" dependencies = [ "base64 0.21.7", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.1.0", + "indexmap 2.2.2", "serde", "serde_json", "serde_with_macros", @@ -3761,9 +3767,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.4.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" +checksum = "568577ff0ef47b879f736cd66740e022f3672788cdf002a05a4e609ea5a6fb15" dependencies = [ "darling", "proc-macro2", @@ -3864,9 +3870,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.2" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "socket2" @@ -3939,6 +3945,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" + [[package]] name = "strum" version = "0.25.0" @@ -3989,14 +4001,14 @@ dependencies = [ "serde", "serde_json", "toml", - "uuid 1.6.1", + "uuid 1.7.0", ] [[package]] name = "svm-rs" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20689c7d03b6461b502d0b95d6c24874c7d24dea2688af80486a130a06af3b07" +checksum = "11297baafe5fa0c99d5722458eac6a5e25c01eb1b8e5cd137f54079093daa7a4" dependencies = [ "dirs", "fs2", @@ -4046,6 +4058,12 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "system-configuration" version = "0.5.1" @@ -4075,13 +4093,12 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.9.0" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", "rustix", "windows-sys 0.52.0", ] @@ -4128,12 +4145,13 @@ dependencies = [ [[package]] name = "time" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", @@ -4148,10 +4166,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" dependencies = [ + "num-conv", "time-core", ] @@ -4181,9 +4200,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.1" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ "backtrace", "bytes", @@ -4260,14 +4279,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" +checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.21.0", + "toml_edit 0.22.4", ] [[package]] @@ -4285,7 +4304,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.2", "toml_datetime", "winnow", ] @@ -4296,18 +4315,29 @@ version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.2", "toml_datetime", "winnow", ] [[package]] name = "toml_edit" -version = "0.21.0" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap 2.2.2", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +checksum = "0c9ffdf896f8daaabf9b66ba8e77ea1ed5ed0f72821b398aba62352e95062951" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.2", "serde", "serde_spanned", "toml_datetime", @@ -4419,9 +4449,9 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-bidi" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -4501,9 +4531,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" dependencies = [ "getrandom", "serde", @@ -4563,9 +4593,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -4573,9 +4603,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" dependencies = [ "bumpalo", "log", @@ -4588,9 +4618,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.39" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" dependencies = [ "cfg-if", "js-sys", @@ -4600,9 +4630,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4610,9 +4640,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" dependencies = [ "proc-macro2", "quote", @@ -4623,15 +4653,25 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" [[package]] name = "web-sys" -version = "0.3.66" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ee269d72cc29bf77a2c4bc689cc750fb39f5cbd493d2205bbb3f5c7779cf7b0" dependencies = [ "js-sys", "wasm-bindgen", @@ -4639,9 +4679,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.3" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "winapi" @@ -4817,9 +4857,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.5.34" +version = "0.5.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" +checksum = "5389a154b01683d28c77f8f68f49dea75f0a4da32557a58f68ee51ebba472d29" dependencies = [ "memchr", ] diff --git a/plonky2x/core/Cargo.toml b/plonky2x/core/Cargo.toml index f55fb48a6..8ede57997 100644 --- a/plonky2x/core/Cargo.toml +++ b/plonky2x/core/Cargo.toml @@ -13,13 +13,13 @@ timing = ["plonky2/timing"] ci = [] [dependencies] -plonky2 = { git = "https://github.com/mir-protocol/plonky2.git", default-features = false, rev = "2d36559d" } +plonky2 = { git = "https://github.com/mir-protocol/plonky2.git", default-features = false, rev = "d2598bd" } curta = { git = "https://github.com/succinctlabs/curta.git" } plonky2x-derive = { path = "../derive" } num = { version = "0.4", default-features = false } sha2 = "0.10.7" -curve25519-dalek = "4.1.1" +curve25519-dalek = "=4.0.0" ff = { package = "ff", version = "0.13", features = ["derive"] } ethers = { version = "2.0" } hex = "0.4.3" @@ -51,7 +51,7 @@ digest = "0.10.7" sha256 = "1.4.0" [dev-dependencies] -plonky2 = { git = "https://github.com/mir-protocol/plonky2.git", rev = "2d36559d", features = [ +plonky2 = { git = "https://github.com/mir-protocol/plonky2.git", rev = "d2598bd", features = [ "gate_testing", ] } env_logger = "0.10.0" diff --git a/plonky2x/core/src/backend/circuit/serialization/hints.rs b/plonky2x/core/src/backend/circuit/serialization/hints.rs index a40aac316..d303ce85a 100644 --- a/plonky2x/core/src/backend/circuit/serialization/hints.rs +++ b/plonky2x/core/src/backend/circuit/serialization/hints.rs @@ -52,7 +52,6 @@ use crate::frontend::eth::beacon::vars::{ BeaconBalancesVariable, BeaconHeaderVariable, BeaconValidatorVariable, BeaconValidatorsVariable, BeaconWithdrawalVariable, BeaconWithdrawalsVariable, }; -use crate::frontend::eth::mpt::generators::LteGenerator; use crate::frontend::eth::storage::generators::{ EthBlockGenerator, EthLogGenerator, EthStorageKeyGenerator, EthStorageProofHint, }; @@ -368,9 +367,6 @@ where let comparison_generator_id = ComparisonGenerator::::id(); r.register_simple::>(comparison_generator_id); - let le_generator_id = LteGenerator::::id(); - r.register_simple::>(le_generator_id); - r.register_hint::(); r.register_async_hint::(); diff --git a/plonky2x/core/src/frontend/curta/builder.rs b/plonky2x/core/src/frontend/curta/builder.rs index 00a1df9f7..e87bdd097 100644 --- a/plonky2x/core/src/frontend/curta/builder.rs +++ b/plonky2x/core/src/frontend/curta/builder.rs @@ -90,7 +90,7 @@ mod tests { const NUM_ARITHMETIC_COLUMNS: usize = 0; const NUM_FREE_COLUMNS: usize = 18; - const EXTENDED_COLUMNS: usize = 24; + const EXTENDED_COLUMNS: usize = 36; } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/plonky2x/core/src/frontend/curta/proof.rs b/plonky2x/core/src/frontend/curta/proof.rs index 1d131375e..b88da17c9 100644 --- a/plonky2x/core/src/frontend/curta/proof.rs +++ b/plonky2x/core/src/frontend/curta/proof.rs @@ -929,7 +929,7 @@ mod tests { let hint = ProofReadHint { proof }; let output_stream = builder.hint(input_stream, hint); let proof_variable = output_stream.read_stark_proof(&mut builder, &stark, &config); - let public_input_variable = output_stream.read_exact_unsafe(&mut builder, 3); + let public_input_variable = output_stream.read_exact(&mut builder, 3); builder.verify_stark_proof( &config, diff --git a/plonky2x/core/src/frontend/ecc/curve25519/curta/accelerator.rs b/plonky2x/core/src/frontend/ecc/curve25519/curta/accelerator.rs index 17b0829ef..5b298ea58 100644 --- a/plonky2x/core/src/frontend/ecc/curve25519/curta/accelerator.rs +++ b/plonky2x/core/src/frontend/ecc/curve25519/curta/accelerator.rs @@ -1,9 +1,8 @@ -use super::request::EcOpRequest; +use super::request::{EcOpRequest, EcOpResponse}; use super::Curve; -use crate::frontend::curta::ec::point::AffinePointVariable; #[derive(Debug, Clone)] pub struct EcOpAccelerator { pub ec_op_requests: Vec>, - pub ec_op_responses: Vec>>, + pub ec_op_responses: Vec>, } diff --git a/plonky2x/core/src/frontend/ecc/curve25519/curta/builder.rs b/plonky2x/core/src/frontend/ecc/curve25519/curta/builder.rs index 5c1acbfe6..be880ff34 100644 --- a/plonky2x/core/src/frontend/ecc/curve25519/curta/builder.rs +++ b/plonky2x/core/src/frontend/ecc/curve25519/curta/builder.rs @@ -1,10 +1,13 @@ +use curta::chip::ec::EllipticCurveParameters; + use super::accelerator::EcOpAccelerator; use super::proof_hint::EcOpProofHint; -use super::request::EcOpRequest; +use super::request::{EcOpRequest, EcOpResponse}; use super::result_hint::EcOpResultHint; use super::stark::{Ed25519OpVariable, Ed25519Stark}; use super::Curve; use crate::frontend::curta::ec::point::AffinePointVariable; +use crate::frontend::curta::field::variable::FieldVariable; use crate::frontend::hint::synchronous::Async; use crate::prelude::{CircuitBuilder, PlonkParameters, VariableStream}; @@ -39,17 +42,23 @@ impl, const D: usize> CircuitBuilder { let output_stream = self.hint(input_stream, result_hint); - match &request { - EcOpRequest::Add(_, _) - | EcOpRequest::ScalarMul(_, _) - | EcOpRequest::Decompress(_) => { - let result = output_stream.read::>(self); - self.assert_is_equal( - result, - response.clone().expect("response should not be None"), - ); + match response { + EcOpResponse::Add(c) => { + let c_hint = output_stream.read_unsafe::>(self); + self.assert_is_equal(c_hint, c.clone()); + } + EcOpResponse::ScalarMul(c) => { + let c_hint = output_stream.read_unsafe::>(self); + self.assert_is_equal(c_hint, c.clone()); } - EcOpRequest::IsValid(_) => {} + EcOpResponse::Decompress(point, root) => { + let point_hint = output_stream.read_unsafe::>(self); + let root_hint = output_stream + .read::::BaseField>>(self); + self.assert_is_equal(point_hint, point.clone()); + self.assert_is_equal(root_hint, root.clone()); + } + EcOpResponse::IsValid => {} } } @@ -63,22 +72,16 @@ impl, const D: usize> CircuitBuilder { .zip(accelerator.ec_op_responses.iter()) { requests.push(request.req_type()); - match &request { - EcOpRequest::Add(a, b) => { - let response = response.as_ref().unwrap(); - input_stream.write(&**a); - input_stream.write(&**b); - input_stream.write(response); - ec_ops.push(Ed25519OpVariable::Add( - *a.clone(), - *b.clone(), - response.clone(), - )) + match (request, response) { + (EcOpRequest::Add(a, b), EcOpResponse::Add(c)) => { + input_stream.write(a.as_ref()); + input_stream.write(b.as_ref()); + input_stream.write(c); + ec_ops.push(Ed25519OpVariable::Add(*a.clone(), *b.clone(), c.clone())) } - EcOpRequest::ScalarMul(scalar, point) => { - let response = response.as_ref().unwrap(); - input_stream.write(&**scalar); - input_stream.write(&**point); + (EcOpRequest::ScalarMul(scalar, point), EcOpResponse::ScalarMul(response)) => { + input_stream.write(scalar.as_ref()); + input_stream.write(point.as_ref()); input_stream.write(response); ec_ops.push(Ed25519OpVariable::ScalarMul( *scalar.clone(), @@ -86,19 +89,23 @@ impl, const D: usize> CircuitBuilder { response.clone(), )) } - EcOpRequest::Decompress(compressed_point) => { - let point = response.as_ref().unwrap(); - input_stream.write(&**compressed_point); + ( + EcOpRequest::Decompress(compressed_point), + EcOpResponse::Decompress(point, root), + ) => { + input_stream.write(compressed_point.as_ref()); input_stream.write(point); ec_ops.push(Ed25519OpVariable::Decompress( compressed_point.clone(), point.clone(), + root.clone(), )) } - EcOpRequest::IsValid(point) => { - input_stream.write(&**point); + (EcOpRequest::IsValid(point), EcOpResponse::IsValid) => { + input_stream.write(point.as_ref()); ec_ops.push(Ed25519OpVariable::IsValid(*point.clone())) } + _ => panic!("invalid request/response pair"), } } diff --git a/plonky2x/core/src/frontend/ecc/curve25519/curta/request.rs b/plonky2x/core/src/frontend/ecc/curve25519/curta/request.rs index 074eda812..821255ec3 100644 --- a/plonky2x/core/src/frontend/ecc/curve25519/curta/request.rs +++ b/plonky2x/core/src/frontend/ecc/curve25519/curta/request.rs @@ -2,6 +2,7 @@ use curta::chip::ec::EllipticCurve; use serde::{Deserialize, Serialize}; use crate::frontend::curta::ec::point::{AffinePointVariable, CompressedEdwardsYVariable}; +use crate::frontend::curta::field::variable::FieldVariable; use crate::prelude::U256Variable; #[derive(Clone, Debug, Copy, Serialize, Deserialize)] @@ -25,6 +26,14 @@ pub enum EcOpRequest { IsValid(Box>), } +#[derive(Debug, Clone)] +pub enum EcOpResponse { + Add(AffinePointVariable), + ScalarMul(AffinePointVariable), + Decompress(AffinePointVariable, FieldVariable), + IsValid, +} + impl EcOpRequest { /// Returns the type of the request. pub const fn req_type(&self) -> EcOpRequestType { diff --git a/plonky2x/core/src/frontend/ecc/curve25519/curta/result_hint.rs b/plonky2x/core/src/frontend/ecc/curve25519/curta/result_hint.rs index 6df452bcd..efb9b3a76 100644 --- a/plonky2x/core/src/frontend/ecc/curve25519/curta/result_hint.rs +++ b/plonky2x/core/src/frontend/ecc/curve25519/curta/result_hint.rs @@ -1,11 +1,12 @@ use curta::chip::ec::edwards::ed25519::decompress::decompress; -use curta::chip::ec::point::AffinePoint; +use curta::chip::ec::EllipticCurveParameters; use num_bigint::BigUint; use serde::{Deserialize, Serialize}; use super::request::EcOpRequestType; use super::Curve; use crate::frontend::curta::ec::point::{AffinePointVariable, CompressedEdwardsYVariable}; +use crate::frontend::curta::field::variable::FieldVariable; use crate::frontend::hint::simple::hint::Hint; use crate::frontend::uint::Uint; use crate::prelude::{PlonkParameters, U256Variable, ValueStream}; @@ -18,12 +19,11 @@ pub struct EcOpResultHint { impl, const D: usize> Hint for EcOpResultHint { fn hint(&self, input_stream: &mut ValueStream, output_stream: &mut ValueStream) { - let mut result: Option> = None; match &self.ec_op { EcOpRequestType::Add => { let a = input_stream.read_value::>(); let b = input_stream.read_value::>(); - result = Some(a + b); + output_stream.write_value::>(a + b); } EcOpRequestType::ScalarMul => { let scalar = BigUint::new( @@ -33,18 +33,19 @@ impl, const D: usize> Hint for EcOpResultHint { .to_vec(), ); let point = input_stream.read_value::>(); - result = Some(point * scalar); + output_stream.write_value::>(point * scalar); } EcOpRequestType::Decompress => { let compressed_point = input_stream.read_value::(); - result = Some(decompress(&compressed_point)); + let (point, root) = decompress(&compressed_point); + output_stream.write_value::>(point); + output_stream + .write_value::::BaseField>>( + root, + ); } EcOpRequestType::IsValid => {} } - - if let Some(return_val) = result { - output_stream.write_value::>(return_val); - } } } diff --git a/plonky2x/core/src/frontend/ecc/curve25519/curta/stark.rs b/plonky2x/core/src/frontend/ecc/curve25519/curta/stark.rs index c466ccbbb..c5d0688a1 100644 --- a/plonky2x/core/src/frontend/ecc/curve25519/curta/stark.rs +++ b/plonky2x/core/src/frontend/ecc/curve25519/curta/stark.rs @@ -1,10 +1,13 @@ use curta::chip::builder::AirBuilder; use curta::chip::ec::edwards::ed25519::gadget::{CompressedPointAirWriter, CompressedPointGadget}; use curta::chip::ec::edwards::ed25519::instruction::Ed25519FpInstruction; +use curta::chip::ec::edwards::ed25519::params::Ed25519BaseField; use curta::chip::ec::edwards::ed25519::point::CompressedPointRegister; use curta::chip::ec::gadget::EllipticCurveAirWriter; use curta::chip::ec::point::{AffinePoint, AffinePointRegister}; use curta::chip::ec::scalar::ECScalarRegister; +use curta::chip::ec::EllipticCurveParameters; +use curta::chip::field::register::FieldRegister; use curta::chip::register::Register; use curta::chip::trace::writer::data::AirWriterData; use curta::chip::trace::writer::AirWriter; @@ -42,7 +45,11 @@ pub enum Ed25519CurtaOp { AffinePointRegister, AffinePointRegister, ), - Decompress(CompressedPointRegister, AffinePointRegister), + Decompress( + CompressedPointRegister, + AffinePointRegister, + FieldRegister, + ), IsValid(AffinePointRegister), } @@ -57,7 +64,11 @@ pub enum Ed25519OpVariable { AffinePointVariable, AffinePointVariable, ), - Decompress(Box, AffinePointVariable), + Decompress( + Box, + AffinePointVariable, + FieldVariable, + ), IsValid(AffinePointVariable), } @@ -148,7 +159,7 @@ impl, const D: usize> Ed25519Stark { panic!("invalid input"); } } - Ed25519CurtaOp::Decompress(compressed_point, _) => { + Ed25519CurtaOp::Decompress(compressed_point, _, _) => { if let Ed25519CurtaOpValue::Decompress(compressed_point_val, _) = &op_value { writer.write_ec_compressed_point(compressed_point, compressed_point_val); } else { @@ -236,8 +247,8 @@ impl, const D: usize> Ed25519Stark { Self::assert_point_equal(builder, result, result_var, public_inputs); } ( - Ed25519CurtaOp::Decompress(compressed_point, result), - Ed25519OpVariable::Decompress(compressed_point_var, result_var), + Ed25519CurtaOp::Decompress(compressed_point, result, pos_sqrt), + Ed25519OpVariable::Decompress(compressed_point_var, result_var, pos_sqrt_var), ) => { Self::assert_compressed_point_equal( builder, @@ -246,6 +257,12 @@ impl, const D: usize> Ed25519Stark { public_inputs, ); Self::assert_point_equal(builder, result, result_var, public_inputs); + Self::assert_field_element_equal( + builder, + pos_sqrt, + pos_sqrt_var, + public_inputs, + ); } (Ed25519CurtaOp::IsValid(point), Ed25519OpVariable::IsValid(point_var)) => { Self::assert_point_equal(builder, point, point_var, public_inputs); @@ -305,18 +322,26 @@ impl, const D: usize> Ed25519Stark { } } + fn assert_field_element_equal( + builder: &mut CircuitBuilder, + element: &FieldRegister<::BaseField>, + element_var: &FieldVariable<::BaseField>, + public_inputs: &[Variable], + ) { + let element = FieldVariable::from_variables_unsafe( + element.read_from_slice(public_inputs).coefficients(), + ); + builder.assert_is_equal(element, element_var.clone()); + } + fn assert_point_equal( builder: &mut CircuitBuilder, a: &AffinePointRegister, a_var: &AffinePointVariable, public_inputs: &[Variable], ) { - let a_x = - FieldVariable::from_variables_unsafe(a.x.read_from_slice(public_inputs).coefficients()); - builder.assert_is_equal(a_x, a_var.x.clone()); - let a_y = - FieldVariable::from_variables_unsafe(a.y.read_from_slice(public_inputs).coefficients()); - builder.assert_is_equal(a_y, a_var.y.clone()); + Self::assert_field_element_equal(builder, &a.x, &a_var.x, public_inputs); + Self::assert_field_element_equal(builder, &a.y, &a_var.y, public_inputs); } pub fn read_proof_with_public_input( @@ -351,8 +376,8 @@ impl Ed25519CurtaOp { } EcOpRequestType::Decompress => { let compressed_point = builder.alloc_public_ec_compressed_point(); - let result = builder.ed25519_decompress(&compressed_point); - Self::Decompress(compressed_point, result) + let (result, pos_square_root) = builder.ed25519_decompress(&compressed_point); + Self::Decompress(compressed_point, result, pos_square_root) } EcOpRequestType::IsValid => { let point = builder.alloc_public_ec_point(); diff --git a/plonky2x/core/src/frontend/ecc/curve25519/ec_ops.rs b/plonky2x/core/src/frontend/ecc/curve25519/ec_ops.rs index 97168c49e..d61c486bc 100644 --- a/plonky2x/core/src/frontend/ecc/curve25519/ec_ops.rs +++ b/plonky2x/core/src/frontend/ecc/curve25519/ec_ops.rs @@ -1,8 +1,10 @@ use curta::chip::ec::edwards::ed25519::params::Ed25519; +use curta::chip::ec::EllipticCurveParameters; use super::curta::accelerator::EcOpAccelerator; -use super::curta::request::{EcOpRequest, EcOpRequestType}; +use super::curta::request::{EcOpRequest, EcOpRequestType, EcOpResponse}; use crate::frontend::curta::ec::point::{AffinePointVariable, CompressedEdwardsYVariable}; +use crate::frontend::curta::field::variable::FieldVariable; use crate::prelude::{CircuitBuilder, PlonkParameters, U256Variable}; impl, const D: usize> CircuitBuilder { @@ -13,7 +15,10 @@ impl, const D: usize> CircuitBuilder { b: AffinePointVariable, ) -> AffinePointVariable { let request = EcOpRequest::Add(Box::new(a), Box::new(b)); - self.add_ec_25519_ops_request(request).unwrap() + match self.add_ec_25519_ops_request(request) { + EcOpResponse::Add(result) => result, + _ => unreachable!("response should be of type Add"), + } } /// Multiply a point on the curve by a scalar. @@ -23,7 +28,10 @@ impl, const D: usize> CircuitBuilder { point: AffinePointVariable, ) -> AffinePointVariable { let request = EcOpRequest::ScalarMul(Box::new(scalar), Box::new(point)); - self.add_ec_25519_ops_request(request).unwrap() + match self.add_ec_25519_ops_request(request) { + EcOpResponse::ScalarMul(result) => result, + _ => unreachable!("response should be of type ScalarMul"), + } } /// Decompress a compressed point. @@ -32,20 +40,23 @@ impl, const D: usize> CircuitBuilder { compressed_point: CompressedEdwardsYVariable, ) -> AffinePointVariable { let request = EcOpRequest::Decompress(Box::new(compressed_point)); - self.add_ec_25519_ops_request(request).unwrap() + match self.add_ec_25519_ops_request(request) { + EcOpResponse::Decompress(point, _) => point, + _ => unreachable!("response should be of type Decompress"), + } } /// Check if a point is valid. pub fn curta_25519_is_valid(&mut self, point: AffinePointVariable) { let request = EcOpRequest::IsValid(Box::new(point)); - self.add_ec_25519_ops_request(request); + match self.add_ec_25519_ops_request(request) { + EcOpResponse::IsValid => {} + _ => unreachable!("response should be of type IsValid"), + } } /// Add an EC operation request to the accelerator. - fn add_ec_25519_ops_request( - &mut self, - request: EcOpRequest, - ) -> Option> { + fn add_ec_25519_ops_request(&mut self, request: EcOpRequest) -> EcOpResponse { if self.ec_25519_ops_accelerator.is_none() { self.ec_25519_ops_accelerator = Some(EcOpAccelerator { ec_op_requests: Vec::new(), @@ -53,13 +64,17 @@ impl, const D: usize> CircuitBuilder { }); } - let mut result: Option> = None; - match &request.req_type() { - EcOpRequestType::Add | EcOpRequestType::ScalarMul | EcOpRequestType::Decompress => { - result = Some(self.init_unsafe::>()); + let response = match request.req_type() { + EcOpRequestType::Add => EcOpResponse::Add(self.init::>()), + EcOpRequestType::ScalarMul => { + EcOpResponse::ScalarMul(self.init::>()) } - EcOpRequestType::IsValid => {} - } + EcOpRequestType::Decompress => EcOpResponse::Decompress( + self.init::>(), + self.init::::BaseField>>(), + ), + EcOpRequestType::IsValid => EcOpResponse::IsValid, + }; let accelerator = self .ec_25519_ops_accelerator @@ -67,8 +82,8 @@ impl, const D: usize> CircuitBuilder { .expect("sha256 accelerator should exist"); accelerator.ec_op_requests.push(request); - accelerator.ec_op_responses.push(result.clone()); + accelerator.ec_op_responses.push(response.clone()); - result + response } } diff --git a/plonky2x/core/src/frontend/ecc/curve25519/ed25519/eddsa.rs b/plonky2x/core/src/frontend/ecc/curve25519/ed25519/eddsa.rs index 92410b58b..573d1ec38 100644 --- a/plonky2x/core/src/frontend/ecc/curve25519/ed25519/eddsa.rs +++ b/plonky2x/core/src/frontend/ecc/curve25519/ed25519/eddsa.rs @@ -126,7 +126,7 @@ impl, const D: usize> CircuitBuilder { self.curta_eddsa_verify_sigs(msg_array, Some(msg_len_vec), sig_array, pub_key_array); } - /// This function will verify a set of eddsa signatures. If message_byte_lengths is None, then + /// This function will verify a set of eddsa signatures. If message_byte_lengths is None, then /// all the messages should have the length of MAX_MSG_LENGTH_BYTES. pub fn curta_eddsa_verify_sigs< // Maximum length of a signed message in bytes. @@ -154,6 +154,9 @@ impl, const D: usize> CircuitBuilder { let scalar_modulus_value = U512::from_little_endian(&Ed25519ScalarField::modulus().to_bytes_le()); let scalar_modulus = self.constant::(scalar_modulus_value); + let scalar_mod_256_value = + U256::from_little_endian(&Ed25519ScalarField::modulus().to_bytes_le()); + let scalar_mod_256 = self.constant::(scalar_mod_256_value); for i in 0..NUM_SIGS { // Create a new BytesVariable that will contain the message to be hashed. @@ -183,7 +186,12 @@ impl, const D: usize> CircuitBuilder { limbs: array![i => h_scalar_512_limbs[i]; 8], }; - let p1 = self.curta_25519_scalar_mul(signatures[i].s, generator_var.clone()); + let s = signatures[i].s; + // Assert that s is less than the scalar modulus. + let s_lt_scalar_mod = self.lt(s, scalar_mod_256); + let true_val = self.constant::(true); + self.assert_is_equal(s_lt_scalar_mod, true_val); + let p1 = self.curta_25519_scalar_mul(s, generator_var.clone()); let pubkey_affine = self.curta_25519_decompress(pubkeys[i].clone()); self.curta_25519_is_valid(pubkey_affine.clone()); let mut p2 = self.curta_25519_scalar_mul(h_scalar, pubkey_affine); diff --git a/plonky2x/core/src/frontend/eth/mpt/builder.rs b/plonky2x/core/src/frontend/eth/mpt/builder.rs index a61f50836..df409f7d4 100644 --- a/plonky2x/core/src/frontend/eth/mpt/builder.rs +++ b/plonky2x/core/src/frontend/eth/mpt/builder.rs @@ -1,11 +1,9 @@ -use std::marker::PhantomData; - use curta::math::field::Field; -use super::generators::*; use crate::frontend::vars::Nibbles; use crate::prelude::{ - ArrayVariable, ByteVariable, Bytes32Variable, CircuitBuilder, PlonkParameters, Variable, + ArrayVariable, ByteVariable, Bytes32Variable, CircuitBuilder, CircuitVariable, PlonkParameters, + U32Variable, Variable, }; pub fn transform_proof_to_padded( @@ -42,27 +40,6 @@ pub fn transform_proof_to_padded, const D: usize> CircuitBuilder { - pub fn byte_to_variable(&mut self, lhs: ByteVariable) -> Variable { - let generator: ByteToVariableGenerator = ByteToVariableGenerator { - lhs, - output: self.init::(), - _phantom: PhantomData, - }; - self.add_simple_generator(generator.clone()); - generator.output - } - - pub fn sub_byte(&mut self, lhs: ByteVariable, rhs: ByteVariable) -> ByteVariable { - let generator: ByteSubGenerator = ByteSubGenerator { - lhs, - rhs, - output: self.init::(), - _phantom: PhantomData, - }; - self.add_simple_generator(generator.clone()); - generator.output - } - const PREFIX_EXTENSION_EVEN: u8 = 0; const PREFIX_EXTENSION_ODD: u8 = 1; const PREFIX_LEAF_EVEN: u8 = 2; @@ -73,7 +50,7 @@ impl, const D: usize> CircuitBuilder { &mut self, key: Bytes32Variable, proof: ArrayVariable, PROOF_LEN>, - len_nodes: ArrayVariable, + len_nodes: ArrayVariable, root: Bytes32Variable, value: Bytes32Variable, ) { @@ -91,8 +68,8 @@ impl, const D: usize> CircuitBuilder { let one: Variable = self.one::(); let two = self.constant::(L::Field::from_canonical_u8(2)); let const_64 = self.constant::(L::Field::from_canonical_u8(64)); - let const_32 = self.constant::(L::Field::from_canonical_u8(32)); - let const_128 = self.constant::(128); + let const_32 = self.constant::(32u32); + let const_128 = self.constant::(128u32); let mut current_key_idx = self.zero::(); let mut finished = self._false(); @@ -102,17 +79,14 @@ impl, const D: usize> CircuitBuilder { padded_root.push(self.constant::(0)); } let mut current_node_id = ArrayVariable::::new(padded_root); - let hash_key = self.keccak256(&key.as_bytes()); - let key_path: ArrayVariable = hash_key - .as_bytes() - .to_vec() - .to_nibbles(self) - .try_into() - .unwrap(); + let hash_key = self.keccak256_witness(&key.as_bytes()); + let key_path: ArrayVariable = + hash_key.as_bytes().to_vec().to_nibbles(self).into(); for i in 0..PROOF_LEN { let current_node = proof[i].clone(); - let current_node_hash = self.keccak256_variable(current_node.as_slice(), len_nodes[i]); + let current_node_hash = + self.keccak256_variable_witness(current_node.as_slice(), len_nodes[i].variable); if i == 0 { self.assert_is_equal(current_node_hash, root); @@ -125,7 +99,7 @@ impl, const D: usize> CircuitBuilder { current_node_hash, current_node_id.as_slice()[0..32].into(), ); - let node_len_le_32 = self.lte(len_nodes[i], const_32); + let node_len_le_32 = self.lt(len_nodes[i], const_32); let case_len_le_32 = self.and(node_len_le_32, first_32_bytes_eq); let inter = self.not(node_len_le_32); let case_len_gt_32 = self.and(inter, hash_eq); @@ -138,7 +112,7 @@ impl, const D: usize> CircuitBuilder { let (decoded_list, decoded_element_lens, len_decoded_list) = self .decode_element_as_list::( current_node, - len_nodes[i], + len_nodes[i].variable, finished, ); @@ -156,7 +130,7 @@ impl, const D: usize> CircuitBuilder { let offset_odd = self.mul(prefix_extension_odd.variable, one); let offset = self.add(offset_even, offset_odd); let branch_key = self.select_array(key_path.clone().as_slice(), current_key_idx); - let branch_key_variable: Variable = self.byte_to_variable(branch_key); // can be unsafe since nibbles are checked + let branch_key_variable = branch_key.to_variable(self); // Case 1 let is_branch_and_key_terminated = self.and(is_branch, key_terminated); @@ -209,37 +183,36 @@ impl, const D: usize> CircuitBuilder { finished = self.or(finished, m); } - let current_node_len = self.sub_byte(current_node_id[0], const_128); - let current_node_len_as_var = self.byte_to_variable(current_node_len); - let lhs_offset = self.sub(const_32, current_node_len_as_var); + // Can be unsafe because `current_node_id` comes from a ByteVariable. + let current_node_id_u32 = + U32Variable::from_variables_unsafe(&[current_node_id[0].to_variable(self)]); + let current_node_len = self.sub(current_node_id_u32, const_128); + let lhs_offset = self.sub(const_32, current_node_len); self.assert_subarray_equal( &value.as_bytes(), - lhs_offset, + lhs_offset.variable, current_node_id.as_slice(), one, - current_node_len_as_var, + current_node_len.variable, ); } } #[cfg(test)] mod tests { - use curta::math::field::Field; use log::debug; use super::super::utils::{read_fixture, EIP1186ProofResponse}; use super::*; use crate::frontend::eth::utils::u256_to_h256_be; - use crate::prelude::{DefaultBuilder, GoldilocksField}; + use crate::prelude::DefaultBuilder; use crate::utils; #[test] #[cfg_attr(feature = "ci", ignore)] fn test_mpt_circuit() { utils::setup_logger(); - type F = GoldilocksField; - let storage_result: EIP1186ProofResponse = read_fixture("./src/frontend/eth/mpt/fixtures/example.json"); @@ -262,16 +235,16 @@ mod tests { let (proof_as_fixed, lengths_as_fixed) = transform_proof_to_padded::(storage_proof); - let len_nodes_field_elements = lengths_as_fixed + let len_nodes_value = lengths_as_fixed .iter() - .map(|x| F::from_canonical_usize(*x)) - .collect::>(); + .map(|x| *x as u32) + .collect::>(); let mut builder = DefaultBuilder::new(); let key_variable = builder.read::(); let proof_variable = builder.read::, PROOF_LEN>>(); - let len_nodes = builder.read::>(); + let len_nodes = builder.read::>(); let root_variable = builder.read::(); let value_variable = builder.read::(); builder.verify_mpt_proof::( @@ -288,7 +261,7 @@ mod tests { input.write::, PROOF_LEN>>( proof_as_fixed, ); - input.write::>(len_nodes_field_elements); + input.write::>(len_nodes_value); input.write::(root); input.write::(value_as_h256); diff --git a/plonky2x/core/src/frontend/eth/mpt/generators.rs b/plonky2x/core/src/frontend/eth/mpt/generators.rs index 79efb75b4..7295daba0 100644 --- a/plonky2x/core/src/frontend/eth/mpt/generators.rs +++ b/plonky2x/core/src/frontend/eth/mpt/generators.rs @@ -1,81 +1,12 @@ use core::marker::PhantomData; -use curta::math::field::Field; use plonky2::field::types::PrimeField64; use plonky2::iop::generator::{GeneratedValues, SimpleGenerator}; use plonky2::iop::witness::PartitionWitness; use plonky2::plonk::circuit_data::CommonCircuitData; -use plonky2::util::serialization::{Buffer, IoResult, Read, Write}; +use plonky2::util::serialization::{Buffer, IoResult}; -use crate::prelude::{ - BoolVariable, ByteVariable, CircuitVariable, PlonkParameters, Target, Variable, -}; - -#[derive(Debug, Clone)] -pub struct LteGenerator, const D: usize> { - pub lhs: Variable, - pub rhs: Variable, - pub output: BoolVariable, - pub _phantom: PhantomData, -} - -impl, const D: usize> LteGenerator { - pub fn id() -> String { - "LeGenerator".to_string() - } -} - -// TODO: add LeGenerator to macro -impl, const D: usize> SimpleGenerator for LteGenerator { - fn id(&self) -> String { - Self::id() - } - - fn dependencies(&self) -> Vec { - let mut targets: Vec = Vec::new(); - targets.extend(self.lhs.targets()); - targets.extend(self.rhs.targets()); - targets - } - - fn run_once( - &self, - witness: &PartitionWitness, - out_buffer: &mut GeneratedValues, - ) { - let lhs = self.lhs.get(witness).to_canonical_u64() as usize; - let rhs = self.rhs.get(witness).to_canonical_u64() as usize; - self.output.set(out_buffer, lhs <= rhs); - } - - #[allow(unused_variables)] - fn serialize( - &self, - dst: &mut Vec, - common_data: &CommonCircuitData, - ) -> IoResult<()> { - dst.write_target_vec(&self.lhs.targets())?; - dst.write_target_vec(&self.rhs.targets())?; - dst.write_target_vec(&self.output.targets())?; - Ok(()) - } - - #[allow(unused_variables)] - fn deserialize( - src: &mut Buffer, - common_data: &CommonCircuitData, - ) -> IoResult { - let lhs = src.read_target_vec()?; - let rhs = src.read_target_vec()?; - let output = src.read_target_vec()?; - Ok(Self { - lhs: Variable::from_targets(&lhs), - rhs: Variable::from_targets(&rhs), - output: BoolVariable::from_targets(&output), - _phantom: PhantomData, - }) - } -} +use crate::prelude::{ByteVariable, CircuitVariable, PlonkParameters, Target, Variable}; #[derive(Debug, Clone)] pub struct SubarrayEqualGenerator, const D: usize> { @@ -139,101 +70,3 @@ impl, const D: usize> SimpleGenerator todo!() } } - -#[derive(Debug, Clone)] -pub struct ByteSubGenerator, const D: usize> { - pub lhs: ByteVariable, - pub rhs: ByteVariable, - pub output: ByteVariable, - pub _phantom: PhantomData, -} - -impl, const D: usize> SimpleGenerator - for ByteSubGenerator -{ - fn id(&self) -> String { - "ByteToVariableGenerator".to_string() - } - - fn dependencies(&self) -> Vec { - let mut targets: Vec = Vec::new(); - targets.extend(self.lhs.targets()); - targets.extend(self.rhs.targets()); - targets - } - - fn run_once( - &self, - witness: &PartitionWitness, - out_buffer: &mut GeneratedValues, - ) { - let lhs = self.lhs.get(witness); - let rhs = self.rhs.get(witness); - self.output.set(out_buffer, lhs - rhs); - } - - #[allow(unused_variables)] - fn serialize( - &self, - dst: &mut Vec, - common_data: &CommonCircuitData, - ) -> IoResult<()> { - todo!() - } - - #[allow(unused_variables)] - fn deserialize( - src: &mut Buffer, - common_data: &CommonCircuitData, - ) -> IoResult { - todo!() - } -} - -#[derive(Debug, Clone)] -pub struct ByteToVariableGenerator, const D: usize> { - pub lhs: ByteVariable, - pub output: Variable, - pub _phantom: PhantomData, -} - -impl, const D: usize> SimpleGenerator - for ByteToVariableGenerator -{ - fn id(&self) -> String { - "ByteToVariableGenerator".to_string() - } - - fn dependencies(&self) -> Vec { - let mut targets: Vec = Vec::new(); - targets.extend(self.lhs.targets()); - targets - } - - fn run_once( - &self, - witness: &PartitionWitness, - out_buffer: &mut GeneratedValues, - ) { - let lhs = self.lhs.get(witness); - self.output - .set(out_buffer, L::Field::from_canonical_u8(lhs)); - } - - #[allow(unused_variables)] - fn serialize( - &self, - dst: &mut Vec, - common_data: &CommonCircuitData, - ) -> IoResult<()> { - todo!() - } - - #[allow(unused_variables)] - fn deserialize( - src: &mut Buffer, - common_data: &CommonCircuitData, - ) -> IoResult { - todo!() - } -} diff --git a/plonky2x/core/src/frontend/eth/mpt/rlc.rs b/plonky2x/core/src/frontend/eth/mpt/rlc.rs index 4e3f650c4..2d86347f2 100644 --- a/plonky2x/core/src/frontend/eth/mpt/rlc.rs +++ b/plonky2x/core/src/frontend/eth/mpt/rlc.rs @@ -35,7 +35,7 @@ impl, const D: usize> CircuitBuilder { b_offset: Variable, len: Variable, ) { - // TODO: implement + // TODO: Need to constrain generator result. let generator: SubarrayEqualGenerator = SubarrayEqualGenerator { a: a.to_vec(), a_offset, diff --git a/plonky2x/core/src/frontend/eth/storage/builder.rs b/plonky2x/core/src/frontend/eth/storage/builder.rs index e7ec991c9..3e15472e2 100644 --- a/plonky2x/core/src/frontend/eth/storage/builder.rs +++ b/plonky2x/core/src/frontend/eth/storage/builder.rs @@ -11,7 +11,7 @@ use crate::frontend::uint::uint256::U256Variable; use crate::frontend::vars::{Bytes32Variable, VariableStream}; impl, const D: usize> CircuitBuilder { - pub fn get_storage_key_at( + pub fn get_storage_key_at_witness( &mut self, mapping_location: U256Variable, map_key: Bytes32Variable, @@ -22,8 +22,7 @@ impl, const D: usize> CircuitBuilder { value } - #[allow(non_snake_case)] - pub fn eth_get_storage_at( + pub fn eth_get_storage_at_witness( &mut self, block_hash: Bytes32Variable, address: AddressVariable, @@ -40,15 +39,16 @@ impl, const D: usize> CircuitBuilder { output_stream.read::(self) } - #[allow(non_snake_case)] - pub fn eth_get_block_by_hash(&mut self, block_hash: Bytes32Variable) -> EthHeaderVariable { + pub fn eth_get_block_by_hash_witness( + &mut self, + block_hash: Bytes32Variable, + ) -> EthHeaderVariable { let generator = EthBlockGenerator::new(self, block_hash); let value = generator.value; self.add_simple_generator(generator); value } - #[allow(non_snake_case)] pub fn eth_get_account( &mut self, _address: Address, @@ -57,8 +57,7 @@ impl, const D: usize> CircuitBuilder { todo!() } - #[allow(non_snake_case)] - pub fn eth_get_transaction_log( + pub fn eth_get_transaction_log_witness( &mut self, transaction_hash: Bytes32Variable, block_hash: Bytes32Variable, @@ -92,7 +91,7 @@ mod tests { #[test] #[cfg_attr(feature = "ci", ignore)] #[allow(non_snake_case)] - fn test_eth_get_storage_at() { + fn test_eth_get_storage_at_witness() { utils::setup_logger(); dotenv::dotenv().ok(); let rpc_url = env::var("RPC_1").unwrap(); @@ -104,7 +103,7 @@ mod tests { let block_hash = builder.evm_read::(); let address = builder.evm_read::(); let location = builder.evm_read::(); - let value = builder.eth_get_storage_at(block_hash, address, location); + let value = builder.eth_get_storage_at_witness(block_hash, address, location); builder.evm_write(value); // Build your circuit. @@ -160,7 +159,7 @@ mod tests { #[test] #[cfg_attr(feature = "ci", ignore)] #[allow(non_snake_case)] - fn test_many_eth_get_storage_at() { + fn test_many_eth_get_storage_at_witness() { utils::setup_logger(); dotenv::dotenv().ok(); let rpc_url = env::var("RPC_1").unwrap(); @@ -176,7 +175,7 @@ mod tests { let block_hash = builder.evm_read::(); let address = builder.evm_read::(); let location = builder.evm_read::(); - let value = builder.eth_get_storage_at(block_hash, address, location); + let value = builder.eth_get_storage_at_witness(block_hash, address, location); builder.evm_write(value); } @@ -229,7 +228,7 @@ mod tests { let mapping_location = builder.read::(); let map_key = builder.read::(); - let value = builder.get_storage_key_at(mapping_location, map_key); + let value = builder.get_storage_key_at_witness(mapping_location, map_key); builder.write(value); // Build your circuit. @@ -278,7 +277,7 @@ mod tests { #[test] #[cfg_attr(feature = "ci", ignore)] #[allow(non_snake_case)] - fn test_eth_get_block_by_hash() { + fn test_eth_get_block_by_hash_witness() { utils::setup_logger(); dotenv::dotenv().ok(); let rpc_url = env::var("RPC_1").unwrap(); @@ -289,7 +288,7 @@ mod tests { builder.set_execution_client(provider); let block_hash = builder.read::(); - let value = builder.eth_get_block_by_hash(block_hash); + let value = builder.eth_get_block_by_hash_witness(block_hash); builder.write(value); // Build your circuit. @@ -352,7 +351,7 @@ mod tests { #[test] #[cfg_attr(feature = "ci", ignore)] #[allow(non_snake_case)] - fn test_eth_get_transaction_log() { + fn test_eth_get_transaction_log_witness() { utils::setup_logger(); dotenv::dotenv().ok(); let rpc_url = env::var("RPC_1").unwrap(); @@ -365,7 +364,8 @@ mod tests { let block_hash = builder.read::(); let log_index = 0u64; - let value = builder.eth_get_transaction_log(transaction_hash, block_hash, log_index); + let value = + builder.eth_get_transaction_log_witness(transaction_hash, block_hash, log_index); builder.write::(value); // Build your circuit. diff --git a/plonky2x/core/src/frontend/hash/blake2/curta.rs b/plonky2x/core/src/frontend/hash/blake2/curta.rs index 8fd8690b2..434f49128 100644 --- a/plonky2x/core/src/frontend/hash/blake2/curta.rs +++ b/plonky2x/core/src/frontend/hash/blake2/curta.rs @@ -31,8 +31,8 @@ impl, const D: usize> AirParameters for BLAKE2BAirParamete type Instruction = UintInstruction; - const NUM_FREE_COLUMNS: usize = 1527; - const EXTENDED_COLUMNS: usize = 708; + const NUM_FREE_COLUMNS: usize = 1271; + const EXTENDED_COLUMNS: usize = 1476; } impl, const D: usize> Hash for BLAKE2B { @@ -175,7 +175,7 @@ impl, const D: usize> CircuitBuilder { }); } - let digest = self.init_unsafe::(); + let digest = self.init::(); let digest_array = BLAKE2B::digest_to_array(self, digest); let accelerator = self .blake2b_accelerator @@ -194,6 +194,11 @@ impl, const D: usize> CircuitBuilder { input: &[ByteVariable], length: U32Variable, ) -> Bytes32Variable { + // Check that length <= input.len(). This is needed to ensure that users cannot + // prove the hash of a longer message than they supplied. + let supplied_input_length = self.constant::(input.len() as u32); + self.lte(length, supplied_input_length); + let last_chunk = self.compute_blake2b_last_chunk_index(length); if self.blake2b_accelerator.is_none() { self.blake2b_accelerator = Some(BLAKE2BAccelerator { @@ -202,7 +207,7 @@ impl, const D: usize> CircuitBuilder { }); } - let digest = self.init_unsafe::(); + let digest = self.init::(); let digest_array = BLAKE2B::digest_to_array(self, digest); let accelerator = self diff --git a/plonky2x/core/src/frontend/hash/curta/stark.rs b/plonky2x/core/src/frontend/hash/curta/stark.rs index ccd118bdb..849e8dbd3 100644 --- a/plonky2x/core/src/frontend/hash/curta/stark.rs +++ b/plonky2x/core/src/frontend/hash/curta/stark.rs @@ -17,7 +17,7 @@ use plonky2::util::timing::TimingTree; use super::data::{HashInputData, HashInputDataValues}; use super::Hash; use crate::frontend::curta::proof::ByteStarkProofVariable; -use crate::prelude::{CircuitBuilder, PlonkParameters, Variable}; +use crate::prelude::{CircuitBuilder, CircuitVariable, PlonkParameters, U32Variable, Variable}; #[derive(Debug, Clone)] pub struct HashStark< @@ -190,5 +190,28 @@ where builder.assert_is_equal(*int, var); } } + + // Connect t values + if HAS_T_VALUES { + for (t_value, register) in hash_input + .t_values + .unwrap() + .iter() + .zip_eq(self.t_values.as_ref().unwrap().iter()) + { + let value = register.read_from_slice(public_inputs); + + let mut acc = builder.zero::(); + for (i, byte) in value.into_iter().enumerate() { + let two_i = + builder.constant::(L::Field::from_canonical_u32(1 << (8 * i))); + let two_i_byte = builder.mul(two_i, byte); + acc = builder.add(acc, two_i_byte); + } + let variable = U32Variable::from_variables_unsafe(&[acc]); + + builder.assert_is_equal(*t_value, variable); + } + } } } diff --git a/plonky2x/core/src/frontend/hash/keccak/mod.rs b/plonky2x/core/src/frontend/hash/keccak/mod.rs index b7b9cf656..ee1867ebb 100644 --- a/plonky2x/core/src/frontend/hash/keccak/mod.rs +++ b/plonky2x/core/src/frontend/hash/keccak/mod.rs @@ -11,7 +11,8 @@ pub mod keccak256; impl, const D: usize> CircuitBuilder { /// WARNING: DO NOT USE IN PRODUCTION, this is unconstrained! - pub fn keccak256(&mut self, bytes: &[ByteVariable]) -> Bytes32Variable { + pub fn keccak256_witness(&mut self, bytes: &[ByteVariable]) -> Bytes32Variable { + // TODO: Need to constrain generator result let generator: Keccak256Generator = Keccak256Generator { input: bytes.to_vec(), output: self.init(), @@ -23,11 +24,13 @@ impl, const D: usize> CircuitBuilder { output } - pub fn keccak256_variable( + /// WARNING: DO NOT USE IN PRODUCTION, this is unconstrained! + pub fn keccak256_variable_witness( &mut self, bytes: &[ByteVariable], length: Variable, ) -> Bytes32Variable { + // TODO: Need to constrain generator result let generator = Keccak256Generator { input: bytes.to_vec(), output: self.init(), @@ -58,7 +61,7 @@ mod tests { let word = builder.constant::(bytes32!( "0x0000000000000000000000000000000000000000000000000000000000000000" )); - let hash = builder.keccak256(&word.0 .0); + let hash = builder.keccak256_witness(&word.0 .0); builder.watch(&hash, "hi"); let circuit = builder.build(); diff --git a/plonky2x/core/src/frontend/hash/sha/sha256/curta.rs b/plonky2x/core/src/frontend/hash/sha/sha256/curta.rs index d4a0c3ec4..43b07f910 100644 --- a/plonky2x/core/src/frontend/hash/sha/sha256/curta.rs +++ b/plonky2x/core/src/frontend/hash/sha/sha256/curta.rs @@ -29,8 +29,8 @@ impl, const D: usize> AirParameters for SHA256AirParameter type Instruction = UintInstruction; - const NUM_FREE_COLUMNS: usize = 605; - const EXTENDED_COLUMNS: usize = 351; + const NUM_FREE_COLUMNS: usize = 418; + const EXTENDED_COLUMNS: usize = 912; } impl, const D: usize> Hash for SHA256 { @@ -57,7 +57,7 @@ impl, const D: usize> Hash for SHA256 input: &[ByteVariable], length: U32Variable, ) -> Vec { - let padded_bytes = builder.pad_message_sha256_variable(input, length); + let padded_bytes = builder.pad_sha256_variable_length(input, length); padded_bytes .chunks_exact(4) @@ -124,7 +124,7 @@ impl, const D: usize> CircuitBuilder { }); } - let digest = self.init_unsafe::(); + let digest = self.init::(); let digest_array = SHA256::digest_to_array(self, digest); let accelerator = self .sha256_accelerator @@ -143,11 +143,19 @@ impl, const D: usize> CircuitBuilder { input: &[ByteVariable], length: U32Variable, ) -> Bytes32Variable { - assert_eq!( - input.len() % 64, - 0, - "input length should be a multiple of 64" - ); + // Check that length <= input.len(). This is needed to ensure that users cannot prove the + // hash of a longer message than they supplied. + let supplied_input_length = self.constant::(input.len() as u32); + self.lte(length, supplied_input_length); + // Extend input's length to the nearest multiple of 64 (if it is not already). + let mut input = input.to_vec(); + if (input.len() % 64) != 0 { + input.resize( + input.len() + 64 - (input.len() % 64), + self.constant::(0), + ); + } + let last_chunk = self.compute_sha256_last_chunk(length); if self.sha256_accelerator.is_none() { self.sha256_accelerator = Some(SHA256Accelerator { @@ -156,7 +164,7 @@ impl, const D: usize> CircuitBuilder { }); } - let digest = self.init_unsafe::(); + let digest = self.init::(); let digest_array = SHA256::digest_to_array(self, digest); let accelerator = self .sha256_accelerator diff --git a/plonky2x/core/src/frontend/hash/sha/sha256/mod.rs b/plonky2x/core/src/frontend/hash/sha/sha256/mod.rs index 8ebc70a44..46cffa560 100644 --- a/plonky2x/core/src/frontend/hash/sha/sha256/mod.rs +++ b/plonky2x/core/src/frontend/hash/sha/sha256/mod.rs @@ -161,7 +161,6 @@ mod tests { use super::*; use crate::prelude::{ByteVariable, CircuitBuilder, DefaultParameters, U32Variable}; use crate::utils::hash::sha256; - use crate::utils::setup_logger; type L = DefaultParameters; const D: usize = 2; @@ -169,8 +168,6 @@ mod tests { #[test] #[cfg_attr(feature = "ci", ignore)] fn test_sha256_padding() { - setup_logger(); - let mut builder = CircuitBuilder::::new(); let max_len = 1024; @@ -209,8 +206,6 @@ mod tests { #[test] #[cfg_attr(feature = "ci", ignore)] fn test_sha256_variable_padding() { - setup_logger(); - let mut builder = CircuitBuilder::::new(); let max_number_of_chunks = 5; @@ -239,7 +234,7 @@ mod tests { .map(|b| builder.constant::(*b)) .collect::>(); - let padding = builder.pad_message_sha256_variable(&message, length); + let padding = builder.pad_sha256_variable_length(&message, length); for (value, expected) in padding.iter().zip(expected_padding.iter()) { builder.assert_is_equal(*value, *expected); diff --git a/plonky2x/core/src/frontend/hash/sha/sha256/pad.rs b/plonky2x/core/src/frontend/hash/sha/sha256/pad.rs index 00c23e810..6cb66ea09 100644 --- a/plonky2x/core/src/frontend/hash/sha/sha256/pad.rs +++ b/plonky2x/core/src/frontend/hash/sha/sha256/pad.rs @@ -1,7 +1,14 @@ use array_macro::array; +use plonky2::util::ceil_div_usize; use crate::prelude::*; +pub const SHA256_CHUNK_SIZE_BYTES: usize = 64; +pub const SHA256_INPUT_LENGTH_BYTE_SIZE: usize = 8; + +pub const SHA256_CHUNK_SIZE_BITS: usize = SHA256_CHUNK_SIZE_BYTES * 8; +pub const SHA256_INPUT_LENGTH_BIT_SIZE: usize = SHA256_INPUT_LENGTH_BYTE_SIZE * 8; + impl, const D: usize> CircuitBuilder { /// Pad the given input according to the SHA-256 spec. /// The last chunk (each chunk is 64 bytes = 512 bits) gets padded. @@ -13,7 +20,8 @@ impl, const D: usize> CircuitBuilder { bits.push(self.api._true()); let l = bits.len() - 1; - let k = 512 - (l + 1 + 64) % 512; + let k = SHA256_CHUNK_SIZE_BITS + - (l + 1 + SHA256_INPUT_LENGTH_BIT_SIZE) % SHA256_CHUNK_SIZE_BITS; for _ in 0..k { bits.push(self.api._false()); } @@ -51,53 +59,66 @@ impl, const D: usize> CircuitBuilder { } /// Pad the given variable length input according to the SHA-256 spec. - /// - /// It is assumed that `input` has length MAX_NUM_CHUNKS * 64. - /// The true number of non-zero bytes in `input` is given by input_byte_length. - pub(crate) fn pad_message_sha256_variable( + /// input_byte_length gives the real length of the input in bytes. + pub(crate) fn pad_sha256_variable_length( &mut self, input: &[ByteVariable], input_byte_length: U32Variable, ) -> Vec { - let max_number_of_chunks = input.len() / 64; - assert_eq!( - max_number_of_chunks * 64, - input.len(), - "input length must be a multiple of 64 bytes" - ); + let true_t = self._true(); + let false_t = self._false(); + let last_chunk = self.compute_sha256_last_chunk(input_byte_length); + // Calculate the number of chunks needed to store the input. 9 bytes are added by the + // padding and LE length representation. + let max_num_chunks = ceil_div_usize( + input.len() + SHA256_INPUT_LENGTH_BYTE_SIZE + 1, + SHA256_CHUNK_SIZE_BYTES, + ); + + // Extend input to size max_num_chunks * 64 before padding. + let mut padded_input = input.to_vec(); + padded_input.resize(max_num_chunks * SHA256_CHUNK_SIZE_BYTES, self.zero()); + // Compute the length bytes (big-endian representation of the length in bits). let zero_byte = self.constant::(0x00); - let mut length_bytes = vec![zero_byte; 4]; let bits_per_byte = self.constant::(8); let input_bit_length = self.mul(input_byte_length, bits_per_byte); - let mut length_bits = self.to_le_bits(input_bit_length); + // Get the length bits in LE order, padded to 64 bits. + let mut length_bits = self + .api + .split_le(input_bit_length.variable.0, SHA256_INPUT_LENGTH_BIT_SIZE); + // Convert length to BE bits length_bits.reverse(); - // Prepend 4 zero bytes to length_bytes as abi.encodePacked(U32Variable) is 4 bytes. - length_bytes.extend_from_slice( - &length_bits - .chunks(8) - .map(|chunk| { - let bits = array![x => chunk[x]; 8]; - ByteVariable(bits) - }) - .collect::>(), - ); + let length_bytes = &length_bits + .chunks(8) + .map(|chunk| { + let bits = array![x => BoolVariable::from_targets(&[chunk[x].target]); 8]; + ByteVariable(bits) + }) + .collect::>(); let mut padded_bytes = Vec::new(); - let mut message_byte_selector = self.constant::(true); - for i in 0..max_number_of_chunks { - let chunk_offset = 64 * i; + // Set to true if the last chunk has been reached. This is used to verify that + // input_byte_length is <= input.len(). + let mut reached_last_chunk = false_t; + + let mut message_byte_selector = true_t; + for i in 0..max_num_chunks { + let chunk_offset = SHA256_CHUNK_SIZE_BYTES * i; let curr_chunk = self.constant::(i as u32); + // Check if this is the chunk where length should be added. let is_last_chunk = self.is_equal(curr_chunk, last_chunk); + reached_last_chunk = self.or(reached_last_chunk, is_last_chunk); - for j in 0..64 { + for j in 0..SHA256_CHUNK_SIZE_BYTES { + // First 64 - 8 bytes are either message | padding | nil bytes. let idx = chunk_offset + j; let idx_t = self.constant::(idx as u32); let is_last_msg_byte = self.is_equal(idx_t, input_byte_length); @@ -112,21 +133,26 @@ impl, const D: usize> CircuitBuilder { let padding_start_byte = self.constant::(0x80); // If message_byte_selector is true, select the message byte. - let mut byte = self.select(message_byte_selector, input[idx], zero_byte); + let mut byte = self.select(message_byte_selector, padded_input[idx], zero_byte); // If idx == length_bytes, select the padding start byte. byte = self.select(is_last_msg_byte, padding_start_byte, byte); - if j >= 64 - 8 { - // If in last chunk, select the length byte. - byte = self.select(is_last_chunk, length_bytes[j % 8], byte); + + if j >= SHA256_CHUNK_SIZE_BYTES - SHA256_INPUT_LENGTH_BYTE_SIZE { + // If in last chunk, this is a length byte. + byte = self.select( + is_last_chunk, + length_bytes[j % SHA256_INPUT_LENGTH_BYTE_SIZE], + byte, + ); } padded_bytes.push(byte); } } + // These checks verify input_byte_length <= input.len(). + self.is_equal(message_byte_selector, false_t); + self.is_equal(reached_last_chunk, true_t); - // self.watch_slice(&padded_bytes, "padded bytes"); - - assert_eq!(padded_bytes.len(), max_number_of_chunks * 64); padded_bytes } } diff --git a/plonky2x/core/src/frontend/hash/sha/sha512/curta.rs b/plonky2x/core/src/frontend/hash/sha/sha512/curta.rs index 65612b9b3..a9fe7e8a2 100644 --- a/plonky2x/core/src/frontend/hash/sha/sha512/curta.rs +++ b/plonky2x/core/src/frontend/hash/sha/sha512/curta.rs @@ -29,8 +29,8 @@ impl, const D: usize> AirParameters for SHA512AirParameter type Instruction = UintInstruction; - const NUM_FREE_COLUMNS: usize = 1191; - const EXTENDED_COLUMNS: usize = 654; + const NUM_FREE_COLUMNS: usize = 815; + const EXTENDED_COLUMNS: usize = 1782; } impl, const D: usize> Hash for SHA512 { @@ -133,7 +133,7 @@ impl, const D: usize> CircuitBuilder { }); } - let digest = self.init_unsafe::>(); + let digest = self.init::>(); let digest_array = SHA512::digest_to_array(self, digest); let accelerator = self .sha512_accelerator @@ -152,6 +152,11 @@ impl, const D: usize> CircuitBuilder { input: &[ByteVariable], length: U32Variable, ) -> BytesVariable<64> { + // Check that length <= input.len(). This is needed to ensure that users cannot prove the + // hash of a longer message than they supplied. + let supplied_input_length = self.constant::(input.len() as u32); + self.lte(length, supplied_input_length); + let last_chunk = self.compute_sha512_last_chunk(length); if self.sha512_accelerator.is_none() { @@ -161,7 +166,7 @@ impl, const D: usize> CircuitBuilder { }); } - let digest = self.init_unsafe::>(); + let digest = self.init::>(); let digest_array = SHA512::digest_to_array(self, digest); let accelerator = self .sha512_accelerator @@ -178,14 +183,14 @@ impl, const D: usize> CircuitBuilder { #[cfg(test)] mod tests { + use std::env; + use rand::{thread_rng, Rng}; use crate::prelude::*; use crate::utils::hash::sha512; - use crate::utils::setup_logger; fn test_sha512_fixed(msg: &[u8], expected_digest: [u8; 64]) { - setup_logger(); let mut builder = DefaultBuilder::new(); let message = msg .iter() @@ -203,7 +208,6 @@ mod tests { } fn test_sha512_variable_length(message: &[u8], input_length: u32, expected_digest: [u8; 64]) { - setup_logger(); let mut builder = DefaultBuilder::new(); let input_length = builder.constant::(input_length); @@ -268,9 +272,14 @@ mod tests { test_sha512_variable_length(&msg, 0, expected_digest); } + // FAILED #[test] #[cfg_attr(feature = "ci", ignore)] fn test_sha512_curta_variable_large_message() { + env::set_var("RUST_LOG", "debug"); + env_logger::try_init().unwrap_or_default(); + dotenv::dotenv().ok(); + let mut msg : Vec = bytes!("35c323757c20640a294345c89c0bfcebe3d554fdb0c7b7a0bdb72222c531b1ecf7ec1c43f4de9d49556de87b86b26a98942cb078486fdb44de38b80864c3973153756363696e6374204c616273"); let len = msg.len() as u32; msg.resize(256, 1); @@ -279,9 +288,14 @@ mod tests { test_sha512_variable_length(&msg, len, expected_digest); } + // FAILED #[test] #[cfg_attr(feature = "ci", ignore)] fn test_sha512_curta_variable_short_message_same_slice() { + env::set_var("RUST_LOG", "debug"); + env_logger::try_init().unwrap_or_default(); + dotenv::dotenv().ok(); + let mut msg: Vec = b"plonky2".to_vec(); let len = msg.len() as u32; msg.resize(128, 1); @@ -290,9 +304,14 @@ mod tests { test_sha512_variable_length(&msg, len, expected_digest); } + // FAILED #[test] #[cfg_attr(feature = "ci", ignore)] fn test_sha512_curta_variable_short_message_different_slice() { + env::set_var("RUST_LOG", "debug"); + env_logger::try_init().unwrap_or_default(); + dotenv::dotenv().ok(); + let mut msg: Vec = b"plonky2".to_vec(); let len = msg.len() as u32; msg.resize(512, 1); @@ -304,7 +323,6 @@ mod tests { #[test] #[cfg_attr(feature = "ci", ignore)] fn test_sha512_fixed_length() { - setup_logger(); let mut builder = DefaultBuilder::new(); let max_len = 300; @@ -331,7 +349,6 @@ mod tests { #[test] #[cfg_attr(feature = "ci", ignore)] fn test_sha512_variable_length_random() { - setup_logger(); let mut builder = DefaultBuilder::new(); let max_number_of_chunks = 2; @@ -367,7 +384,6 @@ mod tests { fn test_sha512_variable_length_max_size() { // This test checks that sha512_variable_pad works as intended, especially when the max // input length is (length % 128 > 128 - 17). - setup_logger(); let mut builder = DefaultBuilder::new(); let max_number_of_chunks = 1; diff --git a/plonky2x/core/src/frontend/hash/sha/sha512/pad.rs b/plonky2x/core/src/frontend/hash/sha/sha512/pad.rs index c62f7d025..48eb45ae5 100644 --- a/plonky2x/core/src/frontend/hash/sha/sha512/pad.rs +++ b/plonky2x/core/src/frontend/hash/sha/sha512/pad.rs @@ -1,46 +1,43 @@ -use plonky2::iop::target::BoolTarget; +use array_macro::array; use plonky2::util::ceil_div_usize; use crate::prelude::*; -pub const SELECT_CHUNK_SIZE_64: usize = 64; -pub const LENGTH_BITS_128: usize = 128; -pub const SHA512_CHUNK_SIZE_BYTES_128: usize = 128; -pub const CHUNK_BITS_1024: usize = 1024; +pub const SHA512_CHUNK_SIZE_BYTES: usize = 128; +pub const SHA512_INPUT_LENGTH_BYTE_SIZE: usize = 16; + +pub const SHA512_CHUNK_SIZE_BITS: usize = SHA512_CHUNK_SIZE_BYTES * 8; +pub const SHA512_INPUT_LENGTH_BIT_SIZE: usize = SHA512_INPUT_LENGTH_BYTE_SIZE * 8; impl, const D: usize> CircuitBuilder { pub(crate) fn pad_message_sha512(&mut self, input: &[ByteVariable]) -> Vec { - let bits = input + let mut bits = input .iter() - .flat_map(|b| b.as_bool_targets().map(|x| x.target).to_vec()) + .flat_map(|b| b.as_bool_targets().to_vec()) .collect::>(); + bits.push(self.api._true()); - let mut bit_targets = Vec::new(); - bit_targets.extend_from_slice(&bits); - - // TODO: Range check size of msg_bit_len? - // Cast to u128 for bitmask - let msg_bit_len: u128 = bits.len().try_into().expect("message too long"); - - // minimum_padding = 1 + 128 (min 1 bit for the pad, and 128 bit for the msg size) - let msg_with_min_padding_len = msg_bit_len as usize + LENGTH_BITS_128 + 1; - - let additional_padding_len = CHUNK_BITS_1024 - (msg_with_min_padding_len % CHUNK_BITS_1024); - - bit_targets.push(self.api.constant_bool(true).target); - for _i in 0..additional_padding_len { - bit_targets.push(self.api.constant_bool(false).target); + let l = bits.len() - 1; + let k = SHA512_CHUNK_SIZE_BITS + - (l + 1 + SHA512_INPUT_LENGTH_BIT_SIZE) % SHA512_CHUNK_SIZE_BITS; + for _ in 0..k { + bits.push(self.api._false()); } - for i in (0..128).rev() { - let has_bit = (msg_bit_len & (1 << i)) != 0; - bit_targets.push(self.api.constant_bool(has_bit).target); - } + (l as u128) + .to_be_bytes() + .iter() + .map(|b| self.constant::(*b)) + .for_each(|b| { + bits.extend_from_slice(&b.as_bool_targets()); + }); + + let bit_targets = bits.iter().map(|b| b.target).collect::>(); // Combine the bits into ByteVariable (0..bit_targets.len() / 8) .map(|i| ByteVariable::from_targets(&bit_targets[i * 8..(i + 1) * 8])) - .collect::>() + .collect() } /// Calculates the last valid SHA512 chunk of an input_byte_length long message. @@ -65,95 +62,94 @@ impl, const D: usize> CircuitBuilder { input: &[ByteVariable], input_byte_length: U32Variable, ) -> Vec { + let true_t = self._true(); + let false_t = self._false(); + let last_chunk = self.compute_sha512_last_chunk(input_byte_length); - // Calculate the number of chunks needed to store the input. 17 is the number of bytes added - // by the padding and LE length representation. - let max_num_chunks = ceil_div_usize(input.len() + 17, SHA512_CHUNK_SIZE_BYTES_128); + // Calculate the number of chunks needed to store the input. 9 bytes are added by the + // padding and LE length representation. + let max_num_chunks = ceil_div_usize( + input.len() + SHA512_INPUT_LENGTH_BYTE_SIZE + 1, + SHA512_CHUNK_SIZE_BYTES, + ); // Extend input to size max_num_chunks * 128 before padding. let mut padded_input = input.to_vec(); - padded_input.resize(max_num_chunks * SHA512_CHUNK_SIZE_BYTES_128, self.zero()); - - let message = padded_input - .iter() - .flat_map(|b| b.as_bool_targets().to_vec()) - .collect::>(); + padded_input.resize(max_num_chunks * SHA512_CHUNK_SIZE_BYTES, self.zero()); - let mut msg_input = Vec::new(); + // Compute the length bytes (big-endian representation of the length in bits). + let zero_byte = self.constant::(0x00); - let eight = self.constant::(8); - let hash_msg_length_bits = self.mul(input_byte_length, eight).variable.0; + let bits_per_byte = self.constant::(8); + let input_bit_length = self.mul(input_byte_length, bits_per_byte); - let mut length_bits = self.api.split_le(hash_msg_length_bits, 128); + // Get the length bits in LE order, padded to 128 bits. + let mut length_bits = self + .api + .split_le(input_bit_length.variable.0, SHA512_INPUT_LENGTH_BIT_SIZE); // Convert length to BE bits length_bits.reverse(); - let last_chunk = last_chunk.variable.0; - let mut add_message_bit_selector = self.api.constant_bool(true); - for i in 0..max_num_chunks { - let chunk_offset = CHUNK_BITS_1024 * i; - let curr_chunk_t = self.api.constant(L::Field::from_canonical_usize(i)); - // Check if this is the chunk where length should be added - let add_length_bit_selector = self.api.is_equal(last_chunk, curr_chunk_t); - // Always message || padding || nil - for j in 0..CHUNK_BITS_1024 - LENGTH_BITS_128 { - let idx = chunk_offset + j; - - let idx_t = self.api.constant(L::Field::from_canonical_usize(idx)); - let idx_length_eq_t = self.api.is_equal(idx_t, hash_msg_length_bits); - - // select_bit AND NOT(idx_length_eq_t) - let not_idx_length_eq_t = self.api.not(idx_length_eq_t); - add_message_bit_selector = BoolTarget::new_unsafe(self.api.select( - add_message_bit_selector, - not_idx_length_eq_t.target, - add_message_bit_selector.target, - )); - - // Set bit to push: (select_bit && message[i]) || idx_length_eq_t - let bit_to_push = self.api.and(add_message_bit_selector, message[idx]); - let bit_to_push = self.api.or(idx_length_eq_t, bit_to_push); - msg_input.push(bit_to_push); - } - - // Message || padding || length || nil - for j in CHUNK_BITS_1024 - LENGTH_BITS_128..CHUNK_BITS_1024 { - let idx = chunk_offset + j; - - // Only true if in the last valid chunk - let length_bit = self - .api - .and(length_bits[j % LENGTH_BITS_128], add_length_bit_selector); - - // TODO: add_length_bit_selector && (add_message_bit_selector || length_bit) should never be true concurrently -> add constraint for this? + let length_bytes = &length_bits + .chunks(8) + .map(|chunk| { + let bits = array![x => BoolVariable::from_targets(&[chunk[x].target]); 8]; + ByteVariable(bits) + }) + .collect::>(); - let idx_t = self.api.constant(L::Field::from_canonical_usize(idx)); - let idx_length_eq_t = self.api.is_equal(idx_t, hash_msg_length_bits); + let mut padded_bytes = Vec::new(); - // select_bit AND NOT(idx_length_eq_t) - let not_idx_length_eq_t = self.api.not(idx_length_eq_t); - add_message_bit_selector = BoolTarget::new_unsafe(self.api.select( - add_message_bit_selector, - not_idx_length_eq_t.target, - add_message_bit_selector.target, - )); + // Set to true if the last chunk has been reached. This is used to verify that + // input_byte_length is <= input.len(). + let mut reached_last_chunk = false_t; - // Set bit to push: (select_bit && message[i]) || idx_length_eq_t - let bit_to_push = self.api.and(add_message_bit_selector, message[idx]); - let bit_to_push = self.api.or(idx_length_eq_t, bit_to_push); + let mut message_byte_selector = true_t; + for i in 0..max_num_chunks { + let chunk_offset = SHA512_CHUNK_SIZE_BYTES * i; + let curr_chunk = self.constant::(i as u32); - let bit_to_push = self.api.or(length_bit, bit_to_push); + // Check if this is the chunk where length should be added. + let is_last_chunk = self.is_equal(curr_chunk, last_chunk); + reached_last_chunk = self.or(reached_last_chunk, is_last_chunk); - // Either length bit || (message[i] || idx_length_eq_t) - msg_input.push(bit_to_push); + for j in 0..SHA512_CHUNK_SIZE_BYTES { + // First 128 - 16 bytes are either message | padding | nil bytes. + let idx = chunk_offset + j; + let idx_t = self.constant::(idx as u32); + let is_last_msg_byte = self.is_equal(idx_t, input_byte_length); + let not_last_msg_byte = self.not(is_last_msg_byte); + + message_byte_selector = self.select( + message_byte_selector, + not_last_msg_byte, + message_byte_selector, + ); + + let padding_start_byte = self.constant::(0x80); + + // If message_byte_selector is true, select the message byte. + let mut byte = self.select(message_byte_selector, padded_input[idx], zero_byte); + // If idx == length_bytes, select the padding start byte. + byte = self.select(is_last_msg_byte, padding_start_byte, byte); + + if j >= SHA512_CHUNK_SIZE_BYTES - SHA512_INPUT_LENGTH_BYTE_SIZE { + // If in last chunk, this is a length byte. + byte = self.select( + is_last_chunk, + length_bytes[j % SHA512_INPUT_LENGTH_BYTE_SIZE], + byte, + ); + } + + padded_bytes.push(byte); } } + // These checks verify input_byte_length <= input.len(). + self.is_equal(message_byte_selector, false_t); + self.is_equal(reached_last_chunk, true_t); - // Combine the bits into ByteVariable - let output_bits = msg_input.iter().map(|b| b.target).collect::>(); - (0..output_bits.len() / 8) - .map(|i| ByteVariable::from_targets(&output_bits[i * 8..(i + 1) * 8])) - .collect::>() + padded_bytes } } diff --git a/plonky2x/core/src/frontend/ops/math.rs b/plonky2x/core/src/frontend/ops/math.rs index c24fc6547..579e6d369 100644 --- a/plonky2x/core/src/frontend/ops/math.rs +++ b/plonky2x/core/src/frontend/ops/math.rs @@ -1,11 +1,8 @@ //! Arithmetic operations. -use std::marker::PhantomData; - use crate::backend::circuit::PlonkParameters; use crate::frontend::builder::CircuitBuilder; -use crate::frontend::eth::mpt::generators::LteGenerator; -use crate::prelude::{BoolVariable, Variable}; +use crate::prelude::BoolVariable; /// The addition operation. /// @@ -171,19 +168,16 @@ impl, const D: usize> CircuitBuilder { /// The less than operation (<). pub fn lt(&mut self, lhs: Lhs, rhs: Rhs) -> BoolVariable where - Lhs: LessThanOrEqual, - Rhs: Sub + One, + Rhs: LessThanOrEqual, { - let one = self.one::(); - let upper_bound = rhs.sub(one, self); - self.lte(lhs, upper_bound) + let lte = rhs.lte(lhs, self); + self.not(lte) } /// The greater than operation (>). pub fn gt(&mut self, lhs: Lhs, rhs: Rhs) -> BoolVariable where - Lhs: Sub + One, - Rhs: LessThanOrEqual, + Lhs: LessThanOrEqual, { self.lt(rhs, lhs) } @@ -191,7 +185,6 @@ impl, const D: usize> CircuitBuilder { /// The greater than or equal to operation (>=). pub fn gte(&mut self, lhs: Lhs, rhs: Rhs) -> BoolVariable where - Lhs: Sub + One, Rhs: LessThanOrEqual, { self.lte(rhs, lhs) @@ -208,24 +201,68 @@ impl, const D: usize> CircuitBuilder { } } -impl, const D: usize> LessThanOrEqual for Variable { - fn lte(self, rhs: Variable, builder: &mut CircuitBuilder) -> BoolVariable { - // TODO: FIX - let generator: LteGenerator = LteGenerator { - lhs: self, - rhs, - output: builder.init::(), - _phantom: PhantomData, - }; - builder.add_simple_generator(generator.clone()); - generator.output - } -} - mod tests { #[allow(unused_imports)] use crate::prelude::{BoolVariable, DefaultBuilder, U32Variable}; + #[test] + fn test_math_lt() { + let mut builder = DefaultBuilder::new(); + + let v0 = builder.read::(); + let v1 = builder.read::(); + let result = builder.read::(); + let computed_result = builder.lt(v0, v1); + builder.assert_is_equal(result, computed_result); + + let circuit = builder.build(); + + let test_cases = [ + (5u32, 0u32, false), + (0u32, 10u32, true), + (10u32, 5u32, false), + ]; + + for test_case in test_cases.iter() { + let mut input = circuit.input(); + input.write::(test_case.0); + input.write::(test_case.1); + input.write::(test_case.2); + + let (proof, output) = circuit.prove(&input); + circuit.verify(&proof, &input, &output); + } + } + + #[test] + fn test_math_lte() { + let mut builder = DefaultBuilder::new(); + + let v0 = builder.read::(); + let v1 = builder.read::(); + let result = builder.read::(); + let computed_result = builder.lte(v0, v1); + builder.assert_is_equal(result, computed_result); + + let circuit = builder.build(); + + let test_cases = [ + (0u32, 0u32, true), + (0u32, 100u32, true), + (10u32, 0u32, false), + ]; + + for test_case in test_cases.iter() { + let mut input = circuit.input(); + input.write::(test_case.0); + input.write::(test_case.1); + input.write::(test_case.2); + + let (proof, output) = circuit.prove(&input); + circuit.verify(&proof, &input, &output); + } + } + #[test] fn test_math_gt() { let mut builder = DefaultBuilder::new(); diff --git a/plonky2x/core/src/frontend/uint/num/biguint/mod.rs b/plonky2x/core/src/frontend/uint/num/biguint/mod.rs index 590b63650..647700936 100644 --- a/plonky2x/core/src/frontend/uint/num/biguint/mod.rs +++ b/plonky2x/core/src/frontend/uint/num/biguint/mod.rs @@ -310,8 +310,9 @@ impl, const D: usize> CircuitBuilderBiguint let div_b_plus_rem = self.add_biguint(&div_b, &rem); self.connect_biguint(a, &div_b_plus_rem); - let cmp_rem_b = self.cmp_biguint(&rem, b); - self.assert_one(cmp_rem_b.target); + // Assert that `r < b`. We do that by asserting that the result of `b \leq r` is `false`. + let cmp_b_rem = self.cmp_biguint(b, &rem); + self.assert_zero(cmp_b_rem.target); (div, rem) } diff --git a/plonky2x/core/src/frontend/uint/num/u32/gadgets/multiple_comparison.rs b/plonky2x/core/src/frontend/uint/num/u32/gadgets/multiple_comparison.rs index 13bbf51dd..3c1e25495 100644 --- a/plonky2x/core/src/frontend/uint/num/u32/gadgets/multiple_comparison.rs +++ b/plonky2x/core/src/frontend/uint/num/u32/gadgets/multiple_comparison.rs @@ -28,6 +28,11 @@ pub fn list_lte_circuit, const D: usize>( let chunk_bits = 2; let num_chunks = ceil_div_usize(num_bits, chunk_bits); + assert_eq!( + num_bits % chunk_bits, + 0, + "num_bits must be divisible by chunk_bits" + ); let one = builder.one(); let mut result = one; diff --git a/plonky2x/core/src/frontend/vars/array.rs b/plonky2x/core/src/frontend/vars/array.rs index bf0d5c768..65a217e59 100644 --- a/plonky2x/core/src/frontend/vars/array.rs +++ b/plonky2x/core/src/frontend/vars/array.rs @@ -9,7 +9,7 @@ use plonky2::iop::challenger::RecursiveChallenger; use plonky2::iop::target::Target; use serde::{Deserialize, Serialize}; -use super::{BoolVariable, ByteVariable, CircuitVariable, ValueStream, Variable, VariableStream}; +use super::{ByteVariable, CircuitVariable, ValueStream, Variable, VariableStream}; use crate::backend::circuit::PlonkParameters; use crate::frontend::builder::CircuitBuilder; use crate::frontend::hint::simple::hint::Hint; @@ -177,10 +177,38 @@ impl, const D: usize> CircuitBuilder { V::from_variables_unsafe(&selected_vars) } - /// Given an `array` of variables, and a dynamic `index` start_idx, returns - /// `array[start_idx..start_idx+sub_array_size]` as an `array`. - /// - /// `seed` is used to generate randomness for the proof. + /// Given an `array` of ByteVariable's, a dynamic `index` start_idx, and a commitment to the + /// `array`, 'seed', return `array[start_idx..start_idx+sub_array_size]` as an `array`. + /// `seed` is used to generate randomness for the proof, and must contain a valid commitment to + /// array (i.e. either the bytes themselves or a hash of the bytes). This function + /// generates a Fiat-Shamir seed from the supplied commitmnet to the array and subarray. + pub fn get_fixed_subarray( + &mut self, + array: &ArrayVariable, + start_idx: Variable, + seed: &[ByteVariable], + ) -> ArrayVariable { + let mut input_stream = VariableStream::new(); + input_stream.write(array); + input_stream.write(&start_idx); + let hint = SubArrayExtractorHint { + array_size: ARRAY_SIZE, + sub_array_size: SUB_ARRAY_SIZE, + }; + let output_stream = self.hint(input_stream, hint); + let sub_array = output_stream.read::>(self); + + // The final seed is generated from the seed (which is a commitment to the array) + // concatenated to the sub_array. seed is Vec because it enables packing + // 7 ByteVariable's into a single Variable, which is useful for the seed's poseidon hashing. + let mut final_seed = seed.to_vec(); + final_seed.extend_from_slice(sub_array.as_slice()); + + self.extract_subarray(array, &sub_array, start_idx, &final_seed); + sub_array + } + + /// Verify that sub_array is a valid subarray of the array given the start_idx. /// /// The security of each challenge is log2(field_size) - log2(array_size), so the total security /// is (log2(field_size) - log2(array_size)) * num_loops. @@ -191,26 +219,30 @@ impl, const D: usize> CircuitBuilder { /// a) i is the index within the subarray. /// b) r^i is the challenge raised to the power of i. /// 3) If outside of the subarray, don't add to the accumulator. - /// 4) Assert that the accumulator is equal to the accumulator from the hinted subarray. - pub fn get_fixed_subarray( + /// 4) Assert that the accumulator is equal to the accumulator from the given subarray. + pub fn extract_subarray( &mut self, - array: &ArrayVariable, + array: &ArrayVariable, + sub_array: &ArrayVariable, start_idx: Variable, seed: &[ByteVariable], - ) -> ArrayVariable { - // TODO: Seed with 120 bits. Check if this is enough bits of security. - const MIN_SEED_BITS: usize = 120; - - let mut input_stream = VariableStream::new(); - input_stream.write(array); - input_stream.write(&start_idx); - - let hint = SubArrayExtractorHint { - array_size: ARRAY_SIZE, - sub_array_size: SUB_ARRAY_SIZE, - }; - let output_stream = self.hint(input_stream, hint); - let sub_array = output_stream.read::>(self); + ) { + // extract_subarray needs the array and subarray to contain variables, so convert + // the bytes to variables (with each variable containing a single byte). + let array_variables = ArrayVariable::::from( + array + .as_slice() + .iter() + .map(|x| x.to_variable(self)) + .collect_vec(), + ); + let subarray_variables = ArrayVariable::::from( + sub_array + .as_slice() + .iter() + .map(|x| x.to_variable(self)) + .collect_vec(), + ); let mut seed_targets = Vec::new(); let mut challenger = RecursiveChallenger::::new(&mut self.api); @@ -226,6 +258,8 @@ impl, const D: usize> CircuitBuilder { seed_bit_len += seed_element_bits.len(); seed_targets.push(seed_element); } + // Seed with at least 120 bits. TODO: Check if this is enough bits of security. + const MIN_SEED_BITS: usize = 120; assert!(seed_bit_len >= MIN_SEED_BITS); @@ -252,6 +286,7 @@ impl, const D: usize> CircuitBuilder { let one: Variable = self.one(); let mut accumulator1 = self.zero::(); + let mut subarray_size: Variable = self.zero(); // r is the source of randomness from the challenger for this loop. let mut r = one; @@ -266,6 +301,8 @@ impl, const D: usize> CircuitBuilder { let at_end_idx = self.is_equal(idx, end_idx); within_sub_array = self.select(at_end_idx, false_v, within_sub_array); + subarray_size = self.add(subarray_size, within_sub_array.variable); + // If within the subarray, multiply the current r by the challenge. let multiplier = self.select(within_sub_array, challenges[i], one); // For subarray[i], the multiplier should be r^i. i is the index within the subarray. @@ -273,38 +310,28 @@ impl, const D: usize> CircuitBuilder { r = self.mul(r, multiplier); // Multiply the current r by the current array element. - let temp_accum = self.mul(r, array[j]); + let temp_accum = self.mul(r, array_variables[j]); // If outside of the subarray, don't add to the accumulator. let temp_accum = self.mul(within_sub_array.variable, temp_accum); accumulator1 = self.add(accumulator1, temp_accum); } + // Assert that the returned subarray's length is == SUB_ARRAY_SIZE. + let expected_subarray_size = + self.constant(L::Field::from_canonical_usize(SUB_ARRAY_SIZE)); + self.assert_is_equal(subarray_size, expected_subarray_size); + let mut accumulator2 = self.zero(); let mut r = one; for j in 0..SUB_ARRAY_SIZE { r = self.mul(r, challenges[i]); - let product = self.mul(r, sub_array[j]); + let product = self.mul(r, subarray_variables[j]); accumulator2 = self.add(accumulator2, product); } self.assert_is_equal(accumulator1, accumulator2); } - - sub_array - } - - pub fn array_contains(&mut self, array: &[V], element: V) -> BoolVariable { - assert!(array.len() < 1 << 16); - let mut accumulator = self.constant::(L::Field::from_canonical_usize(0)); - - for i in 0..array.len() { - let element_equal = self.is_equal(array[i].clone(), element.clone()); - accumulator = self.add(accumulator, element_equal.variable); - } - - let one = self.constant::(L::Field::from_canonical_usize(1)); - self.is_equal(one, accumulator) } } @@ -319,7 +346,7 @@ impl, const D: usize> Hint for SubArrayExtractorHint let mut array_elements = Vec::new(); for _i in 0..self.array_size { - let element = input_stream.read_value::(); + let element = input_stream.read_value::(); array_elements.push(element); } @@ -330,7 +357,7 @@ impl, const D: usize> Hint for SubArrayExtractorHint for i in 0..self.sub_array_size { let element = array_elements[start_idx as usize + i]; - output_stream.write_value::(element); + output_stream.write_value::(element); } } } @@ -472,7 +499,7 @@ mod tests { let mut builder = DefaultBuilder::new(); - let array = builder.read::>(); + let array = builder.read::>(); let start_idx = builder.constant(F::from_canonical_usize(START_IDX)); let seed = builder.read::(); let result = builder.get_fixed_subarray::( @@ -486,9 +513,9 @@ mod tests { // The last 20 elements are dummy let mut rng = OsRng; - let mut array_input = [F::default(); ARRAY_SIZE]; + let mut array_input = [0u8; ARRAY_SIZE]; for elem in array_input.iter_mut() { - *elem = F::from_canonical_u64(rng.gen()); + *elem = rng.gen(); } let mut seed_input = [0u8; 15]; @@ -497,7 +524,7 @@ mod tests { } let mut input = circuit.input(); - input.write::>(array_input.to_vec()); + input.write::>(array_input.to_vec()); input.write::(bytes32!( "0x7c38fc8356aa20394c7f538e3cee3f924e6d9252494c8138d1a6aabfc253118f" )); @@ -507,8 +534,53 @@ mod tests { let expected_sub_array = array_input[START_IDX..START_IDX + SUB_ARRAY_SIZE].to_vec(); assert_eq!( - output.read::>(), + output.read::>(), expected_sub_array ); } + + #[test] + #[should_panic] + fn test_get_fixed_subarray_bad_case() { + utils::setup_logger(); + type F = GoldilocksField; + const ARRAY_SIZE: usize = 12800; + const SUB_ARRAY_SIZE: usize = 3200; + const START_IDX: usize = 12000; + + let mut builder = DefaultBuilder::new(); + + let array = builder.read::>(); + let start_idx = builder.constant(F::from_canonical_usize(START_IDX)); + let seed = builder.read::(); + let result = builder.get_fixed_subarray::( + &array, + start_idx, + &seed.as_bytes(), + ); + builder.write(result); + + let circuit = builder.build(); + + // The last 20 elements are dummy + let mut rng = OsRng; + let mut array_input = [0u8; ARRAY_SIZE]; + for elem in array_input.iter_mut() { + *elem = rng.gen(); + } + + let mut seed_input = [0u8; 15]; + for elem in seed_input.iter_mut() { + *elem = rng.gen(); + } + + let mut input = circuit.input(); + input.write::>(array_input.to_vec()); + input.write::(bytes32!( + "0x7c38fc8356aa20394c7f538e3cee3f924e6d9252494c8138d1a6aabfc253118f" + )); + + let (proof, output) = circuit.prove(&input); + circuit.verify(&proof, &input, &output); + } } diff --git a/plonky2x/core/src/frontend/vars/stream.rs b/plonky2x/core/src/frontend/vars/stream.rs index 92495a5fc..eea369477 100644 --- a/plonky2x/core/src/frontend/vars/stream.rs +++ b/plonky2x/core/src/frontend/vars/stream.rs @@ -38,7 +38,7 @@ impl, const D: usize> OutputVariableStream { pub fn read_exact(&self, builder: &mut CircuitBuilder, len: usize) -> Vec { let variables = (0..len) - .map(|_| builder.init::()) + .map(|_| builder.init_unsafe::()) .collect::>(); let stream = &mut builder .hints @@ -50,31 +50,18 @@ impl, const D: usize> OutputVariableStream { variables } - // Some hints already do validity checks on elements that they write to their output stream. - // Those instances can use this unsafe version of read_exact. E.g. hints that call curta can - // use this for their curta public inputs. - pub fn read_exact_unsafe( - &self, - builder: &mut CircuitBuilder, - len: usize, - ) -> Vec { - let variables = (0..len) - .map(|_| builder.init_unsafe::()) - .collect::>(); - let stream = &mut builder - .hints - .get_mut(self.hint_id) - .expect("Hint not found") - .output_stream_mut(); - stream.0.write_slice(&variables); + /// Read a single variable from the stream. + /// The output value is asserted to be a valid circuit variable. + pub fn read(&self, builder: &mut CircuitBuilder) -> V { + let variables = self.read_exact(builder, V::nb_elements()); - variables + V::from_variables(builder, &variables) } - pub fn read(&self, builder: &mut CircuitBuilder) -> V { + /// Read a circuit variable from the output stream without doing any validity checks. + pub fn read_unsafe(&self, builder: &mut CircuitBuilder) -> V { let variables = self.read_exact(builder, V::nb_elements()); - // "read_exact" will have already done validity checks on the circuit variables. V::from_variables_unsafe(&variables) } diff --git a/plonky2x/core/src/lib.rs b/plonky2x/core/src/lib.rs index b3ec3704b..23ba92333 100644 --- a/plonky2x/core/src/lib.rs +++ b/plonky2x/core/src/lib.rs @@ -3,7 +3,6 @@ #![allow(incomplete_features)] #![feature(trait_alias)] #![feature(decl_macro)] -#![feature(core_intrinsics)] #![feature(trait_upcasting)] extern crate alloc; diff --git a/rust-toolchain b/rust-toolchain index 6c1c341e2..f7ee87eaf 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-08-24" +channel = "nightly-2024-01-25" components = ["llvm-tools", "rustc-dev"] \ No newline at end of file diff --git a/rustx/Cargo.toml b/rustx/Cargo.toml index 7710c1cfd..fb5fae5c4 100644 --- a/rustx/Cargo.toml +++ b/rustx/Cargo.toml @@ -21,13 +21,13 @@ env_logger = "0.10.0" ethers = "2.0.10" hex = "0.4.3" log = "0.4.20" -plonky2 = { git = "https://github.com/mir-protocol/plonky2.git", default-features = false, rev = "2d36559d" } +plonky2 = { git = "https://github.com/mir-protocol/plonky2.git", default-features = false, rev = "d2598bd" } plonky2x = { path = "../plonky2x/core" } serde = "1.0.188" serde_json = "1.0.107" tokio = "1.33.0" [dev-dependencies] -plonky2 = { git = "https://github.com/mir-protocol/plonky2.git", rev = "2d36559d", features = [ +plonky2 = { git = "https://github.com/mir-protocol/plonky2.git", rev = "d2598bd", features = [ "gate_testing", ] }