Theory BD_Security_Unwinding
theory BD_Security_Unwinding
imports BD_Security_IO
begin
section ‹Unwinding proof method›
text ‹This section formalizes the unwinding proof method for BD Security discussed in
\<^cite>‹‹Section 5.1› in "cocon-CAV2014"››
context BD_Security_IO
begin
definition consume :: "('state,'act,'out) trans ⇒ 'value list ⇒ 'value list ⇒ bool" where
"consume trn vl vl' ≡
if φ trn then vl ≠ [] ∧ f trn = hd vl ∧ vl' = tl vl
else vl' = vl"
definition consumeList :: "('state,'act,'out) trans trace ⇒ 'value list ⇒ 'value list ⇒ bool" where
"consumeList tr vl vl' ≡ vl = (V tr) @ vl'"
lemma length_consume[simp]:
"consume trn vl vl' ⟹ length vl' < Suc (length vl)"
unfolding consume_def by (auto split: if_splits)
lemma ex_consume_φ:
assumes "¬ φ trn"
obtains vl' where "consume trn vl vl'"
using assms unfolding consume_def by auto
lemma ex_consume_NO:
assumes "vl ≠ []" and "f trn = hd vl"
obtains vl' where "consume trn vl vl'"
using assms unfolding consume_def by (cases "φ trn") auto
definition iaction where
"iaction Δ s vl s1 vl1 ≡
∃ al1 vl1'.
let tr1 = traceOf s1 al1; s1' = tgtOf (last tr1) in
list_ex φ tr1 ∧ consumeList tr1 vl1 vl1' ∧
never γ tr1
∧
Δ s vl s1' vl1'"
lemma iactionI_ms[intro?]:
assumes s: "sstep s1 al1 = (oul1, s1')"
and l: "list_ex φ (traceOf s1 al1)"
and "consumeList (traceOf s1 al1) vl1 vl1'"
and "never γ (traceOf s1 al1)" and "Δ s vl s1' vl1'"
shows "iaction Δ s vl s1 vl1"
proof-
have "al1 ≠ []" using l by auto
from sstep_tgtOf_traceOf[OF this s] assms
show ?thesis unfolding iaction_def by auto
qed
lemma sstep_eq_singleiff[simp]: "sstep s1 [a1] = ([ou1], s1') ⟷ step s1 a1 = (ou1, s1')"
using sstep_Cons by auto
lemma iactionI[intro?]:
assumes "step s1 a1 = (ou1, s1')" and "φ (Trans s1 a1 ou1 s1')"
and "consume (Trans s1 a1 ou1 s1') vl1 vl1'"
and "¬ γ (Trans s1 a1 ou1 s1')" and "Δ s vl s1' vl1'"
shows "iaction Δ s vl s1 vl1"
using assms
by (intro iactionI_ms[of _ "[a1]" "[ou1]"]) (auto simp: consume_def consumeList_def)
definition match where
"match Δ s s1 vl1 a ou s' vl' ≡
∃ al1 vl1'.
let trn = Trans s a ou s'; tr1 = traceOf s1 al1; s1' = tgtOf (last tr1) in
al1 ≠ [] ∧ consumeList tr1 vl1 vl1' ∧
O tr1 = O [trn] ∧
Δ s' vl' s1' vl1'"
lemma matchI_ms[intro?]:
assumes s: "sstep s1 al1 = (oul1, s1')"
and l: "al1 ≠ []"
and "consumeList (traceOf s1 al1) vl1 vl1'"
and "O (traceOf s1 al1) = O [Trans s a ou s']"
and "Δ s' vl' s1' vl1'"
shows "match Δ s s1 vl1 a ou s' vl'"
proof-
from sstep_tgtOf_traceOf[OF l s] assms
show ?thesis unfolding match_def by (intro exI[of _ al1]) auto
qed
lemma matchI[intro?]:
assumes "validTrans (Trans s1 a1 ou1 s1')"
and "consume (Trans s1 a1 ou1 s1') vl1 vl1'" and "γ (Trans s a ou s') = γ (Trans s1 a1 ou1 s1')"
and "γ (Trans s a ou s') ⟹ g (Trans s a ou s') = g (Trans s1 a1 ou1 s1')"
and "Δ s' vl' s1' vl1'"
shows "match Δ s s1 vl1 a ou s' vl'"
using assms by (intro matchI_ms[of s1 "[a1]" "[ou1]" s1'])
(auto simp: consume_def consumeList_def split: if_splits)
definition ignore where
"ignore Δ s s1 vl1 a ou s' vl' ≡
¬ γ (Trans s a ou s') ∧
Δ s' vl' s1 vl1"
lemma ignoreI[intro?]:
assumes "¬ γ (Trans s a ou s')" and "Δ s' vl' s1 vl1"
shows "ignore Δ s s1 vl1 a ou s' vl'"
unfolding ignore_def using assms by auto
definition reaction where
"reaction Δ s vl s1 vl1 ≡
∀ a ou s' vl'.
let trn = Trans s a ou s' in
validTrans trn ∧ ¬ T trn ∧
consume trn vl vl'
⟶
match Δ s s1 vl1 a ou s' vl'
∨
ignore Δ s s1 vl1 a ou s' vl'"
lemma reactionI[intro?]:
assumes
"⋀a ou s' vl'.
⟦step s a = (ou, s'); ¬ T (Trans s a ou s');
consume (Trans s a ou s') vl vl'⟧
⟹
match Δ s s1 vl1 a ou s' vl' ∨ ignore Δ s s1 vl1 a ou s' vl'"
shows "reaction Δ s vl s1 vl1"
using assms unfolding reaction_def by auto
definition "exit" :: "'state ⇒ 'value ⇒ bool" where
"exit s v ≡ ∀ tr trn. validFrom s (tr ## trn) ∧ never T (tr ## trn) ∧ φ trn ⟶ f trn ≠ v"
lemma exit_coind:
assumes K: "K s"
and I: "⋀ trn. ⟦K (srcOf trn); validTrans trn; ¬ T trn⟧
⟹ (φ trn ⟶ f trn ≠ v) ∧ K (tgtOf trn)"
shows "exit s v"
using K unfolding exit_def proof(intro allI conjI impI)
fix tr trn assume "K s" and "validFrom s (tr ## trn) ∧ never T (tr ## trn) ∧ φ trn"
thus "f trn ≠ v"
using I unfolding validFrom_def by (induction tr arbitrary: s trn)
(auto, metis neq_Nil_conv rotate1.simps(2) rotate1_is_Nil_conv valid_ConsE)
qed
definition noVal where
"noVal K v ≡
∀ s a ou s'. reachNT s ∧ K s ∧ step s a = (ou,s') ∧ φ (Trans s a ou s') ⟶ f (Trans s a ou s') ≠ v"
lemma noVal_disj:
assumes "noVal Inv1 v" and "noVal Inv2 v"
shows "noVal (λ s. Inv1 s ∨ Inv2 s) v"
using assms unfolding noVal_def by metis
lemma noVal_conj:
assumes "noVal Inv1 v" and "noVal Inv2 v"
shows "noVal (λ s. Inv1 s ∧ Inv2 s) v"
using assms unfolding noVal_def by blast
definition noφ where
"noφ K ≡ ∀ s a ou s'. reachNT s ∧ K s ∧ step s a = (ou,s') ⟶ ¬ φ (Trans s a ou s')"
lemma noφ_noVal: "noφ K ⟹ noVal K v"
unfolding noφ_def noVal_def by auto
lemma exitI[consumes 2, induct pred: "exit"]:
assumes rs: "reachNT s" and K: "K s"
and I:
"⋀ s a ou s'.
⟦reach s; reachNT s; step s a = (ou,s'); K s⟧
⟹ (φ (Trans s a ou s') ⟶ f (Trans s a ou s') ≠ v) ∧ K s'"
shows "exit s v"
proof-
let ?K = "λ s. reachNT s ∧ K s"
show ?thesis using assms by (intro exit_coind[of ?K])
(metis reachNT_reach IO_Automaton.validTrans reachNT.Step trans.exhaust_sel)+
qed
lemma exitI2:
assumes rs: "reachNT s" and K: "K s"
and "invarNT K" and "noVal K v"
shows "exit s v"
proof-
let ?K = "λ s. reachNT s ∧ K s"
show ?thesis using assms unfolding invarNT_def noVal_def apply(intro exit_coind[of ?K])
by metis (metis IO_Automaton.validTrans reachNT.Step trans.exhaust_sel)
qed
definition noVal2 where
"noVal2 K v ≡
∀ s a ou s'. reachNT s ∧ K s v ∧ step s a = (ou,s') ∧ φ (Trans s a ou s') ⟶ f (Trans s a ou s') ≠ v"
lemma noVal2_disj:
assumes "noVal2 Inv1 v" and "noVal2 Inv2 v"
shows "noVal2 (λ s v. Inv1 s v ∨ Inv2 s v) v"
using assms unfolding noVal2_def by metis
lemma noVal2_conj:
assumes "noVal2 Inv1 v" and "noVal2 Inv2 v"
shows "noVal2 (λ s v. Inv1 s v ∧ Inv2 s v) v"
using assms unfolding noVal2_def by blast
lemma noVal_noVal2: "noVal K v ⟹ noVal2 (λ s v. K s) v"
unfolding noVal_def noVal2_def by auto
lemma exitI_noVal2[consumes 2, induct pred: "exit"]:
assumes rs: "reachNT s" and K: "K s v"
and I:
"⋀ s a ou s'.
⟦reach s; reachNT s; step s a = (ou,s'); K s v⟧
⟹ (φ (Trans s a ou s') ⟶ f (Trans s a ou s') ≠ v) ∧ K s' v"
shows "exit s v"
proof-
let ?K = "λ s. reachNT s ∧ K s v"
show ?thesis using assms by (intro exit_coind[of ?K])
(metis reachNT_reach IO_Automaton.validTrans reachNT.Step trans.exhaust_sel)+
qed
lemma exitI2_noVal2:
assumes rs: "reachNT s" and K: "K s v"
and "invarNT (λ s. K s v)" and "noVal2 K v"
shows "exit s v"
proof-
let ?K = "λ s. reachNT s ∧ K s v"
show ?thesis using assms unfolding invarNT_def noVal2_def
by (intro exit_coind[of ?K]) (metis IO_Automaton.validTrans reachNT.Step trans.exhaust_sel)+
qed
lemma exit_validFrom:
assumes vl: "vl ≠ []" and i: "exit s (hd vl)" and v: "validFrom s tr" and V: "V tr = vl"
and T: "never T tr"
shows False
using i v V T proof(induction tr arbitrary: s)
case Nil thus ?case by (metis V_simps(1) vl)
next
case (Cons trn tr s)
show ?case
proof(cases "φ trn")
case True
hence "f trn = hd vl" using Cons by (metis V_simps(3) hd_Cons_tl list.inject vl)
moreover have "validFrom s [trn]" using ‹validFrom s (trn # tr)›
unfolding validFrom_def by auto
ultimately show ?thesis using Cons True unfolding exit_def
by (elim allE[of _ "[]"]) auto
next
case False
hence "V tr = vl" using Cons by auto
moreover have "never T tr" by (metis Cons.prems list_all_simps)
moreover from ‹validFrom s (trn # tr)› have "validFrom (tgtOf trn) tr" and s: "s = srcOf trn"
by (metis list.distinct(1) validFrom_def valid_ConsE Cons.prems(2)
validFrom_def list.discI list.sel(1))+
moreover have "exit (tgtOf trn) (hd vl)" using ‹exit s (hd vl)›
unfolding exit_def s by simp
(metis (no_types) Cons.prems(2) Cons.prems(4) append_Cons list.sel(1)
list.distinct list_all_simps valid.Cons validFrom_def valid_ConsE)
ultimately show ?thesis using Cons(1) by auto
qed
qed
definition unwind where
"unwind Δ ≡
∀ s vl s1 vl1.
reachNT s ∧ reach s1 ∧ Δ s vl s1 vl1
⟶
(vl ≠ [] ∧ exit s (hd vl))
∨
iaction Δ s vl s1 vl1
∨
((vl ≠ [] ∨ vl1 = []) ∧ reaction Δ s vl s1 vl1)"
lemma unwindI[intro?]:
assumes
"⋀ s vl s1 vl1.
⟦reachNT s; reach s1; Δ s vl s1 vl1⟧
⟹
(vl ≠ [] ∧ exit s (hd vl))
∨
iaction Δ s vl s1 vl1
∨
((vl ≠ [] ∨ vl1 = []) ∧ reaction Δ s vl s1 vl1)"
shows "unwind Δ"
using assms unfolding unwind_def by auto
lemma unwind_trace:
assumes unwind: "unwind Δ" and "reachNT s" and "reach s1" and "Δ s vl s1 vl1"
and "validFrom s tr" and "never T tr" and "V tr = vl"
shows "∃tr1. validFrom s1 tr1 ∧ O tr1 = O tr ∧ V tr1 = vl1"
proof-
let ?S = "λ tr vl1.
∀ s vl s1. reachNT s ∧ reach s1 ∧ Δ s vl s1 vl1 ∧ validFrom s tr ∧ never T tr ∧ V tr = vl ⟶
(∃tr1. validFrom s1 tr1 ∧ O tr1 = O tr ∧ V tr1 = vl1)"
let ?f = "λ tr vl1. length tr + length vl1"
have "?S tr vl1"
proof(induct rule: measure_induct2[of ?f ?S])
case (IH tr vl1)
show ?case
proof(intro allI impI, elim conjE)
fix s vl s1 assume rs: "reachNT s" and rs1: "reach s1" and Δ: "Δ s vl s1 vl1"
and v: "validFrom s tr" and NT: "never T tr" and V: "V tr = vl"
hence "(vl ≠ [] ∧ exit s (hd vl)) ∨
iaction Δ s vl s1 vl1 ∨
(reaction Δ s vl s1 vl1 ∧ ¬ iaction Δ s vl s1 vl1)"
(is "?exit ∨ ?iact ∨ ?react ∧ _")
using unwind unfolding unwind_def by metis
thus "∃tr1. validFrom s1 tr1 ∧ O tr1 = O tr ∧ V tr1 = vl1"
proof safe
assume "vl ≠ []" and "exit s (hd vl)"
hence False using v V exit_validFrom NT by auto
thus ?thesis by auto
next
assume ?iact
thus ?thesis unfolding iaction_def Let_def proof safe
fix al1 :: "'act list" and vl1'
let ?tr1 = "traceOf s1 al1" let ?s1' = "tgtOf (last ?tr1)"
assume φ1: "list_ex φ (traceOf s1 al1)" and c: "consumeList ?tr1 vl1 vl1'"
and γ: "never γ ?tr1" and Δ: "Δ s vl ?s1' vl1'"
from φ1 have tr1: "?tr1 ≠ []" and len_V1: "length (V ?tr1) > 0"
by (auto iff: list_ex_iff_length_V)
with c have "length vl1' < length vl1" unfolding consumeList_def by auto
moreover have "reach ?s1'" using rs1 tr1 by (intro validFrom_reach) auto
ultimately obtain tr1' where "validFrom ?s1' tr1'" and "O tr1' = O tr" and "V tr1' = vl1'"
using IH[of tr vl1'] rs Δ v NT V by auto
then show ?thesis using tr1 γ c unfolding consumeList_def
by (intro exI[of _ "?tr1 @ tr1'"])
(auto simp: O_append O_Nil_never V_append validFrom_append)
qed
next
assume react: ?react and iact: "¬ ?iact"
show ?thesis
proof(cases tr)
case Nil note tr = Nil
hence vl: "vl = []" using V by simp
show ?thesis proof(cases vl1)
case Nil note vl1 = Nil
show ?thesis using IH[of tr vl1] Δ V NT V unfolding tr vl1 by auto
next
case Cons
hence False using vl unwind rs rs1 Δ iact unfolding unwind_def by auto
thus ?thesis by auto
qed
next
case (Cons trn tr') note tr = Cons
show ?thesis
proof(cases trn)
case (Trans ss a ou s') note trn = Trans let ?trn = "Trans s a ou s'"
have ss: "ss = s" using trn v unfolding tr validFrom_def by auto
have Ta: "¬ T ?trn" and s: "s = srcOf trn" and vtrans: "validTrans ?trn"
and v': "validFrom s' tr'" and NT': "never T tr'"
using v NT V unfolding tr validFrom_def trn by auto
have rs': "reachNT s'" using rs vtrans Ta by (auto intro: reachNT_PairI)
{assume "φ ?trn" hence "vl ≠ [] ∧ f ?trn = hd vl" using V unfolding tr trn ss by auto
}
then obtain vl' where c: "consume ?trn vl vl'"
using ex_consume_φ ex_consume_NO by metis
have V': "V tr' = vl'" using V c unfolding tr trn ss consume_def
by (cases "φ ?trn") (simp_all, metis list.sel(2-3))
have "match Δ s s1 vl1 a ou s' vl' ∨ ignore Δ s s1 vl1 a ou s' vl'" (is "?match ∨ ?ignore")
using react unfolding reaction_def using vtrans Ta c by auto
thus ?thesis proof safe
assume ?match
thus ?thesis unfolding match_def Let_def proof (elim exE conjE)
fix al1 :: "'act list" and vl1'
let ?tr = "traceOf s1 al1"
let ?s1' = "tgtOf (last ?tr)"
assume al1: "al1 ≠ []"
and c: "consumeList ?tr vl1 vl1'"
and O: "O ?tr = O [Trans s a ou s']"
and Δ: "Δ s' vl' ?s1' vl1'"
from c have len: "length tr' + length vl1' < length tr + length vl1"
using tr unfolding consumeList_def by auto
have "reach ?s1'" using rs1 al1 by (intro validFrom_reach) auto
then obtain tr1' where "validFrom ?s1' tr1'" and "O tr1' = O tr'" and "V tr1' = vl1'"
using IH[OF len] rs' Δ v' NT' V' tr by auto
then show ?thesis using c O al1 unfolding consumeList_def tr trn ss
by (intro exI[of _ "?tr @ tr1'"])
(cases "γ ?trn"; auto simp: O_append O_Nil_never V_append validFrom_append)
qed
next
assume ?ignore
thus ?thesis unfolding ignore_def Let_def proof (elim exE conjE)
assume γ: "¬ γ ?trn" and Δ: "Δ s' vl' s1 vl1"
obtain tr1 where v1: "validFrom s1 tr1" and O: "O tr1 = O tr'" and V: "V tr1 = vl1"
using IH[of tr' vl1] rs' rs1 Δ v' NT' V' c unfolding tr by auto
show ?thesis
apply(intro exI[of _ tr1])
using v1 O V γ unfolding tr trn ss by auto
qed
qed
qed
qed
qed
qed
qed
thus ?thesis using assms by auto
qed
theorem unwind_secure:
assumes init: "⋀ vl vl1. B vl vl1 ⟹ Δ istate vl istate vl1"
and unwind: "unwind Δ"
shows secure
using assms unwind_trace unfolding secure_def by (blast intro: reach.Istate reachNT.Istate)
end
end