From 32753831d2823d5f85e3a5dc50d2d7e27807f640 Mon Sep 17 00:00:00 2001 From: Balazs Komuves Date: Fri, 13 Dec 2024 11:35:36 +0100 Subject: [PATCH] export the constant columns (selectors too) for third-party tooling --- plonky2/src/plonk/circuit_builder.rs | 3 ++- plonky2/src/plonk/circuit_data.rs | 2 ++ plonky2/src/plonk/prover.rs | 31 +++++++++++++++++++++------ plonky2/src/util/serialization/mod.rs | 16 ++++++++++++++ 4 files changed, 44 insertions(+), 8 deletions(-) diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 0954483f..f0c0c885 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -1185,7 +1185,7 @@ impl, const D: usize> CircuitBuilder { let fft_root_table = fft_root_table(max_fft_points); let constants_sigmas_commitment = if commit_to_sigma { - let constants_sigmas_vecs = [constant_vecs, sigma_vecs.clone()].concat(); + let constants_sigmas_vecs = [constant_vecs.clone(), sigma_vecs.clone()].concat(); PolynomialBatch::::from_values( constants_sigmas_vecs, rate_bits, @@ -1296,6 +1296,7 @@ impl, const D: usize> CircuitBuilder { let prover_only = ProverOnlyCircuitData:: { generators: self.generators, generator_indices_by_watches, + constants_vecs: constant_vecs.into_iter().map(|x| x.values.clone()).collect(), constants_sigmas_commitment, sigmas: transpose_poly_values(sigma_vecs), subgroup, diff --git a/plonky2/src/plonk/circuit_data.rs b/plonky2/src/plonk/circuit_data.rs index ce3fdb9b..64e50297 100644 --- a/plonky2/src/plonk/circuit_data.rs +++ b/plonky2/src/plonk/circuit_data.rs @@ -369,6 +369,8 @@ pub struct ProverOnlyCircuitData< /// Generator indices (within the `Vec` above), indexed by the representative of each target /// they watch. pub generator_indices_by_watches: BTreeMap>, + /// the constant vectors themselves (including the selectors) + pub constants_vecs: Vec>, /// Commitments to the constants polynomials and sigma polynomials. pub constants_sigmas_commitment: PolynomialBatch, /// The transpose of the list of sigma polynomials. diff --git a/plonky2/src/plonk/prover.rs b/plonky2/src/plonk/prover.rs index fa82d53b..792c58c1 100644 --- a/plonky2/src/plonk/prover.rs +++ b/plonky2/src/plonk/prover.rs @@ -129,21 +129,38 @@ pub const DEFAULT_PROVER_OPTIONS: ProverOptions = ProverOptions { // things we want to export to be used by third party tooling #[derive(Debug,Clone,Serialize)] struct ThingsToExport { - gates: Vec, - selector_vector: Vec, - matrix: Vec>, + gates: Vec, // list of gates used in the circuit + selector_vector: Vec, // the full selector vector (a gate index for each row) + selector_columns: Vec>, // the selector columns (column-major) + constants_columns: Vec>, // the constant columns (column-major) + matrix: Vec>, // the witness matrix (column-major) + // circuit_digest: Vec, } // the idea is to export the witness (plus some more information), // so that third-party tools can for example visualize it fn collect_things_to_export, C: GenericConfig, const D: usize>( common_data: &CommonCircuitData, + prover_data : &ProverOnlyCircuitData, wires_matrix: &MatrixWitness, ) -> ThingsToExport { + + let num_consts_selectors = common_data.num_constants; + let num_selectors = common_data.selectors_info.num_selectors(); + let _num_constants = num_consts_selectors - num_selectors; + let constants_vecs = &prover_data.constants_vecs; + assert!( num_consts_selectors == constants_vecs.len() ); + + let selector_cols: Vec> = constants_vecs[0..num_selectors].to_vec(); + let constant_cols: Vec> = constants_vecs[num_selectors.. ].to_vec(); + ThingsToExport { - gates: common_data.gates.iter().map(|g| g.0.short_id()).collect(), - selector_vector: common_data.selectors_info.selector_vector.clone(), - matrix: wires_matrix.wire_values.clone(), + gates: common_data.gates.iter().map(|g| g.0.short_id()).collect(), + selector_vector: common_data.selectors_info.selector_vector.clone(), + selector_columns: selector_cols, + constants_columns: constant_cols, + matrix: wires_matrix.wire_values.clone(), + // circuit_digest: prover_data.circuit_digest, } } @@ -243,7 +260,7 @@ where match &prover_options.export_witness { None => (), Some(fname) => { - let things_to_export = collect_things_to_export::( &common_data, &witness ); + let things_to_export = collect_things_to_export::( &common_data, &prover_data, &witness ); write_json_file(&fname, &things_to_export)?; println!("exported witness to `{}`",fname); }, diff --git a/plonky2/src/util/serialization/mod.rs b/plonky2/src/util/serialization/mod.rs index 9a709601..e557a872 100644 --- a/plonky2/src/util/serialization/mod.rs +++ b/plonky2/src/util/serialization/mod.rs @@ -850,7 +850,15 @@ pub trait Read { generator_indices_by_watches.insert(k, self.read_usize_vec()?); } + let constants_vecs_len = self.read_usize()?; + let mut constants_vecs = Vec::with_capacity(constants_vecs_len); + for _ in 0..constants_vecs_len { + let vec_len = self.read_usize()?; + constants_vecs.push(self.read_field_vec(vec_len)?); + } + let constants_sigmas_commitment = self.read_polynomial_batch()?; + let sigmas_len = self.read_usize()?; let mut sigmas = Vec::with_capacity(sigmas_len); for _ in 0..sigmas_len { @@ -900,6 +908,7 @@ pub trait Read { Ok(ProverOnlyCircuitData { generators, generator_indices_by_watches, + constants_vecs, constants_sigmas_commitment, sigmas, subgroup, @@ -1854,6 +1863,7 @@ pub trait Write { let ProverOnlyCircuitData { generators, generator_indices_by_watches, + constants_vecs, constants_sigmas_commitment, sigmas, subgroup, @@ -1876,6 +1886,12 @@ pub trait Write { self.write_usize_vec(v)?; } + self.write_usize(constants_vecs.len())?; + for i in 0..constants_vecs.len() { + self.write_usize(constants_vecs[i].len())?; + self.write_field_vec(&constants_vecs[i])?; + } + self.write_polynomial_batch(constants_sigmas_commitment)?; self.write_usize(sigmas.len())?; for i in 0..sigmas.len() {