1 (* Title: HOL/Auth/Guard/Extensions.thy |
1 (* Title: HOL/Auth/Guard/Extensions.thy |
2 Author: Frederic Blanqui, University of Cambridge Computer Laboratory |
2 Author: Frederic Blanqui, University of Cambridge Computer Laboratory |
3 Copyright 2001 University of Cambridge |
3 Copyright 2001 University of Cambridge |
4 *) |
4 *) |
5 |
5 |
6 section {*Extensions to Standard Theories*} |
6 section \<open>Extensions to Standard Theories\<close> |
7 |
7 |
8 theory Extensions |
8 theory Extensions |
9 imports "../Event" |
9 imports "../Event" |
10 begin |
10 begin |
11 |
11 |
12 subsection{*Extensions to Theory @{text Set}*} |
12 subsection\<open>Extensions to Theory \<open>Set\<close>\<close> |
13 |
13 |
14 lemma eq: "[| !!x. x:A ==> x:B; !!x. x:B ==> x:A |] ==> A=B" |
14 lemma eq: "[| !!x. x:A ==> x:B; !!x. x:B ==> x:A |] ==> A=B" |
15 by auto |
15 by auto |
16 |
16 |
17 lemma insert_Un: "P ({x} Un A) ==> P (insert x A)" |
17 lemma insert_Un: "P ({x} Un A) ==> P (insert x A)" |
19 |
19 |
20 lemma in_sub: "x:A ==> {x}<=A" |
20 lemma in_sub: "x:A ==> {x}<=A" |
21 by auto |
21 by auto |
22 |
22 |
23 |
23 |
24 subsection{*Extensions to Theory @{text List}*} |
24 subsection\<open>Extensions to Theory \<open>List\<close>\<close> |
25 |
25 |
26 subsubsection{*"remove l x" erase the first element of "l" equal to "x"*} |
26 subsubsection\<open>"remove l x" erase the first element of "l" equal to "x"\<close> |
27 |
27 |
28 primrec remove :: "'a list => 'a => 'a list" where |
28 primrec remove :: "'a list => 'a => 'a list" where |
29 "remove [] y = []" | |
29 "remove [] y = []" | |
30 "remove (x#xs) y = (if x=y then xs else x # remove xs y)" |
30 "remove (x#xs) y = (if x=y then xs else x # remove xs y)" |
31 |
31 |
32 lemma set_remove: "set (remove l x) <= set l" |
32 lemma set_remove: "set (remove l x) <= set l" |
33 by (induct l, auto) |
33 by (induct l, auto) |
34 |
34 |
35 subsection{*Extensions to Theory @{text Message}*} |
35 subsection\<open>Extensions to Theory \<open>Message\<close>\<close> |
36 |
36 |
37 subsubsection{*declarations for tactics*} |
37 subsubsection\<open>declarations for tactics\<close> |
38 |
38 |
39 declare analz_subset_parts [THEN subsetD, dest] |
39 declare analz_subset_parts [THEN subsetD, dest] |
40 declare parts_insert2 [simp] |
40 declare parts_insert2 [simp] |
41 declare analz_cut [dest] |
41 declare analz_cut [dest] |
42 declare split_if_asm [split] |
42 declare split_if_asm [split] |
43 declare analz_insertI [intro] |
43 declare analz_insertI [intro] |
44 declare Un_Diff [simp] |
44 declare Un_Diff [simp] |
45 |
45 |
46 subsubsection{*extract the agent number of an Agent message*} |
46 subsubsection\<open>extract the agent number of an Agent message\<close> |
47 |
47 |
48 primrec agt_nb :: "msg => agent" where |
48 primrec agt_nb :: "msg => agent" where |
49 "agt_nb (Agent A) = A" |
49 "agt_nb (Agent A) = A" |
50 |
50 |
51 subsubsection{*messages that are pairs*} |
51 subsubsection\<open>messages that are pairs\<close> |
52 |
52 |
53 definition is_MPair :: "msg => bool" where |
53 definition is_MPair :: "msg => bool" where |
54 "is_MPair X == EX Y Z. X = {|Y,Z|}" |
54 "is_MPair X == EX Y Z. X = {|Y,Z|}" |
55 |
55 |
56 declare is_MPair_def [simp] |
56 declare is_MPair_def [simp] |
88 definition has_no_pair :: "msg set => bool" where |
88 definition has_no_pair :: "msg set => bool" where |
89 "has_no_pair H == ALL X Y. {|X,Y|} ~:H" |
89 "has_no_pair H == ALL X Y. {|X,Y|} ~:H" |
90 |
90 |
91 declare has_no_pair_def [simp] |
91 declare has_no_pair_def [simp] |
92 |
92 |
93 subsubsection{*well-foundedness of messages*} |
93 subsubsection\<open>well-foundedness of messages\<close> |
94 |
94 |
95 lemma wf_Crypt1 [iff]: "Crypt K X ~= X" |
95 lemma wf_Crypt1 [iff]: "Crypt K X ~= X" |
96 by (induct X, auto) |
96 by (induct X, auto) |
97 |
97 |
98 lemma wf_Crypt2 [iff]: "X ~= Crypt K X" |
98 lemma wf_Crypt2 [iff]: "X ~= Crypt K X" |
102 by (erule parts.induct, auto) |
102 by (erule parts.induct, auto) |
103 |
103 |
104 lemma wf_Crypt_parts [iff]: "Crypt K X ~:parts {X}" |
104 lemma wf_Crypt_parts [iff]: "Crypt K X ~:parts {X}" |
105 by (auto dest: parts_size) |
105 by (auto dest: parts_size) |
106 |
106 |
107 subsubsection{*lemmas on keysFor*} |
107 subsubsection\<open>lemmas on keysFor\<close> |
108 |
108 |
109 definition usekeys :: "msg set => key set" where |
109 definition usekeys :: "msg set => key set" where |
110 "usekeys G == {K. EX Y. Crypt K Y:G}" |
110 "usekeys G == {K. EX Y. Crypt K Y:G}" |
111 |
111 |
112 lemma finite_keysFor [intro]: "finite G ==> finite (keysFor G)" |
112 lemma finite_keysFor [intro]: "finite G ==> finite (keysFor G)" |
118 apply (subgoal_tac "{Ka. EX Xa. (Ka=K & Xa=X) | Crypt Ka Xa:F} |
118 apply (subgoal_tac "{Ka. EX Xa. (Ka=K & Xa=X) | Crypt Ka Xa:F} |
119 = insert K (usekeys F)", auto simp: usekeys_def) |
119 = insert K (usekeys F)", auto simp: usekeys_def) |
120 by (subgoal_tac "{K. EX X. Crypt K X = x | Crypt K X:F} = usekeys F", |
120 by (subgoal_tac "{K. EX X. Crypt K X = x | Crypt K X:F} = usekeys F", |
121 auto simp: usekeys_def) |
121 auto simp: usekeys_def) |
122 |
122 |
123 subsubsection{*lemmas on parts*} |
123 subsubsection\<open>lemmas on parts\<close> |
124 |
124 |
125 lemma parts_sub: "[| X:parts G; G<=H |] ==> X:parts H" |
125 lemma parts_sub: "[| X:parts G; G<=H |] ==> X:parts H" |
126 by (auto dest: parts_mono) |
126 by (auto dest: parts_mono) |
127 |
127 |
128 lemma parts_Diff [dest]: "X:parts (G - H) ==> X:parts G" |
128 lemma parts_Diff [dest]: "X:parts (G - H) ==> X:parts G" |
151 |
151 |
152 lemma parts_parts_Crypt: "[| Crypt K X:parts G; Nonce n:parts {X} |] |
152 lemma parts_parts_Crypt: "[| Crypt K X:parts G; Nonce n:parts {X} |] |
153 ==> Nonce n:parts G" |
153 ==> Nonce n:parts G" |
154 by (blast intro: parts.Body dest: parts_parts) |
154 by (blast intro: parts.Body dest: parts_parts) |
155 |
155 |
156 subsubsection{*lemmas on synth*} |
156 subsubsection\<open>lemmas on synth\<close> |
157 |
157 |
158 lemma synth_sub: "[| X:synth G; G<=H |] ==> X:synth H" |
158 lemma synth_sub: "[| X:synth G; G<=H |] ==> X:synth H" |
159 by (auto dest: synth_mono) |
159 by (auto dest: synth_mono) |
160 |
160 |
161 lemma Crypt_synth [rule_format]: "[| X:synth G; Key K ~:G |] ==> |
161 lemma Crypt_synth [rule_format]: "[| X:synth G; Key K ~:G |] ==> |
162 Crypt K Y:parts {X} --> Crypt K Y:parts G" |
162 Crypt K Y:parts {X} --> Crypt K Y:parts G" |
163 by (erule synth.induct, auto dest: parts_sub) |
163 by (erule synth.induct, auto dest: parts_sub) |
164 |
164 |
165 subsubsection{*lemmas on analz*} |
165 subsubsection\<open>lemmas on analz\<close> |
166 |
166 |
167 lemma analz_UnI1 [intro]: "X:analz G ==> X:analz (G Un H)" |
167 lemma analz_UnI1 [intro]: "X:analz G ==> X:analz (G Un H)" |
168 by (subgoal_tac "G <= G Un H") (blast dest: analz_mono)+ |
168 by (subgoal_tac "G <= G Un H") (blast dest: analz_mono)+ |
169 |
169 |
170 lemma analz_sub: "[| X:analz G; G <= H |] ==> X:analz H" |
170 lemma analz_sub: "[| X:analz G; G <= H |] ==> X:analz H" |
192 by (erule analz.induct, auto) |
192 by (erule analz.induct, auto) |
193 |
193 |
194 lemma notin_analz_insert: "X ~:analz (insert Y G) ==> X ~:analz G" |
194 lemma notin_analz_insert: "X ~:analz (insert Y G) ==> X ~:analz G" |
195 by auto |
195 by auto |
196 |
196 |
197 subsubsection{*lemmas on parts, synth and analz*} |
197 subsubsection\<open>lemmas on parts, synth and analz\<close> |
198 |
198 |
199 lemma parts_invKey [rule_format,dest]:"X:parts {Y} ==> |
199 lemma parts_invKey [rule_format,dest]:"X:parts {Y} ==> |
200 X:analz (insert (Crypt K Y) H) --> X ~:analz H --> Key (invKey K):analz H" |
200 X:analz (insert (Crypt K Y) H) --> X ~:analz H --> Key (invKey K):analz H" |
201 by (erule parts.induct, auto dest: parts.Fst parts.Snd parts.Body) |
201 by (erule parts.induct, auto dest: parts.Fst parts.Snd parts.Body) |
202 |
202 |
211 apply (frule in_sub) |
211 apply (frule in_sub) |
212 apply (frule parts_mono) |
212 apply (frule parts_mono) |
213 apply auto |
213 apply auto |
214 done |
214 done |
215 |
215 |
216 subsubsection{*greatest nonce used in a message*} |
216 subsubsection\<open>greatest nonce used in a message\<close> |
217 |
217 |
218 fun greatest_msg :: "msg => nat" |
218 fun greatest_msg :: "msg => nat" |
219 where |
219 where |
220 "greatest_msg (Nonce n) = n" |
220 "greatest_msg (Nonce n) = n" |
221 | "greatest_msg {|X,Y|} = max (greatest_msg X) (greatest_msg Y)" |
221 | "greatest_msg {|X,Y|} = max (greatest_msg X) (greatest_msg Y)" |
223 | "greatest_msg other = 0" |
223 | "greatest_msg other = 0" |
224 |
224 |
225 lemma greatest_msg_is_greatest: "Nonce n:parts {X} ==> n <= greatest_msg X" |
225 lemma greatest_msg_is_greatest: "Nonce n:parts {X} ==> n <= greatest_msg X" |
226 by (induct X, auto) |
226 by (induct X, auto) |
227 |
227 |
228 subsubsection{*sets of keys*} |
228 subsubsection\<open>sets of keys\<close> |
229 |
229 |
230 definition keyset :: "msg set => bool" where |
230 definition keyset :: "msg set => bool" where |
231 "keyset G == ALL X. X:G --> (EX K. X = Key K)" |
231 "keyset G == ALL X. X:G --> (EX K. X = Key K)" |
232 |
232 |
233 lemma keyset_in [dest]: "[| keyset G; X:G |] ==> EX K. X = Key K" |
233 lemma keyset_in [dest]: "[| keyset G; X:G |] ==> EX K. X = Key K" |
243 by auto |
243 by auto |
244 |
244 |
245 lemma parts_keyset [simp]: "keyset G ==> parts G = G" |
245 lemma parts_keyset [simp]: "keyset G ==> parts G = G" |
246 by (auto, erule parts.induct, auto) |
246 by (auto, erule parts.induct, auto) |
247 |
247 |
248 subsubsection{*keys a priori necessary for decrypting the messages of G*} |
248 subsubsection\<open>keys a priori necessary for decrypting the messages of G\<close> |
249 |
249 |
250 definition keysfor :: "msg set => msg set" where |
250 definition keysfor :: "msg set => msg set" where |
251 "keysfor G == Key ` keysFor (parts G)" |
251 "keysfor G == Key ` keysFor (parts G)" |
252 |
252 |
253 lemma keyset_keysfor [iff]: "keyset (keysfor G)" |
253 lemma keyset_keysfor [iff]: "keyset (keysfor G)" |
263 by (auto dest: keysfor_Crypt) |
263 by (auto dest: keysfor_Crypt) |
264 |
264 |
265 lemma finite_keysfor [intro]: "finite G ==> finite (keysfor G)" |
265 lemma finite_keysfor [intro]: "finite G ==> finite (keysfor G)" |
266 by (auto simp: keysfor_def intro: finite_UN_I) |
266 by (auto simp: keysfor_def intro: finite_UN_I) |
267 |
267 |
268 subsubsection{*only the keys necessary for G are useful in analz*} |
268 subsubsection\<open>only the keys necessary for G are useful in analz\<close> |
269 |
269 |
270 lemma analz_keyset: "keyset H ==> |
270 lemma analz_keyset: "keyset H ==> |
271 analz (G Un H) = H - keysfor G Un (analz (G Un (H Int keysfor G)))" |
271 analz (G Un H) = H - keysfor G Un (analz (G Un (H Int keysfor G)))" |
272 apply (rule eq) |
272 apply (rule eq) |
273 apply (erule analz.induct, blast) |
273 apply (erule analz.induct, blast) |
278 by (auto intro: analz_sub) |
278 by (auto intro: analz_sub) |
279 |
279 |
280 lemmas analz_keyset_substD = analz_keyset [THEN sym, THEN ssubst] |
280 lemmas analz_keyset_substD = analz_keyset [THEN sym, THEN ssubst] |
281 |
281 |
282 |
282 |
283 subsection{*Extensions to Theory @{text Event}*} |
283 subsection\<open>Extensions to Theory \<open>Event\<close>\<close> |
284 |
284 |
285 |
285 |
286 subsubsection{*general protocol properties*} |
286 subsubsection\<open>general protocol properties\<close> |
287 |
287 |
288 definition is_Says :: "event => bool" where |
288 definition is_Says :: "event => bool" where |
289 "is_Says ev == (EX A B X. ev = Says A B X)" |
289 "is_Says ev == (EX A B X. ev = Says A B X)" |
290 |
290 |
291 lemma is_Says_Says [iff]: "is_Says (Says A B X)" |
291 lemma is_Says_Says [iff]: "is_Says (Says A B X)" |
328 |
328 |
329 lemma has_only_Says_imp_Gets_correct [simp]: "has_only_Says p |
329 lemma has_only_Says_imp_Gets_correct [simp]: "has_only_Says p |
330 ==> Gets_correct p" |
330 ==> Gets_correct p" |
331 by (auto simp: has_only_Says_def Gets_correct_def) |
331 by (auto simp: has_only_Says_def Gets_correct_def) |
332 |
332 |
333 subsubsection{*lemma on knows*} |
333 subsubsection\<open>lemma on knows\<close> |
334 |
334 |
335 lemma Says_imp_spies2: "Says A B {|X,Y|}:set evs ==> Y:parts (spies evs)" |
335 lemma Says_imp_spies2: "Says A B {|X,Y|}:set evs ==> Y:parts (spies evs)" |
336 by (drule Says_imp_spies, drule parts.Inj, drule parts.Snd, simp) |
336 by (drule Says_imp_spies, drule parts.Inj, drule parts.Snd, simp) |
337 |
337 |
338 lemma Says_not_parts: "[| Says A B X:set evs; Y ~:parts (spies evs) |] |
338 lemma Says_not_parts: "[| Says A B X:set evs; Y ~:parts (spies evs) |] |
339 ==> Y ~:parts {X}" |
339 ==> Y ~:parts {X}" |
340 by (auto dest: Says_imp_spies parts_parts) |
340 by (auto dest: Says_imp_spies parts_parts) |
341 |
341 |
342 subsubsection{*knows without initState*} |
342 subsubsection\<open>knows without initState\<close> |
343 |
343 |
344 primrec knows' :: "agent => event list => msg set" where |
344 primrec knows' :: "agent => event list => msg set" where |
345 knows'_Nil: "knows' A [] = {}" | |
345 knows'_Nil: "knows' A [] = {}" | |
346 knows'_Cons0: |
346 knows'_Cons0: |
347 "knows' A (ev # evs) = ( |
347 "knows' A (ev # evs) = ( |
359 |
359 |
360 abbreviation |
360 abbreviation |
361 spies' :: "event list => msg set" where |
361 spies' :: "event list => msg set" where |
362 "spies' == knows' Spy" |
362 "spies' == knows' Spy" |
363 |
363 |
364 subsubsection{*decomposition of knows into knows' and initState*} |
364 subsubsection\<open>decomposition of knows into knows' and initState\<close> |
365 |
365 |
366 lemma knows_decomp: "knows A evs = knows' A evs Un (initState A)" |
366 lemma knows_decomp: "knows A evs = knows' A evs Un (initState A)" |
367 by (induct evs, auto split: event.split simp: knows.simps) |
367 by (induct evs, auto split: event.split simp: knows.simps) |
368 |
368 |
369 lemmas knows_decomp_substI = knows_decomp [THEN ssubst] |
369 lemmas knows_decomp_substI = knows_decomp [THEN ssubst] |
392 |
392 |
393 lemma knows'_sub_spies': "[| evs:p; has_only_Says p; one_step p |] |
393 lemma knows'_sub_spies': "[| evs:p; has_only_Says p; one_step p |] |
394 ==> knows' A evs <= spies' evs" |
394 ==> knows' A evs <= spies' evs" |
395 by (induct evs, auto split: event.splits) |
395 by (induct evs, auto split: event.splits) |
396 |
396 |
397 subsubsection{*knows' is finite*} |
397 subsubsection\<open>knows' is finite\<close> |
398 |
398 |
399 lemma finite_knows' [iff]: "finite (knows' A evs)" |
399 lemma finite_knows' [iff]: "finite (knows' A evs)" |
400 by (induct evs, auto split: event.split simp: knows.simps) |
400 by (induct evs, auto split: event.split simp: knows.simps) |
401 |
401 |
402 subsubsection{*monotonicity of knows*} |
402 subsubsection\<open>monotonicity of knows\<close> |
403 |
403 |
404 lemma knows_sub_Cons: "knows A evs <= knows A (ev#evs)" |
404 lemma knows_sub_Cons: "knows A evs <= knows A (ev#evs)" |
405 by(cases A, induct evs, auto simp: knows.simps split:event.split) |
405 by(cases A, induct evs, auto simp: knows.simps split:event.split) |
406 |
406 |
407 lemma knows_ConsI: "X:knows A evs ==> X:knows A (ev#evs)" |
407 lemma knows_ConsI: "X:knows A evs ==> X:knows A (ev#evs)" |
411 apply (induct evs, auto) |
411 apply (induct evs, auto) |
412 apply (simp add: knows_decomp) |
412 apply (simp add: knows_decomp) |
413 apply (rename_tac a b c) |
413 apply (rename_tac a b c) |
414 by (case_tac a, auto simp: knows.simps) |
414 by (case_tac a, auto simp: knows.simps) |
415 |
415 |
416 subsubsection{*maximum knowledge an agent can have |
416 subsubsection\<open>maximum knowledge an agent can have |
417 includes messages sent to the agent*} |
417 includes messages sent to the agent\<close> |
418 |
418 |
419 primrec knows_max' :: "agent => event list => msg set" where |
419 primrec knows_max' :: "agent => event list => msg set" where |
420 knows_max'_def_Nil: "knows_max' A [] = {}" | |
420 knows_max'_def_Nil: "knows_max' A [] = {}" | |
421 knows_max'_def_Cons: "knows_max' A (ev # evs) = ( |
421 knows_max'_def_Cons: "knows_max' A (ev # evs) = ( |
422 if A=Spy then ( |
422 if A=Spy then ( |
440 |
440 |
441 abbreviation |
441 abbreviation |
442 spies_max :: "event list => msg set" where |
442 spies_max :: "event list => msg set" where |
443 "spies_max evs == knows_max Spy evs" |
443 "spies_max evs == knows_max Spy evs" |
444 |
444 |
445 subsubsection{*basic facts about @{term knows_max}*} |
445 subsubsection\<open>basic facts about @{term knows_max}\<close> |
446 |
446 |
447 lemma spies_max_spies [iff]: "spies_max evs = spies evs" |
447 lemma spies_max_spies [iff]: "spies_max evs = spies evs" |
448 by (induct evs, auto simp: knows_max_def split: event.splits) |
448 by (induct evs, auto simp: knows_max_def split: event.splits) |
449 |
449 |
450 lemma knows_max'_Cons: "knows_max' A (ev#evs) |
450 lemma knows_max'_Cons: "knows_max' A (ev#evs) |
482 by (simp add: in_set_conv_decomp, clarify, simp add: knows_max'_app) |
482 by (simp add: in_set_conv_decomp, clarify, simp add: knows_max'_app) |
483 |
483 |
484 lemma Says_from_knows_max': "Says A B X:set evs ==> X:knows_max' A evs" |
484 lemma Says_from_knows_max': "Says A B X:set evs ==> X:knows_max' A evs" |
485 by (simp add: in_set_conv_decomp, clarify, simp add: knows_max'_app) |
485 by (simp add: in_set_conv_decomp, clarify, simp add: knows_max'_app) |
486 |
486 |
487 subsubsection{*used without initState*} |
487 subsubsection\<open>used without initState\<close> |
488 |
488 |
489 primrec used' :: "event list => msg set" where |
489 primrec used' :: "event list => msg set" where |
490 "used' [] = {}" | |
490 "used' [] = {}" | |
491 "used' (ev # evs) = ( |
491 "used' (ev # evs) = ( |
492 case ev of |
492 case ev of |
509 apply (rename_tac a b) |
509 apply (rename_tac a b) |
510 apply (case_tac a, simp_all) |
510 apply (case_tac a, simp_all) |
511 apply (blast dest: parts_trans)+ |
511 apply (blast dest: parts_trans)+ |
512 done |
512 done |
513 |
513 |
514 subsubsection{*monotonicity of used*} |
514 subsubsection\<open>monotonicity of used\<close> |
515 |
515 |
516 lemma used_sub_Cons: "used evs <= used (ev#evs)" |
516 lemma used_sub_Cons: "used evs <= used (ev#evs)" |
517 by (induct evs, (induct ev, auto)+) |
517 by (induct evs, (induct ev, auto)+) |
518 |
518 |
519 lemma used_ConsI: "X:used evs ==> X:used (ev#evs)" |
519 lemma used_ConsI: "X:used evs ==> X:used (ev#evs)" |
548 apply (drule_tac evs="[Says A B Y]" in used_parts, simp, blast) |
548 apply (drule_tac evs="[Says A B Y]" in used_parts, simp, blast) |
549 apply (drule_tac evs'=evs' in used_appIR) |
549 apply (drule_tac evs'=evs' in used_appIR) |
550 apply (drule_tac evs'=evs in used_appIL) |
550 apply (drule_tac evs'=evs in used_appIL) |
551 by simp |
551 by simp |
552 |
552 |
553 subsubsection{*lemmas on used and knows*} |
553 subsubsection\<open>lemmas on used and knows\<close> |
554 |
554 |
555 lemma initState_used: "X:parts (initState A) ==> X:used evs" |
555 lemma initState_used: "X:parts (initState A) ==> X:used evs" |
556 by (induct evs, auto simp: used.simps split: event.split) |
556 by (induct evs, auto simp: used.simps split: event.split) |
557 |
557 |
558 lemma Says_imp_used: "Says A B X:set evs ==> parts {X} <= used evs" |
558 lemma Says_imp_used: "Says A B X:set evs ==> parts {X} <= used evs" |
603 |
603 |
604 lemma not_used_not_known_max: "[| evs:p; X ~:used evs; |
604 lemma not_used_not_known_max: "[| evs:p; X ~:used evs; |
605 Gets_correct p; one_step p |] ==> X ~:parts (knows_max A evs)" |
605 Gets_correct p; one_step p |] ==> X ~:parts (knows_max A evs)" |
606 by (case_tac "A=Spy", auto dest: not_used_not_spied known_max_used) |
606 by (case_tac "A=Spy", auto dest: not_used_not_spied known_max_used) |
607 |
607 |
608 subsubsection{*a nonce or key in a message cannot equal a fresh nonce or key*} |
608 subsubsection\<open>a nonce or key in a message cannot equal a fresh nonce or key\<close> |
609 |
609 |
610 lemma Nonce_neq [dest]: "[| Nonce n' ~:used evs; |
610 lemma Nonce_neq [dest]: "[| Nonce n' ~:used evs; |
611 Says A B X:set evs; Nonce n:parts {X} |] ==> n ~= n'" |
611 Says A B X:set evs; Nonce n:parts {X} |] ==> n ~= n'" |
612 by (drule not_used_not_spied, auto dest: Says_imp_knows_Spy parts_sub) |
612 by (drule not_used_not_spied, auto dest: Says_imp_knows_Spy parts_sub) |
613 |
613 |
614 lemma Key_neq [dest]: "[| Key n' ~:used evs; |
614 lemma Key_neq [dest]: "[| Key n' ~:used evs; |
615 Says A B X:set evs; Key n:parts {X} |] ==> n ~= n'" |
615 Says A B X:set evs; Key n:parts {X} |] ==> n ~= n'" |
616 by (drule not_used_not_spied, auto dest: Says_imp_knows_Spy parts_sub) |
616 by (drule not_used_not_spied, auto dest: Says_imp_knows_Spy parts_sub) |
617 |
617 |
618 subsubsection{*message of an event*} |
618 subsubsection\<open>message of an event\<close> |
619 |
619 |
620 primrec msg :: "event => msg" |
620 primrec msg :: "event => msg" |
621 where |
621 where |
622 "msg (Says A B X) = X" |
622 "msg (Says A B X) = X" |
623 | "msg (Gets A X) = X" |
623 | "msg (Gets A X) = X" |