bernhard gleiss, gilles barthe, renate eilers, pamina...
TRANSCRIPT
Verifying Relational Properties using Trace Logic
Bernhard Gleiss, Gilles Barthe, Renate Eilers,Pamina Georgiou, Laura Kovacs, Matteo Maffei
October 25, 2019
Motivating example
1 func main() {
2 const Int[] a;
34 Int sum = 0;
56 for (Int i=0; i < a.length; ++i)
7 {
8 sum += a[i];
9 }
10 }
v w
w v
k
a(t1) :
a(t2) :
⇒sum(end , t1)
==
sum(end , t2)
Motivating example
1 func main() {
2 const Int[] a;
34 Int sum = 0;
56 for (Int i=0; i < a.length; ++i)
7 {
8 sum += a[i];
9 }
10 }
v w
w v
k
a(t1) :
a(t2) :
⇒sum(end , t1)
==
sum(end , t2)
Motivating example - Human Proof
FirstIteration
LastIteration
iteration where i = k
iteration where i = k + 2
Induction' Induction'Comm.+
Motivating example - Human Proof
FirstIteration
LastIteration
iteration where i = k
iteration where i = k + 2
Induction' Induction'Comm.+
Motivating example - Human Proof
FirstIteration
LastIteration
iteration where i = k
iteration where i = k + 2
Induction' Induction'Comm.+
Focus
I (Software) programs containing loops and arrays
I Proving Relational Safety Properties
I Proving Correctness (instead of finding Counterexamples)
Remaining Talk - Outline
I Part 1: Language and Semantics - Trace Logic
I Part 2: Verification Approach - Vampire and Trace Lemmas
I Part 3: Extension - Relational Properties
Part 1: Language and Semantics - Trace Logic
Trace Logic
I full first-order logic over UFDTLIA
I explicit notion of time: able to refer to each timepoint of theexecution uniquely, while preserving control flow structure
I can formulate induction directly in the language
I can denote parts of a loop and reason about those partsseparately
Timepoints
1 func main() {
2 const Int[] a;
34 Int sum = 0;
56 for (Int i=0; i < a.length; ++i)
7 {
8 sum += a[i];
9 }
10 }
l4 l8(0) l6(s(0)) l6(n6) l6(it)
Program Variables
1 func main() {
2 const Int[] a;
34 Int sum = 0;
56 for (Int i=0; i < a.length; ++i)
7 {
8 sum += a[i];
9 }
10 }
sum(l8(0)) i(l6(n6)) a(l2, pos)
a(pos)
Program Variables
1 func main() {
2 const Int[] a;
34 Int sum = 0;
56 for (Int i=0; i < a.length; ++i)
7 {
8 sum += a[i];
9 }
10 }
sum(l8(0)) i(l6(n6)) a(pos)
a(l2, pos)
Semantics in Trace Logic
1 func main() {
2 const Int[] a;
34 Int sum = 0;
56 for (Int i=0; i < a.length; ++i)
7 {
8 sum += a[i];
9 }
10 }
i(l6(0)) ' 0
Semantics in Trace Logic
1 func main() {
2 const Int[] a;
34 Int sum = 0;
56 for (Int i=0; i < a.length; ++i)
7 {
8 sum += a[i];
9 }
10 }
∀itN.(it < n6 → i(l6(s(it)))' i(l8(it))+1
)
Part 2: Verification Approach - Vampire and Trace Lemmas
Workflow - Rapid
P JPKSemantics FO-clauses
PropertyFO-clauses
JPK �UFDTLIA Property
Workflow - Rapid
P JPKSemantics FO-clauses
PropertyFO-clauses
VAMPIRE
Trace-LemmasFO-clauses
Trace Lemmas
I provide necessary inductive reasoning
I valid formulas, derivable from instances of the inductionaxiom scheme
I can’t be automatically generated by state-of-the-art tools
I manually identified set of useful Trace Lemmas
Trace Lemmas - Example 1
”For an arbitrary interval: if the value of v stays the same in eachstep, then the value of v at the end is the same as the value of v atthe beginning”
∀itNL ,∀itNR .(∀itN.
(itL ≤ it < itR → v(l6(it))' v(l6(s(it)))
)→
∀itN.v(l6(itL))' v(l6(itR)))
Trace Lemmas - Example 2
Intermediate Value Theorem: ”If i ≤ v at the beginning and i > vat the end and if i is incremented by 1 in each iteration, then thereexists an iteration, where i = v .”
∀v I.((
i(l6(0)) ≤ v ∧i(l6(n6)) > v ∧∀itN.
(it < n→ i(l6(s(it)))' i(l6(it)) + 1
))
→ ∃it ′N.i(l6(it ′))' v
)
Trace Lemmas
I can be instantiated to parts of the loop
I can feature existential quantification over iterations
I can feature quantifier alternations
I can not be synthesized automatically by state-of-the-arttechniques
Workflow - Rapid
P JPKSemantics FO-clauses
PropertyFO-clauses
VAMPIRE
Trace-LemmasFO-clauses
- synthesize split-timepoints- reason about loop-parts sep.- perform interleaved
Part 3: Extension to Relational Properties
Extension - Timepoints and Program Variables
1 func main() {
2 const Int[] a;
34 Int sum = 0;
56 for (Int i=0; i < a.length; ++i)
7 {
8 sum += a[i];
9 }
10 }
n6 sum(l8(0)) i(l6(n8))
Extension - Timepoints and Program Variables
1 func main() {
2 const Int[] a;
34 Int sum = 0;
56 for (Int i=0; i < a.length; ++i)
7 {
8 sum += a[i];
9 }
10 }
n6(t1) sum(l8(0), t1) i(l6(n8), t2)
Extension - Timepoints and Program Variables
1 func main() {
2 const Int[] a;
34 Int sum = 0;
56 for (Int i=0; i < a.length; ++i)
7 {
8 sum += a[i];
9 }
10 }
i(l6(0)) ' 0
Extension - Timepoints and Program Variables
1 func main() {
2 const Int[] a;
34 Int sum = 0;
56 for (Int i=0; i < a.length; ++i)
7 {
8 sum += a[i];
9 }
10 }
∀trT.i(l6(0), tr) ' 0
Extension - Timepoints and Program Variables
1 func main() {
2 const Int[] a;
34 Int sum = 0;
56 for (Int i=0; i < a.length; ++i)
7 {
8 sum += a[i];
9 }
10 }
∀itN.(it < n6 → i(l6(s(it)))' i(l8(it))+1
)
Extension - Timepoints and Program Variables
1 func main() {
2 const Int[] a;
34 Int sum = 0;
56 for (Int i=0; i < a.length; ++i)
7 {
8 sum += a[i];
9 }
10 }
∀trT.∀itN.(it < n6(tr)→ i(l6(s(it)), tr)' i(l8(it), tr)+1
)
Extension - Trace Lemmas
sum has the same value in both traces in iteration it:
Eqsum(it) := sum(l6(it), t1)' sum(l6(it), t2).
Bounded induction with induction hypothesis Eqsum(it):
∀itLN, itRN.(
(Eqsum(itL) ∧∀itN.((itL ≤ it < itR ∧ Eqsum(it))→ Eqsum(s(it)))
)→ Eqsum(itR)
)
Benchmarks
I 27 challenging benchmarks from security applications
I 2-safety properties: non-interference and sensitivity
I 60 second timeout
BenchmarksVampire
CVC4 Z3S S+A F F+A
1-hw-equal-arrays X X - X X X2-hw-last-position-swapped - X - - X X3-hw-swap-and-two-arrays - X - - - -4-hw-swap-in-array-lemma - X - - - -
4-hw-swap-in-array-full - X - - - -1-ni-assign-to-high X X X X X X
2-ni-branch-on-high-twice X X X X X X3-ni-high-guard-equal-branches X X X X X X
4-ni-branch-on-high-twice-prop2 X X - - X X5-ni-temp-impl-flow - - X X X X
6-ni-branch-assign-equal-val - - X X X X7-ni-explicit-flow X X X X X X
8-ni-explicit-flow-while X X - X X X9-ni-equal-output X - - - - X
10-ni-rsa-exponentiation X X X X X -1-sens-equal-sums X X X X X X
2-sens-equal-sums-two-arrays X X X X - -3-sens-abs-diff-up-to-k - - - - X X
4-sens-abs-diff-up-to-k-two-arrays - - - - - -5-sens-two-arrays-equal-k X X X X - -6-sens-diff-up-to-explicit-k X X X X - -
7-sens-diff-up-to-explicit-k-sum - - X X - -8-sens-explicit-swap - - X X - -
9-sens-explicit-swap-prop2 - X X - -10-sens-equal-k X X X X - -
11-sens-equal-k-twice X X X X - -12-sens-diff-up-to-forall-k - - X X X -
Total Vampire 15 18 17 19Unique Vampire 1 4 0 0
Total 25 14 13
Conclusion
I Trace Logic Language and Semantics
I Verification Approach - Vampire and Trace Lemmas
I Application to Relational Verification
Extra slides
Background Theory
I Full first-order logic with equality and uninterpreted functions
I Iterations - Datatype (0, s, p, <) (no arithmetic!)
I Timepoints - Uninterpreted Sort
I Values of program variables - Integers
Motivating example - Property in Trace Logic
Swappeda(k) :=
0 ≤ k < k + 1 < a.length
∧ ∀posI.((pos 6' k ∧ pos 6' k+1)→a(pos, t1)' a(pos, t2))
∧ a(k , t1)' a(k+1, t2)
∧ a(k , t2)' a(k+1, t1)
∀kI.(Swappeda(k)→ sum(end , t1)' sum(end , t2)
)
Rapid Tool
Available at:
https://github.com/gleiss/rapid
Theory reasoning - Blowup
new: 40588. less(-4,0) — less(-6,4)new: 40589. less(-4,-1) — less(-4,4)new: 40590. less(-4,-1) — less(-3,4)new: 40591. less(-4,-1) — less(-2,4)new: 40592. less(-4,-1) — 0 = 4 — less(0,4)new: 40593. less(-4,-1) — less(4,0)new: 40594. less(-4,2) — less(-2,4)new: 40595. less(-4,2) — less(-1,4)new: 40596. less(-4,2) — less(0,4)new: 40597. less(-4,2) — less(4,3)new: 40598. less(-4,2) — less(1,4)new: 40599. less(-4,-2) — less(-4,4)new: 40600. less(-4,-2) — less(-3,4)new: 40601. less(-4,-3) — less(-4,4)new: 40602. less(-4,3) — less(-3,4)new: 40603. less(-4,3) — less(-1,4)new: 40604. less(-4,3) — less(-2,4)new: 40605. less(-4,3) — less(0,4)new: 40606. less(-4,3) — less(1,4)new: 40607. less(-4,3) — less(2,4)new: 40608. less(-4,4) — less(-3,4)new: 40609. less(-4,4) — less(-2,4)new: 40610. less(-4,4) — less(2,4)new: 40611. less(-4,4) — less(1,4)new: 40612. less(-4,4) — less(0,4)new: 40613. less(-4,4) — less(-1,4)new: 40614. less(-4,5) — less(-1,4)new: 40615. less(-4,5) — less(1,4)new: 40616. less(-4,5) — less(0,4)