diff --git a/Cargo.lock b/Cargo.lock index eb715b8a..53eea25b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1105,9 +1105,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.162" +version = "0.2.168" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" +checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" [[package]] name = "libgit2-sys" @@ -2014,10 +2014,11 @@ dependencies = [ "p3-field", "p3-goldilocks", "proofman-common", + "proofman-util", "sm-rom", "stark", "sysinfo 0.32.0", - "zisk-core", + "zisk-pil", ] [[package]] @@ -2186,14 +2187,19 @@ name = "sm-arith" version = "0.1.0" dependencies = [ "log", + "num-bigint", "p3-field", + "pil-std-lib", "proofman", "proofman-common", "proofman-macros", + "proofman-util", "rayon", "sm-common", + "zisk-common", "zisk-core", "zisk-pil", + "ziskemu", ] [[package]] @@ -2297,8 +2303,29 @@ dependencies = [ name = "sm-rom" version = "0.1.0" dependencies = [ + "itertools 0.13.0", + "log", + "p3-field", + "proofman", + "proofman-common", + "proofman-macros", + "proofman-util", + "rayon", + "sm-common", + "zisk-common", + "zisk-core", + "zisk-pil", + "ziskemu", +] + +[[package]] +name = "sm-std" +version = "0.1.0" +dependencies = [ + "itertools 0.13.0", "log", "p3-field", + "pil-std-lib", "proofman", "proofman-common", "proofman-macros", @@ -2463,6 +2490,20 @@ dependencies = [ "windows", ] +[[package]] +name = "sysinfo" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "948512566b1895f93b1592c7574baeb2de842f224f2aab158799ecadb8ebbb46" +dependencies = [ + "core-foundation-sys", + "libc", + "memchr", + "ntapi", + "rayon", + "windows", +] + [[package]] name = "target-lexicon" version = "0.12.16" @@ -3296,6 +3337,7 @@ dependencies = [ "proofman", "proofman-common", "proofman-macros", + "serde", ] [[package]] @@ -3320,6 +3362,7 @@ dependencies = [ "sm-mem", "sm-quick-ops", "sm-rom", + "sm-std", "zisk-core", "zisk-pil", "ziskemu", @@ -3335,7 +3378,7 @@ dependencies = [ "pprof", "rayon", "riscv", - "sysinfo 0.31.4", + "sysinfo 0.33.0", "vergen", "zisk-common", "zisk-core", diff --git a/pil/Cargo.toml b/pil/Cargo.toml index 16a3d3b8..b762107b 100644 --- a/pil/Cargo.toml +++ b/pil/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" proofman-common = { workspace = true } proofman-macros = { workspace = true } proofman = { workspace = true } +serde = { version = "1.0.204", features = ["derive"] } [features] default = [] diff --git a/pil/src/pil_helpers/traces.rs b/pil/src/pil_helpers/traces.rs index e16150bc..ff06c800 100644 --- a/pil/src/pil_helpers/traces.rs +++ b/pil/src/pil_helpers/traces.rs @@ -1,13 +1,12 @@ // WARNING: This file has been autogenerated from the PILOUT file. // Manual modifications are not recommended and may be overwritten. -use proofman_common as common; pub use proofman_macros::trace; pub use proofman_macros::values; #[allow(dead_code)] type FieldExtension = [F; 3]; -pub const PILOUT_HASH: &[u8] = b"ZiskArith-hash"; +pub const PILOUT_HASH: &[u8] = b"Zisk-hash"; //AIRGROUP CONSTANTS @@ -35,13 +34,27 @@ pub const BINARY_EXTENSION_TABLE_AIR_IDS: &[usize] = &[8]; pub const SPECIFIED_RANGES_AIR_IDS: &[usize] = &[9]; + +//PUBLICS +use serde::Deserialize; +use serde::Serialize; +#[derive(Default, Debug, Serialize, Deserialize)] +pub struct ZiskPublics { + #[serde(default)] + pub rom_root: [u64; 4], + +} + +values!(ZiskPublicValues { + rom_root: [F; 4], +}); trace!(MainTrace { a: [F; 2], b: [F; 2], c: [F; 2], flag: F, pc: F, a_src_imm: F, a_src_mem: F, a_offset_imm0: F, a_imm1: F, a_src_step: F, b_src_imm: F, b_src_mem: F, b_offset_imm0: F, b_imm1: F, b_src_ind: F, ind_width: F, is_external_op: F, op: F, store_ra: F, store_mem: F, store_ind: F, store_offset: F, set_pc: F, jmp_offset1: F, jmp_offset2: F, m32: F, addr1: F, __debug_operation_bus_enabled: F, }, 0, 0, 2097152 ); trace!(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, }, 0, 1, 1048576 ); trace!(ArithTrace { @@ -76,6 +89,10 @@ trace!(SpecifiedRangesTrace { mul: [F; 1], }, 0, 9, 16777216 ); +trace!(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, +}, 0, 1, 1048576, 0 ); + values!(MainAirValues { - main_last_segment: FieldExtension, main_segment: FieldExtension, + main_last_segment: F, main_segment: F, }); diff --git a/rom-merkle/Cargo.toml b/rom-merkle/Cargo.toml index 7a5bda84..13b1a66d 100644 --- a/rom-merkle/Cargo.toml +++ b/rom-merkle/Cargo.toml @@ -8,11 +8,12 @@ sm-rom = { path = "../state-machines/rom" } log = { workspace = true } stark = { workspace = true } proofman-common = { workspace = true } -zisk-core = { path = "../core" } +proofman-util = { workspace = true } +zisk-pil = { path="../pil" } p3-goldilocks = { git = "https://github.com/Plonky3/Plonky3.git", rev = "c3d754ef77b9fce585b46b972af751fe6e7a9803" } p3-field = { workspace = true } clap = { version = "4.5.13", features = ["derive", "env"] } env_logger = "0.11" -sysinfo = "0.33" +sysinfo = "0.32" colored = "2" \ No newline at end of file diff --git a/rom-merkle/src/main.rs b/rom-merkle/src/main.rs index 15428c55..655dbc97 100644 --- a/rom-merkle/src/main.rs +++ b/rom-merkle/src/main.rs @@ -1,41 +1,44 @@ use clap::{Arg, Command}; use colored::Colorize; -// use proofman_common::{GlobalInfo, ProofType, SetupCtx}; -// use stark::StarkBufferAllocator; -use std::path::Path; +use p3_goldilocks::Goldilocks; +use proofman_common::{get_custom_commit_trace, GlobalInfo, ProofType, SetupCtx}; +use proofman_util::create_buffer_fast; +use sm_rom::RomSM; +use std::{path::Path, sync::Arc}; use sysinfo::System; -// use zisk_core::Riscv2zisk; +use zisk_pil::RomRomTrace; 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(); // Get the value of the `rom` argument as a path let rom_path_str = matches.get_one::("rom").expect("ROM path is required"); let rom_path = Path::new(rom_path_str); - // 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 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 rom_buffer_str = + matches.get_one::("rom_buffer").expect("Buffer file path is required"); env_logger::builder() .format_timestamp(None) @@ -77,29 +80,25 @@ 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 _sctx = Arc::new(SetupCtx::new(&global_info, &ProofType::Basic)); + let global_info = GlobalInfo::new(proving_key_path); + let sctx = Arc::new(SetupCtx::new(&global_info, &ProofType::Basic)); - // // 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); + let mut custom_rom_trace: RomRomTrace = RomRomTrace::new(); + let setup = sctx.get_setup(custom_rom_trace.airgroup_id(), custom_rom_trace.air_id); - // // Create an instance of the RISCV -> ZisK program converter - // let riscv2zisk = Riscv2zisk::new(elf_filename, String::new(), String::new(), String::new()); + RomSM::::compute_custom_trace_rom(rom_path.to_path_buf(), &mut custom_rom_trace); - // // Convert program to rom - // let _rom = riscv2zisk.run().expect("RomSM::prover() failed running rom"); + let n_ext = (1 << setup.stark_info.stark_struct.n_bits_ext) as usize; + let n_cols = custom_rom_trace.num_rows(); - // // Compute the trace - // // RomSM::::prove_instance(wcm, rom, plan, buffer, trace_rows); + let buffer_ext = create_buffer_fast(n_ext * n_cols); - // // Compute LDE and Merkelize and get the root of the rom - // // TODO: Implement the logic to compute the trace - - log::info!("ROM proof successful"); + get_custom_commit_trace( + custom_rom_trace.commit_id.unwrap() as u64, + 0, + setup, + custom_rom_trace.get_buffer(), + buffer_ext, + rom_buffer_str.as_str(), + ); } diff --git a/state-machines/main/pil/main.pil b/state-machines/main/pil/main.pil index 494c7945..8fb32259 100644 --- a/state-machines/main/pil/main.pil +++ b/state-machines/main/pil/main.pil @@ -274,6 +274,6 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope lookup_assumes(ROM_BUS_ID, [pc, a_offset_imm0, a_imm1, b_offset_imm0, b_imm1, ind_width, op, store_offset, jmp_offset1, jmp_offset2, rom_flags], sel: 1 - SEGMENT_L1); - direct_global_update(MAIN_CONTINUATION_ID, cols: [0, 0, 4096, 0, 0], bus_type: PIOP_BUS_SUM, proves: 1); - direct_global_update(MAIN_CONTINUATION_ID, cols: [0, 1, 0x10000000, 0, 0], bus_type: PIOP_BUS_SUM, proves: 0); + direct_global_update(MAIN_CONTINUATION_ID, cols: [0, 0, 4096, 0, 0, 0, 0, 0], bus_type: PIOP_BUS_SUM, proves: 1); + direct_global_update(MAIN_CONTINUATION_ID, cols: [0, 1, 0x10000000, 0, 0, 0, 0, 0], bus_type: PIOP_BUS_SUM, proves: 0); } \ No newline at end of file diff --git a/state-machines/main/src/main_sm.rs b/state-machines/main/src/main_sm.rs index ece4cf03..51a6e961 100644 --- a/state-machines/main/src/main_sm.rs +++ b/state-machines/main/src/main_sm.rs @@ -132,8 +132,8 @@ impl MainSM { let main_segment = F::from_canonical_usize(current_segment); let mut main_air_values = MainAirValues::::new(); - main_air_values.main_last_segment[0] = main_last_segment; - main_air_values.main_segment[0] = main_segment; + main_air_values.main_last_segment = main_last_segment; + main_air_values.main_segment = main_segment; let air_instance = AirInstance::new_from_trace( self.wcm.get_sctx(), 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 8a0215b7..1360c815 100644 --- a/state-machines/rom/src/rom.rs +++ b/state-machines/rom/src/rom.rs @@ -1,4 +1,4 @@ -use std::sync::Arc; +use std::{path::PathBuf, sync::Arc}; use itertools::Itertools; use log::info; @@ -6,10 +6,9 @@ use p3_field::PrimeField; use proofman::WitnessManager; use sm_common::{ComponentProvider, Instance, InstanceExpanderCtx, Metrics, Plan, Planner}; -use zisk_core::{ZiskRom, SRC_IMM}; -use zisk_pil::{MainTrace, RomTrace, RomTraceRow}; - use crate::{RomCounter, RomInstance, RomPlanner}; +use zisk_core::{Riscv2zisk, ZiskRom, SRC_IMM}; +use zisk_pil::{MainTrace, RomRomTrace, RomRomTraceRow, RomTrace, RomTraceRow}; pub struct RomSM { wcm: Arc>, @@ -28,7 +27,7 @@ impl RomSM { rom: &ZiskRom, plan: &Plan, rom_trace: &mut RomTrace, - trace_rows: usize, + mut rom_custom_trace: &mut RomRomTrace, ) { let metadata = plan.meta.as_ref().unwrap().downcast_ref::().unwrap(); @@ -45,10 +44,7 @@ impl RomSM { // 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 { + for (i, key) in rom.insts.keys().sorted().enumerate() { // Get the Zisk instruction let inst = &rom.insts[key].i; @@ -69,6 +65,22 @@ 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()..rom_trace.num_rows() { + rom_trace[i] = RomTraceRow::default(); + } + + Self::compute_trace_rom(rom, &mut rom_custom_trace); + } + + pub fn compute_trace_rom(rom: &ZiskRom, rom_custom_trace: &mut RomRomTrace) { + // 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 { @@ -98,46 +110,42 @@ impl RomSM { }; // 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 = + rom_custom_trace[i].line = F::from_canonical_u64(inst.paddr); // TODO: unify names: pc, paddr, line + rom_custom_trace[i].a_offset_imm0 = a_offset_imm0; + rom_custom_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 = + rom_custom_trace[i].b_offset_imm0 = b_offset_imm0; + rom_custom_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; + rom_custom_trace[i].ind_width = F::from_canonical_u64(inst.ind_width); + rom_custom_trace[i].op = F::from_canonical_u8(inst.op); + rom_custom_trace[i].store_offset = store_offset; + rom_custom_trace[i].jmp_offset1 = jmp_offset1; + rom_custom_trace[i].jmp_offset2 = jmp_offset2; + rom_custom_trace[i].flags = F::from_canonical_u64(inst.get_flags()); } // Padd with zeroes - for i in rom.insts.len()..trace_rows { - rom_trace[i] = RomTraceRow::default(); + for i in rom.insts.len()..rom_custom_trace.num_rows() { + rom_custom_trace[i] = RomRomTraceRow::default(); } } + + pub fn compute_custom_trace_rom(rom_path: PathBuf, rom_custom_trace: &mut RomRomTrace) { + // 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, rom_custom_trace); + } } impl ComponentProvider for RomSM { diff --git a/state-machines/rom/src/rom_instance.rs b/state-machines/rom/src/rom_instance.rs index f43b69a8..3b89b5a9 100644 --- a/state-machines/rom/src/rom_instance.rs +++ b/state-machines/rom/src/rom_instance.rs @@ -5,7 +5,7 @@ use proofman::WitnessManager; use proofman_common::{AirInstance, FromTrace}; use sm_common::{Instance, InstanceExpanderCtx, InstanceType}; use zisk_core::ZiskRom; -use zisk_pil::RomTrace; +use zisk_pil::{RomRomTrace, RomTrace}; use ziskemu::EmuTrace; use crate::RomSM; @@ -15,6 +15,7 @@ pub struct RomInstance { zisk_rom: Arc, iectx: InstanceExpanderCtx, rom_trace: RomTrace, + rom_custom_trace: RomRomTrace, } impl RomInstance { @@ -24,8 +25,9 @@ impl RomInstance { iectx: InstanceExpanderCtx, ) -> Self { let rom_trace = RomTrace::new(); + let rom_custom_trace = RomRomTrace::new(); - Self { wcm, zisk_rom, iectx, rom_trace } + Self { wcm, zisk_rom, iectx, rom_trace, rom_custom_trace } } } @@ -46,11 +48,14 @@ impl Instance for RomInstance { &self.zisk_rom, &self.iectx.plan, &mut self.rom_trace, - RomTrace::::NUM_ROWS, + &mut self.rom_custom_trace, ); - let air_instance = - AirInstance::new_from_trace(self.wcm.get_sctx(), FromTrace::new(&mut self.rom_trace)); + let air_instance = AirInstance::new_from_trace( + self.wcm.get_sctx(), + FromTrace::new(&mut self.rom_trace) + .with_custom_traces(vec![&mut self.rom_custom_trace]), + ); self.wcm .get_pctx()