Theory CompositionalRefinement
theory CompositionalRefinement
imports Dependent_SIFUM_Type_Systems.Compositionality
begin
lemma inj_card_le:
"inj (f::'a ⇒ 'b) ⟹ finite (UNIV::'b set) ⟹ card (UNIV::'a set) ≤ card (UNIV::'b set)"
by (blast intro: card_inj_on_le)
text ‹
We define a generic locale for capturing refinement between an abstract and a concrete
program. We then define and prove sufficient, conditions that preserve local security
from the abstract to the concrete program.
Below we define a second locale that is more restrictive than this one. Specifically, this
one allows the concrete program to have extra variables not present in the abstract one.
These variables might be used, for instance, to implement a runtime stack that was implicit
in the semantics of the abstract program; or as temporary storage for expression evaluation
that may (appear to be) atomic in the abstract semantics.
The simpler locale below forbids extra variables in the concrete program, making the
necessary conditions for preservation of local security simpler.
›
locale sifum_refinement =
abs: sifum_security dma⇩A 𝒞_vars⇩A 𝒞⇩A eval⇩A some_val +
conc: sifum_security dma⇩C 𝒞_vars⇩C 𝒞⇩C eval⇩C some_val
for dma⇩A :: "('Var⇩A,'Val) Mem ⇒ 'Var⇩A ⇒ Sec"
and dma⇩C :: "('Var⇩C,'Val) Mem ⇒ 'Var⇩C ⇒ Sec"
and 𝒞_vars⇩A :: "'Var⇩A ⇒ 'Var⇩A set"
and 𝒞_vars⇩C :: "'Var⇩C ⇒ 'Var⇩C set"
and 𝒞⇩A :: "'Var⇩A set"
and 𝒞⇩C :: "'Var⇩C set"
and eval⇩A :: "('Com⇩A, 'Var⇩A, 'Val) LocalConf rel"
and eval⇩C :: "('Com⇩C, 'Var⇩C, 'Val) LocalConf rel"
and some_val :: "'Val" +
fixes var⇩C_of :: "'Var⇩A ⇒ 'Var⇩C"
assumes var⇩C_of_inj: "inj var⇩C_of"
assumes dma_consistent:
"dma⇩A (λx⇩A. mem⇩C (var⇩C_of x⇩A)) x⇩A = dma⇩C mem⇩C (var⇩C_of x⇩A)"
assumes 𝒞_vars_consistent:
"(var⇩C_of ` 𝒞_vars⇩A x⇩A) = 𝒞_vars⇩C (var⇩C_of x⇩A)"
assumes control_vars_are_A_vars:
"𝒞⇩C = var⇩C_of ` 𝒞⇩A"
section "General Compositional Refinement"
text ‹
The type of state relations between the abstract and compiled components.
The job of a certifying compiler will be to exhibit one of these for each
component it compiles. Below we'll define the conditions that such a
relation needs to satisfy to give compositional refinement.
›
type_synonym ('Com⇩A, 'Var⇩A, 'Val, 'Com⇩C, 'Var⇩C) state_relation =
"(('Com⇩A, 'Var⇩A, 'Val) LocalConf × ('Com⇩C, 'Var⇩C, 'Val) LocalConf) set"
context sifum_refinement begin
abbreviation
conf_abv⇩A :: "'Com⇩A ⇒ 'Var⇩A Mds ⇒ ('Var⇩A, 'Val) Mem ⇒ (_,_,_) LocalConf"
("⟨_, _, _⟩⇩A" [0, 0, 0] 1000)
where
"⟨ c, mds, mem ⟩⇩A ≡ ((c, mds), mem)"
abbreviation
conf_abv⇩C :: "'Com⇩C ⇒ 'Var⇩C Mds ⇒ ('Var⇩C, 'Val) Mem ⇒ (_,_,_) LocalConf"
("⟨_, _, _⟩⇩C" [0, 0, 0] 1000)
where
"⟨ c, mds, mem ⟩⇩C ≡ ((c, mds), mem)"
abbreviation
eval_abv⇩A :: "('Com⇩A, 'Var⇩A, 'Val) LocalConf ⇒ (_, _, _) LocalConf ⇒ bool"
(infixl "↝⇩A" 70)
where
"x ↝⇩A y ≡ (x, y) ∈ eval⇩A"
abbreviation
eval_abv⇩C :: "('Com⇩C, 'Var⇩C, 'Val) LocalConf ⇒ (_, _, _) LocalConf ⇒ bool"
(infixl "↝⇩C" 70)
where
"x ↝⇩C y ≡ (x, y) ∈ eval⇩C"
definition
preserves_modes_mem :: "('Com⇩A, 'Var⇩A, 'Val, 'Com⇩C, 'Var⇩C) state_relation ⇒ bool"
where
"preserves_modes_mem ℛ ≡
(∀ c⇩A mds⇩A mem⇩A c⇩C mds⇩C mem⇩C. (⟨ c⇩A, mds⇩A, mem⇩A ⟩⇩A, ⟨ c⇩C, mds⇩C, mem⇩C ⟩⇩C) ∈ ℛ ⟶
(∀x⇩A. (mem⇩A x⇩A) = (mem⇩C (var⇩C_of x⇩A))) ∧
(∀m. var⇩C_of ` mds⇩A m = (range var⇩C_of) ∩ mds⇩C m))"
definition
mem⇩A_of :: "('Var⇩C, 'Val) Mem ⇒ ('Var⇩A, 'Val) Mem"
where
"mem⇩A_of mem⇩C ≡ (λx⇩A. (mem⇩C (var⇩C_of x⇩A)))"
definition
mds⇩A_of :: "'Var⇩C Mds ⇒ 'Var⇩A Mds"
where
"mds⇩A_of mds⇩C ≡ (λ m. (inv var⇩C_of) ` (range var⇩C_of ∩ mds⇩C m))"
lemma low_mds_eq_from_conc_to_abs:
"conc.low_mds_eq mds mem mem' ⟹ abs.low_mds_eq (mds⇩A_of mds) (mem⇩A_of mem) (mem⇩A_of mem')"
apply(clarsimp simp: abs.low_mds_eq_def conc.low_mds_eq_def mem⇩A_of_def mds⇩A_of_def)
using var⇩C_of_inj
by (metis IntI control_vars_are_A_vars dma_consistent image_eqI inv_f_f rangeI)
definition
var⇩A_of :: "'Var⇩C ⇒ 'Var⇩A"
where
"var⇩A_of ≡ inv var⇩C_of"
lemma preserves_modes_mem_mem⇩A_simp:
"(∀x⇩A. (mem⇩A x⇩A) = (mem⇩C (var⇩C_of x⇩A))) ⟹
mem⇩A = mem⇩A_of mem⇩C"
unfolding mem⇩A_of_def by blast
lemma preserves_modes_mem_mds⇩A_simp:
"(∀m. var⇩C_of ` mds⇩A m = range (var⇩C_of) ∩ mds⇩C m) ⟹
mds⇩A = mds⇩A_of mds⇩C"
unfolding mds⇩A_of_def
apply(rule ext)
apply(drule_tac x=m in spec)
apply(rule equalityI)
apply clarsimp
apply(rename_tac x⇩A)
apply(drule equalityD1)
apply(drule_tac c="var⇩C_of x⇩A" in subsetD)
apply blast
unfolding image_def
apply clarsimp
apply(rule_tac x="var⇩C_of x⇩A" in bexI)
apply(rule sym)
apply(rule inv_f_f[OF var⇩C_of_inj])
apply(drule inj_onD[OF var⇩C_of_inj])
apply blast+
apply clarsimp
apply(rename_tac x⇩A)
apply(simp add: inv_f_f[OF var⇩C_of_inj])
apply(drule equalityD2)
apply(drule_tac c="var⇩C_of x⇩A" in subsetD)
apply blast
apply clarsimp
apply(drule inj_onD[OF var⇩C_of_inj])
apply blast+
done
text ‹
This version might be more useful. Not sure yet.
›
lemma preserves_modes_mem_def2:
"preserves_modes_mem ℛ =
(∀ c⇩A mds⇩A mem⇩A c⇩C mds⇩C mem⇩C. (⟨ c⇩A, mds⇩A, mem⇩A ⟩⇩A, ⟨ c⇩C, mds⇩C, mem⇩C ⟩⇩C) ∈ ℛ ⟶
mem⇩A = mem⇩A_of mem⇩C ∧
mds⇩A = mds⇩A_of mds⇩C)"
unfolding preserves_modes_mem_def
apply(rule iffI)
apply(blast dest: preserves_modes_mem_mem⇩A_simp preserves_modes_mem_mds⇩A_simp)
apply safe
apply(elim allE impE, assumption, elim conjE)
apply(simp add: mem⇩A_of_def)
apply blast
apply clarsimp
apply(rename_tac x⇩A)
apply(elim allE impE, assumption, elim conjE)
apply clarsimp
apply(clarsimp simp: mds⇩A_of_def image_def)
apply(simp add: inv_f_f[OF var⇩C_of_inj])
apply clarsimp
apply(rename_tac x⇩A)
apply(rule imageI)
apply(elim allE impE, assumption, elim conjE)
apply(clarsimp simp: mds⇩A_of_def)
apply(subst image_def)
apply clarify
apply(rule_tac x="var⇩C_of x⇩A" in bexI)
apply(simp add: inv_f_f[OF var⇩C_of_inj])
apply blast
done
definition
closed_others :: "('Com⇩A, 'Var⇩A, 'Val, 'Com⇩C, 'Var⇩C) state_relation ⇒ bool"
where
"closed_others ℛ ≡
(∀ c⇩A c⇩C mds⇩C mem⇩C mem⇩C'. (⟨ c⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩C ⟩⇩A, ⟨ c⇩C, mds⇩C, mem⇩C ⟩⇩C) ∈ ℛ ⟶
(∀x. mem⇩C x ≠ mem⇩C' x ⟶ ¬ var_asm_not_written mds⇩C x) ⟶
(∀x. dma⇩C mem⇩C x ≠ dma⇩C mem⇩C' x ⟶ ¬ var_asm_not_written mds⇩C x) ⟶
(⟨ c⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩C' ⟩⇩A, ⟨ c⇩C, mds⇩C, mem⇩C' ⟩⇩C) ∈ ℛ)"
definition
stops⇩C :: "('Com⇩C, 'Var⇩C, 'Val) LocalConf ⇒ bool"
where
"stops⇩C c ≡ ∀c'. ¬ (c ↝⇩C c')"
lemmas neval_induct = abs.neval.induct[consumes 1, case_names Zero Suc]
lemma strong_low_bisim_neval':
"abs.neval c⇩1 n c⇩n ⟹ (c⇩1,c⇩1') ∈ ℛ⇩A ⟹ snd (fst c⇩1) = snd (fst c⇩1') ⟹ abs.strong_low_bisim_mm ℛ⇩A ⟹
∃c⇩n'. abs.neval c⇩1' n c⇩n' ∧ (c⇩n,c⇩n') ∈ ℛ⇩A ∧ snd (fst c⇩n) = snd (fst (c⇩n'))"
proof(induct arbitrary: c⇩1' rule: neval_induct)
case (Zero c⇩1 c⇩n)
hence "abs.neval c⇩1' 0 c⇩1' ∧ (c⇩n, c⇩1') ∈ ℛ⇩A ∧ snd (fst c⇩n) = snd (fst c⇩1')"
by(blast intro: abs.neval.intros(1))
thus ?case by blast
next
case (Suc lc⇩0 lc⇩1 n lc⇩n lc⇩0')
obtain c⇩0 mds⇩0 mem⇩0
where [simp]: "lc⇩0 = ⟨c⇩0, mds⇩0, mem⇩0⟩⇩A" by (case_tac lc⇩0, auto)
obtain c⇩1 mds⇩1 mem⇩1
where [simp]: "lc⇩1 = ⟨c⇩1, mds⇩1, mem⇩1⟩⇩A" by (case_tac lc⇩1, auto)
from ‹snd (fst lc⇩0) = snd (fst lc⇩0')› obtain c⇩0' mem⇩0'
where [simp]: "lc⇩0' = ⟨c⇩0', mds⇩0, mem⇩0'⟩⇩A" by (case_tac lc⇩0', auto)
from ‹(lc⇩0, lc⇩0') ∈ ℛ⇩A›[simplified] ‹lc⇩0 ↝⇩A lc⇩1›[simplified] ‹abs.strong_low_bisim_mm ℛ⇩A›
obtain c⇩1' mem⇩1' where a: "⟨c⇩0',mds⇩0, mem⇩0'⟩⇩A ↝⇩A ⟨c⇩1',mds⇩1, mem⇩1'⟩⇩A" and
b: "(⟨c⇩1,mds⇩1,mem⇩1⟩⇩A,⟨c⇩1',mds⇩1, mem⇩1'⟩⇩A) ∈ ℛ⇩A"
unfolding abs.strong_low_bisim_mm_def
by blast
from this Suc.hyps Suc(6) obtain lc⇩S' where "abs.neval ⟨c⇩1',mds⇩1,mem⇩1'⟩⇩A n lc⇩S'" and "(lc⇩n, lc⇩S') ∈ ℛ⇩A" and "snd (fst lc⇩n) = snd (fst lc⇩S')"
by force
with Suc this a b show ?case by(fastforce intro: abs.neval.intros(2))
qed
lemma strong_low_bisim_neval:
"abs.neval ⟨c⇩1,mds⇩1,mem⇩1⟩⇩A n ⟨c⇩n,mds⇩n,mem⇩n⟩⇩A ⟹ (⟨c⇩1,mds⇩1,mem⇩1⟩⇩A,⟨c⇩1',mds⇩1,mem⇩1'⟩⇩A) ∈ ℛ⇩A ⟹ abs.strong_low_bisim_mm ℛ⇩A ⟹
∃c⇩n' mem⇩n'. abs.neval ⟨c⇩1',mds⇩1,mem⇩1'⟩⇩A n ⟨c⇩n',mds⇩n,mem⇩n'⟩⇩A ∧ (⟨c⇩n,mds⇩n,mem⇩n⟩⇩A,⟨c⇩n',mds⇩n,mem⇩n'⟩⇩A) ∈ ℛ⇩A"
by(drule strong_low_bisim_neval', simp+)
lemma in_ℛ_dma':
assumes preserves: "preserves_modes_mem ℛ"
assumes in_ℛ: "(⟨c⇩A,mds⇩A,mem⇩A⟩⇩A,⟨c⇩C,mds⇩C,mem⇩C⟩⇩C) ∈ ℛ"
shows "dma⇩A mem⇩A x⇩A = dma⇩C mem⇩C (var⇩C_of x⇩A)"
proof -
from assms have
mds⇩A_def: "mds⇩A = mds⇩A_of mds⇩C" and
mem⇩A_def: "mem⇩A = mem⇩A_of mem⇩C"
unfolding preserves_modes_mem_def2 by blast+
have "dma⇩A (mem⇩A_of mem⇩C) x⇩A = dma⇩C mem⇩C (var⇩C_of x⇩A)"
unfolding mem⇩A_of_def
by(rule dma_consistent)
thus ?thesis
by(simp add: mem⇩A_def)
qed
lemma in_ℛ_dma:
assumes preserves: "preserves_modes_mem ℛ"
assumes in_ℛ: "(⟨c⇩A,mds⇩A,mem⇩A⟩⇩A,⟨c⇩C,mds⇩C,mem⇩C⟩⇩C) ∈ ℛ"
shows "dma⇩A mem⇩A = (dma⇩C mem⇩C ∘ var⇩C_of)"
unfolding o_def
using assms by(blast intro: in_ℛ_dma')
definition
new_vars_private :: "('Com⇩A, 'Var⇩A, 'Val, 'Com⇩C, 'Var⇩C) state_relation ⇒ bool"
where
"new_vars_private ℛ ≡
(∀ c⇩1⇩A mds⇩A mem⇩1⇩A c⇩1⇩C mds⇩C mem⇩1⇩C.
(⟨ c⇩1⇩A, mds⇩A, mem⇩1⇩A ⟩⇩A, ⟨ c⇩1⇩C, mds⇩C, mem⇩1⇩C ⟩⇩C) ∈ ℛ ⟶
(∀ c⇩1⇩C' mds⇩C' mem⇩1⇩C'. ⟨ c⇩1⇩C, mds⇩C, mem⇩1⇩C ⟩⇩C ↝⇩C ⟨ c⇩1⇩C', mds⇩C', mem⇩1⇩C' ⟩⇩C ⟶
(∀v⇩C. (mem⇩1⇩C' v⇩C ≠ mem⇩1⇩C v⇩C ∨ dma⇩C mem⇩1⇩C' v⇩C < dma⇩C mem⇩1⇩C v⇩C) ∧ v⇩C ∉ range var⇩C_of ⟶ v⇩C ∈ mds⇩C' AsmNoReadOrWrite) ∧
(mds⇩C AsmNoReadOrWrite - (range var⇩C_of)) ⊆ (mds⇩C' AsmNoReadOrWrite - (range var⇩C_of))))"
lemma not_less_eq_is_greater_Sec:
"(¬ a ≤ (b::Sec)) = (a > b)"
unfolding less_Sec_def less_eq_Sec_def using Sec.exhaust by blast
lemma doesnt_have_mode:
"(x ∉ mds⇩A_of mds⇩C m) = (var⇩C_of x ∉ mds⇩C m)"
apply(clarsimp simp: mds⇩A_of_def image_def)
apply(rule iffI)
apply clarsimp
apply(drule_tac x="var⇩C_of x" in bspec)
apply blast
apply(simp add: inv_f_f[OF var⇩C_of_inj])
apply(clarify)
apply(simp add: inv_f_f[OF var⇩C_of_inj])
done
lemma new_vars_private_does_the_thing:
assumes nice: "new_vars_private ℛ"
assumes in_ℛ⇩1: "(⟨ c⇩1⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩1⇩C ⟩⇩A, ⟨ c⇩1⇩C, mds⇩C, mem⇩1⇩C ⟩⇩C) ∈ ℛ"
assumes in_ℛ⇩2: "(⟨ c⇩2⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩2⇩C ⟩⇩A, ⟨ c⇩2⇩C, mds⇩C, mem⇩2⇩C ⟩⇩C) ∈ ℛ"
assumes step⇩1⇩C: "⟨ c⇩1⇩C, mds⇩C, mem⇩1⇩C ⟩⇩C ↝⇩C ⟨ c⇩1⇩C', mds⇩C', mem⇩1⇩C' ⟩⇩C"
assumes step⇩2⇩C: "⟨ c⇩2⇩C, mds⇩C, mem⇩2⇩C ⟩⇩C ↝⇩C ⟨ c⇩2⇩C', mds⇩C', mem⇩2⇩C' ⟩⇩C"
assumes low_mds_eq⇩C: "conc.low_mds_eq mds⇩C mem⇩1⇩C mem⇩2⇩C"
assumes low_mds_eq⇩A': "abs.low_mds_eq (mds⇩A_of mds⇩C') (mem⇩A_of mem⇩1⇩C') (mem⇩A_of mem⇩2⇩C')"
shows "conc.low_mds_eq mds⇩C' mem⇩1⇩C' mem⇩2⇩C'"
unfolding conc.low_mds_eq_def
proof(clarify)
let ?mem⇩1⇩A = "mem⇩A_of mem⇩1⇩C"
let ?mem⇩2⇩A = "mem⇩A_of mem⇩2⇩C"
let ?mem⇩1⇩A' = "mem⇩A_of mem⇩1⇩C'"
let ?mem⇩2⇩A' = "mem⇩A_of mem⇩2⇩C'"
let ?mds⇩A = "mds⇩A_of mds⇩C"
let ?mds⇩A' = "mds⇩A_of mds⇩C'"
fix x⇩C
assume is_Low⇩C': "dma⇩C mem⇩1⇩C' x⇩C = Low"
assume is_readable⇩C': "x⇩C ∈ 𝒞⇩C ∨ x⇩C ∉ mds⇩C' AsmNoReadOrWrite"
show "mem⇩1⇩C' x⇩C = mem⇩2⇩C' x⇩C"
proof(cases "dma⇩C mem⇩1⇩C' x⇩C ≥ dma⇩C mem⇩1⇩C x⇩C ∧ mem⇩1⇩C' x⇩C = mem⇩1⇩C x⇩C ∧ mem⇩2⇩C' x⇩C = mem⇩2⇩C x⇩C ∧ (x⇩C ∈ mds⇩C AsmNoReadOrWrite ⟶ x⇩C ∈ mds⇩C' AsmNoReadOrWrite)")
assume easy: "dma⇩C mem⇩1⇩C' x⇩C ≥ dma⇩C mem⇩1⇩C x⇩C ∧ mem⇩1⇩C' x⇩C = mem⇩1⇩C x⇩C ∧ mem⇩2⇩C' x⇩C = mem⇩2⇩C x⇩C ∧ (x⇩C ∈ mds⇩C AsmNoReadOrWrite ⟶ x⇩C ∈ mds⇩C' AsmNoReadOrWrite)"
with is_Low⇩C' have is_Low⇩C: "dma⇩C mem⇩1⇩C x⇩C = Low" by (simp add: less_eq_Sec_def)
from easy is_readable⇩C' have is_readable⇩C: "x⇩C ∈ 𝒞⇩C ∨ x⇩C ∉ mds⇩C AsmNoReadOrWrite" by blast
from is_Low⇩C is_readable⇩C low_mds_eq⇩C have "mem⇩1⇩C x⇩C = mem⇩2⇩C x⇩C"
unfolding conc.low_mds_eq_def by blast
with easy show ?thesis by metis
next
assume a: "¬ (dma⇩C mem⇩1⇩C x⇩C ≤ dma⇩C mem⇩1⇩C' x⇩C ∧
mem⇩1⇩C' x⇩C = mem⇩1⇩C x⇩C ∧
mem⇩2⇩C' x⇩C = mem⇩2⇩C x⇩C ∧ (x⇩C ∈ mds⇩C AsmNoReadOrWrite ⟶ x⇩C ∈ mds⇩C' AsmNoReadOrWrite))"
hence a_disj: "(dma⇩C mem⇩1⇩C x⇩C > dma⇩C mem⇩1⇩C' x⇩C ∨
mem⇩1⇩C' x⇩C ≠ mem⇩1⇩C x⇩C ∨
mem⇩2⇩C' x⇩C ≠ mem⇩2⇩C x⇩C ∨ (x⇩C ∈ mds⇩C AsmNoReadOrWrite ∧ x⇩C ∉ mds⇩C' AsmNoReadOrWrite))"
using not_less_eq_is_greater_Sec by blast
show "mem⇩1⇩C' x⇩C = mem⇩2⇩C' x⇩C"
proof(cases "x⇩C ∈ range var⇩C_of")
assume C_only_var: "x⇩C ∉ range var⇩C_of"
with in_ℛ⇩1 step⇩1⇩C nice
have "(mem⇩1⇩C' x⇩C ≠ mem⇩1⇩C x⇩C ∨ dma⇩C mem⇩1⇩C' x⇩C < dma⇩C mem⇩1⇩C x⇩C) ⟶ x⇩C ∈ mds⇩C' AsmNoReadOrWrite"
unfolding new_vars_private_def by blast
moreover from C_only_var in_ℛ⇩2 step⇩2⇩C nice have "(mem⇩2⇩C' x⇩C ≠ mem⇩2⇩C x⇩C) ⟶ x⇩C ∈ mds⇩C' AsmNoReadOrWrite"
unfolding new_vars_private_def by blast
moreover from C_only_var in_ℛ⇩1 step⇩1⇩C nice have "x⇩C ∈ mds⇩C AsmNoReadOrWrite ⟶ x⇩C ∈ mds⇩C' AsmNoReadOrWrite" unfolding new_vars_private_def by blast
moreover from C_only_var is_readable⇩C' have "x⇩C ∉ mds⇩C' AsmNoReadOrWrite"
using control_vars_are_A_vars by blast
ultimately have False using a_disj by blast
thus ?thesis by blast
next
assume in_val⇩C_of: "x⇩C ∈ range var⇩C_of"
from this obtain x⇩A where x⇩C_def: "x⇩C = var⇩C_of x⇩A" by blast
from is_Low⇩C' have is_Low⇩A': "dma⇩A ?mem⇩1⇩A' x⇩A = Low"
using dma_consistent unfolding mem⇩A_of_def x⇩C_def by force
from is_readable⇩C' have is_readable⇩A': "x⇩A ∈ 𝒞⇩A ∨ x⇩A ∉ ?mds⇩A' AsmNoReadOrWrite"
using control_vars_are_A_vars x⇩C_def doesnt_have_mode[symmetric] var⇩C_of_inj inj_image_mem_iff by fast
with is_Low⇩A' low_mds_eq⇩A' have x⇩A_eq': "?mem⇩1⇩A' x⇩A = ?mem⇩2⇩A' x⇩A"
unfolding abs.low_mds_eq_def by blast
thus ?thesis by(simp add: mem⇩A_of_def x⇩C_def)
qed
qed
qed
text ‹
Perhaps surprisingly, we don't necessarily
care whether the refinement preserves
termination or divergence behaviour from the source to the target program.
It can do whatever it likes, so long as it transforms two source programs
that are low bisimilar (i.e. perform the same low actions at the
same time), into two target ones that perform the same low actions at the
same time.
Having the concrete step correspond to zero abstract ones is like expanding
abstract code out (think e.g. of side-effect free expression evaluation).
Having the concrete step correspond to more than one abstract step is
like optimising out abstract code. But importantly, the optimisation needs
to look the same for abstract-bisimilar code.
Additionally, we allow the instantiation of this theory to supply
an arbitrary predicate that can be used to restrict our consideration to
pairs of concrete steps that correspond to each other in terms of progress.
This is particularly important for distinguishing between multiple concrete
steps derived from the expansion of a single abstract step.
›
definition
secure_refinement :: "('Com⇩A, 'Var⇩A, 'Val) LocalConf rel ⇒ ('Com⇩A, 'Var⇩A, 'Val, 'Com⇩C, 'Var⇩C) state_relation ⇒
('Com⇩C, 'Var⇩C, 'Val) LocalConf rel ⇒ bool"
where
"secure_refinement ℛ⇩A ℛ P ≡
closed_others ℛ ∧
preserves_modes_mem ℛ ∧
new_vars_private ℛ ∧
conc.closed_glob_consistent P ∧
(∀ c⇩1⇩A mds⇩A mem⇩1⇩A c⇩1⇩C mds⇩C mem⇩1⇩C.
(⟨ c⇩1⇩A, mds⇩A, mem⇩1⇩A ⟩⇩A, ⟨ c⇩1⇩C, mds⇩C, mem⇩1⇩C ⟩⇩C) ∈ ℛ ⟶
(∀ c⇩1⇩C' mds⇩C' mem⇩1⇩C'. ⟨ c⇩1⇩C, mds⇩C, mem⇩1⇩C ⟩⇩C ↝⇩C ⟨ c⇩1⇩C', mds⇩C', mem⇩1⇩C' ⟩⇩C ⟶
(∃ n c⇩1⇩A' mds⇩A' mem⇩1⇩A'. abs.neval ⟨ c⇩1⇩A, mds⇩A, mem⇩1⇩A ⟩⇩A n ⟨ c⇩1⇩A', mds⇩A', mem⇩1⇩A' ⟩⇩A ∧
(⟨ c⇩1⇩A', mds⇩A', mem⇩1⇩A' ⟩⇩A, ⟨ c⇩1⇩C', mds⇩C', mem⇩1⇩C' ⟩⇩C) ∈ ℛ ∧
(∀c⇩2⇩A mem⇩2⇩A c⇩2⇩C mem⇩2⇩C c⇩2⇩A' mem⇩2⇩A'.
(⟨ c⇩1⇩A, mds⇩A, mem⇩1⇩A ⟩⇩A, ⟨ c⇩2⇩A, mds⇩A, mem⇩2⇩A ⟩⇩A) ∈ ℛ⇩A ∧
(⟨ c⇩2⇩A, mds⇩A, mem⇩2⇩A ⟩⇩A, ⟨ c⇩2⇩C, mds⇩C, mem⇩2⇩C ⟩⇩C) ∈ ℛ ∧
(⟨ c⇩1⇩C, mds⇩C, mem⇩1⇩C ⟩⇩C, ⟨ c⇩2⇩C, mds⇩C, mem⇩2⇩C ⟩⇩C) ∈ P ∧
abs.neval ⟨ c⇩2⇩A, mds⇩A, mem⇩2⇩A ⟩⇩A n ⟨ c⇩2⇩A', mds⇩A', mem⇩2⇩A' ⟩⇩A ⟶
(∃ c⇩2⇩C' mem⇩2⇩C'. ⟨ c⇩2⇩C, mds⇩C, mem⇩2⇩C ⟩⇩C ↝⇩C ⟨ c⇩2⇩C', mds⇩C', mem⇩2⇩C' ⟩⇩C ∧
(⟨ c⇩2⇩A', mds⇩A', mem⇩2⇩A' ⟩⇩A, ⟨ c⇩2⇩C', mds⇩C', mem⇩2⇩C' ⟩⇩C) ∈ ℛ ∧
(⟨ c⇩1⇩C', mds⇩C', mem⇩1⇩C' ⟩⇩C, ⟨ c⇩2⇩C', mds⇩C', mem⇩2⇩C' ⟩⇩C) ∈ P)))))"
lemma preserves_modes_memD:
"⟦preserves_modes_mem ℛ; (⟨c⇩A, mds⇩A, mem⇩A⟩⇩A, ⟨c⇩C, mds⇩C, mem⇩C⟩⇩C) ∈ ℛ⟧ ⟹ mem⇩A = mem⇩A_of mem⇩C ∧ mds⇩A = mds⇩A_of mds⇩C"
using preserves_modes_mem_def2 by blast
lemma secure_refinement_def2:
"secure_refinement ℛ⇩A ℛ P ≡
closed_others ℛ ∧
preserves_modes_mem ℛ ∧
new_vars_private ℛ ∧
conc.closed_glob_consistent P ∧
(∀ c⇩1⇩A c⇩1⇩C mds⇩C mem⇩1⇩C.
(⟨ c⇩1⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩1⇩C ⟩⇩A, ⟨ c⇩1⇩C, mds⇩C, mem⇩1⇩C ⟩⇩C) ∈ ℛ ⟶
(∀ c⇩1⇩C' mds⇩C' mem⇩1⇩C'. ⟨ c⇩1⇩C, mds⇩C, mem⇩1⇩C ⟩⇩C ↝⇩C ⟨ c⇩1⇩C', mds⇩C', mem⇩1⇩C' ⟩⇩C ⟶
(∃ n c⇩1⇩A'. abs.neval ⟨ c⇩1⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩1⇩C ⟩⇩A n ⟨ c⇩1⇩A', mds⇩A_of mds⇩C', mem⇩A_of mem⇩1⇩C' ⟩⇩A ∧
(⟨ c⇩1⇩A', mds⇩A_of mds⇩C', mem⇩A_of mem⇩1⇩C' ⟩⇩A, ⟨ c⇩1⇩C', mds⇩C', mem⇩1⇩C' ⟩⇩C) ∈ ℛ ∧
(∀c⇩2⇩A c⇩2⇩C mem⇩2⇩C c⇩2⇩A' mem⇩2⇩A'.
(⟨ c⇩1⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩1⇩C ⟩⇩A, ⟨ c⇩2⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩2⇩C ⟩⇩A) ∈ ℛ⇩A ∧
(⟨ c⇩2⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩2⇩C ⟩⇩A, ⟨ c⇩2⇩C, mds⇩C, mem⇩2⇩C ⟩⇩C) ∈ ℛ ∧
(⟨ c⇩1⇩C, mds⇩C, mem⇩1⇩C ⟩⇩C, ⟨ c⇩2⇩C, mds⇩C, mem⇩2⇩C ⟩⇩C) ∈ P ∧
abs.neval ⟨ c⇩2⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩2⇩C ⟩⇩A n ⟨ c⇩2⇩A', mds⇩A_of mds⇩C', mem⇩2⇩A' ⟩⇩A ⟶
(∃ c⇩2⇩C' mem⇩2⇩C'. ⟨ c⇩2⇩C, mds⇩C, mem⇩2⇩C ⟩⇩C ↝⇩C ⟨ c⇩2⇩C', mds⇩C', mem⇩2⇩C' ⟩⇩C ∧
(⟨ c⇩2⇩A', mds⇩A_of mds⇩C', mem⇩2⇩A' ⟩⇩A, ⟨ c⇩2⇩C', mds⇩C', mem⇩2⇩C' ⟩⇩C) ∈ ℛ ∧
(⟨ c⇩1⇩C', mds⇩C', mem⇩1⇩C' ⟩⇩C, ⟨ c⇩2⇩C', mds⇩C', mem⇩2⇩C' ⟩⇩C) ∈ P)))))"
apply(rule eq_reflection)
unfolding secure_refinement_def
apply(rule conj_cong)
apply(fastforce)
apply(rule conj_cong)
apply(fastforce)
apply(rule conj_cong)
apply(fastforce)
apply(rule conj_cong, fastforce)
apply(rule iffI)
apply(intro allI conjI impI)
apply((drule spec)+,erule (1) impE)
apply((drule spec)+,erule (1) impE)
using preserves_modes_memD apply metis
apply(intro allI conjI impI)
apply(frule (1) preserves_modes_memD, clarify)
apply((drule spec)+,erule (1) impE)
apply((drule spec)+,erule (1) impE)
using preserves_modes_memD apply metis
done
lemma :
"x ∉ range var⇩C_of ⟹ x ∉ 𝒞⇩C"
proof(erule contrapos_nn)
assume "x ∈ 𝒞⇩C"
from this obtain x⇩A where "x = var⇩C_of x⇩A"
using control_vars_are_A_vars by blast
thus "x ∈ range var⇩C_of" by blast
qed
definition
R⇩C_of ::
"((('Com⇩A × (Mode ⇒ 'Var⇩A set)) × ('Var⇩A ⇒ 'Val)) ×
('Com⇩A × (Mode ⇒ 'Var⇩A set)) × ('Var⇩A ⇒ 'Val)) set ⇒
('Com⇩A, 'Var⇩A, 'Val, 'Com⇩C, 'Var⇩C) state_relation ⇒
((('Com⇩C × (Mode ⇒ 'Var⇩C set)) × ('Var⇩C ⇒ 'Val)) ×
('Com⇩C × (Mode ⇒ 'Var⇩C set)) × ('Var⇩C ⇒ 'Val)) set ⇒
((('Com⇩C × (Mode ⇒ 'Var⇩C set)) × ('Var⇩C ⇒ 'Val)) ×
('Com⇩C × (Mode ⇒ 'Var⇩C set)) × ('Var⇩C ⇒ 'Val)) set"
where
"R⇩C_of ℛ⇩A ℛ P ≡ {(x,y). ∃x⇩A y⇩A. (x⇩A,x) ∈ ℛ ∧ (y⇩A,y) ∈ ℛ ∧ (x⇩A,y⇩A) ∈ ℛ⇩A ∧
snd (fst x) = snd (fst y) ∧
conc.low_mds_eq (snd (fst x)) (snd x) (snd y) ∧
(x,y) ∈ P}"
lemma abs_low_mds_eq_dma⇩C_eq:
assumes "abs.low_mds_eq (mds⇩A_of mds) (mem⇩A_of mem⇩1⇩C) (mem⇩A_of mem⇩2⇩C)"
shows "dma⇩C mem⇩1⇩C = dma⇩C mem⇩2⇩C"
proof(rule conc.dma_𝒞, rule ballI)
fix x⇩C
assume "x⇩C ∈ 𝒞⇩C"
from this obtain x⇩A where "var⇩C_of x⇩A = x⇩C" and "x⇩A ∈ 𝒞⇩A" using control_vars_are_A_vars by blast
from assms ‹x⇩A ∈ 𝒞⇩A› have "(mem⇩A_of mem⇩1⇩C) x⇩A = (mem⇩A_of mem⇩2⇩C) x⇩A"
unfolding abs.low_mds_eq_def
using abs.𝒞_Low by blast
thus "(mem⇩1⇩C x⇩C) = (mem⇩2⇩C x⇩C)"
using ‹var⇩C_of x⇩A = x⇩C› unfolding mem⇩A_of_def by blast
qed
lemma R⇩C_ofD:
assumes rr: "secure_refinement ℛ⇩A ℛ P"
assumes in_R: "(⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C, ⟨c⇩2⇩C, mds⇩C', mem⇩2⇩C⟩⇩C) ∈ R⇩C_of ℛ⇩A ℛ P"
shows
"(∃c⇩1⇩A c⇩2⇩A. (⟨c⇩1⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩1⇩C⟩⇩A, ⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C) ∈ ℛ ∧
(⟨c⇩2⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩2⇩C⟩⇩A, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ ℛ ∧
(⟨c⇩1⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩1⇩C⟩⇩A, ⟨c⇩2⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩2⇩C⟩⇩A) ∈ ℛ⇩A) ∧
(mds⇩C' = mds⇩C) ∧
conc.low_mds_eq mds⇩C mem⇩1⇩C mem⇩2⇩C ∧
(⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C, ⟨c⇩2⇩C, mds⇩C', mem⇩2⇩C⟩⇩C) ∈ P"
proof -
have ℛ_preserves_modes_mem: "preserves_modes_mem ℛ"
using rr unfolding secure_refinement_def by blast
from in_R obtain c⇩1⇩A mds⇩1⇩A mem⇩1⇩A c⇩2⇩A mds⇩2⇩A mem⇩2⇩A where
in_ℛ⇩1: "(⟨c⇩1⇩A, mds⇩1⇩A, mem⇩1⇩A⟩⇩A, ⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C) ∈ ℛ" and
in_ℛ⇩2: "(⟨c⇩2⇩A, mds⇩2⇩A, mem⇩2⇩A⟩⇩A, ⟨c⇩2⇩C, mds⇩C', mem⇩2⇩C⟩⇩C) ∈ ℛ" and
in_ℛ⇩A: "(⟨c⇩1⇩A, mds⇩1⇩A, mem⇩1⇩A⟩⇩A, ⟨c⇩2⇩A, mds⇩2⇩A, mem⇩2⇩A⟩⇩A) ∈ ℛ⇩A" and
pred_holds: "(⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ P" and
mds_eq: "mds⇩C = mds⇩C'" and
mds_eq: "conc.low_mds_eq mds⇩C mem⇩1⇩C mem⇩2⇩C"
unfolding R⇩C_of_def by force+
from this ℛ_preserves_modes_mem[simplified preserves_modes_mem_def2, rule_format, OF in_ℛ⇩1] ℛ_preserves_modes_mem[simplified preserves_modes_mem_def2, rule_format, OF in_ℛ⇩2]
show ?thesis by blast
qed
lemma R⇩C_ofI:
"(⟨c⇩1⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩1⇩C⟩⇩A, ⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C) ∈ ℛ ⟹
(⟨c⇩2⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩2⇩C⟩⇩A, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ ℛ ⟹
(⟨c⇩1⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩1⇩C⟩⇩A, ⟨c⇩2⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩2⇩C⟩⇩A) ∈ ℛ⇩A ⟹
conc.low_mds_eq mds⇩C mem⇩1⇩C mem⇩2⇩C ⟹
(⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ P ⟹
(⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ R⇩C_of ℛ⇩A ℛ P"
unfolding R⇩C_of_def by fastforce
lemma R⇩C_of_sym:
assumes "sym ℛ⇩A"
assumes P_sym: "sym P"
assumes rr: "secure_refinement ℛ⇩A ℛ P"
assumes mm:
"⋀c⇩1 mds mem⇩1 c⇩2 mds mem⇩2. (⟨c⇩1, mds, mem⇩1⟩⇩A, ⟨c⇩2, mds, mem⇩2⟩⇩A) ∈ ℛ⇩A ⟹
abs.low_mds_eq mds mem⇩1 mem⇩2"
shows "sym (R⇩C_of ℛ⇩A ℛ P)"
proof(rule symI, clarify)
fix c⇩1⇩C mds⇩C mem⇩1⇩C c⇩2⇩C mds⇩C' mem⇩2⇩C
assume in_R⇩C_of: "(⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C, ⟨c⇩2⇩C, mds⇩C', mem⇩2⇩C⟩⇩C) ∈ R⇩C_of ℛ⇩A ℛ P"
from in_R⇩C_of obtain c⇩1⇩A c⇩2⇩A where
junk:
"(⟨c⇩1⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩1⇩C⟩⇩A, ⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C) ∈ ℛ ∧
(⟨c⇩2⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩2⇩C⟩⇩A, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ ℛ ∧
(⟨c⇩1⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩1⇩C⟩⇩A, ⟨c⇩2⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩2⇩C⟩⇩A) ∈ ℛ⇩A ∧
(mds⇩C' = mds⇩C) ∧ conc.low_mds_eq mds⇩C mem⇩1⇩C mem⇩2⇩C ∧
(⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ P"
using rr R⇩C_ofD by fastforce+
hence dma_eq: "dma⇩C mem⇩1⇩C = dma⇩C mem⇩2⇩C"
using abs_low_mds_eq_dma⇩C_eq[OF mm] by blast
with junk have junk':
"(⟨c⇩1⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩1⇩C⟩⇩A, ⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C) ∈ ℛ ∧
(⟨c⇩2⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩2⇩C⟩⇩A, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ ℛ ∧
(⟨c⇩2⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩2⇩C⟩⇩A, ⟨c⇩1⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩1⇩C⟩⇩A) ∈ ℛ⇩A ∧
(mds⇩C' = mds⇩C) ∧
conc.low_mds_eq mds⇩C' mem⇩2⇩C mem⇩1⇩C ∧
(⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C, ⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C) ∈ P"
using ‹sym ℛ⇩A› P_sym unfolding sym_def using conc.low_mds_eq_sym by metis
thus "(⟨c⇩2⇩C, mds⇩C', mem⇩2⇩C⟩⇩C, ⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C) ∈ R⇩C_of ℛ⇩A ℛ P"
using R⇩C_ofI by auto
qed
lemma R⇩C_of_simp:
assumes rr: "secure_refinement ℛ⇩A ℛ P"
shows "(⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ R⇩C_of ℛ⇩A ℛ P =
((∃c⇩1⇩A c⇩2⇩A. (⟨c⇩1⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩1⇩C⟩⇩A, ⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C) ∈ ℛ ∧
(⟨c⇩2⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩2⇩C⟩⇩A, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ ℛ ∧
(⟨c⇩1⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩1⇩C⟩⇩A, ⟨c⇩2⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩2⇩C⟩⇩A) ∈ ℛ⇩A) ∧
conc.low_mds_eq mds⇩C mem⇩1⇩C mem⇩2⇩C ∧
(⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ P)"
using assms by(blast dest: R⇩C_ofD intro: R⇩C_ofI)
definition
A⇩A_of :: "('Var⇩C,'Val) adaptation ⇒ ('Var⇩A,'Val) adaptation"
where
"A⇩A_of A ≡ λx⇩A. case A (var⇩C_of x⇩A) of None ⇒ None |
Some (v,v') ⇒ Some (v,v')"
lemma var_writable⇩A:
"¬ var_asm_not_written mds⇩C (var⇩C_of x) ⟹ ¬ var_asm_not_written (mds⇩A_of mds⇩C) x"
apply(simp add: var_asm_not_written_def mds⇩A_of_def)
apply(auto simp: inv_f_f[OF var⇩C_of_inj])
done
lemma A⇩A_asm_mem:
assumes A⇩C_asm_mem: "∀x. case A⇩C x of None ⇒ True
| Some (v, v') ⇒
mem⇩1⇩C x ≠ v ∨ mem⇩2⇩C x ≠ v' ⟶ ¬ var_asm_not_written mds⇩C x"
shows "case (A⇩A_of A⇩C) x of None ⇒ True
| Some (v, v') ⇒
(mem⇩A_of mem⇩1⇩C) x ≠ v ∨ (mem⇩A_of mem⇩2⇩C) x ≠ v' ⟶ ¬ var_asm_not_written (mds⇩A_of mds⇩C) x"
apply(split option.splits, simp, intro allI impI)
proof -
fix v v'
assume A⇩A_not_None: "A⇩A_of A⇩C x = Some (v, v')"
assume A⇩A_updates_x: "mem⇩A_of mem⇩1⇩C x = v ⟶ mem⇩A_of mem⇩2⇩C x ≠ v'"
from A⇩A_not_None have
A⇩C_not_None: "A⇩C (var⇩C_of x) = Some (v, v')"
unfolding A⇩A_of_def by (auto split: option.splits)
from A⇩A_updates_x have
A⇩C_updates_x: "mem⇩1⇩C (var⇩C_of x) ≠ v ∨ mem⇩2⇩C (var⇩C_of x) ≠ v'"
unfolding mem⇩A_of_def by fastforce
from A⇩C_not_None A⇩C_updates_x A⇩C_asm_mem have
"¬ var_asm_not_written mds⇩C (var⇩C_of x)" by (auto split: option.splits)
thus "¬ var_asm_not_written (mds⇩A_of mds⇩C) x"
by(rule var_writable⇩A)
qed
lemma dma⇩A_adaptation_eq:
"dma⇩A ((mem⇩A_of mem⇩1⇩C) [∥⇩1 A⇩A_of A⇩C]) x⇩A = dma⇩C (mem⇩1⇩C [∥⇩1 A⇩C]) (var⇩C_of x⇩A)"
apply(subst dma_consistent[folded mem⇩A_of_def, symmetric])
apply(rule_tac x=x⇩A in fun_cong)
apply(rule_tac f="dma⇩A" in arg_cong)
apply(rule ext)
apply(clarsimp simp: apply_adaptation_def A⇩A_of_def mem⇩A_of_def split: option.splits)
done
lemma A⇩A_asm_dma:
assumes A⇩C_asm_dma: "∀x. dma⇩C (mem⇩1⇩C [∥⇩1 A⇩C]) x ≠ dma⇩C mem⇩1⇩C x ⟶ ¬ var_asm_not_written mds⇩C x"
shows "dma⇩A ((mem⇩A_of mem⇩1⇩C) [∥⇩1 (A⇩A_of A⇩C)]) x⇩A ≠ dma⇩A (mem⇩A_of mem⇩1⇩C) x⇩A ⟶ ¬ var_asm_not_written (mds⇩A_of mds⇩C) x⇩A"
proof(intro impI)
assume A⇩A_updates_dma: "dma⇩A ((mem⇩A_of mem⇩1⇩C) [∥⇩1 A⇩A_of A⇩C]) x⇩A ≠ dma⇩A (mem⇩A_of mem⇩1⇩C) x⇩A"
with dma_consistent[folded mem⇩A_of_def] dma⇩A_adaptation_eq
have "dma⇩C (mem⇩1⇩C [∥⇩1 A⇩C]) (var⇩C_of x⇩A) ≠ dma⇩C mem⇩1⇩C (var⇩C_of x⇩A)" by(metis)
with A⇩C_asm_dma have "¬ var_asm_not_written mds⇩C (var⇩C_of x⇩A)" by blast
thus " ¬ var_asm_not_written (mds⇩A_of mds⇩C) x⇩A" by (rule var_writable⇩A)
qed
lemma var⇩C_of_in_𝒞⇩C:
assumes "x⇩A ∈ 𝒞⇩A"
shows "var⇩C_of x⇩A ∈ 𝒞⇩C"
proof -
from assms obtain y⇩A where "x⇩A ∈ 𝒞_vars⇩A y⇩A"
unfolding abs.𝒞_def by blast
hence "var⇩C_of x⇩A ∈ 𝒞_vars⇩C (var⇩C_of y⇩A)"
using 𝒞_vars_consistent by blast
thus ?thesis using conc.𝒞_def by blast
qed
lemma doesnt_have_mode⇩C:
"x ∉ mds⇩A_of mds⇩C m ⟹ var⇩C_of x ∉ mds⇩C m"
by(simp add: doesnt_have_mode)
lemma has_mode⇩A: "var⇩C_of x ∈ mds⇩C m ⟹ x ∈ mds⇩A_of mds⇩C m"
using doesnt_have_mode⇩C
by fastforce
lemma A⇩A_sec:
assumes A⇩C_sec: "∀x. dma⇩C (mem⇩1⇩C [∥⇩1 A⇩C]) x = Low ∧ (x ∉ mds⇩C AsmNoReadOrWrite ∨ x ∈ 𝒞⇩C) ⟶
mem⇩1⇩C [∥⇩1 A⇩C] x = mem⇩2⇩C [∥⇩2 A⇩C] x"
shows "dma⇩A ((mem⇩A_of mem⇩1⇩C) [∥⇩1 A⇩A_of A⇩C]) x = Low ∧ (x ∉ mds⇩A_of mds⇩C AsmNoReadOrWrite ∨ x ∈ 𝒞⇩A) ⟶
(mem⇩A_of mem⇩1⇩C) [∥⇩1 A⇩A_of A⇩C] x = (mem⇩A_of mem⇩2⇩C) [∥⇩2 A⇩A_of A⇩C] x"
proof(clarify)
assume x_is_Low: "dma⇩A ((mem⇩A_of mem⇩1⇩C) [∥⇩1 A⇩A_of A⇩C]) x = Low"
assume x_is_readable: "x ∉ mds⇩A_of mds⇩C AsmNoReadOrWrite ∨ x ∈ 𝒞⇩A"
from x_is_Low have x_is_Low⇩C: "dma⇩C (mem⇩1⇩C [∥⇩1 A⇩C]) (var⇩C_of x) = Low"
using dma⇩A_adaptation_eq by simp
from x_is_readable have "var⇩C_of x ∉ mds⇩C AsmNoReadOrWrite ∨ var⇩C_of x ∈ 𝒞⇩C"
using doesnt_have_mode⇩C var⇩C_of_in_𝒞⇩C by blast
with A⇩C_sec x_is_Low⇩C have "mem⇩1⇩C [∥⇩1 A⇩C] (var⇩C_of x) = mem⇩2⇩C [∥⇩2 A⇩C] (var⇩C_of x)"
by blast
thus "(mem⇩A_of mem⇩1⇩C) [∥⇩1 A⇩A_of A⇩C] x = (mem⇩A_of mem⇩2⇩C) [∥⇩2 A⇩A_of A⇩C] x"
by(auto simp: mem⇩A_of_def apply_adaptation_def A⇩A_of_def split: option.splits)
qed
lemma apply_adaptation⇩A:
"(mem⇩A_of mem⇩1⇩C) [∥⇩1 A⇩A_of A⇩C] = mem⇩A_of (mem⇩1⇩C [∥⇩1 A⇩C])"
"(mem⇩A_of mem⇩1⇩C) [∥⇩2 A⇩A_of A⇩C] = mem⇩A_of (mem⇩1⇩C [∥⇩2 A⇩C])"
by(auto simp: mem⇩A_of_def A⇩A_of_def apply_adaptation_def split: option.splits)
lemma R⇩C_of_closed_glob_consistent:
assumes mm:
"⋀c⇩1 mds mem⇩1 c⇩2 mds mem⇩2. (⟨c⇩1, mds, mem⇩1⟩⇩A, ⟨c⇩2, mds, mem⇩2⟩⇩A) ∈ ℛ⇩A ⟹
abs.low_mds_eq mds mem⇩1 mem⇩2"
assumes cgc: "abs.closed_glob_consistent ℛ⇩A"
assumes rr: "secure_refinement ℛ⇩A ℛ P"
shows "conc.closed_glob_consistent (R⇩C_of ℛ⇩A ℛ P)"
unfolding conc.closed_glob_consistent_def
proof(clarify)
fix c⇩1⇩C mds⇩C mem⇩1⇩C c⇩2⇩C mem⇩2⇩C A⇩C
assume "(⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ R⇩C_of ℛ⇩A ℛ P"
from this rr obtain c⇩1⇩A c⇩2⇩A where
in_ℛ⇩A: "(⟨c⇩1⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩1⇩C⟩⇩A, ⟨c⇩2⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩2⇩C⟩⇩A) ∈ ℛ⇩A" and
in_ℛ⇩1: "(⟨c⇩1⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩1⇩C⟩⇩A, ⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C) ∈ ℛ" and
in_ℛ⇩2: "(⟨c⇩2⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩2⇩C⟩⇩A, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ ℛ"
and
mds_eq: "conc.low_mds_eq mds⇩C mem⇩1⇩C mem⇩2⇩C"
and
P: "(⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ P"
by (blast dest: R⇩C_ofD)
assume A⇩C_asm_mem: "∀x. case A⇩C x of None ⇒ True
| Some (v, v') ⇒
mem⇩1⇩C x ≠ v ∨ mem⇩2⇩C x ≠ v' ⟶ ¬ var_asm_not_written mds⇩C x"
hence A⇩A_asm_mem: "∀x. case (A⇩A_of A⇩C) x of None ⇒ True
| Some (v, v') ⇒
(mem⇩A_of mem⇩1⇩C) x ≠ v ∨ (mem⇩A_of mem⇩2⇩C) x ≠ v' ⟶ ¬ var_asm_not_written (mds⇩A_of mds⇩C) x"
by(metis A⇩A_asm_mem)
assume A⇩C_asm_dma: "∀x. dma⇩C (mem⇩1⇩C [∥⇩1 A⇩C]) x ≠ dma⇩C mem⇩1⇩C x ⟶ ¬ var_asm_not_written mds⇩C x"
hence A⇩A_asm_dma: "∀x⇩A. dma⇩A ((mem⇩A_of mem⇩1⇩C) [∥⇩1 (A⇩A_of A⇩C)]) x⇩A ≠ dma⇩A (mem⇩A_of mem⇩1⇩C) x⇩A ⟶ ¬ var_asm_not_written (mds⇩A_of mds⇩C) x⇩A"
by(metis A⇩A_asm_dma)
assume A⇩C_sec: "∀x. dma⇩C (mem⇩1⇩C [∥⇩1 A⇩C]) x = Low ∧ (x ∉ mds⇩C AsmNoReadOrWrite ∨ x ∈ 𝒞⇩C) ⟶
mem⇩1⇩C [∥⇩1 A⇩C] x = mem⇩2⇩C [∥⇩2 A⇩C] x"
hence A⇩A_sec: "∀x. dma⇩A ((mem⇩A_of mem⇩1⇩C) [∥⇩1 A⇩A_of A⇩C]) x = Low ∧ (x ∉ mds⇩A_of mds⇩C AsmNoReadOrWrite ∨ x ∈ 𝒞⇩A) ⟶
(mem⇩A_of mem⇩1⇩C) [∥⇩1 A⇩A_of A⇩C] x = (mem⇩A_of mem⇩2⇩C) [∥⇩2 A⇩A_of A⇩C] x"
by(metis A⇩A_sec)
from rr have others: "closed_others ℛ"
unfolding secure_refinement_def by blast
from rr have P_cgc: "conc.closed_glob_consistent P"
unfolding secure_refinement_def by blast
let ?mem⇩1⇩C' = "(mem⇩1⇩C [∥⇩1 A⇩C])" and
?mem⇩2⇩C' = "(mem⇩2⇩C [∥⇩2 A⇩C])" and
?mem⇩1⇩A = "(mem⇩A_of mem⇩1⇩C)" and
?mem⇩2⇩A = "(mem⇩A_of mem⇩2⇩C)" and
?mem⇩1⇩A' = "(mem⇩A_of mem⇩1⇩C) [∥⇩1 A⇩A_of A⇩C]" and
?mem⇩2⇩A' = "(mem⇩A_of mem⇩2⇩C) [∥⇩2 A⇩A_of A⇩C]"
have mem'_simps:
"?mem⇩1⇩A' = mem⇩A_of ?mem⇩1⇩C'"
"?mem⇩2⇩A' = mem⇩A_of ?mem⇩2⇩C'" by(simp add: apply_adaptation⇩A)+
from cgc in_ℛ⇩A A⇩A_asm_mem A⇩A_asm_dma A⇩A_sec have
in_ℛ⇩A': "(⟨c⇩1⇩A, mds⇩A_of mds⇩C, (mem⇩A_of mem⇩1⇩C) [∥⇩1 A⇩A_of A⇩C]⟩⇩A, ⟨c⇩2⇩A, mds⇩A_of mds⇩C, (mem⇩A_of mem⇩2⇩C) [∥⇩2 A⇩A_of A⇩C]⟩⇩A) ∈ ℛ⇩A" unfolding abs.closed_glob_consistent_def by blast
from A⇩C_asm_mem A⇩C_asm_dma have
A⇩C_asm_mem⇩1': "∀x. mem⇩1⇩C x ≠ ?mem⇩1⇩C' x ⟶ ¬ var_asm_not_written mds⇩C x" and
A⇩C_asm_dma⇩1': "∀x. dma⇩C mem⇩1⇩C x ≠ dma⇩C ?mem⇩1⇩C' x ⟶ ¬ var_asm_not_written mds⇩C x"
unfolding apply_adaptation_def by(force split: option.splits)+
from A⇩C_asm_mem have
A⇩C_asm_mem⇩2': "∀x. mem⇩2⇩C x ≠ ?mem⇩2⇩C' x ⟶ ¬ var_asm_not_written mds⇩C x"
unfolding apply_adaptation_def by(force split: option.splits)
from in_ℛ⇩1 A⇩C_asm_mem⇩1' A⇩C_asm_dma⇩1' others have
in_ℛ⇩1': "(⟨c⇩1⇩A, mds⇩A_of mds⇩C, ?mem⇩1⇩A'⟩⇩A, ⟨c⇩1⇩C, mds⇩C, ?mem⇩1⇩C'⟩⇩C) ∈ ℛ"
unfolding closed_others_def mem'_simps by blast
from mm[OF in_ℛ⇩A] have
dma⇩C_eq: "dma⇩C mem⇩1⇩C = dma⇩C mem⇩2⇩C" by(rule abs_low_mds_eq_dma⇩C_eq)
have dma⇩C_eq': "dma⇩C ?mem⇩1⇩C' = dma⇩C ?mem⇩2⇩C'"
apply(rule abs_low_mds_eq_dma⇩C_eq[OF mm])
apply(simp add: mem'_simps[symmetric])
by(rule in_ℛ⇩A')
from dma⇩C_eq dma⇩C_eq' A⇩C_asm_dma⇩1' have
A⇩C_asm_dma⇩2': "∀x. dma⇩C mem⇩2⇩C x ≠ dma⇩C ?mem⇩2⇩C' x ⟶ ¬ var_asm_not_written mds⇩C x"
by simp
from in_ℛ⇩2 A⇩C_asm_mem⇩2' A⇩C_asm_dma⇩2' others have
in_ℛ⇩2': "(⟨c⇩2⇩A, mds⇩A_of mds⇩C, ?mem⇩2⇩A'⟩⇩A, ⟨c⇩2⇩C, mds⇩C, ?mem⇩2⇩C'⟩⇩C) ∈ ℛ"
unfolding closed_others_def mem'_simps by blast
have mds_eq': "conc.low_mds_eq mds⇩C ?mem⇩1⇩C' ?mem⇩2⇩C'"
using A⇩C_sec unfolding conc.low_mds_eq_def by blast
from P P_cgc A⇩C_asm_mem A⇩C_asm_dma A⇩C_sec have P': "(⟨c⇩1⇩C, mds⇩C, ?mem⇩1⇩C'⟩⇩C, ⟨c⇩2⇩C, mds⇩C, ?mem⇩2⇩C'⟩⇩C) ∈ P"
unfolding conc.closed_glob_consistent_def by blast
from in_ℛ⇩A' in_ℛ⇩1' in_ℛ⇩2' mem'_simps R⇩C_ofI mds_eq' P' show
"(⟨c⇩1⇩C, mds⇩C, ?mem⇩1⇩C'⟩⇩C, ⟨c⇩2⇩C, mds⇩C, ?mem⇩2⇩C'⟩⇩C) ∈ R⇩C_of ℛ⇩A ℛ P"
by(metis)
qed
lemma R⇩C_of_local_preservation:
assumes rr: "secure_refinement ℛ⇩A ℛ P"
assumes bisim: "abs.strong_low_bisim_mm ℛ⇩A"
assumes in_R⇩C_of: "(⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ R⇩C_of ℛ⇩A ℛ P"
assumes step⇩1⇩C: "⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C ↝⇩C ⟨c⇩1⇩C', mds⇩C', mem⇩1⇩C'⟩⇩C"
shows "∃c⇩2⇩C' mem⇩2⇩C'.
⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C ↝⇩C ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C ∧
(⟨c⇩1⇩C', mds⇩C', mem⇩1⇩C'⟩⇩C, ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C) ∈ R⇩C_of ℛ⇩A ℛ P"
proof -
from rr in_R⇩C_of have
P: "(⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ P"
by(blast dest: R⇩C_ofD)
let ?mds⇩A = "mds⇩A_of mds⇩C" and
?mem⇩1⇩A = "mem⇩A_of mem⇩1⇩C" and
?mem⇩2⇩A = "mem⇩A_of mem⇩2⇩C" and
?mds⇩A' = "mds⇩A_of mds⇩C'" and
?mem⇩1⇩A' = "mem⇩A_of mem⇩1⇩C'"
from rr in_R⇩C_of obtain c⇩1⇩A c⇩2⇩A where
in_ℛ⇩1: "(⟨c⇩1⇩A, ?mds⇩A, ?mem⇩1⇩A⟩⇩A, ⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C) ∈ ℛ" and
in_ℛ⇩2: "(⟨c⇩2⇩A, ?mds⇩A, ?mem⇩2⇩A⟩⇩A, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ ℛ" and
in_ℛ⇩A: "(⟨c⇩1⇩A, ?mds⇩A, ?mem⇩1⇩A⟩⇩A, ⟨c⇩2⇩A, ?mds⇩A, ?mem⇩2⇩A⟩⇩A) ∈ ℛ⇩A" and
low_mds_mds⇩C: "conc.low_mds_eq mds⇩C mem⇩1⇩C mem⇩2⇩C"
by(blast dest: R⇩C_ofD)+
from rr in_ℛ⇩1 in_ℛ⇩A in_ℛ⇩2 step⇩1⇩C obtain n c⇩1⇩A' where
a: "(abs.neval ⟨ c⇩1⇩A, ?mds⇩A, ?mem⇩1⇩A ⟩⇩A n ⟨ c⇩1⇩A', ?mds⇩A', ?mem⇩1⇩A' ⟩⇩A ∧
(⟨ c⇩1⇩A', ?mds⇩A', ?mem⇩1⇩A' ⟩⇩A, ⟨ c⇩1⇩C', mds⇩C', mem⇩1⇩C' ⟩⇩C) ∈ ℛ ∧
(∀c⇩2⇩A' mem⇩2⇩A'.
(⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ P ∧
abs.neval ⟨ c⇩2⇩A, ?mds⇩A, ?mem⇩2⇩A ⟩⇩A n ⟨ c⇩2⇩A', ?mds⇩A', mem⇩2⇩A' ⟩⇩A ⟶
(∃ c⇩2⇩C' mem⇩2⇩C'. ⟨ c⇩2⇩C, mds⇩C, mem⇩2⇩C ⟩⇩C ↝⇩C ⟨ c⇩2⇩C', mds⇩C', mem⇩2⇩C' ⟩⇩C ∧
(⟨ c⇩2⇩A', ?mds⇩A', mem⇩2⇩A' ⟩⇩A, ⟨ c⇩2⇩C', mds⇩C', mem⇩2⇩C' ⟩⇩C) ∈ ℛ ∧
(⟨c⇩1⇩C', mds⇩C', mem⇩1⇩C'⟩⇩C, ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C) ∈ P)))"
unfolding secure_refinement_def2
by metis
show ?thesis
proof -
from a have neval⇩1⇩A: "abs.neval ⟨c⇩1⇩A, ?mds⇩A, ?mem⇩1⇩A⟩⇩A n ⟨c⇩1⇩A', ?mds⇩A', ?mem⇩1⇩A'⟩⇩A" and
in_ℛ⇩1': "(⟨c⇩1⇩A', ?mds⇩A', ?mem⇩1⇩A'⟩⇩A, ⟨c⇩1⇩C', mds⇩C', mem⇩1⇩C'⟩⇩C) ∈ ℛ"
by blast+
from strong_low_bisim_neval[OF neval⇩1⇩A in_ℛ⇩A bisim] obtain c⇩2⇩A' mem⇩2⇩A' where
neval⇩2⇩A: "abs.neval ⟨c⇩2⇩A, ?mds⇩A, ?mem⇩2⇩A⟩⇩A n ⟨c⇩2⇩A', ?mds⇩A', mem⇩2⇩A'⟩⇩A" and
in_ℛ⇩A'_help: "(⟨c⇩1⇩A', ?mds⇩A', ?mem⇩1⇩A'⟩⇩A, ⟨c⇩2⇩A', ?mds⇩A', mem⇩2⇩A'⟩⇩A) ∈ ℛ⇩A"
unfolding abs.strong_low_bisim_mm_def
by blast
from a in_ℛ⇩A in_ℛ⇩2 neval⇩2⇩A P obtain c⇩2⇩C' mem⇩2⇩C' where
step⇩2⇩C: "⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C ↝⇩C ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C" and
in_ℛ⇩2'_help: "(⟨c⇩2⇩A', ?mds⇩A', mem⇩2⇩A'⟩⇩A, ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C) ∈ ℛ" and
P': "(⟨c⇩1⇩C', mds⇩C', mem⇩1⇩C'⟩⇩C, ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C) ∈ P"
by blast
let ?mem⇩2⇩A' = "mem⇩A_of mem⇩2⇩C'"
from in_ℛ⇩2'_help rr preserves_modes_memD have "mem⇩2⇩A' = ?mem⇩2⇩A'"
unfolding secure_refinement_def by metis
with in_ℛ⇩2'_help in_ℛ⇩A'_help have
in_ℛ⇩2': "(⟨c⇩2⇩A', ?mds⇩A', ?mem⇩2⇩A'⟩⇩A, ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C) ∈ ℛ" and
in_ℛ⇩A': "(⟨c⇩1⇩A', ?mds⇩A', ?mem⇩1⇩A'⟩⇩A, ⟨c⇩2⇩A', ?mds⇩A', ?mem⇩2⇩A'⟩⇩A) ∈ ℛ⇩A"
by simp+
have "conc.low_mds_eq mds⇩C' mem⇩1⇩C' mem⇩2⇩C'"
apply(rule new_vars_private_does_the_thing[where ℛ=ℛ, OF _ in_ℛ⇩1 in_ℛ⇩2 step⇩1⇩C step⇩2⇩C low_mds_mds⇩C])
using rr apply(fastforce simp: secure_refinement_def)
using in_ℛ⇩A' bisim unfolding abs.strong_low_bisim_mm_def by blast
with step⇩2⇩C in_ℛ⇩1' in_ℛ⇩2' in_ℛ⇩A' in_ℛ⇩2' P' show ?thesis
by(blast intro: R⇩C_ofI)
qed
qed
text ‹
Security of the concrete system should follow straightforwardly from
security of the abstract one, via the compositionality theorem, presuming
that the compiler also preserves the sound use of modes.
›
lemma R⇩C_of_strong_low_bisim_mm:
assumes abs: "abs.strong_low_bisim_mm ℛ⇩A"
assumes rr: "secure_refinement ℛ⇩A ℛ P"
assumes P_sym: "sym P"
shows "conc.strong_low_bisim_mm (R⇩C_of ℛ⇩A ℛ P)"
unfolding conc.strong_low_bisim_mm_def
apply(intro conjI)
apply(rule R⇩C_of_sym)
using abs rr P_sym unfolding abs.strong_low_bisim_mm_def apply blast+
apply(rule R⇩C_of_closed_glob_consistent)
using abs unfolding abs.strong_low_bisim_mm_def apply blast+
using rr apply blast
apply safe
apply(fastforce simp: R⇩C_of_def)
apply(rule R⇩C_of_local_preservation)
apply(rule rr)
apply(rule abs)
apply assumption+
done
section "A Simpler Proof Principle for General Compositional Refinement"
text ‹
Here we make use of the fact that the source language we are working
in is assumed deterministic. This allows us to invert the direction
of refinement and thereby to derive a simpler condition for secure
compositional refinement.
The simpler condition rests on an ordinary definition of refinement,
and has the user prove separately that the coupling invariant @{term P}
is self-preserving. This allows proofs about coupling invariant properties
to be disentangled from the proof of refinement itself.
›
text ‹
Given a bisimulation @{term ℛ⇩A}, this definition captures the essence of the extra
requirements on a refinement relation~@{term ℛ} needed to ensure that the refined program is
also secure. These requirements are essentially that:
\begin{enumerate}
\item The enabledness of the compiled code depends only on Low abstract data;
\item The length of the abstract program to which a single step of the concrete program
corresponds depends only on Low abstract data;
\item The coupling invariant is maintained.
\end{enumerate}
The second requirement we express via the parameter~@{term abs_steps} that, given an
abstract and corresponding concrete configuration, yields the number of execution steps of
the abstract configuration to which a single step of the concrete configuration corresponds.
Note that a more specialised version of this definition, fixing the coupling
invariant @{term P} to be the one that relates all configurations with
identical programs and mode states, appeared in Murray et al., CSF 2016.
Here we generalise the theory to support a wider class of coupling invariants.
›
definition
simpler_refinement_safe
where
"simpler_refinement_safe ℛ⇩A ℛ P abs_steps ≡
∀c⇩1⇩A mds⇩A mem⇩1⇩A c⇩2⇩A mem⇩2⇩A c⇩1⇩C mds⇩C mem⇩1⇩C c⇩2⇩C mem⇩2⇩C. (⟨c⇩1⇩A,mds⇩A,mem⇩1⇩A⟩⇩A,⟨c⇩2⇩A,mds⇩A,mem⇩2⇩A⟩⇩A) ∈ ℛ⇩A ∧
(⟨c⇩1⇩A,mds⇩A,mem⇩1⇩A⟩⇩A,⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C) ∈ ℛ ∧ (⟨c⇩2⇩A,mds⇩A,mem⇩2⇩A⟩⇩A,⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ ℛ ∧
(⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ P ⟶
(stops⇩C ⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C = stops⇩C ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∧
(abs_steps ⟨c⇩1⇩A,mds⇩A,mem⇩1⇩A⟩⇩A ⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C = abs_steps ⟨c⇩2⇩A,mds⇩A,mem⇩2⇩A⟩⇩A ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∧
(∀mds⇩1⇩C' mds⇩2⇩C' mem⇩1⇩C' mem⇩2⇩C' c⇩1⇩C' c⇩2⇩C'. ⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C ↝⇩C ⟨c⇩1⇩C', mds⇩1⇩C', mem⇩1⇩C'⟩⇩C ∧
⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C ↝⇩C ⟨c⇩2⇩C', mds⇩2⇩C', mem⇩2⇩C'⟩⇩C ⟶
(⟨c⇩1⇩C', mds⇩1⇩C', mem⇩1⇩C'⟩⇩C, ⟨c⇩2⇩C', mds⇩2⇩C', mem⇩2⇩C'⟩⇩C) ∈ P ∧
mds⇩1⇩C' = mds⇩2⇩C')"
definition
secure_refinement_simpler
where
"secure_refinement_simpler ℛ⇩A ℛ P abs_steps ≡
closed_others ℛ ∧
preserves_modes_mem ℛ ∧
new_vars_private ℛ ∧
simpler_refinement_safe ℛ⇩A ℛ P abs_steps ∧
conc.closed_glob_consistent P ∧
(∀ c⇩1⇩A mds⇩A mem⇩1⇩A c⇩1⇩C mds⇩C mem⇩1⇩C.
(⟨ c⇩1⇩A, mds⇩A, mem⇩1⇩A ⟩⇩A, ⟨ c⇩1⇩C, mds⇩C, mem⇩1⇩C ⟩⇩C) ∈ ℛ ⟶
(∀ c⇩1⇩C' mds⇩C' mem⇩1⇩C'. ⟨ c⇩1⇩C, mds⇩C, mem⇩1⇩C ⟩⇩C ↝⇩C ⟨ c⇩1⇩C', mds⇩C', mem⇩1⇩C' ⟩⇩C ⟶
(∃ c⇩1⇩A' mds⇩A' mem⇩1⇩A'. abs.neval ⟨ c⇩1⇩A, mds⇩A, mem⇩1⇩A ⟩⇩A (abs_steps ⟨c⇩1⇩A,mds⇩A,mem⇩1⇩A⟩⇩A ⟨c⇩1⇩C,mds⇩C,mem⇩1⇩C⟩⇩C) ⟨ c⇩1⇩A', mds⇩A', mem⇩1⇩A' ⟩⇩A ∧
(⟨ c⇩1⇩A', mds⇩A', mem⇩1⇩A' ⟩⇩A, ⟨ c⇩1⇩C', mds⇩C', mem⇩1⇩C' ⟩⇩C) ∈ ℛ)))"
lemma secure_refinement_simpler:
assumes rrs: "secure_refinement_simpler ℛ⇩A ℛ P abs_steps"
shows "secure_refinement ℛ⇩A ℛ P"
unfolding secure_refinement_def
proof(safe)
from rrs show "closed_others ℛ"
unfolding secure_refinement_simpler_def by blast
next
from rrs show "preserves_modes_mem ℛ"
unfolding secure_refinement_simpler_def by blast
next
from rrs show "new_vars_private ℛ"
unfolding secure_refinement_simpler_def by blast
next
fix c⇩1⇩A mds⇩A mem⇩1⇩A c⇩1⇩C mds⇩C mem⇩1⇩C c⇩1⇩C' mds⇩C' mem⇩1⇩C'
let ?n = "abs_steps ⟨c⇩1⇩A,mds⇩A,mem⇩1⇩A⟩⇩A ⟨c⇩1⇩C,mds⇩C,mem⇩1⇩C⟩⇩C"
assume in_ℛ⇩1: "(⟨c⇩1⇩A, mds⇩A, mem⇩1⇩A⟩⇩A, ⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C) ∈ ℛ"
and eval⇩1⇩C: "⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C ↝⇩C ⟨c⇩1⇩C', mds⇩C', mem⇩1⇩C'⟩⇩C"
with rrs obtain c⇩1⇩A' mds⇩A' mem⇩1⇩A' where
neval⇩1: "abs.neval ⟨ c⇩1⇩A, mds⇩A, mem⇩1⇩A ⟩⇩A ?n ⟨ c⇩1⇩A', mds⇩A', mem⇩1⇩A' ⟩⇩A" and
in_ℛ⇩1': "(⟨ c⇩1⇩A', mds⇩A', mem⇩1⇩A' ⟩⇩A, ⟨ c⇩1⇩C', mds⇩C', mem⇩1⇩C' ⟩⇩C) ∈ ℛ"
unfolding secure_refinement_simpler_def by metis
have "(∀c⇩2⇩A mem⇩2⇩A c⇩2⇩C mem⇩2⇩C c⇩2⇩A' mem⇩2⇩A'.
(⟨c⇩1⇩A, mds⇩A, mem⇩1⇩A⟩⇩A, ⟨c⇩2⇩A, mds⇩A, mem⇩2⇩A⟩⇩A) ∈ ℛ⇩A ∧
(⟨c⇩2⇩A, mds⇩A, mem⇩2⇩A⟩⇩A, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ ℛ ∧
(⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C,⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ P ∧ abs.neval ⟨c⇩2⇩A, mds⇩A, mem⇩2⇩A⟩⇩A ?n ⟨c⇩2⇩A', mds⇩A', mem⇩2⇩A'⟩⇩A ⟶
(∃c⇩2⇩C' mem⇩2⇩C'.
⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C ↝⇩C ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C ∧
(⟨c⇩2⇩A', mds⇩A', mem⇩2⇩A'⟩⇩A, ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C) ∈ ℛ ∧
(⟨c⇩1⇩C', mds⇩C', mem⇩1⇩C'⟩⇩C,⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C) ∈ P))"
proof(clarsimp)
fix c⇩2⇩A mem⇩2⇩A c⇩2⇩C mem⇩2⇩C c⇩2⇩A' mem⇩2⇩A'
assume
in_ℛ⇩A: "(⟨c⇩1⇩A, mds⇩A, mem⇩1⇩A⟩⇩A, ⟨c⇩2⇩A, mds⇩A, mem⇩2⇩A⟩⇩A) ∈ ℛ⇩A" and
in_ℛ⇩2: "(⟨c⇩2⇩A, mds⇩A, mem⇩2⇩A⟩⇩A, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ ℛ" and
neval⇩2: "abs.neval ⟨c⇩2⇩A, mds⇩A, mem⇩2⇩A⟩⇩A ?n ⟨c⇩2⇩A', mds⇩A', mem⇩2⇩A'⟩⇩A" and
in_P: "(⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C,⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ P"
have "∀c⇩2⇩C' mem⇩2⇩C'. ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C ↝⇩C ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C ⟶ (⟨c⇩2⇩A', mds⇩A', mem⇩2⇩A'⟩⇩A, ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C) ∈ ℛ ∧ (⟨c⇩1⇩C', mds⇩C', mem⇩1⇩C'⟩⇩C, ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C) ∈ P"
proof(clarify)
fix c⇩2⇩C' mem⇩2⇩C'
assume eval⇩2⇩C: "⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C ↝⇩C ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C"
from in_ℛ⇩2 eval⇩2⇩C in_P rrs obtain
c⇩2⇩A'' mds⇩A'' mem⇩2⇩A'' where
neval⇩2': "abs.neval ⟨ c⇩2⇩A, mds⇩A, mem⇩2⇩A ⟩⇩A (abs_steps ⟨c⇩2⇩A,mds⇩A,mem⇩2⇩A⟩⇩A ⟨c⇩2⇩C,mds⇩C,mem⇩2⇩C⟩⇩C) ⟨ c⇩2⇩A'', mds⇩A'', mem⇩2⇩A'' ⟩⇩A" and
in_ℛ⇩2': "(⟨ c⇩2⇩A'', mds⇩A'', mem⇩2⇩A'' ⟩⇩A, ⟨ c⇩2⇩C', mds⇩C', mem⇩2⇩C' ⟩⇩C) ∈ ℛ"
unfolding secure_refinement_simpler_def by blast
let ?n' = "(abs_steps ⟨c⇩2⇩A,mds⇩A,mem⇩2⇩A⟩⇩A ⟨c⇩2⇩C,mds⇩C,mem⇩2⇩C⟩⇩C)"
from rrs have pe: "simpler_refinement_safe ℛ⇩A ℛ P abs_steps"
unfolding secure_refinement_simpler_def by blast
with in_ℛ⇩A in_ℛ⇩1 in_ℛ⇩2 in_P
have "?n' = ?n"
unfolding simpler_refinement_safe_def by fastforce
with neval⇩2 neval⇩2' abs.neval_det
have [simp]: "c⇩2⇩A'' = c⇩2⇩A'" and [simp]: "mds⇩A'' = mds⇩A'" and [simp]: "mem⇩2⇩A'' = mem⇩2⇩A'"
by auto
from in_ℛ⇩2' have in_ℛ⇩2': "(⟨c⇩2⇩A', mds⇩A', mem⇩2⇩A'⟩⇩A, ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C) ∈ ℛ" by simp
from eval⇩1⇩C eval⇩2⇩C in_P have
in_P': "(⟨c⇩1⇩C', mds⇩C', mem⇩1⇩C'⟩⇩C,⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C) ∈ P"
using rrs unfolding secure_refinement_simpler_def
simpler_refinement_safe_def
using in_ℛ⇩A in_ℛ⇩1 in_ℛ⇩2 in_P by auto
with in_ℛ⇩2'
show "(⟨c⇩2⇩A', mds⇩A', mem⇩2⇩A'⟩⇩A, ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C) ∈ ℛ ∧
(⟨c⇩1⇩C', mds⇩C', mem⇩1⇩C'⟩⇩C, ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C) ∈ P" by blast
qed
moreover have "∃c⇩2⇩C' mem⇩2⇩C'. ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C ↝⇩C ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C"
proof -
from rrs have pe: "simpler_refinement_safe ℛ⇩A ℛ P abs_steps"
unfolding secure_refinement_simpler_def by blast
with in_ℛ⇩A in_ℛ⇩1 in_ℛ⇩2 in_P have "stops⇩C ⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C = stops⇩C ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C"
unfolding simpler_refinement_safe_def by blast
moreover from eval⇩1⇩C have "¬ stops⇩C ⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C"
unfolding stops⇩C_def by blast
ultimately have "¬ stops⇩C ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C"
by simp
from this obtain c⇩2⇩C' mds⇩C'' mem⇩2⇩C'' where eval⇩2⇩C': "⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C ↝⇩C ⟨c⇩2⇩C',mds⇩C'',mem⇩2⇩C''⟩⇩C"
unfolding stops⇩C_def by auto
with pe eval⇩1⇩C in_ℛ⇩A in_ℛ⇩1 in_ℛ⇩2 in_P have in_P': "(⟨c⇩1⇩C',mds⇩C', mem⇩1⇩C'⟩⇩C, ⟨c⇩2⇩C',mds⇩C'', mem⇩2⇩C''⟩⇩C) ∈ P"
and [simp]: "mds⇩C'' = mds⇩C'"
unfolding simpler_refinement_safe_def by blast+
from in_P' eval⇩2⇩C'
show "∃c⇩2⇩C' mem⇩2⇩C'. ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C ↝⇩C ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C"
by fastforce
qed
ultimately show
"∃c⇩2⇩C' mem⇩2⇩C'.
⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C ↝⇩C ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C ∧ (⟨c⇩2⇩A', mds⇩A', mem⇩2⇩A'⟩⇩A, ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C) ∈ ℛ ∧ (⟨c⇩1⇩C', mds⇩C', mem⇩1⇩C'⟩⇩C,
⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C)
∈ P"
by blast
qed
with neval⇩1 in_ℛ⇩1 in_ℛ⇩1'
show "∃n c⇩1⇩A' mds⇩A' mem⇩1⇩A'.
abs.neval ⟨c⇩1⇩A, mds⇩A, mem⇩1⇩A⟩⇩A n ⟨c⇩1⇩A', mds⇩A', mem⇩1⇩A'⟩⇩A ∧
(⟨c⇩1⇩A', mds⇩A', mem⇩1⇩A'⟩⇩A, ⟨c⇩1⇩C', mds⇩C', mem⇩1⇩C'⟩⇩C) ∈ ℛ ∧
(∀c⇩2⇩A mem⇩2⇩A c⇩2⇩C mem⇩2⇩C c⇩2⇩A' mem⇩2⇩A'.
(⟨c⇩1⇩A, mds⇩A, mem⇩1⇩A⟩⇩A, ⟨c⇩2⇩A, mds⇩A, mem⇩2⇩A⟩⇩A) ∈ ℛ⇩A ∧
(⟨c⇩2⇩A, mds⇩A, mem⇩2⇩A⟩⇩A, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ ℛ ∧
(⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C, ⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C)
∈ P ∧
abs.neval ⟨c⇩2⇩A, mds⇩A, mem⇩2⇩A⟩⇩A n ⟨c⇩2⇩A', mds⇩A', mem⇩2⇩A'⟩⇩A ⟶
(∃c⇩2⇩C' mem⇩2⇩C'.
⟨c⇩2⇩C, mds⇩C, mem⇩2⇩C⟩⇩C ↝⇩C ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C ∧
(⟨c⇩2⇩A', mds⇩A', mem⇩2⇩A'⟩⇩A, ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C) ∈ ℛ ∧
(⟨c⇩1⇩C', mds⇩C', mem⇩1⇩C'⟩⇩C, ⟨c⇩2⇩C', mds⇩C', mem⇩2⇩C'⟩⇩C)
∈ P))"
by auto
next
show "conc.closed_glob_consistent P"
using rrs unfolding secure_refinement_simpler_def by blast
qed
section "Simple Bisimulations and Simple Refinement"
text ‹
We derive the theory of simple refinements from Murray et al. CSF 2016 from the above
\emph{simpler} theory of secure refinement.
›
definition
bisim_simple
where
"bisim_simple ℛ⇩A ≡ ∀c⇩1⇩A mds mem⇩1⇩A c⇩2⇩A mem⇩2⇩A. (⟨c⇩1⇩A,mds,mem⇩1⇩A⟩⇩A,⟨c⇩2⇩A,mds,mem⇩2⇩A⟩⇩A) ∈ ℛ⇩A ⟶
c⇩1⇩A = c⇩2⇩A"
definition
simple_refinement_safe
where
"simple_refinement_safe ℛ⇩A ℛ abs_steps ≡
∀c⇩A mds⇩A mem⇩1⇩A mem⇩2⇩A c⇩C mds⇩C mem⇩1⇩C mem⇩2⇩C. (⟨c⇩A,mds⇩A,mem⇩1⇩A⟩⇩A,⟨c⇩A,mds⇩A,mem⇩2⇩A⟩⇩A) ∈ ℛ⇩A ∧
(⟨c⇩A,mds⇩A,mem⇩1⇩A⟩⇩A,⟨c⇩C, mds⇩C, mem⇩1⇩C⟩⇩C) ∈ ℛ ∧ (⟨c⇩A,mds⇩A,mem⇩2⇩A⟩⇩A,⟨c⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∈ ℛ ⟶
(stops⇩C ⟨c⇩C, mds⇩C, mem⇩1⇩C⟩⇩C = stops⇩C ⟨c⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∧
(abs_steps ⟨c⇩A,mds⇩A,mem⇩1⇩A⟩⇩A ⟨c⇩C, mds⇩C, mem⇩1⇩C⟩⇩C = abs_steps ⟨c⇩A,mds⇩A,mem⇩2⇩A⟩⇩A ⟨c⇩C, mds⇩C, mem⇩2⇩C⟩⇩C) ∧
(∀mds⇩1⇩C' mds⇩2⇩C' mem⇩1⇩C' mem⇩2⇩C' c⇩1⇩C' c⇩2⇩C'. ⟨c⇩C, mds⇩C, mem⇩1⇩C⟩⇩C ↝⇩C ⟨c⇩1⇩C', mds⇩1⇩C', mem⇩1⇩C'⟩⇩C ∧
⟨c⇩C, mds⇩C, mem⇩2⇩C⟩⇩C ↝⇩C ⟨c⇩2⇩C', mds⇩2⇩C', mem⇩2⇩C'⟩⇩C ⟶
c⇩1⇩C' = c⇩2⇩C' ∧ mds⇩1⇩C' = mds⇩2⇩C')"
definition
secure_refinement_simple
where
"secure_refinement_simple ℛ⇩A ℛ abs_steps ≡
closed_others ℛ ∧
preserves_modes_mem ℛ ∧
new_vars_private ℛ ∧
simple_refinement_safe ℛ⇩A ℛ abs_steps ∧
bisim_simple ℛ⇩A ∧
(∀ c⇩1⇩A mds⇩A mem⇩1⇩A c⇩1⇩C mds⇩C mem⇩1⇩C.
(⟨ c⇩1⇩A, mds⇩A, mem⇩1⇩A ⟩⇩A, ⟨ c⇩1⇩C, mds⇩C, mem⇩1⇩C ⟩⇩C) ∈ ℛ ⟶
(∀ c⇩1⇩C' mds⇩C' mem⇩1⇩C'. ⟨ c⇩1⇩C, mds⇩C, mem⇩1⇩C ⟩⇩C ↝⇩C ⟨ c⇩1⇩C', mds⇩C', mem⇩1⇩C' ⟩⇩C ⟶
(∃ c⇩1⇩A' mds⇩A' mem⇩1⇩A'. abs.neval ⟨ c⇩1⇩A, mds⇩A, mem⇩1⇩A ⟩⇩A (abs_steps ⟨c⇩1⇩A,mds⇩A,mem⇩1⇩A⟩⇩A ⟨c⇩1⇩C,mds⇩C,mem⇩1⇩C⟩⇩C) ⟨ c⇩1⇩A', mds⇩A', mem⇩1⇩A' ⟩⇩A ∧
(⟨ c⇩1⇩A', mds⇩A', mem⇩1⇩A' ⟩⇩A, ⟨ c⇩1⇩C', mds⇩C', mem⇩1⇩C' ⟩⇩C) ∈ ℛ)))"
definition
ℐsimple
where
"ℐsimple ≡ {(⟨c,mds,mem⟩⇩C,⟨c',mds',mem'⟩⇩C)| c mds mem c' mds' mem'. c = c'}"
lemma ℐsimple_closed_glob_consistent:
"conc.closed_glob_consistent ℐsimple"
by(auto simp: conc.closed_glob_consistent_def ℐsimple_def)
lemma secure_refinement_simple:
assumes srs: "secure_refinement_simple ℛ⇩A ℛ abs_steps"
shows "secure_refinement_simpler ℛ⇩A ℛ ℐsimple abs_steps"
unfolding secure_refinement_simpler_def
proof(safe | clarsimp)+
from srs show "closed_others ℛ"
unfolding secure_refinement_simple_def by blast
next
from srs show "preserves_modes_mem ℛ"
unfolding secure_refinement_simple_def by blast
next
from srs show "new_vars_private ℛ"
unfolding secure_refinement_simple_def by blast
next
show "conc.closed_glob_consistent ℐsimple" by (rule ℐsimple_closed_glob_consistent)
next
from srs have safe: "simple_refinement_safe ℛ⇩A ℛ abs_steps"
unfolding secure_refinement_simple_def by blast
from srs have simple: "bisim_simple ℛ⇩A"
unfolding secure_refinement_simple_def by fastforce
from safe simple show "simpler_refinement_safe ℛ⇩A ℛ ℐsimple abs_steps"
by(fastforce simp: simpler_refinement_safe_def ℐsimple_def simple_refinement_safe_def bisim_simple_def)
next
fix c⇩1⇩A mds⇩A mem⇩1⇩A c⇩1⇩C mds⇩C mem⇩1⇩C c⇩1⇩C' mds⇩C' mem⇩1⇩C'
show " (⟨c⇩1⇩A, mds⇩A, mem⇩1⇩A⟩⇩A, ⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C) ∈ ℛ ⟹
⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C ↝⇩C ⟨c⇩1⇩C', mds⇩C', mem⇩1⇩C'⟩⇩C ⟹
∃c⇩1⇩A' mds⇩A' mem⇩1⇩A'.
abs.neval ⟨c⇩1⇩A, mds⇩A, mem⇩1⇩A⟩⇩A (abs_steps ⟨c⇩1⇩A, mds⇩A, mem⇩1⇩A⟩⇩A ⟨c⇩1⇩C, mds⇩C, mem⇩1⇩C⟩⇩C)
⟨c⇩1⇩A', mds⇩A', mem⇩1⇩A'⟩⇩A ∧
(⟨c⇩1⇩A', mds⇩A', mem⇩1⇩A'⟩⇩A, ⟨c⇩1⇩C', mds⇩C', mem⇩1⇩C'⟩⇩C) ∈ ℛ"
using srs unfolding secure_refinement_simple_def by blast
qed
section "Sound Mode Use Preservation"
text ‹
Prove that
\begin{quote}
acquiring a mode on the concrete version of an abstract
variable~@{term x}, and then mapping the new concrete mode state to the
corresponding abstract mode state,
\end{quote}
is equivalent to
\begin{quote}
first mapping the initial concrete mode
state to its corresponding abstract mode state and then acquiring the mode
on the abstract variable~@{term x}.
\end{quote}
This lemma essentially justifies why a concrete program doing
@{term "Acq (var⇩C_of x) SomeMode"}
is a the right way to implement the abstract program doing
@{term "Acq x SomeMode"}.
›
lemma mode_acquire_refinement_helper:
"mds⇩A_of (mds⇩C(SomeMode := insert (var⇩C_of x) (mds⇩C SomeMode))) =
(mds⇩A_of mds⇩C)(SomeMode := insert x (mds⇩A_of mds⇩C SomeMode))"
apply(clarsimp simp: mds⇩A_of_def)
apply(rule ext)
apply(force simp: image_def inv_f_f[OF var⇩C_of_inj])
done
lemma mode_release_refinement_helper:
"mds⇩A_of (mds⇩C(SomeMode := {y ∈ mds⇩C SomeMode. y ≠ (var⇩C_of x)})) =
(mds⇩A_of mds⇩C)(SomeMode := {y ∈ (mds⇩A_of mds⇩C SomeMode). y ≠ x})"
apply(clarsimp simp: mds⇩A_of_def)
apply(rule ext)
apply (force simp: image_def inv_f_f[OF var⇩C_of_inj])
done
definition
preserves_locally_sound_mode_use :: "('Com⇩A, 'Var⇩A, 'Val, 'Com⇩C, 'Var⇩C) state_relation ⇒ bool"
where
"preserves_locally_sound_mode_use ℛ ≡
∀lc⇩A lc⇩C.
(abs.locally_sound_mode_use lc⇩A ∧ (lc⇩A, lc⇩C) ∈ ℛ ⟶
conc.locally_sound_mode_use lc⇩C)"
lemma secure_refinement_loc_reach:
assumes rr: "secure_refinement ℛ⇩A ℛ P"
assumes in_ℛ: "(⟨c⇩A, mds⇩A, mem⇩A⟩⇩A, ⟨c⇩C, mds⇩C, mem⇩C⟩⇩C) ∈ ℛ"
assumes loc_reach⇩C: "⟨c⇩C', mds⇩C', mem⇩C'⟩⇩C ∈ conc.loc_reach ⟨c⇩C, mds⇩C, mem⇩C⟩⇩C"
shows "∃c⇩A' mds⇩A' mem⇩A'.
(⟨c⇩A', mds⇩A', mem⇩A'⟩⇩A, ⟨c⇩C', mds⇩C', mem⇩C'⟩⇩C) ∈ ℛ ∧
⟨c⇩A', mds⇩A', mem⇩A'⟩⇩A ∈ abs.loc_reach ⟨c⇩A, mds⇩A, mem⇩A⟩⇩A"
using loc_reach⇩C proof(induct rule: conc.loc_reach.induct)
case (refl) show ?case
using in_ℛ abs.loc_reach.refl by force
next
case (step c⇩C' mds⇩C' mem⇩C' c⇩C'' mds⇩C'' mem⇩C'')
from step(2) obtain c⇩A' mds⇩A' mem⇩A' where
in_ℛ': "(⟨c⇩A', mds⇩A', mem⇩A'⟩⇩A, ⟨c⇩C', mds⇩C', mem⇩C'⟩⇩C) ∈ ℛ" and
loc_reach⇩A: "⟨c⇩A', mds⇩A', mem⇩A'⟩⇩A ∈ abs.loc_reach ⟨c⇩A, mds⇩A, mem⇩A⟩⇩A "
by blast
from rr in_ℛ' step(3)
obtain n c⇩A'' mds⇩A'' mem⇩A'' where
neval⇩A: "abs.neval ⟨ c⇩A', mds⇩A', mem⇩A' ⟩⇩A n ⟨ c⇩A'', mds⇩A'', mem⇩A'' ⟩⇩A" and
in_ℛ'': "(⟨ c⇩A'', mds⇩A'', mem⇩A'' ⟩⇩A, ⟨ c⇩C'', mds⇩C'', mem⇩C'' ⟩⇩C) ∈ ℛ"
unfolding secure_refinement_def by blast
from neval⇩A loc_reach⇩A have "⟨c⇩A'', mds⇩A'', mem⇩A''⟩⇩A ∈ abs.loc_reach ⟨c⇩A, mds⇩A, mem⇩A⟩⇩A"
using abs.neval_loc_reach
by blast
with in_ℛ'' show ?case by blast
next
case (mem_diff c⇩C' mds⇩C' mem⇩C' mem⇩C'')
from mem_diff(2) obtain c⇩A' mds⇩A' mem⇩A' where
in_ℛ': "(⟨c⇩A', mds⇩A', mem⇩A'⟩⇩A, ⟨c⇩C', mds⇩C', mem⇩C'⟩⇩C) ∈ ℛ" and
loc_reach⇩A: "⟨c⇩A', mds⇩A', mem⇩A'⟩⇩A ∈ abs.loc_reach ⟨c⇩A, mds⇩A, mem⇩A⟩⇩A "
by blast
from rr have mm: "preserves_modes_mem ℛ" and co: "closed_others ℛ"
unfolding secure_refinement_def by blast+
from preserves_modes_memD[OF mm in_ℛ'] have
mem⇩A'_def: "mem⇩A' = mem⇩A_of mem⇩C'" and mds⇩A'_def: "mds⇩A' = mds⇩A_of mds⇩C'"
by simp+
hence in_ℛ': "(⟨c⇩A', mds⇩A_of mds⇩C', mem⇩A_of mem⇩C'⟩⇩A, ⟨c⇩C', mds⇩C', mem⇩C'⟩⇩C) ∈ ℛ"
and loc_reach⇩A: "(⟨c⇩A', mds⇩A_of mds⇩C', mem⇩A_of mem⇩C'⟩⇩A) ∈ abs.loc_reach ⟨c⇩A, mds⇩A, mem⇩A⟩⇩A"
using in_ℛ' loc_reach⇩A by simp+
with mem_diff(3) co
have "(⟨c⇩A', mds⇩A_of mds⇩C', mem⇩A_of mem⇩C''⟩⇩A, ⟨c⇩C', mds⇩C', mem⇩C''⟩⇩C) ∈ ℛ"
unfolding closed_others_def by blast
moreover have "⟨c⇩A', mds⇩A_of mds⇩C', mem⇩A_of mem⇩C''⟩⇩A ∈ abs.loc_reach ⟨c⇩A, mds⇩A, mem⇩A⟩⇩A"
apply(rule abs.loc_reach.mem_diff)
apply(rule loc_reach⇩A)
using mem_diff(3)
using calculation in_ℛ' in_ℛ_dma' mem⇩A_of_def mm var_writable⇩A by fastforce
ultimately show ?case by blast
qed
definition preserves_local_guarantee_compliance ::
"('Com⇩A, 'Var⇩A, 'Val, 'Com⇩C, 'Var⇩C) state_relation ⇒ bool"
where
"preserves_local_guarantee_compliance ℛ ≡
∀cm⇩A mem⇩A cm⇩C mem⇩C.
abs.respects_own_guarantees cm⇩A ∧
((cm⇩A, mem⇩A), (cm⇩C, mem⇩C)) ∈ ℛ ⟶
conc.respects_own_guarantees cm⇩C"
lemma preserves_local_guarantee_compliance_def2:
"preserves_local_guarantee_compliance ℛ ≡
∀c⇩A mds⇩A mem⇩A c⇩C mds⇩C mem⇩C.
abs.respects_own_guarantees (c⇩A, mds⇩A) ∧
(⟨c⇩A, mds⇩A, mem⇩A⟩⇩A, ⟨c⇩C, mds⇩C, mem⇩C⟩⇩C) ∈ ℛ ⟶
conc.respects_own_guarantees (c⇩C, mds⇩C)"
unfolding preserves_local_guarantee_compliance_def
by simp
lemma locally_sound_mode_use_preservation:
assumes rr: "secure_refinement ℛ⇩A ℛ P"
assumes preserves_guarantee_compliance: "preserves_local_guarantee_compliance ℛ"
shows "preserves_locally_sound_mode_use ℛ"
unfolding preserves_locally_sound_mode_use_def
proof(clarsimp)
fix c⇩A mds⇩A mem⇩A c⇩C mds⇩C mem⇩C
assume locally_sound⇩A: "abs.locally_sound_mode_use ⟨c⇩A, mds⇩A, mem⇩A⟩⇩A" and
in_ℛ: "(⟨c⇩A, mds⇩A, mem⇩A⟩⇩A, ⟨c⇩C, mds⇩C, mem⇩C⟩⇩C) ∈ ℛ"
show "conc.locally_sound_mode_use ⟨c⇩C, mds⇩C, mem⇩C⟩⇩C"
unfolding conc.locally_sound_mode_use_def2
proof(clarsimp)
fix c⇩C' mds⇩C' mem⇩C'
assume loc_reach⇩C: "⟨c⇩C', mds⇩C', mem⇩C'⟩⇩C ∈ conc.loc_reach ⟨c⇩C, mds⇩C, mem⇩C⟩⇩C"
from rr in_ℛ loc_reach⇩C
obtain c⇩A' mds⇩A' mem⇩A' where
in_ℛ': "(⟨c⇩A', mds⇩A', mem⇩A'⟩⇩A, ⟨c⇩C', mds⇩C', mem⇩C'⟩⇩C) ∈ ℛ" and
loc_reach⇩A: "⟨c⇩A', mds⇩A', mem⇩A'⟩⇩A ∈ abs.loc_reach ⟨c⇩A, mds⇩A, mem⇩A⟩⇩A"
using secure_refinement_loc_reach by blast
from locally_sound⇩A loc_reach⇩A
have respects_guarantees⇩A': "abs.respects_own_guarantees (c⇩A', mds⇩A')"
unfolding abs.locally_sound_mode_use_def2 by auto
with preserves_guarantee_compliance in_ℛ'
show "conc.respects_own_guarantees (c⇩C', mds⇩C')"
unfolding preserves_local_guarantee_compliance_def by blast
qed
qed
end
section "Refinement without changing the Memory Model"
text ‹
Here we define a locale which restricts the refinement to be between an abstract and
concrete programs that share identical memory models: i,e. have the same set of variables.
This allows us to derive simpler versions of the conditions that are likely to be easier
to work with for initial experimentation.
›
locale sifum_refinement_same_mem =
abs: sifum_security dma 𝒞_vars 𝒞 eval⇩A some_val +
conc: sifum_security dma 𝒞_vars 𝒞 eval⇩C some_val
for dma :: "('Var,'Val) Mem ⇒ 'Var ⇒ Sec"
and 𝒞_vars :: "'Var ⇒ 'Var set"
and 𝒞 :: "'Var set"
and eval⇩A :: "('Com⇩A, 'Var, 'Val) LocalConf rel"
and eval⇩C :: "('Com⇩C, 'Var, 'Val) LocalConf rel"
and some_val :: "'Val"
sublocale sifum_refinement_same_mem ⊆
gen_refine: sifum_refinement dma dma 𝒞_vars 𝒞_vars 𝒞 𝒞 eval⇩A eval⇩C some_val id
by(unfold_locales, simp_all)
context sifum_refinement_same_mem begin
lemma [simp]:
"gen_refine.new_vars_private ℛ"
unfolding gen_refine.new_vars_private_def
by simp
definition
preserves_modes_mem :: "('Com⇩A, 'Var, 'Val, 'Com⇩C, 'Var) state_relation ⇒ bool"
where
"preserves_modes_mem ℛ ≡
(∀ c⇩A mds⇩A mem⇩A c⇩C mds⇩C mem⇩C. (⟨ c⇩A, mds⇩A, mem⇩A ⟩⇩A, ⟨ c⇩C, mds⇩C, mem⇩C ⟩⇩C) ∈ ℛ ⟶
mem⇩A = mem⇩C ∧ mds⇩A = mds⇩C)"
definition
closed_others :: "('Com⇩A, 'Var, 'Val, 'Com⇩C, 'Var) state_relation ⇒ bool"
where
"closed_others ℛ ≡
(∀ c⇩A mds mem c⇩C mem'. (⟨ c⇩A, mds, mem ⟩⇩A, ⟨ c⇩C, mds, mem ⟩⇩C) ∈ ℛ ⟶
(∀x. mem x ≠ mem' x ⟶ ¬ var_asm_not_written mds x) ⟶
(∀x. dma mem x ≠ dma mem' x ⟶ ¬ var_asm_not_written mds x) ⟶
(⟨ c⇩A, mds, mem' ⟩⇩A, ⟨ c⇩C, mds, mem' ⟩⇩C) ∈ ℛ)"
lemma [simp]:
"gen_refine.mds⇩A_of x = x"
by(simp add: gen_refine.mds⇩A_of_def)
lemma [simp]:
"gen_refine.mem⇩A_of x = x"
by(simp add: gen_refine.mem⇩A_of_def)
lemma [simp]:
"preserves_modes_mem ℛ ⟹
gen_refine.closed_others ℛ = closed_others ℛ"
unfolding closed_others_def
gen_refine.closed_others_def
preserves_modes_mem_def
by auto
lemma [simp]:
"gen_refine.preserves_modes_mem ℛ = preserves_modes_mem ℛ"
unfolding gen_refine.preserves_modes_mem_def2 preserves_modes_mem_def
by simp
definition
secure_refinement :: "('Com⇩A, 'Var, 'Val) LocalConf rel ⇒ ('Com⇩A, 'Var, 'Val, 'Com⇩C, 'Var) state_relation ⇒
('Com⇩C, 'Var, 'Val) LocalConf rel ⇒ bool"
where
"secure_refinement ℛ⇩A ℛ P ≡
closed_others ℛ ∧
preserves_modes_mem ℛ ∧
conc.closed_glob_consistent P ∧
(∀ c⇩1⇩A mds mem⇩1 c⇩1⇩C.
(⟨ c⇩1⇩A, mds, mem⇩1 ⟩⇩A, ⟨ c⇩1⇩C, mds, mem⇩1 ⟩⇩C) ∈ ℛ ⟶
(∀ c⇩1⇩C' mds' mem⇩1'. ⟨ c⇩1⇩C, mds, mem⇩1 ⟩⇩C ↝⇩C ⟨ c⇩1⇩C', mds', mem⇩1' ⟩⇩C ⟶
(∃ n c⇩1⇩A'. abs.neval ⟨ c⇩1⇩A, mds, mem⇩1 ⟩⇩A n ⟨ c⇩1⇩A', mds', mem⇩1' ⟩⇩A ∧
(⟨ c⇩1⇩A', mds', mem⇩1' ⟩⇩A, ⟨ c⇩1⇩C', mds', mem⇩1' ⟩⇩C) ∈ ℛ ∧
(∀c⇩2⇩A mem⇩2 c⇩2⇩C c⇩2⇩A' mem⇩2'.
(⟨ c⇩1⇩A, mds, mem⇩1 ⟩⇩A, ⟨ c⇩2⇩A, mds, mem⇩2 ⟩⇩A) ∈ ℛ⇩A ∧
(⟨ c⇩2⇩A, mds, mem⇩2 ⟩⇩A, ⟨ c⇩2⇩C, mds, mem⇩2 ⟩⇩C) ∈ ℛ ∧
(⟨c⇩1⇩C, mds, mem⇩1⟩⇩C, ⟨c⇩2⇩C, mds, mem⇩2⟩⇩C) ∈ P ∧
abs.neval ⟨ c⇩2⇩A, mds, mem⇩2 ⟩⇩A n ⟨ c⇩2⇩A', mds', mem⇩2' ⟩⇩A ⟶
(∃ c⇩2⇩C' . ⟨ c⇩2⇩C, mds, mem⇩2 ⟩⇩C ↝⇩C ⟨ c⇩2⇩C', mds', mem⇩2' ⟩⇩C ∧
(⟨ c⇩2⇩A', mds', mem⇩2' ⟩⇩A, ⟨ c⇩2⇩C', mds', mem⇩2' ⟩⇩C) ∈ ℛ ∧
(⟨c⇩1⇩C', mds', mem⇩1'⟩⇩C, ⟨c⇩2⇩C', mds', mem⇩2'⟩⇩C) ∈ P )))))"
lemma preserves_modes_memD:
"preserves_modes_mem ℛ ⟹
(⟨ c⇩A, mds⇩A, mem⇩A ⟩⇩A, ⟨ c⇩C, mds⇩C, mem⇩C ⟩⇩C) ∈ ℛ ⟹
mem⇩A = mem⇩C ∧ mds⇩A = mds⇩C"
by(auto simp: preserves_modes_mem_def)
lemma [simp]:
"gen_refine.secure_refinement ℛ⇩A ℛ P = secure_refinement ℛ⇩A ℛ P"
unfolding gen_refine.secure_refinement_def secure_refinement_def
apply safe
apply fastforce
apply fastforce
defer
apply fastforce
apply fastforce
apply fastforce
defer
apply ((drule spec)+, erule (1) impE)
apply ((drule spec)+, erule (1) impE)
apply (clarify)
apply(rename_tac n c⇩1⇩A' mds⇩A' mem⇩1⇩A')
apply(rule_tac x=n in exI)
apply(rule_tac x=c⇩1⇩A' in exI)
apply(fastforce dest: preserves_modes_memD)
apply (frule (1) preserves_modes_memD)
apply clarify
apply ((drule spec)+, erule (1) impE)
apply ((drule spec)+, erule (1) impE)
apply clarify
apply(blast dest: preserves_modes_memD)
done
lemma R⇩C_of_strong_low_bisim_mm:
assumes abs: "abs.strong_low_bisim_mm ℛ⇩A"
assumes rr: "secure_refinement ℛ⇩A ℛ P"
assumes P_sym: "sym P"
shows "conc.strong_low_bisim_mm (gen_refine.R⇩C_of ℛ⇩A ℛ P)"
using abs rr gen_refine.R⇩C_of_strong_low_bisim_mm[OF _ _ P_sym]
by simp
end
context sifum_refinement begin
lemma use_secure_refinement_helper:
"secure_refinement ℛ⇩A ℛ P ⟹
((cm⇩A,mem⇩A),(cm⇩C,mem⇩C)) ∈ ℛ ⟹ (cm⇩C,mem⇩C) ↝⇩C (cm⇩C',mem⇩C') ⟹
(∃cm⇩A' mem⇩A' n. abs.neval (cm⇩A,mem⇩A) n (cm⇩A',mem⇩A') ∧
((cm⇩A',mem⇩A'), (cm⇩C',mem⇩C')) ∈ ℛ)"
apply(case_tac cm⇩A, case_tac cm⇩C)
apply clarsimp
apply(clarsimp simp: secure_refinement_def)
by (metis surjective_pairing)
lemma closed_othersD:
"closed_others ℛ ⟹
(⟨c⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩C⟩⇩A, ⟨c⇩C, mds⇩C, mem⇩C⟩⇩C) ∈ ℛ ⟹
(⋀x. mem⇩C' x ≠ mem⇩C x ∨ dma⇩C mem⇩C' x ≠ dma⇩C mem⇩C x ⟹ ¬ var_asm_not_written mds⇩C x) ⟹
(⟨c⇩A, mds⇩A_of mds⇩C, mem⇩A_of mem⇩C'⟩⇩A, ⟨c⇩C, mds⇩C, mem⇩C'⟩⇩C) ∈ ℛ"
unfolding closed_others_def
by auto
end
record ('a, 'Val, 'Var⇩C, 'Com⇩C, 'Var⇩A, 'Com⇩A) componentwise_refinement =
priv_mem :: "'Var⇩C set"
ℛ⇩A_rel :: "('Com⇩A, 'Var⇩A, 'Val) LocalConf rel"
ℛ_rel :: "('Com⇩A, 'Var⇩A, 'Val, 'Com⇩C, 'Var⇩C) state_relation"
P_rel :: "('Com⇩C, 'Var⇩C, 'Val) LocalConf rel"
section "Whole System Refinement"
text ‹
A locale to capture componentwise refinement of an entire system.
›
locale sifum_refinement_sys =
sifum_refinement dma⇩A dma⇩C 𝒞_vars⇩A 𝒞_vars⇩C 𝒞⇩A 𝒞⇩C eval⇩A eval⇩C some_val var⇩C_of
for dma⇩A :: "('Var⇩A,'Val) Mem ⇒ 'Var⇩A ⇒ Sec"
and dma⇩C :: "('Var⇩C,'Val) Mem ⇒ 'Var⇩C ⇒ Sec"
and 𝒞_vars⇩A :: "'Var⇩A ⇒ 'Var⇩A set"
and 𝒞_vars⇩C :: "'Var⇩C ⇒ 'Var⇩C set"
and 𝒞⇩A :: "'Var⇩A set"
and 𝒞⇩C :: "'Var⇩C set"
and eval⇩A :: "('Com⇩A, 'Var⇩A, 'Val) LocalConf rel"
and eval⇩C :: "('Com⇩C, 'Var⇩C, 'Val) LocalConf rel"
and some_val :: "'Val"
and var⇩C_of :: "'Var⇩A ⇒ 'Var⇩C" +
fixes cms :: "('a::wellorder, 'Val, 'Var⇩C, 'Com⇩C, 'Var⇩A, 'Com⇩A) componentwise_refinement list"
fixes priv_mem⇩C :: "'Var⇩C set list"
defines priv_mem⇩C_def: "priv_mem⇩C ≡ map priv_mem cms"
assumes priv_mem_disjoint: "i < length cms ⟹ j < length cms ⟹ i ≠ j ⟹ priv_mem⇩C ! i ∩ priv_mem⇩C ! j = {}"
assumes new_vars_priv: "- range var⇩C_of = ⋃ (set priv_mem⇩C)"
assumes new_privs_preserved: "⟨c, mds, mem⟩⇩C ↝⇩C ⟨c', mds', mem'⟩⇩C ⟹ x ∉ range var⇩C_of ⟹
(x ∈ mds m) = (x ∈ mds' m)"
assumes secure_refinements:
"i < length cms ⟹ secure_refinement (ℛ⇩A_rel (cms ! i)) (ℛ_rel (cms ! i)) (P_rel (cms ! i))"
assumes local_guarantee_preservation:
"i < length cms ⟹ preserves_local_guarantee_compliance (ℛ_rel (cms ! i))"
assumes bisims:
"i < length cms ⟹ abs.strong_low_bisim_mm (ℛ⇩A_rel (cms ! i))"
assumes Ps_sym:
"⋀a b. i < length cms ⟹ sym (P_rel (cms ! i))"
assumes Ps_refl_on_low_mds_eq:
"i < length cms ⟹ conc.low_mds_eq mds⇩C mem⇩C mem⇩C' ⟹ (⟨c⇩C, mds⇩C, mem⇩C⟩⇩C, ⟨c⇩C, mds⇩C, mem⇩C'⟩⇩C) ∈ (P_rel (cms ! i))"
context sifum_security begin
lemma neval_modifies_helper:
assumes nevaln: "neval lcn m lcn'"
assumes lcn_def: "lcn = (cms ! n, mem)"
assumes lcn'_def: "lcn' = (cmn', mem')"
assumes len: "n < length cms"
assumes modified: "mem x ≠ mem' x ∨ dma mem x ≠ dma mem' x"
shows "∃k cmn'' mem'' cmn''' mem'''. k < m ∧ neval (cms ! n,mem) k (cmn'',mem'') ∧
(cmn'',mem'') ↝ (cmn''', mem''') ∧
(mem'' x ≠ mem''' x ∨ dma mem'' x ≠ dma mem''' x)"
using nevaln lcn_def lcn'_def modified len
proof(induct arbitrary: cms cmn' mem mem' rule: neval.induct)
case (neval_0 lcn lcn')
from neval_0 show ?case by simp
next
case (neval_S_n lcn lcn'' m lcn')
obtain cmn'' mem'' where lcn''_def: "lcn'' = (cmn'', mem'')" by fastforce
show ?case
proof(cases "mem x ≠ mem'' x ∨ dma mem x ≠ dma mem'' x")
assume a: "mem x ≠ mem'' x ∨ dma mem x ≠ dma mem'' x"
let ?k = "0::nat"
let ?cmn'' = "cms ! n"
let ?mem'' = "mem"
have "?k < Suc m ∧
neval (cms ! n, mem) ?k (?cmn'', ?mem'') ∧
(?cmn'', ?mem'') ↝ (cmn'', mem'') ∧ (?mem'' x ≠ mem'' x ∨
dma ?mem'' x ≠ dma mem'' x)"
apply (rule conjI, simp add: neval.neval_0)+
apply (simp only: a)
by (simp add: neval_S_n(1)[simplified neval_S_n lcn''_def])
thus ?case by blast
next
assume a: "¬ (mem x ≠ mem'' x ∨ dma mem x ≠ dma mem'' x)"
hence unchanged: "mem'' x = mem x ∧ dma mem'' x = dma mem x"
by (blast intro: sym)
define cms'' where "cms'' = cms[n := cmn'']"
have len'': "n < length cms''"
by(simp add: cms''_def neval_S_n)
hence lcn''_def2: "lcn'' = (cms'' ! n, mem'')"
by(simp add: lcn''_def cms''_def)
from
neval_S_n(3)[OF lcn''_def2 neval_S_n(5), simplified unchanged neval_S_n len'']
obtain k cmn''' mem''' cmn'''' mem'''' where
hyp: "k < m ∧
neval (cms'' ! n, mem'') k (cmn''', mem''') ∧
(cmn''', mem''') ↝ (cmn'''', mem'''') ∧
(mem''' x ≠ mem'''' x ∨ dma mem''' x ≠ dma mem'''' x)"
by blast
have "neval (cms ! n, mem) (Suc k) (cmn''', mem''')"
apply(rule neval.neval_S_n)
prefer 2
using hyp apply fastforce
apply(simp add: cms''_def neval_S_n)
by(rule neval_S_n(1)[simplified neval_S_n lcn''_def])
moreover have "Suc k < Suc m" using hyp by auto
ultimately show ?case using hyp by fastforce
qed
qed
lemma neval_sched_Nil [simp]:
"(cms, mem) →⇘[]⇙ (cms, mem)"
by simp
lemma reachable_mode_states_refl:
"map snd cms ∈ reachable_mode_states (cms, mem)"
apply(clarsimp simp: reachable_mode_states_def)
using neval_sched_Nil by blast
lemma neval_reachable_mode_states:
assumes neval: "neval lc n lc'"
assumes lc_def: "lc = (cms ! k, mem)"
assumes len: "k < length cms"
shows "map snd (cms[k := (fst lc')]) ∈ reachable_mode_states (cms, mem)"
using neval lc_def len proof(induct arbitrary: cms mem rule: neval.induct)
case (neval_0 x y)
thus ?case
apply simp
apply(drule sym, simp add: len reachable_mode_states_refl)
done
next
case (neval_S_n x y n z)
define cms' where "cms' = cms[k := fst y]"
define mem' where "mem' = snd y"
have y_def: "y = (cms' ! k, mem')"
by(simp add: cms'_def mem'_def neval_S_n)
moreover have len': "k < length cms'"
by(simp add: cms'_def neval_S_n)
ultimately have hyp: "map snd (cms'[k := fst z]) ∈ reachable_mode_states (cms', mem')"
using neval_S_n by metis
have "map snd (cms'[k := fst z]) = map snd (cms[k := fst z])"
unfolding cms'_def
by simp
moreover have "(cms, mem) ↝⇘k⇙ (cms', mem')"
using meval_intro neval_S_n y_def cms'_def mem'_def len' by fastforce
ultimately show ?case
using reachable_modes_subset subsetD hyp by fastforce
qed
lemma meval_sched_sound_mode_use:
"sound_mode_use gc ⟹ meval_sched sched gc gc' ⟹ sound_mode_use gc'"
proof(induct rule: meval_sched.induct)
case (1 gc)
thus ?case by simp
next
case (2 n ns gc gc')
from 2(3) obtain gc'' where "meval_abv gc n gc''" and a: "meval_sched ns gc'' gc'" by force
with 2(2) sound_modes_invariant have b: "sound_mode_use gc''" by (metis surjective_pairing)
show ?case by (rule 2(1)[OF b a])
qed
lemma neval_meval:
"neval lcn k lcn' ⟹ n < length cms ⟹ lcn = (cms ! n,mem) ⟹ lcn' = (cmn', mem') ⟹
meval_sched (replicate k n) (cms,mem) (cms[n := cmn'],mem')"
proof(induct arbitrary: cms mem cmn' mem' rule: neval.induct)
case (neval_0 lcn lcn')
thus ?case by fastforce
next
case (neval_S_n lcn lcn'' k lcn')
define cms'' where [simp]: "cms'' = cms[n := fst lcn'']"
define mem'' where [simp]: "mem'' = snd lcn''"
have len'' [simp]: "n < length cms''" by(simp add: neval_S_n(4))
have lcn''_def: "lcn'' = (cms'' ! n, mem'')" using len'' by simp
have hyp: "(cms'', mem'') →⇘replicate k n⇙ (cms''[n := cmn'], mem')"
by (rule neval_S_n(3)[OF len'' lcn''_def neval_S_n(6)])
have meval: "(cms, mem) ↝⇘n⇙ (cms'', mem'')"
using cms''_def neval_S_n.hyps(1) neval_S_n.prems(1) neval_S_n.prems(2) by fastforce
from hyp meval show ?case
by fastforce
qed
lemma meval_sched_app:
"meval_sched as gc gc' ⟹ meval_sched bs gc' gc'' ⟹ meval_sched (as@bs) gc gc''"
proof(induct as arbitrary: gc gc' bs)
case Nil thus ?case by simp
next
case (Cons a as)
from Cons(2)
obtain gc''' where a: "meval_abv gc a gc'''" and as: "meval_sched as gc''' gc'" by force
from Cons(1)[OF as Cons(3)] a
have "gc →⇘a # (as @ bs)⇙ gc''"
by (metis meval_sched.simps)
thus ?case by simp
qed
end
context sifum_refinement_sys begin
lemma conc_respects_priv:
assumes xnin: "x⇩C ∉ range var⇩C_of"
assumes modified⇩C: "mem⇩C x⇩C ≠ mem⇩C' x⇩C ∨ dma⇩C mem⇩C x⇩C ≠ dma⇩C mem⇩C' x⇩C"
assumes eval⇩C: "(cms⇩C ! n, mem⇩C) ↝⇩C (cm⇩Cn', mem⇩C')"
assumes in_ℛn: "((cms⇩A ! n, mem⇩A), cms⇩C ! n, mem⇩C) ∈ ℛn"
assumes preserves: "preserves_local_guarantee_compliance ℛn"
assumes sound_mode_use⇩A: "abs.sound_mode_use (cms⇩A, mem⇩A)"
assumes nlen: "n < length cms"
assumes len_eq: "length cms⇩A = length cms"
assumes len_eq': "length cms⇩C = length cms"
shows "x⇩C ∉ (snd (cms⇩C ! n)) GuarNoWrite ∧ x⇩C ∉ (snd (cms⇩C ! n)) GuarNoReadOrWrite"
proof -
from sound_mode_use⇩A have "abs.respects_own_guarantees (cms⇩A ! n)"
using nlen len_eq abs.locally_sound_respects_guarantees
unfolding abs.sound_mode_use_def list_all_length
by fastforce
with in_ℛn have 1: "conc.respects_own_guarantees (cms⇩C ! n)"
using preserves
unfolding preserves_local_guarantee_compliance_def
by metis
with eval⇩C modified⇩C have 2: "¬ conc.doesnt_modify (fst (cms⇩C ! n)) x⇩C"
unfolding conc.doesnt_modify_def
by (metis surjective_pairing)
then have "¬ conc.doesnt_read_or_modify (fst (cms⇩C ! n)) x⇩C"
using conc.doesnt_read_or_modify_doesnt_modify by metis
with 1 2 show ?thesis
unfolding conc.respects_own_guarantees_def
by metis
qed
lemma modified_variables_are_not_assumed_not_written:
fixes cms⇩A mem⇩A cms⇩C mem⇩C cm⇩Cn' mem⇩C' ℛn cm⇩An' mem⇩A' m⇩A ℛi
assumes sound_mode_use⇩A: "abs.sound_mode_use (cms⇩A, mem⇩A)"
assumes pmmn: "preserves_modes_mem ℛn"
assumes in_ℛn: "((cms⇩A ! n, mem⇩A), (cms⇩C ! n, mem⇩C)) ∈ ℛn"
assumes pmmi: "preserves_modes_mem ℛi"
assumes in_ℛi: "((cms⇩A ! i, mem⇩A), (cms⇩C ! i, mem⇩C)) ∈ ℛi"
assumes nlen: "n < length cms"
assumes len⇩A: "length cms⇩A = length cms"
assumes len⇩C: "length cms⇩C = length cms"
assumes priv_is_asm_priv: "⋀i. i < length cms ⟹ priv_mem⇩C ! i ⊆ snd (cms⇩C ! i) AsmNoReadOrWrite"
assumes priv_is_guar_priv: "⋀i j. i < length cms ⟹ j < length cms ⟹ i ≠ j ⟹ priv_mem⇩C ! i ⊆ snd (cms⇩C ! j) GuarNoReadOrWrite"
assumes new_asms_only_for_priv: "⋀i. i < length cms ⟹
(snd (cms⇩C ! i) AsmNoReadOrWrite ∪ snd (cms⇩C ! i) AsmNoWrite) ∩ (- range var⇩C_of) ⊆ priv_mem⇩C ! i"
assumes eval⇩Cn: "(cms⇩C ! n,mem⇩C) ↝⇩C (cm⇩Cn', mem⇩C')"
assumes neval⇩An: "abs.neval (cms⇩A ! n,mem⇩A) m⇩A (cm⇩An', mem⇩A')"
assumes in_ℛn': "((cm⇩An', mem⇩A'), (cm⇩Cn', mem⇩C')) ∈ ℛn"
assumes modified⇩C: "mem⇩C x⇩C ≠ mem⇩C' x⇩C ∨ dma⇩C mem⇩C x⇩C ≠ dma⇩C mem⇩C' x⇩C"
assumes neq: "i ≠ n"
assumes ilen: "i < length cms"
assumes preserves: "preserves_local_guarantee_compliance ℛn"
shows "¬ var_asm_not_written (snd (cms⇩C ! i)) x⇩C"
proof(cases "x⇩C ∈ range var⇩C_of")
assume "x⇩C ∈ range var⇩C_of"
from this obtain x⇩A where x⇩C_def: "x⇩C = var⇩C_of x⇩A" by blast
obtain c⇩An mds⇩An where [simp]: "cms⇩A ! n = (c⇩An, mds⇩An)" by fastforce
obtain c⇩Cn mds⇩Cn where [simp]: "cms⇩C ! n = (c⇩Cn, mds⇩Cn)" by fastforce
obtain c⇩Cn' mds⇩Cn' where [simp]: "cm⇩Cn' = (c⇩Cn', mds⇩Cn')" by fastforce
obtain c⇩An' mds⇩An' where [simp]: "cm⇩An' = (c⇩An', mds⇩An')" by fastforce
from in_ℛn pmmn have [simp]: "mem⇩A = mem⇩A_of mem⇩C" and [simp]: "mds⇩An = mds⇩A_of mds⇩Cn"
using preserves_modes_memD by auto
from in_ℛn' pmmn have [simp]: "mem⇩A' = mem⇩A_of mem⇩C'" and [simp]: "mds⇩An' = mds⇩A_of mds⇩Cn'"
using preserves_modes_memD by auto
from modified⇩C dma_consistent have
modified⇩A: "mem⇩A x⇩A ≠ mem⇩A' x⇩A ∨ dma⇩A mem⇩A x⇩A ≠ dma⇩A mem⇩A' x⇩A"
by (simp add: mem⇩A_of_def x⇩C_def)
from len⇩A nlen have nlen⇩A: "n < length cms⇩A" by simp
from len⇩A ilen have ilen⇩A: "i < length cms⇩A" by simp
from abs.neval_modifies_helper[OF neval⇩An HOL.refl HOL.refl nlen⇩A modified⇩A]
obtain k⇩A cm⇩An'' mem⇩A'' cm⇩An''' mem⇩A'''
where "k⇩A < m⇩A"
and neval⇩An'': "abs.neval (cms⇩A ! n, mem⇩A) k⇩A (cm⇩An'', mem⇩A'')"
and eval⇩An'': "(cm⇩An'', mem⇩A'') ↝⇩A (cm⇩An''', mem⇩A''')"
and modified⇩A'': "(mem⇩A'' x⇩A ≠ mem⇩A''' x⇩A ∨ dma⇩A mem⇩A'' x⇩A ≠ dma⇩A mem⇩A''' x⇩A)" by blast
let ?c⇩An'' = "fst cm⇩An''"
let ?mds⇩An'' = "snd cm⇩An''"
from eval⇩An'' modified⇩A'' have modifies⇩A'': "¬ abs.doesnt_modify ?c⇩An'' x⇩A"
unfolding abs.doesnt_modify_def
by (metis surjective_pairing)
have loc_reach⇩A'': "(cm⇩An'', mem⇩A'') ∈ abs.loc_reach (cms⇩A ! n, mem⇩A)"
apply(rule abs.neval_loc_reach)
apply(rule neval⇩An'')
using abs.loc_reach.refl by simp
have locally_sound_mode_use⇩An: "abs.locally_sound_mode_use (cms⇩A ! n, mem⇩A)"
using sound_mode_use⇩A nlen⇩A
unfolding abs.sound_mode_use_def
using list_all_length by fastforce
from modifies⇩A'' loc_reach⇩A'' locally_sound_mode_use⇩An abs.doesnt_read_or_modify_doesnt_modify
have no_guar⇩An: "x⇩A ∉ ?mds⇩An'' GuarNoReadOrWrite ∧ x⇩A ∉ ?mds⇩An'' GuarNoWrite"
unfolding abs.locally_sound_mode_use_def
by (metis surjective_pairing)
let ?mdss⇩A'' = "map snd (cms⇩A[n := fst (cm⇩An'',mem⇩A'')])"
have "?mdss⇩A'' ∈ abs.reachable_mode_states (cms⇩A, mem⇩A)"
apply(rule abs.neval_reachable_mode_states)
apply(rule neval⇩An'')
apply(rule HOL.refl)
by(rule nlen⇩A)
hence compat: "abs.compatible_modes ?mdss⇩A''"
using sound_mode_use⇩A
by(simp add: abs.globally_sound_mode_use_def)
have n: "?mdss⇩A'' ! n = ?mds⇩An''"
by(simp add: nlen⇩A)
let ?mds⇩Ai = "snd (cms⇩A ! i)"
have i: "?mdss⇩A'' ! i = ?mds⇩Ai"
apply(simp add: ilen⇩A)
by(metis nth_list_update_neq neq)
from nlen⇩A have nlen⇩A'': "n < length ?mdss⇩A''" by simp
from ilen⇩A have ilen⇩A'': "i < length ?mdss⇩A''" by simp
with compat n i nlen⇩A'' ilen⇩A'' no_guar⇩An neq
have no_asm⇩Ai: "x⇩A ∉ ?mds⇩Ai AsmNoWrite ∧ x⇩A ∉ ?mds⇩Ai AsmNoReadOrWrite"
unfolding abs.compatible_modes_def
by metis
obtain c⇩Ai mds⇩Ai where [simp]: "cms⇩A ! i = (c⇩Ai, mds⇩Ai)" by fastforce
obtain c⇩Ci mds⇩Ci where [simp]: "cms⇩C ! i = (c⇩Ci, mds⇩Ci)" by fastforce
from in_ℛi pmmi have [simp]: "mds⇩Ai = mds⇩A_of mds⇩Ci"
using preserves_modes_memD by auto
have [simp]: "?mds⇩Ai = mds⇩Ai" by simp
from no_asm⇩Ai have no_asm⇩Ci: "x⇩C ∉ mds⇩Ci AsmNoWrite ∧ x⇩C ∉ mds⇩Ci AsmNoReadOrWrite"
using x⇩C_def mds⇩A_of_def
using doesnt_have_mode by auto
thus ?thesis
unfolding var_asm_not_written_def
by simp
next
let ?mds⇩Cn = "snd (cms⇩C ! n)"
let ?mds⇩Ci = "snd (cms⇩C ! i)"
assume new_var: "x⇩C ∉ range var⇩C_of"
from conc_respects_priv[OF new_var modified⇩C eval⇩Cn in_ℛn preserves sound_mode_use⇩A nlen len⇩A len⇩C]
have "x⇩C ∉ ?mds⇩Cn GuarNoWrite ∧ x⇩C ∉ ?mds⇩Cn GuarNoReadOrWrite" .
with priv_is_guar_priv nlen ilen neq
have "x⇩C ∉ priv_mem⇩C ! i"
by blast
with new_var new_asms_only_for_priv ilen
have "x⇩C ∉ ?mds⇩Ci AsmNoReadOrWrite ∪ ?mds⇩Ci AsmNoWrite"
by blast
thus ?thesis
unfolding var_asm_not_written_def
by simp
qed
definition
priv_is_asm_priv :: "'Var⇩C Mds list ⇒ bool"
where
"priv_is_asm_priv mdss⇩C ≡ ∀i < length cms. priv_mem⇩C ! i ⊆ (mdss⇩C ! i) AsmNoReadOrWrite"
definition
priv_is_guar_priv :: "'Var⇩C Mds list ⇒ bool"
where
"priv_is_guar_priv mdss⇩C ≡
∀i < length cms. (∀j < length cms. i ≠ j ⟶ priv_mem⇩C ! i ⊆ (mdss⇩C ! j) GuarNoReadOrWrite)"
definition
new_asms_only_for_priv :: "'Var⇩C Mds list ⇒ bool"
where
"new_asms_only_for_priv mdss⇩C ≡
∀ i < length cms.
((mdss⇩C ! i) AsmNoReadOrWrite ∪ (mdss⇩C ! i) AsmNoWrite) ∩ (- range var⇩C_of) ⊆ priv_mem⇩C ! i"
definition
new_asms_NoReadOrWrite_only :: "'Var⇩C Mds list ⇒ bool"
where
"new_asms_NoReadOrWrite_only mdss⇩C ≡
∀ i < length cms.
(mdss⇩C ! i) AsmNoWrite ∩ (- range var⇩C_of) = {}"
definition
modes_respect_priv :: "'Var⇩C Mds list ⇒ bool"
where
"modes_respect_priv mdss⇩C ≡ priv_is_asm_priv mdss⇩C ∧ priv_is_guar_priv mdss⇩C ∧
new_asms_only_for_priv mdss⇩C ∧
new_asms_NoReadOrWrite_only mdss⇩C"
definition
ignores_old_vars :: "('Var⇩C Mds list ⇒ bool) ⇒ bool"
where
"ignores_old_vars P ≡ ∀mdss mdss'. length mdss = length mdss' ∧ length mdss' = length cms ⟶
(map (λx m. x m ∩ (- range var⇩C_of)) mdss) = (map (λx m. x m ∩ (- range var⇩C_of)) mdss') ⟶
P mdss = P mdss'"
lemma ignores_old_vars_conj:
assumes Rdef: "(⋀x. R x = (P x ∧ Q x))"
assumes iP: "ignores_old_vars P"
assumes iQ: "ignores_old_vars Q"
shows "ignores_old_vars R"
unfolding ignores_old_vars_def
apply(simp add: Rdef)
apply(intro impI allI)
apply(rule conj_cong)
apply(erule (1) iP[unfolded ignores_old_vars_def, rule_format])
apply(erule (1) iQ[unfolded ignores_old_vars_def, rule_format])
done
lemma nth_map_eq':
"length xs = length ys ⟹ map f xs = map g ys ⟹ i < length xs ⟹ f (xs ! i) = g (ys ! i)"
apply(induct xs ys rule: list_induct2)
apply simp
apply(case_tac i)
apply force
by (metis length_map nth_map)
lemma nth_map_eq:
"map f xs = map g ys ⟹ i < length xs ⟹ f (xs ! i) = g (ys ! i)"
apply(rule nth_map_eq')
apply(erule map_eq_imp_length_eq)
apply assumption+
done
lemma nth_in_Union_over_set:
"i < length xs ⟹ xs ! i ⊆ ⋃(set xs)"
by (simp add: Union_upper)
lemma priv_are_new_vars:
"x ∈ priv_mem⇩C ! i ⟹ i < length cms ⟹ x ∉ range var⇩C_of"
using new_vars_priv nth_in_Union_over_set subsetD
using priv_mem⇩C_def by fastforce
lemma priv_is_asm_priv_ignores_old_vars:
"ignores_old_vars priv_is_asm_priv"
apply(clarsimp simp: ignores_old_vars_def priv_is_asm_priv_def)
apply(rule all_cong)
apply(drule nth_map_eq)
apply simp
apply(blast dest: priv_are_new_vars fun_cong)
done
lemma priv_is_guar_priv_ignores_old_vars:
"ignores_old_vars priv_is_guar_priv"
apply(clarsimp simp: ignores_old_vars_def priv_is_guar_priv_def)
apply(rule all_cong)
apply(rule all_cong)
apply(rule imp_cong)
apply(rule HOL.refl)
apply(frule nth_map_eq)
apply simp
apply(drule_tac i=j in nth_map_eq)
apply simp
apply(blast dest: priv_are_new_vars fun_cong)
done
lemma new_asms_only_for_priv_ignores_old_vars:
"ignores_old_vars new_asms_only_for_priv"
apply(clarsimp simp: ignores_old_vars_def new_asms_only_for_priv_def)
apply(rule all_cong)
apply(drule nth_map_eq)
apply simp
apply(blast dest: priv_are_new_vars fun_cong)
done
lemma new_asms_NoReadOrWrite_only_ignores_old_vars:
"ignores_old_vars new_asms_NoReadOrWrite_only"
apply(clarsimp simp: ignores_old_vars_def new_asms_NoReadOrWrite_only_def)
apply(rule all_cong)
apply(drule nth_map_eq)
apply simp
apply(blast dest: priv_are_new_vars fun_cong)
done
lemma modes_respect_priv_ignores_old_vars:
"ignores_old_vars modes_respect_priv"
apply(rule ignores_old_vars_conj)
apply(subst modes_respect_priv_def)
apply(rule HOL.refl)
apply(rule priv_is_asm_priv_ignores_old_vars)
apply(rule ignores_old_vars_conj)
apply(rule HOL.refl)
apply(rule priv_is_guar_priv_ignores_old_vars)
apply(rule ignores_old_vars_conj)
apply(rule HOL.refl)
apply(rule new_asms_only_for_priv_ignores_old_vars)
apply(rule new_asms_NoReadOrWrite_only_ignores_old_vars)
done
lemma ignores_old_varsD:
"ignores_old_vars P ⟹ length mdss = length mdss' ⟹ length mdss' = length cms ⟹
(map (λx m. x m ∩ (- range var⇩C_of)) mdss) = (map (λx m. x m ∩ (- range var⇩C_of)) mdss') ⟹
P mdss = P mdss'"
unfolding ignores_old_vars_def
by force
lemma new_privs_preserved':
"⟨c, mds, mem⟩⇩C ↝⇩C ⟨c', mds', mem'⟩⇩C ⟹ (mds m ∩ (- range var⇩C_of)) = (mds' m ∩ (- range var⇩C_of))"
using new_privs_preserved by blast
lemma map_nth_eq:
"length xs = length ys ⟹ (⋀i. i < length xs ⟹ f (xs ! i) = g (ys ! i)) ⟹
map f xs = map g ys"
apply(induct xs ys rule: list_induct2)
apply simp
apply force
done
lemma ignores_old_vars_conc_meval:
assumes ignores: "ignores_old_vars P"
assumes meval: "conc.meval_abv gc⇩C n gc⇩C'"
assumes len_eq: "length (fst gc⇩C) = length cms"
shows "P (map snd (fst gc⇩C)) = P (map snd (fst gc⇩C'))"
proof -
obtain cms⇩C mem⇩C where [simp]: "gc⇩C = (cms⇩C, mem⇩C)" by fastforce
obtain cms⇩C' mem⇩C' where [simp]: "gc⇩C' = (cms⇩C', mem⇩C')" by fastforce
from meval obtain cmn' mem⇩C' where
eval⇩Cn: "(cms⇩C ! n, mem⇩C) ↝⇩C (cmn', mem⇩C')" and len: "n < length cms⇩C" and cms⇩C'_def: "cms⇩C' = cms⇩C[n := cmn']"
using conc.meval.cases by fastforce
have
"P (map snd cms⇩C) = P (map snd cms⇩C')"
apply(rule ignores_old_varsD[OF ignores])
apply(simp add: cms⇩C'_def)
using len_eq apply (simp add: cms⇩C'_def)
apply(rule map_nth_eq)
apply (simp add: cms⇩C'_def)
apply(case_tac "i = n")
apply simp
apply(rule ext)
apply(simp add: cms⇩C'_def)
using eval⇩Cn new_privs_preserved' apply(metis surjective_pairing)
by (simp add: cms⇩C'_def)
thus ?thesis by simp
qed
lemma ignores_old_vars_conc_meval_sched:
assumes ignores: "ignores_old_vars P"
assumes meval_sched: "conc.meval_sched sched gc⇩C gc⇩C'"
assumes len_eq: "length (fst gc⇩C) = length cms"
shows "P (map snd (fst gc⇩C)) = P (map snd (fst gc⇩C'))"
using meval_sched len_eq proof(induct rule: conc.meval_sched.induct)
case (1 gc gc')
thus ?case by simp
next
case (2 n ns gc gc')
from 2(2) obtain gc'' where b: "conc.meval_abv gc n gc''" and a: "conc.meval_sched ns gc'' gc'" by force
with 2 have "length (fst gc'') = length cms"
using conc.meval.cases
by (metis length_list_update surjective_pairing)
with 2 a b show ?case
using ignores_old_vars_conc_meval ignores by metis
qed
lemma meval_sched_modes_respect_priv:
"conc.meval_sched sched gc⇩C gc⇩C' ⟹ length (fst gc⇩C) = length cms ⟹
modes_respect_priv (map snd (fst gc⇩C)) ⟹
modes_respect_priv (map snd (fst gc⇩C'))"
by(blast dest!: ignores_old_vars_conc_meval_sched[OF modes_respect_priv_ignores_old_vars])
lemma meval_modes_respect_priv:
"conc.meval_abv gc⇩C n gc⇩C' ⟹ length (fst gc⇩C) = length cms ⟹
modes_respect_priv (map snd (fst gc⇩C)) ⟹
modes_respect_priv (map snd (fst gc⇩C'))"
by(blast dest!: ignores_old_vars_conc_meval[OF modes_respect_priv_ignores_old_vars])
lemma traces_refinement:
"⋀gc⇩C gc⇩C' sched⇩C gc⇩A. conc.meval_sched sched⇩C gc⇩C gc⇩C' ⟹
length (fst gc⇩A) = length cms ⟹ length (fst gc⇩C) = length cms ⟹
(⋀i. i < length cms ⟹ ((fst gc⇩A ! i, snd gc⇩A), (fst gc⇩C ! i, snd gc⇩C)) ∈ ℛ_rel (cms ! i)) ⟹
abs.sound_mode_use gc⇩A ⟹ modes_respect_priv (map snd (fst gc⇩C)) ⟹
∃sched⇩A gc⇩A'. abs.meval_sched sched⇩A gc⇩A gc⇩A' ∧
(∀i. i < length cms ⟶ ((fst gc⇩A' ! i, snd gc⇩A'), (fst gc⇩C' ! i, snd gc⇩C')) ∈ ℛ_rel (cms ! i)) ∧
abs.sound_mode_use gc⇩A'"
proof -
fix gc⇩C gc⇩C' sched⇩C gc⇩A
assume meval⇩C: "conc.meval_sched sched⇩C gc⇩C gc⇩C'"
and len_eq [simp]: "length (fst gc⇩A) = length cms"
and len_eq'[simp]: "length (fst gc⇩C) = length cms"
and in_ℛ: "(⋀i. i < length cms ⟹ ((fst gc⇩A ! i, snd gc⇩A), (fst gc⇩C ! i, snd gc⇩C)) ∈ ℛ_rel (cms ! i))"
and sound_mode_use⇩A: "abs.sound_mode_use gc⇩A"
and modes_respect_priv: "modes_respect_priv (map snd (fst gc⇩C))"
thus
"∃sched⇩A gc⇩A'. abs.meval_sched sched⇩A gc⇩A gc⇩A' ∧
(∀i. i < length cms ⟶ ((fst gc⇩A' ! i, snd gc⇩A'), (fst gc⇩C' ! i, snd gc⇩C')) ∈ ℛ_rel (cms ! i)) ∧
abs.sound_mode_use gc⇩A'"
proof(induct arbitrary: gc⇩A rule: conc.meval_sched.induct)
case (1 cms⇩C cms⇩C')
from 1(1) have cms⇩C'_def [simp]: "cms⇩C' = cms⇩C" by simp
with 1 have "abs.meval_sched [] gc⇩A gc⇩A ∧
(∀i<length cms.
((fst gc⇩A ! i, snd gc⇩A), fst cms⇩C' ! i, snd cms⇩C') ∈ ℛ_rel (cms ! i)) ∧
abs.sound_mode_use gc⇩A"
by simp
thus ?case by blast
next
case (2 n ns gc⇩C gc⇩c')
obtain cms⇩C mem⇩C where gc⇩C_def [simp]: "gc⇩C = (cms⇩C, mem⇩C)" by force
obtain cms⇩A mem⇩A where gc⇩A_def [simp]: "gc⇩A = (cms⇩A, mem⇩A)" by force
from 2(2) gc⇩C_def obtain cms⇩C'' mem⇩C'' where
meval⇩C: "((cms⇩C,mem⇩C), n, (cms⇩C'',mem⇩C'')) ∈ conc.meval" and
meval_sched⇩C: "conc.meval_sched ns (cms⇩C'',mem⇩C'') gc⇩c'"
by force
let ?cm⇩Cn = "cms⇩C ! n"
let ?cm⇩An = "cms⇩A ! n"
let ?ℛn = "ℛ_rel (cms ! n)"
from meval⇩C obtain cm⇩Cn'' where
eval⇩Cn: "(?cm⇩Cn, mem⇩C) ↝⇩C (cm⇩Cn'', mem⇩C'')" and
len: "n < length cms⇩C" and
cms⇩C''_def: "cms⇩C'' = cms⇩C [n := cm⇩Cn'']" by (blast elim: conc.meval.cases)
from len have len [simp]: "n < length cms" by (simp add: 2[simplified])
from cms⇩C''_def 2 have
len_cms⇩C'' [simp]: "length cms⇩C'' = length cms" by simp
from 2 len have
in_ℛn: "((?cm⇩An,mem⇩A), (?cm⇩Cn,mem⇩C)) ∈ ?ℛn"
by simp
with eval⇩Cn use_secure_refinement_helper[OF secure_refinements[OF len]]
obtain cm⇩An'' mem⇩A'' m⇩A where
neval⇩An: "abs.neval (?cm⇩An, mem⇩A) m⇩A (cm⇩An'', mem⇩A'')" and
in_ℛn'': "((cm⇩An'',mem⇩A''),(cm⇩Cn'',mem⇩C'')) ∈ ?ℛn"
by blast+
define cms⇩A'' where "cms⇩A'' = cms⇩A [n := cm⇩An'']"
define gc⇩A'' where [simp]: "gc⇩A'' = (cms⇩A'', mem⇩A'')"
have len_cms⇩A'' [simp]: "length cms⇩A'' = length cms" by(simp add: cms⇩A''_def 2[simplified])
have in_ℛ'': "(⋀i. i < length cms ⟹ ((cms⇩A'' ! i, mem⇩A''), cms⇩C'' ! i, mem⇩C'') ∈ ℛ_rel (cms ! i))"
proof -
fix i
assume "i < length cms"
show "?thesis i"
proof(cases "i = n")
assume "i = n"
hence "cms⇩A'' ! i = cm⇩An''"
using cms⇩A''_def len_cms⇩A'' len by simp
moreover from ‹i = n› have "cms⇩C'' ! i = cm⇩Cn''"
using cms⇩C''_def len_cms⇩C'' len by simp
ultimately show ?thesis
using in_ℛn'' ‹i = n›
by simp
next
obtain c⇩Ai mds⇩Ai where cms⇩Ai_def [simp]: "(cms⇩A ! i) = (c⇩Ai, mds⇩Ai)" by fastforce
obtain c⇩Ci mds⇩Ci where cms⇩Ci_def [simp]: "(cms⇩C ! i) = (c⇩Ci, mds⇩Ci)" by fastforce
hence mds⇩Ci_def: "mds⇩Ci = snd (cms⇩C ! i)" by simp
from 2(5) ‹i < length cms› have
in_ℛi: "((cms⇩A ! i,mem⇩A), (cms⇩C ! i,mem⇩C)) ∈ ℛ_rel (cms ! i)"
by force
from in_ℛn'' secure_refinements len preserves_modes_memD
have mem⇩A''_def [simp]: "mem⇩A'' = mem⇩A_of mem⇩C''"
unfolding secure_refinement_def
by (metis surjective_pairing)
from in_ℛi secure_refinements ‹i < length cms› preserves_modes_memD
cms⇩Ai_def cms⇩Ci_def
have mem⇩A_def [simp]: "mem⇩A = mem⇩A_of mem⇩C" and
mds⇩Ai_def [simp]: "mds⇩Ai = mds⇩A_of mds⇩Ci"
unfolding secure_refinement_def
by metis+
assume "i ≠ n"
hence "cms⇩A'' ! i = cms⇩A ! i"
using cms⇩A''_def len_cms⇩A'' len by simp
moreover from ‹i ≠ n› have "cms⇩C'' ! i = cms⇩C ! i"
using cms⇩C''_def len_cms⇩C'' len by simp
ultimately show ?thesis
using 2(5)[of i] ‹i ≠ n› ‹i < length cms›
apply simp
apply(rule closed_othersD)
apply(rule secure_refinements[OF ‹i < length cms›, unfolded secure_refinement_def, THEN conjunct1])
apply assumption
apply(simp only: mds⇩Ci_def)
apply(rule_tac ℛn="ℛ_rel (cms ! n)" and ℛi="ℛ_rel (cms ! i)" in modified_variables_are_not_assumed_not_written)
apply(rule 2(6)[unfolded gc⇩A_def])
using secure_refinements len secure_refinement_def apply blast
apply(rule in_ℛn)
using secure_refinements secure_refinement_def apply blast
apply(rule in_ℛi)
apply(rule len)
using 2 apply simp
using 2 apply simp
using 2(7) unfolding modes_respect_priv_def priv_is_asm_priv_def gc⇩C_def
using "2.prems"(3) apply auto[1]
using 2(7) unfolding modes_respect_priv_def priv_is_guar_priv_def gc⇩C_def
using "2.prems"(3) apply auto[1]
using 2(7) unfolding modes_respect_priv_def new_asms_only_for_priv_def gc⇩C_def
using "2.prems"(3) apply auto[1]
apply(rule eval⇩Cn)
apply(rule neval⇩An)
apply(rule in_ℛn'')
apply fastforce
apply assumption
apply assumption
apply(rule local_guarantee_preservation)
by simp
qed
qed
have meval_sched⇩A: "abs.meval_sched (replicate m⇩A n) gc⇩A (cms⇩A'', mem⇩A'')"
apply(simp add: cms⇩A''_def)
apply(rule abs.neval_meval[OF _ _ HOL.refl HOL.refl])
apply(rule neval⇩An)
using "2.prems"(2) by auto
have sound_mode_use⇩A'': "abs.sound_mode_use (cms⇩A'', mem⇩A'')"
apply(rule abs.meval_sched_sound_mode_use)
apply(rule 2(6))
by(rule meval_sched⇩A)
have respects'': "modes_respect_priv (map snd cms⇩C'')"
apply(rule meval_modes_respect_priv[where gc⇩C'="(cms⇩C'',mem⇩C'')", simplified])
apply(rule meval⇩C)
using "2.prems"(3) gc⇩C_def apply blast
using 2 by simp
from respects'' 2(1)[OF meval_sched⇩C, where gc⇩A7 = gc⇩A''] in_ℛ'' sound_mode_use⇩A''
obtain sched⇩A gc⇩A'
where meval_sched⇩A'': "abs.meval_sched sched⇩A gc⇩A'' gc⇩A'" and
in_ℛ': "(∀i<length cms. ((fst gc⇩A' ! i, snd gc⇩A'), fst gc⇩c' ! i, snd gc⇩c') ∈ ℛ_rel (cms ! i))" and
sound_mode_use⇩A': "abs.sound_mode_use gc⇩A'" by fastforce
define final_sched⇩A where "final_sched⇩A = (replicate m⇩A n) @ sched⇩A"
have meval_final_sched⇩A: "abs.meval_sched final_sched⇩A gc⇩A gc⇩A'"
using meval_sched⇩A'' meval_sched⇩A abs.meval_sched_app final_sched⇩A_def gc⇩A''_def by blast
from meval_final_sched⇩A in_ℛ' sound_mode_use⇩A'
show ?case by blast
qed
qed
end
context sifum_security begin
definition
restrict_modes :: "'Var Mds list ⇒ 'Var set ⇒ 'Var Mds list"
where
"restrict_modes mdss X ≡ map (λmds m. mds m ∩ X) mdss"
lemma restrict_modes_length [simp]:
"length (restrict_modes mdss X) = length mdss"
by(auto simp: restrict_modes_def)
lemma compatible_modes_by_case_distinction:
assumes compat_X: "compatible_modes (restrict_modes mdss X)"
assumes compat_compX: "compatible_modes (restrict_modes mdss (-X ))"
shows "compatible_modes mdss"
unfolding compatible_modes_def
proof(safe)
fix i x j
assume ilen: "i < length mdss"
assume jlen: "j < length mdss"
assume neq: "j ≠ i"
assume asm: "x ∈ (mdss ! i) AsmNoReadOrWrite"
show "x ∈ (mdss ! j) GuarNoReadOrWrite"
proof(cases "x ∈ X")
assume xin: "x ∈ X"
let ?mdss⇩X = "restrict_modes mdss X"
from asm xin have "x ∈ (?mdss⇩X ! i) AsmNoReadOrWrite"
unfolding restrict_modes_def
using ilen by auto
with compat_X jlen ilen neq
have "x ∈ (?mdss⇩X ! j) GuarNoReadOrWrite"
unfolding compatible_modes_def
by auto
with xin jlen show ?thesis
unfolding restrict_modes_def by auto
next
assume xnin: "x ∉ X"
let ?mdss⇩X = "restrict_modes mdss (- X)"
from asm xnin have "x ∈ (?mdss⇩X ! i) AsmNoReadOrWrite"
unfolding restrict_modes_def
using ilen by auto
with compat_compX jlen ilen neq
have "x ∈ (?mdss⇩X ! j) GuarNoReadOrWrite"
unfolding compatible_modes_def
by auto
with xnin jlen show ?thesis
unfolding restrict_modes_def by auto
qed
next
fix i x j
assume ilen: "i < length mdss"
assume jlen: "j < length mdss"
assume neq: "j ≠ i"
assume asm: "x ∈ (mdss ! i) AsmNoWrite"
show "x ∈ (mdss ! j) GuarNoWrite"
proof(cases "x ∈ X")
assume xin: "x ∈ X"
let ?mdss⇩X = "restrict_modes mdss X"
from asm xin have "x ∈ (?mdss⇩X ! i) AsmNoWrite"
unfolding restrict_modes_def
using ilen by auto
with compat_X jlen ilen neq
have "x ∈ (?mdss⇩X ! j) GuarNoWrite"
unfolding compatible_modes_def
by auto
with xin jlen show ?thesis
unfolding restrict_modes_def by auto
next
assume xnin: "x ∉ X"
let ?mdss⇩X = "restrict_modes mdss (- X)"
from asm xnin have "x ∈ (?mdss⇩X ! i) AsmNoWrite"
unfolding restrict_modes_def
using ilen by auto
with compat_compX jlen ilen neq
have "x ∈ (?mdss⇩X ! j) GuarNoWrite"
unfolding compatible_modes_def
by auto
with xnin jlen show ?thesis
unfolding restrict_modes_def by auto
qed
qed
lemma in_restrict_modesD:
"i < length mdss ⟹ x ∈ ((restrict_modes mdss X) ! i) m ⟹ x ∈ X ∧ x ∈ (mdss ! i) m"
by(auto simp: restrict_modes_def)
lemma in_restrict_modesI:
"i < length mdss ⟹ x ∈ X ⟹ x ∈ (mdss ! i) m ⟹ x ∈ ((restrict_modes mdss X) ! i) m "
by(auto simp: restrict_modes_def)
lemma meval_sched_length:
"meval_sched sched gc gc' ⟹ length (fst gc') = length (fst gc)"
apply(induct sched arbitrary: gc gc')
by auto
end
context sifum_refinement_sys begin
lemma compatible_modes_old_vars:
assumes compatible_modes⇩A: "abs.compatible_modes (map snd cms⇩A)"
assumes len⇩A: "length cms⇩A = length cms"
assumes len⇩C: "length cms⇩C = length cms"
assumes in_ℛ: "(∀i<length cms. ((cms⇩A ! i, mem⇩A), cms⇩C ! i, mem⇩C) ∈ ℛ_rel (cms ! i))"
shows "conc.compatible_modes (conc.restrict_modes (map snd cms⇩C) (range var⇩C_of))"
unfolding conc.compatible_modes_def
proof(clarsimp)
fix i x
assume i_len: "i < length cms⇩C"
let ?cms = "cms ! i" and
?c⇩A = "fst (cms⇩A ! i)" and ?mds⇩A = "snd (cms⇩A ! i)" and
?c⇩C = "fst (cms⇩C ! i)" and ?mds⇩C = "snd (cms⇩C ! i)"
from in_ℛ i_len len⇩C
have in_ℛ_i: "((cms⇩A ! i, mem⇩A), cms⇩C ! i, mem⇩C) ∈ ℛ_rel ?cms" by simp
from i_len have "i < length (map snd cms⇩C)" by simp
hence m_x_range: "⋀m. x ∈ (conc.restrict_modes (map snd cms⇩C) (range var⇩C_of) ! i) m ⟹ x ∈ range var⇩C_of ∧ x ∈ (map snd cms⇩C ! i) m"
using conc.in_restrict_modesD i_len by blast+
hence m_x⇩C_i: "⋀m. x ∈ (conc.restrict_modes (map snd cms⇩C) (range var⇩C_of) ! i) m ⟹ x ∈ ?mds⇩C m"
by (simp add: i_len)
from secure_refinements i_len len⇩C
have "secure_refinement (ℛ⇩A_rel ?cms) (ℛ_rel ?cms) (P_rel ?cms)" by simp
hence preserves_modes_mem_ℛ_i: "preserves_modes_mem (ℛ_rel ?cms)"
unfolding secure_refinement_def by simp
from in_ℛ_i have "(⟨?c⇩A, ?mds⇩A, mem⇩A⟩⇩A, ⟨?c⇩C, ?mds⇩C, mem⇩C⟩⇩C) ∈ ℛ_rel ?cms" by clarsimp
with preserves_modes_mem_ℛ_i
have "(∀x⇩A. mem⇩A x⇩A = mem⇩C (var⇩C_of x⇩A)) ∧ (∀m. var⇩C_of ` ?mds⇩A m = range var⇩C_of ∩ ?mds⇩C m)"
unfolding preserves_modes_mem_def by blast
with m_x⇩C_i have m_x⇩A: "⋀m. x ∈ (conc.restrict_modes (map snd cms⇩C) (range var⇩C_of) ! i) m ⟹ var⇩A_of x ∈ ?mds⇩A m"
unfolding var⇩A_of_def using m_x_range inj_image_mem_iff var⇩C_of_inj by fastforce
show "(x ∈ (conc.restrict_modes (map snd cms⇩C) (range var⇩C_of) ! i) AsmNoReadOrWrite ⟶
(∀j<length cms⇩C. j ≠ i ⟶
x ∈ (conc.restrict_modes (map snd cms⇩C) (range var⇩C_of) ! j) GuarNoReadOrWrite)) ∧
(x ∈ (conc.restrict_modes (map snd cms⇩C) (range var⇩C_of) ! i) AsmNoWrite ⟶
(∀j<length cms⇩C. j ≠ i ⟶
x ∈ (conc.restrict_modes (map snd cms⇩C) (range var⇩C_of) ! j) GuarNoWrite))"
proof(safe)
fix j
assume AsmNoRW_x⇩C: "x ∈ (conc.restrict_modes (map snd cms⇩C) (range var⇩C_of) ! i) AsmNoReadOrWrite" and
j_len: "j < length cms⇩C" and
j_not_i: "j ≠ i"
let ?cms' = "cms ! j" and
?c⇩A' = "fst (cms⇩A ! j)" and ?mds⇩A' = "snd (cms⇩A ! j)" and
?c⇩C' = "fst (cms⇩C ! j)" and ?mds⇩C' = "snd (cms⇩C ! j)"
from AsmNoRW_x⇩C m_x_range
have x_range: "x ∈ range var⇩C_of" by simp
from AsmNoRW_x⇩C m_x⇩A
have "var⇩A_of x ∈ ?mds⇩A AsmNoReadOrWrite" by simp
with compatible_modes⇩A
have GuarNoRW_x⇩A: "var⇩A_of x ∈ ?mds⇩A' GuarNoReadOrWrite"
unfolding abs.compatible_modes_def using i_len len⇩A len⇩C j_len j_not_i by clarsimp
from in_ℛ j_len len⇩C
have in_ℛ_j: "((cms⇩A ! j, mem⇩A), cms⇩C ! j, mem⇩C) ∈ ℛ_rel ?cms'" by simp
from j_len have j_len': "j < length (map snd cms⇩C)" by simp
from secure_refinements j_len len⇩C
have "secure_refinement (ℛ⇩A_rel ?cms') (ℛ_rel ?cms') (P_rel ?cms')" by simp
hence preserves_modes_mem_ℛ_j: "preserves_modes_mem (ℛ_rel ?cms')"
unfolding secure_refinement_def by simp
from in_ℛ_j have "(⟨?c⇩A', ?mds⇩A', mem⇩A⟩⇩A, ⟨?c⇩C', ?mds⇩C', mem⇩C⟩⇩C) ∈ ℛ_rel ?cms'" by clarsimp
with preserves_modes_mem_ℛ_j
have "(∀x⇩A. mem⇩A x⇩A = mem⇩C (var⇩C_of x⇩A)) ∧ (∀m. var⇩C_of ` ?mds⇩A' m = range var⇩C_of ∩ ?mds⇩C' m)"
unfolding preserves_modes_mem_def by blast
with GuarNoRW_x⇩A j_len j_len' mds⇩A_of_def x_range conc.in_restrict_modesI var⇩C_of_inj
show "x ∈ (conc.restrict_modes (map snd cms⇩C) (range var⇩C_of) ! j) GuarNoReadOrWrite"
unfolding var⇩A_of_def
by (metis (no_types, lifting) doesnt_have_mode f_inv_into_f image_inv_f_f nth_map)
next
fix j
assume AsmNoWrite_x⇩C: "x ∈ (conc.restrict_modes (map snd cms⇩C) (range var⇩C_of) ! i) AsmNoWrite" and
j_len: "j < length cms⇩C" and
j_not_i: "j ≠ i"
let ?cms' = "cms ! j" and
?c⇩A' = "fst (cms⇩A ! j)" and ?mds⇩A' = "snd (cms⇩A ! j)" and
?c⇩C' = "fst (cms⇩C ! j)" and ?mds⇩C' = "snd (cms⇩C ! j)"
from AsmNoWrite_x⇩C m_x_range
have x_range: "x ∈ range var⇩C_of" by simp
from AsmNoWrite_x⇩C m_x⇩A
have "var⇩A_of x ∈ ?mds⇩A AsmNoWrite" by simp
with compatible_modes⇩A
have GuarNoWrite_x⇩A: "var⇩A_of x ∈ ?mds⇩A' GuarNoWrite"
unfolding abs.compatible_modes_def using i_len len⇩A len⇩C j_len j_not_i by clarsimp
from in_ℛ j_len len⇩C
have in_ℛ_j: "((cms⇩A ! j, mem⇩A), cms⇩C ! j, mem⇩C) ∈ ℛ_rel ?cms'" by simp
from j_len have j_len': "j < length (map snd cms⇩C)" by simp
from secure_refinements j_len len⇩C
have "secure_refinement (ℛ⇩A_rel ?cms') (ℛ_rel ?cms') (P_rel ?cms')" by simp
hence preserves_modes_mem_ℛ_j: "preserves_modes_mem (ℛ_rel ?cms')"
unfolding secure_refinement_def by simp
from in_ℛ_j have "(⟨?c⇩A', ?mds⇩A', mem⇩A⟩⇩A, ⟨?c⇩C', ?mds⇩C', mem⇩C⟩⇩C) ∈ ℛ_rel ?cms'" by clarsimp
with preserves_modes_mem_ℛ_j
have "(∀x⇩A. mem⇩A x⇩A = mem⇩C (var⇩C_of x⇩A)) ∧ (∀m. var⇩C_of ` ?mds⇩A' m = range var⇩C_of ∩ ?mds⇩C' m)"
unfolding preserves_modes_mem_def by blast
with GuarNoWrite_x⇩A j_len j_len' mds⇩A_of_def x_range conc.in_restrict_modesI var⇩C_of_inj
show "x ∈ (conc.restrict_modes (map snd cms⇩C) (range var⇩C_of) ! j) GuarNoWrite"
unfolding var⇩A_of_def
by (metis (no_types, lifting) doesnt_have_mode f_inv_into_f image_inv_f_f nth_map)
qed
qed
lemma compatible_modes_new_vars:
"length mdss = length cms ⟹ modes_respect_priv mdss ⟹ conc.compatible_modes (conc.restrict_modes mdss (- range var⇩C_of))"
unfolding conc.compatible_modes_def
proof(safe)
let ?X = "- range var⇩C_of"
let ?mdss⇩X = "conc.restrict_modes mdss ?X"
assume respect: "modes_respect_priv mdss"
assume len_eq: "length mdss = length cms"
fix i x⇩C j
assume ilen: "i < length ?mdss⇩X"
assume jlen: "j < length ?mdss⇩X"
assume neq: "j ≠ i"
assume asm⇩X: "x⇩C ∈ (?mdss⇩X ! i) AsmNoWrite"
from conc.in_restrict_modesD ilen asm⇩X conc.restrict_modes_length have
xin: "x⇩C ∈ ?X" and
asm: "x⇩C ∈ (mdss ! i) AsmNoWrite" by metis+
from asm have "False"
using respect xin ilen conc.restrict_modes_length len_eq
unfolding modes_respect_priv_def new_asms_NoReadOrWrite_only_def
by force
thus "x⇩C ∈ (?mdss⇩X ! j) GuarNoWrite" by blast
next
let ?X = "- range var⇩C_of"
let ?mdss⇩X = "conc.restrict_modes mdss ?X"
assume respect: "modes_respect_priv mdss"
assume len_eq: "length mdss = length cms"
fix i x⇩C j
assume ilen: "i < length ?mdss⇩X"
assume jlen: "j < length ?mdss⇩X"
assume neq: "j ≠ i"
assume asm⇩X: "x⇩C ∈ (?mdss⇩X ! i) AsmNoReadOrWrite"
from conc.in_restrict_modesD ilen asm⇩X conc.restrict_modes_length have
xin: "x⇩C ∈ ?X" and
asm: "x⇩C ∈ (mdss ! i) AsmNoReadOrWrite" by metis+
from respect asm xin ilen conc.restrict_modes_length len_eq have
"x⇩C ∈ priv_mem⇩C ! i"
unfolding modes_respect_priv_def new_asms_only_for_priv_def
by force
with respect ilen jlen neq conc.restrict_modes_length len_eq have
"x⇩C ∈ (mdss ! j) GuarNoReadOrWrite"
unfolding modes_respect_priv_def priv_is_guar_priv_def
by force
with jlen xin conc.in_restrict_modesI show
"x⇩C ∈ (?mdss⇩X ! j) GuarNoReadOrWrite" by force
qed
lemma sound_mode_use_preservation:
"⋀gc⇩C gc⇩A.
length (fst gc⇩A) = length cms ⟹ length (fst gc⇩C) = length cms ⟹
(⋀i. i < length cms ⟹ ((fst gc⇩A ! i, snd gc⇩A), (fst gc⇩C ! i, snd gc⇩C)) ∈ ℛ_rel (cms ! i)) ⟹
abs.sound_mode_use gc⇩A ⟹ modes_respect_priv (map snd (fst gc⇩C)) ⟹
conc.sound_mode_use gc⇩C"
proof -
fix gc⇩C gc⇩A
assume len_eq [simp]: "length (fst gc⇩A) = length cms"
and len_eq'[simp]: "length (fst gc⇩C) = length cms"
and in_ℛ: "(⋀i. i < length cms ⟹ ((fst gc⇩A ! i, snd gc⇩A), (fst gc⇩C ! i, snd gc⇩C)) ∈ ℛ_rel (cms ! i))"
and sound_mode_use⇩A: "abs.sound_mode_use gc⇩A"
and modes_respect_priv: "modes_respect_priv (map snd (fst gc⇩C))"
have "conc.globally_sound_mode_use gc⇩C"
unfolding conc.globally_sound_mode_use_def
proof(clarsimp)
fix mdss⇩C'
assume in_reachable_modes: "mdss⇩C' ∈ conc.reachable_mode_states gc⇩C"
from this obtain cms⇩C' mem⇩C' sched⇩C where
meval_sched⇩C: "conc.meval_sched sched⇩C gc⇩C (cms⇩C', mem⇩C')" and
mdss⇩C'_def: "mdss⇩C' = map snd cms⇩C'"
unfolding conc.reachable_mode_states_def by blast
from traces_refinement[OF meval_sched⇩C, OF len_eq len_eq' in_ℛ sound_mode_use⇩A modes_respect_priv]
obtain sched⇩A gc⇩A' cms⇩A' mem⇩A' where gc⇩A'_def [simp]: "gc⇩A' = (cms⇩A', mem⇩A')" and
meval_sched⇩A: "abs.meval_sched sched⇩A gc⇩A gc⇩A'" and
in_ℛ: "(∀i<length cms.
((cms⇩A' ! i, mem⇩A'), cms⇩C' ! i, mem⇩C') ∈ ℛ_rel (cms ! i))"
and sound_mode_use⇩A': "abs.sound_mode_use gc⇩A'"
by fastforce
let ?mdss⇩A' = "map snd cms⇩A'"
have "?mdss⇩A' ∈ abs.reachable_mode_states gc⇩A"
unfolding abs.reachable_mode_states_def
using meval_sched⇩A by fastforce
hence compatible_modes⇩A': "abs.compatible_modes ?mdss⇩A'"
using sound_mode_use⇩A unfolding abs.sound_mode_use_def abs.globally_sound_mode_use_def
by fastforce
let ?X = "range var⇩C_of"
show "conc.compatible_modes mdss⇩C'"
proof(rule conc.compatible_modes_by_case_distinction[where X="?X"])
show "conc.compatible_modes (conc.restrict_modes mdss⇩C' ?X)"
apply(simp add: mdss⇩C'_def)
apply(rule compatible_modes_old_vars[OF _ _ _ in_ℛ])
apply(rule compatible_modes⇩A')
using len_eq abs.meval_sched_length[OF meval_sched⇩A] gc⇩A'_def apply simp
using len_eq' conc.meval_sched_length[OF meval_sched⇩C] by simp
next
show "conc.compatible_modes (conc.restrict_modes mdss⇩C' (- ?X))"
apply(rule compatible_modes_new_vars)
using len_eq' conc.meval_sched_length[OF meval_sched⇩C] mdss⇩C'_def apply simp
apply(simp add: mdss⇩C'_def)
apply(rule meval_sched_modes_respect_priv[OF meval_sched⇩C, simplified])
using modes_respect_priv by simp
qed
qed
moreover have "list_all (λ cm. conc.locally_sound_mode_use (cm, (snd gc⇩C))) (fst gc⇩C)"
unfolding list_all_length
proof(clarify)
fix i
assume "i < length (fst gc⇩C)"
hence len: "i < length cms" by simp
have preserves: "preserves_locally_sound_mode_use (ℛ_rel (cms ! i))"
apply(rule locally_sound_mode_use_preservation)
using secure_refinements len apply blast
using local_guarantee_preservation len by blast
have "abs.locally_sound_mode_use (fst gc⇩A ! i, snd gc⇩A)"
using sound_mode_use⇩A ‹i < length cms› len_eq
unfolding abs.sound_mode_use_def list_all_length
by (simp add: case_prod_unfold)
from this in_ℛ[OF len] preserves[unfolded preserves_locally_sound_mode_use_def]
show "conc.locally_sound_mode_use (fst gc⇩C ! i, snd gc⇩C)"
by blast
qed
ultimately show "?thesis gc⇩C gc⇩A" unfolding conc.sound_mode_use_def
by (simp add: case_prod_unfold)
qed
lemma refined_prog_secure:
assumes len⇩A [simp]: "length cms⇩C = length cms"
assumes len⇩C [simp]: "length cms⇩A = length cms"
assumes in_ℛ: "(⋀i mem⇩C. i < length cms ⟹ ((cms⇩A ! i,mem⇩A_of mem⇩C),(cms⇩C ! i, mem⇩C)) ∈ ℛ_rel (cms ! i))"
assumes in_ℛ⇩A: "(⋀i mem⇩C mem⇩C'. ⟦i < length cms; conc.low_mds_eq (snd (cms⇩C ! i)) mem⇩C mem⇩C'⟧
⟹ ((cms⇩A ! i, mem⇩A_of mem⇩C), (cms⇩A ! i, mem⇩A_of mem⇩C')) ∈ ℛ⇩A_rel (cms ! i))"
assumes sound_mode_use⇩A: "(⋀ mem⇩A. abs.sound_mode_use (cms⇩A, mem⇩A))"
assumes modes_respect_priv: "modes_respect_priv (map snd cms⇩C)"
shows "conc.prog_sifum_secure_cont cms⇩C"
apply(rule conc.sifum_compositionality_cont)
apply(clarsimp simp: list_all_length)
apply(clarsimp simp: conc.com_sifum_secure_def conc.low_indistinguishable_def)
apply(rule conc.mm_equiv.intros)
apply(rule R⇩C_of_strong_low_bisim_mm)
apply(fastforce intro: bisims)
apply(fastforce intro: secure_refinements)
apply(fastforce simp: Ps_sym)
apply(clarsimp simp: R⇩C_of_def)
apply(rename_tac i c⇩C mds⇩C mem⇩C mem⇩C')
apply(rule_tac x="fst (cms⇩A ! i)" in exI)
apply(rule_tac x="snd (cms⇩A ! i)" in exI)
apply(rule_tac x="mem⇩A_of mem⇩C" in exI)
apply(rule conjI)
using in_ℛ apply fastforce
apply(rule_tac x="fst (cms⇩A ! i)" in exI)
apply(rule_tac x="snd (cms⇩A ! i)" in exI)
apply(rule_tac x="mem⇩A_of mem⇩C'" in exI)
apply(rule conjI)
using in_ℛ apply fastforce
apply(fastforce simp: in_ℛ⇩A Ps_refl_on_low_mds_eq)
apply(clarify)
apply(rename_tac mem⇩C)
apply(rule_tac gc⇩A="(cms⇩A,mem⇩A_of mem⇩C)" in sound_mode_use_preservation)
apply simp
apply simp
using in_ℛ apply fastforce
apply(rule sound_mode_use⇩A)
apply clarsimp
by(rule modes_respect_priv)
lemma refined_prog_secure':
assumes len⇩A [simp]: "length cms⇩C = length cms"
assumes len⇩C [simp]: "length cms⇩A = length cms"
assumes in_ℛ: "(⋀i mem⇩C. i < length cms ⟹ ((cms⇩A ! i,mem⇩A_of mem⇩C),(cms⇩C ! i, mem⇩C)) ∈ ℛ_rel (cms ! i))"
assumes in_ℛ⇩A: "(⋀i mem⇩A mem⇩A'. ⟦i < length cms; abs.low_mds_eq (snd (cms⇩A ! i)) mem⇩A mem⇩A'⟧
⟹ ((cms⇩A ! i, mem⇩A), (cms⇩A ! i, mem⇩A')) ∈ ℛ⇩A_rel (cms ! i))"
assumes sound_mode_use⇩A: "(⋀ mem⇩A. abs.sound_mode_use (cms⇩A, mem⇩A))"
assumes modes_respect_priv: "modes_respect_priv (map snd cms⇩C)"
shows "conc.prog_sifum_secure_cont cms⇩C"
apply(rule refined_prog_secure)
apply(rule len⇩A)
apply(rule len⇩C)
apply(blast intro: in_ℛ)
apply(rule in_ℛ⇩A)
apply assumption
apply(subgoal_tac "snd (cms⇩A ! i) = mds⇩A_of (snd (cms⇩C ! i))")
using low_mds_eq_from_conc_to_abs apply fastforce
apply(rule_tac ℛ1="ℛ_rel (cms ! i)" and c⇩A1="fst (cms⇩A ! i)" and c⇩C1="fst (cms⇩C ! i)" in preserves_modes_memD[THEN conjunct2])
using secure_refinements unfolding secure_refinement_def apply fast
apply clarsimp
using in_ℛ apply fastforce
apply(blast intro: sound_mode_use⇩A)
by(rule modes_respect_priv)
end
context sifum_security begin
definition
reachable_mems :: "('Com × (Mode ⇒ 'Var set)) list ⇒ ('Var,'Val) Mem ⇒ ('Var,'Val) Mem set"
where
"reachable_mems cms mem ≡ {mem'. ∃sched cms'. meval_sched sched (cms,mem) (cms',mem')}"
lemma reachable_mems_refl:
"mem ∈ reachable_mems cms mem"
apply(clarsimp simp: reachable_mems_def)
apply(rule_tac x="[]" in exI)
apply fastforce
done
end
context sifum_refinement_sys begin
lemma reachable_mems_refinement:
assumes sys_nonempty: "length cms > 0"
assumes len⇩A [simp]: "length cms⇩C = length cms"
assumes len⇩C [simp]: "length cms⇩A = length cms"
assumes in_ℛ: "(⋀i mem⇩C. i < length cms ⟹ ((cms⇩A ! i,mem⇩A_of mem⇩C),(cms⇩C ! i, mem⇩C)) ∈ ℛ_rel (cms ! i))"
assumes sound_mode_use⇩A: "(⋀ mem⇩A. abs.sound_mode_use (cms⇩A, mem⇩A))"
assumes modes_respect_priv: "modes_respect_priv (map snd cms⇩C)"
assumes reachable⇩C: "mem⇩C' ∈ conc.reachable_mems cms⇩C mem⇩C"
shows "mem⇩A_of mem⇩C' ∈ abs.reachable_mems cms⇩A (mem⇩A_of mem⇩C)"
proof -
from reachable⇩C obtain sched⇩C cms⇩C' where
meval_sched⇩C: "conc.meval_sched sched⇩C (cms⇩C, mem⇩C) (cms⇩C', mem⇩C')"
by (fastforce simp: conc.reachable_mems_def)
let ?mem⇩A = "mem⇩A_of mem⇩C"
have sound_mode_use⇩A: "abs.sound_mode_use (cms⇩A, ?mem⇩A)"
by(rule sound_mode_use⇩A)
from traces_refinement[where gc⇩A="(cms⇩A,?mem⇩A)", OF meval_sched⇩C, OF _ _ _ sound_mode_use⇩A]
in_ℛ[of _ mem⇩C]
modes_respect_priv
obtain sched⇩A cms⇩A' mem⇩A' where
meval_sched⇩A: "abs.meval_sched sched⇩A (cms⇩A, ?mem⇩A) (cms⇩A', mem⇩A')" and
in_ℛ': "(∀i<length cms.
((cms⇩A' ! i, mem⇩A'), cms⇩C' ! i, mem⇩C') ∈ ℛ_rel (cms ! i))"
by fastforce
hence reachable⇩A: "mem⇩A' ∈ abs.reachable_mems cms⇩A ?mem⇩A"
by(fastforce simp: abs.reachable_mems_def)
from sys_nonempty obtain i where ilen: "i < length cms" by blast
let ?ℛi = "ℛ_rel (cms ! i)"
from ilen secure_refinements have "preserves_modes_mem ?ℛi"
unfolding secure_refinement_def by blast
from ilen in_ℛ' preserves_modes_memD[OF this] have
mem⇩A'_def: "mem⇩A' = mem⇩A_of mem⇩C'"
by(metis surjective_pairing)
with reachable⇩A show ?thesis by simp
qed
end
end