Skip to content

Commit 5bca067

Browse files
committed
sca: test witness generation
1 parent 9c7e2d2 commit 5bca067

File tree

1 file changed

+41
-3
lines changed

1 file changed

+41
-3
lines changed

patronus-sca/src/lib.rs

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// released under BSD 3-Clause License
33
// author: Kevin Laeufer <laeufer@cornell.edu>
44

5-
use baa::{BitVecMutOps, BitVecOps, BitVecValue, BitVecValueRef};
5+
use baa::{BitVecOps, BitVecValue, BitVecValueRef};
66
use patronus::expr::*;
77
use polysub::{Coef, Term, VarIndex};
88
use rustc_hash::FxHashSet;
@@ -55,7 +55,16 @@ pub fn verify_word_level_equality(ctx: &mut Context, p: ScaEqualityProblem) -> S
5555
ScaVerifyResult::Equal
5656
} else {
5757
let witness = extract_witness(ctx, &result, inputs.iter().cloned());
58-
ScaVerifyResult::Unequal(witness)
58+
// check witness
59+
let is_equal = eval_bv_expr(ctx, witness.as_slice(), p.equality);
60+
if is_equal.is_true() {
61+
println!(
62+
"ERROR: the polynomial does not reduce to zero, but we were not able to find a witness to show inequality. Returning Unknown."
63+
);
64+
ScaVerifyResult::Unknown
65+
} else {
66+
ScaVerifyResult::Unequal(witness)
67+
}
5968
}
6069
}
6170

@@ -533,7 +542,7 @@ impl<'a, 'b> Display for PrettyPoly<'a, 'b> {
533542
mod tests {
534543
use super::*;
535544
use patronus::expr::{eval_bv_expr, find_symbols};
536-
use patronus::smt::{BITWUZLA, Logic, SmtCommand, Solver, SolverContext, read_command};
545+
use patronus::smt::{SmtCommand, read_command};
537546
use rustc_hash::FxHashMap;
538547
use std::io::BufReader;
539548

@@ -720,6 +729,35 @@ mod tests {
720729
assert_eq!(result, ScaVerifyResult::Equal);
721730
}
722731

732+
#[test]
733+
fn test_incorrect_2bit_adder() {
734+
let mut ctx = Context::default();
735+
let a = ctx.bv_symbol("a", 2);
736+
let b = ctx.bv_symbol("b", 2);
737+
let word_level = ctx.add(a, b);
738+
let a_0 = ctx.slice(a, 0, 0);
739+
let a_1 = ctx.slice(a, 1, 1);
740+
let b_0 = ctx.slice(b, 0, 0);
741+
let b_1 = ctx.slice(b, 1, 1);
742+
let gate_level_0 = ctx.xor(a_0, b_0);
743+
let carry_1 = ctx.and(a_0, b_0);
744+
let gate_level_1 = ctx.majority(a_1, b_1, carry_1);
745+
let gate_level = ctx.concat(gate_level_1, gate_level_0);
746+
let equality = ctx.equal(word_level, gate_level);
747+
748+
let problem = find_sca_simplification_candidates(&ctx, equality)[0];
749+
750+
// manually check that our problem is actually incorrect
751+
assert!(!is_eq_exhaustive(&ctx, problem));
752+
753+
let result = verify_word_level_equality(&mut ctx, problem);
754+
if let ScaVerifyResult::Unequal(w) = result {
755+
println!("Witness: {w:?}");
756+
} else {
757+
assert!(false, "{result:?}");
758+
}
759+
}
760+
723761
#[test]
724762
fn test_simplify_coward_three_add_2bit() {
725763
check_eq_coward_smt("../inputs/coward/add_three.2_bit.smt2");

0 commit comments

Comments
 (0)