From c1554b2229e99621d3aa7cf1b89f2f4af8a3788a Mon Sep 17 00:00:00 2001 From: James Parker Date: Fri, 27 Sep 2024 17:02:04 -0400 Subject: [PATCH] Make computation of Bytecode commitments streaming --- jolt-core/src/jolt/vm/bytecode.rs | 51 ++++++++++++++++++- jolt-core/src/jolt/vm/mod.rs | 15 ++++-- .../src/poly/commitment/commitment_scheme.rs | 3 +- jolt-core/src/poly/commitment/hyrax.rs | 1 + 4 files changed, 63 insertions(+), 7 deletions(-) diff --git a/jolt-core/src/jolt/vm/bytecode.rs b/jolt-core/src/jolt/vm/bytecode.rs index 9f5075723..c46a94c45 100644 --- a/jolt-core/src/jolt/vm/bytecode.rs +++ b/jolt-core/src/jolt/vm/bytecode.rs @@ -8,7 +8,7 @@ use std::{collections::HashMap, marker::PhantomData}; use crate::field::JoltField; use crate::jolt::instruction::JoltInstructionSet; -use crate::poly::commitment::commitment_scheme::{BatchType, CommitShape, CommitmentScheme}; +use crate::poly::commitment::commitment_scheme::{BatchType, CommitShape, CommitmentScheme, StreamingCommitmentScheme}; use crate::poly::eq_poly::EqPolynomial; use crate::utils::{ streaming::map_state, @@ -577,6 +577,55 @@ impl AppendToTranscript for BytecodeCommitment { } } +pub struct StreamingBytecodeCommitment { + a_read_write: C::State, + v_read_write: [C::State; 6], + t_read: C::State, +} + +impl StreamingBytecodeCommitment { + /// Initialize a streaming computation of a commitment. + pub fn initialize(size: usize, setup: &C::Setup, batch_type: &BatchType) -> Self { + let a_read_write = C::initialize(size, setup, batch_type); + let v_read_write = std::array::from_fn(|_| a_read_write.clone()); + let t_read = a_read_write.clone(); + + StreamingBytecodeCommitment { + a_read_write, + v_read_write, + t_read, + } + } + + /// Process one step to compute the commitment. + pub fn process(self, step: &BytecodePolynomialStep) -> Self { + let step_v_read_write = [ + step.v_read_write.address, + step.v_read_write.bitflags, + step.v_read_write.rd, + step.v_read_write.rs1, + step.v_read_write.rs2, + step.v_read_write.imm, + ]; + StreamingBytecodeCommitment { + a_read_write: C::process(self.a_read_write, step.a_read_write), + v_read_write: self.v_read_write.into_iter().zip(step_v_read_write) + .map(|(vrd, step)| C::process(vrd, step)).collect::>().try_into().unwrap(), + t_read: C::process(self.t_read, step.t_read), + } + } + + /// Return the trace commitments. + pub fn finalize(self) -> Vec { + [ + C::finalize(self.a_read_write), + C::finalize(self.t_read), + ].into_iter().chain( + self.v_read_write.into_iter().map(|vrw| C::finalize(vrw)) + ).collect() + } +} + impl StructuredCommitment for BytecodePolynomials where F: JoltField, diff --git a/jolt-core/src/jolt/vm/mod.rs b/jolt-core/src/jolt/vm/mod.rs index c54974a32..a4a3743af 100644 --- a/jolt-core/src/jolt/vm/mod.rs +++ b/jolt-core/src/jolt/vm/mod.rs @@ -19,7 +19,10 @@ use crate::jolt::{ }, subtable::JoltSubtableSet, vm::{ - bytecode::StreamingBytecodePolynomials, + bytecode::{ + StreamingBytecodeCommitment, + StreamingBytecodePolynomials, + }, timestamp_range_check::{ RangeCheckPolynomials, TimestampValidityProof, @@ -367,13 +370,13 @@ pub trait Jolt, const C: ); let streaming_bytecode_polynomials = StreamingBytecodePolynomials::::new(&preprocessing.bytecode, &mut trace2); - let initialized_commitment = PCS::initialize(streaming_bytecode_polynomials.length(), &preprocessing.generators, &BatchType::Big); + let initialized_commitment = StreamingBytecodeCommitment::initialize(streaming_bytecode_polynomials.length(), &preprocessing.generators, &BatchType::Big); // JP: `fold` likely isn't sufficient since we need to extract the internal state. let streaming_trace_commitments = streaming_bytecode_polynomials.fold(initialized_commitment, |state, step| { - PCS::process(state, step.a_read_write) + StreamingBytecodeCommitment::process(state, &step) }); - let a_read_write_commitment = PCS::finalize(streaming_trace_commitments); + let bytecode_commitments = StreamingBytecodeCommitment::finalize(streaming_trace_commitments); let jolt_polynomials = JoltPolynomials { bytecode: bytecode_polynomials, @@ -383,7 +386,9 @@ pub trait Jolt, const C: }; let mut jolt_commitments = jolt_polynomials.commit(&preprocessing.generators); - assert_eq!(a_read_write_commitment, jolt_commitments.bytecode.trace_commitments[0]); + + /// TODO: Temp, remove me XXX + assert_eq!(bytecode_commitments, jolt_commitments.bytecode.trace_commitments); let (witness_segments, r1cs_commitments, r1cs_builder) = Self::r1cs_setup( padded_trace_length, diff --git a/jolt-core/src/poly/commitment/commitment_scheme.rs b/jolt-core/src/poly/commitment/commitment_scheme.rs index 857a95efb..6d558bfe3 100644 --- a/jolt-core/src/poly/commitment/commitment_scheme.rs +++ b/jolt-core/src/poly/commitment/commitment_scheme.rs @@ -1,4 +1,5 @@ use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use std::fmt::Debug; use crate::{ field::JoltField, @@ -100,7 +101,7 @@ pub trait CommitmentScheme: Clone + Sync + Send + 'static { } pub trait StreamingCommitmentScheme: CommitmentScheme { - type State; + type State: Clone + Debug; fn initialize(size: usize, setup: &Self::Setup, batch_type: &BatchType) -> Self::State; fn process(state: Self::State, eval: Self::Field) -> Self::State; diff --git a/jolt-core/src/poly/commitment/hyrax.rs b/jolt-core/src/poly/commitment/hyrax.rs index ac17386d3..0587d64ed 100644 --- a/jolt-core/src/poly/commitment/hyrax.rs +++ b/jolt-core/src/poly/commitment/hyrax.rs @@ -148,6 +148,7 @@ impl> CommitmentScheme for HyraxSch } } +#[derive(Clone, Debug)] pub struct HyraxSchemeState { row_commitments: Vec, generators: Vec<::Affine>,