From 7d11d0f8a1f83b5e885caee2bd53fef25064bdad Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Fri, 6 Aug 2021 14:58:39 +0200 Subject: [PATCH 01/10] Change PartialWitness to use `Vec`s --- src/bin/bench_recursion.rs | 2 +- src/gadgets/arithmetic_extension.rs | 4 +- src/gadgets/insert.rs | 2 +- src/gadgets/interpolation.rs | 4 +- src/gadgets/random_access.rs | 2 +- src/gadgets/select.rs | 2 +- src/gadgets/split_base.rs | 4 +- src/gates/gate_testing.rs | 2 +- src/gates/gmimc.rs | 2 +- src/hash/merkle_proofs.rs | 2 +- src/iop/challenger.rs | 2 +- src/iop/witness.rs | 71 +++++++++++++++++++---------- src/plonk/recursive_verifier.rs | 10 ++-- src/util/reducing.rs | 4 +- 14 files changed, 69 insertions(+), 44 deletions(-) diff --git a/src/bin/bench_recursion.rs b/src/bin/bench_recursion.rs index 59cdf4a6..59ee2646 100644 --- a/src/bin/bench_recursion.rs +++ b/src/bin/bench_recursion.rs @@ -49,7 +49,7 @@ fn bench_prove, const D: usize>() -> Result<()> { builder.add_extension(zero_ext, zero_ext); let circuit = builder.build(); - let inputs = PartialWitness::new(); + let inputs = PartialWitness::new(0, 0, 0); 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/gadgets/arithmetic_extension.rs b/src/gadgets/arithmetic_extension.rs index d76dab9d..ad7519ea 100644 --- a/src/gadgets/arithmetic_extension.rs +++ b/src/gadgets/arithmetic_extension.rs @@ -604,7 +604,7 @@ mod tests { let config = CircuitConfig::large_config(); let mut builder = CircuitBuilder::::new(config); - let mut pw = PartialWitness::new(); + let mut pw = PartialWitness::new(0, 0, 0); let vs = FF::rand_vec(3); let ts = builder.add_virtual_extension_targets(3); @@ -654,7 +654,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(PartialWitness::new(0, 0, 0))?; verify(proof, &data.verifier_only, &data.common) } diff --git a/src/gadgets/insert.rs b/src/gadgets/insert.rs index 72fe032b..37a1d302 100644 --- a/src/gadgets/insert.rs +++ b/src/gadgets/insert.rs @@ -83,7 +83,7 @@ mod tests { } let data = builder.build(); - let proof = data.prove(PartialWitness::new())?; + let proof = data.prove(PartialWitness::new(0, 0, 0))?; verify(proof, &data.verifier_only, &data.common) } diff --git a/src/gadgets/interpolation.rs b/src/gadgets/interpolation.rs index cc547d88..12b694d9 100644 --- a/src/gadgets/interpolation.rs +++ b/src/gadgets/interpolation.rs @@ -99,7 +99,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(PartialWitness::new(0, 0, 0))?; verify(proof, &data.verifier_only, &data.common) } @@ -133,7 +133,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(PartialWitness::new(0, 0, 0))?; verify(proof, &data.verifier_only, &data.common) } diff --git a/src/gadgets/random_access.rs b/src/gadgets/random_access.rs index a435b99f..493a1ecc 100644 --- a/src/gadgets/random_access.rs +++ b/src/gadgets/random_access.rs @@ -61,7 +61,7 @@ mod tests { } let data = builder.build(); - let proof = data.prove(PartialWitness::new())?; + let proof = data.prove(PartialWitness::new(0, 0, 0))?; verify(proof, &data.verifier_only, &data.common) } diff --git a/src/gadgets/select.rs b/src/gadgets/select.rs index f1f651dc..ed78eee5 100644 --- a/src/gadgets/select.rs +++ b/src/gadgets/select.rs @@ -49,7 +49,7 @@ mod tests { type FF = QuarticCrandallField; let config = CircuitConfig::large_config(); let mut builder = CircuitBuilder::::new(config); - let mut pw = PartialWitness::new(); + let mut pw = PartialWitness::new(0, 0, 0); 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..c579213d 100644 --- a/src/gadgets/split_base.rs +++ b/src/gadgets/split_base.rs @@ -115,7 +115,7 @@ mod tests { builder.assert_leading_zeros(xt, 64 - 9); let data = builder.build(); - let proof = data.prove(PartialWitness::new())?; + let proof = data.prove(PartialWitness::new(0, 0, 0))?; verify(proof, &data.verifier_only, &data.common) } @@ -147,7 +147,7 @@ mod tests { let data = builder.build(); - let proof = data.prove(PartialWitness::new())?; + let proof = data.prove(PartialWitness::new(0, 0, 0))?; verify(proof, &data.verifier_only, &data.common) } diff --git a/src/gates/gate_testing.rs b/src/gates/gate_testing.rs index f7a17d81..6c27e76d 100644 --- a/src/gates/gate_testing.rs +++ b/src/gates/gate_testing.rs @@ -125,7 +125,7 @@ pub(crate) fn test_eval_fns, G: Gate, const D: usize>( let config = CircuitConfig::large_config(); let mut builder = CircuitBuilder::::new(config); - let mut pw = PartialWitness::new(); + let mut pw = PartialWitness::new(0, 0, 0); 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/gmimc.rs b/src/gates/gmimc.rs index 73fcc190..a6c74e91 100644 --- a/src/gates/gmimc.rs +++ b/src/gates/gmimc.rs @@ -345,7 +345,7 @@ mod tests { let permutation_inputs = (0..W).map(F::from_canonical_usize).collect::>(); - let mut witness = PartialWitness::new(); + let mut witness = PartialWitness::new(0, 0, 0); witness.set_wire( Wire { gate: 0, diff --git a/src/hash/merkle_proofs.rs b/src/hash/merkle_proofs.rs index 9af1cb58..2b5fae13 100644 --- a/src/hash/merkle_proofs.rs +++ b/src/hash/merkle_proofs.rs @@ -155,7 +155,7 @@ mod tests { type F = CrandallField; let config = CircuitConfig::large_config(); let mut builder = CircuitBuilder::::new(config); - let mut pw = PartialWitness::new(); + let mut pw = PartialWitness::new(0, 0, 0); let log_n = 8; let n = 1 << log_n; diff --git a/src/iop/challenger.rs b/src/iop/challenger.rs index 886fb09e..cfffc79f 100644 --- a/src/iop/challenger.rs +++ b/src/iop/challenger.rs @@ -409,7 +409,7 @@ mod tests { ); } let circuit = builder.build(); - let mut witness = PartialWitness::new(); + let mut witness = PartialWitness::new(0, 0, 0); generate_partial_witness( &mut witness, &circuit.prover_only.generators, diff --git a/src/iop/witness.rs b/src/iop/witness.rs index 5b97f546..1eabad4b 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(degree: usize, num_wires: usize, max_virtual_target: usize) -> Self { PartialWitness { - target_values: HashMap::new(), + wire_values: vec![vec![None; num_wires]; degree], + virtual_target_values: vec![None; max_virtual_target], } } - 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,10 @@ 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[gate][input].is_some(), + Target::VirtualTarget { index } => self.virtual_target_values[index].is_some(), + } } pub fn contains_all(&self, targets: &[Target]) -> bool { @@ -96,13 +103,29 @@ 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 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 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 +185,18 @@ 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; + for i in 0..degree { + for j in 0..num_wires { + wire_values[j][i] = self.wire_values[i][j].unwrap_or(F::ZERO); } - }); + } Witness { wire_values } } @@ -215,6 +240,6 @@ impl PartialWitness { impl Default for PartialWitness { fn default() -> Self { - Self::new() + Self::new(0, 0, 0) } } diff --git a/src/plonk/recursive_verifier.rs b/src/plonk/recursive_verifier.rs index 773a695e..e21eec98 100644 --- a/src/plonk/recursive_verifier.rs +++ b/src/plonk/recursive_verifier.rs @@ -387,7 +387,7 @@ mod tests { } let data = builder.build(); ( - data.prove(PartialWitness::new())?, + data.prove(PartialWitness::new(0, 0, 0))?, data.verifier_only, data.common, ) @@ -395,7 +395,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(0, 0, 0); let pt = proof_to_proof_target(&proof_with_pis, &mut builder); set_proof_target(&proof_with_pis, &pt, &mut pw); @@ -442,7 +442,7 @@ mod tests { } let data = builder.build(); ( - data.prove(PartialWitness::new())?, + data.prove(PartialWitness::new(1 << 14, config.num_wires, 1000))?, data.verifier_only, data.common, ) @@ -450,7 +450,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(1 << 14, config.num_wires, 100000); let pt = proof_to_proof_target(&proof_with_pis, &mut builder); set_proof_target(&proof_with_pis, &pt, &mut pw); @@ -468,7 +468,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(1 << 14, config.num_wires, 100000); let pt = proof_to_proof_target(&proof_with_pis, &mut builder); set_proof_target(&proof_with_pis, &pt, &mut pw); diff --git a/src/util/reducing.rs b/src/util/reducing.rs index be95f67a..001783fd 100644 --- a/src/util/reducing.rs +++ b/src/util/reducing.rs @@ -264,7 +264,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(PartialWitness::new(0, 0, 0))?; verify(proof, &data.verifier_only, &data.common) } @@ -294,7 +294,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(PartialWitness::new(0, 0, 0))?; verify(proof, &data.verifier_only, &data.common) } From db236e482462f8d7b00853e1affa79f882b9d6b5 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Fri, 6 Aug 2021 15:14:38 +0200 Subject: [PATCH 02/10] Fix tests --- src/bin/bench_recursion.rs | 2 +- src/gadgets/arithmetic_extension.rs | 5 +++-- src/gadgets/insert.rs | 3 ++- src/gadgets/interpolation.rs | 6 ++++-- src/gadgets/random_access.rs | 3 ++- src/gadgets/select.rs | 2 +- src/gadgets/split_base.rs | 6 ++++-- src/gates/gate_testing.rs | 2 +- src/gates/gmimc.rs | 2 +- src/hash/merkle_proofs.rs | 2 +- src/iop/challenger.rs | 2 +- src/plonk/recursive_verifier.rs | 4 ++-- src/util/reducing.rs | 6 ++++-- 13 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/bin/bench_recursion.rs b/src/bin/bench_recursion.rs index 59ee2646..4a535d20 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(1 << 14, config.num_wires, 1000); 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(0, 0, 0); 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/gadgets/arithmetic_extension.rs b/src/gadgets/arithmetic_extension.rs index ad7519ea..15f1de9b 100644 --- a/src/gadgets/arithmetic_extension.rs +++ b/src/gadgets/arithmetic_extension.rs @@ -603,8 +603,8 @@ mod tests { let config = CircuitConfig::large_config(); + let mut pw = PartialWitness::new(1 << 14, config.num_wires, 1000); let mut builder = CircuitBuilder::::new(config); - let mut pw = PartialWitness::new(0, 0, 0); let vs = FF::rand_vec(3); let ts = builder.add_virtual_extension_targets(3); @@ -640,6 +640,7 @@ mod tests { let config = CircuitConfig::large_config(); + let pw = PartialWitness::new(1 << 14, config.num_wires, 1000); let mut builder = CircuitBuilder::::new(config); let x = FF::rand(); @@ -654,7 +655,7 @@ mod tests { builder.assert_equal_extension(zt, comp_zt_unsafe); let data = builder.build(); - let proof = data.prove(PartialWitness::new(0, 0, 0))?; + 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 37a1d302..bc91a013 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(1 << 14, config.num_wires, 1000); 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(0, 0, 0))?; + 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 12b694d9..bba3befe 100644 --- a/src/gadgets/interpolation.rs +++ b/src/gadgets/interpolation.rs @@ -70,6 +70,7 @@ mod tests { type F = CrandallField; type FF = QuarticCrandallField; let config = CircuitConfig::large_config(); + let pw = PartialWitness::new(1 << 14, config.num_wires, 1000); let mut builder = CircuitBuilder::::new(config); let len = 4; @@ -99,7 +100,7 @@ mod tests { builder.assert_equal_extension(eval, true_eval_target); let data = builder.build(); - let proof = data.prove(PartialWitness::new(0, 0, 0))?; + let proof = data.prove(pw)?; verify(proof, &data.verifier_only, &data.common) } @@ -109,6 +110,7 @@ mod tests { type F = CrandallField; type FF = QuarticCrandallField; let config = CircuitConfig::large_config(); + let pw = PartialWitness::new(1 << 14, config.num_wires, 1000); let mut builder = CircuitBuilder::::new(config); let len = 2; @@ -133,7 +135,7 @@ mod tests { builder.assert_equal_extension(eval, true_eval_target); let data = builder.build(); - let proof = data.prove(PartialWitness::new(0, 0, 0))?; + 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 493a1ecc..36b15e5b 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(1 << 14, config.num_wires, 1000); 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(0, 0, 0))?; + 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 ed78eee5..ce9eed58 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(1 << 14, config.num_wires, 1000); let mut builder = CircuitBuilder::::new(config); - let mut pw = PartialWitness::new(0, 0, 0); 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 c579213d..af67d99c 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(1 << 14, config.num_wires, 1000); 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(0, 0, 0))?; + let proof = data.prove(pw)?; verify(proof, &data.verifier_only, &data.common) } @@ -124,6 +125,7 @@ mod tests { fn test_base_sum() -> Result<()> { type F = CrandallField; let config = CircuitConfig::large_config(); + let pw = PartialWitness::new(1 << 14, config.num_wires, 1000); let mut builder = CircuitBuilder::::new(config); let n = thread_rng().gen_range(0, 1 << 10); @@ -147,7 +149,7 @@ mod tests { let data = builder.build(); - let proof = data.prove(PartialWitness::new(0, 0, 0))?; + 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 6c27e76d..00632d49 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(1 << 14, config.num_wires, 1000); let mut builder = CircuitBuilder::::new(config); - let mut pw = PartialWitness::new(0, 0, 0); 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/gmimc.rs b/src/gates/gmimc.rs index a6c74e91..56c4451b 100644 --- a/src/gates/gmimc.rs +++ b/src/gates/gmimc.rs @@ -345,7 +345,7 @@ mod tests { let permutation_inputs = (0..W).map(F::from_canonical_usize).collect::>(); - let mut witness = PartialWitness::new(0, 0, 0); + let mut witness = PartialWitness::new(1 << 14, 126, 1000); witness.set_wire( Wire { gate: 0, diff --git a/src/hash/merkle_proofs.rs b/src/hash/merkle_proofs.rs index 2b5fae13..139ab0bc 100644 --- a/src/hash/merkle_proofs.rs +++ b/src/hash/merkle_proofs.rs @@ -154,8 +154,8 @@ mod tests { fn test_recursive_merkle_proof() -> Result<()> { type F = CrandallField; let config = CircuitConfig::large_config(); + let mut pw = PartialWitness::new(1 << 14, config.num_wires, 1000); let mut builder = CircuitBuilder::::new(config); - let mut pw = PartialWitness::new(0, 0, 0); let log_n = 8; let n = 1 << log_n; diff --git a/src/iop/challenger.rs b/src/iop/challenger.rs index cfffc79f..d5ae05f5 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(1 << 14, config.num_wires, 1000); let mut builder = CircuitBuilder::::new(config); 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(0, 0, 0); generate_partial_witness( &mut witness, &circuit.prover_only.generators, diff --git a/src/plonk/recursive_verifier.rs b/src/plonk/recursive_verifier.rs index e21eec98..a52020d9 100644 --- a/src/plonk/recursive_verifier.rs +++ b/src/plonk/recursive_verifier.rs @@ -387,7 +387,7 @@ mod tests { } let data = builder.build(); ( - data.prove(PartialWitness::new(0, 0, 0))?, + data.prove(PartialWitness::new(1 << 14, config.num_wires, 1000))?, data.verifier_only, data.common, ) @@ -395,7 +395,7 @@ mod tests { verify(proof_with_pis.clone(), &vd, &cd)?; let mut builder = CircuitBuilder::::new(config.clone()); - let mut pw = PartialWitness::new(0, 0, 0); + let mut pw = PartialWitness::new(1 << 14, config.num_wires, 1000); let pt = proof_to_proof_target(&proof_with_pis, &mut builder); set_proof_target(&proof_with_pis, &pt, &mut pw); diff --git a/src/util/reducing.rs b/src/util/reducing.rs index 001783fd..47386e75 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(1 << 14, config.num_wires, 1000); 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(0, 0, 0))?; + 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(1 << 14, config.num_wires, 1000); 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(0, 0, 0))?; + let proof = data.prove(pw)?; verify(proof, &data.verifier_only, &data.common) } From dd076e5c732b6ee284ef9bd2c45cef390dd5d0cc Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 9 Aug 2021 09:58:09 +0200 Subject: [PATCH 03/10] Auto resize partial witness --- src/bin/bench_recursion.rs | 2 +- src/gadgets/arithmetic_extension.rs | 4 ++-- src/gadgets/insert.rs | 2 +- src/gadgets/interpolation.rs | 4 ++-- src/gadgets/random_access.rs | 2 +- src/gadgets/select.rs | 2 +- src/gadgets/split_base.rs | 4 ++-- src/gates/gate_testing.rs | 2 +- src/gates/gmimc.rs | 2 +- src/hash/merkle_proofs.rs | 2 +- src/iop/challenger.rs | 2 +- src/iop/witness.rs | 30 +++++++++++++++++------------ src/plonk/recursive_verifier.rs | 10 +++++----- src/util/reducing.rs | 4 ++-- 14 files changed, 39 insertions(+), 33 deletions(-) diff --git a/src/bin/bench_recursion.rs b/src/bin/bench_recursion.rs index 4a535d20..3b71c6f4 100644 --- a/src/bin/bench_recursion.rs +++ b/src/bin/bench_recursion.rs @@ -34,7 +34,7 @@ fn bench_prove, const D: usize>() -> Result<()> { }, }; - let inputs = PartialWitness::new(1 << 14, config.num_wires, 1000); + let inputs = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); let zero = builder.zero(); diff --git a/src/gadgets/arithmetic_extension.rs b/src/gadgets/arithmetic_extension.rs index 15f1de9b..29b759fb 100644 --- a/src/gadgets/arithmetic_extension.rs +++ b/src/gadgets/arithmetic_extension.rs @@ -603,7 +603,7 @@ mod tests { let config = CircuitConfig::large_config(); - let mut pw = PartialWitness::new(1 << 14, config.num_wires, 1000); + let mut pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); let vs = FF::rand_vec(3); @@ -640,7 +640,7 @@ mod tests { let config = CircuitConfig::large_config(); - let pw = PartialWitness::new(1 << 14, config.num_wires, 1000); + let pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); let x = FF::rand(); diff --git a/src/gadgets/insert.rs b/src/gadgets/insert.rs index bc91a013..bdc8bde7 100644 --- a/src/gadgets/insert.rs +++ b/src/gadgets/insert.rs @@ -64,7 +64,7 @@ mod tests { type FF = QuarticCrandallField; let len = 1 << len_log; let config = CircuitConfig::large_config(); - let pw = PartialWitness::new(1 << 14, config.num_wires, 1000); + let pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); let v = (0..len - 1) .map(|_| builder.constant_extension(FF::rand())) diff --git a/src/gadgets/interpolation.rs b/src/gadgets/interpolation.rs index bba3befe..8ed5346a 100644 --- a/src/gadgets/interpolation.rs +++ b/src/gadgets/interpolation.rs @@ -70,7 +70,7 @@ mod tests { type F = CrandallField; type FF = QuarticCrandallField; let config = CircuitConfig::large_config(); - let pw = PartialWitness::new(1 << 14, config.num_wires, 1000); + let pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); let len = 4; @@ -110,7 +110,7 @@ mod tests { type F = CrandallField; type FF = QuarticCrandallField; let config = CircuitConfig::large_config(); - let pw = PartialWitness::new(1 << 14, config.num_wires, 1000); + let pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); let len = 2; diff --git a/src/gadgets/random_access.rs b/src/gadgets/random_access.rs index 36b15e5b..395d920e 100644 --- a/src/gadgets/random_access.rs +++ b/src/gadgets/random_access.rs @@ -50,7 +50,7 @@ mod tests { type FF = QuarticCrandallField; let len = 1 << len_log; let config = CircuitConfig::large_config(); - let pw = PartialWitness::new(1 << 14, config.num_wires, 1000); + 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(); diff --git a/src/gadgets/select.rs b/src/gadgets/select.rs index ce9eed58..58de09c6 100644 --- a/src/gadgets/select.rs +++ b/src/gadgets/select.rs @@ -48,7 +48,7 @@ mod tests { type F = CrandallField; type FF = QuarticCrandallField; let config = CircuitConfig::large_config(); - let mut pw = PartialWitness::new(1 << 14, config.num_wires, 1000); + let mut pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); let (x, y) = (FF::rand(), FF::rand()); diff --git a/src/gadgets/split_base.rs b/src/gadgets/split_base.rs index af67d99c..ff420ba0 100644 --- a/src/gadgets/split_base.rs +++ b/src/gadgets/split_base.rs @@ -99,7 +99,7 @@ mod tests { fn test_split_base() -> Result<()> { type F = CrandallField; let config = CircuitConfig::large_config(); - let pw = PartialWitness::new(1 << 14, config.num_wires, 1000); + 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); @@ -125,7 +125,7 @@ mod tests { fn test_base_sum() -> Result<()> { type F = CrandallField; let config = CircuitConfig::large_config(); - let pw = PartialWitness::new(1 << 14, config.num_wires, 1000); + let pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); let n = thread_rng().gen_range(0, 1 << 10); diff --git a/src/gates/gate_testing.rs b/src/gates/gate_testing.rs index 00632d49..66bed775 100644 --- a/src/gates/gate_testing.rs +++ b/src/gates/gate_testing.rs @@ -124,7 +124,7 @@ 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(1 << 14, config.num_wires, 1000); + let mut pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); let wires_t = builder.add_virtual_extension_targets(wires.len()); diff --git a/src/gates/gmimc.rs b/src/gates/gmimc.rs index 46c7b975..03fdef56 100644 --- a/src/gates/gmimc.rs +++ b/src/gates/gmimc.rs @@ -345,7 +345,7 @@ mod tests { let permutation_inputs = (0..W).map(F::from_canonical_usize).collect::>(); - let mut witness = PartialWitness::new(1 << 14, 126, 1000); + let mut witness = PartialWitness::new(126); witness.set_wire( Wire { gate: 0, diff --git a/src/hash/merkle_proofs.rs b/src/hash/merkle_proofs.rs index 139ab0bc..088ffc5a 100644 --- a/src/hash/merkle_proofs.rs +++ b/src/hash/merkle_proofs.rs @@ -154,7 +154,7 @@ mod tests { fn test_recursive_merkle_proof() -> Result<()> { type F = CrandallField; let config = CircuitConfig::large_config(); - let mut pw = PartialWitness::new(1 << 14, config.num_wires, 1000); + let mut pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); let log_n = 8; diff --git a/src/iop/challenger.rs b/src/iop/challenger.rs index 4c13692f..1e41ecea 100644 --- a/src/iop/challenger.rs +++ b/src/iop/challenger.rs @@ -399,7 +399,7 @@ mod tests { num_routed_wires: 27, ..CircuitConfig::default() }; - let mut witness = PartialWitness::new(1 << 14, config.num_wires, 1000); + 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(); diff --git a/src/iop/witness.rs b/src/iop/witness.rs index 1eabad4b..da7ee73f 100644 --- a/src/iop/witness.rs +++ b/src/iop/witness.rs @@ -31,10 +31,10 @@ pub struct PartialWitness { } impl PartialWitness { - pub fn new(degree: usize, num_wires: usize, max_virtual_target: usize) -> Self { + pub fn new(num_wires: usize) -> Self { PartialWitness { - wire_values: vec![vec![None; num_wires]; degree], - virtual_target_values: vec![None; max_virtual_target], + wire_values: vec![vec![None; num_wires]], + virtual_target_values: vec![], } } @@ -93,8 +93,13 @@ impl PartialWitness { pub fn contains(&self, target: Target) -> bool { match target { - Target::Wire(Wire { gate, input }) => self.wire_values[gate][input].is_some(), - Target::VirtualTarget { index } => self.virtual_target_values[index].is_some(), + 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() + } } } @@ -105,6 +110,10 @@ impl PartialWitness { pub fn set_target(&mut self, target: Target, value: F) { 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, @@ -116,6 +125,9 @@ impl PartialWitness { } } 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, @@ -192,7 +204,7 @@ impl PartialWitness { pub fn full_witness(self, degree: usize, num_wires: usize) -> Witness { let mut wire_values = vec![vec![F::ZERO; degree]; num_wires]; - for i in 0..degree { + for i in 0..self.wire_values.len().min(degree) { for j in 0..num_wires { wire_values[j][i] = self.wire_values[i][j].unwrap_or(F::ZERO); } @@ -237,9 +249,3 @@ impl PartialWitness { Ok(()) } } - -impl Default for PartialWitness { - fn default() -> Self { - Self::new(0, 0, 0) - } -} diff --git a/src/plonk/recursive_verifier.rs b/src/plonk/recursive_verifier.rs index 64175a20..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(1 << 14, config.num_wires, 1000))?, + 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(1 << 14, config.num_wires, 1000); + 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(1 << 14, config.num_wires, 1000))?, + 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(1 << 14, config.num_wires, 100000); + 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(1 << 14, config.num_wires, 100000); + 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/util/reducing.rs b/src/util/reducing.rs index 47386e75..ce6827ba 100644 --- a/src/util/reducing.rs +++ b/src/util/reducing.rs @@ -249,7 +249,7 @@ mod tests { let config = CircuitConfig::large_config(); - let pw = PartialWitness::new(1 << 14, config.num_wires, 1000); + let pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); let alpha = FF::rand(); @@ -277,7 +277,7 @@ mod tests { let config = CircuitConfig::large_config(); - let pw = PartialWitness::new(1 << 14, config.num_wires, 1000); + let pw = PartialWitness::new(config.num_wires); let mut builder = CircuitBuilder::::new(config); let alpha = FF::rand(); From c3a0b7cc82a2980fd94cbcef7d3e33d20f6e5b5a Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 9 Aug 2021 18:35:41 +0200 Subject: [PATCH 04/10] PR feedback --- src/gates/gmimc.rs | 2 +- src/iop/witness.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gates/gmimc.rs b/src/gates/gmimc.rs index 03fdef56..e953809b 100644 --- a/src/gates/gmimc.rs +++ b/src/gates/gmimc.rs @@ -345,7 +345,7 @@ mod tests { let permutation_inputs = (0..W).map(F::from_canonical_usize).collect::>(); - let mut witness = PartialWitness::new(126); + let mut witness = PartialWitness::new(gate.num_wires()); witness.set_wire( Wire { gate: 0, diff --git a/src/iop/witness.rs b/src/iop/witness.rs index da7ee73f..49950a72 100644 --- a/src/iop/witness.rs +++ b/src/iop/witness.rs @@ -204,7 +204,8 @@ impl PartialWitness { pub fn full_witness(self, degree: usize, num_wires: usize) -> Witness { let mut wire_values = vec![vec![F::ZERO; degree]; num_wires]; - for i in 0..self.wire_values.len().min(degree) { + 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); } From 21f90ca853b0cb50ff7b19a5a9b46041e4fc3ee3 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 9 Aug 2021 18:42:01 +0200 Subject: [PATCH 05/10] Fix some off-by-one errors in the degrees --- src/gates/gate_tree.rs | 6 +++--- src/plonk/prover.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gates/gate_tree.rs b/src/gates/gate_tree.rs index 9cf3fe26..9badc207 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_vanishig_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/plonk/prover.rs b/src/plonk/prover.rs index de85d94b..ec88a67c 100644 --- a/src/plonk/prover.rs +++ b/src/plonk/prover.rs @@ -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. \ From f08d47b7d99983b854edbbdd100181f4660b563f Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 9 Aug 2021 18:43:12 +0200 Subject: [PATCH 06/10] Update comment --- src/gates/gate_tree.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gates/gate_tree.rs b/src/gates/gate_tree.rs index 9badc207..4b0a541a 100644 --- a/src/gates/gate_tree.rs +++ b/src/gates/gate_tree.rs @@ -64,7 +64,7 @@ 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 quotient polynomials are padded to the next power of 2 in `compute_vanishig_polys`. + // 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 { From 05c947995545d62418c7d3061dadc7534a3291c9 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 9 Aug 2021 18:49:25 +0200 Subject: [PATCH 07/10] Operator precedence --- src/gates/gate_tree.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gates/gate_tree.rs b/src/gates/gate_tree.rs index 4b0a541a..30dd01ed 100644 --- a/src/gates/gate_tree.rs +++ b/src/gates/gate_tree.rs @@ -66,7 +66,7 @@ impl, const D: usize> Tree> { for max_degree_bits in 1..10 { // 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; + 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(); From 4e86d9d7f41d790451740156020240a47772f5fe Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Mon, 9 Aug 2021 19:08:52 +0200 Subject: [PATCH 08/10] Derive `quotient_degree_factor` --- src/plonk/circuit_builder.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/plonk/circuit_builder.rs b/src/plonk/circuit_builder.rs index f4eaa881..9b060710 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< Date: Mon, 9 Aug 2021 10:11:35 -0700 Subject: [PATCH 09/10] PolynomialBatchCommitment tweaks (#164) Very minor things: - A few renames - Instead of having two constructors call a third constructor, just have one constructor call the other. - Invoke FFT with the option that specifies the inputs are mostly zero, as a (minor) optimization - Remove unused field --- src/field/fft.rs | 2 +- src/fri/commitment.rs | 54 ++++++++++++++---------------------- src/plonk/circuit_builder.rs | 2 +- src/plonk/prover.rs | 6 ++-- src/polynomial/polynomial.rs | 21 +++++++++++++- 5 files changed, 46 insertions(+), 39 deletions(-) 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/plonk/circuit_builder.rs b/src/plonk/circuit_builder.rs index f4eaa881..bf1a1385 100644 --- a/src/plonk/circuit_builder.rs +++ b/src/plonk/circuit_builder.rs @@ -555,7 +555,7 @@ impl, 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 ec88a67c..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, diff --git a/src/polynomial/polynomial.rs b/src/polynomial/polynomial.rs index f69602d5..32b16597 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 From b89f4d656d362cb825279612d822922b16dd2fba Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Mon, 9 Aug 2021 10:11:42 -0700 Subject: [PATCH 10/10] Update various dependencies (#163) --- Cargo.toml | 8 ++++---- src/field/crandall_field.rs | 2 +- src/gadgets/split_base.rs | 2 +- src/hash/merkle_proofs.rs | 2 +- src/polynomial/polynomial.rs | 18 +++++++++--------- 5 files changed, 16 insertions(+), 16 deletions(-) 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/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/gadgets/split_base.rs b/src/gadgets/split_base.rs index ff420ba0..9b481e78 100644 --- a/src/gadgets/split_base.rs +++ b/src/gadgets/split_base.rs @@ -128,7 +128,7 @@ mod tests { 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(); diff --git a/src/hash/merkle_proofs.rs b/src/hash/merkle_proofs.rs index 088ffc5a..30391a98 100644 --- a/src/hash/merkle_proofs.rs +++ b/src/hash/merkle_proofs.rs @@ -161,7 +161,7 @@ mod tests { 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/polynomial/polynomial.rs b/src/polynomial/polynomial.rs index 32b16597..4e15be56 100644 --- a/src/polynomial/polynomial.rs +++ b/src/polynomial/polynomial.rs @@ -453,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; @@ -469,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; @@ -491,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); @@ -505,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); @@ -519,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); @@ -533,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 = { @@ -573,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);