diff --git a/Cargo.lock b/Cargo.lock index 4c1f122b0..7d7b3912a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -97,9 +97,9 @@ dependencies = [ [[package]] name = "alloy-core" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5af3faff14c12c8b11037e0a093dd157c3702becb8435577a2408534d0758315" +checksum = "529fc6310dc1126c8de51c376cbc59c79c7f662bd742be7dc67055d5421a81b4" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -152,9 +152,9 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f783611babedbbe90db3478c120fb5f5daacceffc210b39adc0af4fe0da70bad" +checksum = "ccb3ead547f4532bc8af961649942f0b9c16ee9226e26caa3f38420651cc0bf4" dependencies = [ "alloy-rlp", "bytes", @@ -223,7 +223,7 @@ checksum = "d83524c1f6162fcb5b0decf775498a125066c86dda6066ed609531b0e912f85a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -310,23 +310,23 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bad41a7c19498e3f6079f7744656328699f8ea3e783bdd10d85788cd439f572" +checksum = "2b40397ddcdcc266f59f959770f601ce1280e699a91fc1862f29cef91707cd09" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] name = "alloy-sol-macro-expander" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd9899da7d011b4fe4c406a524ed3e3f963797dbc93b45479d60341d3a27b252" +checksum = "867a5469d61480fea08c7333ffeca52d5b621f5ca2e44f271b117ec1fc9a0525" dependencies = [ "alloy-sol-macro-input", "const-hex", @@ -335,31 +335,31 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", "syn-solidity", "tiny-keccak", ] [[package]] name = "alloy-sol-macro-input" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32d595768fdc61331a132b6f65db41afae41b9b97d36c21eb1b955c422a7e60" +checksum = "2e482dc33a32b6fadbc0f599adea520bd3aaa585c141a80b404d0a3e3fa72528" dependencies = [ "const-hex", "dunce", "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", "syn-solidity", ] [[package]] name = "alloy-sol-types" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a49042c6d3b66a9fe6b2b5a8bf0d39fc2ae1ee0310a2a26ffedd79fb097878dd" +checksum = "a91ca40fa20793ae9c3841b83e74569d1cc9af29a2f5237314fd3452d51e38c7" dependencies = [ "alloy-primitives", "alloy-sol-macro", @@ -399,9 +399,9 @@ dependencies = [ [[package]] name = "amq-protocol" -version = "7.2.0" +version = "7.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051d4d77904272e9be7e292607378dc9900d15b8d314bfd3ed4b82fdd84f125" +checksum = "0f0234884b3641db74d22ccc20fc2594db5f23d7d41ade5c93d7ee33d200960c" dependencies = [ "amq-protocol-tcp", "amq-protocol-types", @@ -413,9 +413,9 @@ dependencies = [ [[package]] name = "amq-protocol-tcp" -version = "7.2.0" +version = "7.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e3d51dd36e67d757c9ba80a7b2a2a2a69254c1dbe4d8c631824ec7f5b69f60e" +checksum = "265dca43d9dbb3d5bbb0b3ef1b0cd9044ce3aa5d697d5b66cde974d1f6063f09" dependencies = [ "amq-protocol-uri", "tcp-stream", @@ -424,9 +424,9 @@ dependencies = [ [[package]] name = "amq-protocol-types" -version = "7.2.0" +version = "7.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0acdd47054ced8b9bc89ee0dbb42ccc8028de48d8658b24de4c255a226c9bfec" +checksum = "c7412353b58923fa012feb9a64ccc0c811747babee2e5a2fd63eb102dc8054c3" dependencies = [ "cookie-factory", "nom", @@ -436,9 +436,9 @@ dependencies = [ [[package]] name = "amq-protocol-uri" -version = "7.2.0" +version = "7.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17881b7575dab3e71403f28a3e50b71f0d1bd026829abca3c48664522ce0df0" +checksum = "2be91352c805d5704784e079117d5291fd5bf2569add53c914ebce6d1a795d33" dependencies = [ "amq-protocol-types", "percent-encoding", @@ -678,7 +678,7 @@ checksum = "7378575ff571966e99a744addeff0bff98b8ada0dedf1956d59e634db95eaac1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", "synstructure", ] @@ -690,7 +690,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -834,7 +834,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -845,13 +845,13 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.80" +version = "0.1.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -877,7 +877,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -1034,7 +1034,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.68", + "syn 2.0.70", "which", ] @@ -1210,9 +1210,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.104" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74b6a57f98764a267ff415d50a25e6e166f3831a5071af4995296ea97d210490" +checksum = "eaff6f8ce506b9773fa786672d63fc7a191ffea1be33f72bbd4aeacefca9ffc8" dependencies = [ "jobserver", "libc", @@ -1244,7 +1244,7 @@ dependencies = [ "iana-time-zone", "num-traits", "serde", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -1297,9 +1297,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.8" +version = "4.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84b3edb18336f4df585bc9aa31dd99c036dfa5dc5e9a2939a722a188f3a8970d" +checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462" dependencies = [ "clap_builder", "clap_derive", @@ -1307,9 +1307,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.8" +version = "4.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1c09dd5ada6c6c78075d6fd0da3f90d8080651e2d6cc8eb2f1aaa4034ced708" +checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942" dependencies = [ "anstream", "anstyle", @@ -1326,7 +1326,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -1599,9 +1599,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ "darling_core", "darling_macro", @@ -1609,27 +1609,27 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] name = "darling_macro" -version = "0.20.9" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -1680,13 +1680,13 @@ dependencies = [ [[package]] name = "der_derive" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe87ce4529967e0ba1dcf8450bab64d97dfd5010a6256187ffe2e43e6f0e049" +checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -1720,7 +1720,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.0", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -1761,7 +1761,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -1836,7 +1836,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -1847,7 +1847,7 @@ checksum = "6fd000fd6988e73bbe993ea3db9b1aa64906ab88766d654973924340c8cddb42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -1992,7 +1992,7 @@ dependencies = [ "pest", "pest_derive", "plonky2", - "plonky2_maybe_rayon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "plonky2_maybe_rayon", "plonky2_util", "rand", "rand_chacha", @@ -2218,7 +2218,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -2466,9 +2466,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4fe55fb7a772d59a5ff1dfbff4fe0258d19b89fec4b233e75d35d5d2316badc" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ "bytes", "futures-channel", @@ -2888,7 +2888,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d" dependencies = [ "cfg-if", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -2914,7 +2914,7 @@ checksum = "f8dccda732e04fa3baf2e17cf835bfe2601c7c2edafd64417c627dabae3a8cda" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -3187,7 +3187,7 @@ checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -3216,9 +3216,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "oorandom" -version = "11.1.3" +version = "11.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "openssl" @@ -3243,7 +3243,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -3346,7 +3346,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af25dcb10b7c0ce99abee8694e2e79e4787d7f778b9339dc5a50ba6fc45e5cc9" dependencies = [ "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -3401,7 +3401,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -3466,7 +3466,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -3497,7 +3497,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -3584,7 +3584,6 @@ checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "plonky2" version = "0.2.2" -source = "git+https://github.com/0xPolygonZero/plonky2.git?rev=dc77c77f2b06500e16ad4d7f1c2b057903602eed#dc77c77f2b06500e16ad4d7f1c2b057903602eed" dependencies = [ "ahash", "anyhow", @@ -3595,7 +3594,7 @@ dependencies = [ "log", "num", "plonky2_field", - "plonky2_maybe_rayon 0.2.0 (git+https://github.com/0xPolygonZero/plonky2.git?rev=dc77c77f2b06500e16ad4d7f1c2b057903602eed)", + "plonky2_maybe_rayon", "plonky2_util", "rand", "rand_chacha", @@ -3608,7 +3607,6 @@ dependencies = [ [[package]] name = "plonky2_field" version = "0.2.2" -source = "git+https://github.com/0xPolygonZero/plonky2.git?rev=dc77c77f2b06500e16ad4d7f1c2b057903602eed#dc77c77f2b06500e16ad4d7f1c2b057903602eed" dependencies = [ "anyhow", "itertools 0.11.0", @@ -3623,16 +3621,6 @@ dependencies = [ [[package]] name = "plonky2_maybe_rayon" version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ff44a90aaca13e10e7ddf8fab815ba1b404c3f7c3ca82aaf11c46beabaa923" -dependencies = [ - "rayon", -] - -[[package]] -name = "plonky2_maybe_rayon" -version = "0.2.0" -source = "git+https://github.com/0xPolygonZero/plonky2.git?rev=dc77c77f2b06500e16ad4d7f1c2b057903602eed#dc77c77f2b06500e16ad4d7f1c2b057903602eed" dependencies = [ "rayon", ] @@ -3640,7 +3628,6 @@ dependencies = [ [[package]] name = "plonky2_util" version = "0.2.0" -source = "git+https://github.com/0xPolygonZero/plonky2.git?rev=dc77c77f2b06500e16ad4d7f1c2b057903602eed#dc77c77f2b06500e16ad4d7f1c2b057903602eed" [[package]] name = "plotters" @@ -3742,7 +3729,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -4239,9 +4226,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.10" +version = "0.23.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05cff451f60db80f490f3c182b77c35260baace73209e9cdbbe526bfe3a4d402" +checksum = "4828ea528154ae444e5a642dbb7d5623354030dc9822b83fd9bb79683c7399d0" dependencies = [ "aws-lc-rs", "log", @@ -4267,9 +4254,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" +checksum = "a88d6d420651b496bdd98684116959239430022a115c1240e6c3993be0b15fba" dependencies = [ "openssl-probe", "rustls-pemfile", @@ -4296,9 +4283,9 @@ checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" [[package]] name = "rustls-webpki" -version = "0.102.4" +version = "0.102.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" +checksum = "f9a6fccd794a42c2c105b513a2f62bc3fd8f3ba57a4593677ceb0bd035164d78" dependencies = [ "aws-lc-rs", "ring", @@ -4440,9 +4427,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] @@ -4458,13 +4445,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -4511,9 +4498,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.8.2" +version = "3.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "079f3a42cd87588d924ed95b533f8d30a483388c4e400ab736a7058e34f16169" +checksum = "e73139bc5ec2d45e6c5fd85be5a46949c1c39a4c18e56915f5eb4c12f975e377" dependencies = [ "base64", "chrono", @@ -4529,14 +4516,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.8.2" +version = "3.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc03aad67c1d26b7de277d51c86892e7d9a0110a2fe44bf6b26cc569fba302d6" +checksum = "b80d3d6b56b64335c0180e5ffde23b3c5e08c14c585b51a15bd0e95393f46703" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -4679,7 +4666,6 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "starky" version = "0.4.0" -source = "git+https://github.com/0xPolygonZero/plonky2.git?rev=dc77c77f2b06500e16ad4d7f1c2b057903602eed#dc77c77f2b06500e16ad4d7f1c2b057903602eed" dependencies = [ "ahash", "anyhow", @@ -4688,7 +4674,7 @@ dependencies = [ "log", "num-bigint", "plonky2", - "plonky2_maybe_rayon 0.2.0 (git+https://github.com/0xPolygonZero/plonky2.git?rev=dc77c77f2b06500e16ad4d7f1c2b057903602eed)", + "plonky2_maybe_rayon", "plonky2_util", ] @@ -4723,7 +4709,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -4745,9 +4731,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.68" +version = "2.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" +checksum = "2f0209b68b3613b093e0ec905354eccaedcfe83b8cb37cbdeae64026c3064c16" dependencies = [ "proc-macro2", "quote", @@ -4756,14 +4742,14 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d71e19bca02c807c9faa67b5a47673ff231b6e7449b251695188522f1dc44b2" +checksum = "c837dc8852cb7074e46b444afb81783140dab12c58867b49fb3898fbafedf7ea" dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -4786,7 +4772,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -4845,7 +4831,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -4919,9 +4905,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c55115c6fbe2d2bef26eb09ad74bde02d8255476fc0c7b515ef09fbb35742d82" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -4970,7 +4956,7 @@ checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -5031,7 +5017,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.14", + "toml_edit 0.22.15", ] [[package]] @@ -5056,9 +5042,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.14" +version = "0.22.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" +checksum = "d59a3a72298453f564e2b111fa896f8d07fabb36f51f06d7e875fc5e0b5a3ef1" dependencies = [ "indexmap 2.2.6", "serde", @@ -5137,7 +5123,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -5187,9 +5173,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "trybuild" -version = "1.0.96" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33a5f13f11071020bb12de7a16b925d2d58636175c20c11dc5f96cb64bb6c9b3" +checksum = "5b1e5645f2ee8025c2f1d75e1138f2dd034d74e6ba54620f3c569ba2a2a1ea06" dependencies = [ "glob", "serde", @@ -5285,9 +5271,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.9.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" dependencies = [ "getrandom", "rand", @@ -5388,7 +5374,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", "wasm-bindgen-shared", ] @@ -5422,7 +5408,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5502,7 +5488,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -5520,7 +5506,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -5540,18 +5526,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -5562,9 +5548,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -5574,9 +5560,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -5586,15 +5572,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -5604,9 +5590,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -5616,9 +5602,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -5628,9 +5614,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -5640,9 +5626,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" @@ -5761,7 +5747,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -5781,7 +5767,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", ] [[package]] @@ -5790,6 +5776,6 @@ version = "0.1.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.70", "trybuild", ] diff --git a/Cargo.toml b/Cargo.toml index ad5b36493..0b6bb77cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -113,10 +113,10 @@ rpc = { path = "zero_bin/rpc" } zero_bin_common = { path = "zero_bin/common" } # plonky2-related dependencies -plonky2 = { git = "https://github.com/0xPolygonZero/plonky2.git", rev = "dc77c77f2b06500e16ad4d7f1c2b057903602eed" } -plonky2_maybe_rayon = "0.2.0" -plonky2_util = { git = "https://github.com/0xPolygonZero/plonky2.git", rev = "dc77c77f2b06500e16ad4d7f1c2b057903602eed" } -starky = { git = "https://github.com/0xPolygonZero/plonky2.git", rev = "dc77c77f2b06500e16ad4d7f1c2b057903602eed" } +plonky2 = { path = "../plonky2/plonky2"} +plonky2_maybe_rayon = { path = "../plonky2/maybe_rayon"} +plonky2_util = { path = "../plonky2/util"} +starky = { path = "../plonky2/starky"} # proc macro related dependencies proc-macro2 = "1.0" diff --git a/evm_arithmetization/src/all_stark.rs b/evm_arithmetization/src/all_stark.rs index c3b5733c1..4a874e797 100644 --- a/evm_arithmetization/src/all_stark.rs +++ b/evm_arithmetization/src/all_stark.rs @@ -105,6 +105,26 @@ impl Deref for Table { /// Number of STARK tables. pub(crate) const NUM_TABLES: usize = Table::MemAfter as usize + 1; +pub(crate) const TABLE_DEGREES: [usize; NUM_TABLES] = [ + 18, // Arithmetic + 18, // BytePacking, + 18, // Cpu, + 14, // Keccak, + 14, // KeccakSponge, + 18, // Logic, + 18, // Memory, + 18, // MemBefore, + 15, // MemAfter, +]; + +pub(crate) const ALL_SORTED_TABLES: [Table; NUM_TABLES] = Table::all_sorted(); + +pub(crate) const TABLE_TO_SORTED_INDEX: [usize; NUM_TABLES] = Table::table_to_sorted_index(); + +pub(crate) const SORTED_INDEX_PAIR: [(usize, usize); NUM_TABLES] = Table::sorted_index_pair(); + +pub(crate) const ALL_DEGREE_LOGS: [usize; NUM_TABLES] = Table::all_degree_logs(); + impl Table { /// Returns all STARK table indices. pub(crate) const fn all() -> [Self; NUM_TABLES] { @@ -120,6 +140,88 @@ impl Table { Self::MemAfter, ] } + + /// Returns all STARK table indices in descending order of their padded + /// trace degrees. + const fn all_sorted() -> [Self; NUM_TABLES] { + let mut sorted_pairs = [(0, Table::Arithmetic); NUM_TABLES]; + let mut i = 0; + while i < NUM_TABLES { + sorted_pairs[i] = (TABLE_DEGREES[i], Self::all()[i]); + i += 1; + } + + // Simple bubble sort. + let mut i = 0; + while i < NUM_TABLES - 1 { + let mut j = 0; + while j < NUM_TABLES - i - 1 { + let (pair_a, pair_b) = (sorted_pairs[j], sorted_pairs[j + 1]); + if pair_a.0 < pair_b.0 { + sorted_pairs[j] = pair_b; + sorted_pairs[j + 1] = pair_a; + } + j += 1; + } + i += 1; + } + + let mut sorted_tables = [Table::Arithmetic; NUM_TABLES]; + let mut i = 0; + while i < NUM_TABLES { + sorted_tables[i] = sorted_pairs[i].1; + i += 1; + } + + sorted_tables + } + + /// Returns the ordered position of the tables. This is the inverse of + /// `all_sorted()`. + const fn table_to_sorted_index() -> [usize; NUM_TABLES] { + let mut res = [0; NUM_TABLES]; + let mut i = 0; + while i < NUM_TABLES { + res[Self::all_sorted()[i] as usize] = i; + i += 1; + } + + res + } + + /// Returns the ordered position of the tables in a batch Merkle tree. Each + /// entry is a couple to account for duplicate sizes. + const fn sorted_index_pair() -> [(usize, usize); NUM_TABLES] { + let mut pairs = [(0, 0); NUM_TABLES]; + + let mut outer = 0; + let mut inner = 0; + let mut i = 1; + while i < NUM_TABLES { + if Self::all_degree_logs()[i] < Self::all_degree_logs()[i - 1] { + outer += 1; + inner = 0; + } else { + inner += 1; + } + pairs[i] = (outer, inner); + i += 1; + } + + pairs + } + + /// Returns all STARK padded trace degrees in descending order. + const fn all_degree_logs() -> [usize; NUM_TABLES] { + let mut res = [0; NUM_TABLES]; + let mut i = 0; + while i < NUM_TABLES { + res[i] = TABLE_DEGREES[Self::all_sorted()[i] as usize]; + i += 1; + } + + res + } } /// Returns all the `CrossTableLookups` used for proving the EVM. diff --git a/evm_arithmetization/src/arithmetic/arithmetic_stark.rs b/evm_arithmetization/src/arithmetic/arithmetic_stark.rs index d0712a3bc..ea5224213 100644 --- a/evm_arithmetization/src/arithmetic/arithmetic_stark.rs +++ b/evm_arithmetization/src/arithmetic/arithmetic_stark.rs @@ -18,7 +18,7 @@ use static_assertions::const_assert; use super::columns::{op_flags, NUM_ARITH_COLUMNS}; use super::shift; -use crate::all_stark::{EvmStarkFrame, Table}; +use crate::all_stark::{EvmStarkFrame, Table, ALL_DEGREE_LOGS, TABLE_TO_SORTED_INDEX}; use crate::arithmetic::columns::{NUM_SHARED_COLS, RANGE_COUNTER, RC_FREQUENCIES, SHARED_COLS}; use crate::arithmetic::{addcy, byte, columns, divmod, modular, mul, Operation}; @@ -178,7 +178,13 @@ impl ArithmeticStark { // Pad the trace with zero rows if it doesn't have enough rows // to accommodate the range check columns. Also make sure the // trace length is a power of two. - let padded_len = trace_rows.len().next_power_of_two(); + let padded_len = 1 << ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::Arithmetic]]; + assert!( + padded_len >= trace_rows.len(), + "Padded length {:?} is smaller than actual trace length {:?}", + padded_len, + trace_rows.len() + ); for _ in trace_rows.len()..std::cmp::max(padded_len, RANGE_MAX) { trace_rows.push(vec![F::ZERO; columns::NUM_ARITH_COLUMNS]); } diff --git a/evm_arithmetization/src/batch_proof.rs b/evm_arithmetization/src/batch_proof.rs new file mode 100644 index 000000000..98f8f2757 --- /dev/null +++ b/evm_arithmetization/src/batch_proof.rs @@ -0,0 +1,101 @@ +use ethereum_types::{Address, H256, U256}; +use plonky2::field::extension::Extendable; +use plonky2::fri::proof::FriProof; +use plonky2::hash::hash_types::{HashOutTarget, MerkleCapTarget, RichField, NUM_HASH_OUT_ELTS}; +use plonky2::iop::challenger::Challenger; +use plonky2::iop::target::{BoolTarget, Target}; +use plonky2::plonk::circuit_builder::CircuitBuilder; +use plonky2::plonk::config::GenericConfig; +use plonky2::util::serialization::{Buffer, IoResult, Read, Write}; +use serde::{Deserialize, Serialize}; +use starky::batch_proof::BatchStarkProof; +use starky::config::StarkConfig; +use starky::lookup::{get_grand_product_challenge_set, GrandProductChallengeSet}; +use starky::proof::{MultiProof, StarkProofChallenges}; + +use crate::all_stark::NUM_TABLES; +use crate::get_challenges::observe_public_values; +use crate::proof::PublicValues; +use crate::util::{get_h160, get_h256, get_u256, h2u}; +use crate::witness::errors::ProgramError; +use crate::witness::state::RegistersState; + +/// A batched STARK proof for all tables, plus some metadata used to create +/// recursive wrapper proof. +#[derive(Debug, Clone)] +pub struct EvmProof, C: GenericConfig, const D: usize> { + /// A multi-proof containing all proofs for the different STARK modules and + /// their cross-table lookup challenges. + pub batch_proof: BatchStarkProof, + /// Public memory values used for the recursive proofs. + pub public_values: PublicValues, +} + +impl, C: GenericConfig, const D: usize> EvmProof { + /// Returns the degree of the batched STARK proof. + pub fn degree_bits(&self, config: &StarkConfig) -> usize { + self.batch_proof.recover_degree_bits(config) + } +} + +impl, C: GenericConfig, const D: usize> EvmProof { + /// Computes all Fiat-Shamir challenges used in the STARK proof. + pub(crate) fn get_challenges( + &self, + config: &StarkConfig, + ) -> Result, anyhow::Error> { + let mut challenger = Challenger::::new(); + + challenger.observe_cap(&self.batch_proof.trace_cap); + observe_public_values::(&mut challenger, &self.public_values) + .map_err(|_| anyhow::Error::msg("Invalid conversion of public values."))?; + + let ctl_challenges = + get_grand_product_challenge_set(&mut challenger, config.num_challenges); + + challenger.observe_cap( + &self + .batch_proof + .auxiliary_polys_cap + .as_ref() + .expect("No auxiliary cap?"), + ); + let stark_alphas = challenger.get_n_challenges(config.num_challenges); + + challenger.observe_cap( + &self + .batch_proof + .quotient_polys_cap + .as_ref() + .expect("No quotient cap?"), + ); + let stark_zeta = challenger.get_extension_challenge::(); + + for opening in &self.batch_proof.openings { + challenger.observe_openings(&opening.to_fri_openings()); + } + + let FriProof { + commit_phase_merkle_caps, + final_poly, + pow_witness, + .. + } = &self.batch_proof.opening_proof; + let degree_bits = self.degree_bits(config); + + let fri_challenges = challenger.fri_challenges::( + commit_phase_merkle_caps, + final_poly, + *pow_witness, + degree_bits, + &config.fri_config, + ); + + Ok(StarkProofChallenges { + lookup_challenge_set: Some(ctl_challenges), // CTL challenge contains lookup challenges. + stark_alphas, + stark_zeta, + fri_challenges, + }) + } +} diff --git a/evm_arithmetization/src/batch_verifier.rs b/evm_arithmetization/src/batch_verifier.rs new file mode 100644 index 000000000..2d4b1dc9d --- /dev/null +++ b/evm_arithmetization/src/batch_verifier.rs @@ -0,0 +1,382 @@ +use std::iter::once; + +use anyhow::{ensure, Result}; +use ethereum_types::{BigEndianHash, U256}; +use hashbrown::HashMap; +use itertools::Itertools; +use plonky2::batch_fri::verifier::verify_batch_fri_proof; +use plonky2::field::extension::Extendable; +use plonky2::field::polynomial::PolynomialValues; +use plonky2::fri::oracle::PolynomialBatch; +use plonky2::fri::structure::FriInstanceInfo; +use plonky2::fri::validate_shape::validate_batch_fri_proof_shape; +use plonky2::hash::hash_types::RichField; +use plonky2::hash::merkle_tree::MerkleCap; +use plonky2::iop::challenger::Challenger; +use plonky2::plonk::config::{GenericConfig, GenericHashOut}; +use plonky2::util::timing::TimingTree; +use plonky2::util::transpose; +use starky::batch_proof::{BatchStarkProof, BatchStarkProofWithPublicInputs}; +use starky::config::StarkConfig; +use starky::cross_table_lookup::{ + get_ctl_vars_from_proofs, num_ctl_helper_columns_by_table, verify_cross_table_lookups, + CtlCheckVars, +}; +use starky::evaluation_frame::StarkEvaluationFrame; +use starky::lookup::{get_grand_product_challenge_set, GrandProductChallenge}; +use starky::proof::{StarkOpeningSet, StarkProofChallenges}; +use starky::stark::Stark; +use starky::verifier::{verify_opening_set, verify_stark_proof_with_challenges}; + +use crate::all_stark::{ + AllStark, Table, ALL_DEGREE_LOGS, ALL_SORTED_TABLES, NUM_TABLES, TABLE_TO_SORTED_INDEX, +}; +use crate::batch_proof::EvmProof; +use crate::cpu::kernel::aggregator::KERNEL; +use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; +use crate::get_challenges::observe_public_values; +use crate::memory::segments::Segment; +use crate::memory::VALUE_LIMBS; +use crate::proof::{AllProof, AllProofChallenges, MemCap, PublicValues}; +use crate::prover::all_fri_instance_info; +use crate::util::h2u; + +/// Verify a batched STARK EVM proof. +pub fn verify_evm_proof< + F: RichField + Extendable, + C: GenericConfig, + const D: usize, +>( + all_stark: &AllStark, + evm_proof: EvmProof, + config: &StarkConfig, + is_initial: bool, +) -> Result<()> { + let challenges = evm_proof + .get_challenges(&config) + .expect("Bad EVM proof challenges?"); + + let openings = &evm_proof.batch_proof.openings; + + let num_lookup_columns = all_stark.num_lookups_helper_columns(config); + + let all_ctl_helper_columns = num_ctl_helper_columns_by_table( + &all_stark.cross_table_lookups, + all_stark.arithmetic_stark.constraint_degree(), + ); + + let num_ctl_helper_columns_per_table = (0..NUM_TABLES) + .map(|i| { + all_ctl_helper_columns + .iter() + .map(|ctl_cols: &[usize; NUM_TABLES]| ctl_cols[i]) + .sum() + }) + .collect::>() + .try_into() + .unwrap(); + + let ctl_vars_per_table = CtlCheckVars::from_proofs::( + openings, + &all_stark.cross_table_lookups, + &challenges + .lookup_challenge_set + .as_ref() + .expect("No lookup challenges?"), + &num_lookup_columns, + &all_ctl_helper_columns, + ); + + verify_all_openings( + all_stark, + &evm_proof, + &challenges, + &ctl_vars_per_table, + config, + )?; + + let mut degree_bits_squashed = ALL_DEGREE_LOGS.to_vec(); + degree_bits_squashed.dedup(); + + let merkle_caps = once(evm_proof.batch_proof.trace_cap.clone()) + .chain(evm_proof.batch_proof.auxiliary_polys_cap.clone()) + .chain(evm_proof.batch_proof.quotient_polys_cap.clone()) + .collect_vec(); + + let num_trace_polys_sorted_per_table = (0..NUM_TABLES) + .map(|i| openings[*ALL_SORTED_TABLES[i]].local_values.len()) + .collect::>() + .try_into() + .unwrap(); + + let num_auxiliary_columns_sorted_per_table = (0..NUM_TABLES) + .map(|i| { + openings[*ALL_SORTED_TABLES[i]] + .auxiliary_polys + .as_ref() + .expect("No auxiliary polys?") + .len() + }) + .collect::>() + .try_into() + .unwrap(); + + let num_quotient_polys_sorted_per_table = (0..NUM_TABLES) + .map(|i| { + openings[*ALL_SORTED_TABLES[i]] + .quotient_polys + .as_ref() + .expect("No quotient polys?") + .len() + }) + .collect::>() + .try_into() + .unwrap(); + + let instances = all_fri_instance_info::( + all_stark, + challenges.stark_zeta, + &num_trace_polys_sorted_per_table, + &num_auxiliary_columns_sorted_per_table, + &num_quotient_polys_sorted_per_table, + &num_ctl_helper_columns_per_table, + config, + ); + // println!("Verifier FRI instances:\n{:#?}", instances); + + validate_batch_fri_proof_shape::( + &evm_proof.batch_proof.opening_proof, + &instances, + &config.fri_params(degree_bits_squashed[0]), + )?; + + let sorted_openings: Vec<_> = ALL_SORTED_TABLES + .iter() + .map(|&table| openings[*table].clone()) + .collect(); + + let mut squashed_openings = Vec::new(); + let mut i = 0; + // local_values, next_values, auxiliary_polys, auxiluary_polys_next, + // quotient_polys + let mut current_values_extension = vec![Vec::new(); 5]; + // ctl_zs_first + let mut current_values_base = Vec::new(); + + while i < NUM_TABLES { + let table_opening = &sorted_openings[i]; + current_values_extension[0].extend(table_opening.local_values.iter()); + current_values_extension[1].extend(table_opening.next_values.iter()); + current_values_extension[2].extend( + table_opening + .auxiliary_polys + .as_ref() + .expect("No auxiliary values?"), + ); + current_values_extension[3].extend( + table_opening + .auxiliary_polys_next + .as_ref() + .expect("No auxiliary values?"), + ); + current_values_base.extend( + table_opening + .ctl_zs_first + .as_ref() + .expect("No auxiliary values?"), + ); + current_values_extension[4].extend( + table_opening + .quotient_polys + .as_ref() + .expect("No auxiliary values?"), + ); + + if i == NUM_TABLES - 1 || ALL_DEGREE_LOGS[i + 1] < ALL_DEGREE_LOGS[i] { + let opening_set = StarkOpeningSet { + local_values: current_values_extension[0].clone(), + next_values: current_values_extension[1].clone(), + auxiliary_polys: Some(current_values_extension[2].clone()), + auxiliary_polys_next: Some(current_values_extension[3].clone()), + ctl_zs_first: Some(current_values_base.clone()), + quotient_polys: Some(current_values_extension[4].clone()), + }; + squashed_openings.push(opening_set.clone()); + current_values_extension = vec![Vec::new(); 5]; + current_values_base = Vec::new(); + } + i += 1; + } + + for (i, op) in squashed_openings.iter().enumerate() { + println!("Squashed opening {}:", i); + println!("{} local values\n{} next_values\n{} aux values\n{} next aux values\n{} quotient values\n{} ctlzs first values", op.local_values.len(), op.next_values.len(), op.auxiliary_polys.as_ref().unwrap().len(), op.auxiliary_polys_next.as_ref().unwrap().len(), op.quotient_polys.as_ref().unwrap().len(), op.ctl_zs_first.as_ref().unwrap().len()); + } + + let fri_openings = squashed_openings + .iter() + .map(|opening| opening.to_fri_openings()) + .collect::>(); + + // println!("\n\nOpening for instance 1:"); + // println!("{:?}\n\n", fri_openings[1]); + // for batch in fri_openings[0].batches.iter() { + // println!("{:?}", batch.values.len()); + // } + + verify_batch_fri_proof::( + °ree_bits_squashed, + &instances, + &fri_openings, + &challenges.fri_challenges, + &merkle_caps, + &evm_proof.batch_proof.opening_proof, + &config.fri_params(degree_bits_squashed[0]), + ) + + // Ok(()) +} + +fn verify_all_openings< + F: RichField + Extendable, + C: GenericConfig, + const D: usize, + const N: usize, +>( + all_stark: &AllStark, + evm_proof: &EvmProof, + challenges: &StarkProofChallenges, + ctl_vars_per_table: &[Vec>::Extension, >::Extension, D>>; + N], + config: &StarkConfig, +) -> Result<()> { + let openings = &evm_proof.batch_proof.openings; + + // Arithmetic. + { + let stark = &all_stark.arithmetic_stark; + let table = Table::Arithmetic; + verify_opening_set::( + stark, + &openings[*table], + ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*table]], + challenges, + Some(&ctl_vars_per_table[*table]), + config, + ); + } + + // BytePacking. + { + let stark = &all_stark.byte_packing_stark; + let table = Table::BytePacking; + verify_opening_set::( + stark, + &openings[*table], + ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*table]], + challenges, + Some(&ctl_vars_per_table[*table]), + config, + ); + } + + // Cpu. + { + let stark = &all_stark.cpu_stark; + let table = Table::Cpu; + verify_opening_set::( + stark, + &openings[*table], + ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*table]], + challenges, + Some(&ctl_vars_per_table[*table]), + config, + ); + } + + // Keccak. + { + let stark = &all_stark.keccak_stark; + let table = Table::Keccak; + verify_opening_set::( + stark, + &openings[*table], + ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*table]], + challenges, + Some(&ctl_vars_per_table[*table]), + config, + ); + } + + // KeccakSponge. + { + let stark = &all_stark.keccak_sponge_stark; + let table = Table::KeccakSponge; + verify_opening_set::( + stark, + &openings[*table], + ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*table]], + challenges, + Some(&ctl_vars_per_table[*table]), + config, + ); + } + + // Logic. + { + let stark = &all_stark.logic_stark; + let table = Table::Logic; + verify_opening_set::( + stark, + &openings[*table], + ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*table]], + challenges, + Some(&ctl_vars_per_table[*table]), + config, + ); + } + + // Memory. + { + let stark = &all_stark.memory_stark; + let table = Table::Memory; + verify_opening_set::( + stark, + &openings[*table], + ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*table]], + challenges, + Some(&ctl_vars_per_table[*table]), + config, + ); + } + + // MemBefore. + { + let stark = &all_stark.mem_before_stark; + let table = Table::MemBefore; + verify_opening_set::( + stark, + &openings[*table], + ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*table]], + challenges, + Some(&ctl_vars_per_table[*table]), + config, + ); + } + + // MemAfter. + { + let stark = &all_stark.mem_after_stark; + let table = Table::MemAfter; + verify_opening_set::( + stark, + &openings[*table], + ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*table]], + challenges, + Some(&ctl_vars_per_table[*table]), + config, + ); + } + + Ok(()) +} diff --git a/evm_arithmetization/src/byte_packing/byte_packing_stark.rs b/evm_arithmetization/src/byte_packing/byte_packing_stark.rs index 6f36a889c..e9ed60d92 100644 --- a/evm_arithmetization/src/byte_packing/byte_packing_stark.rs +++ b/evm_arithmetization/src/byte_packing/byte_packing_stark.rs @@ -45,7 +45,7 @@ use starky::lookup::{Column, Filter, Lookup}; use starky::stark::Stark; use super::NUM_BYTES; -use crate::all_stark::EvmStarkFrame; +use crate::all_stark::{EvmStarkFrame, Table, ALL_DEGREE_LOGS, TABLE_TO_SORTED_INDEX}; use crate::byte_packing::columns::{ index_len, value_bytes, ADDR_CONTEXT, ADDR_SEGMENT, ADDR_VIRTUAL, IS_READ, LEN_INDICES_COLS, NUM_COLUMNS, RANGE_COUNTER, RC_FREQUENCIES, TIMESTAMP, @@ -175,7 +175,8 @@ impl, const D: usize> BytePackingStark { ops: Vec, min_rows: usize, ) -> Vec<[F; NUM_COLUMNS]> { - let num_rows = core::cmp::max(ops.len().max(BYTE_RANGE_MAX), min_rows).next_power_of_two(); + let num_rows = 1 << ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::BytePacking]]; + let mut rows = Vec::with_capacity(num_rows); for op in ops { @@ -183,6 +184,13 @@ impl, const D: usize> BytePackingStark { rows.push(self.generate_row_for_op(op)); } } + assert!(num_rows >= rows.len()); + assert!( + num_rows >= rows.len(), + "Padded length {:?} is smaller than actual trace length {:?}", + num_rows, + rows.len() + ); for _ in rows.len()..num_rows { rows.push(self.generate_padding_row()); diff --git a/evm_arithmetization/src/fixed_recursive_verifier.rs b/evm_arithmetization/src/fixed_recursive_verifier.rs index 9d39646dd..b60ec50e9 100644 --- a/evm_arithmetization/src/fixed_recursive_verifier.rs +++ b/evm_arithmetization/src/fixed_recursive_verifier.rs @@ -755,26 +755,28 @@ where // Extra sums to add to the looked last value. // Only necessary for the Memory values. - let mut extra_looking_sums = - vec![vec![builder.zero(); stark_config.num_challenges]; NUM_TABLES]; + let mut extra_looking_sums = HashMap::new(); // Memory - extra_looking_sums[*Table::Memory] = (0..stark_config.num_challenges) - .map(|c| { - get_memory_extra_looking_sum_circuit( - &mut builder, - &public_values, - ctl_challenges.challenges[c], - ) - }) - .collect_vec(); + extra_looking_sums.insert( + Table::Memory as usize, + (0..stark_config.num_challenges) + .map(|c| { + get_memory_extra_looking_sum_circuit( + &mut builder, + &public_values, + ctl_challenges.challenges[c], + ) + }) + .collect_vec(), + ); // Verify the CTL checks. verify_cross_table_lookups_circuit::( &mut builder, all_cross_table_lookups(), pis.map(|p| p.ctl_zs_first), - Some(&extra_looking_sums), + &extra_looking_sums, stark_config, ); diff --git a/evm_arithmetization/src/generation/mod.rs b/evm_arithmetization/src/generation/mod.rs index e79099e6a..9b0f56919 100644 --- a/evm_arithmetization/src/generation/mod.rs +++ b/evm_arithmetization/src/generation/mod.rs @@ -17,7 +17,7 @@ use GlobalMetadata::{ StateTrieRootDigestBefore, TransactionTrieRootDigestAfter, TransactionTrieRootDigestBefore, }; -use crate::all_stark::{AllStark, NUM_TABLES}; +use crate::all_stark::{AllStark, Table, ALL_DEGREE_LOGS, NUM_TABLES, TABLE_TO_SORTED_INDEX}; use crate::cpu::columns::CpuColumnsView; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; @@ -486,11 +486,19 @@ fn simulate_cpu( row.gas = F::from_canonical_u64(state.registers.gas_used); row.stack_len = F::from_canonical_usize(state.registers.stack_len); + let padded_len = 1 << ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::Cpu]]; + assert!( + padded_len >= state.traces.clock(), + "Padded length {:?} is smaller than actual trace length {:?}", + padded_len, + state.traces.clock() + ); + loop { - // Padding to a power of 2. + // Padding. state.push_cpu(row); row.clock += F::ONE; - if state.traces.clock().is_power_of_two() { + if state.traces.clock() == 1 << ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::Cpu]] { break; } } diff --git a/evm_arithmetization/src/keccak/keccak_stark.rs b/evm_arithmetization/src/keccak/keccak_stark.rs index 5f505cf06..85ddc8a6a 100644 --- a/evm_arithmetization/src/keccak/keccak_stark.rs +++ b/evm_arithmetization/src/keccak/keccak_stark.rs @@ -17,7 +17,7 @@ use starky::stark::Stark; use starky::util::trace_rows_to_poly_values; use super::columns::reg_input_limb; -use crate::all_stark::EvmStarkFrame; +use crate::all_stark::{EvmStarkFrame, Table, ALL_DEGREE_LOGS, TABLE_TO_SORTED_INDEX}; use crate::keccak::columns::{ reg_a, reg_a_prime, reg_a_prime_prime, reg_a_prime_prime_0_0_bit, reg_a_prime_prime_prime, reg_b, reg_c, reg_c_prime, reg_output_limb, reg_step, NUM_COLUMNS, TIMESTAMP, @@ -72,9 +72,7 @@ impl, const D: usize> KeccakStark { inputs_and_timestamps: Vec<([u64; NUM_INPUTS], usize)>, min_rows: usize, ) -> Vec<[F; NUM_COLUMNS]> { - let num_rows = (inputs_and_timestamps.len() * NUM_ROUNDS) - .max(min_rows) - .next_power_of_two(); + let num_rows = 1 << ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::Keccak]]; let mut rows = Vec::with_capacity(num_rows); for input_and_timestamp in inputs_and_timestamps.iter() { @@ -82,6 +80,13 @@ impl, const D: usize> KeccakStark { rows.extend(rows_for_perm); } + assert!( + num_rows >= rows.len(), + "Padded length {:?} is smaller than actual trace length {:?}", + num_rows, + rows.len() + ); + while rows.len() < num_rows { rows.push([F::ZERO; NUM_COLUMNS]); } diff --git a/evm_arithmetization/src/keccak_sponge/keccak_sponge_stark.rs b/evm_arithmetization/src/keccak_sponge/keccak_sponge_stark.rs index 73418c40f..b24a2bf88 100644 --- a/evm_arithmetization/src/keccak_sponge/keccak_sponge_stark.rs +++ b/evm_arithmetization/src/keccak_sponge/keccak_sponge_stark.rs @@ -4,6 +4,7 @@ use core::marker::PhantomData; use core::mem::size_of; use itertools::Itertools; +use num::integer::div_ceil; use plonky2::field::extension::{Extendable, FieldExtension}; use plonky2::field::packed::PackedField; use plonky2::field::polynomial::PolynomialValues; @@ -18,7 +19,7 @@ use starky::evaluation_frame::StarkEvaluationFrame; use starky::lookup::{Column, Filter, Lookup}; use starky::stark::Stark; -use crate::all_stark::EvmStarkFrame; +use crate::all_stark::{EvmStarkFrame, Table, ALL_DEGREE_LOGS, TABLE_TO_SORTED_INDEX}; use crate::cpu::kernel::keccak_util::keccakf_u32s; use crate::keccak_sponge::columns::*; use crate::witness::memory::MemoryAddress; @@ -289,7 +290,8 @@ impl, const D: usize> KeccakSpongeStark { rows.extend(self.generate_rows_for_op(op)); } // Pad the trace. - let padded_rows = rows.len().max(min_num_rows).next_power_of_two(); + let padded_rows = 1 << ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::KeccakSponge]]; + assert!(padded_rows >= rows.len()); for _ in rows.len()..padded_rows { rows.push(self.generate_padding_row()); } diff --git a/evm_arithmetization/src/lib.rs b/evm_arithmetization/src/lib.rs index 0f323b5d8..2213d3b34 100644 --- a/evm_arithmetization/src/lib.rs +++ b/evm_arithmetization/src/lib.rs @@ -196,6 +196,8 @@ pub mod memory_continuation; // Proving system components pub mod all_stark; +mod batch_proof; +pub mod batch_verifier; pub mod fixed_recursive_verifier; mod get_challenges; pub mod proof; diff --git a/evm_arithmetization/src/logic.rs b/evm_arithmetization/src/logic.rs index eae7c972b..6a470ee9d 100644 --- a/evm_arithmetization/src/logic.rs +++ b/evm_arithmetization/src/logic.rs @@ -17,7 +17,7 @@ use starky::lookup::{Column, Filter}; use starky::stark::Stark; use starky::util::trace_rows_to_poly_values; -use crate::all_stark::EvmStarkFrame; +use crate::all_stark::{EvmStarkFrame, Table, ALL_DEGREE_LOGS, TABLE_TO_SORTED_INDEX}; use crate::logic::columns::{LogicColumnsView, LOGIC_COL_MAP, NUM_COLUMNS}; use crate::util::{limb_from_bits_le, limb_from_bits_le_recursive}; @@ -220,7 +220,13 @@ impl LogicStark { min_rows: usize, ) -> Vec<[F; NUM_COLUMNS]> { let len = operations.len(); - let padded_len = len.max(min_rows).next_power_of_two(); + let padded_len = 1 << ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::Logic]]; + assert!( + padded_len >= len, + "Padded length {:?} is smaller than actual trace length {:?}", + padded_len, + len + ); let mut rows = Vec::with_capacity(padded_len); for op in operations { diff --git a/evm_arithmetization/src/memory/memory_stark.rs b/evm_arithmetization/src/memory/memory_stark.rs index 53d975498..9fe8236bc 100644 --- a/evm_arithmetization/src/memory/memory_stark.rs +++ b/evm_arithmetization/src/memory/memory_stark.rs @@ -21,7 +21,7 @@ use starky::stark::Stark; use super::columns::{MEM_AFTER_FILTER, STALE_CONTEXTS, STALE_CONTEXTS_FREQUENCIES}; use super::segments::Segment; -use crate::all_stark::{EvmStarkFrame, Table}; +use crate::all_stark::{EvmStarkFrame, Table, ALL_DEGREE_LOGS, TABLE_TO_SORTED_INDEX}; use crate::memory::columns::{ value_limb, ADDR_CONTEXT, ADDR_SEGMENT, ADDR_VIRTUAL, CONTEXT_FIRST_CHANGE, COUNTER, FILTER, FREQUENCIES, INITIALIZE_AUX, IS_PRUNED, IS_READ, IS_STALE, NUM_COLUMNS, RANGE_CHECK, @@ -353,7 +353,14 @@ impl, const D: usize> MemoryStark { let num_ops = memory_ops.len(); // We want at least one padding row, so that the last real operation can have // its flags set correctly. - let num_ops_padded = (num_ops + 1).next_power_of_two(); + let num_ops_padded = 1 << ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::Memory]]; + assert!( + num_ops_padded >= num_ops, + "Padded length {:?} is smaller than actual trace length {:?}", + num_ops_padded, + num_ops + ); + for _ in num_ops..num_ops_padded { memory_ops.push(padding_op); } diff --git a/evm_arithmetization/src/memory_continuation/memory_continuation_stark.rs b/evm_arithmetization/src/memory_continuation/memory_continuation_stark.rs index 72c869b61..dec047cce 100644 --- a/evm_arithmetization/src/memory_continuation/memory_continuation_stark.rs +++ b/evm_arithmetization/src/memory_continuation/memory_continuation_stark.rs @@ -20,7 +20,7 @@ use starky::lookup::{Column, Filter, Lookup}; use starky::stark::Stark; use super::columns::{value_limb, ADDR_CONTEXT, ADDR_SEGMENT, ADDR_VIRTUAL, FILTER, NUM_COLUMNS}; -use crate::all_stark::EvmStarkFrame; +use crate::all_stark::{EvmStarkFrame, Table}; use crate::generation::MemBeforeValues; use crate::memory::VALUE_LIMBS; @@ -79,13 +79,21 @@ impl, const D: usize> MemoryContinuationStark pub(crate) fn generate_trace( &self, propagated_values: Vec>, + log_padded: usize, ) -> Vec> { // Set the trace to the `propagated_values` provided either by `MemoryStark` // (for final values) or the previous segment (for initial values). let mut rows = propagated_values; let num_rows = rows.len(); - let num_rows_padded = max(128, num_rows.next_power_of_two()); + let num_rows_padded = 1 << log_padded; + assert!( + num_rows_padded >= num_rows, + "Padded length {:?} is smaller than actual trace length {:?}", + num_rows_padded, + num_rows + ); + for _ in num_rows..num_rows_padded { rows.push(vec![F::ZERO; NUM_COLUMNS]); } diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index 6ab08896f..5a35580f3 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -1,35 +1,64 @@ +use std::any::type_name; +use std::iter::once; +use std::mem::swap; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; +use std::thread::current; -use anyhow::{anyhow, Result}; +use anyhow::{anyhow, ensure, Result}; use itertools::Itertools; use once_cell::sync::Lazy; -use plonky2::field::extension::Extendable; +use plonky2::batch_fri::oracle::BatchFriOracle; +use plonky2::field::extension::{Extendable, FieldExtension}; use plonky2::field::goldilocks_field::GoldilocksField; -use plonky2::field::polynomial::PolynomialValues; +use plonky2::field::packable::Packable; +use plonky2::field::packed::PackedField; +use plonky2::field::polynomial::{PolynomialCoeffs, PolynomialValues}; use plonky2::field::types::Field; use plonky2::fri::oracle::PolynomialBatch; +use plonky2::fri::reduction_strategies::FriReductionStrategy; +use plonky2::fri::structure::{FriBatchInfo, FriInstanceInfo, FriOpeningBatch, FriOracleInfo}; +use plonky2::fri::FriConfig; use plonky2::hash::hash_types::RichField; use plonky2::hash::merkle_tree::MerkleCap; use plonky2::iop::challenger::Challenger; use plonky2::plonk::config::{GenericConfig, GenericHashOut}; +use plonky2::plonk::proof::ProofWithPublicInputs; use plonky2::timed; use plonky2::util::timing::TimingTree; +use plonky2_maybe_rayon::*; use serde::{Deserialize, Serialize}; +use starky::batch_proof::{BatchStarkProof, BatchStarkProofWithPublicInputs}; use starky::config::StarkConfig; -use starky::cross_table_lookup::{get_ctl_data, CtlData}; -use starky::lookup::GrandProductChallengeSet; -use starky::proof::{MultiProof, StarkProofWithMetadata}; -use starky::prover::prove_with_commitment; +use starky::cross_table_lookup::{ + get_ctl_auxiliary_polys, get_ctl_data, num_ctl_helper_columns_by_table, CtlData, +}; +use starky::lookup::{lookup_helper_columns, GrandProductChallengeSet}; +use starky::proof::{ + MultiProof, StarkOpeningSet, StarkProof, StarkProofWithMetadata, StarkProofWithPublicInputs, +}; +use starky::prover::{compute_quotient_polys, prove_with_commitment}; use starky::stark::Stark; -use crate::all_stark::{AllStark, Table, NUM_TABLES}; +use crate::all_stark::{ + all_cross_table_lookups, AllStark, Table, ALL_DEGREE_LOGS, ALL_SORTED_TABLES, NUM_TABLES, + SORTED_INDEX_PAIR, TABLE_TO_SORTED_INDEX, +}; +use crate::arithmetic::arithmetic_stark::ArithmeticStark; +use crate::batch_proof::EvmProof; +use crate::byte_packing::byte_packing_stark::BytePackingStark; +use crate::cpu::cpu_stark::CpuStark; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::interpreter::{set_registers_and_run, ExtraSegmentData, Interpreter}; use crate::generation::state::{GenerationState, State}; use crate::generation::{generate_traces, GenerationInputs}; use crate::get_challenges::observe_public_values; +use crate::keccak::keccak_stark::KeccakStark; +use crate::keccak_sponge::keccak_sponge_stark::KeccakSpongeStark; +use crate::logic::LogicStark; +use crate::memory::memory_stark::MemoryStark; use crate::memory::segments::Segment; +use crate::memory_continuation::memory_continuation_stark::MemoryContinuationStark; use crate::proof::{AllProof, MemCap, PublicValues, RegistersData}; use crate::witness::memory::{MemoryAddress, MemoryState}; use crate::witness::state::RegistersState; @@ -66,6 +95,40 @@ impl GenerationSegmentData { } } +pub fn zkevm_fast_config() -> StarkConfig { + let cap_height = 4; + let mut strategy = Vec::new(); + for window in ALL_DEGREE_LOGS.windows(2) { + if window[0] != window[1] { + strategy.push(window[0] - window[1]); + } + } + let mut last_degree = ALL_DEGREE_LOGS[NUM_TABLES - 1]; + while last_degree > cap_height { + if last_degree >= cap_height + 4 { + strategy.push(4); + last_degree -= 4; + } else { + strategy.push(last_degree - cap_height); + last_degree = cap_height; + } + } + + StarkConfig { + security_bits: 100, + num_challenges: 2, + fri_config: FriConfig { + rate_bits: 1, + cap_height, + proof_of_work_bits: 16, + // This strategy allows us to hit all intermediary STARK leaves while going through the + // batched Field Merkle Trees. + reduction_strategy: FriReductionStrategy::Fixed(strategy), + num_query_rounds: 84, + }, + } +} + /// Generate traces, then create all STARK proofs. pub fn prove( all_stark: &AllStark, @@ -101,6 +164,40 @@ where Ok(proof) } +/// Generate traces, then create all STARK proofs. +pub fn prove_batch( + all_stark: &AllStark, + config: &StarkConfig, + inputs: GenerationInputs, + segment_data: &mut GenerationSegmentData, + timing: &mut TimingTree, + abort_signal: Option>, +) -> Result> +where + F: RichField + Extendable, + C: GenericConfig, + P: PackedField, +{ + timed!(timing, "build kernel", Lazy::force(&KERNEL)); + + let (mut traces, mut public_values) = timed!( + timing, + "generate all traces", + generate_traces(all_stark, &inputs, config, segment_data, timing)? + ); + + check_abort_signal(abort_signal.clone())?; + + prove_with_traces_batch::( + all_stark, + config, + &mut traces, + &public_values, + timing, + abort_signal, + ) +} + /// Compute all STARK proofs. pub(crate) fn prove_with_traces( all_stark: &AllStark, @@ -249,6 +346,1242 @@ type ProofWithMemCaps = ( MerkleCap, ); +/// Compute all STARK proofs. STARK-batching version. +pub(crate) fn prove_with_traces_batch( + all_stark: &AllStark, + config: &StarkConfig, + mut trace_poly_values: &mut [Vec>; NUM_TABLES], + public_values: &PublicValues, + timing: &mut TimingTree, + abort_signal: Option>, +) -> Result> +where + F: RichField + Extendable, + P: PackedField, + C: GenericConfig, +{ + let rate_bits = config.fri_config.rate_bits; + let cap_height = config.fri_config.cap_height; + + // println!("Mem after trace poly degrees:"); + // for poly in trace_poly_values[*Table::MemAfter].iter() { + // print!("{} ", poly.degree_plus_one()); + // } + + // We compute the Field Merkle Tree of all STARK traces. + reorder_slice(trace_poly_values, Table::all(), ALL_SORTED_TABLES); + let num_trace_polys_sorted_per_table: [usize; NUM_TABLES] = trace_poly_values + .iter() + .map(|polys| polys.len()) + .collect::>() + .try_into() + .unwrap(); + let trace_polys_values_sorted_flat: Vec<_> = + trace_poly_values.clone().into_iter().flatten().collect(); + let num_trace_polys = trace_polys_values_sorted_flat.len(); + let trace_commitment = timed!( + timing, + "compute trace commitments", + BatchFriOracle::::from_values( + trace_polys_values_sorted_flat, + rate_bits, + false, + cap_height, + timing, + &vec![None; num_trace_polys], + ) + ); + + let mut challenger = Challenger::::new(); + challenger.observe_cap(&trace_commitment.batch_merkle_tree.cap); + + observe_public_values::(&mut challenger, &public_values) + .map_err(|_| anyhow::Error::msg("Invalid conversion of public values."))?; + + // For each STARK, compute its cross-table lookup Z polynomials and get the + // associated `CtlData`. + // We need `trace_poly_values` in canonical order. We will sort it again + // afterwards. + reorder_slice(trace_poly_values, ALL_SORTED_TABLES, Table::all()); + let (ctl_challenges, ctl_data_per_table) = timed!( + timing, + "compute CTL data", + get_ctl_data::( + config, + &trace_poly_values, + &all_stark.cross_table_lookups, + &mut challenger, + all_stark.arithmetic_stark.constraint_degree() + ) + ); + + println!("CTL DATA:"); + for i in 0..NUM_TABLES { + println!( + "table {}: {} Zs polys", + i, + ctl_data_per_table[i].zs_columns.len() + ); + } + + check_abort_signal(abort_signal)?; + let lookup_challenges = ctl_challenges + .challenges + .iter() + .map(|ch| ch.beta) + .collect::>(); + + let mut auxiliary_columns = all_auxiliary_columns::( + all_stark, + config, + &trace_poly_values, + &ctl_data_per_table, + &ctl_challenges, + ); + // From now on we need `trace_poly_values` sorted again. + reorder_slice(trace_poly_values, Table::all(), ALL_SORTED_TABLES); + + // println!("Mem after aux poly degrees:"); + // for poly in auxiliary_columns[*Table::MemAfter].iter() { + // print!("{} ", poly.degree_plus_one()); + // } + // We compute the Field Merkle Tree of all auxiliary columns. + reorder_slice( + auxiliary_columns.as_mut_slice(), + Table::all(), + ALL_SORTED_TABLES, + ); + let num_auxiliary_columns_sorted_per_table: [usize; NUM_TABLES] = auxiliary_columns + .iter() + .map(|polys| polys.len()) + .collect::>() + .try_into() + .unwrap(); + let auxiliary_columns_sorted_flat: Vec<_> = + auxiliary_columns.clone().into_iter().flatten().collect(); + let num_aux_polys = auxiliary_columns_sorted_flat.len(); + let auxiliary_commitment = timed!( + timing, + "compute auxiliary commitments", + BatchFriOracle::::from_values( + auxiliary_columns_sorted_flat, + rate_bits, + false, + cap_height, + timing, + &vec![None; num_aux_polys], + ) + ); + challenger.observe_cap(&auxiliary_commitment.batch_merkle_tree.cap); + + // Quotient polynomials. They are already chunked in `degree` pieces. + let alphas = challenger.get_n_challenges(config.num_challenges); + let mut quotient_polys = all_quotient_polys::( + all_stark, + &trace_poly_values, + &trace_commitment, + &auxiliary_columns, + &auxiliary_commitment, + None, + &ctl_data_per_table, + alphas.clone(), + config, + ); + + // We compute the Field Merkle Tree of all quotient polynomials. + reorder_slice( + quotient_polys.as_mut_slice(), + Table::all(), + ALL_SORTED_TABLES, + ); + let num_quotient_polys_sorted_per_table: [usize; NUM_TABLES] = quotient_polys + .iter() + .map(|polys| polys.len()) + .collect::>() + .try_into() + .unwrap(); + let quotient_polys_sorted_flat: Vec<_> = quotient_polys.clone().into_iter().flatten().collect(); + let num_quotient_polys = quotient_polys_sorted_flat.len(); + let quotient_commitment = timed!( + timing, + "compute quotient commitments", + BatchFriOracle::::from_coeffs( + quotient_polys_sorted_flat, + rate_bits, + false, + cap_height, + timing, + &vec![None; num_quotient_polys], + ) + ); + challenger.observe_cap("ient_commitment.batch_merkle_tree.cap); + + let zeta = challenger.get_extension_challenge::(); + + // To avoid leaking witness data, we want to ensure that our opening locations, + // `zeta` and `g * zeta`, are not in our subgroup `H`. It suffices to check + // `zeta` only, since `(g * zeta)^n = zeta^n`, where `n` is the order of + // `g`. + let degree_bits = trace_commitment.degree_bits[0]; + let g: F = F::primitive_root_of_unity(degree_bits); + ensure!( + zeta.exp_power_of_2(degree_bits) != F::Extension::ONE, + "Opening point is in the subgroup." + ); + + // let all_ctl_helper_columns = num_ctl_helper_columns_by_table( + // &all_stark.cross_table_lookups, + // all_stark.arithmetic_stark.constraint_degree(), + // ); + // let num_ctl_helper_columns_per_table = (0..NUM_TABLES) + // .map(|i| { + // all_ctl_helper_columns + // .iter() + // .map(|ctl_cols: &[usize; NUM_TABLES]| ctl_cols[i]) + // .sum() + // }) + // .collect::>() + // .try_into() + // .unwrap(); + + let num_ctl_helper_columns_per_table = Table::all() + .iter() + .map(|&table| { + ctl_data_per_table[*table] + .num_ctl_helper_polys() + .iter() + .sum() + }) + .collect::>() + .try_into() + .unwrap(); + + let all_fri_instances = all_fri_instance_info::( + all_stark, + zeta, + &num_trace_polys_sorted_per_table, + &num_auxiliary_columns_sorted_per_table, + &num_quotient_polys_sorted_per_table, + &num_ctl_helper_columns_per_table, + config, + ); + + // println!("Prover FRI instances:\n{:#?}", all_fri_instances); + + // Get the FRI openings and observe them. + // Compute all openings: evaluate all committed polynomials at `zeta` and, when + // necessary, at `g * zeta`. + let openings = all_openings( + all_stark, + &trace_poly_values, + &trace_commitment, + &auxiliary_columns, + &auxiliary_commitment, + "ient_polys, + "ient_commitment, + &ctl_data_per_table, + zeta, + config, + ); + + for opening in openings.iter() { + challenger.observe_openings(&opening.to_fri_openings()); + } + + let initial_merkle_trees = [ + &trace_commitment, + &auxiliary_commitment, + "ient_commitment, + ]; + + // println!("First instance: {:?}", all_fri_instances[0]) + // println!("First instance oracles: {:?}", all_fri_instances[0].oracles); + // println!("Second instance : {:?}", all_fri_instances[1]); + // for batch in all_fri_instances[1].batches.iter() { + // println!("New batch:"); + // for poly in batch.polynomials.iter() { + // print!( + // "{} ", + // + // initial_merkle_trees[poly.oracle_index].polynomials[poly.polynomial_index] + // .degree_plus_one() + // ) + // } + // } + + let mut degree_bits_squashed = ALL_DEGREE_LOGS.to_vec(); + degree_bits_squashed.dedup(); + assert_eq!(all_fri_instances.len(), degree_bits_squashed.len()); + + // BIG VERIF + for (i, instance) in all_fri_instances.iter().enumerate() { + let n = 1 << degree_bits_squashed[i]; + for ( + j, + &FriBatchInfo { + point, + ref polynomials, + }, + ) in instance.batches.iter().enumerate() + { + for poly in polynomials { + let d_p_one = initial_merkle_trees[poly.oracle_index].polynomials + [poly.polynomial_index] + .degree_plus_one(); + assert!( + d_p_one <= n, + "Problem at instance {}, batch {}, oracle {}, poly {}, d_p_one = {} while n = {}", + i, + j, + poly.oracle_index, + poly.polynomial_index, + d_p_one, + n, + ); + } + } + } + + let opening_proof = BatchFriOracle::prove_openings( + °ree_bits_squashed, + &all_fri_instances, + &initial_merkle_trees, + &mut challenger, + &config.fri_params(degree_bits), + timing, + ); + + // This is an expensive check, hence is only run when `debug_assertions` are + // enabled. + #[cfg(debug_assertions)] + { + use hashbrown::HashMap; + use starky::cross_table_lookup::debug_utils::check_ctls; + + use crate::verifier::debug_utils::get_memory_extra_looking_values; + + let mut extra_values = HashMap::new(); + extra_values.insert( + *Table::Memory, + get_memory_extra_looking_values(&public_values), + ); + check_ctls( + trace_poly_values, + &all_stark.cross_table_lookups, + &extra_values, + ); + } + + let batch_proof = BatchStarkProof { + trace_cap: trace_commitment.batch_merkle_tree.cap.clone(), + auxiliary_polys_cap: Some(auxiliary_commitment.batch_merkle_tree.cap), + quotient_polys_cap: Some(quotient_commitment.batch_merkle_tree.cap), + openings, + opening_proof, + }; + + Ok(EvmProof { + batch_proof, + public_values: public_values.clone(), + }) +} + +/// Generates all auxiliary columns. +fn all_auxiliary_columns( + all_stark: &AllStark, + config: &StarkConfig, + trace_poly_values: &[Vec>; NUM_TABLES], + ctl_data_per_table: &[CtlData; NUM_TABLES], + ctl_challenges: &GrandProductChallengeSet, +) -> Vec>> +where + F: RichField + Extendable, + C: GenericConfig, +{ + let mut res = Vec::with_capacity(NUM_TABLES); + + // Arithmetic. + res.push(auxiliary_columns_single_stark::< + F, + C, + ArithmeticStark, + D, + >( + all_stark.arithmetic_stark, + config, + &trace_poly_values[*Table::Arithmetic], + &ctl_data_per_table[*Table::Arithmetic], + ctl_challenges, + )); + + // BytePacking. + res.push(auxiliary_columns_single_stark::< + F, + C, + BytePackingStark, + D, + >( + all_stark.byte_packing_stark, + config, + &trace_poly_values[*Table::BytePacking], + &ctl_data_per_table[*Table::BytePacking], + ctl_challenges, + )); + + // Cpu. + res.push(auxiliary_columns_single_stark::, D>( + all_stark.cpu_stark, + config, + &trace_poly_values[*Table::Cpu], + &ctl_data_per_table[*Table::Cpu], + ctl_challenges, + )); + + // Keccak. + res.push( + auxiliary_columns_single_stark::, D>( + all_stark.keccak_stark, + config, + &trace_poly_values[*Table::Keccak], + &ctl_data_per_table[*Table::Keccak], + ctl_challenges, + ), + ); + + // KeccakSponge. + res.push(auxiliary_columns_single_stark::< + F, + C, + KeccakSpongeStark, + D, + >( + all_stark.keccak_sponge_stark, + config, + &trace_poly_values[*Table::KeccakSponge], + &ctl_data_per_table[*Table::KeccakSponge], + ctl_challenges, + )); + + // Logic. + res.push(auxiliary_columns_single_stark::, D>( + all_stark.logic_stark, + config, + &trace_poly_values[*Table::Logic], + &ctl_data_per_table[*Table::Logic], + ctl_challenges, + )); + + // Memory. + res.push( + auxiliary_columns_single_stark::, D>( + all_stark.memory_stark, + config, + &trace_poly_values[*Table::Memory], + &ctl_data_per_table[*Table::Memory], + ctl_challenges, + ), + ); + + // MemBefore. + res.push(auxiliary_columns_single_stark::< + F, + C, + MemoryContinuationStark, + D, + >( + all_stark.mem_before_stark, + config, + &trace_poly_values[*Table::MemBefore], + &ctl_data_per_table[*Table::MemBefore], + ctl_challenges, + )); + + // MemAfter. + res.push(auxiliary_columns_single_stark::< + F, + C, + MemoryContinuationStark, + D, + >( + all_stark.mem_before_stark, + config, + &trace_poly_values[*Table::MemAfter], + &ctl_data_per_table[*Table::MemAfter], + ctl_challenges, + )); + + res +} + +fn auxiliary_columns_single_stark( + stark: S, + config: &StarkConfig, + trace_poly_values: &[PolynomialValues], + ctl_data: &CtlData, + ctl_challenges: &GrandProductChallengeSet, +) -> Vec> +where + F: RichField + Extendable, + C: GenericConfig, + S: Stark, +{ + let rate_bits = config.fri_config.rate_bits; + let constraint_degree = stark.constraint_degree(); + assert!( + constraint_degree <= (1 << rate_bits) + 1, + "The degree of the Stark constraints must be <= blowup_factor + 1" + ); + + // Add lookup columns. + let lookups = stark.lookups(); + let mut res = { + let mut columns = Vec::new(); + for lookup in &lookups { + for &challenge in ctl_challenges.challenges.iter() { + columns.extend(lookup_helper_columns( + lookup, + trace_poly_values, + challenge.beta, + constraint_degree, + )); + } + } + columns + }; + let num_lookup_columns = res.len(); + + // Add CTL columns. + if let Some(p) = get_ctl_auxiliary_polys(Some(ctl_data)) { + res.extend(p); + } + + debug_assert!( + (stark.uses_lookups() || stark.requires_ctls()) || get_ctl_auxiliary_polys(Some(ctl_data)).is_none(), + "There should be auxiliary polynomials if and only if we have either lookups or require cross-table lookups." + ); + + res +} + +fn quotient_polys_single_stark( + table: Table, + stark: &S, + trace_poly_values_sorted: &[Vec>; NUM_TABLES], + trace_commitment: &BatchFriOracle, + auxiliary_columns_sorted: &Vec>>, + auxiliary_commitment: &BatchFriOracle, + lookup_challenges: Option<&Vec>, + ctl_data_per_table: &[CtlData; NUM_TABLES], + alphas: Vec, + config: &StarkConfig, +) -> Vec> +where + F: RichField + Extendable, + P: PackedField, + C: GenericConfig, + S: Stark, +{ + let degree_bits = ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*table]]; + let (index_outer, index_inner) = SORTED_INDEX_PAIR[TABLE_TO_SORTED_INDEX[*table]]; + let mut num_trace_polys_before = 0; + let mut num_aux_polys_before = 0; + for i in 0..index_inner { + let prev_sorted_table = TABLE_TO_SORTED_INDEX[*table] - i - 1; + num_trace_polys_before += trace_poly_values_sorted[prev_sorted_table].len(); + num_aux_polys_before += auxiliary_columns_sorted[prev_sorted_table].len(); + } + let trace_leave_len = trace_poly_values_sorted[TABLE_TO_SORTED_INDEX[*table]].len(); + let get_trace_packed = |index, step| { + trace_commitment.get_lde_values_packed::

( + index_outer, + index, + step, + num_trace_polys_before, + trace_leave_len, + ) + }; + let aux_leave_len = auxiliary_columns_sorted[TABLE_TO_SORTED_INDEX[*table]].len(); + let get_aux_packed = |index, step| { + auxiliary_commitment.get_lde_values_packed( + index_outer, + index, + step, + num_aux_polys_before, + aux_leave_len, + ) + }; + + let quotient_polys = compute_quotient_polys::( + stark, + &get_trace_packed, + &get_aux_packed, + lookup_challenges, + Some(&ctl_data_per_table[*table]), + &vec![], + alphas, + degree_bits, + stark.num_lookup_helper_columns(config), + config, + ) + .expect("Couldn't compute quotient polys."); + + // Chunk the quotient polynomials. + let degree = 1 << degree_bits; + quotient_polys + .into_par_iter() + .flat_map(|mut quotient_poly| { + quotient_poly + .trim_to_len(degree * stark.quotient_degree_factor()) + .expect("Quotient has failed, the vanishing polynomial is not divisible by Z_H"); + // Split quotient into degree-n chunks. + quotient_poly.chunks(degree) + }) + .collect() +} + +/// Generates all quotient polynomials. +fn all_quotient_polys( + all_stark: &AllStark, + trace_poly_values_sorted: &[Vec>; NUM_TABLES], + trace_commitment: &BatchFriOracle, + auxiliary_columns_sorted: &Vec>>, + auxiliary_commitment: &BatchFriOracle, + lookup_challenges: Option<&Vec>, + ctl_data_per_table: &[CtlData; NUM_TABLES], + alphas: Vec, + config: &StarkConfig, +) -> Vec>> +where + F: RichField + Extendable, + P: PackedField, + C: GenericConfig, +{ + let mut res = Vec::with_capacity(NUM_TABLES); + + // Arithmetic. + res.push(quotient_polys_single_stark::( + Table::Arithmetic, + &all_stark.arithmetic_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + lookup_challenges, + ctl_data_per_table, + alphas.clone(), + config, + )); + + // Bytepacking. + res.push(quotient_polys_single_stark::( + Table::BytePacking, + &all_stark.byte_packing_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + lookup_challenges, + ctl_data_per_table, + alphas.clone(), + config, + )); + + // Cpu. + res.push(quotient_polys_single_stark::( + Table::Cpu, + &all_stark.cpu_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + lookup_challenges, + ctl_data_per_table, + alphas.clone(), + config, + )); + + // Keccak. + res.push(quotient_polys_single_stark::( + Table::Keccak, + &all_stark.keccak_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + lookup_challenges, + ctl_data_per_table, + alphas.clone(), + config, + )); + + // KeccakSponge. + res.push(quotient_polys_single_stark::( + Table::KeccakSponge, + &all_stark.keccak_sponge_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + lookup_challenges, + ctl_data_per_table, + alphas.clone(), + config, + )); + + // Logic. + res.push(quotient_polys_single_stark::( + Table::Logic, + &all_stark.logic_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + lookup_challenges, + ctl_data_per_table, + alphas.clone(), + config, + )); + // Memory. + res.push(quotient_polys_single_stark::( + Table::Memory, + &all_stark.memory_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + lookup_challenges, + ctl_data_per_table, + alphas.clone(), + config, + )); + + // MemBefore. + res.push(quotient_polys_single_stark::( + Table::MemBefore, + &all_stark.mem_before_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + lookup_challenges, + ctl_data_per_table, + alphas.clone(), + config, + )); + + // MemAfter. + res.push(quotient_polys_single_stark::( + Table::MemAfter, + &all_stark.mem_after_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + lookup_challenges, + ctl_data_per_table, + alphas.clone(), + config, + )); + + res +} + +/// Generates all FRI instances. They are sorted by decreasing degree. +fn fri_instance_info_single_stark( + table: Table, + stark: &S, + zeta: F::Extension, + num_trace_polys_sorted: &[usize; NUM_TABLES], + num_auxiliary_columns_sorted: &[usize; NUM_TABLES], + num_quotient_polys_sorted: &[usize; NUM_TABLES], + num_ctl_helper_columns_per_table: &[usize; NUM_TABLES], + config: &StarkConfig, +) -> FriInstanceInfo +where + F: RichField + Extendable, + C: GenericConfig, + S: Stark, +{ + let sorted_index = TABLE_TO_SORTED_INDEX[*table]; + let g = F::primitive_root_of_unity(ALL_DEGREE_LOGS[sorted_index]); + let num_ctl_helper_polys = num_ctl_helper_columns_per_table[*table]; + let mut num_trace_polys_before = 0; + let mut num_aux_polys_before = 0; + let mut num_quotient_polys_before = 0; + for i in 0..sorted_index { + num_trace_polys_before += num_trace_polys_sorted[i]; + num_aux_polys_before += num_auxiliary_columns_sorted[i]; + num_quotient_polys_before += num_quotient_polys_sorted[i]; + } + let num_aux_columns = num_auxiliary_columns_sorted[sorted_index]; + let num_quotient_polys = num_quotient_polys_sorted[sorted_index]; + let num_cols_before_ctlzs = + num_aux_polys_before + stark.num_lookup_helper_columns(config) + num_ctl_helper_polys; + + println!( + "table {:?}, {} CTLZ polys", + table, + num_aux_columns - stark.num_lookup_helper_columns(config) - num_ctl_helper_polys + ); + + stark.fri_instance_batch( + zeta, + g, + num_trace_polys_before, + num_aux_polys_before, + num_aux_columns, + num_quotient_polys_before, + num_quotient_polys, + num_cols_before_ctlzs, + ) +} + +/// Generates all FRI instances. They are sorted by decreasing degree. +pub(crate) fn all_fri_instance_info( + all_stark: &AllStark, + zeta: F::Extension, + num_trace_polys_sorted: &[usize; NUM_TABLES], + num_auxiliary_columns_sorted: &[usize; NUM_TABLES], + num_quotient_polys_sorted: &[usize; NUM_TABLES], + num_ctl_helper_columns_per_table: &[usize; NUM_TABLES], + config: &StarkConfig, +) -> Vec> +where + F: RichField + Extendable, + C: GenericConfig, +{ + let mut res = Vec::with_capacity(NUM_TABLES); + + // Arithmetic. + res.push(fri_instance_info_single_stark::( + Table::Arithmetic, + &all_stark.arithmetic_stark, + zeta, + num_trace_polys_sorted, + num_auxiliary_columns_sorted, + num_quotient_polys_sorted, + num_ctl_helper_columns_per_table, + config, + )); + + // BytePacking. + res.push(fri_instance_info_single_stark::( + Table::BytePacking, + &all_stark.byte_packing_stark, + zeta, + num_trace_polys_sorted, + num_auxiliary_columns_sorted, + num_quotient_polys_sorted, + num_ctl_helper_columns_per_table, + config, + )); + + // Cpu. + res.push(fri_instance_info_single_stark::( + Table::Cpu, + &all_stark.cpu_stark, + zeta, + num_trace_polys_sorted, + num_auxiliary_columns_sorted, + num_quotient_polys_sorted, + num_ctl_helper_columns_per_table, + config, + )); + + // Keccak. + res.push(fri_instance_info_single_stark::( + Table::Keccak, + &all_stark.keccak_stark, + zeta, + num_trace_polys_sorted, + num_auxiliary_columns_sorted, + num_quotient_polys_sorted, + num_ctl_helper_columns_per_table, + config, + )); + + // KeccakSponge. + res.push(fri_instance_info_single_stark::( + Table::KeccakSponge, + &all_stark.keccak_sponge_stark, + zeta, + num_trace_polys_sorted, + num_auxiliary_columns_sorted, + num_quotient_polys_sorted, + num_ctl_helper_columns_per_table, + config, + )); + + // Logic. + res.push(fri_instance_info_single_stark::( + Table::Logic, + &all_stark.logic_stark, + zeta, + num_trace_polys_sorted, + num_auxiliary_columns_sorted, + num_quotient_polys_sorted, + num_ctl_helper_columns_per_table, + config, + )); + + // Memory. + res.push(fri_instance_info_single_stark::( + Table::Memory, + &all_stark.memory_stark, + zeta, + num_trace_polys_sorted, + num_auxiliary_columns_sorted, + num_quotient_polys_sorted, + num_ctl_helper_columns_per_table, + config, + )); + + // MemBefore. + res.push(fri_instance_info_single_stark::( + Table::MemBefore, + &all_stark.mem_before_stark, + zeta, + num_trace_polys_sorted, + num_auxiliary_columns_sorted, + num_quotient_polys_sorted, + num_ctl_helper_columns_per_table, + config, + )); + + // MemAfter. + res.push(fri_instance_info_single_stark::( + Table::MemAfter, + &all_stark.mem_after_stark, + zeta, + num_trace_polys_sorted, + num_auxiliary_columns_sorted, + num_quotient_polys_sorted, + num_ctl_helper_columns_per_table, + config, + )); + + let res_sorted: Vec<_> = ALL_SORTED_TABLES + .iter() + .map(|&table| res[*table].clone()) + .collect(); + + let mut squashed_res = Vec::new(); + let mut i = 0; + let mut g = F::primitive_root_of_unity(ALL_DEGREE_LOGS[0]); + let mut current_instance = FriInstanceInfo { + oracles: vec![ + FriOracleInfo { + num_polys: 0, + blinding: false, + }, + FriOracleInfo { + num_polys: 0, + blinding: false, + }, + FriOracleInfo { + num_polys: 0, + blinding: false, + }, + ], + batches: vec![ + FriBatchInfo { + point: zeta, + polynomials: Vec::new(), + }, + FriBatchInfo { + point: zeta.scalar_mul(g), + polynomials: Vec::new(), + }, + FriBatchInfo { + point: F::Extension::ONE, + polynomials: Vec::new(), + }, + ], + }; + + while i < NUM_TABLES { + let instance = &res_sorted[i]; + // println!("Sorted instance {}", i); + // for batch in instance.batches.iter() { + // println!("Batch of {}", batch.polynomials.len()); + // } + // println!("Sorted instance {}, batches: {:?}", i, instance.batches); + for (k, oracle) in instance.oracles.iter().enumerate() { + current_instance.oracles[k].num_polys += oracle.num_polys; + } + for (current_batch, table_batch) in current_instance + .batches + .iter_mut() + .zip_eq(instance.batches.iter()) + { + assert_eq!(current_batch.point, table_batch.point, "i={}", i); + current_batch + .polynomials + .extend(table_batch.polynomials.iter()); + } + // current_instance.batches.extend(instance.batches.clone()); + + if i == NUM_TABLES - 1 || ALL_DEGREE_LOGS[i + 1] < ALL_DEGREE_LOGS[i] { + println!("Squashed instance {}", squashed_res.len()); + for batch in current_instance.batches.iter() { + println!("Batch of {}", batch.polynomials.len()); + } + + for batch in current_instance.batches.iter_mut() { + batch.polynomials.sort_by_key(|p| p.oracle_index); + } + + squashed_res.push(current_instance.clone()); + if i < NUM_TABLES - 1 { + g = F::primitive_root_of_unity(ALL_DEGREE_LOGS[i + 1]); + current_instance = FriInstanceInfo { + oracles: vec![ + FriOracleInfo { + num_polys: 0, + blinding: false, + }, + FriOracleInfo { + num_polys: 0, + blinding: false, + }, + FriOracleInfo { + num_polys: 0, + blinding: false, + }, + ], + batches: vec![ + FriBatchInfo { + point: zeta, + polynomials: Vec::new(), + }, + FriBatchInfo { + point: zeta.scalar_mul(g), + polynomials: Vec::new(), + }, + FriBatchInfo { + point: F::Extension::ONE, + polynomials: Vec::new(), + }, + ], + }; + } + // current_instance.batches = vec![]; + } + i += 1; + } + + squashed_res +} + +fn all_openings_single_stark( + table: Table, + stark: &S, + trace_poly_values_sorted: &[Vec>; NUM_TABLES], + trace_commitment: &BatchFriOracle, + auxiliary_columns_sorted: &Vec>>, + auxiliary_commitment: &BatchFriOracle, + quotient_polys_sorted: &Vec>>, + quotient_commitment: &BatchFriOracle, + ctl_data_per_table: &[CtlData; NUM_TABLES], + zeta: F::Extension, + config: &StarkConfig, +) -> StarkOpeningSet +where + F: RichField + Extendable, + C: GenericConfig, + S: Stark, +{ + let g = F::primitive_root_of_unity(ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*table]]); + let table_sorted_index = TABLE_TO_SORTED_INDEX[*table]; + // let (_, index_inner) = SORTED_INDEX_PAIR[table_sorted_index]; + let mut num_trace_polys_before = 0; + let mut num_aux_polys_before = 0; + let mut num_quotient_polys_before = 0; + for i in 0..table_sorted_index { + let prev_sorted_table = TABLE_TO_SORTED_INDEX[*table] - i - 1; + num_trace_polys_before += trace_poly_values_sorted[i].len(); + num_aux_polys_before += auxiliary_columns_sorted[i].len(); + num_quotient_polys_before += quotient_polys_sorted[i].len(); + } + + StarkOpeningSet::new_from_batch( + stark, + zeta, + g, + trace_commitment, + num_trace_polys_before + ..(num_trace_polys_before + trace_poly_values_sorted[table_sorted_index].len()), + auxiliary_commitment, + num_aux_polys_before + ..(num_aux_polys_before + auxiliary_columns_sorted[table_sorted_index].len()), + quotient_commitment, + num_quotient_polys_before + ..(num_quotient_polys_before + quotient_polys_sorted[table_sorted_index].len()), + stark.num_lookup_helper_columns(config), + &ctl_data_per_table[*table].num_ctl_helper_polys(), + ) +} + +/// Generates all opening sets. +fn all_openings( + all_stark: &AllStark, + trace_poly_values_sorted: &[Vec>; NUM_TABLES], + trace_commitment: &BatchFriOracle, + auxiliary_columns_sorted: &Vec>>, + auxiliary_commitment: &BatchFriOracle, + quotient_polys_sorted: &Vec>>, + quotient_commitment: &BatchFriOracle, + ctl_data_per_table: &[CtlData; NUM_TABLES], + zeta: F::Extension, + config: &StarkConfig, +) -> Vec> +where + F: RichField + Extendable, + C: GenericConfig, +{ + let degree_bits = ALL_DEGREE_LOGS; + let mut res = Vec::new(); + + // Arithmetic. + res.push(all_openings_single_stark( + Table::Arithmetic, + &all_stark.arithmetic_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + quotient_polys_sorted, + quotient_commitment, + ctl_data_per_table, + zeta, + config, + )); + + // Bytepacking. + res.push(all_openings_single_stark( + Table::BytePacking, + &all_stark.byte_packing_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + quotient_polys_sorted, + quotient_commitment, + ctl_data_per_table, + zeta, + config, + )); + + // Cpu. + res.push(all_openings_single_stark( + Table::Cpu, + &all_stark.cpu_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + quotient_polys_sorted, + quotient_commitment, + ctl_data_per_table, + zeta, + config, + )); + + // Keccak. + res.push(all_openings_single_stark( + Table::Keccak, + &all_stark.keccak_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + quotient_polys_sorted, + quotient_commitment, + ctl_data_per_table, + zeta, + config, + )); + + // KeccakSponge. + res.push(all_openings_single_stark( + Table::KeccakSponge, + &all_stark.keccak_sponge_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + quotient_polys_sorted, + quotient_commitment, + ctl_data_per_table, + zeta, + config, + )); + + // Logic. + res.push(all_openings_single_stark( + Table::Logic, + &all_stark.logic_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + quotient_polys_sorted, + quotient_commitment, + ctl_data_per_table, + zeta, + config, + )); + + // Memory. + res.push(all_openings_single_stark( + Table::Memory, + &all_stark.memory_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + quotient_polys_sorted, + quotient_commitment, + ctl_data_per_table, + zeta, + config, + )); + + // MemBefore. + res.push(all_openings_single_stark( + Table::MemBefore, + &all_stark.mem_before_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + quotient_polys_sorted, + quotient_commitment, + ctl_data_per_table, + zeta, + config, + )); + + // MemAfter. + let op = all_openings_single_stark( + Table::MemAfter, + &all_stark.mem_after_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + quotient_polys_sorted, + quotient_commitment, + ctl_data_per_table, + zeta, + config, + ); + // println!("Mem after opening: {:?}", op); + res.push(op); + + res +} + /// Generates a proof for each STARK. /// At this stage, we have computed the trace polynomials commitments for the /// various STARKs, and we have the cross-table lookup data for each table, @@ -645,10 +1978,29 @@ pub fn generate_all_data_segments( Ok(all_seg_data) } +fn reorder_slice( + slice: &mut [T], + current_order: [Table; NUM_TABLES], + target_order: [Table; NUM_TABLES], +) { + let mut order = current_order.clone(); + for i in 0..NUM_TABLES - 1 { + if order[i] != target_order[i] { + let j = order + .iter() + .position(|&x| x == target_order[i]) + .expect("Bad ordering?"); + order.swap(i, j); + slice.swap(i, j); + } + } +} + /// A utility module designed to test witness generation externally. pub mod testing { use super::*; use crate::{ + batch_proof::EvmProof, cpu::kernel::interpreter::Interpreter, generation::{output_debug_tries, state::State}, }; @@ -700,6 +2052,37 @@ pub mod testing { Ok(proofs) } + pub fn prove_all_segments_batch( + all_stark: &AllStark, + config: &StarkConfig, + inputs: GenerationInputs, + max_cpu_len_log: usize, + timing: &mut TimingTree, + abort_signal: Option>, + ) -> Result>> + where + F: RichField + Extendable, + C: GenericConfig, + P: PackedField, + { + let mut segment_idx = 0; + let mut data = generate_all_data_segments::(Some(max_cpu_len_log), &inputs)?; + + let mut proofs = Vec::with_capacity(data.len()); + for mut d in data { + proofs.push(prove_batch::( + all_stark, + config, + inputs.clone(), + &mut d, + timing, + abort_signal.clone(), + )?); + } + + Ok(proofs) + } + pub fn simulate_all_segments_interpreter( inputs: GenerationInputs, max_cpu_len_log: usize, diff --git a/evm_arithmetization/src/util.rs b/evm_arithmetization/src/util.rs index d0c353d70..31988fcfa 100644 --- a/evm_arithmetization/src/util.rs +++ b/evm_arithmetization/src/util.rs @@ -1,7 +1,7 @@ use core::mem::{size_of, transmute_copy, ManuallyDrop}; use ethereum_types::{H160, H256, U256}; -use itertools::Itertools; +use itertools::{assert_equal, Itertools}; use num::BigUint; use plonky2::field::extension::Extendable; use plonky2::field::packed::PackedField; diff --git a/evm_arithmetization/src/verifier.rs b/evm_arithmetization/src/verifier.rs index 8a2277037..72043969f 100644 --- a/evm_arithmetization/src/verifier.rs +++ b/evm_arithmetization/src/verifier.rs @@ -1,5 +1,6 @@ use anyhow::{ensure, Result}; use ethereum_types::{BigEndianHash, U256}; +use hashbrown::HashMap; use itertools::Itertools; use plonky2::field::extension::Extendable; use plonky2::field::polynomial::PolynomialValues; @@ -15,7 +16,7 @@ use starky::lookup::GrandProductChallenge; use starky::stark::Stark; use starky::verifier::verify_stark_proof_with_challenges; -use crate::all_stark::{AllStark, Table, NUM_TABLES}; +use crate::all_stark::{AllStark, Table, ALL_DEGREE_LOGS, NUM_TABLES, TABLE_TO_SORTED_INDEX}; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; use crate::memory::segments::Segment; @@ -65,7 +66,8 @@ pub(crate) fn initial_memory_merkle_cap< // Padding. let num_rows = trace.len(); - let num_rows_padded = num_rows.next_power_of_two(); + let num_rows_padded = 1 << ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::MemBefore]]; + assert!(num_rows_padded >= num_rows); trace.resize( num_rows_padded, vec![F::ZERO; crate::memory_continuation::columns::NUM_COLUMNS], @@ -237,12 +239,15 @@ fn verify_proof, C: GenericConfig, const // Extra sums to add to the looked last value. // Only necessary for the Memory values. - let mut extra_looking_sums = vec![vec![F::ZERO; config.num_challenges]; NUM_TABLES]; + let mut extra_looking_sums = HashMap::new(); // Memory - extra_looking_sums[Table::Memory as usize] = (0..config.num_challenges) - .map(|i| get_memory_extra_looking_sum(&public_values, ctl_challenges.challenges[i])) - .collect_vec(); + extra_looking_sums.insert( + Table::Memory as usize, + (0..config.num_challenges) + .map(|i| get_memory_extra_looking_sum(&public_values, ctl_challenges.challenges[i])) + .collect_vec(), + ); verify_cross_table_lookups::( cross_table_lookups, @@ -250,7 +255,7 @@ fn verify_proof, C: GenericConfig, const .multi_proof .stark_proofs .map(|p| p.proof.openings.ctl_zs_first.unwrap()), - Some(&extra_looking_sums), + &extra_looking_sums, config, ) } diff --git a/evm_arithmetization/src/witness/traces.rs b/evm_arithmetization/src/witness/traces.rs index d033dbbb9..5c94e0b24 100644 --- a/evm_arithmetization/src/witness/traces.rs +++ b/evm_arithmetization/src/witness/traces.rs @@ -6,7 +6,7 @@ use plonky2::util::timing::TimingTree; use starky::config::StarkConfig; use starky::util::trace_rows_to_poly_values; -use crate::all_stark::{AllStark, NUM_TABLES}; +use crate::all_stark::{AllStark, Table, ALL_DEGREE_LOGS, NUM_TABLES, TABLE_TO_SORTED_INDEX}; use crate::arithmetic::{BinaryOperator, Operation}; use crate::byte_packing::byte_packing_stark::BytePackingOp; use crate::cpu::columns::CpuColumnsView; @@ -187,16 +187,18 @@ impl Traces { let mem_before_trace = timed!( timing, "generate mem_before trace", - all_stark - .mem_before_stark - .generate_trace(mem_before_values_to_rows(mem_before_values)) + all_stark.mem_before_stark.generate_trace( + mem_before_values_to_rows(mem_before_values), + ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::MemBefore]] + ) ); let mem_after_trace = timed!( timing, "generate mem_after trace", - all_stark - .mem_after_stark - .generate_trace(final_values.clone()) + all_stark.mem_after_stark.generate_trace( + final_values.clone(), + ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::MemAfter]] + ) ); log::info!( diff --git a/evm_arithmetization/tests/simple_transfer.rs b/evm_arithmetization/tests/simple_transfer.rs index ef15c5ecc..8f193cb1f 100644 --- a/evm_arithmetization/tests/simple_transfer.rs +++ b/evm_arithmetization/tests/simple_transfer.rs @@ -4,10 +4,12 @@ use std::time::Duration; use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; use ethereum_types::{Address, BigEndianHash, H256, U256}; +use evm_arithmetization::batch_verifier::verify_evm_proof; use evm_arithmetization::generation::mpt::{AccountRlp, LegacyReceiptRlp}; use evm_arithmetization::generation::{GenerationInputs, TrieInputs}; use evm_arithmetization::proof::{BlockHashes, BlockMetadata, TrieRoots}; -use evm_arithmetization::prover::testing::prove_all_segments; +use evm_arithmetization::prover::testing::{prove_all_segments, prove_all_segments_batch}; +use evm_arithmetization::prover::zkevm_fast_config; use evm_arithmetization::verifier::testing::verify_all_proofs; use evm_arithmetization::{AllStark, Node, StarkConfig}; use hex_literal::hex; @@ -15,10 +17,13 @@ use keccak_hash::keccak; use mpt_trie::nibbles::Nibbles; use mpt_trie::partial_trie::{HashedPartialTrie, PartialTrie}; use plonky2::field::goldilocks_field::GoldilocksField; +use plonky2::field::packable::Packable; +use plonky2::field::packed::PackedField; use plonky2::plonk::config::KeccakGoldilocksConfig; use plonky2::util::timing::TimingTree; type F = GoldilocksField; +type P = ::Packing; const D: usize = 2; type C = KeccakGoldilocksConfig; @@ -28,7 +33,7 @@ fn test_simple_transfer() -> anyhow::Result<()> { init_logger(); let all_stark = AllStark::::default(); - let config = StarkConfig::standard_fast_config(); + let config = zkevm_fast_config(); let beneficiary = hex!("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); let sender = hex!("2c7536e3605d9c16a7a3d7b1898e529396a65c23"); @@ -156,7 +161,7 @@ fn test_simple_transfer() -> anyhow::Result<()> { let max_cpu_len_log = 20; let mut timing = TimingTree::new("prove", log::Level::Debug); - let proofs = prove_all_segments::( + let proofs = prove_all_segments_batch::( &all_stark, &config, inputs, @@ -167,7 +172,13 @@ fn test_simple_transfer() -> anyhow::Result<()> { timing.filter(Duration::from_millis(100)).print(); - verify_all_proofs(&all_stark, &proofs, &config) + for proof in proofs { + verify_evm_proof(&all_stark, proof, &config, false)?; + } + + Ok(()) + + // verify_all_proofs(&all_stark, &proofs, &config) } fn eth_to_wei(eth: U256) -> U256 {