diff --git a/kimchi/src/circuits/constraints.rs b/kimchi/src/circuits/constraints.rs index f8f2f20555..0e9d61faeb 100644 --- a/kimchi/src/circuits/constraints.rs +++ b/kimchi/src/circuits/constraints.rs @@ -639,6 +639,22 @@ impl ConstraintSystem { } } +/// The default number of chunks in a circuit is one (< 2^16 rows) +pub const NUM_CHUNKS_BY_DEFAULT: usize = 1; + +/// The number of rows required for zero knowledge in circuits with one single chunk +pub const ZK_ROWS_BY_DEFAULT: u64 = 3; + +/// This function computes a strict lower bound in the number of rows required +/// for zero knowledge in circuits with `num_chunks` chunks. This means that at +/// least one needs 1 more row than the result of this function to achieve zero +/// knowledge. +/// Example: +/// for 1 chunk, this function returns 2, but at least 3 rows are needed +/// Note: +/// the number of zero knowledge rows is usually computed across the codebase +/// as the formula `(16 * num_chunks + 5) / 7`, which is precisely the formula +/// in this function plus one. pub fn zk_rows_strict_lower_bound(num_chunks: usize) -> usize { (2 * (PERMUTS + 1) * num_chunks - 2) / PERMUTS } diff --git a/kimchi/src/prover.rs b/kimchi/src/prover.rs index 14e043be07..95221b23bc 100644 --- a/kimchi/src/prover.rs +++ b/kimchi/src/prover.rs @@ -210,9 +210,17 @@ where .ok_or(ProverError::NoRoomForZkInWitness)?; let zero_knowledge_limit = zk_rows_strict_lower_bound(num_chunks); - if (index.cs.zk_rows as usize) < zero_knowledge_limit { + // Because the lower bound is strict, the result of the function above + // is not a sufficient number of zero knowledge rows, so the error must + // be raised anytime the number of zero knowledge rows is not greater + // than the strict lower bound. + // Example: + // for 1 chunk, `zero_knowledge_limit` is 2, and we need at least 3, + // thus the error should be raised and the message should say that the + // expected number of zero knowledge rows is 3 (hence the + 1). + if (index.cs.zk_rows as usize) <= zero_knowledge_limit { return Err(ProverError::NotZeroKnowledge( - zero_knowledge_limit, + zero_knowledge_limit + 1, index.cs.zk_rows as usize, )); }