diff --git a/Cargo.toml b/Cargo.toml index fa22a769..4d40b44e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,12 +12,12 @@ edition = "2018" default-run = "bench_recursion" [dependencies] -env_logger = "0.8.3" +env_logger = "0.9.0" log = "0.4.14" itertools = "0.10.0" -num = "0.3" -rand = "0.7.3" -rand_chacha = "0.2.2" +num = "0.4" +rand = "0.8.4" +rand_chacha = "0.3.1" rayon = "1.5.1" unroll = "0.1.5" anyhow = "1.0.40" diff --git a/src/bin/bench_recursion.rs b/src/bin/bench_recursion.rs index 59cdf4a6..3b71c6f4 100644 --- a/src/bin/bench_recursion.rs +++ b/src/bin/bench_recursion.rs @@ -34,6 +34,7 @@ fn bench_prove, const D: usize>() -> Result<()> { }, }; + let inputs = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); let zero = builder.zero(); @@ -49,7 +50,6 @@ fn bench_prove, const D: usize>() -> Result<()> { builder.add_extension(zero_ext, zero_ext); let circuit = builder.build(); - let inputs = PartialWitness::new(); let proof_with_pis = circuit.prove(inputs)?; let proof_bytes = serde_cbor::to_vec(&proof_with_pis).unwrap(); info!("Proof length: {} bytes", proof_bytes.len()); diff --git a/src/field/crandall_field.rs b/src/field/crandall_field.rs index ebdb9e25..fba11677 100644 --- a/src/field/crandall_field.rs +++ b/src/field/crandall_field.rs @@ -343,7 +343,7 @@ impl Field for CrandallField { } fn rand_from_rng(rng: &mut R) -> Self { - Self::from_canonical_u64(rng.gen_range(0, FIELD_ORDER)) + Self::from_canonical_u64(rng.gen_range(0..FIELD_ORDER)) } } diff --git a/src/field/fft.rs b/src/field/fft.rs index 5b81ea06..1566db84 100644 --- a/src/field/fft.rs +++ b/src/field/fft.rs @@ -13,7 +13,7 @@ enum FftStrategy { const FFT_STRATEGY: FftStrategy = FftStrategy::Classic; -type FftRootTable = Vec>; +pub(crate) type FftRootTable = Vec>; fn fft_classic_root_table(n: usize) -> FftRootTable { let lg_n = log2_strict(n); diff --git a/src/fri/commitment.rs b/src/fri/commitment.rs index ee7c2717..79efceb7 100644 --- a/src/fri/commitment.rs +++ b/src/fri/commitment.rs @@ -23,7 +23,6 @@ pub const SALT_SIZE: usize = 2; pub struct PolynomialBatchCommitment { pub polynomials: Vec>, pub merkle_tree: MerkleTree, - pub degree: usize, pub degree_log: usize, pub rate_bits: usize, pub blinding: bool, @@ -31,25 +30,23 @@ pub struct PolynomialBatchCommitment { impl PolynomialBatchCommitment { /// Creates a list polynomial commitment for the polynomials interpolating the values in `values`. - pub(crate) fn new( + pub(crate) fn from_values( values: Vec>, rate_bits: usize, blinding: bool, timing: &mut TimingTree, ) -> Self { - let degree = values[0].len(); - let polynomials = values.par_iter().map(|v| v.ifft()).collect::>(); - let lde_values = timed!( + let coeffs = timed!( timing, - "compute LDE", - Self::lde_values(&polynomials, rate_bits, blinding) + "IFFT", + values.par_iter().map(|v| v.ifft()).collect::>() ); - Self::new_from_data(polynomials, lde_values, degree, rate_bits, blinding, timing) + Self::from_coeffs(coeffs, rate_bits, blinding, timing) } /// Creates a list polynomial commitment for the polynomials `polynomials`. - pub(crate) fn new_from_polys( + pub(crate) fn from_coeffs( polynomials: Vec>, rate_bits: usize, blinding: bool, @@ -58,21 +55,10 @@ impl PolynomialBatchCommitment { let degree = polynomials[0].len(); let lde_values = timed!( timing, - "compute LDE", + "FFT + blinding", Self::lde_values(&polynomials, rate_bits, blinding) ); - Self::new_from_data(polynomials, lde_values, degree, rate_bits, blinding, timing) - } - - fn new_from_data( - polynomials: Vec>, - lde_values: Vec>, - degree: usize, - rate_bits: usize, - blinding: bool, - timing: &mut TimingTree, - ) -> Self { let mut leaves = timed!(timing, "transpose LDEs", transpose(&lde_values)); reverse_index_bits_in_place(&mut leaves); let merkle_tree = timed!(timing, "build Merkle tree", MerkleTree::new(leaves, false)); @@ -80,7 +66,6 @@ impl PolynomialBatchCommitment { Self { polynomials, merkle_tree, - degree, degree_log: log2_strict(degree), rate_bits, blinding, @@ -93,20 +78,23 @@ impl PolynomialBatchCommitment { blinding: bool, ) -> Vec> { let degree = polynomials[0].len(); + + // If blinding, salt with two random elements to each leaf vector. + let salt_size = if blinding { SALT_SIZE } else { 0 }; + polynomials .par_iter() .map(|p| { - assert_eq!(p.len(), degree, "Polynomial degree invalid."); - p.lde(rate_bits).coset_fft(F::coset_shift()).values - }) - .chain(if blinding { - // If blinding, salt with two random elements to each leaf vector. - (0..SALT_SIZE) - .map(|_| F::rand_vec(degree << rate_bits)) - .collect() - } else { - Vec::new() + assert_eq!(p.len(), degree, "Polynomial degrees inconsistent"); + p.lde(rate_bits) + .coset_fft_with_options(F::coset_shift(), Some(rate_bits), None) + .values }) + .chain( + (0..salt_size) + .into_par_iter() + .map(|_| F::rand_vec(degree << rate_bits)), + ) .collect() } @@ -306,7 +294,7 @@ mod tests { let lpcs = (0..4) .map(|i| { - PolynomialBatchCommitment::::new( + PolynomialBatchCommitment::::from_values( gen_random_test_case(ks[i], degree_bits), common_data.config.rate_bits, PlonkPolynomials::polynomials(i).blinding, diff --git a/src/gadgets/arithmetic_extension.rs b/src/gadgets/arithmetic_extension.rs index f210e255..38f583d3 100644 --- a/src/gadgets/arithmetic_extension.rs +++ b/src/gadgets/arithmetic_extension.rs @@ -712,8 +712,8 @@ mod tests { let config = CircuitConfig::large_config(); + let mut pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); - let mut pw = PartialWitness::new(); let vs = FF::rand_vec(3); let ts = builder.add_virtual_extension_targets(3); @@ -749,6 +749,7 @@ mod tests { let config = CircuitConfig::large_config(); + let pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); let x = FF::rand(); @@ -763,7 +764,7 @@ mod tests { builder.assert_equal_extension(zt, comp_zt_unsafe); let data = builder.build(); - let proof = data.prove(PartialWitness::new())?; + let proof = data.prove(pw)?; verify(proof, &data.verifier_only, &data.common) } diff --git a/src/gadgets/insert.rs b/src/gadgets/insert.rs index 72fe032b..bdc8bde7 100644 --- a/src/gadgets/insert.rs +++ b/src/gadgets/insert.rs @@ -64,6 +64,7 @@ mod tests { type FF = QuarticCrandallField; let len = 1 << len_log; let config = CircuitConfig::large_config(); + let pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); let v = (0..len - 1) .map(|_| builder.constant_extension(FF::rand())) @@ -83,7 +84,7 @@ mod tests { } let data = builder.build(); - let proof = data.prove(PartialWitness::new())?; + let proof = data.prove(pw)?; verify(proof, &data.verifier_only, &data.common) } diff --git a/src/gadgets/interpolation.rs b/src/gadgets/interpolation.rs index 36ecf860..92090d90 100644 --- a/src/gadgets/interpolation.rs +++ b/src/gadgets/interpolation.rs @@ -74,6 +74,7 @@ mod tests { type F = CrandallField; type FF = QuarticCrandallField; let config = CircuitConfig::large_config(); + let pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); let len = 4; @@ -103,7 +104,7 @@ mod tests { builder.assert_equal_extension(eval, true_eval_target); let data = builder.build(); - let proof = data.prove(PartialWitness::new())?; + let proof = data.prove(pw)?; verify(proof, &data.verifier_only, &data.common) } @@ -113,6 +114,7 @@ mod tests { type F = CrandallField; type FF = QuarticCrandallField; let config = CircuitConfig::large_config(); + let pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); let len = 2; @@ -137,7 +139,7 @@ mod tests { builder.assert_equal_extension(eval, true_eval_target); let data = builder.build(); - let proof = data.prove(PartialWitness::new())?; + let proof = data.prove(pw)?; verify(proof, &data.verifier_only, &data.common) } diff --git a/src/gadgets/random_access.rs b/src/gadgets/random_access.rs index a435b99f..395d920e 100644 --- a/src/gadgets/random_access.rs +++ b/src/gadgets/random_access.rs @@ -50,6 +50,7 @@ mod tests { type FF = QuarticCrandallField; let len = 1 << len_log; let config = CircuitConfig::large_config(); + let pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); let vec = FF::rand_vec(len); let v: Vec<_> = vec.iter().map(|x| builder.constant_extension(*x)).collect(); @@ -61,7 +62,7 @@ mod tests { } let data = builder.build(); - let proof = data.prove(PartialWitness::new())?; + let proof = data.prove(pw)?; verify(proof, &data.verifier_only, &data.common) } diff --git a/src/gadgets/select.rs b/src/gadgets/select.rs index f1f651dc..58de09c6 100644 --- a/src/gadgets/select.rs +++ b/src/gadgets/select.rs @@ -48,8 +48,8 @@ mod tests { type F = CrandallField; type FF = QuarticCrandallField; let config = CircuitConfig::large_config(); + let mut pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); - let mut pw = PartialWitness::new(); let (x, y) = (FF::rand(), FF::rand()); let xt = builder.add_virtual_extension_target(); diff --git a/src/gadgets/split_base.rs b/src/gadgets/split_base.rs index 0e135c05..9b481e78 100644 --- a/src/gadgets/split_base.rs +++ b/src/gadgets/split_base.rs @@ -99,6 +99,7 @@ mod tests { fn test_split_base() -> Result<()> { type F = CrandallField; let config = CircuitConfig::large_config(); + let pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); let x = F::from_canonical_usize(0b110100000); // 416 = 1532 in base 6. let xt = builder.constant(x); @@ -115,7 +116,7 @@ mod tests { builder.assert_leading_zeros(xt, 64 - 9); let data = builder.build(); - let proof = data.prove(PartialWitness::new())?; + let proof = data.prove(pw)?; verify(proof, &data.verifier_only, &data.common) } @@ -124,9 +125,10 @@ mod tests { fn test_base_sum() -> Result<()> { type F = CrandallField; let config = CircuitConfig::large_config(); + let pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); - let n = thread_rng().gen_range(0, 1 << 10); + let n = thread_rng().gen_range(0..(1 << 10)); let x = builder.constant(F::from_canonical_usize(n)); let zero = builder.zero(); @@ -147,7 +149,7 @@ mod tests { let data = builder.build(); - let proof = data.prove(PartialWitness::new())?; + let proof = data.prove(pw)?; verify(proof, &data.verifier_only, &data.common) } diff --git a/src/gates/gate_testing.rs b/src/gates/gate_testing.rs index f7a17d81..66bed775 100644 --- a/src/gates/gate_testing.rs +++ b/src/gates/gate_testing.rs @@ -124,8 +124,8 @@ pub(crate) fn test_eval_fns, G: Gate, const D: usize>( let constants = F::Extension::rand_vec(gate.num_constants()); let config = CircuitConfig::large_config(); + let mut pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); - let mut pw = PartialWitness::new(); let wires_t = builder.add_virtual_extension_targets(wires.len()); let constants_t = builder.add_virtual_extension_targets(constants.len()); diff --git a/src/gates/gate_tree.rs b/src/gates/gate_tree.rs index 9cf3fe26..30dd01ed 100644 --- a/src/gates/gate_tree.rs +++ b/src/gates/gate_tree.rs @@ -64,9 +64,9 @@ impl, const D: usize> Tree> { gates.sort_unstable_by_key(|g| (-(g.0.degree() as isize), -(g.0.num_constants() as isize))); for max_degree_bits in 1..10 { - // The constraint polynomials are padded to the next power in `compute_vanishig_polys`. - // So we can restrict our search space by setting `max_degree` to a power of 2. - let max_degree = 1 << max_degree_bits; + // The quotient polynomials are padded to the next power of 2 in `compute_quotient_polys`. + // So we can restrict our search space by setting `max_degree` to 1 + a power of 2. + let max_degree = (1 << max_degree_bits) + 1; for max_constants in 1..100 { if let Some(mut best_tree) = Self::find_tree(&gates, max_degree, max_constants) { let mut best_num_constants = best_tree.num_constants(); diff --git a/src/gates/gmimc.rs b/src/gates/gmimc.rs index 31b1b102..003c9ab0 100644 --- a/src/gates/gmimc.rs +++ b/src/gates/gmimc.rs @@ -357,7 +357,7 @@ mod tests { let permutation_inputs = (0..W).map(F::from_canonical_usize).collect::>(); - let mut witness = PartialWitness::new(); + let mut witness = PartialWitness::new(gate.num_wires()); witness.set_wire( Wire { gate: 0, diff --git a/src/hash/merkle_proofs.rs b/src/hash/merkle_proofs.rs index 9af1cb58..30391a98 100644 --- a/src/hash/merkle_proofs.rs +++ b/src/hash/merkle_proofs.rs @@ -154,14 +154,14 @@ mod tests { fn test_recursive_merkle_proof() -> Result<()> { type F = CrandallField; let config = CircuitConfig::large_config(); + let mut pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); - let mut pw = PartialWitness::new(); let log_n = 8; let n = 1 << log_n; let leaves = random_data::(n, 7); let tree = MerkleTree::new(leaves, false); - let i: usize = thread_rng().gen_range(0, n); + let i: usize = thread_rng().gen_range(0..n); let proof = tree.prove(i); let proof_t = MerkleProofTarget { diff --git a/src/iop/challenger.rs b/src/iop/challenger.rs index 72314048..1e41ecea 100644 --- a/src/iop/challenger.rs +++ b/src/iop/challenger.rs @@ -399,6 +399,7 @@ mod tests { num_routed_wires: 27, ..CircuitConfig::default() }; + let mut witness = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config.clone()); let mut recursive_challenger = RecursiveChallenger::new(&mut builder); let mut recursive_outputs_per_round: Vec> = Vec::new(); @@ -409,7 +410,6 @@ mod tests { ); } let circuit = builder.build(); - let mut witness = PartialWitness::new(); generate_partial_witness( &mut witness, &circuit.prover_only.generators, diff --git a/src/iop/witness.rs b/src/iop/witness.rs index 5b97f546..49950a72 100644 --- a/src/iop/witness.rs +++ b/src/iop/witness.rs @@ -26,22 +26,23 @@ impl Witness { #[derive(Clone, Debug)] pub struct PartialWitness { - pub(crate) target_values: HashMap, + pub(crate) wire_values: Vec>>, + pub(crate) virtual_target_values: Vec>, } impl PartialWitness { - pub fn new() -> Self { + pub fn new(num_wires: usize) -> Self { PartialWitness { - target_values: HashMap::new(), + wire_values: vec![vec![None; num_wires]], + virtual_target_values: vec![], } } - pub fn is_empty(&self) -> bool { - self.target_values.is_empty() - } - pub fn get_target(&self, target: Target) -> F { - self.target_values[&target] + match target { + Target::Wire(Wire { gate, input }) => self.wire_values[gate][input].unwrap(), + Target::VirtualTarget { index } => self.virtual_target_values[index].unwrap(), + } } pub fn get_targets(&self, targets: &[Target]) -> Vec { @@ -76,7 +77,10 @@ impl PartialWitness { } pub fn try_get_target(&self, target: Target) -> Option { - self.target_values.get(&target).cloned() + match target { + Target::Wire(Wire { gate, input }) => self.wire_values[gate][input], + Target::VirtualTarget { index } => self.virtual_target_values[index], + } } pub fn get_wire(&self, wire: Wire) -> F { @@ -88,7 +92,15 @@ impl PartialWitness { } pub fn contains(&self, target: Target) -> bool { - self.target_values.contains_key(&target) + match target { + Target::Wire(Wire { gate, input }) => { + self.wire_values.len() > gate && self.wire_values[gate][input].is_some() + } + Target::VirtualTarget { index } => { + self.virtual_target_values.len() > index + && self.virtual_target_values[index].is_some() + } + } } pub fn contains_all(&self, targets: &[Target]) -> bool { @@ -96,13 +108,36 @@ impl PartialWitness { } pub fn set_target(&mut self, target: Target, value: F) { - let opt_old_value = self.target_values.insert(target, value); - if let Some(old_value) = opt_old_value { - assert_eq!( - old_value, value, - "Target was set twice with different values: {:?}", - target - ); + match target { + Target::Wire(Wire { gate, input }) => { + if gate >= self.wire_values.len() { + self.wire_values + .resize(gate + 1, vec![None; self.wire_values[0].len()]); + } + if let Some(old_value) = self.wire_values[gate][input] { + assert_eq!( + old_value, value, + "Target was set twice with different values: {:?}", + target + ); + } else { + self.wire_values[gate][input] = Some(value); + } + } + Target::VirtualTarget { index } => { + if index >= self.virtual_target_values.len() { + self.virtual_target_values.resize(index + 1, None); + } + if let Some(old_value) = self.virtual_target_values[index] { + assert_eq!( + old_value, value, + "Target was set twice with different values: {:?}", + target + ); + } else { + self.virtual_target_values[index] = Some(value); + } + } } } @@ -162,16 +197,19 @@ impl PartialWitness { } pub fn extend>(&mut self, pairs: I) { - self.target_values.extend(pairs); + for (t, v) in pairs { + self.set_target(t, v); + } } pub fn full_witness(self, degree: usize, num_wires: usize) -> Witness { let mut wire_values = vec![vec![F::ZERO; degree]; num_wires]; - self.target_values.into_iter().for_each(|(t, v)| { - if let Target::Wire(Wire { gate, input }) = t { - wire_values[input][gate] = v; + assert!(self.wire_values.len() <= degree); + for i in 0..self.wire_values.len() { + for j in 0..num_wires { + wire_values[j][i] = self.wire_values[i][j].unwrap_or(F::ZERO); } - }); + } Witness { wire_values } } @@ -212,9 +250,3 @@ impl PartialWitness { Ok(()) } } - -impl Default for PartialWitness { - fn default() -> Self { - Self::new() - } -} diff --git a/src/plonk/circuit_builder.rs b/src/plonk/circuit_builder.rs index f4eaa881..0a6c0d06 100644 --- a/src/plonk/circuit_builder.rs +++ b/src/plonk/circuit_builder.rs @@ -506,7 +506,6 @@ impl, const D: usize> CircuitBuilder { /// Builds a "full circuit", with both prover and verifier data. pub fn build(mut self) -> CircuitData { let mut timing = TimingTree::new("preprocess", Level::Trace); - let quotient_degree_factor = 7; // TODO: add this as a parameter. let start = Instant::now(); // Hash the public inputs, and route them to a `PublicInputGate` which will enforce that @@ -541,10 +540,13 @@ impl, const D: usize> CircuitBuilder { let gates = self.gates.iter().cloned().collect(); let (gate_tree, max_filtered_constraint_degree, num_constants) = Tree::from_gates(gates); - assert!( - max_filtered_constraint_degree <= quotient_degree_factor + 1, - "Constraints are too high degree." - ); + // `quotient_degree_factor` has to be between `max_filtered_constraint_degree-1` and `1<, const D: usize> CircuitBuilder { let sigma_vecs = self.sigma_vecs(&k_is, &subgroup); let constants_sigmas_vecs = [constant_vecs, sigma_vecs.clone()].concat(); - let constants_sigmas_commitment = PolynomialBatchCommitment::new( + let constants_sigmas_commitment = PolynomialBatchCommitment::from_values( constants_sigmas_vecs, self.config.rate_bits, self.config.zero_knowledge & PlonkPolynomials::CONSTANTS_SIGMAS.blinding, diff --git a/src/plonk/prover.rs b/src/plonk/prover.rs index de85d94b..27ba31c5 100644 --- a/src/plonk/prover.rs +++ b/src/plonk/prover.rs @@ -81,7 +81,7 @@ pub(crate) fn prove, const D: usize>( let wires_commitment = timed!( timing, "compute wires commitment", - PolynomialBatchCommitment::new( + PolynomialBatchCommitment::from_values( wires_values, config.rate_bits, config.zero_knowledge & PlonkPolynomials::WIRES.blinding, @@ -125,7 +125,7 @@ pub(crate) fn prove, const D: usize>( let zs_partial_products_commitment = timed!( timing, "commit to Z's", - PolynomialBatchCommitment::new( + PolynomialBatchCommitment::from_values( zs_partial_products, config.rate_bits, config.zero_knowledge & PlonkPolynomials::ZS_PARTIAL_PRODUCTS.blinding, @@ -173,7 +173,7 @@ pub(crate) fn prove, const D: usize>( let quotient_polys_commitment = timed!( timing, "commit to quotient polys", - PolynomialBatchCommitment::new_from_polys( + PolynomialBatchCommitment::from_coeffs( all_quotient_poly_chunks, config.rate_bits, config.zero_knowledge & PlonkPolynomials::QUOTIENT.blinding, @@ -332,7 +332,7 @@ fn compute_quotient_polys<'a, F: Extendable, const D: usize>( alphas: &[F], ) -> Vec> { let num_challenges = common_data.config.num_challenges; - let max_degree_bits = log2_ceil(common_data.quotient_degree_factor + 1); + let max_degree_bits = log2_ceil(common_data.quotient_degree_factor); assert!( max_degree_bits <= common_data.config.rate_bits, "Having constraints of degree higher than the rate is not supported yet. \ diff --git a/src/plonk/recursive_verifier.rs b/src/plonk/recursive_verifier.rs index 1e467bc9..ee5f82b9 100644 --- a/src/plonk/recursive_verifier.rs +++ b/src/plonk/recursive_verifier.rs @@ -383,7 +383,7 @@ mod tests { } let data = builder.build(); ( - data.prove(PartialWitness::new())?, + data.prove(PartialWitness::new(config.num_wires))?, data.verifier_only, data.common, ) @@ -391,7 +391,7 @@ mod tests { verify(proof_with_pis.clone(), &vd, &cd)?; let mut builder = CircuitBuilder::::new(config.clone()); - let mut pw = PartialWitness::new(); + let mut pw = PartialWitness::new(config.num_wires); let pt = proof_to_proof_target(&proof_with_pis, &mut builder); set_proof_target(&proof_with_pis, &pt, &mut pw); @@ -438,7 +438,7 @@ mod tests { } let data = builder.build(); ( - data.prove(PartialWitness::new())?, + data.prove(PartialWitness::new(config.num_wires))?, data.verifier_only, data.common, ) @@ -446,7 +446,7 @@ mod tests { verify(proof_with_pis.clone(), &vd, &cd)?; let mut builder = CircuitBuilder::::new(config.clone()); - let mut pw = PartialWitness::new(); + let mut pw = PartialWitness::new(config.num_wires); let pt = proof_to_proof_target(&proof_with_pis, &mut builder); set_proof_target(&proof_with_pis, &pt, &mut pw); @@ -464,7 +464,7 @@ mod tests { verify(proof_with_pis.clone(), &vd, &cd)?; let mut builder = CircuitBuilder::::new(config.clone()); - let mut pw = PartialWitness::new(); + let mut pw = PartialWitness::new(config.num_wires); let pt = proof_to_proof_target(&proof_with_pis, &mut builder); set_proof_target(&proof_with_pis, &pt, &mut pw); diff --git a/src/polynomial/polynomial.rs b/src/polynomial/polynomial.rs index f69602d5..4e15be56 100644 --- a/src/polynomial/polynomial.rs +++ b/src/polynomial/polynomial.rs @@ -6,6 +6,7 @@ use anyhow::{ensure, Result}; use serde::{Deserialize, Serialize}; use crate::field::extension_field::{Extendable, FieldExtension}; +use crate::field::fft::FftRootTable; use crate::field::fft::{fft, fft_with_options, ifft}; use crate::field::field_types::Field; use crate::util::log2_strict; @@ -198,15 +199,33 @@ impl PolynomialCoeffs { fft(self) } + pub fn fft_with_options( + &self, + zero_factor: Option, + root_table: Option>, + ) -> PolynomialValues { + fft_with_options(self, zero_factor, root_table) + } + /// Returns the evaluation of the polynomial on the coset `shift*H`. pub fn coset_fft(&self, shift: F) -> PolynomialValues { + self.coset_fft_with_options(shift, None, None) + } + + /// Returns the evaluation of the polynomial on the coset `shift*H`. + pub fn coset_fft_with_options( + &self, + shift: F, + zero_factor: Option, + root_table: Option>, + ) -> PolynomialValues { let modified_poly: Self = shift .powers() .zip(&self.coeffs) .map(|(r, &c)| r * c) .collect::>() .into(); - modified_poly.fft() + modified_poly.fft_with_options(zero_factor, root_table) } pub fn to_extension(&self) -> PolynomialCoeffs @@ -434,7 +453,7 @@ mod tests { fn test_polynomial_multiplication() { type F = CrandallField; let mut rng = thread_rng(); - let (a_deg, b_deg) = (rng.gen_range(1, 10_000), rng.gen_range(1, 10_000)); + let (a_deg, b_deg) = (rng.gen_range(1..10_000), rng.gen_range(1..10_000)); let a = PolynomialCoeffs::new(F::rand_vec(a_deg)); let b = PolynomialCoeffs::new(F::rand_vec(b_deg)); let m1 = &a * &b; @@ -450,8 +469,8 @@ mod tests { fn test_inv_mod_xn() { type F = CrandallField; let mut rng = thread_rng(); - let a_deg = rng.gen_range(1, 1_000); - let n = rng.gen_range(1, 1_000); + let a_deg = rng.gen_range(1..1_000); + let n = rng.gen_range(1..1_000); let a = PolynomialCoeffs::new(F::rand_vec(a_deg)); let b = a.inv_mod_xn(n); let mut m = &a * &b; @@ -472,7 +491,7 @@ mod tests { fn test_polynomial_long_division() { type F = CrandallField; let mut rng = thread_rng(); - let (a_deg, b_deg) = (rng.gen_range(1, 10_000), rng.gen_range(1, 10_000)); + let (a_deg, b_deg) = (rng.gen_range(1..10_000), rng.gen_range(1..10_000)); let a = PolynomialCoeffs::new(F::rand_vec(a_deg)); let b = PolynomialCoeffs::new(F::rand_vec(b_deg)); let (q, r) = a.div_rem_long_division(&b); @@ -486,7 +505,7 @@ mod tests { fn test_polynomial_division() { type F = CrandallField; let mut rng = thread_rng(); - let (a_deg, b_deg) = (rng.gen_range(1, 10_000), rng.gen_range(1, 10_000)); + let (a_deg, b_deg) = (rng.gen_range(1..10_000), rng.gen_range(1..10_000)); let a = PolynomialCoeffs::new(F::rand_vec(a_deg)); let b = PolynomialCoeffs::new(F::rand_vec(b_deg)); let (q, r) = a.div_rem(&b); @@ -500,7 +519,7 @@ mod tests { fn test_polynomial_division_by_constant() { type F = CrandallField; let mut rng = thread_rng(); - let a_deg = rng.gen_range(1, 10_000); + let a_deg = rng.gen_range(1..10_000); let a = PolynomialCoeffs::new(F::rand_vec(a_deg)); let b = PolynomialCoeffs::from(vec![F::rand()]); let (q, r) = a.div_rem(&b); @@ -514,8 +533,8 @@ mod tests { fn test_division_by_z_h() { type F = CrandallField; let mut rng = thread_rng(); - let a_deg = rng.gen_range(1, 10_000); - let n = rng.gen_range(1, a_deg); + let a_deg = rng.gen_range(1..10_000); + let n = rng.gen_range(1..a_deg); let mut a = PolynomialCoeffs::new(F::rand_vec(a_deg)); a.trim(); let z_h = { @@ -554,7 +573,7 @@ mod tests { PolynomialCoeffs::new(xn_min_one_vec) }; - let a = g.exp(rng.gen_range(0, n as u64)); + let a = g.exp(rng.gen_range(0..(n as u64))); let denom = PolynomialCoeffs::new(vec![-a, F::ONE]); let now = Instant::now(); xn_minus_one.div_rem(&denom); diff --git a/src/util/reducing.rs b/src/util/reducing.rs index be95f67a..ce6827ba 100644 --- a/src/util/reducing.rs +++ b/src/util/reducing.rs @@ -249,6 +249,7 @@ mod tests { let config = CircuitConfig::large_config(); + let pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); let alpha = FF::rand(); @@ -264,7 +265,7 @@ mod tests { builder.assert_equal_extension(manual_reduce, circuit_reduce); let data = builder.build(); - let proof = data.prove(PartialWitness::new())?; + let proof = data.prove(pw)?; verify(proof, &data.verifier_only, &data.common) } @@ -276,6 +277,7 @@ mod tests { let config = CircuitConfig::large_config(); + let pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); let alpha = FF::rand(); @@ -294,7 +296,7 @@ mod tests { builder.assert_equal_extension(manual_reduce, circuit_reduce); let data = builder.build(); - let proof = data.prove(PartialWitness::new())?; + let proof = data.prove(pw)?; verify(proof, &data.verifier_only, &data.common) }