diff --git a/book/src/usage/troubleshooting.md b/book/src/usage/troubleshooting.md index b83556e61..e8c998224 100644 --- a/book/src/usage/troubleshooting.md +++ b/book/src/usage/troubleshooting.md @@ -24,3 +24,14 @@ Jolt restricts the size of the inputs and outputs to 4096 bytes. This value is c ## Guest Attempts to Compile Standard Library Sometimes after installing the toolchain the guest does still tries to compile with the standard library which will fail with a large number of errors that certain items such as `Result` are referenced and not available. This generally happens when one tries to run jolt before installing the toolchain. To address, try rerunning `jolt install-toolchain`, restarting your terminal, and delete both your rust target directory and any files under `/tmp` that begin with jolt. + + +## Getting Help +If none of the above help, please serialize your program and send it along with a detailed bug report. + +Serializing a call to the "fib" function in the Jolt guest: +```rust +// let (prove_fib, verify_fib) = guest::build_fib(); +let program_summary = guest::analyze_fib(10); +program_summary.write_to_file("fib_10.txt".into()).expect("should write"); +``` \ No newline at end of file diff --git a/common/src/rv_trace.rs b/common/src/rv_trace.rs index 2abd181a9..62598e20e 100644 --- a/common/src/rv_trace.rs +++ b/common/src/rv_trace.rs @@ -5,14 +5,14 @@ use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use serde::{Deserialize, Serialize}; use strum_macros::FromRepr; -#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct RVTraceRow { pub instruction: ELFInstruction, pub register_state: RegisterState, pub memory_state: Option, } -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] pub enum MemoryOp { Read(u64, u64), // (address, value) Write(u64, u64), // (address, new_value) @@ -375,7 +375,7 @@ pub struct RegisterState { pub rd_post_val: Option, } -#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub enum MemoryState { Read { address: u64, diff --git a/examples/fibonacci/src/main.rs b/examples/fibonacci/src/main.rs index 5c009c06a..96bcec81c 100644 --- a/examples/fibonacci/src/main.rs +++ b/examples/fibonacci/src/main.rs @@ -1,5 +1,9 @@ pub fn main() { let (prove_fib, verify_fib) = guest::build_fib(); + let program_summary = guest::analyze_fib(10); + program_summary + .write_to_file("fib_10.txt".into()) + .expect("should write"); let (output, proof) = prove_fib(50); let is_valid = verify_fib(proof); diff --git a/jolt-core/Cargo.toml b/jolt-core/Cargo.toml index 063b8c20c..03dd41112 100644 --- a/jolt-core/Cargo.toml +++ b/jolt-core/Cargo.toml @@ -59,6 +59,7 @@ tracing-texray = "0.2.0" common = { path = "../common" } tracer = { path = "../tracer" } +bincode = "1.3.3" [build-dependencies] common = { path = "../common" } diff --git a/jolt-core/src/host/analyze.rs b/jolt-core/src/host/analyze.rs new file mode 100644 index 000000000..aa5cc166e --- /dev/null +++ b/jolt-core/src/host/analyze.rs @@ -0,0 +1,54 @@ +use std::{collections::HashMap, fs::File, io, path::PathBuf}; + +use ark_ff::PrimeField; +use serde::{Deserialize, Serialize}; +use tracer::{ELFInstruction, JoltDevice, RVTraceRow, RV32IM}; + +use crate::jolt::vm::{bytecode::BytecodeRow, rv32i_vm::RV32I}; + +use common::{constants::MEMORY_OPS_PER_INSTRUCTION, rv_trace::MemoryOp}; + +#[derive(Clone, Serialize, Deserialize)] +pub struct ProgramSummary { + pub raw_trace: Vec, + + pub bytecode: Vec, + pub memory_init: Vec<(u64, u8)>, + + pub io_device: JoltDevice, + pub bytecode_trace: Vec, + pub instruction_trace: Vec>, + pub memory_trace: Vec<[MemoryOp; MEMORY_OPS_PER_INSTRUCTION]>, + pub circuit_flags: Vec, +} + +impl ProgramSummary { + pub fn trace_len(&self) -> usize { + self.memory_trace.len() + } + + pub fn analyze(&self) -> Vec<(RV32IM, usize)> { + let mut counts = HashMap::::new(); + for row in self.raw_trace.iter() { + let op = row.instruction.opcode; + if let Some(count) = counts.get(&op) { + counts.insert(op, count + 1); + } else { + counts.insert(op, 1); + } + } + + let mut counts: Vec<_> = counts.into_iter().collect(); + counts.sort_by_key(|v| v.1); + counts.reverse(); + + counts + } + + pub fn write_to_file(self, path: PathBuf) -> Result<(), Box> { + let mut file = File::create(path)?; + let data = bincode::serialize(&self)?; + io::Write::write_all(&mut file, &data)?; + Ok(()) + } +} diff --git a/jolt-core/src/host/mod.rs b/jolt-core/src/host/mod.rs index feef87de9..b43ca28e1 100644 --- a/jolt-core/src/host/mod.rs +++ b/jolt-core/src/host/mod.rs @@ -1,6 +1,5 @@ use core::{str::FromStr, u8}; use std::{ - collections::HashMap, fs::{self, File}, io::{self, Write}, path::PathBuf, @@ -14,7 +13,7 @@ use serde::Serialize; use common::{ constants::MEMORY_OPS_PER_INSTRUCTION, - rv_trace::{JoltDevice, MemoryOp, NUM_CIRCUIT_FLAGS, RV32IM}, + rv_trace::{JoltDevice, MemoryOp, NUM_CIRCUIT_FLAGS}, }; use tracer::ELFInstruction; @@ -23,6 +22,10 @@ use crate::{ utils::thread::unsafe_allocate_zero_vec, }; +use self::analyze::ProgramSummary; + +pub mod analyze; + const DEFAULT_MEMORY_SIZE: usize = 10 * 1024 * 1024; const DEFAULT_STACK_SIZE: usize = 4096; @@ -173,27 +176,31 @@ impl Program { ) } - pub fn trace_analyze(mut self) -> (usize, Vec<(RV32IM, usize)>) { + pub fn trace_analyze(mut self) -> ProgramSummary { self.build(); - let elf = self.elf.unwrap(); - let (rows, _) = tracer::trace(&elf, self.input); - let trace_len = rows.len(); - - let mut counts = HashMap::::new(); - for row in rows { - let op = row.instruction.opcode; - if let Some(count) = counts.get(&op) { - counts.insert(op, count + 1); - } else { - counts.insert(op, 1); - } - } + let elf = self.elf.as_ref().unwrap(); + let (raw_trace, _) = tracer::trace(&elf, self.input.clone()); + + let (bytecode, memory_init) = self.decode(); + let (io_device, bytecode_trace, instruction_trace, memory_trace, circuit_flags) = + self.trace(); + let circuit_flags: Vec = circuit_flags + .into_iter() + .map(|flag: F| flag.is_one()) + .collect(); - let mut counts: Vec<_> = counts.into_iter().collect(); - counts.sort_by_key(|v| v.1); - counts.reverse(); + let program_summary = ProgramSummary { + raw_trace, + bytecode, + memory_init, + io_device, + bytecode_trace, + instruction_trace, + memory_trace, + circuit_flags, + }; - (trace_len, counts) + program_summary } fn save_linker(&self) { diff --git a/jolt-core/src/jolt/instruction/add.rs b/jolt-core/src/jolt/instruction/add.rs index 0dbf163f5..6dd8732a8 100644 --- a/jolt-core/src/jolt/instruction/add.rs +++ b/jolt-core/src/jolt/instruction/add.rs @@ -1,6 +1,7 @@ use ark_ff::PrimeField; use ark_std::log2; use rand::prelude::StdRng; +use serde::{Deserialize, Serialize}; use super::{JoltInstruction, SubtableIndices}; use crate::jolt::subtable::{ @@ -10,7 +11,7 @@ use crate::utils::instruction_utils::{ add_and_chunk_operands, assert_valid_parameters, concatenate_lookups, }; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)] pub struct ADDInstruction(pub u64, pub u64); impl JoltInstruction for ADDInstruction { diff --git a/jolt-core/src/jolt/instruction/and.rs b/jolt-core/src/jolt/instruction/and.rs index f74f9eb4a..fa7ba30bc 100644 --- a/jolt-core/src/jolt/instruction/and.rs +++ b/jolt-core/src/jolt/instruction/and.rs @@ -1,12 +1,13 @@ use ark_ff::PrimeField; use ark_std::log2; use rand::prelude::StdRng; +use serde::{Deserialize, Serialize}; use super::{JoltInstruction, SubtableIndices}; use crate::jolt::subtable::{and::AndSubtable, LassoSubtable}; use crate::utils::instruction_utils::{chunk_and_concatenate_operands, concatenate_lookups}; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)] pub struct ANDInstruction(pub u64, pub u64); impl JoltInstruction for ANDInstruction { diff --git a/jolt-core/src/jolt/instruction/beq.rs b/jolt-core/src/jolt/instruction/beq.rs index beb6a5ec9..88baed8c4 100644 --- a/jolt-core/src/jolt/instruction/beq.rs +++ b/jolt-core/src/jolt/instruction/beq.rs @@ -1,5 +1,6 @@ use ark_ff::PrimeField; use rand::prelude::StdRng; +use serde::{Deserialize, Serialize}; use super::JoltInstruction; use crate::{ @@ -10,7 +11,7 @@ use crate::{ utils::instruction_utils::chunk_and_concatenate_operands, }; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)] pub struct BEQInstruction(pub u64, pub u64); impl JoltInstruction for BEQInstruction { diff --git a/jolt-core/src/jolt/instruction/bge.rs b/jolt-core/src/jolt/instruction/bge.rs index e42bd4911..ee75973a2 100644 --- a/jolt-core/src/jolt/instruction/bge.rs +++ b/jolt-core/src/jolt/instruction/bge.rs @@ -1,5 +1,6 @@ use ark_ff::PrimeField; use rand::prelude::StdRng; +use serde::{Deserialize, Serialize}; use super::{slt::SLTInstruction, JoltInstruction, SubtableIndices}; use crate::{ @@ -10,7 +11,7 @@ use crate::{ utils::instruction_utils::chunk_and_concatenate_operands, }; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)] pub struct BGEInstruction(pub u64, pub u64); impl JoltInstruction for BGEInstruction { diff --git a/jolt-core/src/jolt/instruction/bgeu.rs b/jolt-core/src/jolt/instruction/bgeu.rs index 6092a7824..ff9dc3d3e 100644 --- a/jolt-core/src/jolt/instruction/bgeu.rs +++ b/jolt-core/src/jolt/instruction/bgeu.rs @@ -1,5 +1,6 @@ use ark_ff::PrimeField; use rand::prelude::StdRng; +use serde::{Deserialize, Serialize}; use super::{sltu::SLTUInstruction, JoltInstruction, SubtableIndices}; use crate::{ @@ -7,7 +8,7 @@ use crate::{ utils::instruction_utils::chunk_and_concatenate_operands, }; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)] pub struct BGEUInstruction(pub u64, pub u64); impl JoltInstruction for BGEUInstruction { diff --git a/jolt-core/src/jolt/instruction/bne.rs b/jolt-core/src/jolt/instruction/bne.rs index 7019480b8..7c0430eda 100644 --- a/jolt-core/src/jolt/instruction/bne.rs +++ b/jolt-core/src/jolt/instruction/bne.rs @@ -1,5 +1,6 @@ use ark_ff::PrimeField; use rand::prelude::StdRng; +use serde::{Deserialize, Serialize}; use super::JoltInstruction; use crate::{ @@ -10,7 +11,7 @@ use crate::{ utils::instruction_utils::chunk_and_concatenate_operands, }; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)] pub struct BNEInstruction(pub u64, pub u64); impl JoltInstruction for BNEInstruction { diff --git a/jolt-core/src/jolt/instruction/lb.rs b/jolt-core/src/jolt/instruction/lb.rs index 5b7f402af..2bf343c19 100644 --- a/jolt-core/src/jolt/instruction/lb.rs +++ b/jolt-core/src/jolt/instruction/lb.rs @@ -1,5 +1,6 @@ use ark_ff::PrimeField; use rand::prelude::StdRng; +use serde::{Deserialize, Serialize}; use super::{JoltInstruction, SubtableIndices}; use crate::jolt::subtable::{ @@ -7,7 +8,7 @@ use crate::jolt::subtable::{ }; use crate::utils::instruction_utils::chunk_operand_usize; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)] pub struct LBInstruction(pub u64); impl JoltInstruction for LBInstruction { diff --git a/jolt-core/src/jolt/instruction/lh.rs b/jolt-core/src/jolt/instruction/lh.rs index 1f3b1b51b..a4001f247 100644 --- a/jolt-core/src/jolt/instruction/lh.rs +++ b/jolt-core/src/jolt/instruction/lh.rs @@ -1,5 +1,6 @@ use ark_ff::PrimeField; use rand::prelude::StdRng; +use serde::{Deserialize, Serialize}; use super::{JoltInstruction, SubtableIndices}; use crate::jolt::subtable::{ @@ -7,7 +8,7 @@ use crate::jolt::subtable::{ }; use crate::utils::instruction_utils::chunk_operand_usize; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)] pub struct LHInstruction(pub u64); impl JoltInstruction for LHInstruction { diff --git a/jolt-core/src/jolt/instruction/mod.rs b/jolt-core/src/jolt/instruction/mod.rs index 3817b7b6b..6fed7db49 100644 --- a/jolt-core/src/jolt/instruction/mod.rs +++ b/jolt-core/src/jolt/instruction/mod.rs @@ -2,6 +2,7 @@ use ark_ff::PrimeField; use enum_dispatch::enum_dispatch; use fixedbitset::*; use rand::prelude::StdRng; +use serde::Serialize; use std::marker::Sync; use std::ops::Range; use strum::{EnumCount, IntoEnumIterator}; @@ -12,7 +13,7 @@ use common::rv_trace::ELFInstruction; use std::fmt::Debug; #[enum_dispatch] -pub trait JoltInstruction: Clone + Debug + Send + Sync { +pub trait JoltInstruction: Clone + Debug + Send + Sync + Serialize { fn operands(&self) -> (u64, u64); /// Combines `vals` according to the instruction's "collation" polynomial `g`. /// If `vals` are subtable entries (as opposed to MLE evaluations), this function returns the diff --git a/jolt-core/src/jolt/instruction/or.rs b/jolt-core/src/jolt/instruction/or.rs index 42b2d595e..b060b65cd 100644 --- a/jolt-core/src/jolt/instruction/or.rs +++ b/jolt-core/src/jolt/instruction/or.rs @@ -1,12 +1,13 @@ use ark_ff::PrimeField; use ark_std::log2; use rand::prelude::StdRng; +use serde::{Deserialize, Serialize}; use super::{JoltInstruction, SubtableIndices}; use crate::jolt::subtable::{or::OrSubtable, LassoSubtable}; use crate::utils::instruction_utils::{chunk_and_concatenate_operands, concatenate_lookups}; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)] pub struct ORInstruction(pub u64, pub u64); impl JoltInstruction for ORInstruction { diff --git a/jolt-core/src/jolt/instruction/sb.rs b/jolt-core/src/jolt/instruction/sb.rs index a1d168e1b..78bc23973 100644 --- a/jolt-core/src/jolt/instruction/sb.rs +++ b/jolt-core/src/jolt/instruction/sb.rs @@ -1,11 +1,12 @@ use ark_ff::PrimeField; use rand::prelude::StdRng; +use serde::{Deserialize, Serialize}; use super::{JoltInstruction, SubtableIndices}; use crate::jolt::subtable::{truncate_overflow::TruncateOverflowSubtable, LassoSubtable}; use crate::utils::instruction_utils::chunk_operand_usize; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)] pub struct SBInstruction(pub u64); impl JoltInstruction for SBInstruction { diff --git a/jolt-core/src/jolt/instruction/sh.rs b/jolt-core/src/jolt/instruction/sh.rs index 599c9c92d..f43221413 100644 --- a/jolt-core/src/jolt/instruction/sh.rs +++ b/jolt-core/src/jolt/instruction/sh.rs @@ -1,12 +1,13 @@ use ark_ff::PrimeField; use rand::prelude::StdRng; +use serde::{Deserialize, Serialize}; use super::{JoltInstruction, SubtableIndices}; use crate::jolt::subtable::{identity::IdentitySubtable, LassoSubtable}; use crate::utils::instruction_utils::chunk_operand_usize; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)] pub struct SHInstruction(pub u64); impl JoltInstruction for SHInstruction { diff --git a/jolt-core/src/jolt/instruction/sll.rs b/jolt-core/src/jolt/instruction/sll.rs index 9d55649c4..de14fca7f 100644 --- a/jolt-core/src/jolt/instruction/sll.rs +++ b/jolt-core/src/jolt/instruction/sll.rs @@ -1,6 +1,7 @@ use ark_ff::PrimeField; use ark_std::log2; use rand::prelude::StdRng; +use serde::{Deserialize, Serialize}; use super::{JoltInstruction, SubtableIndices}; use crate::jolt::subtable::{sll::SllSubtable, LassoSubtable}; @@ -8,7 +9,7 @@ use crate::utils::instruction_utils::{ assert_valid_parameters, chunk_and_concatenate_for_shift, concatenate_lookups, }; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)] pub struct SLLInstruction(pub u64, pub u64); impl JoltInstruction for SLLInstruction { diff --git a/jolt-core/src/jolt/instruction/slt.rs b/jolt-core/src/jolt/instruction/slt.rs index 3f2e0f80e..94cf245aa 100644 --- a/jolt-core/src/jolt/instruction/slt.rs +++ b/jolt-core/src/jolt/instruction/slt.rs @@ -1,5 +1,6 @@ use ark_ff::PrimeField; use rand::prelude::StdRng; +use serde::{Deserialize, Serialize}; use super::{JoltInstruction, SubtableIndices}; use crate::{ @@ -10,7 +11,7 @@ use crate::{ utils::instruction_utils::chunk_and_concatenate_operands, }; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)] pub struct SLTInstruction(pub u64, pub u64); impl JoltInstruction for SLTInstruction { diff --git a/jolt-core/src/jolt/instruction/sltu.rs b/jolt-core/src/jolt/instruction/sltu.rs index cd0d178e8..804eb8aa9 100644 --- a/jolt-core/src/jolt/instruction/sltu.rs +++ b/jolt-core/src/jolt/instruction/sltu.rs @@ -1,5 +1,6 @@ use ark_ff::PrimeField; use rand::prelude::StdRng; +use serde::{Deserialize, Serialize}; use super::JoltInstruction; use crate::{ @@ -10,7 +11,7 @@ use crate::{ utils::instruction_utils::chunk_and_concatenate_operands, }; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)] pub struct SLTUInstruction(pub u64, pub u64); impl JoltInstruction for SLTUInstruction { diff --git a/jolt-core/src/jolt/instruction/sra.rs b/jolt-core/src/jolt/instruction/sra.rs index b26dd23f4..8199249eb 100644 --- a/jolt-core/src/jolt/instruction/sra.rs +++ b/jolt-core/src/jolt/instruction/sra.rs @@ -1,11 +1,12 @@ use ark_ff::PrimeField; use rand::prelude::StdRng; +use serde::{Deserialize, Serialize}; use super::{JoltInstruction, SubtableIndices}; use crate::jolt::subtable::{sra_sign::SraSignSubtable, srl::SrlSubtable, LassoSubtable}; use crate::utils::instruction_utils::{assert_valid_parameters, chunk_and_concatenate_for_shift}; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)] pub struct SRAInstruction(pub u64, pub u64); impl JoltInstruction for SRAInstruction { diff --git a/jolt-core/src/jolt/instruction/srl.rs b/jolt-core/src/jolt/instruction/srl.rs index d1e5540e6..54bc0a203 100644 --- a/jolt-core/src/jolt/instruction/srl.rs +++ b/jolt-core/src/jolt/instruction/srl.rs @@ -1,11 +1,12 @@ use ark_ff::PrimeField; use rand::prelude::StdRng; +use serde::{Deserialize, Serialize}; use super::{JoltInstruction, SubtableIndices}; use crate::jolt::subtable::{srl::SrlSubtable, LassoSubtable}; use crate::utils::instruction_utils::{assert_valid_parameters, chunk_and_concatenate_for_shift}; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)] pub struct SRLInstruction(pub u64, pub u64); impl JoltInstruction for SRLInstruction { diff --git a/jolt-core/src/jolt/instruction/sub.rs b/jolt-core/src/jolt/instruction/sub.rs index 8a5d20048..b4af69855 100644 --- a/jolt-core/src/jolt/instruction/sub.rs +++ b/jolt-core/src/jolt/instruction/sub.rs @@ -1,6 +1,7 @@ use ark_ff::PrimeField; use ark_std::log2; use rand::prelude::StdRng; +use serde::{Deserialize, Serialize}; use super::{JoltInstruction, SubtableIndices}; use crate::jolt::subtable::{ @@ -10,7 +11,7 @@ use crate::utils::instruction_utils::{ add_and_chunk_operands, assert_valid_parameters, concatenate_lookups, }; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)] pub struct SUBInstruction(pub u64, pub u64); impl JoltInstruction for SUBInstruction { diff --git a/jolt-core/src/jolt/instruction/sw.rs b/jolt-core/src/jolt/instruction/sw.rs index ba2b1d744..6b3141c96 100644 --- a/jolt-core/src/jolt/instruction/sw.rs +++ b/jolt-core/src/jolt/instruction/sw.rs @@ -1,12 +1,13 @@ use ark_ff::PrimeField; use ark_std::log2; use rand::prelude::StdRng; +use serde::{Deserialize, Serialize}; use super::{JoltInstruction, SubtableIndices}; use crate::jolt::subtable::{identity::IdentitySubtable, LassoSubtable}; use crate::utils::instruction_utils::{chunk_operand_usize, concatenate_lookups}; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)] pub struct SWInstruction(pub u64); impl JoltInstruction for SWInstruction { diff --git a/jolt-core/src/jolt/instruction/xor.rs b/jolt-core/src/jolt/instruction/xor.rs index 55760600c..88020a8f6 100644 --- a/jolt-core/src/jolt/instruction/xor.rs +++ b/jolt-core/src/jolt/instruction/xor.rs @@ -1,13 +1,14 @@ use ark_ff::PrimeField; use ark_std::log2; use rand::prelude::StdRng; +use serde::{Deserialize, Serialize}; use super::JoltInstruction; use crate::jolt::instruction::SubtableIndices; use crate::jolt::subtable::{xor::XorSubtable, LassoSubtable}; use crate::utils::instruction_utils::{chunk_and_concatenate_operands, concatenate_lookups}; -#[derive(Copy, Clone, Default, Debug)] +#[derive(Copy, Clone, Default, Debug, Serialize, Deserialize)] pub struct XORInstruction(pub u64, pub u64); impl JoltInstruction for XORInstruction { diff --git a/jolt-core/src/jolt/vm/bytecode.rs b/jolt-core/src/jolt/vm/bytecode.rs index 0c21f6763..ad5685257 100644 --- a/jolt-core/src/jolt/vm/bytecode.rs +++ b/jolt-core/src/jolt/vm/bytecode.rs @@ -3,6 +3,7 @@ use ark_ff::PrimeField; use merlin::Transcript; use rand::rngs::StdRng; use rand_core::RngCore; +use serde::{Deserialize, Serialize}; use std::{collections::HashMap, marker::PhantomData}; use crate::jolt::instruction::JoltInstructionSet; @@ -36,7 +37,7 @@ pub type BytecodeProof = MemoryCheckingProof< BytecodeInitFinalOpenings, >; -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct BytecodeRow { /// Memory address as read from the ELF. address: usize, @@ -183,9 +184,7 @@ impl BytecodePreprocessing { bytecode.insert(0, BytecodeRow::no_op(0)); // Bytecode: Pad to nearest power of 2 - for _ in bytecode.len()..bytecode.len().next_power_of_two() { - bytecode.push(BytecodeRow::no_op(0)); - } + bytecode.resize(bytecode.len().next_power_of_two(), BytecodeRow::no_op(0)); let max_bytecode_address = bytecode.iter().map(|instr| instr.address).max().unwrap(); // Bytecode addresses are 0-indexed, so we add one to `max_bytecode_address` @@ -246,10 +245,7 @@ impl> BytecodePolynomials { } // Pad trace to nearest power of 2 - for _ in trace.len()..trace.len().next_power_of_two() { - // All padded elements of the trace point at the no_op row of the bytecode - trace.push(BytecodeRow::no_op(0)); - } + trace.resize(trace.len().next_power_of_two(), BytecodeRow::no_op(0)); let num_ops = trace.len(); diff --git a/jolt-core/src/jolt/vm/rv32i_vm.rs b/jolt-core/src/jolt/vm/rv32i_vm.rs index 162337d8a..dc7c21e6d 100644 --- a/jolt-core/src/jolt/vm/rv32i_vm.rs +++ b/jolt-core/src/jolt/vm/rv32i_vm.rs @@ -2,6 +2,7 @@ use ark_ec::CurveGroup; use ark_ff::PrimeField; use enum_dispatch::enum_dispatch; use rand::{prelude::StdRng, RngCore}; +use serde::{Deserialize, Serialize}; use std::any::TypeId; use strum::{EnumCount, IntoEnumIterator}; use strum_macros::{EnumCount as EnumCountMacro, EnumIter}; @@ -29,7 +30,7 @@ macro_rules! instruction_set { ($enum_name:ident, $($alias:ident: $struct:ty),+) => { #[allow(non_camel_case_types)] #[repr(u8)] - #[derive(Copy, Clone, Debug, EnumIter, EnumCountMacro)] + #[derive(Copy, Clone, Debug, EnumIter, EnumCountMacro, Serialize, Deserialize)] #[enum_dispatch(JoltInstruction)] pub enum $enum_name { $($alias($struct)),+ } impl JoltInstructionSet for $enum_name {} diff --git a/jolt-sdk/macros/src/lib.rs b/jolt-sdk/macros/src/lib.rs index 46ef10bc8..754fa21d9 100644 --- a/jolt-sdk/macros/src/lib.rs +++ b/jolt-sdk/macros/src/lib.rs @@ -138,14 +138,14 @@ impl MacroBuilder { quote! { #[cfg(not(feature = "guest"))] - pub fn #analyze_fn_name(#inputs) -> (usize, Vec<(jolt::RV32IM, usize)>) { + pub fn #analyze_fn_name(#inputs) -> jolt::host::analyze::ProgramSummary { #imports let mut program = Program::new(#guest_name); #set_mem_size #(#set_program_args;)* - program.trace_analyze() + program.trace_analyze::() } } }