Theory Friend_Openness
theory Friend_Openness
imports "Friend_State_Indistinguishability"
begin
subsection ‹Dynamic declassification trigger›
context Friend
begin
text ‹The dynamic declassification trigger condition holds, i.e.~the access window to the
confidential information is open, as long as the two users have not been created yet (so there cannot
be friendship between them) or while one of them is a local friend of an observer.›
definition openByA :: "state ⇒ bool"
where "openByA s ≡ ¬ UID1 ∈∈ userIDs s ∨ ¬ UID2 ∈∈ userIDs s"
definition openByF :: "state ⇒ bool"
where "openByF s ≡ ∃uid ∈ UIDs. uid ∈∈ friendIDs s UID1 ∨ uid ∈∈ friendIDs s UID2"
definition "open" :: "state ⇒ bool"
where "open s ≡ openByA s ∨ openByF s"
lemmas open_defs = open_def openByA_def openByF_def
lemma step_openByA_cases:
assumes "step s a = (ou, s')"
and "openByA s ≠ openByA s'"
obtains (CloseA) uid p uid' p' where "a = Cact (cUser uid p uid' p')"
"uid' = UID1 ∨ uid' = UID2" "ou = outOK" "p = pass s uid"
"openByA s" "¬openByA s'"
using assms proof (cases a)
case (Dact da) then show ?thesis using assms by (cases da) (auto simp: d_defs openByA_def) next
case (Uact ua) then show ?thesis using assms by (cases ua) (auto simp: u_defs openByA_def) next
case (COMact ca) then show ?thesis using assms by (cases ca) (auto simp: com_defs openByA_def) next
case (Sact sa)
then show ?thesis using assms UID1_UID2 by (cases sa) (auto simp: s_defs openByA_def) next
case (Cact ca)
then show ?thesis using assms UID1_UID2 proof (cases ca)
case (cUser uid p uid' p')
then show ?thesis using Cact assms by (intro that) (auto simp: c_defs openByA_def)
qed (auto simp: c_defs openByA_def)
qed auto
lemma step_openByF_cases:
assumes "step s a = (ou, s')"
and "openByF s ≠ openByF s'"
obtains
(OpenF) uid p uid' where "a = Cact (cFriend uid p uid')" "ou = outOK" "p = pass s uid"
"uid ∈ UIDs ∧ uid' ∈ {UID1,UID2} ∨ uid ∈ {UID1,UID2} ∧ uid' ∈ UIDs"
"openByF s'" "¬openByF s"
| (CloseF) uid p uid' where "a = Dact (dFriend uid p uid')" "ou = outOK" "p = pass s uid"
"uid ∈ UIDs ∧ uid' ∈ {UID1,UID2} ∨ uid ∈ {UID1,UID2} ∧ uid' ∈ UIDs"
"openByF s" "¬openByF s'"
using assms proof (cases a)
case (Uact ua) then show ?thesis using assms by (cases ua) (auto simp: u_defs openByF_def) next
case (COMact ca) then show ?thesis using assms by (cases ca) (auto simp: com_defs openByF_def) next
case (Sact sa)
then show ?thesis using assms UID1_UID2 by (cases sa) (auto simp: s_defs openByF_def)
next
case (Cact ca)
then show ?thesis using assms UID1_UID2 proof (cases ca)
case (cFriend uid p uid')
then show ?thesis using Cact assms by (intro OpenF) (auto simp: c_defs openByF_def)
qed (auto simp: c_defs openByF_def)
next
case (Dact da)
then show ?thesis using assms proof (cases da)
case (dFriend uid p uid')
then show ?thesis using Dact assms by (intro CloseF) (auto simp: d_defs openByF_def)
qed
qed auto
lemma step_open_cases:
assumes step: "step s a = (ou, s')"
and op: "open s ≠ open s'"
obtains
(CloseA) uid p uid' p' where "a = Cact (cUser uid p uid' p')"
"uid' = UID1 ∨ uid' = UID2" "ou = outOK" "p = pass s uid"
"openByA s" "¬openByA s'" "¬openByF s" "¬openByF s'"
| (OpenF) uid p uid' where "a = Cact (cFriend uid p uid')" "ou = outOK" "p = pass s uid"
"uid ∈ UIDs ∧ uid' ∈ {UID1,UID2} ∨ uid ∈ {UID1,UID2} ∧ uid' ∈ UIDs"
"openByF s'" "¬openByF s" "¬openByA s" "¬openByA s'"
| (CloseF) uid p uid' where "a = Dact (dFriend uid p uid')" "ou = outOK" "p = pass s uid"
"uid ∈ UIDs ∧ uid' ∈ {UID1,UID2} ∨ uid ∈ {UID1,UID2} ∧ uid' ∈ UIDs"
"openByF s" "¬openByF s'" "¬openByA s" "¬openByA s'"
proof -
from op have "openByF s ≠ openByF s' ∨ openByA s ≠ openByA s'"
unfolding open_def by auto
then show thesis proof
assume "openByF s ≠ openByF s'"
with step show thesis proof (cases rule: step_openByF_cases)
case (OpenF uid p uid')
then have "openByA s = openByA s'" using step
by (cases "openByA s ≠ openByA s'", elim step_openByA_cases) auto
then have "¬openByA s ∧ ¬openByA s'" using op unfolding open_def by auto
with OpenF show thesis by (intro that(2)) auto
next
case (CloseF uid p uid')
then have "openByA s = openByA s'" using step
by (cases "openByA s ≠ openByA s'", elim step_openByA_cases) auto
then have "¬openByA s ∧ ¬openByA s'" using op unfolding open_def by auto
with CloseF show thesis by (intro that(3)) auto
qed
next
assume "openByA s ≠ openByA s'"
with step show thesis proof (cases rule: step_openByA_cases)
case (CloseA uid p uid' p')
then have "openByF s = openByF s'" using step
by (cases "openByF s ≠ openByF s'", elim step_openByF_cases) auto
then have "¬openByF s ∧ ¬openByF s'" using op unfolding open_def by auto
with CloseA show thesis by (intro that(1)) auto
qed
qed
qed
lemma eqButUID_openByA_eq:
assumes "eqButUID s s1"
shows "openByA s = openByA s1"
using assms unfolding openByA_def eqButUID_def by auto
lemma eqButUID_openByF_eq:
assumes ss1: "eqButUID s s1"
shows "openByF s = openByF s1"
proof -
from ss1 have fIDs: "eqButUIDf (friendIDs s) (friendIDs s1)" unfolding eqButUID_def by auto
have "∀uid ∈ UIDs. uid ∈∈ friendIDs s UID1 ⟷ uid ∈∈ friendIDs s1 UID1"
using UID1_UID2_UIDs UID1_UID2 by (intro ballI eqButUIDf_not_UID'[OF fIDs]; auto)
moreover have "∀uid ∈ UIDs. uid ∈∈ friendIDs s UID2 ⟷ uid ∈∈ friendIDs s1 UID2"
using UID1_UID2_UIDs UID1_UID2 by (intro ballI eqButUIDf_not_UID'[OF fIDs]; auto)
ultimately show "openByF s = openByF s1" unfolding openByF_def by auto
qed
lemma eqButUID_open_eq: "eqButUID s s1 ⟹ open s = open s1"
using eqButUID_openByA_eq eqButUID_openByF_eq unfolding open_def by blast
lemma eqButUID_step_γ_out:
assumes ss1: "eqButUID s s1"
and step: "step s a = (ou,s')" and step1: "step s1 a = (ou1,s1')"
and γ: "γ (Trans s a ou s')"
and os: "open s ⟶ friendIDs s = friendIDs s1"
shows "ou = ou1"
proof -
obtain uid sa com_act where uid_a: "(userOfA a = Some uid ∧ uid ∈ UIDs ∧ uid ≠ UID1 ∧ uid ≠ UID2)
∨ a = COMact com_act ∨ a = Sact sa"
using γ UID1_UID2_UIDs by fastforce
{ fix uid
assume "uid ∈∈ friendIDs s UID1 ∨ uid ∈∈ friendIDs s UID2" and "uid ∈ UIDs"
with os have "friendIDs s = friendIDs s1" unfolding open_def openByF_def by auto
} note fIDs = this
{ fix uid uid'
assume uid: "uid ≠ UID1" "uid ≠ UID2"
have "friendIDs s uid = friendIDs s1 uid" (is ?f_eq)
and "pendingFReqs s uid = pendingFReqs s1 uid" (is ?pFR_eq)
and "uid ∈∈ friendIDs s uid' ⟷ uid ∈∈ friendIDs s1 uid'" (is ?f_iff)
and "uid ∈∈ pendingFReqs s uid' ⟷ uid ∈∈ pendingFReqs s1 uid'" (is ?pFR_iff)
and "friendReq s uid uid' = friendReq s1 uid uid'" (is ?FR_eq)
and "friendReq s uid' uid = friendReq s1 uid' uid" (is ?FR_eq')
proof -
show ?f_eq ?pFR_eq using uid ss1 UID1_UID2_UIDs unfolding eqButUID_def
by (auto intro!: eqButUIDf_not_UID)
show ?f_iff ?pFR_iff using uid ss1 UID1_UID2_UIDs unfolding eqButUID_def
by (auto intro!: eqButUIDf_not_UID')
from uid have "¬ (uid,uid') ∈ {(UID1,UID2), (UID2,UID1)}" by auto
then show ?FR_eq ?FR_eq' using ss1 UID1_UID2_UIDs unfolding eqButUID_def
by (auto intro!: eqButUID12_not_UID)
qed
} note simps = this eqButUID_stateSelectors r_defs s_defs c_defs com_defs l_defs u_defs d_defs
note facts = ss1 step step1 uid_a
show ?thesis
proof (cases a)
case (Ract ra) then show ?thesis using facts by (cases ra) (auto simp add: simps)
next
case (Sact sa) then show ?thesis using facts by (cases sa) (auto simp add: simps)
next
case (Cact ca) then show ?thesis using facts by (cases ca) (auto simp add: simps)
next
case (COMact ca) then show ?thesis using facts by (cases ca) (auto simp add: simps)
next
case (Lact la)
then show ?thesis using facts proof (cases la)
case (lFriends uid p uid')
with γ have uid: "uid ∈ UIDs" using Lact by auto
then have uid_uid': "uid ∈∈ friendIDs s uid' ⟷ uid ∈∈ friendIDs s1 uid'"
using ss1 UID1_UID2_UIDs unfolding eqButUID_def by (intro eqButUIDf_not_UID') auto
show ?thesis
proof (cases "(uid' = UID1 ∨ uid' = UID2) ∧ uid ∈∈ friendIDs s uid'")
case True
with uid have "friendIDs s = friendIDs s1" by (intro fIDs) auto
then show ?thesis using lFriends facts Lact by (auto simp: simps)
next
case False
then show ?thesis using lFriends facts Lact simps(1) uid_uid' by (auto simp: simps)
qed
next
case (lInnerPosts uid p)
then have o: "⋀nid. owner s nid = owner s1 nid"
and n: "⋀nid. post s nid = post s1 nid"
and nids: "postIDs s = postIDs s1"
and vis: "vis s = vis s1"
and fu: "⋀uid'. uid ∈∈ friendIDs s uid' ⟷ uid ∈∈ friendIDs s1 uid'"
and e: "e_listInnerPosts s uid p ⟷ e_listInnerPosts s1 uid p"
using ss1 uid_a Lact unfolding eqButUID_def l_defs by (auto simp add: simps(3))
have "listInnerPosts s uid p = listInnerPosts s1 uid p"
unfolding listInnerPosts_def o n nids vis fu ..
with e show ?thesis using Lact lInnerPosts step step1 by auto
qed (auto simp add: simps)
next
case (Uact ua) then show ?thesis using facts by (cases ua) (auto simp add: simps)
next
case (Dact da) then show ?thesis using facts by (cases da) (auto simp add: simps)
qed
qed
end
end