From 18d314126fac8202482cda4a6e1419f2ea4084b5 Mon Sep 17 00:00:00 2001 From: Uma Roy Date: Wed, 6 Sep 2023 20:37:38 -0700 Subject: [PATCH 1/6] Added mock feature flag and test --- evm/tests/basic_smart_contract.rs | 2 +- plonky2/Cargo.toml | 1 + plonky2/src/fri/oracle.rs | 23 ++++++++++++++ plonky2/src/hash/merkle_tree.rs | 16 ++++++++++ plonky2/src/iop/generator.rs | 2 +- plonky2/src/lookup_test.rs | 45 ++++++++++++++++++++++++++++ plonky2/src/plonk/circuit_builder.rs | 22 ++++++++------ 7 files changed, 100 insertions(+), 11 deletions(-) diff --git a/evm/tests/basic_smart_contract.rs b/evm/tests/basic_smart_contract.rs index 89aacd2c..28b5be0b 100644 --- a/evm/tests/basic_smart_contract.rs +++ b/evm/tests/basic_smart_contract.rs @@ -27,7 +27,7 @@ type C = KeccakGoldilocksConfig; /// Test a simple token transfer to a new address. #[test] -#[ignore] // Too slow to run on CI. +// #[ignore] // Too slow to run on CI. fn test_basic_smart_contract() -> anyhow::Result<()> { init_logger(); diff --git a/plonky2/Cargo.toml b/plonky2/Cargo.toml index c5de1e63..367b99d0 100644 --- a/plonky2/Cargo.toml +++ b/plonky2/Cargo.toml @@ -16,6 +16,7 @@ gate_testing = [] parallel = ["hashbrown/rayon", "plonky2_maybe_rayon/parallel"] std = ["anyhow/std", "rand/std", "itertools/use_std"] timing = ["std"] +mock = [] [dependencies] ahash = { version = "0.8.3", default-features = false, features = ["compile-time-rng"] } # NOTE: Be sure to keep this version the same as the dependency in `hashbrown`. diff --git a/plonky2/src/fri/oracle.rs b/plonky2/src/fri/oracle.rs index dca3202a..a7182e15 100644 --- a/plonky2/src/fri/oracle.rs +++ b/plonky2/src/fri/oracle.rs @@ -36,9 +36,32 @@ pub struct PolynomialBatch, C: GenericConfig, C: GenericConfig, const D: usize> Default + for PolynomialBatch +{ + fn default() -> Self { + PolynomialBatch { + polynomials: Vec::new(), + merkle_tree: MerkleTree::default(), + degree_log: 0, + rate_bits: 0, + blinding: false, + } + } +} + impl, C: GenericConfig, const D: usize> PolynomialBatch { + pub fn default() -> Self { + Self { + polynomials: Vec::new(), + merkle_tree: MerkleTree::default(), + degree_log: 0, + rate_bits: 0, + blinding: false, + } + } /// Creates a list polynomial commitment for the polynomials interpolating the values in `values`. pub fn from_values( values: Vec>, diff --git a/plonky2/src/hash/merkle_tree.rs b/plonky2/src/hash/merkle_tree.rs index b3b0e0cb..ab7e3958 100644 --- a/plonky2/src/hash/merkle_tree.rs +++ b/plonky2/src/hash/merkle_tree.rs @@ -17,6 +17,12 @@ use crate::util::log2_strict; // TODO: Change H to GenericHashOut, since this only cares about the hash, not the hasher. pub struct MerkleCap>(pub Vec); +impl> Default for MerkleCap { + fn default() -> Self { + Self(Vec::new()) + } +} + impl> MerkleCap { pub fn len(&self) -> usize { self.0.len() @@ -54,6 +60,16 @@ pub struct MerkleTree> { pub cap: MerkleCap, } +impl> Default for MerkleTree { + fn default() -> Self { + Self { + leaves: Vec::new(), + digests: Vec::new(), + cap: MerkleCap::default(), + } + } +} + fn capacity_up_to_mut(v: &mut Vec, len: usize) -> &mut [MaybeUninit] { assert!(v.capacity() >= len); let v_ptr = v.as_mut_ptr().cast::>(); diff --git a/plonky2/src/iop/generator.rs b/plonky2/src/iop/generator.rs index 478c5ff5..10293339 100644 --- a/plonky2/src/iop/generator.rs +++ b/plonky2/src/iop/generator.rs @@ -16,7 +16,7 @@ use crate::util::serialization::{Buffer, IoResult, Read, Write}; /// Given a `PartitionWitness` that has only inputs set, populates the rest of the witness using the /// given set of generators. -pub(crate) fn generate_partial_witness< +pub fn generate_partial_witness< 'a, F: RichField + Extendable, C: GenericConfig, diff --git a/plonky2/src/lookup_test.rs b/plonky2/src/lookup_test.rs index c575417e..c8b084cc 100644 --- a/plonky2/src/lookup_test.rs +++ b/plonky2/src/lookup_test.rs @@ -469,6 +469,51 @@ mod tests { Ok(()) } + #[cfg(feature = "mock")] + #[test] + fn test_circuit_build_mock() { + // This code is taken from examples/fibonacci.rs + use crate::field::types::Field; + use crate::iop::generator::generate_partial_witness; + use crate::iop::witness::{PartialWitness, Witness, WitnessWrite}; + use crate::plonk::circuit_builder::CircuitBuilder; + use crate::plonk::circuit_data::CircuitConfig; + use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; + + const D: usize = 2; + type C = PoseidonGoldilocksConfig; + type F = >::F; + + let config = CircuitConfig::standard_recursion_config(); + let mut builder = CircuitBuilder::::new(config); + + // The arithmetic circuit. + let initial_a = builder.add_virtual_target(); + let initial_b = builder.add_virtual_target(); + let mut prev_target = initial_a; + let mut cur_target = initial_b; + for _ in 0..99 { + let temp = builder.add(prev_target, cur_target); + prev_target = cur_target; + cur_target = temp; + } + + // Public inputs are the two initial values (provided below) and the result (which is generated). + builder.register_public_input(initial_a); + builder.register_public_input(initial_b); + builder.register_public_input(cur_target); + + // Provide initial values. + let mut pw = PartialWitness::new(); + pw.set_target(initial_a, F::ZERO); + pw.set_target(initial_b, F::ONE); + + let data = builder.build::(); + let partition_witness = generate_partial_witness(pw, &data.prover_only, &data.common); + let result = partition_witness.try_get_target(cur_target).unwrap(); + assert_eq!(result, F::from_canonical_u64(3736710860384812976)); + } + fn init_logger() -> anyhow::Result<()> { let mut builder = env_logger::Builder::from_default_env(); builder.format_timestamp(None); diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 82d4ee89..89ec0903 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -1023,15 +1023,19 @@ impl, const D: usize> CircuitBuilder { let max_fft_points = 1 << (degree_bits + max(rate_bits, log2_ceil(quotient_degree_factor))); let fft_root_table = fft_root_table(max_fft_points); - let constants_sigmas_vecs = [constant_vecs, sigma_vecs.clone()].concat(); - let constants_sigmas_commitment = PolynomialBatch::::from_values( - constants_sigmas_vecs, - rate_bits, - PlonkOracle::CONSTANTS_SIGMAS.blinding, - cap_height, - &mut timing, - Some(&fft_root_table), - ); + let mut constants_sigmas_commitment = PolynomialBatch::::default(); + #[cfg(not(feature = "mock"))] + { + let constants_sigmas_vecs = [constant_vecs, sigma_vecs.clone()].concat(); + constants_sigmas_commitment = PolynomialBatch::::from_values( + constants_sigmas_vecs, + rate_bits, + PlonkOracle::CONSTANTS_SIGMAS.blinding, + cap_height, + &mut timing, + Some(&fft_root_table), + ); + } // Map between gates where not all generators are used and the gate's number of used generators. let incomplete_gates = self From 4782519d8b16463e8e8abf2f6e6be664d90028f7 Mon Sep 17 00:00:00 2001 From: Uma Roy Date: Wed, 6 Sep 2023 20:40:43 -0700 Subject: [PATCH 2/6] remove spurious --- evm/tests/basic_smart_contract.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm/tests/basic_smart_contract.rs b/evm/tests/basic_smart_contract.rs index 28b5be0b..89aacd2c 100644 --- a/evm/tests/basic_smart_contract.rs +++ b/evm/tests/basic_smart_contract.rs @@ -27,7 +27,7 @@ type C = KeccakGoldilocksConfig; /// Test a simple token transfer to a new address. #[test] -// #[ignore] // Too slow to run on CI. +#[ignore] // Too slow to run on CI. fn test_basic_smart_contract() -> anyhow::Result<()> { init_logger(); From 0ca796e1ff253f2d2501d1ad3a3fcffc6c531ebd Mon Sep 17 00:00:00 2001 From: Uma Roy Date: Thu, 7 Sep 2023 11:29:04 -0700 Subject: [PATCH 3/6] Removed mock feature flag and added mock_build --- plonky2/Cargo.toml | 1 - plonky2/src/lookup_test.rs | 6 ++---- plonky2/src/plonk/circuit_builder.rs | 23 ++++++++++++++++++----- plonky2/src/plonk/circuit_data.rs | 20 ++++++++++++++++++-- 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/plonky2/Cargo.toml b/plonky2/Cargo.toml index 367b99d0..c5de1e63 100644 --- a/plonky2/Cargo.toml +++ b/plonky2/Cargo.toml @@ -16,7 +16,6 @@ gate_testing = [] parallel = ["hashbrown/rayon", "plonky2_maybe_rayon/parallel"] std = ["anyhow/std", "rand/std", "itertools/use_std"] timing = ["std"] -mock = [] [dependencies] ahash = { version = "0.8.3", default-features = false, features = ["compile-time-rng"] } # NOTE: Be sure to keep this version the same as the dependency in `hashbrown`. diff --git a/plonky2/src/lookup_test.rs b/plonky2/src/lookup_test.rs index c8b084cc..165d5dfe 100644 --- a/plonky2/src/lookup_test.rs +++ b/plonky2/src/lookup_test.rs @@ -469,12 +469,10 @@ mod tests { Ok(()) } - #[cfg(feature = "mock")] #[test] fn test_circuit_build_mock() { // This code is taken from examples/fibonacci.rs use crate::field::types::Field; - use crate::iop::generator::generate_partial_witness; use crate::iop::witness::{PartialWitness, Witness, WitnessWrite}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::CircuitConfig; @@ -508,8 +506,8 @@ mod tests { pw.set_target(initial_a, F::ZERO); pw.set_target(initial_b, F::ONE); - let data = builder.build::(); - let partition_witness = generate_partial_witness(pw, &data.prover_only, &data.common); + let data = builder.mock_build::(); + let partition_witness = data.generate_witness(pw); let result = partition_witness.try_get_target(cur_target).unwrap(); assert_eq!(result, F::from_canonical_u64(3736710860384812976)); } diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 89ec0903..5a9eb3b2 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -40,8 +40,8 @@ use crate::iop::generator::{ use crate::iop::target::{BoolTarget, Target}; use crate::iop::wire::Wire; use crate::plonk::circuit_data::{ - CircuitConfig, CircuitData, CommonCircuitData, ProverCircuitData, ProverOnlyCircuitData, - VerifierCircuitData, VerifierCircuitTarget, VerifierOnlyCircuitData, + CircuitConfig, CircuitData, CommonCircuitData, MockCircuitData, ProverCircuitData, + ProverOnlyCircuitData, VerifierCircuitData, VerifierCircuitTarget, VerifierOnlyCircuitData, }; use crate::plonk::config::{AlgebraicHasher, GenericConfig, GenericHashOut, Hasher}; use crate::plonk::copy_constraint::CopyConstraint; @@ -916,7 +916,10 @@ impl, const D: usize> CircuitBuilder { } /// Builds a "full circuit", with both prover and verifier data. - pub fn build>(mut self) -> CircuitData { + pub fn build_with_options>( + mut self, + commit_to_sigma: bool, + ) -> CircuitData { let mut timing = TimingTree::new("preprocess", Level::Trace); #[cfg(feature = "std")] @@ -1024,8 +1027,7 @@ impl, const D: usize> CircuitBuilder { let fft_root_table = fft_root_table(max_fft_points); let mut constants_sigmas_commitment = PolynomialBatch::::default(); - #[cfg(not(feature = "mock"))] - { + if commit_to_sigma { let constants_sigmas_vecs = [constant_vecs, sigma_vecs.clone()].concat(); constants_sigmas_commitment = PolynomialBatch::::from_values( constants_sigmas_vecs, @@ -1155,6 +1157,17 @@ impl, const D: usize> CircuitBuilder { } } + pub fn build>(self) -> CircuitData { + self.build_with_options(true) + } + + pub fn mock_build>(self) -> MockCircuitData { + let circuit_data = self.build_with_options(false); + MockCircuitData { + prover_only: circuit_data.prover_only, + common: circuit_data.common, + } + } /// Builds a "prover circuit", with data needed to generate proofs but not verify them. pub fn build_prover>(self) -> ProverCircuitData { // TODO: Can skip parts of this. diff --git a/plonky2/src/plonk/circuit_data.rs b/plonky2/src/plonk/circuit_data.rs index 6e4e0638..0b96c527 100644 --- a/plonky2/src/plonk/circuit_data.rs +++ b/plonky2/src/plonk/circuit_data.rs @@ -24,9 +24,9 @@ use crate::gates::selectors::SelectorsInfo; use crate::hash::hash_types::{HashOutTarget, MerkleCapTarget, RichField}; use crate::hash::merkle_tree::MerkleCap; use crate::iop::ext_target::ExtensionTarget; -use crate::iop::generator::WitnessGeneratorRef; +use crate::iop::generator::{generate_partial_witness, WitnessGeneratorRef}; use crate::iop::target::Target; -use crate::iop::witness::PartialWitness; +use crate::iop::witness::{PartialWitness, PartitionWitness}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::config::{GenericConfig, Hasher}; use crate::plonk::plonk_common::PlonkOracle; @@ -111,6 +111,22 @@ impl CircuitConfig { } } +/// Circuit data required by the prover or the verifier. +#[derive(Eq, PartialEq, Debug)] +pub struct MockCircuitData, C: GenericConfig, const D: usize> +{ + pub prover_only: ProverOnlyCircuitData, + pub common: CommonCircuitData, +} + +impl<'a, F: RichField + Extendable, C: GenericConfig, const D: usize> + MockCircuitData +{ + pub fn generate_witness(&self, inputs: PartialWitness) -> PartitionWitness { + generate_partial_witness::(inputs, &self.prover_only, &self.common) + } +} + /// Circuit data required by the prover or the verifier. #[derive(Eq, PartialEq, Debug)] pub struct CircuitData, C: GenericConfig, const D: usize> { From 5a3c8b26d10afb34f1554905bf4d2a741c7b66d5 Mon Sep 17 00:00:00 2001 From: Uma Roy Date: Thu, 7 Sep 2023 11:30:19 -0700 Subject: [PATCH 4/6] clippy --- plonky2/src/fri/oracle.rs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/plonky2/src/fri/oracle.rs b/plonky2/src/fri/oracle.rs index a7182e15..8642a6c5 100644 --- a/plonky2/src/fri/oracle.rs +++ b/plonky2/src/fri/oracle.rs @@ -53,15 +53,6 @@ impl, C: GenericConfig, const D: usize> D impl, C: GenericConfig, const D: usize> PolynomialBatch { - pub fn default() -> Self { - Self { - polynomials: Vec::new(), - merkle_tree: MerkleTree::default(), - degree_log: 0, - rate_bits: 0, - blinding: false, - } - } /// Creates a list polynomial commitment for the polynomials interpolating the values in `values`. pub fn from_values( values: Vec>, From a64330710821cf5735d7013111b29a8e53618eed Mon Sep 17 00:00:00 2001 From: Uma Roy Date: Thu, 7 Sep 2023 17:41:52 -0700 Subject: [PATCH 5/6] Fixes --- plonky2/src/plonk/circuit_builder.rs | 11 ++++++----- plonky2/src/plonk/circuit_data.rs | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 5a9eb3b2..bd436f2c 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -1026,18 +1026,19 @@ impl, const D: usize> CircuitBuilder { let max_fft_points = 1 << (degree_bits + max(rate_bits, log2_ceil(quotient_degree_factor))); let fft_root_table = fft_root_table(max_fft_points); - let mut constants_sigmas_commitment = PolynomialBatch::::default(); - if commit_to_sigma { + let constants_sigmas_commitment = if commit_to_sigma { let constants_sigmas_vecs = [constant_vecs, sigma_vecs.clone()].concat(); - constants_sigmas_commitment = PolynomialBatch::::from_values( + PolynomialBatch::::from_values( constants_sigmas_vecs, rate_bits, PlonkOracle::CONSTANTS_SIGMAS.blinding, cap_height, &mut timing, Some(&fft_root_table), - ); - } + ) + } else { + PolynomialBatch::::default() + }; // Map between gates where not all generators are used and the gate's number of used generators. let incomplete_gates = self diff --git a/plonky2/src/plonk/circuit_data.rs b/plonky2/src/plonk/circuit_data.rs index 0b96c527..26094679 100644 --- a/plonky2/src/plonk/circuit_data.rs +++ b/plonky2/src/plonk/circuit_data.rs @@ -111,7 +111,7 @@ impl CircuitConfig { } } -/// Circuit data required by the prover or the verifier. +/// Mock circuit data to only do witness generation without generating a proof. #[derive(Eq, PartialEq, Debug)] pub struct MockCircuitData, C: GenericConfig, const D: usize> { From 1be1ca4d321fa42e0db07ed57491b1d4d09a4a63 Mon Sep 17 00:00:00 2001 From: Uma Roy Date: Thu, 7 Sep 2023 17:43:37 -0700 Subject: [PATCH 6/6] clippy --- plonky2/src/plonk/circuit_data.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plonky2/src/plonk/circuit_data.rs b/plonky2/src/plonk/circuit_data.rs index 26094679..c93de8cb 100644 --- a/plonky2/src/plonk/circuit_data.rs +++ b/plonky2/src/plonk/circuit_data.rs @@ -119,7 +119,7 @@ pub struct MockCircuitData, C: GenericConfig, } -impl<'a, F: RichField + Extendable, C: GenericConfig, const D: usize> +impl, C: GenericConfig, const D: usize> MockCircuitData { pub fn generate_witness(&self, inputs: PartialWitness) -> PartitionWitness {