From 8b653b2c2e8b125f9fec67eecc7511c2f57ab3af Mon Sep 17 00:00:00 2001 From: hratoanina Date: Sat, 29 Jun 2024 21:54:52 -0400 Subject: [PATCH 01/24] Add STARK batching --- Cargo.lock | 292 +++---- Cargo.toml | 8 +- evm_arithmetization/src/all_stark.rs | 27 + .../src/fixed_recursive_verifier.rs | 26 +- .../src/keccak_sponge/keccak_sponge_stark.rs | 1 + evm_arithmetization/src/prover.rs | 798 +++++++++++++++++- evm_arithmetization/src/verifier.rs | 14 +- 7 files changed, 985 insertions(+), 181 deletions(-) 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..97a2ad910 100644 --- a/evm_arithmetization/src/all_stark.rs +++ b/evm_arithmetization/src/all_stark.rs @@ -120,6 +120,33 @@ impl Table { Self::MemAfter, ] } + + /// Returns all STARK table indices in descending order of their padded + /// trace degrees. + pub(crate) const fn all_sorted() -> [Self; NUM_TABLES] { + [ + Self::Memory, + Self::MemBefore, + Self::MemAfter, + Self::Cpu, + Self::Arithmetic, + Self::BytePacking, + Self::Keccak, + Self::Logic, + Self::KeccakSponge, + ] + } + + /// Returns the ordered position of the tables. This is the inverse of + /// `all_sorted()`. + pub(crate) const fn table_to_sorted_index() -> [usize; NUM_TABLES] { + [4, 5, 3, 6, 8, 7, 0, 1, 2] + } + + /// Returns all STARK padded trace degrees in descending order. + pub(crate) const fn all_degree_logs() -> [usize; NUM_TABLES] { + [23, 22, 22, 20, 19, 19, 19, 17, 14] + } } /// Returns all the `CrossTableLookups` used for proving the EVM. 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/keccak_sponge/keccak_sponge_stark.rs b/evm_arithmetization/src/keccak_sponge/keccak_sponge_stark.rs index 73418c40f..056016830 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; diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index 6ab08896f..1bc618a35 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -1,34 +1,51 @@ +use std::iter::once; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; -use anyhow::{anyhow, Result}; +use anyhow::{anyhow, ensure, Result}; use itertools::Itertools; use once_cell::sync::Lazy; +use plonky2::batch_fri::oracle::BatchFriOracle; use plonky2::field::extension::Extendable; 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::FriInstanceInfo; +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 serde::{Deserialize, Serialize}; 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, 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, NUM_TABLES}; +use crate::arithmetic::arithmetic_stark::ArithmeticStark; +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::proof::{AllProof, MemCap, PublicValues, RegistersData}; use crate::witness::memory::{MemoryAddress, MemoryState}; @@ -66,6 +83,22 @@ impl GenerationSegmentData { } } +pub(crate) fn zkevm_fast_config() -> StarkConfig { + StarkConfig { + security_bits: 100, + num_challenges: 2, + fri_config: FriConfig { + rate_bits: 1, + cap_height: 4, + 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(vec![3, 2, 2, 1, 2, 3, 4, 4, 2]), + num_query_rounds: 84, + }, + } +} + /// Generate traces, then create all STARK proofs. pub fn prove( all_stark: &AllStark, @@ -249,6 +282,757 @@ type ProofWithMemCaps = ( MerkleCap, ); +/// Compute all STARK proofs. STARK-batching version. +pub(crate) fn prove_with_traces_batch( + all_stark: &AllStark, + config: &StarkConfig, + trace_poly_values: [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; + + let trace_poly_values_sorted: [_; NUM_TABLES] = Table::all_sorted() + .iter() + .map(|&table| trace_poly_values[*table].clone()) + .collect::>() + .try_into() + .unwrap(); + + // We compute the Field Merkle Tree of all STARK traces. + let trace_polys_values_sorted_flat = trace_poly_values_sorted + .clone() + .into_iter() + .flatten() + .collect(); + let trace_commitment = timed!( + timing, + "compute trace commitments", + BatchFriOracle::::from_values( + trace_polys_values_sorted_flat, + rate_bits, + false, + cap_height, + timing, + &[None; NUM_TABLES], + ) + ); + + 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`. + 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() + ) + ); + + check_abort_signal(abort_signal)?; + let lookup_challenges = ctl_challenges + .challenges + .iter() + .map(|ch| ch.beta) + .collect::>(); + + let auxiliary_columns = all_auxiliary_columns::( + all_stark, + config, + &trace_poly_values, + &ctl_data_per_table, + &ctl_challenges, + ); + + // We compute the Field Merkle Tree of all auxiliary columns. + let auxiliary_columns_sorted: Vec<_> = Table::all_sorted() + .iter() + .map(|&table| auxiliary_columns[*table].clone()) + .collect(); + let auxiliary_columns_sorted_flat = auxiliary_columns_sorted + .clone() + .into_iter() + .flatten() + .collect(); + let auxiliary_commitment = timed!( + timing, + "compute auxiliary commitments", + BatchFriOracle::::from_values( + auxiliary_columns_sorted_flat, + rate_bits, + false, + cap_height, + timing, + &[None; NUM_TABLES], + ) + ); + challenger.observe_cap(&auxiliary_commitment.batch_merkle_tree.cap); + + // Quotient polynomials. + let alphas = challenger.get_n_challenges(config.num_challenges); + let quotient_polys = all_quotient_polys::( + all_stark, + &trace_commitment, + &auxiliary_commitment, + &auxiliary_columns, + None, + &ctl_data_per_table, + alphas.clone(), + config, + ); + + // We compute the Field Merkle Tree of all quotient polynomials. + let quotient_polys_sorted: Vec<_> = Table::all_sorted() + .iter() + .map(|&table| quotient_polys[*table].clone()) + .collect(); + let quotient_polys_sorted_flat = quotient_polys_sorted + .clone() + .into_iter() + .flatten() + .collect(); + let quotient_commitment = timed!( + timing, + "compute quotient commitments", + BatchFriOracle::::from_coeffs( + quotient_polys_sorted_flat, + rate_bits, + false, + cap_height, + timing, + &[None; NUM_TABLES], + ) + ); + 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::primitive_root_of_unity(degree_bits); + ensure!( + zeta.exp_power_of_2(degree_bits) != F::Extension::ONE, + "Opening point is in the subgroup." + ); + + let mut all_fri_instances = all_fri_instance_info( + all_stark, + &trace_commitment, + &auxiliary_commitment, + &ctl_data_per_table, + alphas, + zeta, + config, + ); + + // Get the FRI openings and observe them. + // Compute all openings: evaluate all committed polynomials at `zeta` and, when + // necessary, at `g * zeta`. + // TODO: Need batched openings. + let openings = StarkOpeningSet { + local_values: Vec::new(), + next_values: Vec::new(), + auxiliary_polys: None, + auxiliary_polys_next: None, + ctl_zs_first: None, + quotient_polys: None, + }; + + challenger.observe_openings(&openings.to_fri_openings()); + + let initial_merkle_trees = [ + &trace_commitment, + &auxiliary_commitment, + "ient_commitment, + ]; + + let opening_proof = BatchFriOracle::prove_openings( + &Table::all_degree_logs(), + &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_sorted, + &all_stark.cross_table_lookups, + &extra_values, + ); + } + + let stark_proof = StarkProof { + 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(StarkProofWithPublicInputs { + proof: stark_proof, + public_inputs: vec![], + }) +} + +/// 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::new(); + + // 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, + ), + ); + + 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" + ); + + let lookup_challenges: Vec<_> = ctl_challenges.challenges.iter().map(|ch| ch.beta).collect(); + // Add lookup columns. + let lookups = stark.lookups(); + let mut res = { + let mut columns = Vec::new(); + for lookup in &lookups { + for &challenge in lookup_challenges.iter() { + columns.extend(lookup_helper_columns( + lookup, + trace_poly_values, + challenge, + 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 +} + +/// Generates all quotient polynomials. +fn all_quotient_polys( + all_stark: &AllStark, + trace_commitment: &BatchFriOracle, + auxiliary_commitment: &BatchFriOracle, + all_auxiliary_columns: &Vec>>, + 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::new(); + + // This method assumes that all STARKs have distinct degrees. + // TODO: Relax this. + assert!(Table::all_degree_logs() + .windows(2) + .all(|pair| { pair[0] > pair[1] })); + + // Arithmetic. + { + let trace_leave_len = trace_commitment.batch_merkle_tree.leaves + [Table::table_to_sorted_index()[*Table::Arithmetic]][0] + .len(); + let get_trace_packed = |index, step| { + trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) + }; + let aux_leave_len = trace_commitment.batch_merkle_tree.leaves + [Table::table_to_sorted_index()[*Table::Arithmetic]][0] + .len(); + let get_aux_packed = |index, step| { + auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) + }; + let num_lookup_columns = all_auxiliary_columns[*Table::Arithmetic].len(); + res.push( + compute_quotient_polys::, D>( + &all_stark.arithmetic_stark, + &get_trace_packed, + &get_aux_packed, + lookup_challenges, + Some(&ctl_data_per_table[*Table::Arithmetic]), + &vec![], + alphas.clone(), + Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::Arithmetic]], + num_lookup_columns, + config, + ) + .expect("Couldn't compute quotient polys."), + ); + } + + // Bytepacking. + { + let trace_leave_len = trace_commitment.batch_merkle_tree.leaves + [Table::table_to_sorted_index()[*Table::BytePacking]][0] + .len(); + let get_trace_packed = |index, step| { + trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) + }; + let aux_leave_len = trace_commitment.batch_merkle_tree.leaves + [Table::table_to_sorted_index()[*Table::BytePacking]][0] + .len(); + let get_aux_packed = |index, step| { + auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) + }; + let num_lookup_columns = all_auxiliary_columns[*Table::BytePacking].len(); + res.push( + compute_quotient_polys::, D>( + &all_stark.byte_packing_stark, + &get_trace_packed, + &get_aux_packed, + lookup_challenges, + Some(&ctl_data_per_table[*Table::BytePacking]), + &vec![], + alphas.clone(), + Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::BytePacking]], + num_lookup_columns, + config, + ) + .expect("Couldn't compute quotient polys."), + ); + } + + // Cpu. + { + let trace_leave_len = trace_commitment.batch_merkle_tree.leaves + [Table::table_to_sorted_index()[*Table::Cpu]][0] + .len(); + let get_trace_packed = |index, step| { + trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) + }; + let aux_leave_len = trace_commitment.batch_merkle_tree.leaves + [Table::table_to_sorted_index()[*Table::Cpu]][0] + .len(); + let get_aux_packed = |index, step| { + auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) + }; + let num_lookup_columns = all_auxiliary_columns[*Table::Cpu].len(); + res.push( + compute_quotient_polys::, D>( + &all_stark.cpu_stark, + &get_trace_packed, + &get_aux_packed, + lookup_challenges, + Some(&ctl_data_per_table[*Table::Cpu]), + &vec![], + alphas.clone(), + Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::Cpu]], + num_lookup_columns, + config, + ) + .expect("Couldn't compute quotient polys."), + ); + } + + // Keccak. + { + let trace_leave_len = trace_commitment.batch_merkle_tree.leaves + [Table::table_to_sorted_index()[*Table::Keccak]][0] + .len(); + let get_trace_packed = |index, step| { + trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) + }; + let aux_leave_len = trace_commitment.batch_merkle_tree.leaves + [Table::table_to_sorted_index()[*Table::Keccak]][0] + .len(); + let get_aux_packed = |index, step| { + auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) + }; + let num_lookup_columns = all_auxiliary_columns[*Table::Keccak].len(); + res.push( + compute_quotient_polys::, D>( + &all_stark.keccak_stark, + &get_trace_packed, + &get_aux_packed, + lookup_challenges, + Some(&ctl_data_per_table[*Table::Keccak]), + &vec![], + alphas.clone(), + Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::Keccak]], + num_lookup_columns, + config, + ) + .expect("Couldn't compute quotient polys."), + ); + } + + // KeccakSponge. + { + let trace_leave_len = trace_commitment.batch_merkle_tree.leaves + [Table::table_to_sorted_index()[*Table::KeccakSponge]][0] + .len(); + let get_trace_packed = |index, step| { + trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) + }; + let aux_leave_len = trace_commitment.batch_merkle_tree.leaves + [Table::table_to_sorted_index()[*Table::KeccakSponge]][0] + .len(); + let get_aux_packed = |index, step| { + auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) + }; + let num_lookup_columns = all_auxiliary_columns[*Table::KeccakSponge].len(); + res.push( + compute_quotient_polys::, D>( + &all_stark.keccak_sponge_stark, + &get_trace_packed, + &get_aux_packed, + lookup_challenges, + Some(&ctl_data_per_table[*Table::KeccakSponge]), + &vec![], + alphas.clone(), + Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::KeccakSponge]], + num_lookup_columns, + config, + ) + .expect("Couldn't compute quotient polys."), + ); + } + + // Logic. + { + let trace_leave_len = trace_commitment.batch_merkle_tree.leaves + [Table::table_to_sorted_index()[*Table::Logic]][0] + .len(); + let get_trace_packed = |index, step| { + trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) + }; + let aux_leave_len = trace_commitment.batch_merkle_tree.leaves + [Table::table_to_sorted_index()[*Table::Logic]][0] + .len(); + let get_aux_packed = |index, step| { + auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) + }; + let num_lookup_columns = all_auxiliary_columns[*Table::Logic].len(); + res.push( + compute_quotient_polys::, D>( + &all_stark.logic_stark, + &get_trace_packed, + &get_aux_packed, + lookup_challenges, + Some(&ctl_data_per_table[*Table::Logic]), + &vec![], + alphas.clone(), + Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::Logic]], + num_lookup_columns, + config, + ) + .expect("Couldn't compute quotient polys."), + ); + } + + // Memory. + { + let trace_leave_len = trace_commitment.batch_merkle_tree.leaves + [Table::table_to_sorted_index()[*Table::Memory]][0] + .len(); + let get_trace_packed = |index, step| { + trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) + }; + let aux_leave_len = trace_commitment.batch_merkle_tree.leaves + [Table::table_to_sorted_index()[*Table::Memory]][0] + .len(); + let get_aux_packed = |index, step| { + auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) + }; + let num_lookup_columns = all_auxiliary_columns[*Table::Memory].len(); + res.push( + compute_quotient_polys::, D>( + &all_stark.memory_stark, + &get_trace_packed, + &get_aux_packed, + lookup_challenges, + Some(&ctl_data_per_table[*Table::Memory]), + &vec![], + alphas.clone(), + Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::Memory]], + num_lookup_columns, + config, + ) + .expect("Couldn't compute quotient polys."), + ); + } + + res +} + +/// Generates all FRI instances. They are sorted by decreasing degree. +fn all_fri_instance_info( + all_stark: &AllStark, + trace_commitment: &BatchFriOracle, + auxiliary_commitment: &BatchFriOracle, + ctl_data_per_table: &[CtlData; NUM_TABLES], + alphas: Vec, + zeta: F::Extension, + config: &StarkConfig, + // ctl_data_per_table: &[CtlData; NUM_TABLES], + // ctl_challenges: &GrandProductChallengeSet, +) -> Vec> +where + F: RichField + Extendable, + C: GenericConfig, +{ + let degree_bits = Table::all_degree_logs(); + let mut res = Vec::new(); + + // Arithmetic. + { + let g = F::primitive_root_of_unity( + degree_bits[Table::table_to_sorted_index()[*Table::Arithmetic]], + ); + let num_ctl_helper_polys = ctl_data_per_table[*Table::Arithmetic].num_ctl_helper_polys(); + res.push(all_stark.arithmetic_stark.fri_instance( + zeta, + g, + num_ctl_helper_polys.iter().sum(), + num_ctl_helper_polys, + config, + )); + } + + // BytePacking. + { + let g = F::primitive_root_of_unity( + degree_bits[Table::table_to_sorted_index()[*Table::BytePacking]], + ); + let num_ctl_helper_polys = ctl_data_per_table[*Table::BytePacking].num_ctl_helper_polys(); + res.push(all_stark.byte_packing_stark.fri_instance( + zeta, + g, + num_ctl_helper_polys.iter().sum(), + num_ctl_helper_polys, + config, + )); + } + + // Cpu. + { + let g = + F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*Table::Cpu]]); + let num_ctl_helper_polys = ctl_data_per_table[*Table::Cpu].num_ctl_helper_polys(); + res.push(all_stark.cpu_stark.fri_instance( + zeta, + g, + num_ctl_helper_polys.iter().sum(), + num_ctl_helper_polys, + config, + )); + } + + // Keccak. + { + let g = + F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*Table::Keccak]]); + let num_ctl_helper_polys = ctl_data_per_table[*Table::Keccak].num_ctl_helper_polys(); + res.push(all_stark.keccak_stark.fri_instance( + zeta, + g, + num_ctl_helper_polys.iter().sum(), + num_ctl_helper_polys, + config, + )); + } + + // KeccakSponge. + { + let g = F::primitive_root_of_unity( + degree_bits[Table::table_to_sorted_index()[*Table::KeccakSponge]], + ); + let num_ctl_helper_polys = ctl_data_per_table[*Table::KeccakSponge].num_ctl_helper_polys(); + res.push(all_stark.keccak_sponge_stark.fri_instance( + zeta, + g, + num_ctl_helper_polys.iter().sum(), + num_ctl_helper_polys, + config, + )); + } + + // Logic. + { + let g = + F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*Table::Logic]]); + let num_ctl_helper_polys = ctl_data_per_table[*Table::Logic].num_ctl_helper_polys(); + res.push(all_stark.logic_stark.fri_instance( + zeta, + g, + num_ctl_helper_polys.iter().sum(), + num_ctl_helper_polys, + config, + )); + } + + // Memory. + { + let g = + F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*Table::Memory]]); + let num_ctl_helper_polys = ctl_data_per_table[*Table::Memory].num_ctl_helper_polys(); + res.push(all_stark.memory_stark.fri_instance( + zeta, + g, + num_ctl_helper_polys.iter().sum(), + num_ctl_helper_polys, + config, + )); + } + + 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, diff --git a/evm_arithmetization/src/verifier.rs b/evm_arithmetization/src/verifier.rs index 8a2277037..1c07d2606 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; @@ -237,12 +238,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 +254,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, ) } From b86c0d2721fc349d837f9e9352255db3cfeb09f1 Mon Sep 17 00:00:00 2001 From: hratoanina Date: Fri, 12 Jul 2024 19:25:29 -0400 Subject: [PATCH 02/24] Add batch openings --- evm_arithmetization/src/all_stark.rs | 16 + evm_arithmetization/src/prover.rs | 421 +++++++++++++++++++++++---- 2 files changed, 374 insertions(+), 63 deletions(-) diff --git a/evm_arithmetization/src/all_stark.rs b/evm_arithmetization/src/all_stark.rs index 97a2ad910..34ad7099a 100644 --- a/evm_arithmetization/src/all_stark.rs +++ b/evm_arithmetization/src/all_stark.rs @@ -143,6 +143,22 @@ impl Table { [4, 5, 3, 6, 8, 7, 0, 1, 2] } + /// Returns the ordered position of the tables in a batch Merkle tree. Each + /// entry is a couple to account for duplicate sizes. + pub(crate) const fn table_to_sorted_index_pair() -> [(usize, usize); NUM_TABLES] { + [ + (3, 0), + (3, 1), + (2, 0), + (3, 2), + (5, 0), + (4, 0), + (0, 0), + (1, 0), + (1, 1), + ] + } + /// Returns all STARK padded trace degrees in descending order. pub(crate) const fn all_degree_logs() -> [usize; NUM_TABLES] { [23, 22, 22, 20, 19, 19, 19, 17, 14] diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index 1bc618a35..5faa04ae4 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -14,7 +14,7 @@ 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::FriInstanceInfo; +use plonky2::fri::structure::{FriInstanceInfo, FriOpeningBatch}; use plonky2::fri::FriConfig; use plonky2::hash::hash_types::RichField; use plonky2::hash::merkle_tree::MerkleCap; @@ -24,6 +24,7 @@ use plonky2::plonk::proof::ProofWithPublicInputs; use plonky2::timed; use plonky2::util::timing::TimingTree; use serde::{Deserialize, Serialize}; +use starky::batch_proof::{BatchStarkProof, BatchStarkProofWithPublicInputs}; use starky::config::StarkConfig; use starky::cross_table_lookup::{get_ctl_auxiliary_polys, get_ctl_data, CtlData}; use starky::lookup::{lookup_helper_columns, GrandProductChallengeSet}; @@ -290,7 +291,7 @@ pub(crate) fn prove_with_traces_batch( public_values: PublicValues, timing: &mut TimingTree, abort_signal: Option>, -) -> Result> +) -> Result> where F: RichField + Extendable, P: PackedField, @@ -447,17 +448,22 @@ where // Get the FRI openings and observe them. // Compute all openings: evaluate all committed polynomials at `zeta` and, when // necessary, at `g * zeta`. - // TODO: Need batched openings. - let openings = StarkOpeningSet { - local_values: Vec::new(), - next_values: Vec::new(), - auxiliary_polys: None, - auxiliary_polys_next: None, - ctl_zs_first: None, - quotient_polys: None, - }; + let openings = all_openings( + all_stark, + &trace_poly_values_sorted, + &trace_commitment, + &auxiliary_columns_sorted, + &auxiliary_commitment, + "ient_polys_sorted, + "ient_commitment, + &ctl_data_per_table, + zeta, + config, + ); - challenger.observe_openings(&openings.to_fri_openings()); + for opening in openings.iter() { + challenger.observe_openings(&opening.to_fri_openings()); + } let initial_merkle_trees = [ &trace_commitment, @@ -495,15 +501,15 @@ where ); } - let stark_proof = StarkProof { + let stark_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, + openings: openings.try_into().unwrap(), opening_proof, }; - Ok(StarkProofWithPublicInputs { + Ok(BatchStarkProofWithPublicInputs { proof: stark_proof, public_inputs: vec![], }) @@ -677,23 +683,16 @@ where { let mut res = Vec::new(); - // This method assumes that all STARKs have distinct degrees. - // TODO: Relax this. - assert!(Table::all_degree_logs() - .windows(2) - .all(|pair| { pair[0] > pair[1] })); - // Arithmetic. { - let trace_leave_len = trace_commitment.batch_merkle_tree.leaves - [Table::table_to_sorted_index()[*Table::Arithmetic]][0] - .len(); + let (index_outer, index_inner) = Table::table_to_sorted_index_pair()[*Table::Arithmetic]; + let trace_leave_len = + trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); let get_trace_packed = |index, step| { trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) }; - let aux_leave_len = trace_commitment.batch_merkle_tree.leaves - [Table::table_to_sorted_index()[*Table::Arithmetic]][0] - .len(); + let aux_leave_len = + trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); let get_aux_packed = |index, step| { auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) }; @@ -717,15 +716,14 @@ where // Bytepacking. { - let trace_leave_len = trace_commitment.batch_merkle_tree.leaves - [Table::table_to_sorted_index()[*Table::BytePacking]][0] - .len(); + let (index_outer, index_inner) = Table::table_to_sorted_index_pair()[*Table::BytePacking]; + let trace_leave_len = + trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); let get_trace_packed = |index, step| { trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) }; - let aux_leave_len = trace_commitment.batch_merkle_tree.leaves - [Table::table_to_sorted_index()[*Table::BytePacking]][0] - .len(); + let aux_leave_len = + trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); let get_aux_packed = |index, step| { auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) }; @@ -749,15 +747,14 @@ where // Cpu. { - let trace_leave_len = trace_commitment.batch_merkle_tree.leaves - [Table::table_to_sorted_index()[*Table::Cpu]][0] - .len(); + let (index_outer, index_inner) = Table::table_to_sorted_index_pair()[*Table::Cpu]; + let trace_leave_len = + trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); let get_trace_packed = |index, step| { trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) }; - let aux_leave_len = trace_commitment.batch_merkle_tree.leaves - [Table::table_to_sorted_index()[*Table::Cpu]][0] - .len(); + let aux_leave_len = + trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); let get_aux_packed = |index, step| { auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) }; @@ -781,15 +778,14 @@ where // Keccak. { - let trace_leave_len = trace_commitment.batch_merkle_tree.leaves - [Table::table_to_sorted_index()[*Table::Keccak]][0] - .len(); + let (index_outer, index_inner) = Table::table_to_sorted_index_pair()[*Table::Keccak]; + let trace_leave_len = + trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); let get_trace_packed = |index, step| { trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) }; - let aux_leave_len = trace_commitment.batch_merkle_tree.leaves - [Table::table_to_sorted_index()[*Table::Keccak]][0] - .len(); + let aux_leave_len = + trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); let get_aux_packed = |index, step| { auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) }; @@ -813,15 +809,14 @@ where // KeccakSponge. { - let trace_leave_len = trace_commitment.batch_merkle_tree.leaves - [Table::table_to_sorted_index()[*Table::KeccakSponge]][0] - .len(); + let (index_outer, index_inner) = Table::table_to_sorted_index_pair()[*Table::KeccakSponge]; + let trace_leave_len = + trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); let get_trace_packed = |index, step| { trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) }; - let aux_leave_len = trace_commitment.batch_merkle_tree.leaves - [Table::table_to_sorted_index()[*Table::KeccakSponge]][0] - .len(); + let aux_leave_len = + trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); let get_aux_packed = |index, step| { auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) }; @@ -845,15 +840,14 @@ where // Logic. { - let trace_leave_len = trace_commitment.batch_merkle_tree.leaves - [Table::table_to_sorted_index()[*Table::Logic]][0] - .len(); + let (index_outer, index_inner) = Table::table_to_sorted_index_pair()[*Table::Logic]; + let trace_leave_len = + trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); let get_trace_packed = |index, step| { trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) }; - let aux_leave_len = trace_commitment.batch_merkle_tree.leaves - [Table::table_to_sorted_index()[*Table::Logic]][0] - .len(); + let aux_leave_len = + trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); let get_aux_packed = |index, step| { auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) }; @@ -877,15 +871,14 @@ where // Memory. { - let trace_leave_len = trace_commitment.batch_merkle_tree.leaves - [Table::table_to_sorted_index()[*Table::Memory]][0] - .len(); + let (index_outer, index_inner) = Table::table_to_sorted_index_pair()[*Table::Memory]; + let trace_leave_len = + trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); let get_trace_packed = |index, step| { trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) }; - let aux_leave_len = trace_commitment.batch_merkle_tree.leaves - [Table::table_to_sorted_index()[*Table::Memory]][0] - .len(); + let aux_leave_len = + trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); let get_aux_packed = |index, step| { auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) }; @@ -1033,6 +1026,308 @@ where res } +/// 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 = Table::all_degree_logs(); + let mut res = Vec::new(); + + // Arithmetic. + { + let stark = all_stark.arithmetic_stark; + let table = Table::Arithmetic; + let g = F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*table]]); + let table_sorted_index = Table::table_to_sorted_index()[*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..table_sorted_index { + 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(); + } + + let num_trace_polys = res.push(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..auxiliary_columns_sorted[table_sorted_index].len(), + quotient_commitment, + 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(), + )); + } + + // Bytepacking. + { + let stark = all_stark.byte_packing_stark; + let table = Table::BytePacking; + let g = F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*table]]); + let table_sorted_index = Table::table_to_sorted_index()[*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..table_sorted_index { + 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(); + } + + let num_trace_polys = res.push(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..auxiliary_columns_sorted[table_sorted_index].len(), + quotient_commitment, + 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(), + )); + } + + // Cpu. + { + let stark = all_stark.cpu_stark; + let table = Table::Cpu; + let g = F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*table]]); + let table_sorted_index = Table::table_to_sorted_index()[*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..table_sorted_index { + 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(); + } + + let num_trace_polys = res.push(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..auxiliary_columns_sorted[table_sorted_index].len(), + quotient_commitment, + 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(), + )); + } + + // Keccak. + { + let stark = all_stark.keccak_stark; + let table = Table::Keccak; + let g = F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*table]]); + let table_sorted_index = Table::table_to_sorted_index()[*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..table_sorted_index { + 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(); + } + + let num_trace_polys = res.push(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..auxiliary_columns_sorted[table_sorted_index].len(), + quotient_commitment, + 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(), + )); + } + + // KeccakSponge. + { + let stark = all_stark.keccak_sponge_stark; + let table = Table::KeccakSponge; + let g = F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*table]]); + let table_sorted_index = Table::table_to_sorted_index()[*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..table_sorted_index { + 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(); + } + + let num_trace_polys = res.push(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..auxiliary_columns_sorted[table_sorted_index].len(), + quotient_commitment, + 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(), + )); + } + + // Logic. + { + let stark = all_stark.logic_stark; + let table = Table::Logic; + let g = F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*table]]); + let table_sorted_index = Table::table_to_sorted_index()[*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..table_sorted_index { + 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(); + } + + let num_trace_polys = res.push(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..auxiliary_columns_sorted[table_sorted_index].len(), + quotient_commitment, + 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(), + )); + } + + // Memory. + { + let stark = all_stark.memory_stark; + let table = Table::Memory; + let g = F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*table]]); + let table_sorted_index = Table::table_to_sorted_index()[*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..table_sorted_index { + 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(); + } + + let num_trace_polys = res.push(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..auxiliary_columns_sorted[table_sorted_index].len(), + quotient_commitment, + 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(), + )); + } + + // MemBefore. + { + let stark = all_stark.mem_before_stark; + let table = Table::MemBefore; + let g = F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*table]]); + let table_sorted_index = Table::table_to_sorted_index()[*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..table_sorted_index { + 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(); + } + + let num_trace_polys = res.push(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..auxiliary_columns_sorted[table_sorted_index].len(), + quotient_commitment, + 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(), + )); + } + + // MemAfter. + { + let stark = all_stark.mem_after_stark; + let table = Table::MemAfter; + let g = F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*table]]); + let table_sorted_index = Table::table_to_sorted_index()[*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..table_sorted_index { + 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(); + } + + let num_trace_polys = res.push(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..auxiliary_columns_sorted[table_sorted_index].len(), + quotient_commitment, + 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(), + )); + } + + 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, From 6f22a9ae514cbc933907616f92e1e3518e296208 Mon Sep 17 00:00:00 2001 From: hratoanina Date: Mon, 15 Jul 2024 12:17:32 -0400 Subject: [PATCH 03/24] Adapt simple_transfer test --- evm_arithmetization/src/all_stark.rs | 12 ++-- .../src/arithmetic/arithmetic_stark.rs | 3 +- .../src/byte_packing/byte_packing_stark.rs | 6 +- .../src/keccak/keccak_stark.rs | 7 +- .../src/keccak_sponge/keccak_sponge_stark.rs | 5 +- evm_arithmetization/src/logic.rs | 5 +- .../src/memory/memory_stark.rs | 3 +- .../memory_continuation_stark.rs | 5 +- evm_arithmetization/src/prover.rs | 70 ++++++++++++++++++- evm_arithmetization/tests/simple_transfer.rs | 11 ++- 10 files changed, 103 insertions(+), 24 deletions(-) diff --git a/evm_arithmetization/src/all_stark.rs b/evm_arithmetization/src/all_stark.rs index 34ad7099a..7476485ee 100644 --- a/evm_arithmetization/src/all_stark.rs +++ b/evm_arithmetization/src/all_stark.rs @@ -147,12 +147,12 @@ impl Table { /// entry is a couple to account for duplicate sizes. pub(crate) const fn table_to_sorted_index_pair() -> [(usize, usize); NUM_TABLES] { [ - (3, 0), - (3, 1), + (2, 1), + (2, 2), (2, 0), - (3, 2), - (5, 0), - (4, 0), + (2, 3), + (3, 0), + (2, 4), (0, 0), (1, 0), (1, 1), @@ -161,7 +161,7 @@ impl Table { /// Returns all STARK padded trace degrees in descending order. pub(crate) const fn all_degree_logs() -> [usize; NUM_TABLES] { - [23, 22, 22, 20, 19, 19, 19, 17, 14] + [23, 22, 22, 20, 20, 20, 20, 20, 16] } } diff --git a/evm_arithmetization/src/arithmetic/arithmetic_stark.rs b/evm_arithmetization/src/arithmetic/arithmetic_stark.rs index d0712a3bc..ede0b47cc 100644 --- a/evm_arithmetization/src/arithmetic/arithmetic_stark.rs +++ b/evm_arithmetization/src/arithmetic/arithmetic_stark.rs @@ -178,7 +178,8 @@ 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 << Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::Arithmetic]]; 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/byte_packing/byte_packing_stark.rs b/evm_arithmetization/src/byte_packing/byte_packing_stark.rs index 6f36a889c..08b8df204 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}; 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,9 @@ 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 << Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::BytePacking]]; + let mut rows = Vec::with_capacity(num_rows); for op in ops { diff --git a/evm_arithmetization/src/keccak/keccak_stark.rs b/evm_arithmetization/src/keccak/keccak_stark.rs index 5f505cf06..bd8014157 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}; 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,8 @@ 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 << Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::Keccak]]; let mut rows = Vec::with_capacity(num_rows); for input_and_timestamp in inputs_and_timestamps.iter() { diff --git a/evm_arithmetization/src/keccak_sponge/keccak_sponge_stark.rs b/evm_arithmetization/src/keccak_sponge/keccak_sponge_stark.rs index 056016830..27e568e05 100644 --- a/evm_arithmetization/src/keccak_sponge/keccak_sponge_stark.rs +++ b/evm_arithmetization/src/keccak_sponge/keccak_sponge_stark.rs @@ -19,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}; use crate::cpu::kernel::keccak_util::keccakf_u32s; use crate::keccak_sponge::columns::*; use crate::witness::memory::MemoryAddress; @@ -290,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 << Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::KeccakSponge]]; for _ in rows.len()..padded_rows { rows.push(self.generate_padding_row()); } diff --git a/evm_arithmetization/src/logic.rs b/evm_arithmetization/src/logic.rs index eae7c972b..d420df3a2 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}; 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,8 @@ 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 << Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::Logic]]; 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..8a6a9f7b4 100644 --- a/evm_arithmetization/src/memory/memory_stark.rs +++ b/evm_arithmetization/src/memory/memory_stark.rs @@ -353,7 +353,8 @@ 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 << Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::Memory]]; 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..cd160852c 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; @@ -85,7 +85,8 @@ impl, const D: usize> MemoryContinuationStark 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 << Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::MemBefore]]; 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 5faa04ae4..179a9eaae 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -94,7 +94,7 @@ pub(crate) fn zkevm_fast_config() -> StarkConfig { 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(vec![3, 2, 2, 1, 2, 3, 4, 4, 2]), + reduction_strategy: FriReductionStrategy::Fixed(vec![1, 2, 4, 4, 4, 4]), num_query_rounds: 84, }, } @@ -135,6 +135,42 @@ 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 (traces, mut public_values) = timed!( + timing, + "generate all traces", + generate_traces(all_stark, &inputs, config, segment_data, timing)? + ); + + check_abort_signal(abort_signal.clone())?; + + let proof = prove_with_traces_batch::( + all_stark, + config, + traces, + public_values, + timing, + abort_signal, + )?; + + Ok(proof) +} + /// Compute all STARK proofs. pub(crate) fn prove_with_traces( all_stark: &AllStark, @@ -1779,6 +1815,38 @@ 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 { + let proof = prove_batch::( + all_stark, + config, + inputs.clone(), + &mut d, + timing, + abort_signal.clone(), + )?; + proofs.push(proof); + } + + Ok(proofs) + } + pub fn simulate_all_segments_interpreter( inputs: GenerationInputs, max_cpu_len_log: usize, diff --git a/evm_arithmetization/tests/simple_transfer.rs b/evm_arithmetization/tests/simple_transfer.rs index ef15c5ecc..7e3e00b8e 100644 --- a/evm_arithmetization/tests/simple_transfer.rs +++ b/evm_arithmetization/tests/simple_transfer.rs @@ -7,7 +7,7 @@ use ethereum_types::{Address, BigEndianHash, H256, U256}; 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::verifier::testing::verify_all_proofs; use evm_arithmetization::{AllStark, Node, StarkConfig}; use hex_literal::hex; @@ -15,10 +15,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; @@ -156,7 +159,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 +170,9 @@ fn test_simple_transfer() -> anyhow::Result<()> { timing.filter(Duration::from_millis(100)).print(); - verify_all_proofs(&all_stark, &proofs, &config) + Ok(()) + + // verify_all_proofs(&all_stark, &proofs, &config) } fn eth_to_wei(eth: U256) -> U256 { From 509ce342d736d9a1a79006952dbb6f6f2a046e70 Mon Sep 17 00:00:00 2001 From: hratoanina Date: Tue, 16 Jul 2024 10:53:33 -0400 Subject: [PATCH 04/24] Lower Keccak len --- evm_arithmetization/src/all_stark.rs | 18 +-- evm_arithmetization/src/generation/mod.rs | 8 +- evm_arithmetization/src/prover.rs | 173 ++++++++++++++++------ 3 files changed, 145 insertions(+), 54 deletions(-) diff --git a/evm_arithmetization/src/all_stark.rs b/evm_arithmetization/src/all_stark.rs index 7476485ee..2dd060c55 100644 --- a/evm_arithmetization/src/all_stark.rs +++ b/evm_arithmetization/src/all_stark.rs @@ -131,8 +131,8 @@ impl Table { Self::Cpu, Self::Arithmetic, Self::BytePacking, - Self::Keccak, Self::Logic, + Self::Keccak, Self::KeccakSponge, ] } @@ -140,28 +140,28 @@ impl Table { /// Returns the ordered position of the tables. This is the inverse of /// `all_sorted()`. pub(crate) const fn table_to_sorted_index() -> [usize; NUM_TABLES] { - [4, 5, 3, 6, 8, 7, 0, 1, 2] + [4, 5, 3, 7, 8, 6, 0, 1, 2] } /// Returns the ordered position of the tables in a batch Merkle tree. Each /// entry is a couple to account for duplicate sizes. - pub(crate) const fn table_to_sorted_index_pair() -> [(usize, usize); NUM_TABLES] { + pub(crate) const fn sorted_index_pair() -> [(usize, usize); NUM_TABLES] { [ + (0, 0), + (1, 0), + (1, 1), + (2, 0), (2, 1), (2, 2), - (2, 0), (2, 3), (3, 0), - (2, 4), - (0, 0), - (1, 0), - (1, 1), + (4, 0), ] } /// Returns all STARK padded trace degrees in descending order. pub(crate) const fn all_degree_logs() -> [usize; NUM_TABLES] { - [23, 22, 22, 20, 20, 20, 20, 20, 16] + [23, 22, 22, 20, 20, 20, 20, 18, 16] } } diff --git a/evm_arithmetization/src/generation/mod.rs b/evm_arithmetization/src/generation/mod.rs index e79099e6a..25174268a 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, NUM_TABLES}; use crate::cpu::columns::CpuColumnsView; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; @@ -487,10 +487,12 @@ fn simulate_cpu( row.stack_len = F::from_canonical_usize(state.registers.stack_len); 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 << Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::Cpu]] + { break; } } diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index 179a9eaae..760d3fdc5 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -721,7 +721,10 @@ where // Arithmetic. { - let (index_outer, index_inner) = Table::table_to_sorted_index_pair()[*Table::Arithmetic]; + let table = Table::Arithmetic; + let stark = &all_stark.arithmetic_stark; + let (index_outer, index_inner) = + Table::sorted_index_pair()[Table::table_to_sorted_index()[*table]]; let trace_leave_len = trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); let get_trace_packed = |index, step| { @@ -732,17 +735,17 @@ where let get_aux_packed = |index, step| { auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) }; - let num_lookup_columns = all_auxiliary_columns[*Table::Arithmetic].len(); + let num_lookup_columns = all_auxiliary_columns[*table].len(); res.push( - compute_quotient_polys::, D>( - &all_stark.arithmetic_stark, + compute_quotient_polys::( + stark, &get_trace_packed, &get_aux_packed, lookup_challenges, - Some(&ctl_data_per_table[*Table::Arithmetic]), + Some(&ctl_data_per_table[*table]), &vec![], alphas.clone(), - Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::Arithmetic]], + Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], num_lookup_columns, config, ) @@ -752,7 +755,10 @@ where // Bytepacking. { - let (index_outer, index_inner) = Table::table_to_sorted_index_pair()[*Table::BytePacking]; + let table = Table::BytePacking; + let stark = &all_stark.byte_packing_stark; + let (index_outer, index_inner) = + Table::sorted_index_pair()[Table::table_to_sorted_index()[*table]]; let trace_leave_len = trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); let get_trace_packed = |index, step| { @@ -763,17 +769,17 @@ where let get_aux_packed = |index, step| { auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) }; - let num_lookup_columns = all_auxiliary_columns[*Table::BytePacking].len(); + let num_lookup_columns = all_auxiliary_columns[*table].len(); res.push( - compute_quotient_polys::, D>( - &all_stark.byte_packing_stark, + compute_quotient_polys::( + stark, &get_trace_packed, &get_aux_packed, lookup_challenges, - Some(&ctl_data_per_table[*Table::BytePacking]), + Some(&ctl_data_per_table[*table]), &vec![], alphas.clone(), - Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::BytePacking]], + Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], num_lookup_columns, config, ) @@ -783,7 +789,10 @@ where // Cpu. { - let (index_outer, index_inner) = Table::table_to_sorted_index_pair()[*Table::Cpu]; + let table = Table::Cpu; + let stark = &all_stark.cpu_stark; + let (index_outer, index_inner) = + Table::sorted_index_pair()[Table::table_to_sorted_index()[*table]]; let trace_leave_len = trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); let get_trace_packed = |index, step| { @@ -794,17 +803,17 @@ where let get_aux_packed = |index, step| { auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) }; - let num_lookup_columns = all_auxiliary_columns[*Table::Cpu].len(); + let num_lookup_columns = all_auxiliary_columns[*table].len(); res.push( - compute_quotient_polys::, D>( - &all_stark.cpu_stark, + compute_quotient_polys::( + stark, &get_trace_packed, &get_aux_packed, lookup_challenges, - Some(&ctl_data_per_table[*Table::Cpu]), + Some(&ctl_data_per_table[*table]), &vec![], alphas.clone(), - Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::Cpu]], + Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], num_lookup_columns, config, ) @@ -814,7 +823,10 @@ where // Keccak. { - let (index_outer, index_inner) = Table::table_to_sorted_index_pair()[*Table::Keccak]; + let table = Table::Keccak; + let stark = &all_stark.keccak_stark; + let (index_outer, index_inner) = + Table::sorted_index_pair()[Table::table_to_sorted_index()[*table]]; let trace_leave_len = trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); let get_trace_packed = |index, step| { @@ -825,17 +837,17 @@ where let get_aux_packed = |index, step| { auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) }; - let num_lookup_columns = all_auxiliary_columns[*Table::Keccak].len(); + let num_lookup_columns = all_auxiliary_columns[*table].len(); res.push( - compute_quotient_polys::, D>( - &all_stark.keccak_stark, + compute_quotient_polys::( + stark, &get_trace_packed, &get_aux_packed, lookup_challenges, - Some(&ctl_data_per_table[*Table::Keccak]), + Some(&ctl_data_per_table[*table]), &vec![], alphas.clone(), - Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::Keccak]], + Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], num_lookup_columns, config, ) @@ -845,7 +857,10 @@ where // KeccakSponge. { - let (index_outer, index_inner) = Table::table_to_sorted_index_pair()[*Table::KeccakSponge]; + let table = Table::KeccakSponge; + let stark = &all_stark.keccak_sponge_stark; + let (index_outer, index_inner) = + Table::sorted_index_pair()[Table::table_to_sorted_index()[*table]]; let trace_leave_len = trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); let get_trace_packed = |index, step| { @@ -856,17 +871,17 @@ where let get_aux_packed = |index, step| { auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) }; - let num_lookup_columns = all_auxiliary_columns[*Table::KeccakSponge].len(); + let num_lookup_columns = all_auxiliary_columns[*table].len(); res.push( - compute_quotient_polys::, D>( - &all_stark.keccak_sponge_stark, + compute_quotient_polys::( + stark, &get_trace_packed, &get_aux_packed, lookup_challenges, - Some(&ctl_data_per_table[*Table::KeccakSponge]), + Some(&ctl_data_per_table[*table]), &vec![], alphas.clone(), - Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::KeccakSponge]], + Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], num_lookup_columns, config, ) @@ -876,7 +891,10 @@ where // Logic. { - let (index_outer, index_inner) = Table::table_to_sorted_index_pair()[*Table::Logic]; + let table = Table::Logic; + let stark = &all_stark.logic_stark; + let (index_outer, index_inner) = + Table::sorted_index_pair()[Table::table_to_sorted_index()[*table]]; let trace_leave_len = trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); let get_trace_packed = |index, step| { @@ -887,17 +905,17 @@ where let get_aux_packed = |index, step| { auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) }; - let num_lookup_columns = all_auxiliary_columns[*Table::Logic].len(); + let num_lookup_columns = all_auxiliary_columns[*table].len(); res.push( - compute_quotient_polys::, D>( - &all_stark.logic_stark, + compute_quotient_polys::( + stark, &get_trace_packed, &get_aux_packed, lookup_challenges, - Some(&ctl_data_per_table[*Table::Logic]), + Some(&ctl_data_per_table[*table]), &vec![], alphas.clone(), - Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::Logic]], + Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], num_lookup_columns, config, ) @@ -907,7 +925,78 @@ where // Memory. { - let (index_outer, index_inner) = Table::table_to_sorted_index_pair()[*Table::Memory]; + let table = Table::Memory; + let stark = &all_stark.memory_stark; + let (index_outer, index_inner) = + Table::sorted_index_pair()[Table::table_to_sorted_index()[*table]]; + let trace_leave_len = + trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); + let get_trace_packed = |index, step| { + trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) + }; + let aux_leave_len = + trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); + let get_aux_packed = |index, step| { + auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) + }; + let num_lookup_columns = all_auxiliary_columns[*table].len(); + res.push( + compute_quotient_polys::( + stark, + &get_trace_packed, + &get_aux_packed, + lookup_challenges, + Some(&ctl_data_per_table[*table]), + &vec![], + alphas.clone(), + Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], + num_lookup_columns, + config, + ) + .expect("Couldn't compute quotient polys."), + ); + } + + // MemBefore. + { + let table = Table::MemBefore; + let stark = &all_stark.mem_before_stark; + let (index_outer, index_inner) = + Table::sorted_index_pair()[Table::table_to_sorted_index()[*table]]; + let trace_leave_len = + trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); + let get_trace_packed = |index, step| { + trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) + }; + let aux_leave_len = + trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); + let get_aux_packed = |index, step| { + auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) + }; + let num_lookup_columns = all_auxiliary_columns[*table].len(); + res.push( + compute_quotient_polys::( + stark, + &get_trace_packed, + &get_aux_packed, + lookup_challenges, + Some(&ctl_data_per_table[*table]), + &vec![], + alphas.clone(), + Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], + num_lookup_columns, + config, + ) + .expect("Couldn't compute quotient polys."), + ); + } + + // MemAfter. + { + let table = Table::MemAfter; + let stark = &all_stark.mem_after_stark; + let (index_outer, index_inner) = + Table::sorted_index_pair()[Table::table_to_sorted_index()[*table]]; let trace_leave_len = trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); let get_trace_packed = |index, step| { @@ -918,17 +1007,17 @@ where let get_aux_packed = |index, step| { auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) }; - let num_lookup_columns = all_auxiliary_columns[*Table::Memory].len(); + let num_lookup_columns = all_auxiliary_columns[*table].len(); res.push( - compute_quotient_polys::, D>( - &all_stark.memory_stark, + compute_quotient_polys::( + stark, &get_trace_packed, &get_aux_packed, lookup_challenges, - Some(&ctl_data_per_table[*Table::Memory]), + Some(&ctl_data_per_table[*table]), &vec![], alphas.clone(), - Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::Memory]], + Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], num_lookup_columns, config, ) From c7dcb86d19c9e4ff5d986c63b05ebb7159b0c816 Mon Sep 17 00:00:00 2001 From: hratoanina Date: Tue, 16 Jul 2024 11:26:07 -0400 Subject: [PATCH 05/24] Update Fri strategy --- evm_arithmetization/src/prover.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index 760d3fdc5..d28998b5b 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -94,7 +94,7 @@ pub(crate) fn zkevm_fast_config() -> StarkConfig { 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(vec![1, 2, 4, 4, 4, 4]), + reduction_strategy: FriReductionStrategy::Fixed(vec![1, 2, 2, 2, 4, 4, 4]), num_query_rounds: 84, }, } From 9472223c2a05e10b9ecdbf57baf5f024960915d8 Mon Sep 17 00:00:00 2001 From: hratoanina Date: Tue, 16 Jul 2024 11:35:53 -0400 Subject: [PATCH 06/24] Fix FFT table vec len --- evm_arithmetization/src/prover.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index d28998b5b..01e26b7cc 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -344,11 +344,12 @@ where .unwrap(); // We compute the Field Merkle Tree of all STARK traces. - let trace_polys_values_sorted_flat = trace_poly_values_sorted + let trace_polys_values_sorted_flat: Vec<_> = trace_poly_values_sorted .clone() .into_iter() .flatten() .collect(); + let num_trace_polys = trace_polys_values_sorted_flat.len(); let trace_commitment = timed!( timing, "compute trace commitments", @@ -358,7 +359,7 @@ where false, cap_height, timing, - &[None; NUM_TABLES], + &vec![None; num_trace_polys], ) ); @@ -402,11 +403,12 @@ where .iter() .map(|&table| auxiliary_columns[*table].clone()) .collect(); - let auxiliary_columns_sorted_flat = auxiliary_columns_sorted + let auxiliary_columns_sorted_flat: Vec<_> = auxiliary_columns_sorted .clone() .into_iter() .flatten() .collect(); + let num_aux_polys = auxiliary_columns_sorted_flat.len(); let auxiliary_commitment = timed!( timing, "compute auxiliary commitments", @@ -416,7 +418,7 @@ where false, cap_height, timing, - &[None; NUM_TABLES], + &vec![None; num_aux_polys], ) ); challenger.observe_cap(&auxiliary_commitment.batch_merkle_tree.cap); From 29b7ce41061b2590f1e2ddc4a275906e8729f3d5 Mon Sep 17 00:00:00 2001 From: hratoanina Date: Tue, 16 Jul 2024 11:46:46 -0400 Subject: [PATCH 07/24] Add missing tables to all_auxiliary_columns --- evm_arithmetization/src/prover.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index 01e26b7cc..20c6dcd11 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -48,6 +48,7 @@ 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; @@ -649,6 +650,34 @@ where ), ); + // 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 } From 791a840845ba5c1064f91cc084bae8374538642f Mon Sep 17 00:00:00 2001 From: hratoanina Date: Tue, 16 Jul 2024 12:15:23 -0400 Subject: [PATCH 08/24] Lower trace length --- evm_arithmetization/src/all_stark.rs | 12 ++++++------ evm_arithmetization/src/prover.rs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/evm_arithmetization/src/all_stark.rs b/evm_arithmetization/src/all_stark.rs index 2dd060c55..54a51a068 100644 --- a/evm_arithmetization/src/all_stark.rs +++ b/evm_arithmetization/src/all_stark.rs @@ -126,9 +126,9 @@ impl Table { pub(crate) const fn all_sorted() -> [Self; NUM_TABLES] { [ Self::Memory, + Self::Cpu, Self::MemBefore, Self::MemAfter, - Self::Cpu, Self::Arithmetic, Self::BytePacking, Self::Logic, @@ -140,7 +140,7 @@ impl Table { /// Returns the ordered position of the tables. This is the inverse of /// `all_sorted()`. pub(crate) const fn table_to_sorted_index() -> [usize; NUM_TABLES] { - [4, 5, 3, 7, 8, 6, 0, 1, 2] + [4, 5, 1, 7, 8, 6, 0, 2, 3] } /// Returns the ordered position of the tables in a batch Merkle tree. Each @@ -149,19 +149,19 @@ impl Table { [ (0, 0), (1, 0), - (1, 1), (2, 0), (2, 1), - (2, 2), - (2, 3), (3, 0), + (3, 1), + (3, 2), + (3, 3), (4, 0), ] } /// Returns all STARK padded trace degrees in descending order. pub(crate) const fn all_degree_logs() -> [usize; NUM_TABLES] { - [23, 22, 22, 20, 20, 20, 20, 18, 16] + [23, 20, 18, 18, 16, 16, 16, 16, 14] } } diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index 20c6dcd11..bbab63ec0 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -95,7 +95,7 @@ pub(crate) fn zkevm_fast_config() -> StarkConfig { 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(vec![1, 2, 2, 2, 4, 4, 4]), + reduction_strategy: FriReductionStrategy::Fixed(vec![3, 2, 2, 2, 4, 4, 2]), num_query_rounds: 84, }, } From 3ca2cf334f575c4d288bd2ea5d3b9f91e9357646 Mon Sep 17 00:00:00 2001 From: hratoanina Date: Tue, 16 Jul 2024 15:35:25 -0400 Subject: [PATCH 09/24] Multiple fixes to batch prover --- evm_arithmetization/src/prover.rs | 938 ++++++++++++------------------ 1 file changed, 386 insertions(+), 552 deletions(-) diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index bbab63ec0..02b35c7b6 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -428,7 +428,9 @@ where let alphas = challenger.get_n_challenges(config.num_challenges); let quotient_polys = all_quotient_polys::( all_stark, + &trace_poly_values_sorted, &trace_commitment, + &auxiliary_columns_sorted, &auxiliary_commitment, &auxiliary_columns, None, @@ -442,11 +444,12 @@ where .iter() .map(|&table| quotient_polys[*table].clone()) .collect(); - let quotient_polys_sorted_flat = quotient_polys_sorted + let quotient_polys_sorted_flat: Vec<_> = quotient_polys_sorted .clone() .into_iter() .flatten() .collect(); + let num_quotient_polys = quotient_polys_sorted_flat.len(); let quotient_commitment = timed!( timing, "compute quotient commitments", @@ -456,7 +459,7 @@ where false, cap_height, timing, - &[None; NUM_TABLES], + &vec![None; num_quotient_polys], ) ); challenger.observe_cap("ient_commitment.batch_merkle_tree.cap); @@ -732,10 +735,76 @@ where 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, + all_auxiliary_columns: &Vec>>, + 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 (index_outer, index_inner) = + Table::sorted_index_pair()[Table::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::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::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::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, + ) + }; + + compute_quotient_polys::( + stark, + &get_trace_packed, + &get_aux_packed, + lookup_challenges, + Some(&ctl_data_per_table[*table]), + &vec![], + alphas, + Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], + stark.num_lookup_helper_columns(config), + config, + ) + .expect("Couldn't compute quotient polys.") +} + /// 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, all_auxiliary_columns: &Vec>>, lookup_challenges: Option<&Vec>, @@ -751,310 +820,138 @@ where let mut res = Vec::new(); // Arithmetic. - { - let table = Table::Arithmetic; - let stark = &all_stark.arithmetic_stark; - let (index_outer, index_inner) = - Table::sorted_index_pair()[Table::table_to_sorted_index()[*table]]; - let trace_leave_len = - trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); - let get_trace_packed = |index, step| { - trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) - }; - let aux_leave_len = - trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); - let get_aux_packed = |index, step| { - auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) - }; - let num_lookup_columns = all_auxiliary_columns[*table].len(); - res.push( - compute_quotient_polys::( - stark, - &get_trace_packed, - &get_aux_packed, - lookup_challenges, - Some(&ctl_data_per_table[*table]), - &vec![], - alphas.clone(), - Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], - num_lookup_columns, - config, - ) - .expect("Couldn't compute quotient polys."), - ); - } + res.push(quotient_polys_single_stark::( + Table::Arithmetic, + &all_stark.arithmetic_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + all_auxiliary_columns, + lookup_challenges, + ctl_data_per_table, + alphas.clone(), + config, + )); // Bytepacking. - { - let table = Table::BytePacking; - let stark = &all_stark.byte_packing_stark; - let (index_outer, index_inner) = - Table::sorted_index_pair()[Table::table_to_sorted_index()[*table]]; - let trace_leave_len = - trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); - let get_trace_packed = |index, step| { - trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) - }; - let aux_leave_len = - trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); - let get_aux_packed = |index, step| { - auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) - }; - let num_lookup_columns = all_auxiliary_columns[*table].len(); - res.push( - compute_quotient_polys::( - stark, - &get_trace_packed, - &get_aux_packed, - lookup_challenges, - Some(&ctl_data_per_table[*table]), - &vec![], - alphas.clone(), - Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], - num_lookup_columns, - config, - ) - .expect("Couldn't compute quotient polys."), - ); - } + res.push(quotient_polys_single_stark::( + Table::BytePacking, + &all_stark.byte_packing_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + all_auxiliary_columns, + lookup_challenges, + ctl_data_per_table, + alphas.clone(), + config, + )); // Cpu. - { - let table = Table::Cpu; - let stark = &all_stark.cpu_stark; - let (index_outer, index_inner) = - Table::sorted_index_pair()[Table::table_to_sorted_index()[*table]]; - let trace_leave_len = - trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); - let get_trace_packed = |index, step| { - trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) - }; - let aux_leave_len = - trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); - let get_aux_packed = |index, step| { - auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) - }; - let num_lookup_columns = all_auxiliary_columns[*table].len(); - res.push( - compute_quotient_polys::( - stark, - &get_trace_packed, - &get_aux_packed, - lookup_challenges, - Some(&ctl_data_per_table[*table]), - &vec![], - alphas.clone(), - Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], - num_lookup_columns, - config, - ) - .expect("Couldn't compute quotient polys."), - ); - } + res.push(quotient_polys_single_stark::( + Table::Cpu, + &all_stark.cpu_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + all_auxiliary_columns, + lookup_challenges, + ctl_data_per_table, + alphas.clone(), + config, + )); // Keccak. - { - let table = Table::Keccak; - let stark = &all_stark.keccak_stark; - let (index_outer, index_inner) = - Table::sorted_index_pair()[Table::table_to_sorted_index()[*table]]; - let trace_leave_len = - trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); - let get_trace_packed = |index, step| { - trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) - }; - let aux_leave_len = - trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); - let get_aux_packed = |index, step| { - auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) - }; - let num_lookup_columns = all_auxiliary_columns[*table].len(); - res.push( - compute_quotient_polys::( - stark, - &get_trace_packed, - &get_aux_packed, - lookup_challenges, - Some(&ctl_data_per_table[*table]), - &vec![], - alphas.clone(), - Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], - num_lookup_columns, - config, - ) - .expect("Couldn't compute quotient polys."), - ); - } + res.push(quotient_polys_single_stark::( + Table::Keccak, + &all_stark.keccak_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + all_auxiliary_columns, + lookup_challenges, + ctl_data_per_table, + alphas.clone(), + config, + )); // KeccakSponge. - { - let table = Table::KeccakSponge; - let stark = &all_stark.keccak_sponge_stark; - let (index_outer, index_inner) = - Table::sorted_index_pair()[Table::table_to_sorted_index()[*table]]; - let trace_leave_len = - trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); - let get_trace_packed = |index, step| { - trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) - }; - let aux_leave_len = - trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); - let get_aux_packed = |index, step| { - auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) - }; - let num_lookup_columns = all_auxiliary_columns[*table].len(); - res.push( - compute_quotient_polys::( - stark, - &get_trace_packed, - &get_aux_packed, - lookup_challenges, - Some(&ctl_data_per_table[*table]), - &vec![], - alphas.clone(), - Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], - num_lookup_columns, - config, - ) - .expect("Couldn't compute quotient polys."), - ); - } + res.push(quotient_polys_single_stark::( + Table::KeccakSponge, + &all_stark.keccak_sponge_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + all_auxiliary_columns, + lookup_challenges, + ctl_data_per_table, + alphas.clone(), + config, + )); // Logic. - { - let table = Table::Logic; - let stark = &all_stark.logic_stark; - let (index_outer, index_inner) = - Table::sorted_index_pair()[Table::table_to_sorted_index()[*table]]; - let trace_leave_len = - trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); - let get_trace_packed = |index, step| { - trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) - }; - let aux_leave_len = - trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); - let get_aux_packed = |index, step| { - auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) - }; - let num_lookup_columns = all_auxiliary_columns[*table].len(); - res.push( - compute_quotient_polys::( - stark, - &get_trace_packed, - &get_aux_packed, - lookup_challenges, - Some(&ctl_data_per_table[*table]), - &vec![], - alphas.clone(), - Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], - num_lookup_columns, - config, - ) - .expect("Couldn't compute quotient polys."), - ); - } - + res.push(quotient_polys_single_stark::( + Table::Logic, + &all_stark.logic_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + all_auxiliary_columns, + lookup_challenges, + ctl_data_per_table, + alphas.clone(), + config, + )); // Memory. - { - let table = Table::Memory; - let stark = &all_stark.memory_stark; - let (index_outer, index_inner) = - Table::sorted_index_pair()[Table::table_to_sorted_index()[*table]]; - let trace_leave_len = - trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); - let get_trace_packed = |index, step| { - trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) - }; - let aux_leave_len = - trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); - let get_aux_packed = |index, step| { - auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) - }; - let num_lookup_columns = all_auxiliary_columns[*table].len(); - res.push( - compute_quotient_polys::( - stark, - &get_trace_packed, - &get_aux_packed, - lookup_challenges, - Some(&ctl_data_per_table[*table]), - &vec![], - alphas.clone(), - Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], - num_lookup_columns, - config, - ) - .expect("Couldn't compute quotient polys."), - ); - } + res.push(quotient_polys_single_stark::( + Table::Memory, + &all_stark.memory_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + all_auxiliary_columns, + lookup_challenges, + ctl_data_per_table, + alphas.clone(), + config, + )); // MemBefore. - { - let table = Table::MemBefore; - let stark = &all_stark.mem_before_stark; - let (index_outer, index_inner) = - Table::sorted_index_pair()[Table::table_to_sorted_index()[*table]]; - let trace_leave_len = - trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); - let get_trace_packed = |index, step| { - trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) - }; - let aux_leave_len = - trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); - let get_aux_packed = |index, step| { - auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) - }; - let num_lookup_columns = all_auxiliary_columns[*table].len(); - res.push( - compute_quotient_polys::( - stark, - &get_trace_packed, - &get_aux_packed, - lookup_challenges, - Some(&ctl_data_per_table[*table]), - &vec![], - alphas.clone(), - Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], - num_lookup_columns, - config, - ) - .expect("Couldn't compute quotient polys."), - ); - } + res.push(quotient_polys_single_stark::( + Table::MemBefore, + &all_stark.mem_before_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + all_auxiliary_columns, + lookup_challenges, + ctl_data_per_table, + alphas.clone(), + config, + )); // MemAfter. - { - let table = Table::MemAfter; - let stark = &all_stark.mem_after_stark; - let (index_outer, index_inner) = - Table::sorted_index_pair()[Table::table_to_sorted_index()[*table]]; - let trace_leave_len = - trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); - let get_trace_packed = |index, step| { - trace_commitment.get_lde_values_packed::

(0, index, step, 0, trace_leave_len) - }; - let aux_leave_len = - trace_commitment.batch_merkle_tree.leaves[index_outer][index_inner].len(); - let get_aux_packed = |index, step| { - auxiliary_commitment.get_lde_values_packed(0, index, step, 0, aux_leave_len) - }; - let num_lookup_columns = all_auxiliary_columns[*table].len(); - res.push( - compute_quotient_polys::( - stark, - &get_trace_packed, - &get_aux_packed, - lookup_challenges, - Some(&ctl_data_per_table[*table]), - &vec![], - alphas.clone(), - Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], - num_lookup_columns, - config, - ) - .expect("Couldn't compute quotient polys."), - ); - } + res.push(quotient_polys_single_stark::( + Table::MemAfter, + &all_stark.mem_after_stark, + trace_poly_values_sorted, + trace_commitment, + auxiliary_columns_sorted, + auxiliary_commitment, + all_auxiliary_columns, + lookup_challenges, + ctl_data_per_table, + alphas.clone(), + config, + )); res } @@ -1179,9 +1076,90 @@ where )); } + // MemBefore. + { + let g = F::primitive_root_of_unity( + degree_bits[Table::table_to_sorted_index()[*Table::MemBefore]], + ); + let num_ctl_helper_polys = ctl_data_per_table[*Table::MemBefore].num_ctl_helper_polys(); + res.push(all_stark.mem_before_stark.fri_instance( + zeta, + g, + num_ctl_helper_polys.iter().sum(), + num_ctl_helper_polys, + config, + )); + } + + // Memory. + { + let g = F::primitive_root_of_unity( + degree_bits[Table::table_to_sorted_index()[*Table::MemAfter]], + ); + let num_ctl_helper_polys = ctl_data_per_table[*Table::MemAfter].num_ctl_helper_polys(); + res.push(all_stark.mem_after_stark.fri_instance( + zeta, + g, + num_ctl_helper_polys.iter().sum(), + num_ctl_helper_polys, + config, + )); + } + 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( + Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], + ); + let table_sorted_index = Table::table_to_sorted_index()[*table]; + let (_, index_inner) = Table::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..index_inner { + let prev_sorted_table = 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, @@ -1203,283 +1181,139 @@ where let mut res = Vec::new(); // Arithmetic. - { - let stark = all_stark.arithmetic_stark; - let table = Table::Arithmetic; - let g = F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*table]]); - let table_sorted_index = Table::table_to_sorted_index()[*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..table_sorted_index { - 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(); - } - - let num_trace_polys = res.push(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..auxiliary_columns_sorted[table_sorted_index].len(), - quotient_commitment, - 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(), - )); - } + 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. - { - let stark = all_stark.byte_packing_stark; - let table = Table::BytePacking; - let g = F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*table]]); - let table_sorted_index = Table::table_to_sorted_index()[*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..table_sorted_index { - 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(); - } - - let num_trace_polys = res.push(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..auxiliary_columns_sorted[table_sorted_index].len(), - quotient_commitment, - 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(), - )); - } + 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. - { - let stark = all_stark.cpu_stark; - let table = Table::Cpu; - let g = F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*table]]); - let table_sorted_index = Table::table_to_sorted_index()[*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..table_sorted_index { - 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(); - } - - let num_trace_polys = res.push(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..auxiliary_columns_sorted[table_sorted_index].len(), - quotient_commitment, - 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(), - )); - } + 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. - { - let stark = all_stark.keccak_stark; - let table = Table::Keccak; - let g = F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*table]]); - let table_sorted_index = Table::table_to_sorted_index()[*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..table_sorted_index { - 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(); - } - - let num_trace_polys = res.push(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..auxiliary_columns_sorted[table_sorted_index].len(), - quotient_commitment, - 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(), - )); - } + 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. - { - let stark = all_stark.keccak_sponge_stark; - let table = Table::KeccakSponge; - let g = F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*table]]); - let table_sorted_index = Table::table_to_sorted_index()[*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..table_sorted_index { - 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(); - } - - let num_trace_polys = res.push(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..auxiliary_columns_sorted[table_sorted_index].len(), - quotient_commitment, - 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(), - )); - } + 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. - { - let stark = all_stark.logic_stark; - let table = Table::Logic; - let g = F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*table]]); - let table_sorted_index = Table::table_to_sorted_index()[*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..table_sorted_index { - 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(); - } - - let num_trace_polys = res.push(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..auxiliary_columns_sorted[table_sorted_index].len(), - quotient_commitment, - 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(), - )); - } + 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. - { - let stark = all_stark.memory_stark; - let table = Table::Memory; - let g = F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*table]]); - let table_sorted_index = Table::table_to_sorted_index()[*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..table_sorted_index { - 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(); - } - - let num_trace_polys = res.push(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..auxiliary_columns_sorted[table_sorted_index].len(), - quotient_commitment, - 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(), - )); - } + 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. - { - let stark = all_stark.mem_before_stark; - let table = Table::MemBefore; - let g = F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*table]]); - let table_sorted_index = Table::table_to_sorted_index()[*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..table_sorted_index { - 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(); - } - - let num_trace_polys = res.push(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..auxiliary_columns_sorted[table_sorted_index].len(), - quotient_commitment, - 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(), - )); - } + 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 stark = all_stark.mem_after_stark; - let table = Table::MemAfter; - let g = F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*table]]); - let table_sorted_index = Table::table_to_sorted_index()[*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..table_sorted_index { - 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(); - } - - let num_trace_polys = res.push(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..auxiliary_columns_sorted[table_sorted_index].len(), - quotient_commitment, - 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(), - )); - } + res.push(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, + )); res } From 76cd6fa5bc123bdcb8a2dc35aa262fe0f0565762 Mon Sep 17 00:00:00 2001 From: hratoanina Date: Wed, 17 Jul 2024 18:45:34 -0400 Subject: [PATCH 10/24] Fix instances --- evm_arithmetization/src/prover.rs | 286 +++++++++++++++++------------- 1 file changed, 158 insertions(+), 128 deletions(-) diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index 02b35c7b6..7bee4cc9b 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -1,3 +1,4 @@ +use std::any::type_name; use std::iter::once; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; @@ -95,7 +96,7 @@ pub(crate) fn zkevm_fast_config() -> StarkConfig { 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(vec![3, 2, 2, 2, 4, 4, 2]), + reduction_strategy: FriReductionStrategy::Fixed(vec![2, 2, 2, 4, 4, 2]), num_query_rounds: 84, }, } @@ -477,13 +478,13 @@ where "Opening point is in the subgroup." ); - let mut all_fri_instances = all_fri_instance_info( + let all_fri_instances = all_fri_instance_info::( all_stark, - &trace_commitment, - &auxiliary_commitment, - &ctl_data_per_table, - alphas, zeta, + &trace_poly_values_sorted, + &auxiliary_columns_sorted, + "ient_polys_sorted, + &ctl_data_per_table, config, ); @@ -754,6 +755,7 @@ where C: GenericConfig, S: Stark, { + println!("Computing quotients for {:?}...", type_name::(),); let (index_outer, index_inner) = Table::sorted_index_pair()[Table::table_to_sorted_index()[*table]]; let mut num_trace_polys_before = 0; @@ -956,157 +958,185 @@ where res } +/// Generates all FRI instances. They are sorted by decreasing degree. +fn fri_instance_info_single_stark( + table: Table, + stark: &S, + zeta: F::Extension, + trace_poly_values_sorted: &[Vec>; NUM_TABLES], + auxiliary_columns_sorted: &Vec>>, + quotient_polys_sorted: &Vec>>, + ctl_data_per_table: &[CtlData; NUM_TABLES], + config: &StarkConfig, +) -> FriInstanceInfo +where + F: RichField + Extendable, + C: GenericConfig, + S: Stark, +{ + let g = F::primitive_root_of_unity( + Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], + ); + let sorted_index = Table::table_to_sorted_index()[*table]; + let num_ctl_helper_polys = ctl_data_per_table[*table].num_ctl_helper_polys(); + 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 { + let prev_sorted_table = 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(); + } + let num_aux_columns = auxiliary_columns_sorted[sorted_index].len(); + let num_quotient_polys = quotient_polys_sorted[sorted_index].len(); + let num_cols_before_ctlzs = num_aux_polys_before + + stark.num_lookup_helper_columns(config) + + ctl_data_per_table[*table] + .num_ctl_helper_polys() + .iter() + .sum::(); + + 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. fn all_fri_instance_info( all_stark: &AllStark, - trace_commitment: &BatchFriOracle, - auxiliary_commitment: &BatchFriOracle, - ctl_data_per_table: &[CtlData; NUM_TABLES], - alphas: Vec, zeta: F::Extension, + trace_poly_values_sorted: &[Vec>; NUM_TABLES], + auxiliary_columns_sorted: &Vec>>, + quotient_polys_sorted: &Vec>>, + ctl_data_per_table: &[CtlData; NUM_TABLES], config: &StarkConfig, - // ctl_data_per_table: &[CtlData; NUM_TABLES], - // ctl_challenges: &GrandProductChallengeSet, ) -> Vec> where F: RichField + Extendable, C: GenericConfig, { - let degree_bits = Table::all_degree_logs(); let mut res = Vec::new(); // Arithmetic. - { - let g = F::primitive_root_of_unity( - degree_bits[Table::table_to_sorted_index()[*Table::Arithmetic]], - ); - let num_ctl_helper_polys = ctl_data_per_table[*Table::Arithmetic].num_ctl_helper_polys(); - res.push(all_stark.arithmetic_stark.fri_instance( - zeta, - g, - num_ctl_helper_polys.iter().sum(), - num_ctl_helper_polys, - config, - )); - } + res.push(fri_instance_info_single_stark::( + Table::Arithmetic, + &all_stark.arithmetic_stark, + zeta, + trace_poly_values_sorted, + auxiliary_columns_sorted, + quotient_polys_sorted, + ctl_data_per_table, + config, + )); // BytePacking. - { - let g = F::primitive_root_of_unity( - degree_bits[Table::table_to_sorted_index()[*Table::BytePacking]], - ); - let num_ctl_helper_polys = ctl_data_per_table[*Table::BytePacking].num_ctl_helper_polys(); - res.push(all_stark.byte_packing_stark.fri_instance( - zeta, - g, - num_ctl_helper_polys.iter().sum(), - num_ctl_helper_polys, - config, - )); - } + res.push(fri_instance_info_single_stark::( + Table::BytePacking, + &all_stark.byte_packing_stark, + zeta, + trace_poly_values_sorted, + auxiliary_columns_sorted, + quotient_polys_sorted, + ctl_data_per_table, + config, + )); // Cpu. - { - let g = - F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*Table::Cpu]]); - let num_ctl_helper_polys = ctl_data_per_table[*Table::Cpu].num_ctl_helper_polys(); - res.push(all_stark.cpu_stark.fri_instance( - zeta, - g, - num_ctl_helper_polys.iter().sum(), - num_ctl_helper_polys, - config, - )); - } + res.push(fri_instance_info_single_stark::( + Table::Cpu, + &all_stark.cpu_stark, + zeta, + trace_poly_values_sorted, + auxiliary_columns_sorted, + quotient_polys_sorted, + ctl_data_per_table, + config, + )); // Keccak. - { - let g = - F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*Table::Keccak]]); - let num_ctl_helper_polys = ctl_data_per_table[*Table::Keccak].num_ctl_helper_polys(); - res.push(all_stark.keccak_stark.fri_instance( - zeta, - g, - num_ctl_helper_polys.iter().sum(), - num_ctl_helper_polys, - config, - )); - } + res.push(fri_instance_info_single_stark::( + Table::Keccak, + &all_stark.keccak_stark, + zeta, + trace_poly_values_sorted, + auxiliary_columns_sorted, + quotient_polys_sorted, + ctl_data_per_table, + config, + )); // KeccakSponge. - { - let g = F::primitive_root_of_unity( - degree_bits[Table::table_to_sorted_index()[*Table::KeccakSponge]], - ); - let num_ctl_helper_polys = ctl_data_per_table[*Table::KeccakSponge].num_ctl_helper_polys(); - res.push(all_stark.keccak_sponge_stark.fri_instance( - zeta, - g, - num_ctl_helper_polys.iter().sum(), - num_ctl_helper_polys, - config, - )); - } + res.push(fri_instance_info_single_stark::( + Table::KeccakSponge, + &all_stark.keccak_sponge_stark, + zeta, + trace_poly_values_sorted, + auxiliary_columns_sorted, + quotient_polys_sorted, + ctl_data_per_table, + config, + )); // Logic. - { - let g = - F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*Table::Logic]]); - let num_ctl_helper_polys = ctl_data_per_table[*Table::Logic].num_ctl_helper_polys(); - res.push(all_stark.logic_stark.fri_instance( - zeta, - g, - num_ctl_helper_polys.iter().sum(), - num_ctl_helper_polys, - config, - )); - } + res.push(fri_instance_info_single_stark::( + Table::Logic, + &all_stark.logic_stark, + zeta, + trace_poly_values_sorted, + auxiliary_columns_sorted, + quotient_polys_sorted, + ctl_data_per_table, + config, + )); // Memory. - { - let g = - F::primitive_root_of_unity(degree_bits[Table::table_to_sorted_index()[*Table::Memory]]); - let num_ctl_helper_polys = ctl_data_per_table[*Table::Memory].num_ctl_helper_polys(); - res.push(all_stark.memory_stark.fri_instance( - zeta, - g, - num_ctl_helper_polys.iter().sum(), - num_ctl_helper_polys, - config, - )); - } + res.push(fri_instance_info_single_stark::( + Table::Memory, + &all_stark.memory_stark, + zeta, + trace_poly_values_sorted, + auxiliary_columns_sorted, + quotient_polys_sorted, + ctl_data_per_table, + config, + )); // MemBefore. - { - let g = F::primitive_root_of_unity( - degree_bits[Table::table_to_sorted_index()[*Table::MemBefore]], - ); - let num_ctl_helper_polys = ctl_data_per_table[*Table::MemBefore].num_ctl_helper_polys(); - res.push(all_stark.mem_before_stark.fri_instance( - zeta, - g, - num_ctl_helper_polys.iter().sum(), - num_ctl_helper_polys, - config, - )); - } + res.push(fri_instance_info_single_stark::( + Table::MemBefore, + &all_stark.mem_before_stark, + zeta, + trace_poly_values_sorted, + auxiliary_columns_sorted, + quotient_polys_sorted, + ctl_data_per_table, + config, + )); - // Memory. - { - let g = F::primitive_root_of_unity( - degree_bits[Table::table_to_sorted_index()[*Table::MemAfter]], - ); - let num_ctl_helper_polys = ctl_data_per_table[*Table::MemAfter].num_ctl_helper_polys(); - res.push(all_stark.mem_after_stark.fri_instance( - zeta, - g, - num_ctl_helper_polys.iter().sum(), - num_ctl_helper_polys, - config, - )); - } + // MemAfter. + res.push(fri_instance_info_single_stark::( + Table::MemAfter, + &all_stark.mem_after_stark, + zeta, + trace_poly_values_sorted, + auxiliary_columns_sorted, + quotient_polys_sorted, + ctl_data_per_table, + config, + )); - res + Table::all_sorted() + .iter() + .map(|&table| res[*table].clone()) + .collect() } fn all_openings_single_stark( From c9ed24ce26e962bf59fc87cf903f7b9f75e109a7 Mon Sep 17 00:00:00 2001 From: hratoanina Date: Thu, 18 Jul 2024 10:58:50 -0400 Subject: [PATCH 11/24] Chunk quotient polynomials --- evm_arithmetization/src/prover.rs | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index 7bee4cc9b..3f25b44eb 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -24,6 +24,7 @@ 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; @@ -425,7 +426,7 @@ where ); challenger.observe_cap(&auxiliary_commitment.batch_merkle_tree.cap); - // Quotient polynomials. + // Quotient polynomials. They are already chunked in `degree` pieces. let alphas = challenger.get_n_challenges(config.num_challenges); let quotient_polys = all_quotient_polys::( all_stark, @@ -755,7 +756,7 @@ where C: GenericConfig, S: Stark, { - println!("Computing quotients for {:?}...", type_name::(),); + let degree_bits = Table::all_degree_logs()[Table::table_to_sorted_index()[*table]]; let (index_outer, index_inner) = Table::sorted_index_pair()[Table::table_to_sorted_index()[*table]]; let mut num_trace_polys_before = 0; @@ -786,7 +787,7 @@ where ) }; - compute_quotient_polys::( + let quotient_polys = compute_quotient_polys::( stark, &get_trace_packed, &get_aux_packed, @@ -794,11 +795,24 @@ where Some(&ctl_data_per_table[*table]), &vec![], alphas, - Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], + degree_bits, stark.num_lookup_helper_columns(config), config, ) - .expect("Couldn't compute quotient polys.") + .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. From a3c23aa7a218a7c6c02e42f0f4eb4fd7c25f2bc9 Mon Sep 17 00:00:00 2001 From: hratoanina Date: Fri, 19 Jul 2024 00:02:45 -0400 Subject: [PATCH 12/24] Fix fri instances --- evm_arithmetization/src/prover.rs | 62 ++++++++++++++++++-- evm_arithmetization/tests/simple_transfer.rs | 3 +- 2 files changed, 59 insertions(+), 6 deletions(-) diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index 3f25b44eb..c4eaaaf6f 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -15,7 +15,7 @@ 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::{FriInstanceInfo, FriOpeningBatch}; +use plonky2::fri::structure::{FriInstanceInfo, FriOpeningBatch, FriOracleInfo}; use plonky2::fri::FriConfig; use plonky2::hash::hash_types::RichField; use plonky2::hash::merkle_tree::MerkleCap; @@ -87,7 +87,7 @@ impl GenerationSegmentData { } } -pub(crate) fn zkevm_fast_config() -> StarkConfig { +pub fn zkevm_fast_config() -> StarkConfig { StarkConfig { security_bits: 100, num_challenges: 2, @@ -515,8 +515,10 @@ where "ient_commitment, ]; + let mut degree_bits_squashed = Table::all_degree_logs().to_vec(); + degree_bits_squashed.dedup(); let opening_proof = BatchFriOracle::prove_openings( - &Table::all_degree_logs(), + °ree_bits_squashed, &all_fri_instances, &initial_merkle_trees, &mut challenger, @@ -1147,10 +1149,60 @@ where config, )); - Table::all_sorted() + let res_sorted: Vec<_> = Table::all_sorted() .iter() .map(|&table| res[*table].clone()) - .collect() + .collect(); + + let mut squashed_res = Vec::new(); + let mut i = 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![], + }; + + while i < NUM_TABLES { + let instance = &res_sorted[i]; + for (k, oracle) in instance.oracles.iter().enumerate() { + current_instance.oracles[k].num_polys += oracle.num_polys; + } + current_instance.batches.extend(instance.batches.clone()); + + if i == NUM_TABLES - 1 || Table::all_degree_logs()[i + 1] < Table::all_degree_logs()[i] { + squashed_res.push(current_instance.clone()); + current_instance.oracles = vec![ + FriOracleInfo { + num_polys: 0, + blinding: false, + }, + FriOracleInfo { + num_polys: 0, + blinding: false, + }, + FriOracleInfo { + num_polys: 0, + blinding: false, + }, + ]; + current_instance.batches = vec![]; + } + i += 1; + } + + squashed_res } fn all_openings_single_stark( diff --git a/evm_arithmetization/tests/simple_transfer.rs b/evm_arithmetization/tests/simple_transfer.rs index 7e3e00b8e..c68ed0976 100644 --- a/evm_arithmetization/tests/simple_transfer.rs +++ b/evm_arithmetization/tests/simple_transfer.rs @@ -8,6 +8,7 @@ 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, 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; @@ -31,7 +32,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"); From e78b987bbfde3b1154e5e00f3dcb1e5e634ee880 Mon Sep 17 00:00:00 2001 From: hratoanina Date: Fri, 19 Jul 2024 09:06:39 -0400 Subject: [PATCH 13/24] Update ranges --- evm_arithmetization/src/all_stark.rs | 12 ++++++------ evm_arithmetization/src/prover.rs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/evm_arithmetization/src/all_stark.rs b/evm_arithmetization/src/all_stark.rs index 54a51a068..2dd060c55 100644 --- a/evm_arithmetization/src/all_stark.rs +++ b/evm_arithmetization/src/all_stark.rs @@ -126,9 +126,9 @@ impl Table { pub(crate) const fn all_sorted() -> [Self; NUM_TABLES] { [ Self::Memory, - Self::Cpu, Self::MemBefore, Self::MemAfter, + Self::Cpu, Self::Arithmetic, Self::BytePacking, Self::Logic, @@ -140,7 +140,7 @@ impl Table { /// Returns the ordered position of the tables. This is the inverse of /// `all_sorted()`. pub(crate) const fn table_to_sorted_index() -> [usize; NUM_TABLES] { - [4, 5, 1, 7, 8, 6, 0, 2, 3] + [4, 5, 3, 7, 8, 6, 0, 1, 2] } /// Returns the ordered position of the tables in a batch Merkle tree. Each @@ -149,19 +149,19 @@ impl Table { [ (0, 0), (1, 0), + (1, 1), (2, 0), (2, 1), + (2, 2), + (2, 3), (3, 0), - (3, 1), - (3, 2), - (3, 3), (4, 0), ] } /// Returns all STARK padded trace degrees in descending order. pub(crate) const fn all_degree_logs() -> [usize; NUM_TABLES] { - [23, 20, 18, 18, 16, 16, 16, 16, 14] + [23, 22, 22, 20, 20, 20, 20, 18, 16] } } diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index c4eaaaf6f..801ee87bf 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -97,7 +97,7 @@ pub fn zkevm_fast_config() -> StarkConfig { 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(vec![2, 2, 2, 4, 4, 2]), + reduction_strategy: FriReductionStrategy::Fixed(vec![1, 2, 2, 2, 4, 4, 4]), num_query_rounds: 84, }, } From e977e600b3f99be427ede66dbfd02a82dcef8773 Mon Sep 17 00:00:00 2001 From: hratoanina Date: Fri, 19 Jul 2024 12:46:13 -0400 Subject: [PATCH 14/24] Define ranges dynamically --- evm_arithmetization/src/all_stark.rs | 99 +++++++++++++++++++++------- evm_arithmetization/src/prover.rs | 22 ++++++- 2 files changed, 95 insertions(+), 26 deletions(-) diff --git a/evm_arithmetization/src/all_stark.rs b/evm_arithmetization/src/all_stark.rs index 2dd060c55..b6fddaf71 100644 --- a/evm_arithmetization/src/all_stark.rs +++ b/evm_arithmetization/src/all_stark.rs @@ -105,6 +105,18 @@ 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] = [ + 20, // Arithmetic + 20, // BytePacking, + 20, // Cpu, + 18, // Keccak, + 16, // KeccakSponge, + 20, // Logic, + 23, // Memory, + 22, // MemBefore, + 22, // MemAfter, +]; + impl Table { /// Returns all STARK table indices. pub(crate) const fn all() -> [Self; NUM_TABLES] { @@ -124,44 +136,83 @@ impl Table { /// Returns all STARK table indices in descending order of their padded /// trace degrees. pub(crate) const fn all_sorted() -> [Self; NUM_TABLES] { - [ - Self::Memory, - Self::MemBefore, - Self::MemAfter, - Self::Cpu, - Self::Arithmetic, - Self::BytePacking, - Self::Logic, - Self::Keccak, - Self::KeccakSponge, - ] + 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()`. pub(crate) const fn table_to_sorted_index() -> [usize; NUM_TABLES] { - [4, 5, 3, 7, 8, 6, 0, 1, 2] + 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. pub(crate) const fn sorted_index_pair() -> [(usize, usize); NUM_TABLES] { - [ - (0, 0), - (1, 0), - (1, 1), - (2, 0), - (2, 1), - (2, 2), - (2, 3), - (3, 0), - (4, 0), - ] + 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] = (inner, outer); + i += 1; + } + + pairs } /// Returns all STARK padded trace degrees in descending order. pub(crate) const fn all_degree_logs() -> [usize; NUM_TABLES] { - [23, 22, 22, 20, 20, 20, 20, 18, 16] + let mut res = [0; NUM_TABLES]; + let mut i = 0; + while i < NUM_TABLES { + res[i] = TABLE_DEGREES[Self::all()[i] as usize]; + i += 1; + } + + res } } diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index 801ee87bf..de32ec209 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -88,16 +88,34 @@ impl GenerationSegmentData { } pub fn zkevm_fast_config() -> StarkConfig { + let cap_height = 4; + let mut strategy = Vec::new(); + for window in Table::all_degree_logs().windows(2) { + if window[0] != window[1] { + strategy.push(window[1] - window[0]); + } + } + let mut last_degree = Table::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: 4, + 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(vec![1, 2, 2, 2, 4, 4, 4]), + reduction_strategy: FriReductionStrategy::Fixed(strategy), num_query_rounds: 84, }, } From f4f936cbecafb8908e656ca1d65fcbea837c9e6e Mon Sep 17 00:00:00 2001 From: hratoanina Date: Fri, 19 Jul 2024 13:13:22 -0400 Subject: [PATCH 15/24] Small fixes --- evm_arithmetization/src/all_stark.rs | 4 ++-- evm_arithmetization/src/prover.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/evm_arithmetization/src/all_stark.rs b/evm_arithmetization/src/all_stark.rs index b6fddaf71..dddb14358 100644 --- a/evm_arithmetization/src/all_stark.rs +++ b/evm_arithmetization/src/all_stark.rs @@ -196,7 +196,7 @@ impl Table { } else { inner += 1; } - pairs[i] = (inner, outer); + pairs[i] = (outer, inner); i += 1; } @@ -208,7 +208,7 @@ impl Table { let mut res = [0; NUM_TABLES]; let mut i = 0; while i < NUM_TABLES { - res[i] = TABLE_DEGREES[Self::all()[i] as usize]; + res[i] = TABLE_DEGREES[Self::all_sorted()[i] as usize]; i += 1; } diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index de32ec209..12360e02d 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -92,7 +92,7 @@ pub fn zkevm_fast_config() -> StarkConfig { let mut strategy = Vec::new(); for window in Table::all_degree_logs().windows(2) { if window[0] != window[1] { - strategy.push(window[1] - window[0]); + strategy.push(window[0] - window[1]); } } let mut last_degree = Table::all_degree_logs()[NUM_TABLES - 1]; From 91e7a698ccce3b9961cfc7f650dec3245655a775 Mon Sep 17 00:00:00 2001 From: hratoanina Date: Wed, 24 Jul 2024 19:07:57 -0400 Subject: [PATCH 16/24] Fix continuation traces padding --- .../memory_continuation_stark.rs | 4 ++-- evm_arithmetization/src/witness/traces.rs | 16 +++++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/evm_arithmetization/src/memory_continuation/memory_continuation_stark.rs b/evm_arithmetization/src/memory_continuation/memory_continuation_stark.rs index cd160852c..77e3d470b 100644 --- a/evm_arithmetization/src/memory_continuation/memory_continuation_stark.rs +++ b/evm_arithmetization/src/memory_continuation/memory_continuation_stark.rs @@ -79,14 +79,14 @@ 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 = - 1 << Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::MemBefore]]; + let num_rows_padded = 1 << log_padded; for _ in num_rows..num_rows_padded { rows.push(vec![F::ZERO; NUM_COLUMNS]); } diff --git a/evm_arithmetization/src/witness/traces.rs b/evm_arithmetization/src/witness/traces.rs index d033dbbb9..70ff0df43 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, NUM_TABLES}; 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), + Table::all_degree_logs()[Table::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(), + Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::MemAfter]] + ) ); log::info!( From 94ec3466820a27434716310c6ead1609f9ba5c30 Mon Sep 17 00:00:00 2001 From: hratoanina Date: Mon, 29 Jul 2024 16:17:40 -0400 Subject: [PATCH 17/24] Address some comments --- evm_arithmetization/src/all_stark.rs | 34 +++-- .../src/arithmetic/arithmetic_stark.rs | 5 +- .../src/byte_packing/byte_packing_stark.rs | 5 +- evm_arithmetization/src/generation/mod.rs | 6 +- .../src/keccak/keccak_stark.rs | 5 +- .../src/keccak_sponge/keccak_sponge_stark.rs | 5 +- evm_arithmetization/src/logic.rs | 5 +- .../src/memory/memory_stark.rs | 5 +- evm_arithmetization/src/prover.rs | 121 ++++++++---------- evm_arithmetization/src/util.rs | 2 +- evm_arithmetization/src/witness/traces.rs | 6 +- 11 files changed, 94 insertions(+), 105 deletions(-) diff --git a/evm_arithmetization/src/all_stark.rs b/evm_arithmetization/src/all_stark.rs index dddb14358..4a874e797 100644 --- a/evm_arithmetization/src/all_stark.rs +++ b/evm_arithmetization/src/all_stark.rs @@ -106,17 +106,25 @@ impl Deref for Table { pub(crate) const NUM_TABLES: usize = Table::MemAfter as usize + 1; pub(crate) const TABLE_DEGREES: [usize; NUM_TABLES] = [ - 20, // Arithmetic - 20, // BytePacking, - 20, // Cpu, - 18, // Keccak, - 16, // KeccakSponge, - 20, // Logic, - 23, // Memory, - 22, // MemBefore, - 22, // MemAfter, + 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] { @@ -135,7 +143,7 @@ impl Table { /// Returns all STARK table indices in descending order of their padded /// trace degrees. - pub(crate) const fn all_sorted() -> [Self; NUM_TABLES] { + const fn all_sorted() -> [Self; NUM_TABLES] { let mut sorted_pairs = [(0, Table::Arithmetic); NUM_TABLES]; let mut i = 0; while i < NUM_TABLES { @@ -170,7 +178,7 @@ impl Table { /// Returns the ordered position of the tables. This is the inverse of /// `all_sorted()`. - pub(crate) const fn table_to_sorted_index() -> [usize; NUM_TABLES] { + const fn table_to_sorted_index() -> [usize; NUM_TABLES] { let mut res = [0; NUM_TABLES]; let mut i = 0; while i < NUM_TABLES { @@ -183,7 +191,7 @@ impl Table { /// Returns the ordered position of the tables in a batch Merkle tree. Each /// entry is a couple to account for duplicate sizes. - pub(crate) const fn sorted_index_pair() -> [(usize, usize); NUM_TABLES] { + const fn sorted_index_pair() -> [(usize, usize); NUM_TABLES] { let mut pairs = [(0, 0); NUM_TABLES]; let mut outer = 0; @@ -204,7 +212,7 @@ impl Table { } /// Returns all STARK padded trace degrees in descending order. - pub(crate) const fn all_degree_logs() -> [usize; NUM_TABLES] { + const fn all_degree_logs() -> [usize; NUM_TABLES] { let mut res = [0; NUM_TABLES]; let mut i = 0; while i < NUM_TABLES { diff --git a/evm_arithmetization/src/arithmetic/arithmetic_stark.rs b/evm_arithmetization/src/arithmetic/arithmetic_stark.rs index ede0b47cc..ef4d0cbfb 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,8 +178,7 @@ 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 = - 1 << Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::Arithmetic]]; + let padded_len = 1 << ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::Arithmetic]]; 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/byte_packing/byte_packing_stark.rs b/evm_arithmetization/src/byte_packing/byte_packing_stark.rs index 08b8df204..d6cb35981 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, Table}; +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,8 +175,7 @@ impl, const D: usize> BytePackingStark { ops: Vec, min_rows: usize, ) -> Vec<[F; NUM_COLUMNS]> { - let num_rows = - 1 << Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::BytePacking]]; + let num_rows = 1 << ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::BytePacking]]; let mut rows = Vec::with_capacity(num_rows); diff --git a/evm_arithmetization/src/generation/mod.rs b/evm_arithmetization/src/generation/mod.rs index 25174268a..6e3c8a961 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, Table, 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; @@ -490,9 +490,7 @@ fn simulate_cpu( // Padding. state.push_cpu(row); row.clock += F::ONE; - if state.traces.clock() - == 1 << Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::Cpu]] - { + 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 bd8014157..9fb472340 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, Table}; +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,8 +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 = - 1 << Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::Keccak]]; + 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() { diff --git a/evm_arithmetization/src/keccak_sponge/keccak_sponge_stark.rs b/evm_arithmetization/src/keccak_sponge/keccak_sponge_stark.rs index 27e568e05..ee81dc99b 100644 --- a/evm_arithmetization/src/keccak_sponge/keccak_sponge_stark.rs +++ b/evm_arithmetization/src/keccak_sponge/keccak_sponge_stark.rs @@ -19,7 +19,7 @@ use starky::evaluation_frame::StarkEvaluationFrame; use starky::lookup::{Column, Filter, Lookup}; use starky::stark::Stark; -use crate::all_stark::{EvmStarkFrame, Table}; +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; @@ -290,8 +290,7 @@ impl, const D: usize> KeccakSpongeStark { rows.extend(self.generate_rows_for_op(op)); } // Pad the trace. - let padded_rows = - 1 << Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::KeccakSponge]]; + let padded_rows = 1 << ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::KeccakSponge]]; for _ in rows.len()..padded_rows { rows.push(self.generate_padding_row()); } diff --git a/evm_arithmetization/src/logic.rs b/evm_arithmetization/src/logic.rs index d420df3a2..ea3f94e8c 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, Table}; +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,8 +220,7 @@ impl LogicStark { min_rows: usize, ) -> Vec<[F; NUM_COLUMNS]> { let len = operations.len(); - let padded_len = - 1 << Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::Logic]]; + let padded_len = 1 << ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::Logic]]; 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 8a6a9f7b4..e03687224 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,8 +353,7 @@ 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 = - 1 << Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::Memory]]; + let num_ops_padded = 1 << ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::Memory]]; for _ in num_ops..num_ops_padded { memory_ops.push(padding_op); } diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index 12360e02d..7398a0c18 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -1,5 +1,6 @@ use std::any::type_name; use std::iter::once; +use std::mem::swap; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; @@ -36,7 +37,10 @@ use starky::proof::{ use starky::prover::{compute_quotient_polys, prove_with_commitment}; use starky::stark::Stark; -use crate::all_stark::{all_cross_table_lookups, 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::byte_packing::byte_packing_stark::BytePackingStark; use crate::cpu::cpu_stark::CpuStark; @@ -90,12 +94,12 @@ impl GenerationSegmentData { pub fn zkevm_fast_config() -> StarkConfig { let cap_height = 4; let mut strategy = Vec::new(); - for window in Table::all_degree_logs().windows(2) { + for window in ALL_DEGREE_LOGS.windows(2) { if window[0] != window[1] { strategy.push(window[0] - window[1]); } } - let mut last_degree = Table::all_degree_logs()[NUM_TABLES - 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); @@ -172,7 +176,7 @@ where { timed!(timing, "build kernel", Lazy::force(&KERNEL)); - let (traces, mut public_values) = timed!( + let (mut traces, mut public_values) = timed!( timing, "generate all traces", generate_traces(all_stark, &inputs, config, segment_data, timing)? @@ -357,12 +361,13 @@ where let rate_bits = config.fri_config.rate_bits; let cap_height = config.fri_config.cap_height; - let trace_poly_values_sorted: [_; NUM_TABLES] = Table::all_sorted() + let trace_poly_values_sorted: [_; NUM_TABLES] = ALL_SORTED_TABLES .iter() .map(|&table| trace_poly_values[*table].clone()) .collect::>() .try_into() .unwrap(); + // reorder_slice(trace_poly_values, ALL_SORTED_TABLES); // We compute the Field Merkle Tree of all STARK traces. let trace_polys_values_sorted_flat: Vec<_> = trace_poly_values_sorted @@ -411,7 +416,7 @@ where .map(|ch| ch.beta) .collect::>(); - let auxiliary_columns = all_auxiliary_columns::( + let mut auxiliary_columns = all_auxiliary_columns::( all_stark, config, &trace_poly_values, @@ -420,15 +425,9 @@ where ); // We compute the Field Merkle Tree of all auxiliary columns. - let auxiliary_columns_sorted: Vec<_> = Table::all_sorted() - .iter() - .map(|&table| auxiliary_columns[*table].clone()) - .collect(); - let auxiliary_columns_sorted_flat: Vec<_> = auxiliary_columns_sorted - .clone() - .into_iter() - .flatten() - .collect(); + reorder_slice(auxiliary_columns.as_mut_slice(), ALL_SORTED_TABLES); + 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, @@ -446,13 +445,12 @@ where // Quotient polynomials. They are already chunked in `degree` pieces. let alphas = challenger.get_n_challenges(config.num_challenges); - let quotient_polys = all_quotient_polys::( + let mut quotient_polys = all_quotient_polys::( all_stark, &trace_poly_values_sorted, &trace_commitment, - &auxiliary_columns_sorted, - &auxiliary_commitment, &auxiliary_columns, + &auxiliary_commitment, None, &ctl_data_per_table, alphas.clone(), @@ -460,15 +458,8 @@ where ); // We compute the Field Merkle Tree of all quotient polynomials. - let quotient_polys_sorted: Vec<_> = Table::all_sorted() - .iter() - .map(|&table| quotient_polys[*table].clone()) - .collect(); - let quotient_polys_sorted_flat: Vec<_> = quotient_polys_sorted - .clone() - .into_iter() - .flatten() - .collect(); + reorder_slice(quotient_polys.as_mut_slice(), ALL_SORTED_TABLES); + 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, @@ -501,8 +492,8 @@ where all_stark, zeta, &trace_poly_values_sorted, - &auxiliary_columns_sorted, - "ient_polys_sorted, + &auxiliary_columns, + "ient_polys, &ctl_data_per_table, config, ); @@ -514,9 +505,9 @@ where all_stark, &trace_poly_values_sorted, &trace_commitment, - &auxiliary_columns_sorted, + &auxiliary_columns, &auxiliary_commitment, - "ient_polys_sorted, + "ient_polys, "ient_commitment, &ctl_data_per_table, zeta, @@ -533,7 +524,7 @@ where "ient_commitment, ]; - let mut degree_bits_squashed = Table::all_degree_logs().to_vec(); + let mut degree_bits_squashed = ALL_DEGREE_LOGS.to_vec(); degree_bits_squashed.dedup(); let opening_proof = BatchFriOracle::prove_openings( °ree_bits_squashed, @@ -591,7 +582,7 @@ where F: RichField + Extendable, C: GenericConfig, { - let mut res = Vec::new(); + let mut res = Vec::with_capacity(NUM_TABLES); // Arithmetic. res.push(auxiliary_columns_single_stark::< @@ -764,7 +755,6 @@ fn quotient_polys_single_stark( trace_commitment: &BatchFriOracle, auxiliary_columns_sorted: &Vec>>, auxiliary_commitment: &BatchFriOracle, - all_auxiliary_columns: &Vec>>, lookup_challenges: Option<&Vec>, ctl_data_per_table: &[CtlData; NUM_TABLES], alphas: Vec, @@ -776,17 +766,16 @@ where C: GenericConfig, S: Stark, { - let degree_bits = Table::all_degree_logs()[Table::table_to_sorted_index()[*table]]; - let (index_outer, index_inner) = - Table::sorted_index_pair()[Table::table_to_sorted_index()[*table]]; + 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::table_to_sorted_index()[*table] - i - 1; + 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::table_to_sorted_index()[*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, @@ -796,7 +785,7 @@ where trace_leave_len, ) }; - let aux_leave_len = auxiliary_columns_sorted[Table::table_to_sorted_index()[*table]].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, @@ -842,7 +831,6 @@ fn all_quotient_polys( trace_commitment: &BatchFriOracle, auxiliary_columns_sorted: &Vec>>, auxiliary_commitment: &BatchFriOracle, - all_auxiliary_columns: &Vec>>, lookup_challenges: Option<&Vec>, ctl_data_per_table: &[CtlData; NUM_TABLES], alphas: Vec, @@ -853,7 +841,7 @@ where P: PackedField, C: GenericConfig, { - let mut res = Vec::new(); + let mut res = Vec::with_capacity(NUM_TABLES); // Arithmetic. res.push(quotient_polys_single_stark::( @@ -863,7 +851,6 @@ where trace_commitment, auxiliary_columns_sorted, auxiliary_commitment, - all_auxiliary_columns, lookup_challenges, ctl_data_per_table, alphas.clone(), @@ -878,7 +865,6 @@ where trace_commitment, auxiliary_columns_sorted, auxiliary_commitment, - all_auxiliary_columns, lookup_challenges, ctl_data_per_table, alphas.clone(), @@ -893,7 +879,6 @@ where trace_commitment, auxiliary_columns_sorted, auxiliary_commitment, - all_auxiliary_columns, lookup_challenges, ctl_data_per_table, alphas.clone(), @@ -908,7 +893,6 @@ where trace_commitment, auxiliary_columns_sorted, auxiliary_commitment, - all_auxiliary_columns, lookup_challenges, ctl_data_per_table, alphas.clone(), @@ -923,7 +907,6 @@ where trace_commitment, auxiliary_columns_sorted, auxiliary_commitment, - all_auxiliary_columns, lookup_challenges, ctl_data_per_table, alphas.clone(), @@ -938,7 +921,6 @@ where trace_commitment, auxiliary_columns_sorted, auxiliary_commitment, - all_auxiliary_columns, lookup_challenges, ctl_data_per_table, alphas.clone(), @@ -952,7 +934,6 @@ where trace_commitment, auxiliary_columns_sorted, auxiliary_commitment, - all_auxiliary_columns, lookup_challenges, ctl_data_per_table, alphas.clone(), @@ -967,7 +948,6 @@ where trace_commitment, auxiliary_columns_sorted, auxiliary_commitment, - all_auxiliary_columns, lookup_challenges, ctl_data_per_table, alphas.clone(), @@ -982,7 +962,6 @@ where trace_commitment, auxiliary_columns_sorted, auxiliary_commitment, - all_auxiliary_columns, lookup_challenges, ctl_data_per_table, alphas.clone(), @@ -1008,16 +987,14 @@ where C: GenericConfig, S: Stark, { - let g = F::primitive_root_of_unity( - Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], - ); - let sorted_index = Table::table_to_sorted_index()[*table]; + let g = F::primitive_root_of_unity(ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*table]]); + let sorted_index = TABLE_TO_SORTED_INDEX[*table]; let num_ctl_helper_polys = ctl_data_per_table[*table].num_ctl_helper_polys(); 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 { - let prev_sorted_table = Table::table_to_sorted_index()[*table] - i - 1; + 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(); @@ -1057,7 +1034,7 @@ where F: RichField + Extendable, C: GenericConfig, { - let mut res = Vec::new(); + let mut res = Vec::with_capacity(NUM_TABLES); // Arithmetic. res.push(fri_instance_info_single_stark::( @@ -1167,7 +1144,7 @@ where config, )); - let res_sorted: Vec<_> = Table::all_sorted() + let res_sorted: Vec<_> = ALL_SORTED_TABLES .iter() .map(|&table| res[*table].clone()) .collect(); @@ -1199,7 +1176,7 @@ where } current_instance.batches.extend(instance.batches.clone()); - if i == NUM_TABLES - 1 || Table::all_degree_logs()[i + 1] < Table::all_degree_logs()[i] { + if i == NUM_TABLES - 1 || ALL_DEGREE_LOGS[i + 1] < ALL_DEGREE_LOGS[i] { squashed_res.push(current_instance.clone()); current_instance.oracles = vec![ FriOracleInfo { @@ -1241,16 +1218,14 @@ where C: GenericConfig, S: Stark, { - let g = F::primitive_root_of_unity( - Table::all_degree_logs()[Table::table_to_sorted_index()[*table]], - ); - let table_sorted_index = Table::table_to_sorted_index()[*table]; - let (_, index_inner) = Table::sorted_index_pair()[table_sorted_index]; + 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..index_inner { - let prev_sorted_table = Table::table_to_sorted_index()[*table] - i - 1; + 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(); @@ -1291,7 +1266,7 @@ where F: RichField + Extendable, C: GenericConfig, { - let degree_bits = Table::all_degree_logs(); + let degree_bits = ALL_DEGREE_LOGS; let mut res = Vec::new(); // Arithmetic. @@ -1828,6 +1803,20 @@ pub fn generate_all_data_segments( Ok(all_seg_data) } +fn reorder_slice(slice: &mut [T], ordering: [Table; NUM_TABLES]) { + let mut current_order = Table::all(); + for i in 0..NUM_TABLES - 1 { + if current_order[i] != ordering[i] { + let j = current_order + .iter() + .position(|&x| x == ordering[i]) + .expect("Bad ordering?"); + current_order.swap(i, j); + slice.swap(i, j); + } + } +} + /// A utility module designed to test witness generation externally. pub mod testing { use super::*; 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/witness/traces.rs b/evm_arithmetization/src/witness/traces.rs index 70ff0df43..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, Table, 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; @@ -189,7 +189,7 @@ impl Traces { "generate mem_before trace", all_stark.mem_before_stark.generate_trace( mem_before_values_to_rows(mem_before_values), - Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::MemBefore]] + ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::MemBefore]] ) ); let mem_after_trace = timed!( @@ -197,7 +197,7 @@ impl Traces { "generate mem_after trace", all_stark.mem_after_stark.generate_trace( final_values.clone(), - Table::all_degree_logs()[Table::table_to_sorted_index()[*Table::MemAfter]] + ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::MemAfter]] ) ); From 1309f83590bc6095892f860a7687aa0f820cb041 Mon Sep 17 00:00:00 2001 From: hratoanina Date: Mon, 29 Jul 2024 16:26:55 -0400 Subject: [PATCH 18/24] Use CTL challenges directly --- evm_arithmetization/src/prover.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index 7398a0c18..4b6d2e222 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -716,17 +716,16 @@ where "The degree of the Stark constraints must be <= blowup_factor + 1" ); - let lookup_challenges: Vec<_> = ctl_challenges.challenges.iter().map(|ch| ch.beta).collect(); // Add lookup columns. let lookups = stark.lookups(); let mut res = { let mut columns = Vec::new(); for lookup in &lookups { - for &challenge in lookup_challenges.iter() { + for &challenge in ctl_challenges.challenges.iter() { columns.extend(lookup_helper_columns( lookup, trace_poly_values, - challenge, + challenge.beta, constraint_degree, )); } From 9c7117a35936755eb0f0a12458735b97c8c726e7 Mon Sep 17 00:00:00 2001 From: hratoanina Date: Mon, 29 Jul 2024 19:04:02 -0400 Subject: [PATCH 19/24] Assert validity of padded lengths --- evm_arithmetization/src/arithmetic/arithmetic_stark.rs | 1 + evm_arithmetization/src/byte_packing/byte_packing_stark.rs | 1 + evm_arithmetization/src/generation/mod.rs | 3 +++ evm_arithmetization/src/keccak/keccak_stark.rs | 1 + evm_arithmetization/src/keccak_sponge/keccak_sponge_stark.rs | 1 + evm_arithmetization/src/logic.rs | 1 + evm_arithmetization/src/memory/memory_stark.rs | 1 + .../src/memory_continuation/memory_continuation_stark.rs | 1 + 8 files changed, 10 insertions(+) diff --git a/evm_arithmetization/src/arithmetic/arithmetic_stark.rs b/evm_arithmetization/src/arithmetic/arithmetic_stark.rs index ef4d0cbfb..76aee1b14 100644 --- a/evm_arithmetization/src/arithmetic/arithmetic_stark.rs +++ b/evm_arithmetization/src/arithmetic/arithmetic_stark.rs @@ -179,6 +179,7 @@ impl ArithmeticStark { // to accommodate the range check columns. Also make sure the // trace length is a power of two. let padded_len = 1 << ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::Arithmetic]]; + assert!(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/byte_packing/byte_packing_stark.rs b/evm_arithmetization/src/byte_packing/byte_packing_stark.rs index d6cb35981..0745f25f5 100644 --- a/evm_arithmetization/src/byte_packing/byte_packing_stark.rs +++ b/evm_arithmetization/src/byte_packing/byte_packing_stark.rs @@ -184,6 +184,7 @@ impl, const D: usize> BytePackingStark { rows.push(self.generate_row_for_op(op)); } } + assert!(num_rows >= rows.len()); for _ in rows.len()..num_rows { rows.push(self.generate_padding_row()); diff --git a/evm_arithmetization/src/generation/mod.rs b/evm_arithmetization/src/generation/mod.rs index 6e3c8a961..beaa8e693 100644 --- a/evm_arithmetization/src/generation/mod.rs +++ b/evm_arithmetization/src/generation/mod.rs @@ -486,6 +486,9 @@ 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()); + loop { // Padding. state.push_cpu(row); diff --git a/evm_arithmetization/src/keccak/keccak_stark.rs b/evm_arithmetization/src/keccak/keccak_stark.rs index 9fb472340..931aafba4 100644 --- a/evm_arithmetization/src/keccak/keccak_stark.rs +++ b/evm_arithmetization/src/keccak/keccak_stark.rs @@ -80,6 +80,7 @@ impl, const D: usize> KeccakStark { rows.extend(rows_for_perm); } + assert!(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 ee81dc99b..b24a2bf88 100644 --- a/evm_arithmetization/src/keccak_sponge/keccak_sponge_stark.rs +++ b/evm_arithmetization/src/keccak_sponge/keccak_sponge_stark.rs @@ -291,6 +291,7 @@ impl, const D: usize> KeccakSpongeStark { } // Pad the trace. 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/logic.rs b/evm_arithmetization/src/logic.rs index ea3f94e8c..a1fe07073 100644 --- a/evm_arithmetization/src/logic.rs +++ b/evm_arithmetization/src/logic.rs @@ -221,6 +221,7 @@ impl LogicStark { ) -> Vec<[F; NUM_COLUMNS]> { let len = operations.len(); let padded_len = 1 << ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::Logic]]; + assert!(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 e03687224..129a1f88d 100644 --- a/evm_arithmetization/src/memory/memory_stark.rs +++ b/evm_arithmetization/src/memory/memory_stark.rs @@ -354,6 +354,7 @@ impl, const D: usize> MemoryStark { // We want at least one padding row, so that the last real operation can have // its flags set correctly. let num_ops_padded = 1 << ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::Memory]]; + assert!(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 77e3d470b..98f87867b 100644 --- a/evm_arithmetization/src/memory_continuation/memory_continuation_stark.rs +++ b/evm_arithmetization/src/memory_continuation/memory_continuation_stark.rs @@ -87,6 +87,7 @@ impl, const D: usize> MemoryContinuationStark let num_rows = rows.len(); let num_rows_padded = 1 << log_padded; + assert!(num_rows_padded >= num_rows); for _ in num_rows..num_rows_padded { rows.push(vec![F::ZERO; NUM_COLUMNS]); } From f44f9a4585ebfc59e7c4587f4bad6c0417f9a9be Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Mon, 29 Jul 2024 19:37:33 -0400 Subject: [PATCH 20/24] Add error msg --- evm_arithmetization/src/arithmetic/arithmetic_stark.rs | 7 ++++++- .../src/byte_packing/byte_packing_stark.rs | 6 ++++++ evm_arithmetization/src/generation/mod.rs | 7 ++++++- evm_arithmetization/src/keccak/keccak_stark.rs | 8 +++++++- evm_arithmetization/src/logic.rs | 7 ++++++- evm_arithmetization/src/memory/memory_stark.rs | 8 +++++++- .../src/memory_continuation/memory_continuation_stark.rs | 8 +++++++- 7 files changed, 45 insertions(+), 6 deletions(-) diff --git a/evm_arithmetization/src/arithmetic/arithmetic_stark.rs b/evm_arithmetization/src/arithmetic/arithmetic_stark.rs index 76aee1b14..ea5224213 100644 --- a/evm_arithmetization/src/arithmetic/arithmetic_stark.rs +++ b/evm_arithmetization/src/arithmetic/arithmetic_stark.rs @@ -179,7 +179,12 @@ impl ArithmeticStark { // to accommodate the range check columns. Also make sure the // trace length is a power of two. let padded_len = 1 << ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::Arithmetic]]; - assert!(padded_len >= trace_rows.len()); + 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/byte_packing/byte_packing_stark.rs b/evm_arithmetization/src/byte_packing/byte_packing_stark.rs index 0745f25f5..e9ed60d92 100644 --- a/evm_arithmetization/src/byte_packing/byte_packing_stark.rs +++ b/evm_arithmetization/src/byte_packing/byte_packing_stark.rs @@ -185,6 +185,12 @@ impl, const D: usize> BytePackingStark { } } 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/generation/mod.rs b/evm_arithmetization/src/generation/mod.rs index beaa8e693..9b0f56919 100644 --- a/evm_arithmetization/src/generation/mod.rs +++ b/evm_arithmetization/src/generation/mod.rs @@ -487,7 +487,12 @@ fn simulate_cpu( 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()); + assert!( + padded_len >= state.traces.clock(), + "Padded length {:?} is smaller than actual trace length {:?}", + padded_len, + state.traces.clock() + ); loop { // Padding. diff --git a/evm_arithmetization/src/keccak/keccak_stark.rs b/evm_arithmetization/src/keccak/keccak_stark.rs index 931aafba4..85ddc8a6a 100644 --- a/evm_arithmetization/src/keccak/keccak_stark.rs +++ b/evm_arithmetization/src/keccak/keccak_stark.rs @@ -80,7 +80,13 @@ impl, const D: usize> KeccakStark { rows.extend(rows_for_perm); } - assert!(num_rows >= rows.len()); + 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/logic.rs b/evm_arithmetization/src/logic.rs index a1fe07073..6a470ee9d 100644 --- a/evm_arithmetization/src/logic.rs +++ b/evm_arithmetization/src/logic.rs @@ -221,7 +221,12 @@ impl LogicStark { ) -> Vec<[F; NUM_COLUMNS]> { let len = operations.len(); let padded_len = 1 << ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::Logic]]; - assert!(padded_len >= len); + 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 129a1f88d..9fe8236bc 100644 --- a/evm_arithmetization/src/memory/memory_stark.rs +++ b/evm_arithmetization/src/memory/memory_stark.rs @@ -354,7 +354,13 @@ impl, const D: usize> MemoryStark { // We want at least one padding row, so that the last real operation can have // its flags set correctly. let num_ops_padded = 1 << ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*Table::Memory]]; - assert!(num_ops_padded >= num_ops); + 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 98f87867b..dec047cce 100644 --- a/evm_arithmetization/src/memory_continuation/memory_continuation_stark.rs +++ b/evm_arithmetization/src/memory_continuation/memory_continuation_stark.rs @@ -87,7 +87,13 @@ impl, const D: usize> MemoryContinuationStark let num_rows = rows.len(); let num_rows_padded = 1 << log_padded; - assert!(num_rows_padded >= num_rows); + 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]); } From 47216b3b9d8a03707b030769d522112bee66ce8f Mon Sep 17 00:00:00 2001 From: hratoanina Date: Wed, 31 Jul 2024 15:13:08 -0400 Subject: [PATCH 21/24] Do not clone for trace sorting --- evm_arithmetization/src/batch_proof.rs | 43 ++++++++++++ evm_arithmetization/src/batch_verifier.rs | 81 +++++++++++++++++++++++ evm_arithmetization/src/lib.rs | 2 + evm_arithmetization/src/prover.rs | 61 +++++++++-------- evm_arithmetization/src/verifier.rs | 5 +- 5 files changed, 163 insertions(+), 29 deletions(-) create mode 100644 evm_arithmetization/src/batch_proof.rs create mode 100644 evm_arithmetization/src/batch_verifier.rs diff --git a/evm_arithmetization/src/batch_proof.rs b/evm_arithmetization/src/batch_proof.rs new file mode 100644 index 000000000..6c179af90 --- /dev/null +++ b/evm_arithmetization/src/batch_proof.rs @@ -0,0 +1,43 @@ +use ethereum_types::{Address, H256, U256}; +use plonky2::field::extension::Extendable; +use plonky2::hash::hash_types::{HashOutTarget, MerkleCapTarget, RichField, NUM_HASH_OUT_ELTS}; +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::GrandProductChallengeSet; +use starky::proof::{MultiProof, StarkProofChallenges}; + +use crate::all_stark::NUM_TABLES; +use crate::proof::PublicValues; +use crate::util::{get_h160, get_h256, get_u256, h2u}; +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) + } +} + +/// Randomness for all STARKs. +pub(crate) struct EvmProofChallenges, const D: usize> { + /// Randomness used in the batched STARK proof. + pub stark_challenges: StarkProofChallenges, + /// Randomness used for cross-table lookups. + pub ctl_challenges: GrandProductChallengeSet, +} diff --git a/evm_arithmetization/src/batch_verifier.rs b/evm_arithmetization/src/batch_verifier.rs new file mode 100644 index 000000000..b52a08e6d --- /dev/null +++ b/evm_arithmetization/src/batch_verifier.rs @@ -0,0 +1,81 @@ +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; +use plonky2::fri::oracle::PolynomialBatch; +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::BatchStarkProofWithPublicInputs; +use starky::config::StarkConfig; +use starky::cross_table_lookup::{get_ctl_vars_from_proofs, verify_cross_table_lookups}; +use starky::lookup::{get_grand_product_challenge_set, GrandProductChallenge}; +use starky::stark::Stark; +use starky::verifier::verify_stark_proof_with_challenges; + +use crate::all_stark::{AllStark, Table, NUM_TABLES}; +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::util::h2u; + +fn verify_evm_proof< + F: RichField + Extendable, + C: GenericConfig, + const D: usize, + const N: usize, +>( + all_stark: &AllStark, + evm_proof: EvmProof, + config: &StarkConfig, + is_initial: bool, +) -> Result<()> { + let mut challenger = Challenger::::new(); + + // TODO: Can we observe public values first, so that we can use + // `batch_proof_with_pis.get_challenges`? + challenger.observe_cap(&evm_proof.batch_proof.trace_cap); + observe_public_values::(&mut challenger, &evm_proof.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); + + let lookup_challenges = ctl_challenges + .challenges + .iter() + .map(|ch| ch.beta) + .collect::>(); + + challenger.observe_cap( + &evm_proof + .batch_proof + .auxiliary_polys_cap + .expect("No auxiliary cap?"), + ); + + let alphas = challenger.get_n_challenges(config.num_challenges); + challenger.observe_cap( + &evm_proof + .batch_proof + .quotient_polys_cap + .expect("No quotient cap?"), + ); + + let zeta = challenger.get_extension_challenge::(); + + for opening in evm_proof.batch_proof.openings { + challenger.observe_openings(&opening.to_fri_openings()); + } + + let fri_alpha = challenger.get_extension_challenge::(); + Ok(()) +} diff --git a/evm_arithmetization/src/lib.rs b/evm_arithmetization/src/lib.rs index 0f323b5d8..ff6432059 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; +mod batch_verifier; pub mod fixed_recursive_verifier; mod get_challenges; pub mod proof; diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index 4b6d2e222..a7ed4d0d6 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -187,7 +187,7 @@ where let proof = prove_with_traces_batch::( all_stark, config, - traces, + &mut traces, public_values, timing, abort_signal, @@ -348,7 +348,7 @@ type ProofWithMemCaps = ( pub(crate) fn prove_with_traces_batch( all_stark: &AllStark, config: &StarkConfig, - trace_poly_values: [Vec>; NUM_TABLES], + mut trace_poly_values: &mut [Vec>; NUM_TABLES], public_values: PublicValues, timing: &mut TimingTree, abort_signal: Option>, @@ -361,20 +361,10 @@ where let rate_bits = config.fri_config.rate_bits; let cap_height = config.fri_config.cap_height; - let trace_poly_values_sorted: [_; NUM_TABLES] = ALL_SORTED_TABLES - .iter() - .map(|&table| trace_poly_values[*table].clone()) - .collect::>() - .try_into() - .unwrap(); - // reorder_slice(trace_poly_values, ALL_SORTED_TABLES); - // We compute the Field Merkle Tree of all STARK traces. - let trace_polys_values_sorted_flat: Vec<_> = trace_poly_values_sorted - .clone() - .into_iter() - .flatten() - .collect(); + reorder_slice(trace_poly_values, Table::all(), ALL_SORTED_TABLES); + 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, @@ -397,6 +387,9 @@ where // 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", @@ -423,9 +416,15 @@ where &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); // We compute the Field Merkle Tree of all auxiliary columns. - reorder_slice(auxiliary_columns.as_mut_slice(), ALL_SORTED_TABLES); + reorder_slice( + auxiliary_columns.as_mut_slice(), + Table::all(), + ALL_SORTED_TABLES, + ); let auxiliary_columns_sorted_flat: Vec<_> = auxiliary_columns.clone().into_iter().flatten().collect(); let num_aux_polys = auxiliary_columns_sorted_flat.len(); @@ -447,7 +446,7 @@ where let alphas = challenger.get_n_challenges(config.num_challenges); let mut quotient_polys = all_quotient_polys::( all_stark, - &trace_poly_values_sorted, + &trace_poly_values, &trace_commitment, &auxiliary_columns, &auxiliary_commitment, @@ -458,7 +457,11 @@ where ); // We compute the Field Merkle Tree of all quotient polynomials. - reorder_slice(quotient_polys.as_mut_slice(), ALL_SORTED_TABLES); + reorder_slice( + quotient_polys.as_mut_slice(), + Table::all(), + ALL_SORTED_TABLES, + ); 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!( @@ -491,7 +494,7 @@ where let all_fri_instances = all_fri_instance_info::( all_stark, zeta, - &trace_poly_values_sorted, + &trace_poly_values, &auxiliary_columns, "ient_polys, &ctl_data_per_table, @@ -503,7 +506,7 @@ where // necessary, at `g * zeta`. let openings = all_openings( all_stark, - &trace_poly_values_sorted, + &trace_poly_values, &trace_commitment, &auxiliary_columns, &auxiliary_commitment, @@ -550,7 +553,7 @@ where get_memory_extra_looking_values(&public_values), ); check_ctls( - &trace_poly_values_sorted, + trace_poly_values, &all_stark.cross_table_lookups, &extra_values, ); @@ -1802,15 +1805,19 @@ pub fn generate_all_data_segments( Ok(all_seg_data) } -fn reorder_slice(slice: &mut [T], ordering: [Table; NUM_TABLES]) { - let mut current_order = Table::all(); +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 current_order[i] != ordering[i] { - let j = current_order + if order[i] != target_order[i] { + let j = order .iter() - .position(|&x| x == ordering[i]) + .position(|&x| x == target_order[i]) .expect("Bad ordering?"); - current_order.swap(i, j); + order.swap(i, j); slice.swap(i, j); } } diff --git a/evm_arithmetization/src/verifier.rs b/evm_arithmetization/src/verifier.rs index 1c07d2606..72043969f 100644 --- a/evm_arithmetization/src/verifier.rs +++ b/evm_arithmetization/src/verifier.rs @@ -16,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; @@ -66,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], From d33418a276332fb9df93652d145da2d2a9fd4121 Mon Sep 17 00:00:00 2001 From: hratoanina Date: Mon, 5 Aug 2024 11:00:02 -0400 Subject: [PATCH 22/24] Prove openings --- evm_arithmetization/src/batch_proof.rs | 73 ++++- evm_arithmetization/src/batch_verifier.rs | 291 ++++++++++++++++--- evm_arithmetization/src/lib.rs | 2 +- evm_arithmetization/src/prover.rs | 174 ++++++----- evm_arithmetization/tests/simple_transfer.rs | 5 + 5 files changed, 434 insertions(+), 111 deletions(-) diff --git a/evm_arithmetization/src/batch_proof.rs b/evm_arithmetization/src/batch_proof.rs index 6c179af90..5c6ec88b4 100644 --- a/evm_arithmetization/src/batch_proof.rs +++ b/evm_arithmetization/src/batch_proof.rs @@ -1,6 +1,8 @@ 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; @@ -8,12 +10,14 @@ use plonky2::util::serialization::{Buffer, IoResult, Read, Write}; use serde::{Deserialize, Serialize}; use starky::batch_proof::BatchStarkProof; use starky::config::StarkConfig; -use starky::lookup::GrandProductChallengeSet; +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 @@ -34,10 +38,65 @@ impl, C: GenericConfig, const D: usize> E } } -/// Randomness for all STARKs. -pub(crate) struct EvmProofChallenges, const D: usize> { - /// Randomness used in the batched STARK proof. - pub stark_challenges: StarkProofChallenges, - /// Randomness used for cross-table lookups. - pub ctl_challenges: GrandProductChallengeSet, +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 fri_alpha = challenger.get_extension_challenge::(); + + 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 index b52a08e6d..fc703d766 100644 --- a/evm_arithmetization/src/batch_verifier.rs +++ b/evm_arithmetization/src/batch_verifier.rs @@ -1,7 +1,10 @@ +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; @@ -11,14 +14,21 @@ use plonky2::iop::challenger::Challenger; use plonky2::plonk::config::{GenericConfig, GenericHashOut}; use plonky2::util::timing::TimingTree; use plonky2::util::transpose; -use starky::batch_proof::BatchStarkProofWithPublicInputs; +use starky::batch_proof::{BatchStarkProof, BatchStarkProofWithPublicInputs}; use starky::config::StarkConfig; -use starky::cross_table_lookup::{get_ctl_vars_from_proofs, verify_cross_table_lookups}; +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_stark_proof_with_challenges; +use starky::verifier::{verify_opening_set, verify_stark_proof_with_challenges}; -use crate::all_stark::{AllStark, Table, NUM_TABLES}; +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; @@ -26,56 +36,271 @@ 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; -fn verify_evm_proof< +/// Verify a batched STARK EVM proof. +pub fn verify_evm_proof< F: RichField + Extendable, C: GenericConfig, const D: usize, - const N: usize, >( all_stark: &AllStark, evm_proof: EvmProof, config: &StarkConfig, is_initial: bool, ) -> Result<()> { - let mut challenger = Challenger::::new(); + // let mut challenger = Challenger::::new(); - // TODO: Can we observe public values first, so that we can use - // `batch_proof_with_pis.get_challenges`? - challenger.observe_cap(&evm_proof.batch_proof.trace_cap); - observe_public_values::(&mut challenger, &evm_proof.public_values) - .map_err(|_| anyhow::Error::msg("Invalid conversion of public values."))?; + let challenges = evm_proof + .get_challenges(&config) + .expect("Bad EVM proof challenges?"); - let ctl_challenges = get_grand_product_challenge_set(&mut challenger, config.num_challenges); + let openings = &evm_proof.batch_proof.openings; - let lookup_challenges = ctl_challenges - .challenges - .iter() - .map(|ch| ch.beta) - .collect::>(); + let num_lookup_columns = all_stark.num_lookups_helper_columns(config); - challenger.observe_cap( - &evm_proof - .batch_proof - .auxiliary_polys_cap - .expect("No auxiliary cap?"), + let all_ctl_helper_columns = num_ctl_helper_columns_by_table( + &all_stark.cross_table_lookups, + all_stark.arithmetic_stark.constraint_degree(), ); - let alphas = challenger.get_n_challenges(config.num_challenges); - challenger.observe_cap( - &evm_proof - .batch_proof - .quotient_polys_cap - .expect("No quotient cap?"), + 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, ); - let zeta = challenger.get_extension_challenge::(); + let fri_openings = openings + .iter() + .map(|opening| opening.to_fri_openings()) + .collect::>(); + + 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, + ); + } - for opening in evm_proof.batch_proof.openings { - challenger.observe_openings(&opening.to_fri_openings()); + // 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, + ); } - let fri_alpha = challenger.get_extension_challenge::(); Ok(()) } diff --git a/evm_arithmetization/src/lib.rs b/evm_arithmetization/src/lib.rs index ff6432059..2213d3b34 100644 --- a/evm_arithmetization/src/lib.rs +++ b/evm_arithmetization/src/lib.rs @@ -197,7 +197,7 @@ pub mod memory_continuation; // Proving system components pub mod all_stark; mod batch_proof; -mod batch_verifier; +pub mod batch_verifier; pub mod fixed_recursive_verifier; mod get_challenges; pub mod proof; diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index a7ed4d0d6..ba36bb98f 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -29,7 +29,9 @@ 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_auxiliary_polys, get_ctl_data, CtlData}; +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, @@ -168,7 +170,7 @@ pub fn prove_batch( segment_data: &mut GenerationSegmentData, timing: &mut TimingTree, abort_signal: Option>, -) -> Result> +) -> Result<(BatchStarkProofWithPublicInputs, PublicValues)> where F: RichField + Extendable, C: GenericConfig, @@ -188,12 +190,12 @@ where all_stark, config, &mut traces, - public_values, + &public_values, timing, abort_signal, )?; - Ok(proof) + Ok((proof, public_values)) } /// Compute all STARK proofs. @@ -349,7 +351,7 @@ pub(crate) fn prove_with_traces_batch( all_stark: &AllStark, config: &StarkConfig, mut trace_poly_values: &mut [Vec>; NUM_TABLES], - public_values: PublicValues, + public_values: &PublicValues, timing: &mut TimingTree, abort_signal: Option>, ) -> Result> @@ -363,6 +365,12 @@ where // 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(); @@ -425,6 +433,12 @@ where 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(); @@ -462,6 +476,12 @@ where 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!( @@ -491,13 +511,28 @@ where "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 all_fri_instances = all_fri_instance_info::( all_stark, zeta, - &trace_poly_values, - &auxiliary_columns, - "ient_polys, - &ctl_data_per_table, + &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, ); @@ -978,10 +1013,10 @@ fn fri_instance_info_single_stark( table: Table, stark: &S, zeta: F::Extension, - trace_poly_values_sorted: &[Vec>; NUM_TABLES], - auxiliary_columns_sorted: &Vec>>, - quotient_polys_sorted: &Vec>>, - ctl_data_per_table: &[CtlData; NUM_TABLES], + 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 @@ -991,24 +1026,19 @@ where { let g = F::primitive_root_of_unity(ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*table]]); let sorted_index = TABLE_TO_SORTED_INDEX[*table]; - let num_ctl_helper_polys = ctl_data_per_table[*table].num_ctl_helper_polys(); + 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 { - 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(); + 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 = auxiliary_columns_sorted[sorted_index].len(); - let num_quotient_polys = quotient_polys_sorted[sorted_index].len(); - let num_cols_before_ctlzs = num_aux_polys_before - + stark.num_lookup_helper_columns(config) - + ctl_data_per_table[*table] - .num_ctl_helper_polys() - .iter() - .sum::(); + 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; stark.fri_instance_batch( zeta, @@ -1023,13 +1053,13 @@ where } /// Generates all FRI instances. They are sorted by decreasing degree. -fn all_fri_instance_info( +pub(crate) fn all_fri_instance_info( all_stark: &AllStark, zeta: F::Extension, - trace_poly_values_sorted: &[Vec>; NUM_TABLES], - auxiliary_columns_sorted: &Vec>>, - quotient_polys_sorted: &Vec>>, - ctl_data_per_table: &[CtlData; NUM_TABLES], + 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 @@ -1043,10 +1073,10 @@ where Table::Arithmetic, &all_stark.arithmetic_stark, zeta, - trace_poly_values_sorted, - auxiliary_columns_sorted, - quotient_polys_sorted, - ctl_data_per_table, + num_trace_polys_sorted, + num_auxiliary_columns_sorted, + num_quotient_polys_sorted, + num_ctl_helper_columns_per_table, config, )); @@ -1055,10 +1085,10 @@ where Table::BytePacking, &all_stark.byte_packing_stark, zeta, - trace_poly_values_sorted, - auxiliary_columns_sorted, - quotient_polys_sorted, - ctl_data_per_table, + num_trace_polys_sorted, + num_auxiliary_columns_sorted, + num_quotient_polys_sorted, + num_ctl_helper_columns_per_table, config, )); @@ -1067,10 +1097,10 @@ where Table::Cpu, &all_stark.cpu_stark, zeta, - trace_poly_values_sorted, - auxiliary_columns_sorted, - quotient_polys_sorted, - ctl_data_per_table, + num_trace_polys_sorted, + num_auxiliary_columns_sorted, + num_quotient_polys_sorted, + num_ctl_helper_columns_per_table, config, )); @@ -1079,10 +1109,10 @@ where Table::Keccak, &all_stark.keccak_stark, zeta, - trace_poly_values_sorted, - auxiliary_columns_sorted, - quotient_polys_sorted, - ctl_data_per_table, + num_trace_polys_sorted, + num_auxiliary_columns_sorted, + num_quotient_polys_sorted, + num_ctl_helper_columns_per_table, config, )); @@ -1091,10 +1121,10 @@ where Table::KeccakSponge, &all_stark.keccak_sponge_stark, zeta, - trace_poly_values_sorted, - auxiliary_columns_sorted, - quotient_polys_sorted, - ctl_data_per_table, + num_trace_polys_sorted, + num_auxiliary_columns_sorted, + num_quotient_polys_sorted, + num_ctl_helper_columns_per_table, config, )); @@ -1103,10 +1133,10 @@ where Table::Logic, &all_stark.logic_stark, zeta, - trace_poly_values_sorted, - auxiliary_columns_sorted, - quotient_polys_sorted, - ctl_data_per_table, + num_trace_polys_sorted, + num_auxiliary_columns_sorted, + num_quotient_polys_sorted, + num_ctl_helper_columns_per_table, config, )); @@ -1115,10 +1145,10 @@ where Table::Memory, &all_stark.memory_stark, zeta, - trace_poly_values_sorted, - auxiliary_columns_sorted, - quotient_polys_sorted, - ctl_data_per_table, + num_trace_polys_sorted, + num_auxiliary_columns_sorted, + num_quotient_polys_sorted, + num_ctl_helper_columns_per_table, config, )); @@ -1127,10 +1157,10 @@ where Table::MemBefore, &all_stark.mem_before_stark, zeta, - trace_poly_values_sorted, - auxiliary_columns_sorted, - quotient_polys_sorted, - ctl_data_per_table, + num_trace_polys_sorted, + num_auxiliary_columns_sorted, + num_quotient_polys_sorted, + num_ctl_helper_columns_per_table, config, )); @@ -1139,10 +1169,10 @@ where Table::MemAfter, &all_stark.mem_after_stark, zeta, - trace_poly_values_sorted, - auxiliary_columns_sorted, - quotient_polys_sorted, - ctl_data_per_table, + num_trace_polys_sorted, + num_auxiliary_columns_sorted, + num_quotient_polys_sorted, + num_ctl_helper_columns_per_table, config, )); @@ -1827,6 +1857,7 @@ fn reorder_slice( pub mod testing { use super::*; use crate::{ + batch_proof::EvmProof, cpu::kernel::interpreter::Interpreter, generation::{output_debug_tries, state::State}, }; @@ -1885,7 +1916,7 @@ pub mod testing { max_cpu_len_log: usize, timing: &mut TimingTree, abort_signal: Option>, - ) -> Result>> + ) -> Result>> where F: RichField + Extendable, C: GenericConfig, @@ -1896,7 +1927,7 @@ pub mod testing { let mut proofs = Vec::with_capacity(data.len()); for mut d in data { - let proof = prove_batch::( + let (proof, public_values) = prove_batch::( all_stark, config, inputs.clone(), @@ -1904,7 +1935,10 @@ pub mod testing { timing, abort_signal.clone(), )?; - proofs.push(proof); + proofs.push(EvmProof { + batch_proof: proof.proof, + public_values: PublicValues::default(), + }); } Ok(proofs) diff --git a/evm_arithmetization/tests/simple_transfer.rs b/evm_arithmetization/tests/simple_transfer.rs index c68ed0976..8f193cb1f 100644 --- a/evm_arithmetization/tests/simple_transfer.rs +++ b/evm_arithmetization/tests/simple_transfer.rs @@ -4,6 +4,7 @@ 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}; @@ -171,6 +172,10 @@ fn test_simple_transfer() -> anyhow::Result<()> { timing.filter(Duration::from_millis(100)).print(); + for proof in proofs { + verify_evm_proof(&all_stark, proof, &config, false)?; + } + Ok(()) // verify_all_proofs(&all_stark, &proofs, &config) From 6df9dbae3b107454da0553c6bd67a2cc20c52c9b Mon Sep 17 00:00:00 2001 From: hratoanina Date: Mon, 5 Aug 2024 17:19:53 -0400 Subject: [PATCH 23/24] Include public values --- evm_arithmetization/src/batch_proof.rs | 1 - evm_arithmetization/src/prover.rs | 27 +++++++++++--------------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/evm_arithmetization/src/batch_proof.rs b/evm_arithmetization/src/batch_proof.rs index 5c6ec88b4..98f8f2757 100644 --- a/evm_arithmetization/src/batch_proof.rs +++ b/evm_arithmetization/src/batch_proof.rs @@ -74,7 +74,6 @@ impl, C: GenericConfig, const D: usize> E for opening in &self.batch_proof.openings { challenger.observe_openings(&opening.to_fri_openings()); } - let fri_alpha = challenger.get_extension_challenge::(); let FriProof { commit_phase_merkle_caps, diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index ba36bb98f..e9b1f3fba 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -44,6 +44,7 @@ use crate::all_stark::{ 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; @@ -170,7 +171,7 @@ pub fn prove_batch( segment_data: &mut GenerationSegmentData, timing: &mut TimingTree, abort_signal: Option>, -) -> Result<(BatchStarkProofWithPublicInputs, PublicValues)> +) -> Result> where F: RichField + Extendable, C: GenericConfig, @@ -186,16 +187,14 @@ where check_abort_signal(abort_signal.clone())?; - let proof = prove_with_traces_batch::( + prove_with_traces_batch::( all_stark, config, &mut traces, &public_values, timing, abort_signal, - )?; - - Ok((proof, public_values)) + ) } /// Compute all STARK proofs. @@ -354,7 +353,7 @@ pub(crate) fn prove_with_traces_batch( public_values: &PublicValues, timing: &mut TimingTree, abort_signal: Option>, -) -> Result> +) -> Result> where F: RichField + Extendable, P: PackedField, @@ -594,7 +593,7 @@ where ); } - let stark_proof = BatchStarkProof { + 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), @@ -602,9 +601,9 @@ where opening_proof, }; - Ok(BatchStarkProofWithPublicInputs { - proof: stark_proof, - public_inputs: vec![], + Ok(EvmProof { + batch_proof, + public_values: public_values.clone(), }) } @@ -1927,18 +1926,14 @@ pub mod testing { let mut proofs = Vec::with_capacity(data.len()); for mut d in data { - let (proof, public_values) = prove_batch::( + proofs.push(prove_batch::( all_stark, config, inputs.clone(), &mut d, timing, abort_signal.clone(), - )?; - proofs.push(EvmProof { - batch_proof: proof.proof, - public_values: PublicValues::default(), - }); + )?); } Ok(proofs) From 4b6c39b375374f98aad148a262dc2e0556914ff1 Mon Sep 17 00:00:00 2001 From: hratoanina Date: Fri, 9 Aug 2024 20:41:24 -0400 Subject: [PATCH 24/24] Debug --- evm_arithmetization/src/batch_verifier.rs | 82 ++++++++- evm_arithmetization/src/prover.rs | 212 ++++++++++++++++++---- 2 files changed, 257 insertions(+), 37 deletions(-) diff --git a/evm_arithmetization/src/batch_verifier.rs b/evm_arithmetization/src/batch_verifier.rs index fc703d766..2d4b1dc9d 100644 --- a/evm_arithmetization/src/batch_verifier.rs +++ b/evm_arithmetization/src/batch_verifier.rs @@ -8,6 +8,8 @@ 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; @@ -50,8 +52,6 @@ pub fn verify_evm_proof< config: &StarkConfig, is_initial: bool, ) -> Result<()> { - // let mut challenger = Challenger::::new(); - let challenges = evm_proof .get_challenges(&config) .expect("Bad EVM proof challenges?"); @@ -142,12 +142,88 @@ pub fn verify_evm_proof< &num_ctl_helper_columns_per_table, config, ); + // println!("Verifier FRI instances:\n{:#?}", instances); - let fri_openings = openings + 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, diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index e9b1f3fba..5a35580f3 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -3,12 +3,13 @@ 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, ensure, Result}; use itertools::Itertools; use once_cell::sync::Lazy; use plonky2::batch_fri::oracle::BatchFriOracle; -use plonky2::field::extension::Extendable; +use plonky2::field::extension::{Extendable, FieldExtension}; use plonky2::field::goldilocks_field::GoldilocksField; use plonky2::field::packable::Packable; use plonky2::field::packed::PackedField; @@ -16,7 +17,7 @@ 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::{FriInstanceInfo, FriOpeningBatch, FriOracleInfo}; +use plonky2::fri::structure::{FriBatchInfo, FriInstanceInfo, FriOpeningBatch, FriOracleInfo}; use plonky2::fri::FriConfig; use plonky2::hash::hash_types::RichField; use plonky2::hash::merkle_tree::MerkleCap; @@ -362,6 +363,11 @@ where 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 @@ -409,6 +415,15 @@ where ) ); + 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 @@ -426,6 +441,10 @@ where // 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(), @@ -504,21 +523,33 @@ where // `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::primitive_root_of_unity(degree_bits); + 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 + // 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() - .map(|ctl_cols: &[usize; NUM_TABLES]| ctl_cols[i]) .sum() }) .collect::>() @@ -535,6 +566,8 @@ where 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`. @@ -561,8 +594,54 @@ where "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, @@ -597,7 +676,7 @@ where 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: openings.try_into().unwrap(), + openings, opening_proof, }; @@ -1023,8 +1102,8 @@ where C: GenericConfig, S: Stark, { - let g = F::primitive_root_of_unity(ALL_DEGREE_LOGS[TABLE_TO_SORTED_INDEX[*table]]); 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; @@ -1039,6 +1118,12 @@ where 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, @@ -1182,6 +1267,7 @@ where 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 { @@ -1197,33 +1283,89 @@ where blinding: false, }, ], - batches: vec![], + 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; } - current_instance.batches.extend(instance.batches.clone()); + 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()); - current_instance.oracles = vec![ - FriOracleInfo { - num_polys: 0, - blinding: false, - }, - FriOracleInfo { - num_polys: 0, - blinding: false, - }, - FriOracleInfo { - num_polys: 0, - blinding: false, - }, - ]; - current_instance.batches = vec![]; + 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; } @@ -1251,11 +1393,11 @@ where { 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 (_, 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..index_inner { + 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(); @@ -1421,7 +1563,7 @@ where )); // MemAfter. - res.push(all_openings_single_stark( + let op = all_openings_single_stark( Table::MemAfter, &all_stark.mem_after_stark, trace_poly_values_sorted, @@ -1433,7 +1575,9 @@ where ctl_data_per_table, zeta, config, - )); + ); + // println!("Mem after opening: {:?}", op); + res.push(op); res }