From c59884424571e0eb7daf9f8ae2d577a359df8c6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Taul=C3=A9=20Buxadera?= <55488871+RogerTaule@users.noreply.github.com> Date: Tue, 3 Dec 2024 12:20:25 +0100 Subject: [PATCH] Feature/custom commits (#166) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Custom cols rom (#159) Custom cols working --------- Co-authored-by: Xavier Pinsach <10213118+xavi-pinsach@users.noreply.github.com> * Cached custom commits * Updating proofman to 0.0.12 * Cargo fmt * Cargo fmt * Fix cargo clippy * Rom trace is now deterministic * cargo fmt * Global constraints verifying again * Optimizing the binary component (#167) * Optimizing the binary * Updating the executor * Updating to 0.0.13 * Not creating unnecessary instances of arith tables * Pil2-proofman 0.0.14 --------- Co-authored-by: Xavier Pinsach <10213118+xavi-pinsach@users.noreply.github.com> Co-authored-by: Héctor Masip Ardevol --- Cargo.lock | 86 ++-- Cargo.toml | 14 +- book/getting_started/quickstart.md | 6 +- book/getting_started/quickstart_dev.md | 6 +- pil/src/pil_helpers/traces.rs | 8 +- rom-merkle/Cargo.toml | 2 + rom-merkle/src/main.rs | 53 +- state-machines/arith/src/arith_range_table.rs | 11 +- state-machines/arith/src/arith_table.rs | 11 +- state-machines/binary/pil/binary.pil | 86 ++-- state-machines/binary/src/binary_basic.rs | 35 +- state-machines/rom/pil/rom.pil | 25 +- state-machines/rom/src/rom.rs | 462 +++++------------- 13 files changed, 321 insertions(+), 484 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 326ad3e7..b53c75b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -682,9 +682,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "heck" @@ -1039,9 +1039,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a73e9fe3c49d7afb2ace819fa181a287ce54a0983eda4e0eb05c22f82ffe534" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jobserver" @@ -1075,9 +1075,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.164" +version = "0.2.165" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" +checksum = "fcb4d3d38eab6c5239a362fa8bae48c03baf980a6e7079f063942d563ef3533e" [[package]] name = "libgit2-sys" @@ -1131,9 +1131,9 @@ checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "litemap" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" [[package]] name = "lock_api" @@ -1467,7 +1467,7 @@ dependencies = [ [[package]] name = "pil-std-lib" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?rev=0.0.10#cb182461a9e8dc4077be76b81733b5384d640a21" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?rev=0.0.14#7d9bf98f0eaf3230399d22ad1e06b67fe864d16b" dependencies = [ "log", "num-bigint", @@ -1485,7 +1485,7 @@ dependencies = [ [[package]] name = "pilout" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?rev=0.0.10#cb182461a9e8dc4077be76b81733b5384d640a21" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?rev=0.0.14#7d9bf98f0eaf3230399d22ad1e06b67fe864d16b" dependencies = [ "bytes", "log", @@ -1542,9 +1542,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" +checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" [[package]] name = "powerfmt" @@ -1595,9 +1595,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.89" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -1605,7 +1605,7 @@ dependencies = [ [[package]] name = "proofman" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?rev=0.0.10#cb182461a9e8dc4077be76b81733b5384d640a21" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?rev=0.0.14#7d9bf98f0eaf3230399d22ad1e06b67fe864d16b" dependencies = [ "colored", "env_logger", @@ -1626,11 +1626,12 @@ dependencies = [ [[package]] name = "proofman-common" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?rev=0.0.10#cb182461a9e8dc4077be76b81733b5384d640a21" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?rev=0.0.14#7d9bf98f0eaf3230399d22ad1e06b67fe864d16b" dependencies = [ "env_logger", "log", "p3-field", + "p3-goldilocks", "pilout", "proofman-macros", "proofman-starks-lib-c", @@ -1644,7 +1645,7 @@ dependencies = [ [[package]] name = "proofman-hints" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?rev=0.0.10#cb182461a9e8dc4077be76b81733b5384d640a21" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?rev=0.0.14#7d9bf98f0eaf3230399d22ad1e06b67fe864d16b" dependencies = [ "p3-field", "proofman-common", @@ -1654,7 +1655,7 @@ dependencies = [ [[package]] name = "proofman-macros" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?rev=0.0.10#cb182461a9e8dc4077be76b81733b5384d640a21" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?rev=0.0.14#7d9bf98f0eaf3230399d22ad1e06b67fe864d16b" dependencies = [ "proc-macro2", "quote", @@ -1664,7 +1665,7 @@ dependencies = [ [[package]] name = "proofman-starks-lib-c" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?rev=0.0.10#cb182461a9e8dc4077be76b81733b5384d640a21" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?rev=0.0.14#7d9bf98f0eaf3230399d22ad1e06b67fe864d16b" dependencies = [ "log", ] @@ -1672,7 +1673,7 @@ dependencies = [ [[package]] name = "proofman-util" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?rev=0.0.10#cb182461a9e8dc4077be76b81733b5384d640a21" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?rev=0.0.14#7d9bf98f0eaf3230399d22ad1e06b67fe864d16b" dependencies = [ "colored", "sysinfo 0.31.4", @@ -1990,6 +1991,7 @@ dependencies = [ "sm-rom", "stark", "sysinfo 0.32.0", + "zisk-pil", ] [[package]] @@ -2019,9 +2021,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.17" +version = "0.23.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f1a745511c54ba6d4465e8d5dfbd81b45791756de28d4981af70d6dca128f1e" +checksum = "9c9cc1d47e243d655ace55ed38201c19ae02c148ae56412ab8750e8f0166ab7f" dependencies = [ "once_cell", "ring", @@ -2316,7 +2318,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "stark" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?rev=0.0.10#cb182461a9e8dc4077be76b81733b5384d640a21" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?rev=0.0.14#7d9bf98f0eaf3230399d22ad1e06b67fe864d16b" dependencies = [ "log", "p3-field", @@ -2380,9 +2382,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.87" +version = "2.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" dependencies = [ "proc-macro2", "quote", @@ -2391,9 +2393,9 @@ dependencies = [ [[package]] name = "sync_wrapper" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" dependencies = [ "futures-core", ] @@ -2656,9 +2658,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", ] @@ -2666,7 +2668,7 @@ dependencies = [ [[package]] name = "transcript" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?rev=0.0.10#cb182461a9e8dc4077be76b81733b5384d640a21" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?rev=0.0.14#7d9bf98f0eaf3230399d22ad1e06b67fe864d16b" dependencies = [ "proofman-starks-lib-c", ] @@ -2713,9 +2715,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.3" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", @@ -2898,9 +2900,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.6" +version = "0.26.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" +checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" dependencies = [ "rustls-pki-types", ] @@ -3187,9 +3189,9 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "yoke" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ "serde", "stable_deref_trait", @@ -3199,9 +3201,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", @@ -3232,18 +3234,18 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index b97f5cb2..eadb5b99 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,13 +26,13 @@ opt-level = 3 opt-level = 3 [workspace.dependencies] -proofman-common = { git = "https://github.com/0xPolygonHermez/pil2-proofman.git", rev = "0.0.10" } -proofman-macros = { git = "https://github.com/0xPolygonHermez/pil2-proofman.git", rev = "0.0.10" } -proofman-util = { git = "https://github.com/0xPolygonHermez/pil2-proofman.git", rev = "0.0.10" } -proofman = { git = "https://github.com/0xPolygonHermez/pil2-proofman.git", rev = "0.0.10" } -pil-std-lib = { git = "https://github.com/0xPolygonHermez/pil2-proofman.git", rev = "0.0.10" } -stark = { git = "https://github.com/0xPolygonHermez/pil2-proofman.git", rev = "0.0.10" } -# Local development +proofman-common = { git = "https://github.com/0xPolygonHermez/pil2-proofman.git", rev = "0.0.14" } +proofman-macros = { git = "https://github.com/0xPolygonHermez/pil2-proofman.git", rev = "0.0.14" } +proofman-util = { git = "https://github.com/0xPolygonHermez/pil2-proofman.git", rev = "0.0.14" } +proofman = { git = "https://github.com/0xPolygonHermez/pil2-proofman.git", rev = "0.0.14" } +pil-std-lib = { git = "https://github.com/0xPolygonHermez/pil2-proofman.git", rev = "0.0.14" } +stark = { git = "https://github.com/0xPolygonHermez/pil2-proofman.git", rev = "0.0.14" } +#Local development # proofman-common = { path = "../pil2-proofman/common" } # proofman-macros = { path = "../pil2-proofman/macros" } # proofman-util = { path = "../pil2-proofman/util" } diff --git a/book/getting_started/quickstart.md b/book/getting_started/quickstart.md index 724a3587..72e9b7dd 100644 --- a/book/getting_started/quickstart.md +++ b/book/getting_started/quickstart.md @@ -112,9 +112,9 @@ ziskup ```bash git clone https://github.com/0xPolygonHermez/zisk git clone -b develop https://github.com/0xPolygonHermez/pil2-compiler.git -git clone -b 0.0.10 https://github.com/0xPolygonHermez/pil2-proofman.git -git clone -b 0.0.10 https://github.com/0xPolygonHermez/pil2-proofman-js -git clone -b 0.0.10 https://github.com/0xPolygonHermez/pil2-stark-js +git clone -b 0.0.13 https://github.com/0xPolygonHermez/pil2-proofman.git +git clone -b 0.0.13 https://github.com/0xPolygonHermez/pil2-proofman-js +git clone -b 0.0.13 https://github.com/0xPolygonHermez/pil2-stark-js ``` All following commands should be executed in the `zisk` folder. diff --git a/book/getting_started/quickstart_dev.md b/book/getting_started/quickstart_dev.md index dfa921e9..1d006ecd 100644 --- a/book/getting_started/quickstart_dev.md +++ b/book/getting_started/quickstart_dev.md @@ -18,9 +18,9 @@ Run the following commands to clone the necessary repositories: ```bash git clone -b develop https://github.com/0xPolygonHermez/pil2-compiler.git git clone -b develop https://github.com/0xPolygonHermez/zisk.git -git clone -b 0.0.10 https://github.com/0xPolygonHermez/pil2-proofman.git -git clone -b 0.0.10 https://github.com/0xPolygonHermez/pil2-stark-js.git -git clone -b 0.0.10 https://github.com/0xPolygonHermez/pil2-proofman-js +git clone -b 0.0.13 https://github.com/0xPolygonHermez/pil2-proofman.git +git clone -b 0.0.13 https://github.com/0xPolygonHermez/pil2-stark-js.git +git clone -b 0.0.13 https://github.com/0xPolygonHermez/pil2-proofman-js ``` ## Compile a Verifiable Rust Program diff --git a/pil/src/pil_helpers/traces.rs b/pil/src/pil_helpers/traces.rs index 32cfe09f..da3c9ff1 100644 --- a/pil/src/pil_helpers/traces.rs +++ b/pil/src/pil_helpers/traces.rs @@ -8,7 +8,7 @@ trace!(MainRow, MainTrace { }); trace!(RomRow, RomTrace { - line: F, a_offset_imm0: F, a_imm1: F, b_offset_imm0: F, b_imm1: F, ind_width: F, op: F, store_offset: F, jmp_offset1: F, jmp_offset2: F, flags: F, multiplicity: F, + multiplicity: F, }); trace!(ArithRow, ArithTrace { @@ -24,7 +24,7 @@ trace!(ArithRangeTableRow, ArithRangeTableTrace { }); trace!(BinaryRow, BinaryTrace { - m_op: F, mode32: F, free_in_a: [F; 8], free_in_b: [F; 8], free_in_c: [F; 8], carry: [F; 8], use_last_carry: F, op_is_min_max: F, multiplicity: F, main_step: F, + m_op: F, mode32: F, free_in_a: [F; 8], free_in_b: [F; 8], free_in_c: [F; 8], carry: [F; 8], use_last_carry: F, op_is_min_max: F, cout: F, result_is_a: F, use_last_carry_mode32: F, use_last_carry_mode64: F, m_op_or_ext: F, free_in_a_or_c: [F; 4], free_in_b_or_zero: [F; 4], multiplicity: F, main_step: F, }); trace!(BinaryTableRow, BinaryTableTrace { @@ -42,3 +42,7 @@ trace!(BinaryExtensionTableRow, BinaryExtensionTableTrace { trace!(SpecifiedRangesRow, SpecifiedRangesTrace { mul: [F; 1], }); + +trace!(RomRomRow, RomRomTrace { + line: F, a_offset_imm0: F, a_imm1: F, b_offset_imm0: F, b_imm1: F, ind_width: F, op: F, store_offset: F, jmp_offset1: F, jmp_offset2: F, flags: F, +}); diff --git a/rom-merkle/Cargo.toml b/rom-merkle/Cargo.toml index 4558eda3..7fd14009 100644 --- a/rom-merkle/Cargo.toml +++ b/rom-merkle/Cargo.toml @@ -8,6 +8,8 @@ sm-rom = { path = "../state-machines/rom" } log = { workspace = true } stark = { workspace = true } proofman-common = { workspace = true } +zisk-pil = { path="../pil" } + p3-goldilocks = { git = "https://github.com/Plonky3/Plonky3.git", rev = "c3d754ef77b9fce585b46b972af751fe6e7a9803" } p3-field = { workspace = true } diff --git a/rom-merkle/src/main.rs b/rom-merkle/src/main.rs index fa856247..7729582d 100644 --- a/rom-merkle/src/main.rs +++ b/rom-merkle/src/main.rs @@ -1,30 +1,33 @@ use clap::{Arg, Command}; use colored::Colorize; use p3_goldilocks::Goldilocks; -use proofman_common::{GlobalInfo, ProofType, SetupCtx}; +use proofman_common::{get_custom_commit_trace, GlobalInfo, ProofType, SetupCtx}; use sm_rom::RomSM; use stark::StarkBufferAllocator; use std::{path::Path, sync::Arc}; use sysinfo::System; +use zisk_pil::{ROM_AIR_IDS, ZISK_AIRGROUP_ID}; fn main() { let matches = Command::new("ROM Handler") .version("1.0") .about("Compute the Merkle Root of a ROM file") - .arg(Arg::new("rom").value_name("FILE").help("The ROM file path").required(true).index(1)) + .arg( + Arg::new("rom").long("rom").value_name("FILE").help("The ROM file path").required(true), + ) .arg( Arg::new("proving_key") + .long("proving-key") .value_name("FILE") .help("The proving key folder path") - .required(true) - .index(2), + .required(true), ) .arg( - Arg::new("global_info") + Arg::new("rom_buffer") + .long("rom-buffer") .value_name("FILE") - .help("The global info file path") - .required(true) - .index(3), + .help("The rom buffer path") + .required(true), ) .get_matches(); @@ -34,9 +37,8 @@ fn main() { let proving_key_path_str = matches.get_one::("proving_key").expect("Proving key path is required"); let proving_key_path = Path::new(proving_key_path_str); - let global_info_path_str = - matches.get_one::("global_info").expect("Global info path is required"); - let global_info_path = Path::new(global_info_path_str); + let rom_buffer_str = + matches.get_one::("rom_buffer").expect("Buffer file path is required"); env_logger::builder() .format_timestamp(None) @@ -78,23 +80,24 @@ fn main() { std::process::exit(1); } - // If all checks pass, continue with the program - println!("ROM Path is valid: {}", rom_path.display()); - let buffer_allocator: Arc = Arc::new(StarkBufferAllocator::new(proving_key_path.to_path_buf())); - let global_info = GlobalInfo::new(global_info_path); + let global_info = GlobalInfo::new(proving_key_path); let sctx = Arc::new(SetupCtx::new(&global_info, &ProofType::Basic)); - if let Err(e) = - RomSM::::compute_trace(rom_path.to_path_buf(), buffer_allocator, &sctx) - { - log::error!("Error: {}", e); - std::process::exit(1); - } - - // Compute LDE and Merkelize and get the root of the rom - // TODO: Implement the logic to compute the trace + let setup = sctx.get_setup(ZISK_AIRGROUP_ID, ROM_AIR_IDS[0]); - log::info!("ROM proof successful"); + match RomSM::::compute_trace_rom_buffer( + rom_path.to_path_buf(), + buffer_allocator, + &sctx, + ) { + Ok((commit_id, buffer_rom)) => { + get_custom_commit_trace(commit_id, 0, setup, buffer_rom, rom_buffer_str.as_str()); + } + Err(e) => { + log::error!("Error: {}", e); + std::process::exit(1); + } + } } diff --git a/state-machines/arith/src/arith_range_table.rs b/state-machines/arith/src/arith_range_table.rs index 4b3dcf1f..5668a964 100644 --- a/state-machines/arith/src/arith_range_table.rs +++ b/state-machines/arith/src/arith_range_table.rs @@ -1,5 +1,5 @@ use std::sync::{ - atomic::{AtomicU32, Ordering}, + atomic::{AtomicBool, AtomicU32, Ordering}, Arc, Mutex, }; @@ -21,6 +21,7 @@ pub struct ArithRangeTableSM { // Inputs num_rows: usize, multiplicity: Mutex>, + used: AtomicBool, } impl ArithRangeTableSM { @@ -34,6 +35,7 @@ impl ArithRangeTableSM { registered_predecessors: AtomicU32::new(0), num_rows: air.num_rows(), multiplicity: Mutex::new(vec![0; air.num_rows()]), + used: AtomicBool::new(false), }; let arith_range_table_sm = Arc::new(arith_range_table_sm); @@ -47,7 +49,9 @@ impl ArithRangeTableSM { } pub fn unregister_predecessor(&self) { - if self.registered_predecessors.fetch_sub(1, Ordering::SeqCst) == 1 { + if self.registered_predecessors.fetch_sub(1, Ordering::SeqCst) == 1 && + self.used.load(Ordering::SeqCst) + { self.create_air_instance(); } } @@ -58,6 +62,7 @@ impl ArithRangeTableSM { for (row, value) in inputs { _multiplicity[row] += value; } + self.used.store(true, Ordering::Relaxed); } pub fn create_air_instance(&self) { let ectx = self.wcm.get_ectx(); @@ -86,7 +91,7 @@ impl ArithRangeTableSM { .for_each(|(i, input)| *input = F::from_canonical_u64(multiplicity_[i])); info!( - "{}: ··· Creating Binary basic table instance [{} rows filled 100%]", + "{}: ··· Creating Arith range basic table instance [{} rows filled 100%]", Self::MY_NAME, self.num_rows, ); diff --git a/state-machines/arith/src/arith_table.rs b/state-machines/arith/src/arith_table.rs index 6805f407..565357f6 100644 --- a/state-machines/arith/src/arith_table.rs +++ b/state-machines/arith/src/arith_table.rs @@ -1,5 +1,5 @@ use std::sync::{ - atomic::{AtomicU32, Ordering}, + atomic::{AtomicBool, AtomicU32, Ordering}, Arc, Mutex, }; @@ -21,6 +21,7 @@ pub struct ArithTableSM { // Inputs num_rows: usize, multiplicity: Mutex>, + used: AtomicBool, } impl ArithTableSM { @@ -34,6 +35,7 @@ impl ArithTableSM { registered_predecessors: AtomicU32::new(0), num_rows: air.num_rows(), multiplicity: Mutex::new(vec![0; air.num_rows()]), + used: AtomicBool::new(false), }; let arith_table_sm = Arc::new(_arith_table_sm); @@ -47,7 +49,9 @@ impl ArithTableSM { } pub fn unregister_predecessor(&self) { - if self.registered_predecessors.fetch_sub(1, Ordering::SeqCst) == 1 { + if self.registered_predecessors.fetch_sub(1, Ordering::SeqCst) == 1 && + self.used.load(Ordering::SeqCst) + { self.create_air_instance(); } } @@ -60,6 +64,7 @@ impl ArithTableSM { info!("{}: ··· Processing row {} with value {}", Self::MY_NAME, row, value); _multiplicity[row] += value; } + self.used.store(true, Ordering::Relaxed); } pub fn create_air_instance(&self) { let ectx = self.wcm.get_ectx(); @@ -88,7 +93,7 @@ impl ArithTableSM { .for_each(|(i, input)| *input = F::from_canonical_u64(multiplicity_[i])); info!( - "{}: ··· Creating Binary basic table instance [{} rows filled 100%]", + "{}: ··· Creating Arith basic table instance [{} rows filled 100%]", Self::MY_NAME, self.num_rows, ); diff --git a/state-machines/binary/pil/binary.pil b/state-machines/binary/pil/binary.pil index b6c48f73..d23b7d06 100644 --- a/state-machines/binary/pil/binary.pil +++ b/state-machines/binary/pil/binary.pil @@ -65,6 +65,7 @@ airtemplate Binary(const int N = 2**21, const int operation_bus_id = BINARY_ID) // Default values const int bits = 64; const int bytes = bits / 8; + const int half_bytes = bytes / 2; // Main values const int input_chunks = 2; @@ -80,51 +81,70 @@ airtemplate Binary(const int N = 2**21, const int operation_bus_id = BINARY_ID) // Secondary columns col witness use_last_carry; // 1 if the operation uses the last carry as its result - col witness op_is_min_max; // 1 if op ∈ {MINU,MIN,MAXU,MAX} + col witness op_is_min_max; // 1 if the operation is any of the MIN/MAX operations - const expr cout32 = carry[bytes/2-1]; + const expr mode64 = 1 - mode32; + const expr cout32 = carry[half_bytes-1]; const expr cout64 = carry[bytes-1]; - expr cout = (1-mode32) * (cout64 - cout32) + cout32; use_last_carry * (1 - use_last_carry) === 0; op_is_min_max * (1 - op_is_min_max) === 0; cout32*(1 - cout32) === 0; cout64*(1 - cout64) === 0; - // Constraints to check the correctness of each binary operation + // Auxiliary columns (primarily used to optimize lookups, but can be substituted with expressions) + col witness cout; + col witness result_is_a; + col witness use_last_carry_mode32; + col witness use_last_carry_mode64; + cout === mode64 * (cout64 - cout32) + cout32; + result_is_a === op_is_min_max * cout; + use_last_carry_mode32 === mode32 * use_last_carry; + use_last_carry_mode64 === mode64 * use_last_carry; + /* - opid last a b c cin cout - ─────────────────────────────────────────────────────────────── - m_op 0 a0 b0 c0 0 carry0 - m_op 0 a1 b1 c1 carry0 carry1 - m_op 0 a2 b2 c2 carry1 carry2 - m_op 0 a3 b3 c3 carry2 carry3 + 2*use_last_carry - m_op|EXT_32 0 a4|c3 b4|0 c4 carry3 carry4 - m_op|EXT_32 0 a5|c3 b5|0 c5 carry4 carry5 - m_op|EXT_32 0 a6|c3 b6|0 c6 carry5 carry6 - m_op|EXT_32 1 a7|c3 b7|0 c7 carry6 carry7 + 2*use_last_carry + Constraints to check the correctness of each binary operation + opid last a b c cin cout + flags + ───────────────────────────────────────────────────────────────------------------------------------------------- + m_op 0 a0 b0 c0 0 carry0 + 2*op_is_min_max + 4*result_is_a + m_op 0 a1 b1 c1 carry0 carry1 + 2*op_is_min_max + 4*result_is_a + m_op 0 a2 b2 c2 carry1 carry2 + 2*op_is_min_max + 4*result_is_a + m_op 0|1 a3 b3 c3 carry2 carry3 + 2*op_is_min_max + 4*result_is_a + 8*use_last_carry_mode32 + m_op|EXT_32 0 a4|c3 b4|0 c4 carry3 carry4 + 2*op_is_min_max + 4*result_is_a + m_op|EXT_32 0 a5|c3 b5|0 c5 carry4 carry5 + 2*op_is_min_max + 4*result_is_a + m_op|EXT_32 0 a6|c3 b6|0 c6 carry5 carry6 + 2*op_is_min_max + 4*result_is_a + m_op|EXT_32 0|1 a7|c3 b7|0 c7 carry6 carry7 + 2*op_is_min_max + 4*result_is_a + 8*use_last_carry_mode64 + ───────────────────────────────────────────────────────────────------------------------------------------------- + Perform, at the byte level, lookups against the binary table on inputs: + [last, m_op, a, b, cin, c, cout + flags] + where last indicates whether the byte is the last one in the operation */ - // Perform, at the byte level, lookups against the binary table on inputs: - // [last, m_op, a, b, cin, c, cout + flags] - // where last indicates whether the byte is the last one in the operation - - lookup_assumes(BINARY_TABLE_ID, [0, m_op, free_in_a[0], free_in_b[0], 0, free_in_c[0], carry[0] + 2*op_is_min_max + 4*op_is_min_max*cout]); + lookup_assumes(BINARY_TABLE_ID, [0, m_op, free_in_a[0], free_in_b[0], 0, free_in_c[0], carry[0] + 2*op_is_min_max + 4*result_is_a]); - expr _m_op = (1-mode32) * (m_op - EXT_32_OP) + EXT_32_OP; + // More auxiliary columns + col witness m_op_or_ext; + col witness free_in_a_or_c[half_bytes]; + col witness free_in_b_or_zero[half_bytes]; + m_op_or_ext === mode64 * (m_op - EXT_32_OP) + EXT_32_OP; + int j = 0; for (int i = 1; i < bytes; i++) { - expr _free_in_a = (1-mode32) * (free_in_a[i] - free_in_c[bytes/2-1]) + free_in_c[bytes/2-1]; - expr _free_in_b = (1-mode32) * free_in_b[i]; - - if (i < bytes/2 - 1) { - lookup_assumes(BINARY_TABLE_ID, [0, m_op, free_in_a[i], free_in_b[i], carry[i-1], free_in_c[i], carry[i] + 2*op_is_min_max + 4*op_is_min_max*cout]); - } else if (i == bytes/2 - 1) { - lookup_assumes(BINARY_TABLE_ID, [mode32, m_op, free_in_a[i], free_in_b[i], carry[i-1], free_in_c[i], cout32 + 2*op_is_min_max + 4*op_is_min_max*cout + 8*use_last_carry*mode32]); - } else if (i < bytes - 1) { - lookup_assumes(BINARY_TABLE_ID, [0, _m_op, _free_in_a, _free_in_b, carry[i-1], free_in_c[i], carry[i] + 2*op_is_min_max + 4*op_is_min_max*cout]); - } else { - lookup_assumes(BINARY_TABLE_ID, [1-mode32, _m_op, _free_in_a, _free_in_b, carry[i-1], free_in_c[i], cout64 + 2*op_is_min_max + 4*op_is_min_max*cout + 8*use_last_carry*(1-mode32)]); - } + if (i >= half_bytes) { + free_in_a_or_c[j] === mode64 * (free_in_a[i] - free_in_c[half_bytes-1]) + free_in_c[half_bytes-1]; + free_in_b_or_zero[j] === mode64 * free_in_b[i]; + } + + if (i < half_bytes - 1) { + lookup_assumes(BINARY_TABLE_ID, [0, m_op, free_in_a[i], free_in_b[i], carry[i-1], free_in_c[i], carry[i] + 2*op_is_min_max + 4*result_is_a]); + } else if (i == half_bytes - 1) { + lookup_assumes(BINARY_TABLE_ID, [mode32, m_op, free_in_a[i], free_in_b[i], carry[i-1], free_in_c[i], cout32 + 2*op_is_min_max + 4*result_is_a + 8*use_last_carry_mode32]); + } else if (i < bytes - 1) { + lookup_assumes(BINARY_TABLE_ID, [0, m_op_or_ext, free_in_a_or_c[j], free_in_b_or_zero[j], carry[i-1], free_in_c[i], carry[i] + 2*op_is_min_max + 4*result_is_a]); + j++; + } else { + lookup_assumes(BINARY_TABLE_ID, [mode64, m_op_or_ext, free_in_a_or_c[j], free_in_b_or_zero[j], carry[i-1], free_in_c[i], cout64 + 2*op_is_min_max + 4*result_is_a + 8*use_last_carry_mode64]); + j++; + } } // Constraints to make sure that this component is called from the main component @@ -164,5 +184,5 @@ airtemplate Binary(const int N = 2**21, const int operation_bus_id = BINARY_ID) col witness multiplicity; col witness main_step; - lookup_proves(OPERATION_BUS_ID, [main_step, op, ...a, ...b, ...c, (1-op_is_min_max)*cout], multiplicity); + lookup_proves(OPERATION_BUS_ID, [main_step, op, ...a, ...b, ...c, cout - result_is_a], multiplicity); } \ No newline at end of file diff --git a/state-machines/binary/src/binary_basic.rs b/state-machines/binary/src/binary_basic.rs index 765ed11f..40cb3698 100644 --- a/state-machines/binary/src/binary_basic.rs +++ b/state-machines/binary/src/binary_basic.rs @@ -16,6 +16,9 @@ use zisk_pil::*; use crate::{BinaryBasicTableOp, BinaryBasicTableSM}; +const BYTES: usize = 8; +const HALF_BYTES: usize = BYTES / 2; + pub struct BinaryBasicSM { wcm: Arc>, @@ -158,6 +161,7 @@ impl BinaryBasicSM { let opcode = ZiskOp::try_from_code(operation.opcode).expect("Invalid ZiskOp opcode"); let mode32 = Self::opcode_is_32_bits(opcode); row.mode32 = F::from_bool(mode32); + let mode64 = F::from_bool(!mode32); // Set c_filtered let c_filtered = if mode32 { c & 0xFFFFFFFF } else { c }; @@ -667,6 +671,33 @@ impl BinaryBasicSM { _ => panic!("BinaryBasicSM::process_slice() found invalid opcode={}", operation.opcode), } + // Set cout + let cout32 = row.carry[HALF_BYTES - 1]; + let cout64 = row.carry[BYTES - 1]; + row.cout = mode64 * (cout64 - cout32) + cout32; + + // Set result_is_a + row.result_is_a = row.op_is_min_max * row.cout; + + // Set use_last_carry_mode32 and use_last_carry_mode64 + row.use_last_carry_mode32 = F::from_bool(mode32) * row.use_last_carry; + row.use_last_carry_mode64 = mode64 * row.use_last_carry; + + // Set micro opcode + row.m_op = F::from_canonical_u8(binary_basic_table_op as u8); + + // Set m_op_or_ext + let ext_32_op = F::from_canonical_u8(BinaryBasicTableOp::Ext32 as u8); + row.m_op_or_ext = mode64 * (row.m_op - ext_32_op) + ext_32_op; + + // Set free_in_a_or_c and free_in_b_or_zero + for i in 0..HALF_BYTES { + row.free_in_a_or_c[i] = mode64 * + (row.free_in_a[i + HALF_BYTES] - row.free_in_c[HALF_BYTES - 1]) + + row.free_in_c[HALF_BYTES - 1]; + row.free_in_b_or_zero[i] = mode64 * row.free_in_b[i + HALF_BYTES]; + } + if row.use_last_carry == F::one() { // Set first and last elements row.free_in_c[7] = row.free_in_c[0]; @@ -676,9 +707,6 @@ impl BinaryBasicSM { // TODO: Find duplicates of this trace and reuse them by increasing their multiplicity. row.multiplicity = F::one(); - // Set micro opcode - row.m_op = F::from_canonical_u8(binary_basic_table_op as u8); - // Return row } @@ -732,6 +760,7 @@ impl BinaryBasicSM { timer_start_trace!(BINARY_PADDING); let padding_row = BinaryRow:: { m_op: F::from_canonical_u8(0x20), + m_op_or_ext: F::from_canonical_u8(0x20), multiplicity: F::zero(), main_step: F::zero(), /* TODO: remove, since main_step is just for * debugging */ diff --git a/state-machines/rom/pil/rom.pil b/state-machines/rom/pil/rom.pil index 2c2011e0..578333bc 100644 --- a/state-machines/rom/pil/rom.pil +++ b/state-machines/rom/pil/rom.pil @@ -2,19 +2,22 @@ require "std_lookup.pil" const int ROM_BUS_ID = 7890; +public rom_root[4]; + airtemplate Rom(int N = 2**21, int stack_enabled = 0, const int rom_bus_id = ROM_BUS_ID) { + commit stage(0) public(rom_root) rom; - col witness line; - col witness a_offset_imm0; - col witness a_imm1; - col witness b_offset_imm0; - col witness b_imm1; - col witness ind_width; - col witness op; - col witness store_offset; - col witness jmp_offset1; - col witness jmp_offset2; - col witness flags; + col rom line; + col rom a_offset_imm0; + col rom a_imm1; + col rom b_offset_imm0; + col rom b_imm1; + col rom ind_width; + col rom op; + col rom store_offset; + col rom jmp_offset1; + col rom jmp_offset2; + col rom flags; col witness multiplicity; diff --git a/state-machines/rom/src/rom.rs b/state-machines/rom/src/rom.rs index 3fc4f9b1..061540c2 100644 --- a/state-machines/rom/src/rom.rs +++ b/state-machines/rom/src/rom.rs @@ -6,10 +6,11 @@ use proofman::{WitnessComponent, WitnessManager}; use proofman_common::{AirInstance, BufferAllocator, SetupCtx}; use proofman_util::create_buffer_fast; -use zisk_core::{Riscv2zisk, ZiskPcHistogram, ZiskRom, SRC_IMM}; -use zisk_pil::{Pilout, RomRow, RomTrace, MAIN_AIR_IDS, ROM_AIR_IDS, ZISK_AIRGROUP_ID}; -//use ziskemu::ZiskEmulatorErr; use std::error::Error; +use zisk_core::{Riscv2zisk, ZiskPcHistogram, ZiskRom, SRC_IMM}; +use zisk_pil::{ + Pilout, RomRomRow, RomRomTrace, RomRow, RomTrace, MAIN_AIR_IDS, ROM_AIR_IDS, ZISK_AIRGROUP_ID, +}; pub struct RomSM { wcm: Arc>, @@ -31,145 +32,29 @@ impl RomSM { rom: &ZiskRom, pc_histogram: ZiskPcHistogram, ) -> Result<(), Box> { - let buffer_allocator = self.wcm.get_ectx().buffer_allocator.clone(); - let sctx = self.wcm.get_sctx(); - if pc_histogram.end_pc == 0 { panic!("RomSM::prove() detected pc_histogram.end_pc == 0"); // TODO: return an error } - let main_trace_len = - self.wcm.get_pctx().pilout.get_air(ZISK_AIRGROUP_ID, MAIN_AIR_IDS[0]).num_rows() as u64; - - let (prover_buffer, _, air_id) = - Self::compute_trace_rom(rom, buffer_allocator, &sctx, pc_histogram, main_trace_len)?; - - let air_instance = - AirInstance::new(sctx.clone(), ZISK_AIRGROUP_ID, air_id, None, prover_buffer); - let (is_mine, instance_gid) = - self.wcm.get_ectx().dctx.write().unwrap().add_instance(ZISK_AIRGROUP_ID, air_id, 1); - if is_mine { - self.wcm - .get_pctx() - .air_instance_repo - .add_air_instance(air_instance, Some(instance_gid)); - } - - Ok(()) - } - pub fn compute_trace( - rom_path: PathBuf, - buffer_allocator: Arc>, - sctx: &SetupCtx, - ) -> Result<(Vec, u64, usize), Box> { - // Get the ELF file path as a string - let elf_filename: String = rom_path.to_str().unwrap().into(); - println!("Proving ROM for ELF file={}", elf_filename); - - // Load and parse the ELF file, and transpile it into a ZisK ROM using Riscv2zisk - - // Create an instance of the RISCV -> ZisK program converter - let riscv2zisk = Riscv2zisk::new(elf_filename, String::new(), String::new(), String::new()); - - // Convert program to rom - let rom_result = riscv2zisk.run(); - if rom_result.is_err() { - //return Err(ZiskEmulatorErr::Unknown(zisk_rom.err().unwrap().to_string())); - panic!("RomSM::prover() failed converting elf to rom"); - } - let rom = rom_result.unwrap(); - - let empty_pc_histogram = ZiskPcHistogram::default(); - - Self::compute_trace_rom(&rom, buffer_allocator, sctx, empty_pc_histogram, 0) - } - - pub fn compute_trace_rom( - rom: &ZiskRom, - buffer_allocator: Arc>, - sctx: &SetupCtx, - pc_histogram: ZiskPcHistogram, - main_trace_len: u64, - ) -> Result<(Vec, u64, usize), Box> { - let pilout = Pilout::pilout(); - let sizes = ( - pilout.get_air(ZISK_AIRGROUP_ID, ROM_AIR_IDS[0]).num_rows(), - // pilout.get_air(ZISK_AIRGROUP_ID, ROM_M_AIR_IDS[0]).num_rows(), - // pilout.get_air(ZISK_AIRGROUP_ID, ROM_L_AIR_IDS[0]).num_rows(), - ); - - let number_of_instructions = rom.insts.len(); - - Self::create_rom_s( - sizes.0, - rom, - number_of_instructions, - buffer_allocator, - sctx, - pc_histogram, - main_trace_len, - ) - // match number_of_instructions { - // n if n <= sizes.0 => Self::create_rom_s( - // sizes.0, - // rom, - // n, - // buffer_allocator, - // sctx, - // pc_histogram, - // main_trace_len, - // ), - // n if n <= sizes.1 => Self::create_rom_m( - // sizes.1, - // rom, - // n, - // buffer_allocator, - // sctx, - // pc_histogram, - // main_trace_len, - // ), - // n if n < sizes.2 => Self::create_rom_l( - // sizes.2, - // rom, - // n, - // buffer_allocator, - // sctx, - // pc_histogram, - // main_trace_len, - // ), - // _ => panic!("RomSM::compute_trace() found rom too big size={}", - // number_of_instructions), } - } - - fn create_rom_s( - rom_s_size: usize, - rom: &zisk_core::ZiskRom, - number_of_instructions: usize, - buffer_allocator: Arc>, - sctx: &SetupCtx, - pc_histogram: ZiskPcHistogram, - main_trace_len: u64, - ) -> Result<(Vec, u64, usize), Box> { - // Set trace size - let trace_size = rom_s_size; - // Allocate a prover buffer + let buffer_allocator = self.wcm.get_ectx().buffer_allocator.clone(); + let sctx = self.wcm.get_sctx(); let (buffer_size, offsets) = buffer_allocator - .get_buffer_info(sctx, ZISK_AIRGROUP_ID, ROM_AIR_IDS[0]) + .get_buffer_info(&sctx, ZISK_AIRGROUP_ID, ROM_AIR_IDS[0]) .unwrap_or_else(|err| panic!("Error getting buffer info: {}", err)); - let mut prover_buffer = create_buffer_fast(buffer_size as usize); // Create an empty ROM trace + let pilout = Pilout::pilout(); + let trace_rows = pilout.get_air(ZISK_AIRGROUP_ID, ROM_AIR_IDS[0]).num_rows(); + let mut prover_buffer = create_buffer_fast(buffer_size as usize); + let mut rom_trace = - RomTrace::::map_buffer(&mut prover_buffer, trace_size, offsets[0] as usize) + RomTrace::::map_buffer(&mut prover_buffer, trace_rows, offsets[0] as usize) .expect("RomSM::compute_trace() failed mapping buffer to ROMSRow"); // For every instruction in the rom, fill its corresponding ROM trace - //for (i, inst_builder) in rom.insts.clone().into_iter().enumerate() { - let keys = rom.insts.keys(); - let sorted_keys = keys.sorted(); - let mut i = 0; - for key in sorted_keys { + let main_trace_len = pilout.get_air(ZISK_AIRGROUP_ID, MAIN_AIR_IDS[0]).num_rows() as u64; + for (i, key) in rom.insts.keys().sorted().enumerate() { // Get the Zisk instruction let inst = &rom.insts[key].i; @@ -190,6 +75,83 @@ impl RomSM { continue; // We skip those pc's that are not used in this execution } } + rom_trace[i].multiplicity = F::from_canonical_u64(multiplicity); + } + + // Padd with zeroes + for i in rom.insts.len()..trace_rows { + rom_trace[i] = RomRow::default(); + } + + let mut air_instance = + AirInstance::new(sctx.clone(), ZISK_AIRGROUP_ID, ROM_AIR_IDS[0], None, prover_buffer); + + match self + .wcm + .get_ectx() + .cached_buffers_path + .as_ref() + .and_then(|cached_buffers| cached_buffers.get("rom").cloned()) + { + Some(buffer_path) => { + let (_, _, commit_id) = buffer_allocator + .clone() + .get_buffer_info_custom_commit(&sctx, ZISK_AIRGROUP_ID, ROM_AIR_IDS[0], "rom") + .unwrap_or_else(|err| panic!("Error getting buffer info: {}", err)); + + air_instance.set_custom_commit_cached_file(&sctx, commit_id, buffer_path); + } + None => { + let (commit_id_rom, prover_buffer_rom) = + Self::compute_trace_rom(rom, buffer_allocator.clone(), &sctx)?; + + air_instance.set_custom_commit_id_buffer(&sctx, prover_buffer_rom, commit_id_rom); + } + } + + let (commit_id_rom, prover_buffer_rom) = + Self::compute_trace_rom(rom, buffer_allocator.clone(), &sctx)?; + + air_instance.set_custom_commit_id_buffer(&sctx, prover_buffer_rom, commit_id_rom); + + let (is_mine, instance_gid) = self.wcm.get_ectx().dctx.write().unwrap().add_instance( + ZISK_AIRGROUP_ID, + ROM_AIR_IDS[0], + 1, + ); + if is_mine { + self.wcm + .get_pctx() + .air_instance_repo + .add_air_instance(air_instance, Some(instance_gid)); + } + + Ok(()) + } + + pub fn compute_trace_rom( + rom: &ZiskRom, + buffer_allocator: Arc>, + sctx: &SetupCtx, + ) -> Result<(u64, Vec), Box> { + // Allocate a prover buffer + let (buffer_size_rom, offsets_rom, commit_id) = buffer_allocator + .get_buffer_info_custom_commit(sctx, ZISK_AIRGROUP_ID, ROM_AIR_IDS[0], "rom") + .unwrap_or_else(|err| panic!("Error getting buffer info: {}", err)); + + // Create an empty ROM trace + let pilout = Pilout::pilout(); + let trace_rows = pilout.get_air(ZISK_AIRGROUP_ID, ROM_AIR_IDS[0]).num_rows(); + let mut prover_buffer = create_buffer_fast(buffer_size_rom as usize); + + let mut rom_trace = + RomRomTrace::::map_buffer(&mut prover_buffer, trace_rows, offsets_rom[0] as usize) + .expect("RomRootSM::compute_trace() failed mapping buffer to ROMSRow"); + + // For every instruction in the rom, fill its corresponding ROM trace + for (i, key) in rom.insts.keys().sorted().enumerate() { + // Get the Zisk instruction + let inst = &rom.insts[key].i; // Convert the i64 offsets to F let jmp_offset1 = if inst.jmp_offset1 >= 0 { @@ -226,239 +188,41 @@ impl RomSM { rom_trace[i].b_offset_imm0 = b_offset_imm0; rom_trace[i].b_imm1 = F::from_canonical_u64(if inst.b_src == SRC_IMM { inst.b_use_sp_imm1 } else { 0 }); - //rom_trace[i].b_src_ind = - // F::from_canonical_u64(if inst.b_src == SRC_IND { 1 } else { 0 }); rom_trace[i].ind_width = F::from_canonical_u64(inst.ind_width); rom_trace[i].op = F::from_canonical_u8(inst.op); rom_trace[i].store_offset = store_offset; rom_trace[i].jmp_offset1 = jmp_offset1; rom_trace[i].jmp_offset2 = jmp_offset2; rom_trace[i].flags = F::from_canonical_u64(inst.get_flags()); - rom_trace[i].multiplicity = F::from_canonical_u64(multiplicity); - /*println!( - "ROM SM [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}], {}", - inst.paddr, - inst.a_offset_imm0, - if inst.a_src == SRC_IMM { inst.a_use_sp_imm1 } else { 0 }, - inst.b_offset_imm0, - if inst.b_src == SRC_IMM { inst.b_use_sp_imm1 } else { 0 }, - if inst.b_src == SRC_IND { 1 } else { 0 }, - inst.ind_width, - inst.op, - inst.store_offset as u64, - inst.jmp_offset1 as u64, - inst.jmp_offset2 as u64, - inst.get_flags(), - multiplicity, - );*/ - i += 1; } // Padd with zeroes - for i in number_of_instructions..trace_size { - rom_trace[i] = RomRow::default(); + for i in rom.insts.len()..trace_rows { + rom_trace[i] = RomRomRow::default(); } - Ok((prover_buffer, offsets[0], ROM_AIR_IDS[0])) + Ok((commit_id, prover_buffer)) } - // fn create_rom_m( - // rom_m_size: usize, - // rom: &zisk_core::ZiskRom, - // number_of_instructions: usize, - // buffer_allocator: Arc, - // sctx: &SetupCtx, - // pc_histogram: ZiskPcHistogram, - // main_trace_len: u64, - // ) -> Result<(Vec, u64, usize), Box> { - // // Set trace size - // let trace_size = rom_m_size; - - // // Allocate a prover buffer - // let (buffer_size, offsets) = buffer_allocator - // .get_buffer_info(sctx, ZISK_AIRGROUP_ID, ROM_M_AIR_IDS[0]) - // .unwrap_or_else(|err| panic!("Error getting buffer info: {}", err)); - // let mut prover_buffer = create_buffer_fast(buffer_size as usize); - - // // Create an empty ROM trace - // let mut rom_trace = - // RomM1Trace::::map_buffer(&mut prover_buffer, trace_size, offsets[0] as usize) - // .expect("RomSM::compute_trace() failed mapping buffer to ROMMRow"); - - // // For every instruction in the rom, fill its corresponding ROM trace - // for (i, inst_builder) in rom.insts.clone().into_iter().enumerate() { - // // Get the Zisk instruction - // let inst = inst_builder.1.i; - - // // Calculate the multiplicity, i.e. the number of times this pc is used in this - // // execution - // let mut multiplicity: u64; - // if pc_histogram.map.is_empty() { - // multiplicity = 1; // If the histogram is empty, we use 1 for all pc's - // } else { - // let counter = pc_histogram.map.get(&inst.paddr); - // if counter.is_some() { - // multiplicity = *counter.unwrap(); - // if inst.paddr == pc_histogram.end_pc { - // multiplicity += main_trace_len - 1 - (pc_histogram.steps % - // main_trace_len); } - // } else { - // continue; // We skip those pc's that are not used in this execution - // } - // } - - // // Convert the i64 offsets to F - // let jmp_offset1 = if inst.jmp_offset1 >= 0 { - // F::from_canonical_u64(inst.jmp_offset1 as u64) - // } else { - // F::neg(F::from_canonical_u64((-inst.jmp_offset1) as u64)) - // }; - // let jmp_offset2 = if inst.jmp_offset2 >= 0 { - // F::from_canonical_u64(inst.jmp_offset2 as u64) - // } else { - // F::neg(F::from_canonical_u64((-inst.jmp_offset2) as u64)) - // }; - // let store_offset = if inst.store_offset >= 0 { - // F::from_canonical_u64(inst.store_offset as u64) - // } else { - // F::neg(F::from_canonical_u64((-inst.store_offset) as u64)) - // }; - // let a_offset_imm0 = if inst.a_offset_imm0 as i64 >= 0 { - // F::from_canonical_u64(inst.a_offset_imm0) - // } else { - // F::neg(F::from_canonical_u64((-(inst.a_offset_imm0 as i64)) as u64)) - // }; - // let b_offset_imm0 = if inst.b_offset_imm0 as i64 >= 0 { - // F::from_canonical_u64(inst.b_offset_imm0) - // } else { - // F::neg(F::from_canonical_u64((-(inst.b_offset_imm0 as i64)) as u64)) - // }; - - // // Fill the rom trace row fields - // rom_trace[i].line = F::from_canonical_u64(inst.paddr); // TODO: unify names: pc, - // paddr, line rom_trace[i].a_offset_imm0 = a_offset_imm0; - // rom_trace[i].a_imm1 = - // F::from_canonical_u64(if inst.a_src == SRC_IMM { inst.a_use_sp_imm1 } else { 0 - // }); rom_trace[i].b_offset_imm0 = b_offset_imm0; - // rom_trace[i].b_imm1 = - // F::from_canonical_u64(if inst.b_src == SRC_IMM { inst.b_use_sp_imm1 } else { 0 - // }); //rom_trace[i].b_src_ind = - // // F::from_canonical_u64(if inst.b_src == SRC_IND { 1 } else { 0 }); - // rom_trace[i].ind_width = F::from_canonical_u64(inst.ind_width); - // rom_trace[i].op = F::from_canonical_u8(inst.op); - // rom_trace[i].store_offset = store_offset; - // rom_trace[i].jmp_offset1 = jmp_offset1; - // rom_trace[i].jmp_offset2 = jmp_offset2; - // rom_trace[i].flags = F::from_canonical_u64(inst.get_flags()); - // rom_trace[i].multiplicity = F::from_canonical_u64(multiplicity); - // } - - // // Padd with zeroes - // for i in number_of_instructions..trace_size { - // rom_trace[i] = RomM1Row::default(); - // } - - // Ok((prover_buffer, offsets[0], ROM_M_AIR_IDS[0])) - // } - - // fn create_rom_l( - // rom_l_size: usize, - // rom: &zisk_core::ZiskRom, - // number_of_instructions: usize, - // buffer_allocator: Arc, - // sctx: &SetupCtx, - // pc_histogram: ZiskPcHistogram, - // main_trace_len: u64, - // ) -> Result<(Vec, u64, usize), Box> { - // // Set trace size - // let trace_size = rom_l_size; - - // // Allocate a prover buffer - // let (buffer_size, offsets) = buffer_allocator - // .get_buffer_info(sctx, ZISK_AIRGROUP_ID, ROM_L_AIR_IDS[0]) - // .unwrap_or_else(|err| panic!("Error getting buffer info: {}", err)); - // let mut prover_buffer = create_buffer_fast(buffer_size as usize); - - // // Create an empty ROM trace - // let mut rom_trace = - // RomL2Trace::::map_buffer(&mut prover_buffer, trace_size, offsets[0] as usize) - // .expect("RomSM::compute_trace() failed mapping buffer to ROMLRow"); - - // // For every instruction in the rom, fill its corresponding ROM trace - // for (i, inst_builder) in rom.insts.clone().into_iter().enumerate() { - // // Get the Zisk instruction - // let inst = inst_builder.1.i; - - // // Calculate the multiplicity, i.e. the number of times this pc is used in this - // // execution - // let mut multiplicity: u64; - // if pc_histogram.map.is_empty() { - // multiplicity = 1; // If the histogram is empty, we use 1 for all pc's - // } else { - // let counter = pc_histogram.map.get(&inst.paddr); - // if counter.is_some() { - // multiplicity = *counter.unwrap(); - // if inst.paddr == pc_histogram.end_pc { - // multiplicity += main_trace_len - 1 - (pc_histogram.steps % - // main_trace_len); } - // } else { - // continue; // We skip those pc's that are not used in this execution - // } - // } - - // // Convert the i64 offsets to F - // let jmp_offset1 = if inst.jmp_offset1 >= 0 { - // F::from_canonical_u64(inst.jmp_offset1 as u64) - // } else { - // F::neg(F::from_canonical_u64((-inst.jmp_offset1) as u64)) - // }; - // let jmp_offset2 = if inst.jmp_offset2 >= 0 { - // F::from_canonical_u64(inst.jmp_offset2 as u64) - // } else { - // F::neg(F::from_canonical_u64((-inst.jmp_offset2) as u64)) - // }; - // let store_offset = if inst.store_offset >= 0 { - // F::from_canonical_u64(inst.store_offset as u64) - // } else { - // F::neg(F::from_canonical_u64((-inst.store_offset) as u64)) - // }; - // let a_offset_imm0 = if inst.a_offset_imm0 as i64 >= 0 { - // F::from_canonical_u64(inst.a_offset_imm0) - // } else { - // F::neg(F::from_canonical_u64((-(inst.a_offset_imm0 as i64)) as u64)) - // }; - // let b_offset_imm0 = if inst.b_offset_imm0 as i64 >= 0 { - // F::from_canonical_u64(inst.b_offset_imm0) - // } else { - // F::neg(F::from_canonical_u64((-(inst.b_offset_imm0 as i64)) as u64)) - // }; - - // // Fill the rom trace row fields - // rom_trace[i].line = F::from_canonical_u64(inst.paddr); // TODO: unify names: pc, - // paddr, line rom_trace[i].a_offset_imm0 = a_offset_imm0; - // rom_trace[i].a_imm1 = - // F::from_canonical_u64(if inst.a_src == SRC_IMM { inst.a_use_sp_imm1 } else { 0 - // }); rom_trace[i].b_offset_imm0 = b_offset_imm0; - // rom_trace[i].b_imm1 = - // F::from_canonical_u64(if inst.b_src == SRC_IMM { inst.b_use_sp_imm1 } else { 0 - // }); //rom_trace[i].b_src_ind = - // // F::from_canonical_u64(if inst.b_src == SRC_IND { 1 } else { 0 }); - // rom_trace[i].ind_width = F::from_canonical_u64(inst.ind_width); - // rom_trace[i].op = F::from_canonical_u8(inst.op); - // rom_trace[i].store_offset = store_offset; - // rom_trace[i].jmp_offset1 = jmp_offset1; - // rom_trace[i].jmp_offset2 = jmp_offset2; - // rom_trace[i].flags = F::from_canonical_u64(inst.get_flags()); - // rom_trace[i].multiplicity = F::from_canonical_u64(multiplicity); - // } - - // // Padd with zeroes - // for i in number_of_instructions..trace_size { - // rom_trace[i] = RomL2Row::default(); - // } - - // Ok((prover_buffer, offsets[0], ROM_L_AIR_IDS[0])) - // } + pub fn compute_trace_rom_buffer( + rom_path: PathBuf, + buffer_allocator: Arc>, + sctx: &SetupCtx, + ) -> Result<(u64, Vec), Box> { + // Get the ELF file path as a string + let elf_filename: String = rom_path.to_str().unwrap().into(); + println!("Proving ROM for ELF file={}", elf_filename); + + // Load and parse the ELF file, and transpile it into a ZisK ROM using Riscv2zisk + + // Create an instance of the RISCV -> ZisK program converter + let riscv2zisk = Riscv2zisk::new(elf_filename, String::new(), String::new(), String::new()); + + // Convert program to rom + let rom = riscv2zisk.run().expect("RomSM::prover() failed converting elf to rom"); + + Self::compute_trace_rom(&rom, buffer_allocator, sctx) + } } impl WitnessComponent for RomSM {}