diff --git a/src/plonk/keygen.rs b/src/plonk/keygen.rs index 5df667a..c04fd42 100644 --- a/src/plonk/keygen.rs +++ b/src/plonk/keygen.rs @@ -76,6 +76,17 @@ where .max() .unwrap_or(1); + // The lookup argument also serves alongside the gates and must be accounted + // for. + degree = std::cmp::max( + degree, + cs.lookups + .iter() + .map(|l| l.required_degree()) + .max() + .unwrap_or(1), + ); + // Account for each gate to ensure our quotient polynomial is the // correct degree and that our extended domain is the right size. for poly in cs.gates.iter() { diff --git a/src/plonk/lookup.rs b/src/plonk/lookup.rs index 640faef..7d588d0 100644 --- a/src/plonk/lookup.rs +++ b/src/plonk/lookup.rs @@ -18,6 +18,24 @@ impl Argument { table_columns: table_columns.to_vec(), } } + + pub(crate) fn required_degree(&self) -> usize { + assert_eq!(self.input_columns.len(), self.table_columns.len()); + + // degree 2: + // l_0(X) * (1 - z'(X)) = 0 + // + // degree 3: + // z'(X) (a'(X) + \beta) (s'(X) + \gamma) + // - z'(\omega^{-1} X) (\theta^{m-1} a_0(X) + ... + a_{m-1}(X) + \beta) (\theta^{m-1} s_0(X) + ... + s_{m-1}(X) + \gamma) + // + // degree 2: + // l_0(X) * (a'(X) - s'(X)) = 0 + // + // degree 2: + // (a′(X)−s′(X))⋅(a′(X)−a′(\omega{-1} X)) = 0 + 3 + } } #[derive(Clone, Debug)] diff --git a/src/plonk/permutation.rs b/src/plonk/permutation.rs index deda02b..0de904c 100644 --- a/src/plonk/permutation.rs +++ b/src/plonk/permutation.rs @@ -24,8 +24,18 @@ impl Argument { pub(crate) fn required_degree(&self) -> usize { // The permutation argument will serve alongside the gates, so must be - // accounted for. - self.columns.len() + 1 + // accounted for. There are constraints of degree 2 regardless of the + // number of columns involved. (It doesn't make sense to make a + // permutation argument with zero columns but to be rigorous we account + // for it here.) + + // degree 2: + // l_0(X) * (1 - z(X)) = 0 + // + // degree columns + 1 + // z(X) \prod (p(X) + \beta s_i(X) + \gamma) + // - z(omega^{-1} X) \prod (p(X) + \delta^i \beta X + \gamma) + std::cmp::max(self.columns.len() + 1, 2) } }