diff --git a/src/plonk.rs b/src/plonk.rs index 4559c0f..d223173 100644 --- a/src/plonk.rs +++ b/src/plonk.rs @@ -262,6 +262,8 @@ fn test_proving() { let c = meta.advice_wire(); let d = meta.advice_wire(); + let x = meta.aux_wire(); + let perm = meta.permutation(&[a, b, c]); let perm2 = meta.permutation(&[a, b, c]); @@ -269,6 +271,7 @@ fn test_proving() { let sa = meta.fixed_wire(); let sb = meta.fixed_wire(); let sc = meta.fixed_wire(); + let sx = meta.fixed_wire(); meta.create_gate(|meta| { let d = meta.query_advice(d, 1); @@ -278,12 +281,19 @@ fn test_proving() { let b = meta.query_advice(b, 0); let c = meta.query_advice(c, 0); + let x = meta.query_advice(x, 0); + let sa = meta.query_fixed(sa, 0); let sb = meta.query_fixed(sb, 0); let sc = meta.query_fixed(sc, 0); let sm = meta.query_fixed(sm, 0); - a.clone() * sa + b.clone() * sb + a * b * sm + (c * sc * (-F::one())) + sf * (d * e) + a.clone() * sa + + b.clone() * sb + + a * b * sm + + (c * sc * (-F::one())) + + sf * (d * e) + + (x * sx * (-F::one())) }); PLONKConfig { diff --git a/src/plonk/circuit.rs b/src/plonk/circuit.rs index 301eff8..5330a1b 100644 --- a/src/plonk/circuit.rs +++ b/src/plonk/circuit.rs @@ -160,6 +160,7 @@ pub(crate) struct PointIndex(pub usize); pub struct ConstraintSystem { pub(crate) num_fixed_wires: usize, pub(crate) num_advice_wires: usize, + pub(crate) num_aux_wires: usize, pub(crate) gates: Vec>, pub(crate) advice_queries: Vec<(AdviceWire, Rotation)>, pub(crate) aux_queries: Vec<(AuxWire, Rotation)>, @@ -186,6 +187,7 @@ impl Default for ConstraintSystem { ConstraintSystem { num_fixed_wires: 0, num_advice_wires: 0, + num_aux_wires: 0, gates: vec![], fixed_queries: Vec::new(), advice_queries: Vec::new(), @@ -266,6 +268,32 @@ impl ConstraintSystem { Expression::Advice(self.query_advice_index(wire, at)) } + fn query_aux_index(&mut self, wire: AuxWire, at: i32) -> usize { + let at = Rotation(at); + { + let len = self.rotations.len(); + self.rotations.entry(at).or_insert(PointIndex(len)); + } + + // Return existing query, if it exists + for (index, aux_query) in self.aux_queries.iter().enumerate() { + if aux_query == &(wire, at) { + return index; + } + } + + // Make a new query + let index = self.aux_queries.len(); + self.aux_queries.push((wire, at)); + + index + } + + /// Query an auxiliary wire at a relative position + pub fn query_aux(&mut self, wire: AuxWire, at: i32) -> Expression { + Expression::Aux(self.query_aux_index(wire, at)) + } + /// Create a new gate pub fn create_gate(&mut self, f: impl FnOnce(&mut Self) -> Expression) { let poly = f(self); @@ -285,4 +313,11 @@ impl ConstraintSystem { self.num_advice_wires += 1; tmp } + + /// Allocate a new auxiliary wire + pub fn aux_wire(&mut self) -> AuxWire { + let tmp = AuxWire(self.num_aux_wires); + self.num_aux_wires += 1; + tmp + } } diff --git a/src/plonk/verifier.rs b/src/plonk/verifier.rs index 6c2cf75..6c7c239 100644 --- a/src/plonk/verifier.rs +++ b/src/plonk/verifier.rs @@ -15,6 +15,11 @@ impl<'a, C: CurveAffine> Proof { mut msm: MSM<'a, C>, aux_commitments: Vec, ) -> Result, Error> { + // Check that aux_commitments matches the expected number of aux_wires + if aux_commitments.len() != srs.cs.num_aux_wires { + return Err(Error::IncompatibleParams); + } + // Scale the MSM by a random factor to ensure that if the existing MSM // has is_zero() == false then this argument won't be able to interfere // with it to make it true, with high probability.