src/Doc/Tutorial/Protocol/Message.thy
changeset 67613 ce654b0e6d69
parent 67443 3abf6a722518
child 68237 e7c85e2dc198
equal deleted inserted replaced
67610:4939494ed791 67613:ce654b0e6d69
    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,
   509 done
   509 done
   510 
   510 
   511 
   511 
   512 subsubsection\<open>Idempotence and transitivity\<close>
   512 subsubsection\<open>Idempotence and transitivity\<close>
   513 
   513 
   514 lemma analz_analzD [dest!]: "X\<in> analz (analz H) ==> X\<in> analz H"
   514 lemma analz_analzD [dest!]: "X\<in> analz (analz H) \<Longrightarrow> X\<in> analz H"
   515 by (erule analz.induct, blast+)
   515 by (erule analz.induct, blast+)
   516 
   516 
   517 lemma analz_idem [simp]: "analz (analz H) = analz H"
   517 lemma analz_idem [simp]: "analz (analz H) = analz H"
   518 by blast
   518 by blast
   519 
   519 
   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 
   695 
   695 
   696 lemma Key_synth_eq [simp]: "(Key K \<in> synth H) = (Key K \<in> H)"
   696 lemma Key_synth_eq [simp]: "(Key K \<in> synth H) = (Key K \<in> H)"
   697 by blast
   697 by blast
   698 
   698 
   699 lemma Crypt_synth_eq [simp]:
   699 lemma Crypt_synth_eq [simp]:
   700      "Key K \<notin> H ==> (Crypt K X \<in> synth H) = (Crypt K X \<in> H)"
   700      "Key K \<notin> H \<Longrightarrow> (Crypt K X \<in> synth H) = (Crypt K X \<in> H)"
   701 by blast
   701 by blast
   702 
   702 
   703 
   703 
   704 lemma keysFor_synth [simp]: 
   704 lemma keysFor_synth [simp]: 
   705     "keysFor (synth H) = keysFor H \<union> invKey`{K. Key K \<in> H}"
   705     "keysFor (synth H) = keysFor H \<union> invKey`{K. Key K \<in> H}"
   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