author | wenzelm |
Mon, 13 Apr 2020 22:08:14 +0200 | |
changeset 71751 | abf3e80bd815 |
parent 67613 | ce654b0e6d69 |
child 71989 | bad75618fb82 |
permissions | -rw-r--r-- |
41775 | 1 |
(* Title: HOL/Auth/Guard/P2.thy |
2 |
Author: Frederic Blanqui, University of Cambridge Computer Laboratory |
|
3 |
Copyright 2002 University of Cambridge |
|
13508 | 4 |
|
41775 | 5 |
From G. Karjoth, N. Asokan and C. Gulcu |
6 |
"Protecting the computation results of free-roaming agents" |
|
7 |
Mobiles Agents 1998, LNCS 1477. |
|
8 |
*) |
|
13508 | 9 |
|
61830 | 10 |
section\<open>Protocol P2\<close> |
13508 | 11 |
|
16417 | 12 |
theory P2 imports Guard_Public List_Msg begin |
13508 | 13 |
|
61830 | 14 |
subsection\<open>Protocol Definition\<close> |
13508 | 15 |
|
16 |
||
61830 | 17 |
text\<open>Like P1 except the definitions of \<open>chain\<close>, \<open>shop\<close>, |
18 |
\<open>next_shop\<close> and \<open>nonce\<close>\<close> |
|
13508 | 19 |
|
61830 | 20 |
subsubsection\<open>offer chaining: |
21 |
B chains his offer for A with the head offer of L for sending it to C\<close> |
|
13508 | 22 |
|
35416
d8d7d1b785af
replaced a couple of constsdefs by definitions (also some old primrecs by modern ones)
haftmann
parents:
23746
diff
changeset
|
23 |
definition chain :: "agent => nat => agent => msg => agent => msg" where |
13508 | 24 |
"chain B ofr A L C == |
25 |
let m1= sign B (Nonce ofr) in |
|
61956 | 26 |
let m2= Hash \<lbrace>head L, Agent C\<rbrace> in |
27 |
\<lbrace>Crypt (pubK A) m1, m2\<rbrace>" |
|
13508 | 28 |
|
29 |
declare Let_def [simp] |
|
30 |
||
31 |
lemma chain_inj [iff]: "(chain B ofr A L C = chain B' ofr' A' L' C') |
|
32 |
= (B=B' & ofr=ofr' & A=A' & head L = head L' & C=C')" |
|
33 |
by (auto simp: chain_def Let_def) |
|
34 |
||
67613 | 35 |
lemma Nonce_in_chain [iff]: "Nonce ofr \<in> parts {chain B ofr A L C}" |
13508 | 36 |
by (auto simp: chain_def sign_def) |
37 |
||
61830 | 38 |
subsubsection\<open>agent whose key is used to sign an offer\<close> |
13508 | 39 |
|
35418 | 40 |
fun shop :: "msg => msg" where |
61956 | 41 |
"shop \<lbrace>Crypt K \<lbrace>B,ofr,Crypt K' H\<rbrace>,m2\<rbrace> = Agent (agt K')" |
13508 | 42 |
|
43 |
lemma shop_chain [simp]: "shop (chain B ofr A L C) = Agent B" |
|
44 |
by (simp add: chain_def sign_def) |
|
45 |
||
61830 | 46 |
subsubsection\<open>nonce used in an offer\<close> |
13508 | 47 |
|
35418 | 48 |
fun nonce :: "msg => msg" where |
61956 | 49 |
"nonce \<lbrace>Crypt K \<lbrace>B,ofr,CryptH\<rbrace>,m2\<rbrace> = ofr" |
13508 | 50 |
|
51 |
lemma nonce_chain [simp]: "nonce (chain B ofr A L C) = Nonce ofr" |
|
52 |
by (simp add: chain_def sign_def) |
|
53 |
||
61830 | 54 |
subsubsection\<open>next shop\<close> |
13508 | 55 |
|
35418 | 56 |
fun next_shop :: "msg => agent" where |
61956 | 57 |
"next_shop \<lbrace>m1,Hash \<lbrace>headL,Agent C\<rbrace>\<rbrace> = C" |
13508 | 58 |
|
59 |
lemma "next_shop (chain B ofr A L C) = C" |
|
60 |
by (simp add: chain_def sign_def) |
|
61 |
||
61830 | 62 |
subsubsection\<open>anchor of the offer list\<close> |
13508 | 63 |
|
35416
d8d7d1b785af
replaced a couple of constsdefs by definitions (also some old primrecs by modern ones)
haftmann
parents:
23746
diff
changeset
|
64 |
definition anchor :: "agent => nat => agent => msg" where |
13508 | 65 |
"anchor A n B == chain A n A (cons nil nil) B" |
66 |
||
67 |
lemma anchor_inj [iff]: |
|
67613 | 68 |
"(anchor A n B = anchor A' n' B') = (A=A' \<and> n=n' \<and> B=B')" |
13508 | 69 |
by (auto simp: anchor_def) |
70 |
||
67613 | 71 |
lemma Nonce_in_anchor [iff]: "Nonce n \<in> parts {anchor A n B}" |
13508 | 72 |
by (auto simp: anchor_def) |
73 |
||
74 |
lemma shop_anchor [simp]: "shop (anchor A n B) = Agent A" |
|
75 |
by (simp add: anchor_def) |
|
76 |
||
61830 | 77 |
subsubsection\<open>request event\<close> |
13508 | 78 |
|
35416
d8d7d1b785af
replaced a couple of constsdefs by definitions (also some old primrecs by modern ones)
haftmann
parents:
23746
diff
changeset
|
79 |
definition reqm :: "agent => nat => nat => msg => agent => msg" where |
61956 | 80 |
"reqm A r n I B == \<lbrace>Agent A, Number r, cons (Agent A) (cons (Agent B) I), |
81 |
cons (anchor A n B) nil\<rbrace>" |
|
13508 | 82 |
|
83 |
lemma reqm_inj [iff]: "(reqm A r n I B = reqm A' r' n' I' B') |
|
84 |
= (A=A' & r=r' & n=n' & I=I' & B=B')" |
|
85 |
by (auto simp: reqm_def) |
|
86 |
||
67613 | 87 |
lemma Nonce_in_reqm [iff]: "Nonce n \<in> parts {reqm A r n I B}" |
13508 | 88 |
by (auto simp: reqm_def) |
89 |
||
35416
d8d7d1b785af
replaced a couple of constsdefs by definitions (also some old primrecs by modern ones)
haftmann
parents:
23746
diff
changeset
|
90 |
definition req :: "agent => nat => nat => msg => agent => event" where |
13508 | 91 |
"req A r n I B == Says A B (reqm A r n I B)" |
92 |
||
93 |
lemma req_inj [iff]: "(req A r n I B = req A' r' n' I' B') |
|
94 |
= (A=A' & r=r' & n=n' & I=I' & B=B')" |
|
95 |
by (auto simp: req_def) |
|
96 |
||
61830 | 97 |
subsubsection\<open>propose event\<close> |
13508 | 98 |
|
35416
d8d7d1b785af
replaced a couple of constsdefs by definitions (also some old primrecs by modern ones)
haftmann
parents:
23746
diff
changeset
|
99 |
definition prom :: "agent => nat => agent => nat => msg => msg => |
d8d7d1b785af
replaced a couple of constsdefs by definitions (also some old primrecs by modern ones)
haftmann
parents:
23746
diff
changeset
|
100 |
msg => agent => msg" where |
61956 | 101 |
"prom B ofr A r I L J C == \<lbrace>Agent A, Number r, |
102 |
app (J, del (Agent B, I)), cons (chain B ofr A L C) L\<rbrace>" |
|
13508 | 103 |
|
104 |
lemma prom_inj [dest]: "prom B ofr A r I L J C = prom B' ofr' A' r' I' L' J' C' |
|
105 |
==> B=B' & ofr=ofr' & A=A' & r=r' & L=L' & C=C'" |
|
106 |
by (auto simp: prom_def) |
|
107 |
||
67613 | 108 |
lemma Nonce_in_prom [iff]: "Nonce ofr \<in> parts {prom B ofr A r I L J C}" |
13508 | 109 |
by (auto simp: prom_def) |
110 |
||
35416
d8d7d1b785af
replaced a couple of constsdefs by definitions (also some old primrecs by modern ones)
haftmann
parents:
23746
diff
changeset
|
111 |
definition pro :: "agent => nat => agent => nat => msg => msg => |
d8d7d1b785af
replaced a couple of constsdefs by definitions (also some old primrecs by modern ones)
haftmann
parents:
23746
diff
changeset
|
112 |
msg => agent => event" where |
13508 | 113 |
"pro B ofr A r I L J C == Says B C (prom B ofr A r I L J C)" |
114 |
||
115 |
lemma pro_inj [dest]: "pro B ofr A r I L J C = pro B' ofr' A' r' I' L' J' C' |
|
116 |
==> B=B' & ofr=ofr' & A=A' & r=r' & L=L' & C=C'" |
|
117 |
by (auto simp: pro_def dest: prom_inj) |
|
118 |
||
61830 | 119 |
subsubsection\<open>protocol\<close> |
13508 | 120 |
|
23746 | 121 |
inductive_set p2 :: "event list set" |
122 |
where |
|
13508 | 123 |
|
67613 | 124 |
Nil: "[] \<in> p2" |
13508 | 125 |
|
67613 | 126 |
| Fake: "[| evsf \<in> p2; X \<in> synth (analz (spies evsf)) |] ==> Says Spy B X # evsf \<in> p2" |
13508 | 127 |
|
67613 | 128 |
| Request: "[| evsr \<in> p2; Nonce n \<notin> used evsr; I \<in> agl |] ==> req A r n I B # evsr \<in> p2" |
13508 | 129 |
|
67613 | 130 |
| Propose: "[| evsp \<in> p2; Says A' B \<lbrace>Agent A,Number r,I,cons M L\<rbrace> \<in> set evsp; |
131 |
I \<in> agl; J \<in> agl; isin (Agent C, app (J, del (Agent B, I))); |
|
132 |
Nonce ofr \<notin> used evsp |] ==> pro B ofr A r I (cons M L) J C # evsp \<in> p2" |
|
13508 | 133 |
|
61830 | 134 |
subsubsection\<open>valid offer lists\<close> |
13508 | 135 |
|
23746 | 136 |
inductive_set |
67613 | 137 |
valid :: "agent \<Rightarrow> nat \<Rightarrow> agent \<Rightarrow> msg set" |
23746 | 138 |
for A :: agent and n :: nat and B :: agent |
139 |
where |
|
67613 | 140 |
Request [intro]: "cons (anchor A n B) nil \<in> valid A n B" |
13508 | 141 |
|
67613 | 142 |
| Propose [intro]: "L \<in> valid A n B |
143 |
\<Longrightarrow> cons (chain (next_shop (head L)) ofr A L C) L \<in> valid A n B" |
|
13508 | 144 |
|
61830 | 145 |
subsubsection\<open>basic properties of valid\<close> |
13508 | 146 |
|
67613 | 147 |
lemma valid_not_empty: "L \<in> valid A n B \<Longrightarrow> \<exists>M L'. L = cons M L'" |
13508 | 148 |
by (erule valid.cases, auto) |
149 |
||
67613 | 150 |
lemma valid_pos_len: "L \<in> valid A n B \<Longrightarrow> 0 < len L" |
13508 | 151 |
by (erule valid.induct, auto) |
152 |
||
61830 | 153 |
subsubsection\<open>list of offers\<close> |
13508 | 154 |
|
67613 | 155 |
fun offers :: "msg \<Rightarrow> msg" |
35418 | 156 |
where |
61956 | 157 |
"offers (cons M L) = cons \<lbrace>shop M, nonce M\<rbrace> (offers L)" |
35418 | 158 |
| "offers other = nil" |
13508 | 159 |
|
160 |
||
61830 | 161 |
subsection\<open>Properties of Protocol P2\<close> |
13508 | 162 |
|
61830 | 163 |
text\<open>same as \<open>P1_Prop\<close> except that publicly verifiable forward |
164 |
integrity is replaced by forward privacy\<close> |
|
13508 | 165 |
|
61830 | 166 |
subsection\<open>strong forward integrity: |
167 |
except the last one, no offer can be modified\<close> |
|
13508 | 168 |
|
67613 | 169 |
lemma strong_forward_integrity: "\<forall>L. Suc i < len L |
170 |
\<longrightarrow> L \<in> valid A n B \<longrightarrow> repl (L,Suc i,M) \<in> valid A n B \<longrightarrow> M = ith (L,Suc i)" |
|
13508 | 171 |
apply (induct i) |
172 |
(* i = 0 *) |
|
173 |
apply clarify |
|
174 |
apply (frule len_not_empty, clarsimp) |
|
175 |
apply (frule len_not_empty, clarsimp) |
|
67613 | 176 |
apply (ind_cases "\<lbrace>x,xa,l'a\<rbrace> \<in> valid A n B" for x xa l'a) |
177 |
apply (ind_cases "\<lbrace>x,M,l'a\<rbrace> \<in> valid A n B" for x l'a) |
|
13508 | 178 |
apply (simp add: chain_def) |
179 |
(* i > 0 *) |
|
180 |
apply clarify |
|
181 |
apply (frule len_not_empty, clarsimp) |
|
67613 | 182 |
apply (ind_cases "\<lbrace>x,repl(l',Suc na,M)\<rbrace> \<in> valid A n B" for x l' na) |
13508 | 183 |
apply (frule len_not_empty, clarsimp) |
67613 | 184 |
apply (ind_cases "\<lbrace>x,l'\<rbrace> \<in> valid A n B" for x l') |
13508 | 185 |
by (drule_tac x=l' in spec, simp, blast) |
186 |
||
61830 | 187 |
subsection\<open>insertion resilience: |
188 |
except at the beginning, no offer can be inserted\<close> |
|
13508 | 189 |
|
67613 | 190 |
lemma chain_isnt_head [simp]: "L \<in> valid A n B \<Longrightarrow> |
191 |
head L \<noteq> chain (next_shop (head L)) ofr A L C" |
|
13508 | 192 |
by (erule valid.induct, auto simp: chain_def sign_def anchor_def) |
193 |
||
67613 | 194 |
lemma insertion_resilience: "\<forall>L. L \<in> valid A n B \<longrightarrow> Suc i < len L |
195 |
\<longrightarrow> ins (L,Suc i,M) \<notin> valid A n B" |
|
13508 | 196 |
apply (induct i) |
197 |
(* i = 0 *) |
|
198 |
apply clarify |
|
199 |
apply (frule len_not_empty, clarsimp) |
|
67613 | 200 |
apply (ind_cases "\<lbrace>x,l'\<rbrace> \<in> valid A n B" for x l', simp) |
201 |
apply (ind_cases "\<lbrace>x,M,l'\<rbrace> \<in> valid A n B" for x l', clarsimp) |
|
202 |
apply (ind_cases "\<lbrace>head l',l'\<rbrace> \<in> valid A n B" for l', simp, simp) |
|
13508 | 203 |
(* i > 0 *) |
204 |
apply clarify |
|
205 |
apply (frule len_not_empty, clarsimp) |
|
67613 | 206 |
apply (ind_cases "\<lbrace>x,l'\<rbrace> \<in> valid A n B" for x l') |
13508 | 207 |
apply (frule len_not_empty, clarsimp) |
67613 | 208 |
apply (ind_cases "\<lbrace>x,ins(l',Suc na,M)\<rbrace> \<in> valid A n B" for x l' na) |
13508 | 209 |
apply (frule len_not_empty, clarsimp) |
210 |
by (drule_tac x=l' in spec, clarsimp) |
|
211 |
||
61830 | 212 |
subsection\<open>truncation resilience: |
213 |
only shop i can truncate at offer i\<close> |
|
13508 | 214 |
|
67613 | 215 |
lemma truncation_resilience: "\<forall>L. L \<in> valid A n B \<longrightarrow> Suc i < len L |
216 |
\<longrightarrow> cons M (trunc (L,Suc i)) \<in> valid A n B \<longrightarrow> shop M = shop (ith (L,i))" |
|
13508 | 217 |
apply (induct i) |
218 |
(* i = 0 *) |
|
219 |
apply clarify |
|
220 |
apply (frule len_not_empty, clarsimp) |
|
67613 | 221 |
apply (ind_cases "\<lbrace>x,l'\<rbrace> \<in> valid A n B" for x l') |
13508 | 222 |
apply (frule len_not_empty, clarsimp) |
67613 | 223 |
apply (ind_cases "\<lbrace>M,l'\<rbrace> \<in> valid A n B" for l') |
13508 | 224 |
apply (frule len_not_empty, clarsimp, simp) |
225 |
(* i > 0 *) |
|
226 |
apply clarify |
|
227 |
apply (frule len_not_empty, clarsimp) |
|
67613 | 228 |
apply (ind_cases "\<lbrace>x,l'\<rbrace> \<in> valid A n B" for x l') |
13508 | 229 |
apply (frule len_not_empty, clarsimp) |
230 |
by (drule_tac x=l' in spec, clarsimp) |
|
231 |
||
61830 | 232 |
subsection\<open>declarations for tactics\<close> |
13508 | 233 |
|
234 |
declare knows_Spy_partsEs [elim] |
|
235 |
declare Fake_parts_insert [THEN subsetD, dest] |
|
236 |
declare initState.simps [simp del] |
|
237 |
||
61830 | 238 |
subsection\<open>get components of a message\<close> |
13508 | 239 |
|
67613 | 240 |
lemma get_ML [dest]: "Says A' B \<lbrace>A,R,I,M,L\<rbrace> \<in> set evs \<Longrightarrow> |
241 |
M \<in> parts (spies evs) \<and> L \<in> parts (spies evs)" |
|
13508 | 242 |
by blast |
243 |
||
61830 | 244 |
subsection\<open>general properties of p2\<close> |
13508 | 245 |
|
246 |
lemma reqm_neq_prom [iff]: |
|
67613 | 247 |
"reqm A r n I B \<noteq> prom B' ofr A' r' I' (cons M L) J C" |
13508 | 248 |
by (auto simp: reqm_def prom_def) |
249 |
||
250 |
lemma prom_neq_reqm [iff]: |
|
67613 | 251 |
"prom B' ofr A' r' I' (cons M L) J C \<noteq> reqm A r n I B" |
13508 | 252 |
by (auto simp: reqm_def prom_def) |
253 |
||
67613 | 254 |
lemma req_neq_pro [iff]: "req A r n I B \<noteq> pro B' ofr A' r' I' (cons M L) J C" |
13508 | 255 |
by (auto simp: req_def pro_def) |
256 |
||
67613 | 257 |
lemma pro_neq_req [iff]: "pro B' ofr A' r' I' (cons M L) J C \<noteq> req A r n I B" |
13508 | 258 |
by (auto simp: req_def pro_def) |
259 |
||
67613 | 260 |
lemma p2_has_no_Gets: "evs \<in> p2 \<Longrightarrow> \<forall>A X. Gets A X \<notin> set evs" |
13508 | 261 |
by (erule p2.induct, auto simp: req_def pro_def) |
262 |
||
263 |
lemma p2_is_Gets_correct [iff]: "Gets_correct p2" |
|
264 |
by (auto simp: Gets_correct_def dest: p2_has_no_Gets) |
|
265 |
||
266 |
lemma p2_is_one_step [iff]: "one_step p2" |
|
67613 | 267 |
by (unfold one_step_def, clarify, ind_cases "ev#evs \<in> p2" for ev evs, auto) |
13508 | 268 |
|
67613 | 269 |
lemma p2_has_only_Says' [rule_format]: "evs \<in> p2 \<Longrightarrow> |
270 |
ev \<in> set evs \<longrightarrow> (\<exists>A B X. ev=Says A B X)" |
|
13508 | 271 |
by (erule p2.induct, auto simp: req_def pro_def) |
272 |
||
273 |
lemma p2_has_only_Says [iff]: "has_only_Says p2" |
|
274 |
by (auto simp: has_only_Says_def dest: p2_has_only_Says') |
|
275 |
||
276 |
lemma p2_is_regular [iff]: "regular p2" |
|
277 |
apply (simp only: regular_def, clarify) |
|
278 |
apply (erule_tac p2.induct) |
|
279 |
apply (simp_all add: initState.simps knows.simps pro_def prom_def |
|
280 |
req_def reqm_def anchor_def chain_def sign_def) |
|
281 |
by (auto dest: no_Key_in_agl no_Key_in_appdel parts_trans) |
|
282 |
||
61830 | 283 |
subsection\<open>private keys are safe\<close> |
13508 | 284 |
|
285 |
lemma priK_parts_Friend_imp_bad [rule_format,dest]: |
|
67613 | 286 |
"[| evs \<in> p2; Friend B \<noteq> A |] |
287 |
==> (Key (priK A) \<in> parts (knows (Friend B) evs)) \<longrightarrow> (A \<in> bad)" |
|
13508 | 288 |
apply (erule p2.induct) |
289 |
apply (simp_all add: initState.simps knows.simps pro_def prom_def |
|
17778 | 290 |
req_def reqm_def anchor_def chain_def sign_def) |
13508 | 291 |
apply (blast dest: no_Key_in_agl) |
292 |
apply (auto del: parts_invKey disjE dest: parts_trans |
|
293 |
simp add: no_Key_in_appdel) |
|
294 |
done |
|
295 |
||
296 |
lemma priK_analz_Friend_imp_bad [rule_format,dest]: |
|
67613 | 297 |
"[| evs \<in> p2; Friend B \<noteq> A |] |
298 |
==> (Key (priK A) \<in> analz (knows (Friend B) evs)) \<longrightarrow> (A \<in> bad)" |
|
13508 | 299 |
by auto |
300 |
||
301 |
lemma priK_notin_knows_max_Friend: |
|
67613 | 302 |
"[| evs \<in> p2; A \<notin> bad; A \<noteq> Friend C |] |
303 |
==> Key (priK A) \<notin> analz (knows_max (Friend C) evs)" |
|
13508 | 304 |
apply (rule not_parts_not_analz, simp add: knows_max_def, safe) |
305 |
apply (drule_tac H="spies' evs" in parts_sub) |
|
306 |
apply (rule_tac p=p2 in knows_max'_sub_spies', simp+) |
|
307 |
apply (drule_tac H="spies evs" in parts_sub) |
|
308 |
by (auto dest: knows'_sub_knows [THEN subsetD] priK_notin_initState_Friend) |
|
309 |
||
61830 | 310 |
subsection\<open>general guardedness properties\<close> |
13508 | 311 |
|
67613 | 312 |
lemma agl_guard [intro]: "I \<in> agl \<Longrightarrow> I \<in> guard n Ks" |
13508 | 313 |
by (erule agl.induct, auto) |
314 |
||
67613 | 315 |
lemma Says_to_knows_max'_guard: "[| Says A' C \<lbrace>A'',r,I,L\<rbrace> \<in> set evs; |
316 |
Guard n Ks (knows_max' C evs) |] ==> L \<in> guard n Ks" |
|
13508 | 317 |
by (auto dest: Says_to_knows_max') |
318 |
||
67613 | 319 |
lemma Says_from_knows_max'_guard: "[| Says C A' \<lbrace>A'',r,I,L\<rbrace> \<in> set evs; |
320 |
Guard n Ks (knows_max' C evs) |] ==> L \<in> guard n Ks" |
|
13508 | 321 |
by (auto dest: Says_from_knows_max') |
322 |
||
67613 | 323 |
lemma Says_Nonce_not_used_guard: "[| Says A' B \<lbrace>A'',r,I,L\<rbrace> \<in> set evs; |
324 |
Nonce n \<notin> used evs |] ==> L \<in> guard n Ks" |
|
13508 | 325 |
by (drule not_used_not_parts, auto) |
326 |
||
61830 | 327 |
subsection\<open>guardedness of messages\<close> |
13508 | 328 |
|
67613 | 329 |
lemma chain_guard [iff]: "chain B ofr A L C \<in> guard n {priK A}" |
13508 | 330 |
by (case_tac "ofr=n", auto simp: chain_def sign_def) |
331 |
||
67613 | 332 |
lemma chain_guard_Nonce_neq [intro]: "n \<noteq> ofr |
333 |
\<Longrightarrow> chain B ofr A' L C \<in> guard n {priK A}" |
|
13508 | 334 |
by (auto simp: chain_def sign_def) |
335 |
||
67613 | 336 |
lemma anchor_guard [iff]: "anchor A n' B \<in> guard n {priK A}" |
13508 | 337 |
by (case_tac "n'=n", auto simp: anchor_def) |
338 |
||
67613 | 339 |
lemma anchor_guard_Nonce_neq [intro]: "n \<noteq> n' |
340 |
\<Longrightarrow> anchor A' n' B \<in> guard n {priK A}" |
|
13508 | 341 |
by (auto simp: anchor_def) |
342 |
||
67613 | 343 |
lemma reqm_guard [intro]: "I \<in> agl \<Longrightarrow> reqm A r n' I B \<in> guard n {priK A}" |
13508 | 344 |
by (case_tac "n'=n", auto simp: reqm_def) |
345 |
||
67613 | 346 |
lemma reqm_guard_Nonce_neq [intro]: "[| n \<noteq> n'; I \<in> agl |] |
347 |
==> reqm A' r n' I B \<in> guard n {priK A}" |
|
13508 | 348 |
by (auto simp: reqm_def) |
349 |
||
67613 | 350 |
lemma prom_guard [intro]: "[| I \<in> agl; J \<in> agl; L \<in> guard n {priK A} |] |
351 |
==> prom B ofr A r I L J C \<in> guard n {priK A}" |
|
13508 | 352 |
by (auto simp: prom_def) |
353 |
||
67613 | 354 |
lemma prom_guard_Nonce_neq [intro]: "[| n \<noteq> ofr; I \<in> agl; J \<in> agl; |
355 |
L \<in> guard n {priK A} |] ==> prom B ofr A' r I L J C \<in> guard n {priK A}" |
|
13508 | 356 |
by (auto simp: prom_def) |
357 |
||
61830 | 358 |
subsection\<open>Nonce uniqueness\<close> |
13508 | 359 |
|
67613 | 360 |
lemma uniq_Nonce_in_chain [dest]: "Nonce k \<in> parts {chain B ofr A L C} \<Longrightarrow> k=ofr" |
13508 | 361 |
by (auto simp: chain_def sign_def) |
362 |
||
67613 | 363 |
lemma uniq_Nonce_in_anchor [dest]: "Nonce k \<in> parts {anchor A n B} \<Longrightarrow> k=n" |
13508 | 364 |
by (auto simp: anchor_def chain_def sign_def) |
365 |
||
67613 | 366 |
lemma uniq_Nonce_in_reqm [dest]: "[| Nonce k \<in> parts {reqm A r n I B}; |
367 |
I \<in> agl |] ==> k=n" |
|
13508 | 368 |
by (auto simp: reqm_def dest: no_Nonce_in_agl) |
369 |
||
67613 | 370 |
lemma uniq_Nonce_in_prom [dest]: "[| Nonce k \<in> parts {prom B ofr A r I L J C}; |
371 |
I \<in> agl; J \<in> agl; Nonce k \<notin> parts {L} |] ==> k=ofr" |
|
13508 | 372 |
by (auto simp: prom_def dest: no_Nonce_in_agl no_Nonce_in_appdel) |
373 |
||
61830 | 374 |
subsection\<open>requests are guarded\<close> |
13508 | 375 |
|
67613 | 376 |
lemma req_imp_Guard [rule_format]: "[| evs \<in> p2; A \<notin> bad |] ==> |
377 |
req A r n I B \<in> set evs \<longrightarrow> Guard n {priK A} (spies evs)" |
|
13508 | 378 |
apply (erule p2.induct, simp) |
379 |
apply (simp add: req_def knows.simps, safe) |
|
380 |
apply (erule in_synth_Guard, erule Guard_analz, simp) |
|
381 |
by (auto simp: req_def pro_def dest: Says_imp_knows_Spy) |
|
382 |
||
67613 | 383 |
lemma req_imp_Guard_Friend: "[| evs \<in> p2; A \<notin> bad; req A r n I B \<in> set evs |] |
13508 | 384 |
==> Guard n {priK A} (knows_max (Friend C) evs)" |
385 |
apply (rule Guard_knows_max') |
|
386 |
apply (rule_tac H="spies evs" in Guard_mono) |
|
387 |
apply (rule req_imp_Guard, simp+) |
|
388 |
apply (rule_tac B="spies' evs" in subset_trans) |
|
389 |
apply (rule_tac p=p2 in knows_max'_sub_spies', simp+) |
|
390 |
by (rule knows'_sub_knows) |
|
391 |
||
61830 | 392 |
subsection\<open>propositions are guarded\<close> |
13508 | 393 |
|
67613 | 394 |
lemma pro_imp_Guard [rule_format]: "[| evs \<in> p2; B \<notin> bad; A \<notin> bad |] ==> |
395 |
pro B ofr A r I (cons M L) J C \<in> set evs \<longrightarrow> Guard ofr {priK A} (spies evs)" |
|
13508 | 396 |
apply (erule p2.induct) (* +3 subgoals *) |
397 |
(* Nil *) |
|
398 |
apply simp |
|
399 |
(* Fake *) |
|
400 |
apply (simp add: pro_def, safe) (* +4 subgoals *) |
|
401 |
(* 1 *) |
|
402 |
apply (erule in_synth_Guard, drule Guard_analz, simp, simp) |
|
403 |
(* 2 *) |
|
404 |
apply simp |
|
405 |
(* 3 *) |
|
406 |
apply (simp, simp add: req_def pro_def, blast) |
|
407 |
(* 4 *) |
|
408 |
apply (simp add: pro_def) |
|
409 |
apply (blast dest: prom_inj Says_Nonce_not_used_guard Nonce_not_used_Guard) |
|
410 |
(* 5 *) |
|
411 |
apply simp |
|
412 |
apply safe (* +1 subgoal *) |
|
413 |
apply (simp add: pro_def) |
|
414 |
apply (blast dest: prom_inj Says_Nonce_not_used_guard) |
|
415 |
(* 6 *) |
|
416 |
apply (simp add: pro_def) |
|
417 |
apply (blast dest: Says_imp_knows_Spy) |
|
418 |
(* Request *) |
|
419 |
apply (simp add: pro_def) |
|
420 |
apply (blast dest: prom_inj Says_Nonce_not_used_guard Nonce_not_used_Guard) |
|
421 |
(* Propose *) |
|
422 |
apply simp |
|
423 |
apply safe (* +1 subgoal *) |
|
424 |
(* 1 *) |
|
425 |
apply (simp add: pro_def) |
|
426 |
apply (blast dest: prom_inj Says_Nonce_not_used_guard) |
|
427 |
(* 2 *) |
|
428 |
apply (simp add: pro_def) |
|
429 |
by (blast dest: Says_imp_knows_Spy) |
|
430 |
||
67613 | 431 |
lemma pro_imp_Guard_Friend: "[| evs \<in> p2; B \<notin> bad; A \<notin> bad; |
432 |
pro B ofr A r I (cons M L) J C \<in> set evs |] |
|
13508 | 433 |
==> Guard ofr {priK A} (knows_max (Friend D) evs)" |
434 |
apply (rule Guard_knows_max') |
|
435 |
apply (rule_tac H="spies evs" in Guard_mono) |
|
436 |
apply (rule pro_imp_Guard, simp+) |
|
437 |
apply (rule_tac B="spies' evs" in subset_trans) |
|
438 |
apply (rule_tac p=p2 in knows_max'_sub_spies', simp+) |
|
439 |
by (rule knows'_sub_knows) |
|
440 |
||
61830 | 441 |
subsection\<open>data confidentiality: |
442 |
no one other than the originator can decrypt the offers\<close> |
|
13508 | 443 |
|
67613 | 444 |
lemma Nonce_req_notin_spies: "[| evs \<in> p2; req A r n I B \<in> set evs; A \<notin> bad |] |
445 |
==> Nonce n \<notin> analz (spies evs)" |
|
13508 | 446 |
by (frule req_imp_Guard, simp+, erule Guard_Nonce_analz, simp+) |
447 |
||
67613 | 448 |
lemma Nonce_req_notin_knows_max_Friend: "[| evs \<in> p2; req A r n I B \<in> set evs; |
449 |
A \<notin> bad; A \<noteq> Friend C |] ==> Nonce n \<notin> analz (knows_max (Friend C) evs)" |
|
13508 | 450 |
apply (clarify, frule_tac C=C in req_imp_Guard_Friend, simp+) |
451 |
apply (simp add: knows_max_def, drule Guard_invKey_keyset, simp+) |
|
452 |
by (drule priK_notin_knows_max_Friend, auto simp: knows_max_def) |
|
453 |
||
67613 | 454 |
lemma Nonce_pro_notin_spies: "[| evs \<in> p2; B \<notin> bad; A \<notin> bad; |
455 |
pro B ofr A r I (cons M L) J C \<in> set evs |] ==> Nonce ofr \<notin> analz (spies evs)" |
|
13508 | 456 |
by (frule pro_imp_Guard, simp+, erule Guard_Nonce_analz, simp+) |
457 |
||
67613 | 458 |
lemma Nonce_pro_notin_knows_max_Friend: "[| evs \<in> p2; B \<notin> bad; A \<notin> bad; |
459 |
A \<noteq> Friend D; pro B ofr A r I (cons M L) J C \<in> set evs |] |
|
460 |
==> Nonce ofr \<notin> analz (knows_max (Friend D) evs)" |
|
13508 | 461 |
apply (clarify, frule_tac A=A in pro_imp_Guard_Friend, simp+) |
462 |
apply (simp add: knows_max_def, drule Guard_invKey_keyset, simp+) |
|
463 |
by (drule priK_notin_knows_max_Friend, auto simp: knows_max_def) |
|
464 |
||
61830 | 465 |
subsection\<open>forward privacy: |
466 |
only the originator can know the identity of the shops\<close> |
|
13508 | 467 |
|
67613 | 468 |
lemma forward_privacy_Spy: "[| evs \<in> p2; B \<notin> bad; A \<notin> bad; |
469 |
pro B ofr A r I (cons M L) J C \<in> set evs |] |
|
470 |
==> sign B (Nonce ofr) \<notin> analz (spies evs)" |
|
13508 | 471 |
by (auto simp:sign_def dest: Nonce_pro_notin_spies) |
472 |
||
67613 | 473 |
lemma forward_privacy_Friend: "[| evs \<in> p2; B \<notin> bad; A \<notin> bad; A \<noteq> Friend D; |
474 |
pro B ofr A r I (cons M L) J C \<in> set evs |] |
|
475 |
==> sign B (Nonce ofr) \<notin> analz (knows_max (Friend D) evs)" |
|
13508 | 476 |
by (auto simp:sign_def dest:Nonce_pro_notin_knows_max_Friend ) |
477 |
||
61830 | 478 |
subsection\<open>non repudiability: an offer signed by B has been sent by B\<close> |
13508 | 479 |
|
67613 | 480 |
lemma Crypt_reqm: "[| Crypt (priK A) X \<in> parts {reqm A' r n I B}; I \<in> agl |] ==> A=A'" |
13508 | 481 |
by (auto simp: reqm_def anchor_def chain_def sign_def dest: no_Crypt_in_agl) |
482 |
||
67613 | 483 |
lemma Crypt_prom: "[| Crypt (priK A) X \<in> parts {prom B ofr A' r I L J C}; |
484 |
I \<in> agl; J \<in> agl |] ==> A=B | Crypt (priK A) X \<in> parts {L}" |
|
13508 | 485 |
apply (simp add: prom_def anchor_def chain_def sign_def) |
486 |
by (blast dest: no_Crypt_in_agl no_Crypt_in_appdel) |
|
487 |
||
67613 | 488 |
lemma Crypt_safeness: "[| evs \<in> p2; A \<notin> bad |] ==> Crypt (priK A) X \<in> parts (spies evs) |
489 |
\<longrightarrow> (\<exists>B Y. Says A B Y \<in> set evs & Crypt (priK A) X \<in> parts {Y})" |
|
13508 | 490 |
apply (erule p2.induct) |
491 |
(* Nil *) |
|
492 |
apply simp |
|
493 |
(* Fake *) |
|
494 |
apply clarsimp |
|
67613 | 495 |
apply (drule_tac P="\<lambda>G. Crypt (priK A) X \<in> G" in parts_insert_substD, simp) |
13508 | 496 |
apply (erule disjE) |
497 |
apply (drule_tac K="priK A" in Crypt_synth, simp+, blast, blast) |
|
498 |
(* Request *) |
|
499 |
apply (simp add: req_def, clarify) |
|
67613 | 500 |
apply (drule_tac P="\<lambda>G. Crypt (priK A) X \<in> G" in parts_insert_substD, simp) |
13508 | 501 |
apply (erule disjE) |
502 |
apply (frule Crypt_reqm, simp, clarify) |
|
503 |
apply (rule_tac x=B in exI, rule_tac x="reqm A r n I B" in exI, simp, blast) |
|
504 |
(* Propose *) |
|
505 |
apply (simp add: pro_def, clarify) |
|
67613 | 506 |
apply (drule_tac P="\<lambda>G. Crypt (priK A) X \<in> G" in parts_insert_substD, simp) |
13508 | 507 |
apply (rotate_tac -1, erule disjE) |
508 |
apply (frule Crypt_prom, simp, simp) |
|
509 |
apply (rotate_tac -1, erule disjE) |
|
510 |
apply (rule_tac x=C in exI) |
|
511 |
apply (rule_tac x="prom B ofr Aa r I (cons M L) J C" in exI, blast) |
|
67613 | 512 |
apply (subgoal_tac "cons M L \<in> parts (spies evsp)") |
13508 | 513 |
apply (drule_tac G="{cons M L}" and H="spies evsp" in parts_trans, blast, blast) |
514 |
apply (drule Says_imp_spies, rotate_tac -1, drule parts.Inj) |
|
515 |
apply (drule parts.Snd, drule parts.Snd, drule parts.Snd) |
|
516 |
by auto |
|
517 |
||
67613 | 518 |
lemma Crypt_Hash_imp_sign: "[| evs \<in> p2; A \<notin> bad |] ==> |
519 |
Crypt (priK A) (Hash X) \<in> parts (spies evs) |
|
520 |
\<longrightarrow> (\<exists>B Y. Says A B Y \<in> set evs \<and> sign A X \<in> parts {Y})" |
|
13508 | 521 |
apply (erule p2.induct) |
522 |
(* Nil *) |
|
523 |
apply simp |
|
524 |
(* Fake *) |
|
525 |
apply clarsimp |
|
67613 | 526 |
apply (drule_tac P="\<lambda>G. Crypt (priK A) (Hash X) \<in> G" in parts_insert_substD) |
13508 | 527 |
apply simp |
528 |
apply (erule disjE) |
|
529 |
apply (drule_tac K="priK A" in Crypt_synth, simp+, blast, blast) |
|
530 |
(* Request *) |
|
531 |
apply (simp add: req_def, clarify) |
|
67613 | 532 |
apply (drule_tac P="\<lambda>G. Crypt (priK A) (Hash X) \<in> G" in parts_insert_substD) |
13508 | 533 |
apply simp |
534 |
apply (erule disjE) |
|
535 |
apply (frule Crypt_reqm, simp+) |
|
536 |
apply (rule_tac x=B in exI, rule_tac x="reqm Aa r n I B" in exI) |
|
537 |
apply (simp add: reqm_def sign_def anchor_def no_Crypt_in_agl) |
|
538 |
apply (simp add: chain_def sign_def, blast) |
|
539 |
(* Propose *) |
|
540 |
apply (simp add: pro_def, clarify) |
|
67613 | 541 |
apply (drule_tac P="\<lambda>G. Crypt (priK A) (Hash X) \<in> G" in parts_insert_substD) |
13508 | 542 |
apply simp |
543 |
apply (rotate_tac -1, erule disjE) |
|
544 |
apply (simp add: prom_def sign_def no_Crypt_in_agl no_Crypt_in_appdel) |
|
545 |
apply (simp add: chain_def sign_def) |
|
546 |
apply (rotate_tac -1, erule disjE) |
|
547 |
apply (rule_tac x=C in exI) |
|
548 |
apply (rule_tac x="prom B ofr Aa r I (cons M L) J C" in exI) |
|
549 |
apply (simp add: prom_def chain_def sign_def) |
|
550 |
apply (erule impE) |
|
551 |
apply (blast dest: get_ML parts_sub) |
|
552 |
apply (blast del: MPair_parts)+ |
|
553 |
done |
|
554 |
||
67613 | 555 |
lemma sign_safeness: "[| evs \<in> p2; A \<notin> bad |] ==> sign A X \<in> parts (spies evs) |
556 |
\<longrightarrow> (\<exists>B Y. Says A B Y \<in> set evs \<and> sign A X \<in> parts {Y})" |
|
13508 | 557 |
apply (clarify, simp add: sign_def, frule parts.Snd) |
558 |
apply (blast dest: Crypt_Hash_imp_sign [unfolded sign_def]) |
|
559 |
done |
|
560 |
||
62390 | 561 |
end |