(* Author: Matthias Brun, ETH Zürich, 2019 *) (* Author: Dmitriy Traytel, ETH Zürich, 2019 *)
section‹Formalization of Miller et al.'s~cite‹"adsg"› Main Results›
(*<*) theory Results imports Agreement begin (*>*)
lemma judge_imp_agree: assumes"Γ ⊨ e : τ" shows"Γ ⊨ e, e, e : τ" using assms by (induct Γ e τ) (auto simp: fresh_Pair)
subsection‹Lemma 2.1›
lemma lemma2_1: assumes"Γ ⊨ e, eP, eV : τ" shows"(eP) = eV" using assms by (induct Γ e eP eV τ) (simp_all add: Abs1_eq)
subsection‹Counterexample to Lemma 2.2›
lemma lemma2_2_false: fixes x :: var assumes"∧Γ e eP eV τ eP' eV'. [ Γ ⊨ e, eP, eV : τ; Γ ⊨ e, eP', eV' : τ ]==> eP = eP' ∧ eV = eV'" shows False proof - have a1: "{$$} ⊨ Prj1 (Pair Unit Unit), Prj1 (Pair Unit Unit), Prj1 (Pair Unit Unit) : One" by fastforce alsohave a2: "{$$} ⊨ Prj1 (Pair Unit Unit), Prj1 (Pair Unit (Hashed (hash Unit) Unit)), Prj1 (Pair Unit (Hash (hash Unit))) : One" by fastforce from a1 a2 have"Prj1 (Pair Unit Unit) = Prj1 (Pair Unit (Hash (hash Unit)))" by (auto dest: assms) thenshow False by simp qed
lemma smallstep_ideal_deterministic: "≪[], t≫ I→≪[], u≫==>≪[], t≫ I→≪[], u'≫==> u = u'" proof (nominal_induct "[]::proofstream" t I "[]::proofstream" u avoiding: u' rule: smallstep.strong_induct) case (s_App1 e1 e1' e2) from s_App1(3) value_no_step[OF s_App1(1)] show ?case by (auto dest!: s_App1(2)) next case (s_App2 v1 e2 e2') from s_App2(4) value_no_step[OF s_App2(2)] value_no_step[OF _ s_App2(1)] show ?case by (force dest!: s_App2(3)) next case (s_AppLam v x e) from s_AppLam(5,1,3) value_no_step[OF _ s_AppLam(2)] show ?case proof (cases rule: s_App_inv) case (AppLam y e') obtain z :: var where"atom z ♯ (x, e, y, e')" by (metis obtain_fresh) with AppLam s_AppLam(1,3) show ?thesis by (auto simp: fresh_Pair intro: box_equals[OF _ subst_term_perm[symmetric, of z] subst_term_perm[symmetric, of z]]) qed (auto dest: value_no_step) next case (s_AppRec v x e) from s_AppRec(5,1,3) value_no_step[OF _ s_AppRec(2)] show ?case proof (cases rule: s_App_inv) case (AppRec y e') obtain z :: var where"atom z ♯ (x, e, y, e')" by (metis obtain_fresh) with AppRec(1-4) AppRec(5)[simplified] s_AppRec(1,3) show ?thesis apply (auto simp: fresh_Pair AppRec(1)) apply (rule box_equals[OF _ subst_term_perm[symmetric, of z] subst_term_perm[symmetric, of z]]) using AppRec(1) apply auto done qed (auto dest: value_no_step) next case (s_Let1 x e1 e1' e2) from s_Let1(1,2,3,8) value_no_step[OF s_Let1(6)] show ?case by (auto dest: s_Let1(7)) next case (s_Let2 v x e) from s_Let2(1,3,5) value_no_step[OF _ s_Let2(2)] show ?case by force next case (s_Inj1 e e') from s_Inj1(2,3) show ?case by auto next case (s_Inj2 e e') from s_Inj2(2,3) show ?case by auto next case (s_Case e e' e1 e2) from s_Case(2,3) value_no_step[OF s_Case(1)] show ?case by auto next case (s_Pair1 e1 e1' e2) from s_Pair1(2,3) value_no_step[OF s_Pair1(1)] show ?case by auto next case (s_Pair2 v1 e2 e2') from s_Pair2(3,4) value_no_step[OF _ s_Pair2(1)] value_no_step[OF s_Pair2(2)] show ?case by force next case (s_Prj1 e e') from s_Prj1(2,3) value_no_step[OF s_Prj1(1)] show ?case by auto next case (s_Prj2 e e') from s_Prj2(2,3) value_no_step[OF s_Prj2(1)] show ?case by auto next case (s_Unroll e e') from s_Unroll(2,3) value_no_step[OF s_Unroll(1)] show ?case by auto next case (s_Roll e e') from s_Roll(2,3) show ?case by auto next case (s_Auth e e') from s_Auth(2,3) value_no_step[OF s_Auth(1)] show ?case by auto next case (s_Unauth e e') from s_Unauth(2,3) value_no_step[OF s_Unauth(1)] show ?case by auto qed (auto 03 dest: value_no_step)
lemma smallsteps_ideal_deterministic: "≪[], t≫ I→i ≪[], u≫==>≪[], t≫ I→i ≪[], u'≫==> u = u'" proof (induct "[]::proofstream" t I i "[]::proofstream" u arbitrary: u' rule: smallsteps.induct) case (s_Tr e1 i π2 e2 e3) from s_Tr(4) show ?case proof (cases rule: smallsteps.cases) case _: (s_Tr i π4 e4) with s_Tr(1,3) s_Tr(2)[of e4] show ?thesis using smallstepsI_ps_emptyD(2)[of e1 i π4 e4] smallstepI_ps_eq[of π2 e2"[]" e3] by (auto intro!: smallstep_ideal_deterministic elim!: smallstepI_ps_emptyD) qed simp qed auto
subsection‹Lemma 2.3›
lemma lemma2_3: assumes"Γ ⊨ e, eP, eV : τ" shows"erase_env Γ ⊨W e : erase τ" using assms unfolding erase_env_def proof (nominal_induct Γ e eP eV τ rule: agree.strong_induct) case (a_HashI v vP τ h Γ) thenshow ?case by (induct Γ) (auto simp: judge_weak_weakening_2 fmmap_fmupd judge_weak_fresh_env_fresh_term fresh_tyenv_None) qed (simp_all add: fresh_fmmap_erase_fresh fmmap_fmupd judge_weak_fresh_env_fresh_term)
subsection‹Lemma 2.4›
lemma lemma2_4[dest]: assumes"Γ ⊨ e, eP, eV : τ" shows"value e ∧ value eP ∧ value eV ∨¬ value e ∧¬ value eP ∧¬ value eV" using assms by (nominal_induct Γ e eP eV τ rule: agree.strong_induct) auto
subsection‹Lemma 3›
lemma lemma3_general: fixes Γ :: tyenv and vs vPs vVs :: tenv assumes"Γ ⊨ e : τ""A |⊆| fmdom Γ" and"fmdom vs = A""fmdom vPs = A""fmdom vVs = A" and"∀x. x |∈| A ⟶ (∃τ' v vP h. Γ $$ x = Some (AuthT τ') ∧ vs $$ x = Some v ∧ vPs $$ x = Some (Hashed h vP) ∧ vVs $$ x = Some (Hash h) ∧ {$$} ⊨ v, Hashed h vP, Hash h : (AuthT τ'))" shows"fmdrop_fset A Γ ⊨ psubst_term e vs, psubst_term e vPs, psubst_term e vVs : τ" using assms proof (nominal_induct Γ e τ avoiding: vs vPs vVs A rule: judge.strong_induct) case (j_Unit Γ) thenshow ?case by auto next case (j_Var Γ x τ) with j_Var show ?case proof (cases "x |∈| A") case True with j_Var show ?thesis by (fastforce dest!: spec[of _ x] intro: agree_weakening_env) next case False with j_Var show ?thesis by (auto simp add: a_Var dest!: fmdomI split: option.splits) qed next case (j_Lam x Γ τ1 e τ2) from j_Lam(4) have [simp]: "A |-| {|x|} = A" by (simp add: fresh_fset_fminus) from j_Lam(5,8-) have"fmdrop_fset A Γ(x $$:= τ1) ⊨ psubst_term e vs, psubst_term e vPs, psubst_term e vVs : τ2" by (intro j_Lam(7)[of A vs vPs vVs]) (auto simp: fresh_tyenv_None) with j_Lam(1-5) show ?case by (auto simp: fresh_fmdrop_fset) next case (j_App Γ e τ1 τ2 e') thenhave"fmdrop_fset A Γ ⊨ psubst_term e vs, psubst_term e vPs, psubst_term e vVs : Fun τ1 τ2" and"fmdrop_fset A Γ ⊨ psubst_term e' vs, psubst_term e' vPs, psubst_term e' vVs : τ1" by simp_all thenshow ?case by auto next case (j_Let x Γ e1 τ1 e2 τ2) from j_Let(4) have [simp]: "A |-| {|x|} = A" by (simp add: fresh_fset_fminus) from j_Let(8,11-) have"fmdrop_fset A Γ ⊨ psubst_term e1 vs, psubst_term e1 vPs, psubst_term e1 vVs : τ1" by simp moreoverfrom j_Let(4,5,11-) have"fmdrop_fset A Γ(x $$:= τ1) ⊨ psubst_term e2 vs, psubst_term e2 vPs, psubst_term e2 vVs : τ2" by (intro j_Let(10)) (auto simp: fresh_tyenv_None) ultimatelyshow ?caseusing j_Let(1-6) by (auto simp: fresh_fmdrop_fset fresh_Pair fresh_psubst) next case (j_Rec x Γ y τ1 τ2 e') from j_Rec(4) have [simp]: "A |-| {|x|} = A" by (simp add: fresh_fset_fminus) from j_Rec(9,14-) have"fmdrop_fset A Γ(x $$:= Fun τ1 τ2) ⊨ psubst_term (Lam y e') vs, psubst_term (Lam y e') vPs, psubst_term (Lam y e') vVs : Fun τ1 τ2" by (intro j_Rec(13)) (auto simp: fresh_tyenv_None) with j_Rec(1-11) show ?case by (auto simp: fresh_fmdrop_fset) next case (j_Case Γ e τ1 τ2 e1 τ e2) thenhave"fmdrop_fset A Γ ⊨ psubst_term e vs, psubst_term e vPs, psubst_term e vVs : Sum τ1 τ2" and"fmdrop_fset A Γ ⊨ psubst_term e1 vs, psubst_term e1 vPs, psubst_term e1 vVs : Fun τ1 τ" and"fmdrop_fset A Γ ⊨ psubst_term e2 vs, psubst_term e2 vPs, psubst_term e2 vVs : Fun τ2 τ" by simp_all thenshow ?case by auto next case (j_Prj1 Γ e τ1 τ2) thenhave"fmdrop_fset A Γ ⊨ psubst_term e vs, psubst_term e vPs, psubst_term e vVs : Prod τ1 τ2" by simp thenshow ?case by auto next case (j_Prj2 Γ e τ1 τ2) thenhave"fmdrop_fset A Γ ⊨ psubst_term e vs, psubst_term e vPs, psubst_term e vVs : Prod τ1 τ2" by simp thenshow ?case by auto next case (j_Roll α Γ e τ) thenhave"fmdrop_fset A Γ ⊨ psubst_term e vs, psubst_term e vPs, psubst_term e vVs : subst_type τ (Mu α τ) α" by simp with j_Roll(4,5) show ?case by (auto simp: fresh_fmdrop_fset) next case (j_Unroll α Γ e τ) thenhave"fmdrop_fset A Γ ⊨ psubst_term e vs, psubst_term e vPs, psubst_term e vVs : Mu α τ" by simp with j_Unroll(4,5) show ?case by (auto simp: fresh_fmdrop_fset) qed auto
lemmas lemma3 = lemma3_general[where A = "fmdom Γ"and Γ = Γ, simplified] for Γ
subsection‹Lemma 4›
lemma lemma4: assumes"Γ(x $$:= τ') ⊨ e, eP, eV : τ" and"{$$} ⊨ v, vP, vV : τ'" and"value v""value vP""value vV" shows"Γ ⊨ e[v / x], eP[vP / x], eV[vV / x] : τ" using assms proof (nominal_induct "Γ(x $$:= τ')" e eP eV τ avoiding: x Γ rule: agree.strong_induct) case a_Unit thenshow ?caseby auto next case (a_Var y τ) thenshow ?case proof (induct Γ) case fmempty thenshow ?caseby (metis agree.a_Var fmupd_lookup option.sel subst_term.simps(2)) next case (fmupd x y Γ) thenshow ?case using agree_weakening_2 fresh_tyenv_None by auto qed next case (a_Lam y τ1 e eP eV τ2) from a_Lam(1,2,5,6,7-) show ?case using agree_empty_fresh by (auto simp: fmupd_reorder_neq) next case (a_App v1 v2 v1P v2P v1V v2V τ1 τ2) from a_App(5-) show ?case by (auto intro: a_App(2,4)) next case (a_Let y e1 eP1 eV1 τ1 e2 eP2 eV2 τ2) thenshow ?case using agree_empty_fresh by (auto simp: fmupd_reorder_neq intro!: agree.a_Let[where x=y]) next case (a_Rec y z τ1 τ2 e eP eV) from a_Rec(10) have"∀a::var. atom a ♯ v""∀a::var. atom a ♯ vP""∀a::var. atom a ♯ vV" by auto with a_Rec(1-8,10-) show ?case using a_Rec(9)[OF fmupd_reorder_neq] by (auto simp: fmupd_reorder_neq intro!: agree.a_Rec[where x=y]) next case (a_Case v v1 v2 vP v1P v2P vV v1V v2V τ1 τ2 τ) from a_Case(7-) show ?case by (auto intro: a_Case(2,4,6)) next case (a_HashI v vP τ h) thenhave"atom x ♯ v""atom x ♯ vP"by auto with a_HashI show ?caseby auto qed auto
subsection‹Lemma 5: Single-Step Correctness›
lemma lemma5: assumes"{$$} ⊨ e, eP, eV : τ" and"≪ [], e ≫ I→≪ [], e' ≫" obtains eP' eV' π where"{$$} ⊨ e', eP', eV' : τ""∀πP. ≪ πP, eP ≫ P→≪ πP @ π, eP' ≫""∀π'. ≪ π @ π', eV ≫ V→≪ π', eV' ≫" proof (atomize_elim, insert assms, nominal_induct "{$$}::tyenv" e eP eV τ avoiding: e' rule: agree.strong_induct) case (a_App e1 eP1 eV1 τ1 τ2 e2 eP2 eV2) from a_App(5) show ?case proof (cases rule: s_App_inv) case (App1 e1') with a_App(2) obtain eP1' eV1' π where *: "{$$} ⊨ e1', eP1', eV1' : Fun τ1 τ2" "∀πP. ≪πP, eP1≫ P→≪πP @ π, eP1'≫""∀π'. ≪π @ π', eV1≫ V→≪π', eV1'≫" by blast show ?thesis proof (intro exI conjI) from * App1 a_App(1,3,5-) show"{$$} ⊨ e', App eP1' eP2, App eV1' eV2 : τ2" "∀πP. ≪πP, App eP1 eP2≫ P→≪πP @ π, App eP1' eP2≫" "∀π'. ≪π @ π', App eV1 eV2≫ V→≪π', App eV1' eV2≫" by auto qed next case (App2 e2') with a_App(4) obtain eP2' eV2' π where *: "{$$} ⊨ e2', eP2', eV2' : τ1" "∀πP. ≪πP, eP2≫ P→≪πP @ π, eP2'≫""∀π'. ≪π @ π', eV2≫ V→≪π', eV2'≫" by blast show ?thesis proof (intro exI conjI) from * App2 a_App(1,3,5-) show"{$$} ⊨ e', App eP1 eP2', App eV1 eV2' : τ2" "∀πP. ≪πP, App eP1 eP2≫ P→≪πP @ π, App eP1 eP2'≫" "∀π'. ≪π @ π', App eV1 eV2≫ V→≪π', App eV1 eV2'≫" by auto qed next case (AppLam x e) from a_App(1)[unfolded ‹e1 = Lam x e›] show ?thesis proof (cases rule: a_Lam_inv_I[case_names _ Lam]) case (Lam eP eV) show ?thesis proof (intro exI conjI) from Lam a_App(3,5) AppLam show"{$$} ⊨ e', eP[eP2 / x], eV[eV2 / x] : τ2" by (auto intro: lemma4) from Lam a_App(3,5) AppLam show"∀πP. ≪πP, App eP1 eP2≫ P→≪πP @ [], eP[eP2 / x]≫" by (intro allI iffD1[OF smallstepP_ps_prepend[where π = "[]", simplified]])
(auto simp: fresh_Pair intro!: s_AppLam[where v=eP2]) from Lam a_App(3,5) AppLam show"∀π'. ≪[] @ π', App eV1 eV2≫ V→≪π', eV[eV2 / x]≫" by (intro allI iffD1[OF smallstepV_ps_append[where π' = "[]", simplified]])
(auto simp: fresh_Pair intro!: s_AppLam[where v=eV2]) qed qed simp next case (AppRec x e) from a_App(1)[unfolded ‹e1 = Rec x e›] show ?thesis proof (cases rule: a_Rec_inv_I[consumes 1, case_names _ Rec]) case (Rec y e'' eP' eV') from Rec(5,4) show ?thesis proof (cases rule: a_Lam_inv_I[consumes 1, case_names _ Lam]) case (Lam eP'' eV'') show ?thesis proof (intro conjI exI[of _ "[]"] exI) let ?eP = "App (Lam y eP''[Rec x (Lam y eP'') / x]) eP2" let ?eV = "App (Lam y eV''[Rec x (Lam y eV'') / x]) eV2" from a_App(3) AppRec have [simp]: "value eP2""atom x ♯ eP2""value eV2""atom x ♯ eV2" by (auto simp: fresh_Pair) from Lam a_App(3,5-) AppRec Rec show"{$$} ⊨ e', ?eP, ?eV : τ2" unfoldingterm.eq_iff Abs1_eq(3) by (auto simp: fmupd_reorder_neq
intro!: agree.a_App[where Γ="{$$}"] a_Lam[where x=y] lemma4) from Lam a_App(3,5-) AppRec Rec show"∀πP. ≪πP, App eP1 eP2≫ P→≪πP @ [], ?eP≫" unfoldingterm.eq_iff Abs1_eq(3) using s_AppRec[where v=eP2and x=x and π="[]"and e="Lam y eP''"and uv=P] by (intro allI iffD1[OF smallstepP_ps_prepend[of "[]", simplified]])
(auto simp: fresh_Pair simp del: s_AppRec) from Lam a_App(3,5-) AppRec Rec show"∀π'. ≪[] @ π', App eV1 eV2≫ V→≪π', ?eV≫" unfoldingterm.eq_iff Abs1_eq(3) using s_AppRec[where v=eV2and x=x and π="[]"and e="Lam y eV''"and uv=V] by (intro allI iffD1[OF smallstepV_ps_append[of _ _ "[]", simplified]])
(auto simp: fresh_Pair simp del: s_AppRec) qed qed (simp add: fresh_fmap_update) qed simp qed next case (a_Let x e1 eP1 eV1 τ1 e2 eP2 eV2 τ2) thenhave"atom x ♯ (e1, [])"by auto with a_Let(10) show ?case proof (cases rule: s_Let_inv) case Let1 show ?thesis proof (intro conjI exI[of _ "[]"] exI) from a_Let(6,8) Let1 show"{$$} ⊨ e', eP2[eP1 / x], eV2[eV1 / x] : τ2" by (auto intro: lemma4) from a_Let(4,6) Let1 show"∀πP. ≪πP, Let eP1 x eP2≫ P→≪πP @ [], eP2[eP1 / x]≫" by (intro allI iffD1[OF smallstepP_ps_prepend[of "[]", simplified]] s_Let2) auto from a_Let(5,6) Let1 show"∀π'. ≪[] @ π', Let eV1 x eV2≫ V→≪π', eV2[eV1 / x]≫" by (intro allI iffD1[OF smallstepV_ps_append[of _ _ "[]", simplified]] s_Let2) auto qed next case (Let2 e1') moreover from Let2 a_Let(7) obtain eP1' eV1' π where ih: "{$$} ⊨ e1', eP1', eV1' : τ1" "∀πP. ≪πP, eP1≫ P→≪πP @ π, eP1'≫" "∀π'. ≪π @ π', eV1≫ V→≪π', eV1'≫" by (blast dest: spec[of _ "[]"]) thenhave [simp]: "atom x ♯ ({$$}, e1', eP1', eV1')" using agree_empty_fresh by auto from ih a_Let(4) have [simp]: "atom x ♯ π" using fresh_Nil fresh_append fresh_ps_smallstep_P by blast from a_Let ih have agree: "{$$} ⊨ Let e1' x e2, Let eP1' x eP2, Let eV1' x eV2 : τ2" by auto moreoverfrom a_Let(4,5) ih(1) spec[OF ih(2), of "[]", simplified] have"≪π', Let eP1 x eP2≫ P→≪π' @ π, Let eP1' x eP2≫"for π' by (intro iffD1[OF smallstepP_ps_prepend[of "[]", simplified]] s_Let1) (auto simp: fresh_Pair) moreoverfrom a_Let(4,5) ih(1) spec[OF ih(3), of "[]", simplified] have"≪π @ π', Let eV1 x eV2≫ V→≪π', Let eV1' x eV2≫"for π' by (intro iffD1[OF smallstepV_ps_append[of π _ "[]", simplified]] s_Let1) (auto simp: fresh_Pair) ultimatelyshow ?thesis by blast qed next case (a_Case e eP eV τ1 τ2 e1 eP1 eV1 τ e2 eP2 eV2) from a_Case(7) show ?case proof (cases rule: s_Case_inv) case (Case e'') with a_Case(2)[of e''] obtain eP'' eV'' π where ih: "{$$} ⊨ e'', eP'', eV'' : Syntax.Sum τ1 τ2" "∀πP. ≪πP, eP≫ P→≪πP @ π, eP''≫""∀π'. ≪π @ π', eV≫ V→≪π', eV''≫" by blast show ?thesis proof (intro conjI exI[of _ π] exI) from ih(1) a_Case(3,5) Caseshow"{$$} ⊨ e', Case eP'' eP1 eP2, Case eV'' eV1 eV2 : τ" by auto from a_Case(5) spec[OF ih(2), of "[]", simplified] show"∀πP. ≪πP, Case eP eP1 eP2≫ P→≪πP @ π, Case eP'' eP1 eP2≫" by (intro allI iffD1[OF smallstepP_ps_prepend[of "[]", simplified]] s_Case) auto from a_Case(5) spec[OF ih(3), of "[]", simplified] show"∀π'. ≪π @ π', Case eV eV1 eV2≫ V→≪π', Case eV'' eV1 eV2≫" by (intro allI iffD1[OF smallstepV_ps_append[of _ _ "[]", simplified]] s_Case) auto qed next case (Inj1 v) from a_Case(1)[unfolded ‹e = Inj1 v›] show ?thesis proof (cases rule: a_Inj1_inv_I[consumes 1, case_names Case]) case (Case vP vV) with a_Case(3,5) Inj1 show ?thesis proof (intro conjI exI[of _ "[]"] exI) fromCase a_Case(3,5) Inj1 show"{$$} ⊨ e', App eP1 vP, App eV1 vV : τ" by auto qed auto qed next case (Inj2 v) from a_Case(1)[unfolded ‹e = Inj2 v›] show ?thesis proof (cases rule: a_Inj2_inv_I[consumes 1, case_names Case]) case (Case vP vV) with a_Case(3,5) Inj2 show ?thesis proof (intro conjI exI[of _ "[]"] exI) fromCase a_Case(3,5) Inj2 show"{$$} ⊨ e', App eP2 vP, App eV2 vV : τ" by auto qed auto qed qed next case (a_Prj1 e eP eV τ1 τ2) from a_Prj1(3) show ?case proof (cases rule: s_Prj1_inv) case (Prj1 e'') thenshow ?thesis by (blast dest!: a_Prj1(2)) next case (PrjPair1 v2) from a_Prj1(1)[unfolded ‹e = Syntax.Pair e' v2›] show ?thesis proof (cases rule: a_Pair_inv_I[consumes 1, case_names Pair]) case (Pair eP1 eV1 eP2 eV2) with PrjPair1 show ?thesis proof (intro conjI exI[of _ "[]"] exI) show"{$$} ⊨ e', eP1, eV1 : τ1" by (rule Pair) qed auto qed qed next case (a_Prj2 e eP eV τ1 τ2) from a_Prj2(3) show ?case proof (cases rule: s_Prj2_inv) case (Prj2 e'') thenshow ?thesis by (blast dest!: a_Prj2(2)) next case (PrjPair2 v1) from a_Prj2(1)[unfolded ‹e = Syntax.Pair v1 e'›] show ?thesis proof (cases rule: a_Pair_inv_I[consumes 1, case_names Pair]) case (Pair eP1 eV1 eP2 eV2) with PrjPair2 show ?thesis proof (intro conjI exI[of _ "[]"] exI) show"{$$} ⊨ e', eP2, eV2 : τ2" by (rule Pair) qed auto qed qed next case (a_Roll α e eP eV τ) from a_Roll(5) show ?case proof (cases rule: s_Roll_inv) case (Roll e'') with a_Roll(4) obtain eP'' eV'' π where *: "{$$} ⊨ e'', eP'', eV'' : subst_type τ (Mu α τ) α" "∀πP. ≪πP, eP≫ P→≪πP @ π, eP''≫""∀π'. ≪π @ π', eV≫ V→≪π', eV''≫" by blast show ?thesis proof (intro exI conjI) from * Roll show"{$$} ⊨ e', Roll eP'', Roll eV'' : Mu α τ" "∀πP. ≪πP, Roll eP≫ P→≪πP @ π, Roll eP''≫" "∀π'. ≪π @ π', Roll eV≫ V→≪π', Roll eV''≫" by auto qed qed next case (a_Unroll α e eP eV τ) from a_Unroll(5) show ?case proof (cases rule: s_Unroll_inv) case (Unroll e'') with a_Unroll(4) obtain eP'' eV'' π where *: "{$$} ⊨ e'', eP'', eV'' : Mu α τ" "∀πP. ≪πP, eP≫ P→≪πP @ π, eP''≫""∀π'. ≪π @ π', eV≫ V→≪π', eV''≫" by blast show ?thesis proof (intro exI conjI) from * Unroll show"{$$} ⊨ e', Unroll eP'', Unroll eV'' : subst_type τ (Mu α τ) α" "∀πP. ≪πP, Unroll eP≫ P→≪πP @ π, Unroll eP''≫" "∀π'. ≪π @ π', Unroll eV≫ V→≪π', Unroll eV''≫" by auto qed next case UnrollRoll with a_Unroll(3)[unfolded ‹e = Roll e'›] show ?thesis proof (cases rule: a_Roll_inv_I[case_names Roll]) case (Roll eP' eV') with UnrollRoll show ?thesis proof (intro conjI exI[of _ "[]"] exI) show"{$$} ⊨ e', eP', eV' : subst_type τ (Mu α τ) α"by fact qed auto qed qed next case (a_Auth e eP eV τ) from a_Auth(1) have [simp]: "atom x ♯ eP"for x :: var using agree_empty_fresh by simp from a_Auth(3) show ?case proof (cases rule: s_AuthI_inv) case (Auth e'') thenshow ?thesis by (blast dest!: a_Auth(2)) next case AuthI with a_Auth(1) have"value eP""value eV"by auto with a_Auth(1) AuthI(2) show ?thesis proof (intro conjI exI[of _ "[]"] exI) from a_Auth(1) AuthI(2) ‹value eP› show"{$$} ⊨ e', Hashed (hash (eP)) eP, Hash (hash (eP)) : AuthT τ" by (auto dest: lemma2_1 simp: fresh_shallow) qed (auto dest: lemma2_1 simp: fresh_shallow) qed next case (a_Unauth e eP eV τ) from a_Unauth(1) have eP_closed: "closed eP" using agree_empty_fresh by simp from a_Unauth(3) show ?case proof (cases rule: s_UnauthI_inv) case (Unauth e') thenshow ?thesis by (blast dest!: a_Unauth(2)) next case UnauthI with a_Unauth(1) have"value eP""value eV"by auto from a_Unauth(1) show ?thesis proof (cases rule: a_AuthT_value_inv[case_names _ _ _ Unauth]) case (Unauth vP') show ?thesis proof (intro conjI exI[of _ "[(vP')]"] exI) from Unauth(1,2) UnauthI(2) a_Unauth(1) show"{$$} ⊨ e', vP', (vP') : τ" by (auto simp: fresh_shallow) thenhave"closed vP'" by auto with Unauth(1,2) a_Unauth(1) show "∀πP. ≪πP, Unauth eP≫ P→≪πP @ [(vP')], vP'≫" "∀π'. ≪[(vP')] @ π', Unauth eV≫ V→≪π', (vP')≫" by (auto simp: fresh_shallow) qed qed (auto simp: ‹value e›‹value eP›‹value eV›) qed next case (a_Pair e1 eP1 eV1 τ1 e2 eP2 eV2 τ2) from a_Pair(5) show ?case proof (cases rule: s_Pair_inv) case (Pair1 e1') with a_Pair(1,3) show ?thesis by (blast dest!: a_Pair(2)) next case (Pair2 e2') with a_Pair(1,3) show ?thesis by (blast dest!: a_Pair(4)) qed next case (a_Inj1 e eP eV τ1 τ2) from a_Inj1(3) show ?case proof (cases rule: s_Inj1_inv) case (Inj1 e') with a_Inj1(1) show ?thesis by (blast dest!: a_Inj1(2)) qed next case (a_Inj2 e eP eV τ2 τ1) from a_Inj2(3) show ?case proof (cases rule: s_Inj2_inv) case (Inj2 e'') with a_Inj2(1) show ?thesis by (blast dest!: a_Inj2(2)) qed qed (simp, meson value.intros value_no_step)+
subsection‹Lemma 6: Single-Step Security›
lemma lemma6: assumes"{$$} ⊨ e, eP, eV : τ" and"≪ πA, eV ≫ V→≪ π', eV' ≫" obtains e' eP' π where"≪ [], e ≫ I→≪ [], e' ≫""∀πP. ≪ πP, eP ≫ P→≪ πP @ π, eP' ≫" and"{$$} ⊨ e', eP', eV' : τ ∧ πA = π @ π' ∨ (∃s s'. closed s ∧ closed s' ∧ π = [s] ∧ πA = [s'] @ π' ∧ s ≠ s' ∧ hash s = hash s')" proof (atomize_elim, insert assms, nominal_induct "{$$}::tyenv" e eP eV τ avoiding: πA π' eV' rule: agree.strong_induct) case (a_App e1 eP1 eV1 τ1 τ2 e2 eP2 eV2) from a_App(5) show ?case proof (cases rule: s_App_inv) case (App1 eV1') with a_App(1,3) show ?thesis by (blast dest!: a_App(2)) next case (App2 e2') with a_App(1,3) show ?thesis by (blast dest!: a_App(4)) next case (AppLam x eV'') from a_App(1)[unfolded ‹eV1 = Lam x eV''›] show ?thesis proof (cases rule: a_Lam_inv_V[case_names Lam]) case (Lam e'' eP'') with a_App(3) AppLam show ?thesis proof (intro conjI exI[of _ "[]"] exI disjI1) from Lam a_App(3) AppLam show"{$$} ⊨ e''[e2 / x], eP''[eP2 / x], eV' : τ2" by (auto intro: lemma4) qed (auto 03 simp: fresh_Pair intro!: s_AppLam[where π="[]"]
intro: iffD1[OF smallstepP_ps_prepend[of "[]" _ "[]", simplified]]) qed next case (AppRec x eV'') from a_App(1)[unfolded ‹eV1 = Rec x eV''›] show ?thesis proof (cases rule: a_Rec_inv_V[case_names _ Rec]) case (Rec y e''' eP''' eV''') with a_App(1,3) AppRec show ?thesis proof (intro conjI exI[of _ "[]"] exI disjI1) let ?e = "App (Lam y e'''[Rec x (Lam y e''') / x]) e2" let ?eP = "App (Lam y eP'''[Rec x (Lam y eP''') / x]) eP2" from Rec a_App(3) AppRec show"{$$} ⊨ ?e, ?eP, eV' : τ2" by (auto simp del: subst_term.simps(3) intro!: agree.a_App[where Γ="{$$}"] lemma4) qed (auto 03 simp del: subst_term.simps(3) simp: fresh_Pair intro!: s_AppRec[where π="[]"]
intro: iffD1[OF smallstepP_ps_prepend[of "[]" _ "[]", simplified]]) qed simp qed next case (a_Let x e1 eP1 eV1 τ1 e2 eP2 eV2 τ2) thenhave"atom x ♯ (eV1, πA)"by auto with a_Let(12) show ?case proof (cases rule: s_Let_inv) case Let1 with a_Let(5,6,8,10) show ?thesis proof (intro conjI exI[of _ "[]"] exI disjI1) from Let1 a_Let(5,6,8,10) show"{$$} ⊨ e2[e1 / x], eP2[eP1 / x], eV' : τ2" by (auto intro: lemma4) qed (auto 03 intro: iffD1[OF smallstepP_ps_prepend[of "[]" _ "[]", simplified]]) next case (Let2 eV1') with a_Let(9)[of πA π' eV1'] obtain e1' π eP1' s s' where
ih: "≪[], e1≫ I→≪[], e1'≫""∀πP. ≪πP, eP1≫ P→≪πP @ π, eP1'≫" "{$$} ⊨ e1', eP1', eV1' : τ1∧ πA = π @ π' ∨ closed s ∧ closed s' ∧ π = [s] ∧ πA = [s'] @ π' ∧ s ≠ s' ∧ hash s = hash s'" by blast with a_Let(5,6) have fresh: "atom x ♯ e1'""atom x ♯ eP1'" using fresh_smallstep_I fresh_smallstep_P by blast+ from ih a_Let(2,6) have"atom x ♯ π" using fresh_append fresh_ps_smallstep_P by blast with Let2 a_Let(1-8,10,12-) fresh ih show ?thesis proof (intro conjI exI[of _ "π"] exI) from‹atom x ♯ π› Let2 a_Let(1-8,10,12-) fresh ih show"{$$} ⊨ Let e1' x e2, Let eP1' x eP2, eV' : τ2∧ πA = π @ π' ∨ (∃s s'. closed s ∧ closed s' ∧ π = [s] ∧ πA = [s'] @ π' ∧ s ≠ s' ∧ hash s = hash s')" by auto qed (auto dest: spec[of _ "[]"] intro!: iffD1[OF smallstepP_ps_prepend, of "[]", simplified]) qed next case (a_Case e eP eV τ1 τ2 e1 eP1 eV1 τ e2 eP2 eV2) from a_Case(7) show ?case proof (cases rule: s_Case_inv) case (Case eV'') from a_Case(2)[OF Case(2)] show ?thesis proof (elim exE disjE conjE, goal_cases ok collision) case (ok e'' π eP'') withCase a_Case(3,5) show ?caseby blast next case (collision e'' π eP'' s s') withCase a_Case(3,5) show ?case proof (intro exI[of _ "[s]"] exI conjI disjI2) fromCase a_Case(3,5) collision show"≪[], Case e e1 e2≫ I→≪[], Case e'' e1 e2≫" "∀πP. ≪πP, Case eP eP1 eP2≫ P→≪πP @ [s], Case eP'' eP1 eP2≫" by auto from collision show"closed s""closed s'""s ≠ s'""hash s = hash s'"by auto qed simp qed next case (Inj1 vV) from a_Case(1)[unfolded ‹eV = Inj1 vV›] show ?thesis proof (cases rule: a_Inj1_inv_V[consumes 1, case_names Inj]) case (Inj v' vP') with Inj1 show ?thesis proof (intro conjI exI[of _ "[]"] exI disjI1) from a_Case(3) Inj Inj1 show"{$$} ⊨ App e1 v', App eP1 vP', eV' : τ" by auto qed auto qed next case (Inj2 vV) from a_Case(1)[unfolded ‹eV = Inj2 vV›] show ?thesis proof (cases rule: a_Inj2_inv_V[consumes 1, case_names Inj]) case (Inj v' vP') with Inj2 show ?thesis proof (intro conjI exI[of _ "[]"] exI disjI1) from a_Case(5) Inj Inj2 show"{$$} ⊨ App e2 v', App eP2 vP', eV' : τ" by auto qed auto qed qed next case (a_Prj1 e eP eV τ1 τ2) from a_Prj1(3) show ?case proof (cases rule: s_Prj1_inv) case (Prj1 eV'') thenshow ?thesis by (blast dest!: a_Prj1(2)) next case (PrjPair1 v2) with a_Prj1(1) show ?thesis proof (cases rule: a_Prod_inv[consumes 1, case_names _ _ _ _ Pair]) case (Pair e1 eP1 eV1 e2 eP2 eV2) with PrjPair1 a_Prj1(1) show ?thesis proof (intro conjI exI[of _ "[]"] exI disjI1) from Pair PrjPair1 a_Prj1(1) show"{$$} ⊨ e1, eP1, eV' : τ1" by auto qed auto qed simp_all qed next case (a_Prj2 e eP eV τ1 τ2) from a_Prj2(3) show ?case proof (cases rule: s_Prj2_inv) case (Prj2 eV'') thenshow ?thesis by (blast dest!: a_Prj2(2)) next case (PrjPair2 v2) with a_Prj2(1) show ?thesis proof (cases rule: a_Prod_inv[consumes 1, case_names _ _ _ _ Pair]) case (Pair e1 eP1 eV1 e2 eP2 eV2) with PrjPair2 a_Prj2(1) show ?thesis proof (intro conjI exI[of _ "[]"] exI disjI1) from Pair PrjPair2 a_Prj2(1) show"{$$} ⊨ e2, eP2, eV' : τ2" by auto qed auto qed simp_all qed next case (a_Roll α e eP eV τ) from a_Roll(7) show ?case proof (cases rule: s_Roll_inv) case (Roll eV'') from a_Roll(6)[OF Roll(2)] obtain e'' π eP'' where ih: "≪[], e≫ I→≪[], e''≫""∀πP. ≪πP, eP≫ P→≪πP @ π, eP''≫" "{$$} ⊨ e'', eP'', eV'' : subst_type τ (Mu α τ) α ∧ πA = π @ π' ∨ (∃s s'. closed s ∧ closed s' ∧ π = [s] ∧ πA = [s'] @ π' ∧ s ≠ s' ∧ hash s = hash s')" by blast with Roll show ?thesis proof (intro exI[of _ "π"] exI conjI) from ih Roll show"{$$} ⊨ Roll e'', Roll eP'', eV' : Mu α τ ∧ πA = π @ π' ∨ (∃s s'. closed s ∧ closed s' ∧ π = [s] ∧ πA = [s'] @ π' ∧ s ≠ s' ∧ hash s = hash s')" by auto qed auto qed next case (a_Unroll α e eP eV τ) from a_Unroll(7) show ?case proof (cases rule: s_Unroll_inv) case (Unroll eV'') from a_Unroll(6)[OF Unroll(2)] obtain e'' π eP'' where ih: "≪[], e≫ I→≪[], e''≫""∀πP. ≪πP, eP≫ P→≪πP @ π, eP''≫" "{$$} ⊨ e'', eP'', eV'' : Mu α τ ∧ πA = π @ π' ∨ (∃s s'. closed s ∧ closed s' ∧ π = [s] ∧ πA = [s'] @ π' ∧ s ≠ s' ∧ hash s = hash s')" by blast with Unroll show ?thesis proof (intro exI[of _ "π"] exI conjI) from ih Unroll show"{$$} ⊨ Unroll e'', Unroll eP'', eV' : subst_type τ (Mu α τ) α ∧ πA = π @ π' ∨ (∃s s'. closed s ∧ closed s' ∧ π = [s] ∧ πA = [s'] @ π' ∧ s ≠ s' ∧ hash s = hash s')" by auto qed auto next case UnrollRoll with a_Unroll(5) show ?thesis by fastforce qed next case (a_Auth e eP eV τ) from a_Auth(1) have [simp]: "atom x ♯ eP"for x :: var using agree_empty_fresh by simp from a_Auth(3) show ?case proof (cases rule: s_AuthV_inv) case (Auth eV'') from a_Auth(2)[OF Auth(2)] show ?thesis proof (elim exE disjE conjE, goal_cases ok collision) case (ok e'' π eP'') with Auth show ?case proof (intro conjI exI[of _ "π"] exI disjI1) from ok Auth show"{$$} ⊨ Auth e'', Auth eP'', eV' : AuthT τ" by auto qed auto next case (collision e'' π eP'' s s') thenshow ?caseby blast qed next case AuthV with a_Auth(1) show ?thesis proof (intro exI[of _ "[]"] exI conjI disjI1) from a_Auth(1) AuthV show"{$$} ⊨ e, Hashed (hash (eP)) eP, eV' : AuthT τ" by (auto dest: lemma2_1) qed (auto simp: fresh_shallow) qed next case (a_Unauth e eP eV τ) from a_Unauth(3) show ?case proof (cases rule: s_UnauthV_inv) case (Unauth e') thenshow ?thesis by (blast dest!: a_Unauth(2)) next case UnauthV from a_Unauth(1)[unfolded ‹eV = Hash (hash eV')›] UnauthV a_Unauth(1) show ?thesis proof (cases rule: a_AuthT_value_inv[consumes 1, case_names _ _ _ Hashed]) case (Hashed vP') with UnauthV a_Unauth(1) show ?thesis proof (intro exI[of _ "[(vP')]"] exI conjI) from Hashed UnauthV a_Unauth(1) show"{$$} ⊨ e, vP', eV' : τ ∧ πA = [(vP')] @ π' ∨ (∃s s'. closed s ∧ closed s' ∧ [(vP')] = [s] ∧ πA = [s'] @ π' ∧ s ≠ s' ∧ hash s = hash s')" by (fastforce elim: a_HashI_inv[where Γ="{$$}"]) qed auto qed auto qed next case (a_Pair e1 eP1 eV1 τ1 e2 eP2 eV2 τ2) from a_Pair(5) show ?case proof (cases rule: s_Pair_inv) case (Pair1 eV1') with a_Pair(3) show ?thesis using a_Pair(2)[of πA π' eV1'] by blast next case (Pair2 eV2') with a_Pair(1) show ?thesis using a_Pair(4)[of πA π' eV2'] by blast qed next case (a_Inj1 e eP eV τ1 τ2) from a_Inj1(3) show ?case proof (cases rule: s_Inj1_inv) case (Inj1 eV'') thenshow ?thesis using a_Inj1(2)[of πA π' eV''] by blast qed next case (a_Inj2 e eP eV τ2 τ1) from a_Inj2(3) show ?case proof (cases rule: s_Inj2_inv) case (Inj2 eV'') with a_Inj2(1) show ?thesis using a_Inj2(2)[of πA π' eV''] by blast qed qed (simp, meson value.intros value_no_step)+
subsection‹Theorem 1: Correctness›
lemma theorem1_correctness: assumes"{$$} ⊨ e, eP, eV : τ" and"≪ [], e ≫ I→i ≪ [], e' ≫" obtains eP' eV' π where"≪ [], eP ≫ P→i ≪ π, eP' ≫" "≪ π, eV ≫ V→i ≪ [], eV' ≫" "{$$} ⊨ e', eP', eV' : τ" using assms(2,1) proof (atomize_elim, induct "[]::proofstream" e I i "[]::proofstream" e' rule: smallsteps.induct) case (s_Id e) thenshow ?caseby auto next case (s_Tr e1 i π2 e2 e3) thenhave"π2 = []"by (auto dest: smallstepI_ps_eq) with s_Tr obtain eP2 π eV2where ih: "≪[], eP≫ P→i ≪π, eP2≫""≪π, eV≫ V→i ≪[], eV2≫""{$$} ⊨ e2, eP2, eV2 : τ" by (atomize_elim, intro s_Tr(2)) auto moreoverobtain eP3 eV3 π' where agree: "{$$} ⊨ e3, eP3, eV3 : τ" and"≪πP, eP2≫ P→≪πP @ π', eP3≫""≪π' @ π'', eV2≫ V→≪π'', eV3≫" for πP π'' using lemma5[OF ih(3) s_Tr(3)[unfolded ‹π2 = []›], of thesis] by blast ultimatelyhave"≪[], eP≫ P→i + 1 ≪π @ π', eP3≫""≪π @ π', eV≫ V→i + 1 ≪[], eV3≫" by (auto simp: smallstepsV_ps_append[of _ _ _ "[]", simplified, symmetric]
intro!: smallsteps.s_Tr[of "π @ π'"]) with agree show ?caseby blast qed
subsection‹Counterexamples to Theorem 1: Security›
text‹Counterexample using administrative normal form.›
lemma security_false: assumes agree: "∧e eP eV τ πA i π' eV'. [ {$$} ⊨ e, eP, eV : τ; ≪ πA, eV ≫ V→i ≪ π', eV' ≫]==> ∃e' eP' π j π0 s s'. (≪ [], e ≫ I→i ≪ [], e' ≫∧≪ [], eP ≫ P→i ≪ π, eP' ≫∧ (πA = π @ π') ∧ {$$} ⊨ e', eP', eV' : τ) ∨ (j ≤ i ∧≪ [], eP ≫ P→j ≪ π0 @ [s], eP' ≫∧ (πA = π0 @ [s'] @ π') ∧ s ≠ s' ∧ hash s = hash s')" and collision: "hash (Inj1 Unit) = hash (Inj2 Unit)" and no_collision_with_Unit: "∧t. hash Unit = hash t ==> t = Unit" shows False proof -
define i where"i = Suc (Suc (Suc (Suc (Suc (Suc (Suc (Suc 0)))))))" obtain x y z :: var where fresh: "atom y ♯ x""atom z ♯ (x, y)" by (metis obtain_fresh)
define t where"t = Let (Let (Auth (Inj1 Unit)) y (Unauth (Var y))) x (Let (Let (Auth Unit) z (Unauth (Var z))) y (Var x))" note fresh_Cons[simp] have prover: "≪ [], t ≫ P→i ≪ [Inj1 Unit, Unit], Inj1 Unit ≫" ― ‹prover execution› unfolding i_def t_def Suc_eq_plus1 using fresh apply - apply (rule smallsteps.intros)+ apply (rule s_Let1[rotated]) apply (rule s_Let1[rotated]) apply (rule s_AuthP[rotated]) apply simp apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_Let2) apply simp apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_UnauthP) apply simp apply simp apply simp apply (rule s_Let2) apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_Let1[rotated]) apply (rule s_AuthP[rotated]) apply simp apply simp apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_Let2) apply simp apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_UnauthP) apply simp apply simp apply simp apply (rule s_Let2[of Unit y _ "Inj1 Unit", simplified]) apply simp done have verifier1: "≪ [Inj1 Unit, Unit], t ≫ V→i ≪ [], Inj1 Unit ≫" ― ‹verifier execution› unfolding i_def t_def Suc_eq_plus1 using fresh apply - apply (rule smallsteps.intros)+ apply (rule s_Let1[rotated]) apply (rule s_Let1[rotated]) apply (rule s_AuthV[rotated]) apply simp apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_Let2) apply simp apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_UnauthV) apply simp apply simp apply simp apply (rule s_Let2) apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_Let1[rotated]) apply (rule s_AuthV[rotated]) apply simp apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_Let2) apply simp apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_UnauthV) apply simp apply simp apply simp apply (rule s_Let2[of Unit y _ "Inj1 Unit", simplified]) apply simp done have verifier2: "≪ [Inj2 Unit, Unit], t ≫ V→i ≪ [], Inj2 Unit ≫" ― ‹verifier execution with proofstream containing collision› unfolding i_def t_def Suc_eq_plus1 using fresh apply - apply (rule smallsteps.intros)+ apply (rule s_Let1[rotated]) apply (rule s_Let1[rotated]) apply (rule s_AuthV[rotated]) apply simp apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_Let2) apply simp apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_UnauthV) apply simp apply (simp add: collision) apply simp apply (rule s_Let2) apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_Let1[rotated]) apply (rule s_AuthV[rotated]) apply simp apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_Let2) apply simp apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_UnauthV) apply simp apply simp apply simp apply (rule s_Let2[of Unit y _ "Inj2 Unit", simplified]) apply simp done have judge: "{$$} ⊨ t : Sum One One" unfolding t_def using fresh by (force simp: fresh_Pair fresh_fmap_update) have ideal_deterministic: "e = Inj1 Unit"if"≪[], t≫ I→i ≪[], e≫"for e apply (rule smallsteps_ideal_deterministic[OF that]) unfolding i_def t_def Suc_eq_plus1 using fresh apply - apply (rule smallsteps.intros)+ apply (rule s_Let1[rotated]) apply (rule s_Let1[rotated]) apply (rule s_AuthI[rotated]) apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_Let2) apply simp apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_UnauthI) apply simp apply simp apply (rule s_Let2) apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_Let1[rotated]) apply (rule s_AuthI[rotated]) apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_Let2) apply simp apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_UnauthI) apply simp apply simp apply (rule s_Let2[of Unit y _ "Inj1 Unit", simplified]) apply simp done from agree[OF judge_imp_agree[OF judge] verifier2] collision prover verifier1 show False proof safe fix e' eP' assume agree: "{$$} ⊨ e', eP', Inj2 Unit : Sum One One" assume assm: "≪[], t≫ I→i ≪[], e'≫" thenhave"e' = Inj1 Unit" by (simp add: ideal_deterministic) with agree show False by auto qed (auto dest!: no_collision_with_Unit[OF sym]) qed
text‹Alternative, shorter counterexample not in administrative normal form.›
lemma security_false_alt: assumes agree: "∧e eP eV τ πA i π' eV'. [ {$$} ⊨ e, eP, eV : τ; ≪ πA, eV ≫ V→i ≪ π', eV' ≫]==> ∃e' eP' π j π0 s s'. (≪ [], e ≫ I→i ≪ [], e' ≫∧≪ [], eP ≫ P→i ≪ π, eP' ≫∧ (πA = π @ π') ∧ {$$} ⊨ e', eP', eV' : τ) ∨ (j ≤ i ∧≪ [], eP ≫ P→j ≪ π0 @ [s], eP' ≫∧ (πA = π0 @ [s'] @ π') ∧ s ≠ s' ∧ hash s = hash s')" and collision: "hash (Inj1 Unit) = hash (Inj2 Unit)" and no_collision_with_Unit: "∧t. hash Unit = hash t ==> t = Unit" shows False proof -
define i where"i = Suc (Suc (Suc (Suc (Suc (Suc 0)))))" obtain x y z :: var where fresh: "atom y ♯ x""atom z ♯ (x, y)" by (metis obtain_fresh)
define t where"t = Let (Unauth (Auth (Inj1 Unit))) x (Let (Unauth (Auth Unit)) y (Var x))" note fresh_Cons[simp] have prover: "≪ [], t ≫ P→i ≪ [Inj1 Unit, Unit], Inj1 Unit ≫" ― ‹prover execution› unfolding i_def t_def Suc_eq_plus1 using fresh apply - apply (rule smallsteps.intros)+ apply (rule s_Let1[rotated]) apply (rule s_Unauth) apply (rule s_AuthP[rotated]) apply simp apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_UnauthP) apply simp apply simp apply simp apply (rule s_Let2) apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_Unauth) apply (rule s_AuthP[rotated]) apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_UnauthP) apply simp apply simp apply simp apply (rule s_Let2[of Unit y _ "Inj1 Unit", simplified]) apply simp done have verifier1: "≪ [Inj1 Unit, Unit], t ≫ V→i ≪ [], Inj1 Unit ≫" ― ‹verifier execution› unfolding i_def t_def Suc_eq_plus1 using fresh apply - apply (rule smallsteps.intros)+ apply (rule s_Let1[rotated]) apply (rule s_Unauth) apply (rule s_AuthV[rotated]) apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_UnauthV) apply simp apply simp apply simp apply (rule s_Let2) apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_Unauth) apply (rule s_AuthV[rotated]) apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_UnauthV) apply simp apply simp apply simp apply (rule s_Let2[of Unit y _ "Inj1 Unit", simplified]) apply simp done have verifier2: "≪ [Inj2 Unit, Unit], t ≫ V→i ≪ [], Inj2 Unit ≫" ― ‹verifier execution with proofstream containing collision› unfolding i_def t_def Suc_eq_plus1 using fresh apply - apply (rule smallsteps.intros)+ apply (rule s_Let1[rotated]) apply (rule s_Unauth) apply (rule s_AuthV[rotated]) apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_UnauthV) apply simp apply (simp add: collision) apply simp apply (rule s_Let2) apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_Unauth) apply (rule s_AuthV[rotated]) apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_UnauthV) apply simp apply simp apply simp apply (rule s_Let2[of Unit y _ "Inj2 Unit", simplified]) apply simp done have judge: "{$$} ⊨ t : Sum One One" unfolding t_def using fresh by (force simp: fresh_Pair fresh_fmap_update) have ideal_deterministic: "e = Inj1 Unit"if"≪[], t≫ I→i ≪[], e≫"for e apply (rule smallsteps_ideal_deterministic[OF that]) unfolding i_def t_def Suc_eq_plus1 using fresh apply - apply (rule smallsteps.intros)+ apply (rule s_Let1[rotated]) apply (rule s_Unauth) apply (rule s_AuthI[rotated]) apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_UnauthI) apply simp apply simp apply (rule s_Let2) apply simp apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_Unauth) apply (rule s_AuthI[rotated]) apply simp apply simp apply (rule s_Let1[rotated]) apply (rule s_UnauthI) apply simp apply simp apply (rule s_Let2[of Unit y _ "Inj1 Unit", simplified]) apply simp done from agree[OF judge_imp_agree[OF judge] verifier2] collision prover verifier1 show False proof safe fix e' eP' assume agree: "{$$} ⊨ e', eP', Inj2 Unit : Sum One One" assume assm: "≪[], t≫ I→i ≪[], e'≫" thenhave"e' = Inj1 Unit" by (simp add: ideal_deterministic) with agree show False by auto qed (auto dest!: no_collision_with_Unit[OF sym]) qed
subsection‹Corrected Theorem 1: Security›
lemma theorem1_security: assumes"{$$} ⊨ e, eP, eV : τ" and"≪ πA, eV ≫ V→i ≪ π', eV' ≫" shows"(∃e' eP' π. ≪ [], e ≫ I→i ≪ [], e' ≫∧≪ [], eP ≫ P→i ≪ π, eP' ≫∧ πA = π @ π' ∧{$$} ⊨ e', eP', eV' : τ) ∨ (∃eP' j π0 π0' s s'. j ≤ i ∧≪ [], eP ≫ P→j ≪ π0 @ [s], eP' ≫∧ πA = π0 @ [s'] @ π0' @ π' ∧ s ≠ s' ∧ hash s = hash s' ∧ closed s ∧ closed s')" using assms(2,1) proof (induct πA eV V i π' eV' rule: smallsteps.induct) case (s_Id π e) thenshow ?caseby blast next case (s_Tr π1 eV1 i π2 eV2 π3 eV3) thenobtain e2 π eP2 j π0 π0' s s' where"≪[], e≫ I→i ≪[], e2≫∧≪[], eP≫ P→i ≪π, eP2≫∧ π1 = π @ π2∧ {$$} ⊨ e2, eP2, eV2 : τ ∨ j ≤ i ∧≪[], eP≫ P→j ≪π0 @ [s], eP2≫∧ closed s ∧ closed s' ∧ π1 = π0 @ [s'] @ π0' @ π2∧ s ≠ s' ∧ hash s = hash s'" by blast thenshow ?case proof (elim disjE conjE, goal_cases ok collision) case ok obtain e3 eP3 π' where "≪[], e2≫ I→≪[], e3≫""≪πP, eP2≫ P→≪πP @ π', eP3≫" "{$$} ⊨ e3, eP3, eV3 : τ ∧ π2 = π' @ π3∨ (∃s s'. closed s ∧ closed s' ∧ π' = [s] ∧ π2 = [s'] @ π3∧ s ≠ s' ∧ hash s = hash s')" for πPusing lemma6[OF ok(4) s_Tr(3), of thesis] by blast thenshow ?case proof (elim disjE conjE exE, goal_cases ok2 collision) case ok2 with s_Tr(1,3-) ok show ?case by auto next case (collision s s') thenshow ?case proof (intro disjI2 exI conjI) from ok collision show"≪[], eP≫ P→i + 1 ≪π @ [s], eP3≫" by (elim smallsteps.s_Tr) auto from ok collision show"π1 = π @ [s'] @ [] @ π3" by simp qed simp_all qed next case collision from s_Tr(3) collision show ?case proof (elim smallstepV_consumes_proofstream, intro disjI2 exI conjI) fix π0'' assume *: "π2 = π0'' @ π3" from collision * show"π1 = π0 @ [s'] @ (π0' @ π0'') @ π3" by simp qed simp_all qed qed
subsection‹Remark 1›
lemma remark1_single: assumes"{$$} ⊨ e, eP, eV : τ" and"≪ πP, eP ≫ P→≪ πP @ π, eP' ≫" obtains e' eV' where"{$$} ⊨ e', eP', eV' : τ ∧≪ [], e ≫ I→≪ [], e' ≫∧≪ π, eV ≫ V→≪ [], eV' ≫" proof (atomize_elim, insert assms, nominal_induct "{$$}::tyenv" e eP eV τ avoiding: πP π eP' rule: agree.strong_induct) case (a_App e1 eP1 eV1 τ1 τ2 e2 eP2 eV2) from a_App(5) show ?case proof (cases rule: s_App_inv) case (App1 eP1') with a_App(2,3) show ?thesis by blast next case (App2 eP2') with a_App(1,4) show ?thesis by blast next case (AppLam x eP) from a_App(1)[unfolded ‹eP1 = Lam x eP›] show ?thesis proof (cases rule: a_Lam_inv_P[case_names Lam]) case (Lam v' vV') with a_App(3) AppLam show ?thesis by (auto 04 simp: fresh_Pair del: s_AppLam intro!: s_AppLam lemma4) qed next case (AppRec x e) from a_App(1)[unfolded ‹eP1 = Rec x e›] show ?thesis proof (cases rule: a_Rec_inv_P[case_names _ Rec]) case (Rec y e'' eP'' eV'') show ?thesis proof (intro exI conjI) let ?e = "App (Lam y (e''[Rec x (Lam y e'') / x])) e2" let ?eV = "App (Lam y (eV''[Rec x (Lam y eV'') / x])) eV2" from a_App(3) Rec AppRec show"{$$} ⊨ ?e, eP', ?eV : τ2" by (auto intro!: agree.a_App[where Γ="{$$}"] lemma4
simp del: subst_term.simps(3) simp: subst_term.simps(3)[symmetric]) from a_App(3) Rec AppRec show"≪[], App e1 e2≫ I→≪[], ?e≫" by (auto intro!: s_AppRec[where v=e2]
simp del: subst_term.simps(3) simp: subst_term.simps(3)[symmetric] fresh_Pair) from a_App(3) Rec AppRec show"≪π, App eV1 eV2≫ V→≪[], ?eV≫" by (auto intro!: s_AppRec[where v=eV2]
simp del: subst_term.simps(3) simp: subst_term.simps(3)[symmetric] fresh_Pair) qed qed simp qed next case (a_Let x e1 eP1 eV1 τ1 e2 eP2 eV2 τ2) thenhave"atom x ♯ (eP1, πP)"by auto with a_Let(12) show ?case proof (cases rule: s_Let_inv) case Let1 with a_Let show ?thesis by (intro exI[where P = "λx. ∃y. (Q x y)"for Q, OF exI, of _ "e2[e1 / x]""eV2[eV1 / x]"])
(auto intro!: lemma4) next case (Let2 eP1') with a_Let(9) obtain e1' eV1' where ih: "{$$} ⊨ e1', eP1', eV1' : τ1""≪[], e1≫ I→≪[], e1'≫""≪π, eV1≫ V→≪[], eV1'≫" by blast from a_Let Let2 have"¬ value e1""¬ value eP1""¬ value eV1"by auto with Let2 a_Let(2,5,7,10) ih show ?thesis
by (intro exI[where P = "\<lambda>x. \<exists>y. (Q x y)" for Q, OF exI, of _ "Let e\<^sub>1' x e\<^sub>2""Let eV\<^sub>1' x eV\<^sub>2"])
(fastforce simp: fresh_Pair del: agree.a_Let intro!: agree.a_Let)
qed
next case (a_Case e eP eV \<tau>\<^sub>1 \<tau>\<^sub>2 e\<^sub>1 eP\<^sub>1 eV\<^sub>1 \<tau> e\<^sub>2 eP\<^sub>2 eV\<^sub>2)
from a_Case(7) show ?case
proof (cases rule: s_Case_inv) case (Case eP'') with a_Case(2,3,5) show ?thesis by blast
next case (Inj1 v) with a_Case(1,3,5) show ?thesis by blast
next case (Inj2 v) with a_Case(1,3,5) show ?thesis by blast
qed
next case (a_Prj1 e eP eV \<tau>\<^sub>1 \<tau>\<^sub>2 \<pi>P \<pi> eP')
from a_Prj1(3) show ?case
proof (cases rule: s_Prj1_inv) case (Prj1 eP'') with a_Prj1(2) show ?thesis by blast
next case (PrjPair1 v\<^sub>2) with a_Prj1(1) show ?thesis by fastforce
qed
next case (a_Prj2 v vP vV \<tau>\<^sub>1 \<tau>\<^sub>2)
from a_Prj2(3) show ?case
proof (cases rule: s_Prj2_inv) case (Prj2 eP'') with a_Prj2(2) show ?thesis by blast
next case (PrjPair2 v\<^sub>2) with a_Prj2(1) show ?thesis by fastforce
qed
next case (a_Roll \<alpha> e eP eV \<tau>)
from a_Roll(7) show ?case
proof (cases rule: s_Roll_inv) case (Roll eP'') with a_Roll(4,5,6) show ?thesis by blast
qed
next case (a_Unroll \<alpha> e eP eV \<tau>)
from a_Unroll(7) show ?case
proof (cases rule: s_Unroll_inv) case (Unroll eP'') with a_Unroll(5,6) show ?thesis by fastforce
next case UnrollRoll with a_Unroll(5) show ?thesis by blast
qed
next case (a_Auth e eP eV \<tau>)
from a_Auth(3) show ?case
proof (cases rule: s_AuthP_inv) case (Auth eP'') with a_Auth(3) show ?thesis
by (auto dest!: a_Auth(2)[of \<pi>P \<pi> eP''])
next case AuthP with a_Auth(1) show ?thesis
by (auto 04 simp: lemma2_1 intro: exI[of _ "Hash (hash \<lparr>eP\<rparr>)"] exI[of _ e])
qed
next case (a_Unauth e eP eV \<tau>)
from a_Unauth(1) have eP_closed: "closed eP"
using agree_empty_fresh by simp
from a_Unauth(3) show ?case
proof (cases rule: s_UnauthP_inv) case (Unauth e') with a_Unauth(2) show ?thesis
by blast
next case (UnauthP h) with a_Unauth(1,3) eP_closed show ?thesis
by (force intro: a_AuthT_value_inv[OF a_Unauth(1)] simp: fresh_shallow)
qed
next case (a_Inj1 e eP eV \<tau>\<^sub>1 \<tau>\<^sub>2)
from a_Inj1(3) show ?case
proof (cases rule: s_Inj1_inv) case (Inj1 eP'') with a_Inj1(1,2) show ?thesis by blast
qed
next case (a_Inj2 e eP eV \<tau>\<^sub>2 \<tau>\<^sub>1)
from a_Inj2(3) show ?case
proof (cases rule: s_Inj2_inv) case (Inj2 eP'') with a_Inj2(1,2) show ?thesis by blast
qed
next case (a_Pair e\<^sub>1 eP\<^sub>1 eV\<^sub>1 \<tau>\<^sub>1 e\<^sub>2 eP\<^sub>2 eV\<^sub>2 \<tau>\<^sub>2)
from a_Pair(5) show ?case
proof (cases rule: s_Pair_inv) case (Pair1 eP\<^sub>1') with a_Pair(1,2,3) show ?thesis by blast
next case (Pair2 eP\<^sub>2') with a_Pair(1,3,4) show ?thesis by blast
qed
qed (auto dest: value_no_step)
lemma remark1:
assumes "{$$} \<turnstile> e, eP, eV : \<tau>" and"\<lless> \<pi>\<^sub>P, eP \<ggreater> P\<rightarrow>i \<lless> \<pi>\<^sub>P @ \<pi>, eP' \<ggreater>"
obtains e' eV'
where "{$$} \<turnstile> e', eP', eV' : \<tau>""\<lless> [], e \<ggreater> I\<rightarrow>i \<lless> [], e' \<ggreater>""\<lless> \<pi>, eV \<ggreater> V\<rightarrow>i \<lless> [], eV' \<ggreater>"
using assms(2,1)
proof (atomize_elim, nominal_induct \<pi>\<^sub>P eP P i "\<pi>\<^sub>P @ \<pi>" eP' arbitrary: \<pi> rule: smallsteps.strong_induct) case (s_Id e \<pi>P) then show ?case
using s_Id_inv by blast
next case (s_Tr \<pi>\<^sub>1 eP\<^sub>1 i \<pi>\<^sub>2 eP\<^sub>2 eP\<^sub>3)
from s_Tr obtain \<pi>' \<pi>'' where ps: "\<pi>\<^sub>2 = \<pi>\<^sub>1 @ \<pi>'" "\<pi> = \<pi>' @ \<pi>''"
by (force elim: smallstepP_generates_proofstream smallstepsP_generates_proofstream) with s_Tr obtain e\<^sub>2 eV\<^sub>2 where ih: "{$$} \<turnstile> e\<^sub>2, eP\<^sub>2, eV\<^sub>2 : \<tau>" "\<lless>[], e\<ggreater> I\<rightarrow>i \<lless>[], e\<^sub>2\<ggreater>""\<lless>\<pi>', eV\<ggreater> V\<rightarrow>i \<lless>[], eV\<^sub>2\<ggreater>"
by atomize_elim (auto elim: s_Tr(2)[of \<pi>'])
moreover
obtain e\<^sub>3 eV\<^sub>3 where agree: "{$$} \<turnstile> e\<^sub>3, eP\<^sub>3, eV\<^sub>3 : \<tau>"and "\<lless>[], e\<^sub>2\<ggreater> I\<rightarrow> \<lless>[], e\<^sub>3\<ggreater>""\<lless>\<pi>'', eV\<^sub>2\<ggreater> V\<rightarrow> \<lless>[], eV\<^sub>3\<ggreater>"
by (rule remark1_single[OF ih(1) iffD2[OF smallstepP_ps_prepend s_Tr(3)[unfolded ps]]]) blast
ultimately have "\<lless>[], e\<ggreater> I\<rightarrow>i + 1 \<lless>[], e\<^sub>3\<ggreater>""\<lless>\<pi>, eV\<ggreater> V\<rightarrow>i + 1 \<lless>[], eV\<^sub>3\<ggreater>"
by (auto simp: smallstepsV_ps_append[of _ _ _ "[]", simplified, symmetric] ps
intro!: smallsteps.s_Tr[where m=V and \<pi>\<^sub>1="\<pi>' @ \<pi>''"and \<pi>\<^sub>2=\<pi>'']) with agree show ?case
by blast
qed
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.