Skip to content

Commit 191993e

Browse files
committed
Make the IR1CS optimizer more aggressive
Previously, we would eliminate only final-round witnesses. This is obviously sound, but sub-optimal. Anna has found some protocols (SHA with lookups) where the sub-optimality matters, so I've made the optimizer a bit more aggressive.
1 parent 3ba1be4 commit 191993e

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

src/target/r1cs/mod.rs

+31
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,37 @@ impl R1cs {
370370
matches!(var.ty(), VarType::FinalWit)
371371
}
372372

373+
/// Can this variable be eliminated within this constraint?
374+
///
375+
/// A witness variable can be eliminated iff it is in the *last* round of its constraint.
376+
/// We only approximate this.
377+
/// We elim if:
378+
/// 1) this is a final wit or
379+
/// 2) this is a wit with only other wits and insts and it is the last wit
380+
///
381+
/// This is an approximation because we comparse witness numbers in (2) instead of witness
382+
/// rounds. So, we under-approximate the set of eliminatable variables.
383+
pub fn can_eliminate_in(&self, var: Var, constraint: &Lc) -> bool {
384+
match var.ty() {
385+
VarType::FinalWit => true,
386+
VarType::Inst | VarType::Chall | VarType::CWit => false,
387+
VarType::RoundWit => {
388+
for v in constraint.monomials.keys() {
389+
match v.ty() {
390+
VarType::Inst | VarType::CWit => {}
391+
VarType::Chall | VarType::FinalWit => return false,
392+
VarType::RoundWit => {
393+
if v.number() > var.number() {
394+
return false;
395+
}
396+
}
397+
}
398+
}
399+
true
400+
}
401+
}
402+
}
403+
373404
/// Get a nice string represenation of the tuple.
374405
pub fn format_qeq(&self, (a, b, c): &(Lc, Lc, Lc)) -> String {
375406
format!(

src/target/r1cs/opt.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ impl LinReducer {
177177
fn as_linear_sub((a, b, c): &(Lc, Lc, Lc), r1cs: &R1cs) -> Option<(Var, Lc)> {
178178
if a.is_zero() || b.is_zero() {
179179
for i in c.monomials.keys() {
180-
if r1cs.can_eliminate(*i) {
180+
if r1cs.can_eliminate_in(*i, c) {
181181
let mut lc = c.clone();
182182
let v = lc.monomials.remove(i).unwrap();
183183
lc *= v.recip();

0 commit comments

Comments
 (0)