37 (*<*) |
37 (*<*) |
38 consts all_symmetric :: bool \<comment> \<open>true if all keys are symmetric\<close> |
38 consts all_symmetric :: bool \<comment> \<open>true if all keys are symmetric\<close> |
39 |
39 |
40 specification (invKey) |
40 specification (invKey) |
41 invKey [simp]: "invKey (invKey K) = K" |
41 invKey [simp]: "invKey (invKey K) = K" |
42 invKey_symmetric: "all_symmetric --> invKey = id" |
42 invKey_symmetric: "all_symmetric \<longrightarrow> invKey = id" |
43 by (rule exI [of _ id], auto) |
43 by (rule exI [of _ id], auto) |
44 |
44 |
45 |
45 |
46 text\<open>The inverse of a symmetric key is itself; that of a public key |
46 text\<open>The inverse of a symmetric key is itself; that of a public key |
47 is the private key and vice versa\<close> |
47 is the private key and vice versa\<close> |
79 \<close> |
79 \<close> |
80 |
80 |
81 (*<*) |
81 (*<*) |
82 text\<open>Concrete syntax: messages appear as \<open>\<lbrace>A,B,NA\<rbrace>\<close>, etc...\<close> |
82 text\<open>Concrete syntax: messages appear as \<open>\<lbrace>A,B,NA\<rbrace>\<close>, etc...\<close> |
83 syntax |
83 syntax |
84 "_MTuple" :: "['a, args] => 'a * 'b" ("(2\<lbrace>_,/ _\<rbrace>)") |
84 "_MTuple" :: "['a, args] \<Rightarrow> 'a * 'b" ("(2\<lbrace>_,/ _\<rbrace>)") |
85 translations |
85 translations |
86 "\<lbrace>x, y, z\<rbrace>" == "\<lbrace>x, \<lbrace>y, z\<rbrace>\<rbrace>" |
86 "\<lbrace>x, y, z\<rbrace>" == "\<lbrace>x, \<lbrace>y, z\<rbrace>\<rbrace>" |
87 "\<lbrace>x, y\<rbrace>" == "CONST MPair x y" |
87 "\<lbrace>x, y\<rbrace>" == "CONST MPair x y" |
88 |
88 |
89 |
89 |
90 definition keysFor :: "msg set => key set" where |
90 definition keysFor :: "msg set \<Rightarrow> key set" where |
91 \<comment> \<open>Keys useful to decrypt elements of a message set\<close> |
91 \<comment> \<open>Keys useful to decrypt elements of a message set\<close> |
92 "keysFor H == invKey ` {K. \<exists>X. Crypt K X \<in> H}" |
92 "keysFor H == invKey ` {K. \<exists>X. Crypt K X \<in> H}" |
93 |
93 |
94 |
94 |
95 subsubsection\<open>Inductive Definition of All Parts" of a Message\<close> |
95 subsubsection\<open>Inductive Definition of All Parts" of a Message\<close> |
96 |
96 |
97 inductive_set |
97 inductive_set |
98 parts :: "msg set => msg set" |
98 parts :: "msg set \<Rightarrow> msg set" |
99 for H :: "msg set" |
99 for H :: "msg set" |
100 where |
100 where |
101 Inj [intro]: "X \<in> H ==> X \<in> parts H" |
101 Inj [intro]: "X \<in> H \<Longrightarrow> X \<in> parts H" |
102 | Fst: "\<lbrace>X,Y\<rbrace> \<in> parts H ==> X \<in> parts H" |
102 | Fst: "\<lbrace>X,Y\<rbrace> \<in> parts H \<Longrightarrow> X \<in> parts H" |
103 | Snd: "\<lbrace>X,Y\<rbrace> \<in> parts H ==> Y \<in> parts H" |
103 | Snd: "\<lbrace>X,Y\<rbrace> \<in> parts H \<Longrightarrow> Y \<in> parts H" |
104 | Body: "Crypt K X \<in> parts H ==> X \<in> parts H" |
104 | Body: "Crypt K X \<in> parts H \<Longrightarrow> X \<in> parts H" |
105 |
105 |
106 |
106 |
107 text\<open>Monotonicity\<close> |
107 text\<open>Monotonicity\<close> |
108 lemma parts_mono: "G \<subseteq> H ==> parts(G) \<subseteq> parts(H)" |
108 lemma parts_mono: "G \<subseteq> H \<Longrightarrow> parts(G) \<subseteq> parts(H)" |
109 apply auto |
109 apply auto |
110 apply (erule parts.induct) |
110 apply (erule parts.induct) |
111 apply (blast dest: parts.Fst parts.Snd parts.Body)+ |
111 apply (blast dest: parts.Fst parts.Snd parts.Body)+ |
112 done |
112 done |
113 |
113 |
114 |
114 |
115 text\<open>Equations hold because constructors are injective.\<close> |
115 text\<open>Equations hold because constructors are injective.\<close> |
116 lemma Friend_image_eq [simp]: "(Friend x \<in> Friend`A) = (x:A)" |
116 lemma Friend_image_eq [simp]: "(Friend x \<in> Friend`A) = (x\<in>A)" |
117 by auto |
117 by auto |
118 |
118 |
119 lemma Key_image_eq [simp]: "(Key x \<in> Key`A) = (x\<in>A)" |
119 lemma Key_image_eq [simp]: "(Key x \<in> Key`A) = (x\<in>A)" |
120 by auto |
120 by auto |
121 |
121 |
141 |
141 |
142 lemma keysFor_UN [simp]: "keysFor (\<Union>i\<in>A. H i) = (\<Union>i\<in>A. keysFor (H i))" |
142 lemma keysFor_UN [simp]: "keysFor (\<Union>i\<in>A. H i) = (\<Union>i\<in>A. keysFor (H i))" |
143 by (unfold keysFor_def, blast) |
143 by (unfold keysFor_def, blast) |
144 |
144 |
145 text\<open>Monotonicity\<close> |
145 text\<open>Monotonicity\<close> |
146 lemma keysFor_mono: "G \<subseteq> H ==> keysFor(G) \<subseteq> keysFor(H)" |
146 lemma keysFor_mono: "G \<subseteq> H \<Longrightarrow> keysFor(G) \<subseteq> keysFor(H)" |
147 by (unfold keysFor_def, blast) |
147 by (unfold keysFor_def, blast) |
148 |
148 |
149 lemma keysFor_insert_Agent [simp]: "keysFor (insert (Agent A) H) = keysFor H" |
149 lemma keysFor_insert_Agent [simp]: "keysFor (insert (Agent A) H) = keysFor H" |
150 by (unfold keysFor_def, auto) |
150 by (unfold keysFor_def, auto) |
151 |
151 |
163 by (unfold keysFor_def, auto) |
163 by (unfold keysFor_def, auto) |
164 |
164 |
165 lemma keysFor_image_Key [simp]: "keysFor (Key`E) = {}" |
165 lemma keysFor_image_Key [simp]: "keysFor (Key`E) = {}" |
166 by (unfold keysFor_def, auto) |
166 by (unfold keysFor_def, auto) |
167 |
167 |
168 lemma Crypt_imp_invKey_keysFor: "Crypt K X \<in> H ==> invKey K \<in> keysFor H" |
168 lemma Crypt_imp_invKey_keysFor: "Crypt K X \<in> H \<Longrightarrow> invKey K \<in> keysFor H" |
169 by (unfold keysFor_def, blast) |
169 by (unfold keysFor_def, blast) |
170 |
170 |
171 |
171 |
172 subsection\<open>Inductive relation "parts"\<close> |
172 subsection\<open>Inductive relation "parts"\<close> |
173 |
173 |
190 lemma parts_empty [simp]: "parts{} = {}" |
190 lemma parts_empty [simp]: "parts{} = {}" |
191 apply safe |
191 apply safe |
192 apply (erule parts.induct, blast+) |
192 apply (erule parts.induct, blast+) |
193 done |
193 done |
194 |
194 |
195 lemma parts_emptyE [elim!]: "X\<in> parts{} ==> P" |
195 lemma parts_emptyE [elim!]: "X\<in> parts{} \<Longrightarrow> P" |
196 by simp |
196 by simp |
197 |
197 |
198 text\<open>WARNING: loops if H = {Y}, therefore must not be repeated!\<close> |
198 text\<open>WARNING: loops if H = {Y}, therefore must not be repeated!\<close> |
199 lemma parts_singleton: "X\<in> parts H ==> \<exists>Y\<in>H. X\<in> parts {Y}" |
199 lemma parts_singleton: "X\<in> parts H \<Longrightarrow> \<exists>Y\<in>H. X\<in> parts {Y}" |
200 by (erule parts.induct, fast+) |
200 by (erule parts.induct, fast+) |
201 |
201 |
202 |
202 |
203 subsubsection\<open>Unions\<close> |
203 subsubsection\<open>Unions\<close> |
204 |
204 |
250 lemma parts_insert_subset: "insert X (parts H) \<subseteq> parts(insert X H)" |
250 lemma parts_insert_subset: "insert X (parts H) \<subseteq> parts(insert X H)" |
251 by (blast intro: parts_mono [THEN [2] rev_subsetD]) |
251 by (blast intro: parts_mono [THEN [2] rev_subsetD]) |
252 |
252 |
253 subsubsection\<open>Idempotence and transitivity\<close> |
253 subsubsection\<open>Idempotence and transitivity\<close> |
254 |
254 |
255 lemma parts_partsD [dest!]: "X\<in> parts (parts H) ==> X\<in> parts H" |
255 lemma parts_partsD [dest!]: "X \<in> parts (parts H) \<Longrightarrow> X\<in> parts H" |
256 by (erule parts.induct, blast+) |
256 by (erule parts.induct, blast+) |
257 |
257 |
258 lemma parts_idem [simp]: "parts (parts H) = parts H" |
258 lemma parts_idem [simp]: "parts (parts H) = parts H" |
259 by blast |
259 by blast |
260 |
260 |
322 apply (erule parts.induct, auto) |
322 apply (erule parts.induct, auto) |
323 done |
323 done |
324 |
324 |
325 |
325 |
326 text\<open>In any message, there is an upper bound N on its greatest nonce.\<close> |
326 text\<open>In any message, there is an upper bound N on its greatest nonce.\<close> |
327 lemma msg_Nonce_supply: "\<exists>N. \<forall>n. N\<le>n --> Nonce n \<notin> parts {msg}" |
327 lemma msg_Nonce_supply: "\<exists>N. \<forall>n. N\<le>n \<longrightarrow> Nonce n \<notin> parts {msg}" |
328 apply (induct_tac "msg") |
328 apply (induct_tac "msg") |
329 apply (simp_all (no_asm_simp) add: exI parts_insert2) |
329 apply (simp_all (no_asm_simp) add: exI parts_insert2) |
330 txt\<open>MPair case: blast works out the necessary sum itself!\<close> |
330 txt\<open>MPair case: blast works out the necessary sum itself!\<close> |
331 prefer 2 apply auto apply (blast elim!: add_leE) |
331 prefer 2 apply auto apply (blast elim!: add_leE) |
332 txt\<open>Nonce case\<close> |
332 txt\<open>Nonce case\<close> |
361 | Decrypt [dest]: |
361 | Decrypt [dest]: |
362 "\<lbrakk>Crypt K X \<in> analz H; Key(invKey K) \<in> analz H\<rbrakk> |
362 "\<lbrakk>Crypt K X \<in> analz H; Key(invKey K) \<in> analz H\<rbrakk> |
363 \<Longrightarrow> X \<in> analz H" |
363 \<Longrightarrow> X \<in> analz H" |
364 (*<*) |
364 (*<*) |
365 text\<open>Monotonicity; Lemma 1 of Lowe's paper\<close> |
365 text\<open>Monotonicity; Lemma 1 of Lowe's paper\<close> |
366 lemma analz_mono: "G\<subseteq>H ==> analz(G) \<subseteq> analz(H)" |
366 lemma analz_mono: "G\<subseteq>H \<Longrightarrow> analz(G) \<subseteq> analz(H)" |
367 apply auto |
367 apply auto |
368 apply (erule analz.induct) |
368 apply (erule analz.induct) |
369 apply (auto dest: analz.Fst analz.Snd) |
369 apply (auto dest: analz.Fst analz.Snd) |
370 done |
370 done |
371 |
371 |
433 apply (erule analz.induct, auto) |
433 apply (erule analz.induct, auto) |
434 done |
434 done |
435 |
435 |
436 text\<open>Can only pull out Keys if they are not needed to decrypt the rest\<close> |
436 text\<open>Can only pull out Keys if they are not needed to decrypt the rest\<close> |
437 lemma analz_insert_Key [simp]: |
437 lemma analz_insert_Key [simp]: |
438 "K \<notin> keysFor (analz H) ==> |
438 "K \<notin> keysFor (analz H) \<Longrightarrow> |
439 analz (insert (Key K) H) = insert (Key K) (analz H)" |
439 analz (insert (Key K) H) = insert (Key K) (analz H)" |
440 apply (unfold keysFor_def) |
440 apply (unfold keysFor_def) |
441 apply (rule analz_insert_eq_I) |
441 apply (rule analz_insert_eq_I) |
442 apply (erule analz.induct, auto) |
442 apply (erule analz.induct, auto) |
443 done |
443 done |
453 done |
453 done |
454 |
454 |
455 text\<open>Can pull out enCrypted message if the Key is not known\<close> |
455 text\<open>Can pull out enCrypted message if the Key is not known\<close> |
456 lemma analz_insert_Crypt: |
456 lemma analz_insert_Crypt: |
457 "Key (invKey K) \<notin> analz H |
457 "Key (invKey K) \<notin> analz H |
458 ==> analz (insert (Crypt K X) H) = insert (Crypt K X) (analz H)" |
458 \<Longrightarrow> analz (insert (Crypt K X) H) = insert (Crypt K X) (analz H)" |
459 apply (rule analz_insert_eq_I) |
459 apply (rule analz_insert_eq_I) |
460 apply (erule analz.induct, auto) |
460 apply (erule analz.induct, auto) |
461 |
461 |
462 done |
462 done |
463 |
463 |
464 lemma lemma1: "Key (invKey K) \<in> analz H ==> |
464 lemma lemma1: "Key (invKey K) \<in> analz H \<Longrightarrow> |
465 analz (insert (Crypt K X) H) \<subseteq> |
465 analz (insert (Crypt K X) H) \<subseteq> |
466 insert (Crypt K X) (analz (insert X H))" |
466 insert (Crypt K X) (analz (insert X H))" |
467 apply (rule subsetI) |
467 apply (rule subsetI) |
468 apply (erule_tac x = x in analz.induct, auto) |
468 apply (erule_tac x = x in analz.induct, auto) |
469 done |
469 done |
470 |
470 |
471 lemma lemma2: "Key (invKey K) \<in> analz H ==> |
471 lemma lemma2: "Key (invKey K) \<in> analz H \<Longrightarrow> |
472 insert (Crypt K X) (analz (insert X H)) \<subseteq> |
472 insert (Crypt K X) (analz (insert X H)) \<subseteq> |
473 analz (insert (Crypt K X) H)" |
473 analz (insert (Crypt K X) H)" |
474 apply auto |
474 apply auto |
475 apply (erule_tac x = x in analz.induct, auto) |
475 apply (erule_tac x = x in analz.induct, auto) |
476 apply (blast intro: analz_insertI analz.Decrypt) |
476 apply (blast intro: analz_insertI analz.Decrypt) |
477 done |
477 done |
478 |
478 |
479 lemma analz_insert_Decrypt: |
479 lemma analz_insert_Decrypt: |
480 "Key (invKey K) \<in> analz H ==> |
480 "Key (invKey K) \<in> analz H \<Longrightarrow> |
481 analz (insert (Crypt K X) H) = |
481 analz (insert (Crypt K X) H) = |
482 insert (Crypt K X) (analz (insert X H))" |
482 insert (Crypt K X) (analz (insert X H))" |
483 by (intro equalityI lemma1 lemma2) |
483 by (intro equalityI lemma1 lemma2) |
484 |
484 |
485 text\<open>Case analysis: either the message is secure, or it is not! Effective, |
485 text\<open>Case analysis: either the message is secure, or it is not! Effective, |
529 text\<open>Cut; Lemma 2 of Lowe\<close> |
529 text\<open>Cut; Lemma 2 of Lowe\<close> |
530 lemma analz_cut: "[| Y\<in> analz (insert X H); X\<in> analz H |] ==> Y\<in> analz H" |
530 lemma analz_cut: "[| Y\<in> analz (insert X H); X\<in> analz H |] ==> Y\<in> analz H" |
531 by (erule analz_trans, blast) |
531 by (erule analz_trans, blast) |
532 |
532 |
533 (*Cut can be proved easily by induction on |
533 (*Cut can be proved easily by induction on |
534 "Y: analz (insert X H) ==> X: analz H --> Y: analz H" |
534 "Y \<in> analz (insert X H) \<Longrightarrow> X \<in> analz H \<longrightarrow> Y \<in> analz H" |
535 *) |
535 *) |
536 |
536 |
537 text\<open>This rewrite rule helps in the simplification of messages that involve |
537 text\<open>This rewrite rule helps in the simplification of messages that involve |
538 the forwarding of unknown components (X). Without it, removing occurrences |
538 the forwarding of unknown components (X). Without it, removing occurrences |
539 of X can be very complicated.\<close> |
539 of X can be very complicated.\<close> |
540 lemma analz_insert_eq: "X\<in> analz H ==> analz (insert X H) = analz H" |
540 lemma analz_insert_eq: "X\<in> analz H \<Longrightarrow> analz (insert X H) = analz H" |
541 by (blast intro: analz_cut analz_insertI) |
541 by (blast intro: analz_cut analz_insertI) |
542 |
542 |
543 |
543 |
544 text\<open>A congruence rule for "analz"\<close> |
544 text\<open>A congruence rule for "analz"\<close> |
545 |
545 |
554 "[| analz G = analz G'; analz H = analz H' |] |
554 "[| analz G = analz G'; analz H = analz H' |] |
555 ==> analz (G \<union> H) = analz (G' \<union> H')" |
555 ==> analz (G \<union> H) = analz (G' \<union> H')" |
556 by (intro equalityI analz_subset_cong, simp_all) |
556 by (intro equalityI analz_subset_cong, simp_all) |
557 |
557 |
558 lemma analz_insert_cong: |
558 lemma analz_insert_cong: |
559 "analz H = analz H' ==> analz(insert X H) = analz(insert X H')" |
559 "analz H = analz H' \<Longrightarrow> analz(insert X H) = analz(insert X H')" |
560 by (force simp only: insert_def intro!: analz_cong) |
560 by (force simp only: insert_def intro!: analz_cong) |
561 |
561 |
562 text\<open>If there are no pairs or encryptions then analz does nothing\<close> |
562 text\<open>If there are no pairs or encryptions then analz does nothing\<close> |
563 lemma analz_trivial: |
563 lemma analz_trivial: |
564 "[| \<forall>X Y. \<lbrace>X,Y\<rbrace> \<notin> H; \<forall>X K. Crypt K X \<notin> H |] ==> analz H = H" |
564 "[| \<forall>X Y. \<lbrace>X,Y\<rbrace> \<notin> H; \<forall>X K. Crypt K X \<notin> H |] ==> analz H = H" |
566 apply (erule analz.induct, blast+) |
566 apply (erule analz.induct, blast+) |
567 done |
567 done |
568 |
568 |
569 text\<open>These two are obsolete (with a single Spy) but cost little to prove...\<close> |
569 text\<open>These two are obsolete (with a single Spy) but cost little to prove...\<close> |
570 lemma analz_UN_analz_lemma: |
570 lemma analz_UN_analz_lemma: |
571 "X\<in> analz (\<Union>i\<in>A. analz (H i)) ==> X\<in> analz (\<Union>i\<in>A. H i)" |
571 "X\<in> analz (\<Union>i\<in>A. analz (H i)) \<Longrightarrow> X\<in> analz (\<Union>i\<in>A. H i)" |
572 apply (erule analz.induct) |
572 apply (erule analz.induct) |
573 apply (blast intro: analz_mono [THEN [2] rev_subsetD])+ |
573 apply (blast intro: analz_mono [THEN [2] rev_subsetD])+ |
574 done |
574 done |
575 |
575 |
576 lemma analz_UN_analz [simp]: "analz (\<Union>i\<in>A. analz (H i)) = analz (\<Union>i\<in>A. H i)" |
576 lemma analz_UN_analz [simp]: "analz (\<Union>i\<in>A. analz (H i)) = analz (\<Union>i\<in>A. H i)" |
596 | MPair [intro]: |
596 | MPair [intro]: |
597 "\<lbrakk>X \<in> synth H; Y \<in> synth H\<rbrakk> \<Longrightarrow> \<lbrace>X,Y\<rbrace> \<in> synth H" |
597 "\<lbrakk>X \<in> synth H; Y \<in> synth H\<rbrakk> \<Longrightarrow> \<lbrace>X,Y\<rbrace> \<in> synth H" |
598 | Crypt [intro]: |
598 | Crypt [intro]: |
599 "\<lbrakk>X \<in> synth H; Key K \<in> H\<rbrakk> \<Longrightarrow> Crypt K X \<in> synth H" |
599 "\<lbrakk>X \<in> synth H; Key K \<in> H\<rbrakk> \<Longrightarrow> Crypt K X \<in> synth H" |
600 (*<*) |
600 (*<*) |
601 lemma synth_mono: "G\<subseteq>H ==> synth(G) \<subseteq> synth(H)" |
601 lemma synth_mono: "G\<subseteq>H \<Longrightarrow> synth(G) \<subseteq> synth(H)" |
602 by (auto, erule synth.induct, auto) |
602 by (auto, erule synth.induct, auto) |
603 |
603 |
604 inductive_cases Key_synth [elim!]: "Key K \<in> synth H" |
604 inductive_cases Key_synth [elim!]: "Key K \<in> synth H" |
605 inductive_cases MPair_synth [elim!]: "\<lbrace>X,Y\<rbrace> \<in> synth H" |
605 inductive_cases MPair_synth [elim!]: "\<lbrace>X,Y\<rbrace> \<in> synth H" |
606 inductive_cases Crypt_synth [elim!]: "Crypt K X \<in> synth H" |
606 inductive_cases Crypt_synth [elim!]: "Crypt K X \<in> synth H" |
666 lemma synth_insert: "insert X (synth H) \<subseteq> synth(insert X H)" |
666 lemma synth_insert: "insert X (synth H) \<subseteq> synth(insert X H)" |
667 by (blast intro: synth_mono [THEN [2] rev_subsetD]) |
667 by (blast intro: synth_mono [THEN [2] rev_subsetD]) |
668 |
668 |
669 subsubsection\<open>Idempotence and transitivity\<close> |
669 subsubsection\<open>Idempotence and transitivity\<close> |
670 |
670 |
671 lemma synth_synthD [dest!]: "X\<in> synth (synth H) ==> X\<in> synth H" |
671 lemma synth_synthD [dest!]: "X\<in> synth (synth H) \<Longrightarrow> X\<in> synth H" |
672 by (erule synth.induct, blast+) |
672 by (erule synth.induct, blast+) |
673 |
673 |
674 lemma synth_idem: "synth (synth H) = synth H" |
674 lemma synth_idem: "synth (synth H) = synth H" |
675 by blast |
675 by blast |
676 |
676 |
722 done |
722 done |
723 |
723 |
724 |
724 |
725 subsubsection\<open>For reasoning about the Fake rule in traces\<close> |
725 subsubsection\<open>For reasoning about the Fake rule in traces\<close> |
726 |
726 |
727 lemma parts_insert_subset_Un: "X\<in> G ==> parts(insert X H) \<subseteq> parts G \<union> parts H" |
727 lemma parts_insert_subset_Un: "X \<in> G \<Longrightarrow> parts(insert X H) \<subseteq> parts G \<union> parts H" |
728 by (rule subset_trans [OF parts_mono parts_Un_subset2], blast) |
728 by (rule subset_trans [OF parts_mono parts_Un_subset2], blast) |
729 |
729 |
730 text\<open>More specifically for Fake. Very occasionally we could do with a version |
730 text\<open>More specifically for Fake. Very occasionally we could do with a version |
731 of the form @{term"parts{X} \<subseteq> synth (analz H) \<union> parts H"}\<close> |
731 of the form @{term"parts{X} \<subseteq> synth (analz H) \<union> parts H"}\<close> |
732 lemma Fake_parts_insert: |
732 lemma Fake_parts_insert: |
733 "X \<in> synth (analz H) ==> |
733 "X \<in> synth (analz H) \<Longrightarrow> |
734 parts (insert X H) \<subseteq> synth (analz H) \<union> parts H" |
734 parts (insert X H) \<subseteq> synth (analz H) \<union> parts H" |
735 apply (drule parts_insert_subset_Un) |
735 apply (drule parts_insert_subset_Un) |
736 apply (simp (no_asm_use)) |
736 apply (simp (no_asm_use)) |
737 apply blast |
737 apply blast |
738 done |
738 done |
739 |
739 |
740 lemma Fake_parts_insert_in_Un: |
740 lemma Fake_parts_insert_in_Un: |
741 "[|Z \<in> parts (insert X H); X: synth (analz H)|] |
741 "[|Z \<in> parts (insert X H); X \<in> synth (analz H)|] |
742 ==> Z \<in> synth (analz H) \<union> parts H" |
742 ==> Z \<in> synth (analz H) \<union> parts H" |
743 by (blast dest: Fake_parts_insert [THEN subsetD, dest]) |
743 by (blast dest: Fake_parts_insert [THEN subsetD, dest]) |
744 |
744 |
745 text\<open>@{term H} is sometimes @{term"Key ` KK \<union> spies evs"}, so can't put |
745 text\<open>@{term H} is sometimes @{term"Key ` KK \<union> spies evs"}, so can't put |
746 @{term "G=H"}.\<close> |
746 @{term "G=H"}.\<close> |
747 lemma Fake_analz_insert: |
747 lemma Fake_analz_insert: |
748 "X\<in> synth (analz G) ==> |
748 "X \<in> synth (analz G) \<Longrightarrow> |
749 analz (insert X H) \<subseteq> synth (analz G) \<union> analz (G \<union> H)" |
749 analz (insert X H) \<subseteq> synth (analz G) \<union> analz (G \<union> H)" |
750 apply (rule subsetI) |
750 apply (rule subsetI) |
751 apply (subgoal_tac "x \<in> analz (synth (analz G) \<union> H) ") |
751 apply (subgoal_tac "x \<in> analz (synth (analz G) \<union> H) ") |
752 prefer 2 apply (blast intro: analz_mono [THEN [2] rev_subsetD] analz_mono [THEN synth_mono, THEN [2] rev_subsetD]) |
752 prefer 2 apply (blast intro: analz_mono [THEN [2] rev_subsetD] analz_mono [THEN synth_mono, THEN [2] rev_subsetD]) |
753 apply (simp (no_asm_use)) |
753 apply (simp (no_asm_use)) |
867 |
867 |
868 |
868 |
869 lemma Crypt_notin_image_Key [simp]: "Crypt K X \<notin> Key ` A" |
869 lemma Crypt_notin_image_Key [simp]: "Crypt K X \<notin> Key ` A" |
870 by auto |
870 by auto |
871 |
871 |
872 lemma synth_analz_mono: "G\<subseteq>H ==> synth (analz(G)) \<subseteq> synth (analz(H))" |
872 lemma synth_analz_mono: "G\<subseteq>H \<Longrightarrow> synth (analz(G)) \<subseteq> synth (analz(H))" |
873 by (iprover intro: synth_mono analz_mono) |
873 by (iprover intro: synth_mono analz_mono) |
874 |
874 |
875 lemma Fake_analz_eq [simp]: |
875 lemma Fake_analz_eq [simp]: |
876 "X \<in> synth(analz H) ==> synth (analz (insert X H)) = synth (analz H)" |
876 "X \<in> synth(analz H) \<Longrightarrow> synth (analz (insert X H)) = synth (analz H)" |
877 apply (drule Fake_analz_insert[of _ _ "H"]) |
877 apply (drule Fake_analz_insert[of _ _ "H"]) |
878 apply (simp add: synth_increasing[THEN Un_absorb2]) |
878 apply (simp add: synth_increasing[THEN Un_absorb2]) |
879 apply (drule synth_mono) |
879 apply (drule synth_mono) |
880 apply (simp add: synth_idem) |
880 apply (simp add: synth_idem) |
881 apply (rule equalityI) |
881 apply (rule equalityI) |
883 apply (rule synth_analz_mono, blast) |
883 apply (rule synth_analz_mono, blast) |
884 done |
884 done |
885 |
885 |
886 text\<open>Two generalizations of @{text analz_insert_eq}\<close> |
886 text\<open>Two generalizations of @{text analz_insert_eq}\<close> |
887 lemma gen_analz_insert_eq [rule_format]: |
887 lemma gen_analz_insert_eq [rule_format]: |
888 "X \<in> analz H ==> ALL G. H \<subseteq> G --> analz (insert X G) = analz G" |
888 "X \<in> analz H \<Longrightarrow> \<forall>G. H \<subseteq> G \<longrightarrow> analz (insert X G) = analz G" |
889 by (blast intro: analz_cut analz_insertI analz_mono [THEN [2] rev_subsetD]) |
889 by (blast intro: analz_cut analz_insertI analz_mono [THEN [2] rev_subsetD]) |
890 |
890 |
891 lemma synth_analz_insert_eq [rule_format]: |
891 lemma synth_analz_insert_eq [rule_format]: |
892 "X \<in> synth (analz H) |
892 "X \<in> synth (analz H) |
893 ==> ALL G. H \<subseteq> G --> (Key K \<in> analz (insert X G)) = (Key K \<in> analz G)" |
893 \<Longrightarrow> \<forall>G. H \<subseteq> G \<longrightarrow> (Key K \<in> analz (insert X G)) = (Key K \<in> analz G)" |
894 apply (erule synth.induct) |
894 apply (erule synth.induct) |
895 apply (simp_all add: gen_analz_insert_eq subset_trans [OF _ subset_insertI]) |
895 apply (simp_all add: gen_analz_insert_eq subset_trans [OF _ subset_insertI]) |
896 done |
896 done |
897 |
897 |
898 lemma Fake_parts_sing: |
898 lemma Fake_parts_sing: |
899 "X \<in> synth (analz H) ==> parts{X} \<subseteq> synth (analz H) \<union> parts H" |
899 "X \<in> synth (analz H) \<Longrightarrow> parts{X} \<subseteq> synth (analz H) \<union> parts H" |
900 apply (rule subset_trans) |
900 apply (rule subset_trans) |
901 apply (erule_tac [2] Fake_parts_insert) |
901 apply (erule_tac [2] Fake_parts_insert) |
902 apply (rule parts_mono, blast) |
902 apply (rule parts_mono, blast) |
903 done |
903 done |
904 |
904 |