From d932595779234c2760c7202a12221bbe21c393ad Mon Sep 17 00:00:00 2001 From: sragss Date: Wed, 27 Mar 2024 09:58:22 -0700 Subject: [PATCH 01/10] serialize commitments --- jolt-core/src/benches/bench.rs | 10 ++++++++++ jolt-core/src/jolt/vm/bytecode.rs | 3 +++ jolt-core/src/jolt/vm/instruction_lookups.rs | 1 + jolt-core/src/jolt/vm/mod.rs | 3 +++ jolt-core/src/jolt/vm/read_write_memory.rs | 2 ++ jolt-core/src/poly/hyrax.rs | 5 +++-- jolt-core/src/poly/pedersen.rs | 3 ++- jolt-core/src/r1cs/snark.rs | 3 +++ jolt-core/src/subprotocols/concatenated_commitment.rs | 2 ++ 9 files changed, 29 insertions(+), 3 deletions(-) diff --git a/jolt-core/src/benches/bench.rs b/jolt-core/src/benches/bench.rs index cf2b0e9b8..4d317a285 100644 --- a/jolt-core/src/benches/bench.rs +++ b/jolt-core/src/benches/bench.rs @@ -6,6 +6,7 @@ use crate::jolt::vm::rv32i_vm::{RV32IJoltVM, C, M, RV32I}; use crate::jolt::vm::Jolt; use crate::poly::dense_mlpoly::bench::{init_commit_bench, run_commit_bench}; use ark_bn254::{Fr, G1Projective}; +use ark_serialize::CanonicalSerialize; use common::rv_trace::{ELFInstruction, JoltDevice}; use criterion::black_box; use merlin::Transcript; @@ -244,6 +245,15 @@ fn prove_example( circuit_flags, preprocessing.clone(), ); + use std::fs::File; + use std::io::Write; + let mut file = File::create("temp_file").unwrap(); + jolt_commitments.serialize_compressed(&mut file).unwrap(); + let file_size_bytes = file.metadata().unwrap().len(); + let file_size_kb = file_size_bytes / 1024; + let file_size_mb = file_size_kb / 1024; + let file_size_gb = file_size_mb / 1024; + println!("Serialized size: {} bytes ({} KB, {} MB, {} GB)", file_size_bytes, file_size_kb, file_size_mb, file_size_gb); let verification_result = RV32IJoltVM::verify(preprocessing, jolt_proof, jolt_commitments); assert!( verification_result.is_ok(), diff --git a/jolt-core/src/jolt/vm/bytecode.rs b/jolt-core/src/jolt/vm/bytecode.rs index 892255f08..76871de1a 100644 --- a/jolt-core/src/jolt/vm/bytecode.rs +++ b/jolt-core/src/jolt/vm/bytecode.rs @@ -16,6 +16,7 @@ use crate::poly::pedersen::PedersenGenerators; use common::constants::{BYTES_PER_INSTRUCTION, NUM_R1CS_POLYS, RAM_START_ADDRESS, REGISTER_COUNT}; use common::rv_trace::ELFInstruction; use common::to_ram_address; +use ark_serialize::{CanonicalSerialize, CanonicalDeserialize}; use rayon::prelude::*; @@ -329,6 +330,8 @@ impl> BytecodePolynomials { } } + +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct BytecodeCommitment { pub read_write_generators: HyraxGenerators, pub read_write_commitments: Vec>, diff --git a/jolt-core/src/jolt/vm/instruction_lookups.rs b/jolt-core/src/jolt/vm/instruction_lookups.rs index 40c0a14e2..4746e6a85 100644 --- a/jolt-core/src/jolt/vm/instruction_lookups.rs +++ b/jolt-core/src/jolt/vm/instruction_lookups.rs @@ -89,6 +89,7 @@ pub struct BatchedInstructionPolynomials { } /// Commitments to BatchedInstructionPolynomials. +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct InstructionCommitment { pub read_write_generators: HyraxGenerators, /// Commitments to dim_i and read_cts_i polynomials. diff --git a/jolt-core/src/jolt/vm/mod.rs b/jolt-core/src/jolt/vm/mod.rs index f54aaeab5..d08f52f6c 100644 --- a/jolt-core/src/jolt/vm/mod.rs +++ b/jolt-core/src/jolt/vm/mod.rs @@ -1,11 +1,13 @@ use ark_ec::CurveGroup; use ark_ff::PrimeField; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use ark_std::log2; use common::constants::NUM_R1CS_POLYS; use common::rv_trace::JoltDevice; use itertools::max; use merlin::Transcript; use rayon::prelude::*; +use serde::Serialize; use crate::jolt::{ instruction::JoltInstruction, subtable::JoltSubtableSet, @@ -72,6 +74,7 @@ where pub instruction_lookups: InstructionPolynomials, } +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct JoltCommitments { pub bytecode: BytecodeCommitment, pub read_write_memory: MemoryCommitment, diff --git a/jolt-core/src/jolt/vm/read_write_memory.rs b/jolt-core/src/jolt/vm/read_write_memory.rs index 199fada94..27ad450a4 100644 --- a/jolt-core/src/jolt/vm/read_write_memory.rs +++ b/jolt-core/src/jolt/vm/read_write_memory.rs @@ -32,6 +32,7 @@ use common::constants::{ }; use common::rv_trace::{ELFInstruction, JoltDevice, MemoryOp, RV32IM}; use common::to_ram_address; +use ark_serialize::{CanonicalSerialize, CanonicalDeserialize}; use super::timestamp_range_check::TimestampValidityProof; @@ -449,6 +450,7 @@ pub struct BatchedMemoryPolynomials { batched_init_final: DensePolynomial, } +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct MemoryCommitment { /// Generators for a_read_write, v_read, v_write pub read_write_generators: HyraxGenerators, diff --git a/jolt-core/src/poly/hyrax.rs b/jolt-core/src/poly/hyrax.rs index 6e1ac9d2b..9fb4a4c0b 100644 --- a/jolt-core/src/poly/hyrax.rs +++ b/jolt-core/src/poly/hyrax.rs @@ -12,6 +12,7 @@ use merlin::Transcript; use num_integer::Roots; use rayon::prelude::*; use tracing::trace_span; +use ark_serialize::{CanonicalSerialize, CanonicalDeserialize}; #[cfg(feature = "ark-msm")] use ark_ec::VariableBaseMSM; @@ -31,7 +32,7 @@ pub fn matrix_dimensions(num_vars: usize, matrix_aspect_ratio: usize) -> (usize, (col_size, row_size) } -#[derive(Clone)] +#[derive(Clone, ark_serialize::CanonicalSerialize, ark_serialize::CanonicalDeserialize)] pub struct HyraxGenerators { pub gens: PedersenGenerators, } @@ -45,7 +46,7 @@ impl HyraxGenerators { } } -#[derive(Debug, Clone)] +#[derive(Clone, Debug, CanonicalSerialize, CanonicalDeserialize)] pub struct HyraxCommitment { row_commitments: Vec, } diff --git a/jolt-core/src/poly/pedersen.rs b/jolt-core/src/poly/pedersen.rs index b0225a1aa..73e84f924 100644 --- a/jolt-core/src/poly/pedersen.rs +++ b/jolt-core/src/poly/pedersen.rs @@ -4,6 +4,7 @@ use digest::{ExtendableOutput, Input}; use rand_chacha::ChaCha20Rng; use sha3::Shake256; use std::io::Read; +use ark_serialize::{CanonicalSerialize, CanonicalDeserialize}; #[cfg(feature = "ark-msm")] use ark_ec::VariableBaseMSM; @@ -11,7 +12,7 @@ use ark_ec::VariableBaseMSM; #[cfg(not(feature = "ark-msm"))] use crate::msm::VariableBaseMSM; -#[derive(Clone)] +#[derive(Clone, CanonicalSerialize, CanonicalDeserialize)] pub struct PedersenGenerators { pub generators: Vec, } diff --git a/jolt-core/src/r1cs/snark.rs b/jolt-core/src/r1cs/snark.rs index 4a70ee230..b8ea1efab 100644 --- a/jolt-core/src/r1cs/snark.rs +++ b/jolt-core/src/r1cs/snark.rs @@ -8,6 +8,7 @@ use common::constants::{NUM_R1CS_POLYS, RAM_START_ADDRESS}; use ark_ff::PrimeField; use merlin::Transcript; use rayon::prelude::*; +use ark_serialize::{CanonicalSerialize, CanonicalDeserialize}; /// Reorder and drop first element [[a1, b1, c1], [a2, b2, c2]] => [[a2], [b2], [c2]] #[tracing::instrument(skip_all)] @@ -222,12 +223,14 @@ impl R1CSInputs { } /// Derived elements exclusive to the R1CS circuit. +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct R1CSInternalCommitments { io: Vec>, aux: Vec>, } /// Commitments unique to R1CS. +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct R1CSUniqueCommitments { internal_commitments: R1CSInternalCommitments, diff --git a/jolt-core/src/subprotocols/concatenated_commitment.rs b/jolt-core/src/subprotocols/concatenated_commitment.rs index 56ceaf932..9e6a33aae 100644 --- a/jolt-core/src/subprotocols/concatenated_commitment.rs +++ b/jolt-core/src/subprotocols/concatenated_commitment.rs @@ -13,6 +13,8 @@ use crate::{ }, }; + +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct ConcatenatedPolynomialCommitment { pub generators: HyraxGenerators<1, G>, pub joint_commitment: HyraxCommitment<1, G>, From c169dac7a30ba38d1f7df2b6e21748e7b7b8a0ec Mon Sep 17 00:00:00 2001 From: sragss Date: Wed, 27 Mar 2024 10:48:59 -0700 Subject: [PATCH 02/10] remaining serialization impls --- common/src/rv_trace.rs | 3 +- jolt-core/src/benches/bench.rs | 26 +++-- jolt-core/src/jolt/vm/bytecode.rs | 2 + jolt-core/src/jolt/vm/instruction_lookups.rs | 101 +++++++++++++++++- jolt-core/src/jolt/vm/mod.rs | 60 +++++++++++ jolt-core/src/jolt/vm/read_write_memory.rs | 4 + .../src/jolt/vm/timestamp_range_check.rs | 4 + jolt-core/src/lasso/memory_checking.rs | 83 ++++++++++++++ jolt-core/src/lasso/surge.rs | 49 ++++++++- jolt-core/src/poly/structured_poly.rs | 7 +- jolt-core/src/r1cs/r1cs_shape.rs | 3 +- jolt-core/src/r1cs/snark.rs | 1 + jolt-core/src/r1cs/spartan.rs | 4 + 13 files changed, 328 insertions(+), 19 deletions(-) diff --git a/common/src/rv_trace.rs b/common/src/rv_trace.rs index 421b11122..1e44b582d 100644 --- a/common/src/rv_trace.rs +++ b/common/src/rv_trace.rs @@ -1,4 +1,5 @@ use crate::constants::{MEMORY_OPS_PER_INSTRUCTION, PANIC_ADDRESS, INPUT_START_ADDRESS, OUTPUT_START_ADDRESS}; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use serde::{Deserialize, Serialize}; use strum_macros::FromRepr; @@ -646,7 +647,7 @@ impl RV32IM { /// all reads from the reserved memory address space for program inputs and all writes /// to the reserved memory address space for program outputs. /// The inputs and outputs are part of the public inputs to the proof. -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, CanonicalSerialize, CanonicalDeserialize)] pub struct JoltDevice { pub inputs: Vec, pub outputs: Vec, diff --git a/jolt-core/src/benches/bench.rs b/jolt-core/src/benches/bench.rs index 4d317a285..f1ec634e4 100644 --- a/jolt-core/src/benches/bench.rs +++ b/jolt-core/src/benches/bench.rs @@ -219,6 +219,17 @@ fn sha3() -> Vec<(tracing::Span, Box)> { prove_example("sha3-guest", &vec![5u8; 2048]) } +fn serialize_and_print_size(name: &str, item: &impl ark_serialize::CanonicalSerialize) { + use std::fs::File; + let mut file = File::create("temp_file").unwrap(); + item.serialize_compressed(&mut file).unwrap(); + let file_size_bytes = file.metadata().unwrap().len(); + let file_size_kb = file_size_bytes as f64 / 1024.0; + let file_size_mb = file_size_kb / 1024.0; + let file_size_gb = file_size_mb / 1024.0; + println!("{} serialized size: {:.3} bytes ({:.3} KB, {:.3} MB, {:.3} GB)", name, file_size_bytes as f64, file_size_kb, file_size_mb, file_size_gb); +} + fn prove_example( example_name: &str, input: &T, @@ -245,15 +256,10 @@ fn prove_example( circuit_flags, preprocessing.clone(), ); - use std::fs::File; - use std::io::Write; - let mut file = File::create("temp_file").unwrap(); - jolt_commitments.serialize_compressed(&mut file).unwrap(); - let file_size_bytes = file.metadata().unwrap().len(); - let file_size_kb = file_size_bytes / 1024; - let file_size_mb = file_size_kb / 1024; - let file_size_gb = file_size_mb / 1024; - println!("Serialized size: {} bytes ({} KB, {} MB, {} GB)", file_size_bytes, file_size_kb, file_size_mb, file_size_gb); + + serialize_and_print_size("jolt_commitments", &jolt_commitments); + serialize_and_print_size("jolt_proof", &jolt_proof); + let verification_result = RV32IJoltVM::verify(preprocessing, jolt_proof, jolt_commitments); assert!( verification_result.is_ok(), @@ -268,4 +274,4 @@ fn prove_example( )); tasks -} +} \ No newline at end of file diff --git a/jolt-core/src/jolt/vm/bytecode.rs b/jolt-core/src/jolt/vm/bytecode.rs index 76871de1a..076ddbc4f 100644 --- a/jolt-core/src/jolt/vm/bytecode.rs +++ b/jolt-core/src/jolt/vm/bytecode.rs @@ -574,6 +574,7 @@ where } } +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct BytecodeReadWriteOpenings where F: PrimeField, @@ -662,6 +663,7 @@ where } } +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct BytecodeInitFinalOpenings where F: PrimeField, diff --git a/jolt-core/src/jolt/vm/instruction_lookups.rs b/jolt-core/src/jolt/vm/instruction_lookups.rs index 4746e6a85..74bf84a80 100644 --- a/jolt-core/src/jolt/vm/instruction_lookups.rs +++ b/jolt-core/src/jolt/vm/instruction_lookups.rs @@ -219,6 +219,7 @@ where } } +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct InstructionReadWriteOpenings where F: PrimeField, @@ -349,6 +350,54 @@ where v_init_final: Option>, } +impl ark_serialize::CanonicalSerialize for InstructionFinalOpenings +where + F: PrimeField, + Subtables: JoltSubtableSet, +{ + fn serialize_with_mode(&self, mut writer: W, mode: ark_serialize::Compress) -> Result<(), ark_serialize::SerializationError> { + self.final_openings.serialize_with_mode(&mut writer, mode)?; + self.a_init_final.serialize_with_mode(&mut writer, mode)?; + self.v_init_final.serialize_with_mode(&mut writer, mode)?; + Ok(()) + } + + fn serialized_size(&self, mode: ark_serialize::Compress) -> usize { + self.final_openings.serialized_size(mode) + self.a_init_final.serialized_size(mode) + self.v_init_final.serialized_size(mode) + } +} + +impl ark_serialize::CanonicalDeserialize for InstructionFinalOpenings +where + F: PrimeField, + Subtables: JoltSubtableSet, +{ + fn deserialize_with_mode(mut reader: R, compress: ark_serialize::Compress, validate: ark_serialize::Validate) -> Result { + let final_openings = Vec::::deserialize_with_mode(&mut reader, compress, validate)?; + let a_init_final = Option::::deserialize_with_mode(&mut reader, compress, validate)?; + let v_init_final = Option::>::deserialize_with_mode(&mut reader, compress, validate)?; + Ok(Self { + _subtables: PhantomData, + final_openings, + a_init_final, + v_init_final, + }) + } +} + +impl ark_serialize::Valid for InstructionFinalOpenings +where + F: PrimeField, + Subtables: JoltSubtableSet, +{ + fn check(&self) -> Result<(), ark_serialize::SerializationError> { + self.final_openings.check()?; + self.a_init_final.check()?; + self.v_init_final.check()?; + Ok(()) + } +} + impl StructuredOpeningProof> for InstructionFinalOpenings where @@ -757,10 +806,7 @@ where InstructionSet: JoltInstructionSet, { _instructions: PhantomData, - /// "Primary" sumcheck, i.e. proving \sum_x \tilde{eq}(r, x) * \sum_i flag_i(x) * g_i(E_1(x), ..., E_\alpha(x)) primary_sumcheck: PrimarySumcheck, - - /// Memory checking proof, showing that E_i polynomials are well-formed. memory_checking: MemoryCheckingProof< G, InstructionPolynomials, @@ -769,6 +815,55 @@ where >, } +impl CanonicalSerialize for InstructionLookupsProof +where + F: PrimeField, + G: CurveGroup, + Subtables: JoltSubtableSet, + InstructionSet: JoltInstructionSet, +{ + fn serialize_with_mode(&self, mut writer: W, mode: ark_serialize::Compress) -> Result<(), ark_serialize::SerializationError> { + self.primary_sumcheck.serialize_with_mode(&mut writer, mode)?; + self.memory_checking.serialize_with_mode(&mut writer, mode)?; + Ok(()) + } + + fn serialized_size(&self, mode: ark_serialize::Compress) -> usize { + self.primary_sumcheck.serialized_size(mode) + self.memory_checking.serialized_size(mode) + } +} + +impl CanonicalDeserialize for InstructionLookupsProof +where + F: PrimeField, + G: CurveGroup, + Subtables: JoltSubtableSet, + InstructionSet: JoltInstructionSet, +{ + fn deserialize_with_mode(mut reader: R, compress: ark_serialize::Compress, validate: ark_serialize::Validate) -> Result { + let primary_sumcheck = PrimarySumcheck::deserialize_with_mode(&mut reader, compress, validate)?; + let memory_checking = MemoryCheckingProof::deserialize_with_mode(&mut reader, compress, validate)?; + Ok(Self { _instructions: PhantomData, primary_sumcheck, memory_checking }) + } +} + +impl ark_serialize::Valid for InstructionLookupsProof +where + F: PrimeField, + G: CurveGroup, + Subtables: JoltSubtableSet, + InstructionSet: JoltInstructionSet, +{ + fn check(&self) -> Result<(), ark_serialize::SerializationError> { + self.primary_sumcheck.check()?; + self.memory_checking.check()?; + Ok(()) + } +} + + + +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct PrimarySumcheck> { sumcheck_proof: SumcheckInstanceProof, num_rounds: usize, diff --git a/jolt-core/src/jolt/vm/mod.rs b/jolt-core/src/jolt/vm/mod.rs index d08f52f6c..da2473ef0 100644 --- a/jolt-core/src/jolt/vm/mod.rs +++ b/jolt-core/src/jolt/vm/mod.rs @@ -64,6 +64,66 @@ where r1cs: R1CSProof, } +impl ark_serialize::CanonicalSerialize for JoltProof +where + F: PrimeField, + G: CurveGroup, + InstructionSet: JoltInstructionSet, + Subtables: JoltSubtableSet, +{ + fn serialize_with_mode(&self, mut writer: W, mode: ark_serialize::Compress) -> Result<(), ark_serialize::SerializationError> { + self.bytecode.serialize_with_mode(&mut writer, mode)?; + self.read_write_memory.serialize_with_mode(&mut writer, mode)?; + self.instruction_lookups.serialize_with_mode(&mut writer, mode)?; + self.r1cs.serialize_with_mode(&mut writer, mode)?; + Ok(()) + } + + fn serialized_size(&self, mode: ark_serialize::Compress) -> usize { + self.bytecode.serialized_size(mode) + + self.read_write_memory.serialized_size(mode) + + self.instruction_lookups.serialized_size(mode) + + self.r1cs.serialized_size(mode) + } +} + +impl ark_serialize::CanonicalDeserialize for JoltProof +where + F: PrimeField, + G: CurveGroup, + InstructionSet: JoltInstructionSet, + Subtables: JoltSubtableSet, +{ + fn deserialize_with_mode(mut reader: R, compress: ark_serialize::Compress, validate: ark_serialize::Validate) -> Result { + let bytecode = BytecodeProof::deserialize_with_mode(&mut reader, compress, validate)?; + let read_write_memory = ReadWriteMemoryProof::deserialize_with_mode(&mut reader, compress, validate)?; + let instruction_lookups = InstructionLookupsProof::deserialize_with_mode(&mut reader, compress, validate)?; + let r1cs = R1CSProof::deserialize_with_mode(&mut reader, compress, validate)?; + Ok(Self { + bytecode, + read_write_memory, + instruction_lookups, + r1cs, + }) + } +} + +impl ark_serialize::Valid for JoltProof +where + F: PrimeField, + G: CurveGroup, + InstructionSet: JoltInstructionSet, + Subtables: JoltSubtableSet, +{ + fn check(&self) -> Result<(), ark_serialize::SerializationError> { + self.bytecode.check()?; + self.read_write_memory.check()?; + self.instruction_lookups.check()?; + self.r1cs.check()?; + Ok(()) + } +} + pub struct JoltPolynomials where F: PrimeField, diff --git a/jolt-core/src/jolt/vm/read_write_memory.rs b/jolt-core/src/jolt/vm/read_write_memory.rs index 27ad450a4..221f1c352 100644 --- a/jolt-core/src/jolt/vm/read_write_memory.rs +++ b/jolt-core/src/jolt/vm/read_write_memory.rs @@ -120,6 +120,7 @@ pub fn random_memory_trace( memory_trace } +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct ReadWriteMemoryProof where F: PrimeField, @@ -516,6 +517,7 @@ where } } +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct MemoryReadWriteOpenings where F: PrimeField, @@ -533,6 +535,7 @@ where pub t_write_opening: [F; MEMORY_OPS_PER_INSTRUCTION], } +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct MemoryReadWriteOpeningProof { a_v_opening_proof: BatchedHyraxOpeningProof, t_opening_proof: ConcatenatedPolynomialOpeningProof, @@ -651,6 +654,7 @@ where } } +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct MemoryInitFinalOpenings where F: PrimeField, diff --git a/jolt-core/src/jolt/vm/timestamp_range_check.rs b/jolt-core/src/jolt/vm/timestamp_range_check.rs index e27b808fa..eb32c2228 100644 --- a/jolt-core/src/jolt/vm/timestamp_range_check.rs +++ b/jolt-core/src/jolt/vm/timestamp_range_check.rs @@ -1,5 +1,6 @@ use ark_ec::CurveGroup; use ark_ff::PrimeField; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use common::constants::MEMORY_OPS_PER_INSTRUCTION; use itertools::interleave; use merlin::Transcript; @@ -201,6 +202,7 @@ where } } +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct RangeCheckOpenings where F: PrimeField, @@ -215,6 +217,7 @@ where identity_poly_opening: Option, } +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct RangeCheckOpeningProof where G: CurveGroup, @@ -589,6 +592,7 @@ where } } +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct TimestampValidityProof where F: PrimeField, diff --git a/jolt-core/src/lasso/memory_checking.rs b/jolt-core/src/lasso/memory_checking.rs index cb86d9967..6f3567955 100644 --- a/jolt-core/src/lasso/memory_checking.rs +++ b/jolt-core/src/lasso/memory_checking.rs @@ -13,12 +13,14 @@ use crate::utils::transcript::ProofTranscript; use ark_ec::CurveGroup; use ark_ff::PrimeField; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use itertools::interleave; use merlin::Transcript; use rayon::iter::{IntoParallelIterator, IntoParallelRefIterator, ParallelIterator}; use std::iter::zip; use std::marker::PhantomData; +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct MultisetHashes { /// Multiset hash of "read" tuples pub read_hashes: Vec, @@ -82,6 +84,87 @@ where pub init_final_opening_proof: InitFinalOpenings::Proof, } +impl CanonicalSerialize for MemoryCheckingProof +where + G: CurveGroup, + Polynomials: BatchablePolynomials + ?Sized, + ReadWriteOpenings: StructuredOpeningProof, + InitFinalOpenings: StructuredOpeningProof, +{ + fn serialize_with_mode(&self, mut writer: W, mode: ark_serialize::Compress) -> Result<(), ark_serialize::SerializationError> { + // self._polys.serialize_with_mode(&mut writer, mode)?; + self.multiset_hashes.serialize_with_mode(&mut writer, mode)?; + self.read_write_grand_product.serialize_with_mode(&mut writer, mode)?; + self.init_final_grand_product.serialize_with_mode(&mut writer, mode)?; + self.read_write_openings.serialize_with_mode(&mut writer, mode)?; + self.read_write_opening_proof.serialize_with_mode(&mut writer, mode)?; + self.init_final_openings.serialize_with_mode(&mut writer, mode)?; + self.init_final_opening_proof.serialize_with_mode(&mut writer, mode)?; + Ok(()) + } + + fn serialized_size(&self, mode: ark_serialize::Compress) -> usize { + // self._polys.serialized_size(mode) + + self.multiset_hashes.serialized_size(mode) + + self.read_write_grand_product.serialized_size(mode) + + self.init_final_grand_product.serialized_size(mode) + + self.read_write_openings.serialized_size(mode) + + self.read_write_opening_proof.serialized_size(mode) + + self.init_final_openings.serialized_size(mode) + + self.init_final_opening_proof.serialized_size(mode) + } +} + +impl CanonicalDeserialize for MemoryCheckingProof +where + G: CurveGroup, + Polynomials: BatchablePolynomials + ?Sized, + ReadWriteOpenings: StructuredOpeningProof, + InitFinalOpenings: StructuredOpeningProof, +{ + fn deserialize_with_mode(mut reader: R, compress: ark_serialize::Compress, validate: ark_serialize::Validate) -> Result { + // let _polys = PhantomData::deserialize_with_mode(&mut reader, compress, validate)?; + let multiset_hashes = MultisetHashes::deserialize_with_mode(&mut reader, compress, validate)?; + let read_write_grand_product = BatchedGrandProductArgument::deserialize_with_mode(&mut reader, compress, validate)?; + let init_final_grand_product = BatchedGrandProductArgument::deserialize_with_mode(&mut reader, compress, validate)?; + let read_write_openings = ReadWriteOpenings::deserialize_with_mode(&mut reader, compress, validate)?; + let read_write_opening_proof = ReadWriteOpenings::Proof::deserialize_with_mode(&mut reader, compress, validate)?; + let init_final_openings = InitFinalOpenings::deserialize_with_mode(&mut reader, compress, validate)?; + let init_final_opening_proof = InitFinalOpenings::Proof::deserialize_with_mode(&mut reader, compress, validate)?; + Ok(Self { + _polys: PhantomData, + multiset_hashes, + read_write_grand_product, + init_final_grand_product, + read_write_openings, + read_write_opening_proof, + init_final_openings, + init_final_opening_proof, + }) + } +} + +impl ark_serialize::Valid for MemoryCheckingProof +where + G: CurveGroup, + Polynomials: BatchablePolynomials + ?Sized, + ReadWriteOpenings: StructuredOpeningProof, + InitFinalOpenings: StructuredOpeningProof, +{ + fn check(&self) -> Result<(), ark_serialize::SerializationError> { + // self._polys.check()?; + self.multiset_hashes.check()?; + self.read_write_grand_product.check()?; + self.init_final_grand_product.check()?; + self.read_write_openings.check()?; + self.read_write_opening_proof.check()?; + self.init_final_openings.check()?; + self.init_final_opening_proof.check()?; + Ok(()) + } +} + + // Empty struct to represent that no preprocessing data is used. pub struct NoPreprocessing; diff --git a/jolt-core/src/lasso/surge.rs b/jolt-core/src/lasso/surge.rs index a29ad8fa5..29278f168 100644 --- a/jolt-core/src/lasso/surge.rs +++ b/jolt-core/src/lasso/surge.rs @@ -1,5 +1,6 @@ use ark_ec::CurveGroup; use ark_ff::PrimeField; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use merlin::Transcript; use rayon::iter::{IntoParallelIterator, IntoParallelRefIterator, ParallelIterator}; use std::marker::{PhantomData, Sync}; @@ -40,6 +41,7 @@ pub struct BatchedSurgePolynomials { pub batched_E: DensePolynomial, } +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct SurgeCommitment { pub dim_read_commitment: ConcatenatedPolynomialCommitment, pub final_commitment: ConcatenatedPolynomialCommitment, @@ -137,6 +139,7 @@ impl> StructuredOpeningProof where F: PrimeField, @@ -146,6 +149,7 @@ where E_poly_openings: Vec, // NUM_MEMORIES-sized } +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct SurgeReadWriteOpeningProof where F: PrimeField, @@ -241,7 +245,7 @@ where pub struct SurgeFinalOpenings where F: PrimeField, - Instruction: JoltInstruction + Default, + Instruction: JoltInstruction + Default + Sync, { _instruction: PhantomData, final_openings: Vec, // C-sized @@ -249,6 +253,49 @@ where v_init_final: Option>, // Computed by verifier } +impl CanonicalSerialize for SurgeFinalOpenings +where + F: PrimeField + CanonicalSerialize, + Instruction: JoltInstruction + Default + Sync, +{ + fn serialize_with_mode(&self, mut writer: W, mode: ark_serialize::Compress) -> Result<(), ark_serialize::SerializationError> { + self.final_openings.serialize_with_mode(&mut writer, mode)?; + self.a_init_final.serialize_with_mode(&mut writer, mode)?; + self.v_init_final.serialize_with_mode(&mut writer, mode)?; + Ok(()) + } + + fn serialized_size(&self, mode: ark_serialize::Compress) -> usize { + self.final_openings.serialized_size(mode) + self.a_init_final.serialized_size(mode) + self.v_init_final.serialized_size(mode) + } +} + +impl CanonicalDeserialize for SurgeFinalOpenings +where + F: PrimeField + CanonicalDeserialize, + Instruction: JoltInstruction + Default + Sync, +{ + fn deserialize_with_mode(mut reader: R, compress: ark_serialize::Compress, validate: ark_serialize::Validate) -> Result { + let final_openings = Vec::::deserialize_with_mode(&mut reader, compress, validate)?; + let a_init_final = Option::::deserialize_with_mode(&mut reader, compress, validate)?; + let v_init_final = Option::>::deserialize_with_mode(&mut reader, compress, validate)?; + Ok(Self { _instruction: PhantomData, final_openings, a_init_final, v_init_final }) + } +} + +impl ark_serialize::Valid for SurgeFinalOpenings +where + F: PrimeField + ark_serialize::Valid, + Instruction: JoltInstruction + Default + Sync, +{ + fn check(&self) -> Result<(), ark_serialize::SerializationError> { + self.final_openings.check()?; + self.a_init_final.check()?; + self.v_init_final.check()?; + Ok(()) + } +} + impl StructuredOpeningProof> for SurgeFinalOpenings where diff --git a/jolt-core/src/poly/structured_poly.rs b/jolt-core/src/poly/structured_poly.rs index 62d7832d0..7e8710cfa 100644 --- a/jolt-core/src/poly/structured_poly.rs +++ b/jolt-core/src/poly/structured_poly.rs @@ -1,5 +1,6 @@ use ark_ec::CurveGroup; use ark_ff::PrimeField; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use merlin::Transcript; use super::pedersen::PedersenGenerators; @@ -12,7 +13,7 @@ use crate::{ /// Encapsulates the pattern of a collection of related polynomials (e.g. those used to /// prove instruction lookups in Jolt) that can be "batched" for more efficient /// commitments/openings. -pub trait BatchablePolynomials { +pub trait BatchablePolynomials: Sync { /// The batched form of these polynomials. type BatchedPolynomials; /// The batched commitment to these polynomials. @@ -33,14 +34,14 @@ pub trait BatchablePolynomials { /// Note that there may be a one-to-many mapping from `BatchablePolynomials` to `StructuredOpeningProof`: /// different subset of the same polynomials may be opened at different points, resulting in /// different opening proofs. -pub trait StructuredOpeningProof +pub trait StructuredOpeningProof: Sync + CanonicalSerialize + CanonicalDeserialize where F: PrimeField, G: CurveGroup, Polynomials: BatchablePolynomials + ?Sized, { type Preprocessing = NoPreprocessing; - type Proof = ConcatenatedPolynomialOpeningProof; + type Proof: Sync + CanonicalSerialize + CanonicalDeserialize = ConcatenatedPolynomialOpeningProof; /// Evaluates each fo the given `polynomials` at the given `opening_point`. fn open(polynomials: &Polynomials, opening_point: &Vec) -> Self; diff --git a/jolt-core/src/r1cs/r1cs_shape.rs b/jolt-core/src/r1cs/r1cs_shape.rs index 765faa447..d69c297f8 100644 --- a/jolt-core/src/r1cs/r1cs_shape.rs +++ b/jolt-core/src/r1cs/r1cs_shape.rs @@ -1,6 +1,7 @@ use std::cmp::max; use ark_ff::PrimeField; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use rayon::prelude::*; use crate::utils::mul_0_1_optimized; @@ -8,7 +9,7 @@ use crate::utils::mul_0_1_optimized; use super::spartan::{IndexablePoly, SpartanError}; /// A type that holds the shape of the R1CS matrices -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq, CanonicalSerialize, CanonicalDeserialize)] pub struct R1CSShape { pub(crate) num_cons: usize, pub(crate) num_vars: usize, diff --git a/jolt-core/src/r1cs/snark.rs b/jolt-core/src/r1cs/snark.rs index b8ea1efab..f578c5e4d 100644 --- a/jolt-core/src/r1cs/snark.rs +++ b/jolt-core/src/r1cs/snark.rs @@ -277,6 +277,7 @@ impl R1CSUniqueCommitments { } } +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct R1CSProof> { pub key: UniformSpartanKey, proof: UniformSpartanProof, diff --git a/jolt-core/src/r1cs/spartan.rs b/jolt-core/src/r1cs/spartan.rs index e78920824..d8fea2338 100644 --- a/jolt-core/src/r1cs/spartan.rs +++ b/jolt-core/src/r1cs/spartan.rs @@ -5,6 +5,8 @@ use crate::utils::transcript::AppendToTranscript; use crate::utils::transcript::ProofTranscript; use ark_ec::CurveGroup; use ark_ff::PrimeField; +use ark_serialize::CanonicalDeserialize; +use ark_serialize::CanonicalSerialize; use merlin::Transcript; use rayon::prelude::*; use thiserror::Error; @@ -20,6 +22,7 @@ use crate::{ }; use common::constants::NUM_R1CS_POLYS; +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct UniformSpartanKey { shape_single_step: R1CSShape, // Single step shape num_cons_total: usize, // Number of constraints @@ -144,6 +147,7 @@ impl IndexablePoly for SegmentedPaddedWitness { /// A succinct proof of knowledge of a witness to a relaxed R1CS instance /// The proof is produced using Spartan's combination of the sum-check and /// the commitment to a vector viewed as a polynomial commitment +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct UniformSpartanProof> { outer_sumcheck_proof: SumcheckInstanceProof, outer_sumcheck_claims: (F, F, F), From 35f929e93ca41d7b9a8501e938884b90b9a27559 Mon Sep 17 00:00:00 2001 From: sragss Date: Wed, 27 Mar 2024 10:57:10 -0700 Subject: [PATCH 03/10] rm custom PhantomData serialization derivation from InstructionFinalOpenings --- jolt-core/src/jolt/subtable/mod.rs | 2 +- jolt-core/src/jolt/vm/instruction_lookups.rs | 49 +------------------- 2 files changed, 2 insertions(+), 49 deletions(-) diff --git a/jolt-core/src/jolt/subtable/mod.rs b/jolt-core/src/jolt/subtable/mod.rs index c8d7a4e3c..1fffc7ce0 100644 --- a/jolt-core/src/jolt/subtable/mod.rs +++ b/jolt-core/src/jolt/subtable/mod.rs @@ -22,7 +22,7 @@ pub trait LassoSubtable: 'static + Sync { pub type SubtableId = TypeId; pub trait JoltSubtableSet: - LassoSubtable + IntoEnumIterator + EnumCount + From + Into + LassoSubtable + IntoEnumIterator + EnumCount + From + Into + Send + Sync { fn enum_index(subtable: Box>) -> usize { Self::from(subtable.subtable_id()).into() diff --git a/jolt-core/src/jolt/vm/instruction_lookups.rs b/jolt-core/src/jolt/vm/instruction_lookups.rs index 74bf84a80..b3862f02d 100644 --- a/jolt-core/src/jolt/vm/instruction_lookups.rs +++ b/jolt-core/src/jolt/vm/instruction_lookups.rs @@ -336,6 +336,7 @@ where } } +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct InstructionFinalOpenings where F: PrimeField, @@ -350,54 +351,6 @@ where v_init_final: Option>, } -impl ark_serialize::CanonicalSerialize for InstructionFinalOpenings -where - F: PrimeField, - Subtables: JoltSubtableSet, -{ - fn serialize_with_mode(&self, mut writer: W, mode: ark_serialize::Compress) -> Result<(), ark_serialize::SerializationError> { - self.final_openings.serialize_with_mode(&mut writer, mode)?; - self.a_init_final.serialize_with_mode(&mut writer, mode)?; - self.v_init_final.serialize_with_mode(&mut writer, mode)?; - Ok(()) - } - - fn serialized_size(&self, mode: ark_serialize::Compress) -> usize { - self.final_openings.serialized_size(mode) + self.a_init_final.serialized_size(mode) + self.v_init_final.serialized_size(mode) - } -} - -impl ark_serialize::CanonicalDeserialize for InstructionFinalOpenings -where - F: PrimeField, - Subtables: JoltSubtableSet, -{ - fn deserialize_with_mode(mut reader: R, compress: ark_serialize::Compress, validate: ark_serialize::Validate) -> Result { - let final_openings = Vec::::deserialize_with_mode(&mut reader, compress, validate)?; - let a_init_final = Option::::deserialize_with_mode(&mut reader, compress, validate)?; - let v_init_final = Option::>::deserialize_with_mode(&mut reader, compress, validate)?; - Ok(Self { - _subtables: PhantomData, - final_openings, - a_init_final, - v_init_final, - }) - } -} - -impl ark_serialize::Valid for InstructionFinalOpenings -where - F: PrimeField, - Subtables: JoltSubtableSet, -{ - fn check(&self) -> Result<(), ark_serialize::SerializationError> { - self.final_openings.check()?; - self.a_init_final.check()?; - self.v_init_final.check()?; - Ok(()) - } -} - impl StructuredOpeningProof> for InstructionFinalOpenings where From 657ee9c607dd2e1d55bc4320c7be9c6d02f1495a Mon Sep 17 00:00:00 2001 From: sragss Date: Wed, 27 Mar 2024 10:58:24 -0700 Subject: [PATCH 04/10] rm custom PhantomData serialization derivation from InstructionLookupsProof --- jolt-core/src/jolt/instruction/mod.rs | 2 +- jolt-core/src/jolt/vm/instruction_lookups.rs | 49 +------------------- 2 files changed, 2 insertions(+), 49 deletions(-) diff --git a/jolt-core/src/jolt/instruction/mod.rs b/jolt-core/src/jolt/instruction/mod.rs index ea38f8b02..b3d328451 100644 --- a/jolt-core/src/jolt/instruction/mod.rs +++ b/jolt-core/src/jolt/instruction/mod.rs @@ -70,7 +70,7 @@ pub trait JoltInstruction: Sync + Clone + Debug { } pub trait JoltInstructionSet: - JoltInstruction + IntoEnumIterator + EnumCount + for<'a> TryFrom<&'a ELFInstruction> + JoltInstruction + IntoEnumIterator + EnumCount + for<'a> TryFrom<&'a ELFInstruction> + Send + Sync { fn enum_index(instruction: &Self) -> usize { unsafe { *<*const _>::from(instruction).cast::() as usize } diff --git a/jolt-core/src/jolt/vm/instruction_lookups.rs b/jolt-core/src/jolt/vm/instruction_lookups.rs index b3862f02d..3d404dbc1 100644 --- a/jolt-core/src/jolt/vm/instruction_lookups.rs +++ b/jolt-core/src/jolt/vm/instruction_lookups.rs @@ -751,6 +751,7 @@ where } /// Proof of instruction lookups for a single Jolt program execution. +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct InstructionLookupsProof where F: PrimeField, @@ -768,54 +769,6 @@ where >, } -impl CanonicalSerialize for InstructionLookupsProof -where - F: PrimeField, - G: CurveGroup, - Subtables: JoltSubtableSet, - InstructionSet: JoltInstructionSet, -{ - fn serialize_with_mode(&self, mut writer: W, mode: ark_serialize::Compress) -> Result<(), ark_serialize::SerializationError> { - self.primary_sumcheck.serialize_with_mode(&mut writer, mode)?; - self.memory_checking.serialize_with_mode(&mut writer, mode)?; - Ok(()) - } - - fn serialized_size(&self, mode: ark_serialize::Compress) -> usize { - self.primary_sumcheck.serialized_size(mode) + self.memory_checking.serialized_size(mode) - } -} - -impl CanonicalDeserialize for InstructionLookupsProof -where - F: PrimeField, - G: CurveGroup, - Subtables: JoltSubtableSet, - InstructionSet: JoltInstructionSet, -{ - fn deserialize_with_mode(mut reader: R, compress: ark_serialize::Compress, validate: ark_serialize::Validate) -> Result { - let primary_sumcheck = PrimarySumcheck::deserialize_with_mode(&mut reader, compress, validate)?; - let memory_checking = MemoryCheckingProof::deserialize_with_mode(&mut reader, compress, validate)?; - Ok(Self { _instructions: PhantomData, primary_sumcheck, memory_checking }) - } -} - -impl ark_serialize::Valid for InstructionLookupsProof -where - F: PrimeField, - G: CurveGroup, - Subtables: JoltSubtableSet, - InstructionSet: JoltInstructionSet, -{ - fn check(&self) -> Result<(), ark_serialize::SerializationError> { - self.primary_sumcheck.check()?; - self.memory_checking.check()?; - Ok(()) - } -} - - - #[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct PrimarySumcheck> { sumcheck_proof: SumcheckInstanceProof, From 9d560e64ad67cb22c50670f5663f739585bf4677 Mon Sep 17 00:00:00 2001 From: sragss Date: Wed, 27 Mar 2024 10:59:18 -0700 Subject: [PATCH 05/10] rm custom PhantomData serialization derivation from JoltProof --- jolt-core/src/jolt/vm/mod.rs | 61 +----------------------------------- 1 file changed, 1 insertion(+), 60 deletions(-) diff --git a/jolt-core/src/jolt/vm/mod.rs b/jolt-core/src/jolt/vm/mod.rs index da2473ef0..edd3183fc 100644 --- a/jolt-core/src/jolt/vm/mod.rs +++ b/jolt-core/src/jolt/vm/mod.rs @@ -51,6 +51,7 @@ where pub read_write_memory: ReadWriteMemoryPreprocessing, } +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct JoltProof where F: PrimeField, @@ -64,66 +65,6 @@ where r1cs: R1CSProof, } -impl ark_serialize::CanonicalSerialize for JoltProof -where - F: PrimeField, - G: CurveGroup, - InstructionSet: JoltInstructionSet, - Subtables: JoltSubtableSet, -{ - fn serialize_with_mode(&self, mut writer: W, mode: ark_serialize::Compress) -> Result<(), ark_serialize::SerializationError> { - self.bytecode.serialize_with_mode(&mut writer, mode)?; - self.read_write_memory.serialize_with_mode(&mut writer, mode)?; - self.instruction_lookups.serialize_with_mode(&mut writer, mode)?; - self.r1cs.serialize_with_mode(&mut writer, mode)?; - Ok(()) - } - - fn serialized_size(&self, mode: ark_serialize::Compress) -> usize { - self.bytecode.serialized_size(mode) - + self.read_write_memory.serialized_size(mode) - + self.instruction_lookups.serialized_size(mode) - + self.r1cs.serialized_size(mode) - } -} - -impl ark_serialize::CanonicalDeserialize for JoltProof -where - F: PrimeField, - G: CurveGroup, - InstructionSet: JoltInstructionSet, - Subtables: JoltSubtableSet, -{ - fn deserialize_with_mode(mut reader: R, compress: ark_serialize::Compress, validate: ark_serialize::Validate) -> Result { - let bytecode = BytecodeProof::deserialize_with_mode(&mut reader, compress, validate)?; - let read_write_memory = ReadWriteMemoryProof::deserialize_with_mode(&mut reader, compress, validate)?; - let instruction_lookups = InstructionLookupsProof::deserialize_with_mode(&mut reader, compress, validate)?; - let r1cs = R1CSProof::deserialize_with_mode(&mut reader, compress, validate)?; - Ok(Self { - bytecode, - read_write_memory, - instruction_lookups, - r1cs, - }) - } -} - -impl ark_serialize::Valid for JoltProof -where - F: PrimeField, - G: CurveGroup, - InstructionSet: JoltInstructionSet, - Subtables: JoltSubtableSet, -{ - fn check(&self) -> Result<(), ark_serialize::SerializationError> { - self.bytecode.check()?; - self.read_write_memory.check()?; - self.instruction_lookups.check()?; - self.r1cs.check()?; - Ok(()) - } -} - pub struct JoltPolynomials where F: PrimeField, From 24e19b6f89020d55714954e304172831420549ec Mon Sep 17 00:00:00 2001 From: sragss Date: Wed, 27 Mar 2024 11:01:16 -0700 Subject: [PATCH 06/10] rm custom PhantomData serialization derivation from MemoryCheckingProof --- jolt-core/src/lasso/memory_checking.rs | 84 +------------------------- jolt-core/src/poly/structured_poly.rs | 2 +- 2 files changed, 3 insertions(+), 83 deletions(-) diff --git a/jolt-core/src/lasso/memory_checking.rs b/jolt-core/src/lasso/memory_checking.rs index 6f3567955..ae5a266de 100644 --- a/jolt-core/src/lasso/memory_checking.rs +++ b/jolt-core/src/lasso/memory_checking.rs @@ -60,10 +60,11 @@ impl MultisetHashes { } } +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct MemoryCheckingProof where G: CurveGroup, - Polynomials: BatchablePolynomials + ?Sized, + Polynomials: BatchablePolynomials, ReadWriteOpenings: StructuredOpeningProof, InitFinalOpenings: StructuredOpeningProof, { @@ -84,87 +85,6 @@ where pub init_final_opening_proof: InitFinalOpenings::Proof, } -impl CanonicalSerialize for MemoryCheckingProof -where - G: CurveGroup, - Polynomials: BatchablePolynomials + ?Sized, - ReadWriteOpenings: StructuredOpeningProof, - InitFinalOpenings: StructuredOpeningProof, -{ - fn serialize_with_mode(&self, mut writer: W, mode: ark_serialize::Compress) -> Result<(), ark_serialize::SerializationError> { - // self._polys.serialize_with_mode(&mut writer, mode)?; - self.multiset_hashes.serialize_with_mode(&mut writer, mode)?; - self.read_write_grand_product.serialize_with_mode(&mut writer, mode)?; - self.init_final_grand_product.serialize_with_mode(&mut writer, mode)?; - self.read_write_openings.serialize_with_mode(&mut writer, mode)?; - self.read_write_opening_proof.serialize_with_mode(&mut writer, mode)?; - self.init_final_openings.serialize_with_mode(&mut writer, mode)?; - self.init_final_opening_proof.serialize_with_mode(&mut writer, mode)?; - Ok(()) - } - - fn serialized_size(&self, mode: ark_serialize::Compress) -> usize { - // self._polys.serialized_size(mode) + - self.multiset_hashes.serialized_size(mode) + - self.read_write_grand_product.serialized_size(mode) + - self.init_final_grand_product.serialized_size(mode) + - self.read_write_openings.serialized_size(mode) + - self.read_write_opening_proof.serialized_size(mode) + - self.init_final_openings.serialized_size(mode) + - self.init_final_opening_proof.serialized_size(mode) - } -} - -impl CanonicalDeserialize for MemoryCheckingProof -where - G: CurveGroup, - Polynomials: BatchablePolynomials + ?Sized, - ReadWriteOpenings: StructuredOpeningProof, - InitFinalOpenings: StructuredOpeningProof, -{ - fn deserialize_with_mode(mut reader: R, compress: ark_serialize::Compress, validate: ark_serialize::Validate) -> Result { - // let _polys = PhantomData::deserialize_with_mode(&mut reader, compress, validate)?; - let multiset_hashes = MultisetHashes::deserialize_with_mode(&mut reader, compress, validate)?; - let read_write_grand_product = BatchedGrandProductArgument::deserialize_with_mode(&mut reader, compress, validate)?; - let init_final_grand_product = BatchedGrandProductArgument::deserialize_with_mode(&mut reader, compress, validate)?; - let read_write_openings = ReadWriteOpenings::deserialize_with_mode(&mut reader, compress, validate)?; - let read_write_opening_proof = ReadWriteOpenings::Proof::deserialize_with_mode(&mut reader, compress, validate)?; - let init_final_openings = InitFinalOpenings::deserialize_with_mode(&mut reader, compress, validate)?; - let init_final_opening_proof = InitFinalOpenings::Proof::deserialize_with_mode(&mut reader, compress, validate)?; - Ok(Self { - _polys: PhantomData, - multiset_hashes, - read_write_grand_product, - init_final_grand_product, - read_write_openings, - read_write_opening_proof, - init_final_openings, - init_final_opening_proof, - }) - } -} - -impl ark_serialize::Valid for MemoryCheckingProof -where - G: CurveGroup, - Polynomials: BatchablePolynomials + ?Sized, - ReadWriteOpenings: StructuredOpeningProof, - InitFinalOpenings: StructuredOpeningProof, -{ - fn check(&self) -> Result<(), ark_serialize::SerializationError> { - // self._polys.check()?; - self.multiset_hashes.check()?; - self.read_write_grand_product.check()?; - self.init_final_grand_product.check()?; - self.read_write_openings.check()?; - self.read_write_opening_proof.check()?; - self.init_final_openings.check()?; - self.init_final_opening_proof.check()?; - Ok(()) - } -} - - // Empty struct to represent that no preprocessing data is used. pub struct NoPreprocessing; diff --git a/jolt-core/src/poly/structured_poly.rs b/jolt-core/src/poly/structured_poly.rs index 7e8710cfa..09d0cc68b 100644 --- a/jolt-core/src/poly/structured_poly.rs +++ b/jolt-core/src/poly/structured_poly.rs @@ -13,7 +13,7 @@ use crate::{ /// Encapsulates the pattern of a collection of related polynomials (e.g. those used to /// prove instruction lookups in Jolt) that can be "batched" for more efficient /// commitments/openings. -pub trait BatchablePolynomials: Sync { +pub trait BatchablePolynomials: Send + Sync + Sized { /// The batched form of these polynomials. type BatchedPolynomials; /// The batched commitment to these polynomials. From cbd33a19e091883871e8f50df4e0c83a877b8d09 Mon Sep 17 00:00:00 2001 From: sragss Date: Wed, 27 Mar 2024 11:02:30 -0700 Subject: [PATCH 07/10] rm custom PhantomData serialization derivation from SurgeFinalOpenings --- jolt-core/src/jolt/instruction/mod.rs | 2 +- jolt-core/src/lasso/surge.rs | 46 ++------------------------- 2 files changed, 3 insertions(+), 45 deletions(-) diff --git a/jolt-core/src/jolt/instruction/mod.rs b/jolt-core/src/jolt/instruction/mod.rs index b3d328451..2e7937f39 100644 --- a/jolt-core/src/jolt/instruction/mod.rs +++ b/jolt-core/src/jolt/instruction/mod.rs @@ -12,7 +12,7 @@ use common::rv_trace::ELFInstruction; use std::fmt::Debug; #[enum_dispatch] -pub trait JoltInstruction: Sync + Clone + Debug { +pub trait JoltInstruction: Clone + Debug + Send + Sync { fn operands(&self) -> [u64; 2]; /// 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/lasso/surge.rs b/jolt-core/src/lasso/surge.rs index 29278f168..40925a0a0 100644 --- a/jolt-core/src/lasso/surge.rs +++ b/jolt-core/src/lasso/surge.rs @@ -242,10 +242,11 @@ where } } +#[derive(CanonicalSerialize, CanonicalDeserialize)] pub struct SurgeFinalOpenings where F: PrimeField, - Instruction: JoltInstruction + Default + Sync, + Instruction: JoltInstruction + Default, { _instruction: PhantomData, final_openings: Vec, // C-sized @@ -253,49 +254,6 @@ where v_init_final: Option>, // Computed by verifier } -impl CanonicalSerialize for SurgeFinalOpenings -where - F: PrimeField + CanonicalSerialize, - Instruction: JoltInstruction + Default + Sync, -{ - fn serialize_with_mode(&self, mut writer: W, mode: ark_serialize::Compress) -> Result<(), ark_serialize::SerializationError> { - self.final_openings.serialize_with_mode(&mut writer, mode)?; - self.a_init_final.serialize_with_mode(&mut writer, mode)?; - self.v_init_final.serialize_with_mode(&mut writer, mode)?; - Ok(()) - } - - fn serialized_size(&self, mode: ark_serialize::Compress) -> usize { - self.final_openings.serialized_size(mode) + self.a_init_final.serialized_size(mode) + self.v_init_final.serialized_size(mode) - } -} - -impl CanonicalDeserialize for SurgeFinalOpenings -where - F: PrimeField + CanonicalDeserialize, - Instruction: JoltInstruction + Default + Sync, -{ - fn deserialize_with_mode(mut reader: R, compress: ark_serialize::Compress, validate: ark_serialize::Validate) -> Result { - let final_openings = Vec::::deserialize_with_mode(&mut reader, compress, validate)?; - let a_init_final = Option::::deserialize_with_mode(&mut reader, compress, validate)?; - let v_init_final = Option::>::deserialize_with_mode(&mut reader, compress, validate)?; - Ok(Self { _instruction: PhantomData, final_openings, a_init_final, v_init_final }) - } -} - -impl ark_serialize::Valid for SurgeFinalOpenings -where - F: PrimeField + ark_serialize::Valid, - Instruction: JoltInstruction + Default + Sync, -{ - fn check(&self) -> Result<(), ark_serialize::SerializationError> { - self.final_openings.check()?; - self.a_init_final.check()?; - self.v_init_final.check()?; - Ok(()) - } -} - impl StructuredOpeningProof> for SurgeFinalOpenings where From 63f90b02b40bf0fe491321b4e27362cd3037c8e8 Mon Sep 17 00:00:00 2001 From: sragss Date: Wed, 27 Mar 2024 11:05:38 -0700 Subject: [PATCH 08/10] clean nits --- jolt-core/src/jolt/vm/mod.rs | 1 - jolt-core/src/poly/hyrax.rs | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/jolt-core/src/jolt/vm/mod.rs b/jolt-core/src/jolt/vm/mod.rs index edd3183fc..fa465622e 100644 --- a/jolt-core/src/jolt/vm/mod.rs +++ b/jolt-core/src/jolt/vm/mod.rs @@ -7,7 +7,6 @@ use common::rv_trace::JoltDevice; use itertools::max; use merlin::Transcript; use rayon::prelude::*; -use serde::Serialize; use crate::jolt::{ instruction::JoltInstruction, subtable::JoltSubtableSet, diff --git a/jolt-core/src/poly/hyrax.rs b/jolt-core/src/poly/hyrax.rs index 9fb4a4c0b..584d72cee 100644 --- a/jolt-core/src/poly/hyrax.rs +++ b/jolt-core/src/poly/hyrax.rs @@ -6,7 +6,6 @@ use crate::utils::math::Math; use crate::utils::transcript::{AppendToTranscript, ProofTranscript}; use crate::utils::{compute_dotproduct, mul_0_1_optimized}; use ark_ec::CurveGroup; -use ark_serialize::*; use ark_std::{One, Zero}; use merlin::Transcript; use num_integer::Roots; @@ -32,7 +31,7 @@ pub fn matrix_dimensions(num_vars: usize, matrix_aspect_ratio: usize) -> (usize, (col_size, row_size) } -#[derive(Clone, ark_serialize::CanonicalSerialize, ark_serialize::CanonicalDeserialize)] +#[derive(Clone, CanonicalSerialize, CanonicalDeserialize)] pub struct HyraxGenerators { pub gens: PedersenGenerators, } From f608097689644f5d64dcd69ae857575d8082a634 Mon Sep 17 00:00:00 2001 From: sragss Date: Wed, 27 Mar 2024 12:52:58 -0700 Subject: [PATCH 09/10] print detailed jolt_proof sizes --- jolt-core/src/benches/bench.rs | 10 ++++++++-- jolt-core/src/jolt/vm/mod.rs | 9 +++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/jolt-core/src/benches/bench.rs b/jolt-core/src/benches/bench.rs index f1ec634e4..72f6f5c84 100644 --- a/jolt-core/src/benches/bench.rs +++ b/jolt-core/src/benches/bench.rs @@ -226,8 +226,9 @@ fn serialize_and_print_size(name: &str, item: &impl ark_serialize::CanonicalSeri let file_size_bytes = file.metadata().unwrap().len(); let file_size_kb = file_size_bytes as f64 / 1024.0; let file_size_mb = file_size_kb / 1024.0; - let file_size_gb = file_size_mb / 1024.0; - println!("{} serialized size: {:.3} bytes ({:.3} KB, {:.3} MB, {:.3} GB)", name, file_size_bytes as f64, file_size_kb, file_size_mb, file_size_gb); + // let file_size_gb = file_size_mb / 1024.0; + // println!("{} serialized size: {:.3} bytes ({:.3} KB, {:.3} MB, {:.3} GB)", name, file_size_bytes as f64, file_size_kb, file_size_mb, file_size_gb); + println!("{:<30} : {:.3} MB", name, file_size_mb); } fn prove_example( @@ -257,8 +258,13 @@ fn prove_example( preprocessing.clone(), ); + println!("Proof sizing:"); serialize_and_print_size("jolt_commitments", &jolt_commitments); serialize_and_print_size("jolt_proof", &jolt_proof); + serialize_and_print_size(" jolt_proof.r1cs", &jolt_proof.r1cs); + serialize_and_print_size(" jolt_proof.bytecode", &jolt_proof.bytecode); + serialize_and_print_size(" jolt_proof.read_write_memory", &jolt_proof.read_write_memory); + serialize_and_print_size(" jolt_proof.instruction_lookups", &jolt_proof.instruction_lookups); let verification_result = RV32IJoltVM::verify(preprocessing, jolt_proof, jolt_commitments); assert!( diff --git a/jolt-core/src/jolt/vm/mod.rs b/jolt-core/src/jolt/vm/mod.rs index fa465622e..2233e7dd0 100644 --- a/jolt-core/src/jolt/vm/mod.rs +++ b/jolt-core/src/jolt/vm/mod.rs @@ -58,10 +58,10 @@ where InstructionSet: JoltInstructionSet, Subtables: JoltSubtableSet, { - bytecode: BytecodeProof, - read_write_memory: ReadWriteMemoryProof, - instruction_lookups: InstructionLookupsProof, - r1cs: R1CSProof, + pub bytecode: BytecodeProof, + pub read_write_memory: ReadWriteMemoryProof, + pub instruction_lookups: InstructionLookupsProof, + pub r1cs: R1CSProof, } pub struct JoltPolynomials @@ -156,6 +156,7 @@ pub trait Jolt, const C: usize, co JoltProof, JoltCommitments, ) { + println!("Jolt::prove({})", memory_trace.len()); let mut transcript = Transcript::new(b"Jolt transcript"); let bytecode_rows: Vec = bytecode .iter() From 6eedae23dc002cf74391c2bf745a193566b57c13 Mon Sep 17 00:00:00 2001 From: sragss Date: Wed, 27 Mar 2024 12:53:17 -0700 Subject: [PATCH 10/10] print detailed jolt_proof sizes --- jolt-core/src/benches/bench.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/jolt-core/src/benches/bench.rs b/jolt-core/src/benches/bench.rs index 72f6f5c84..bc7b48169 100644 --- a/jolt-core/src/benches/bench.rs +++ b/jolt-core/src/benches/bench.rs @@ -226,8 +226,6 @@ fn serialize_and_print_size(name: &str, item: &impl ark_serialize::CanonicalSeri let file_size_bytes = file.metadata().unwrap().len(); let file_size_kb = file_size_bytes as f64 / 1024.0; let file_size_mb = file_size_kb / 1024.0; - // let file_size_gb = file_size_mb / 1024.0; - // println!("{} serialized size: {:.3} bytes ({:.3} KB, {:.3} MB, {:.3} GB)", name, file_size_bytes as f64, file_size_kb, file_size_mb, file_size_gb); println!("{:<30} : {:.3} MB", name, file_size_mb); }