src/HOL/Auth/Event.thy
changeset 76341 d72a8cdca1ab
parent 76299 0ad6f6508274
equal deleted inserted replaced
76340:fdb91b733b65 76341:d72a8cdca1ab
    10 
    10 
    11 section\<open>Theory of Events for Security Protocols\<close>
    11 section\<open>Theory of Events for Security Protocols\<close>
    12 
    12 
    13 theory Event imports Message begin
    13 theory Event imports Message begin
    14 
    14 
    15 consts  (*Initial states of agents -- parameter of the construction*)
    15 consts  \<comment> \<open>Initial states of agents --- a parameter of the construction\<close>
    16   initState :: "agent \<Rightarrow> msg set"
    16   initState :: "agent \<Rightarrow> msg set"
    17 
    17 
    18 datatype
    18 datatype
    19   event = Says  agent agent msg
    19   event = Says  agent agent msg
    20         | Gets  agent       msg
    20         | Gets  agent       msg
    56 
    56 
    57 text\<open>The constant "spies" is retained for compatibility's sake\<close>
    57 text\<open>The constant "spies" is retained for compatibility's sake\<close>
    58 
    58 
    59 abbreviation (input)
    59 abbreviation (input)
    60   spies  :: "event list \<Rightarrow> msg set" where
    60   spies  :: "event list \<Rightarrow> msg set" where
    61   "spies == knows Spy"
    61   "spies \<equiv> knows Spy"
    62 
    62 
    63 
    63 
    64 (*Set of items that might be visible to somebody:
    64 text \<open>Set of items that might be visible to somebody: complement of the set of fresh items\<close>
    65     complement of the set of fresh items*)
       
    66 
       
    67 primrec used :: "event list \<Rightarrow> msg set"
    65 primrec used :: "event list \<Rightarrow> msg set"
    68 where
    66 where
    69   used_Nil:   "used []         = (UN B. parts (initState B))"
    67   used_Nil:   "used []         = (UN B. parts (initState B))"
    70 | used_Cons:  "used (ev # evs) =
    68 | used_Cons:  "used (ev # evs) =
    71                      (case ev of
    69                      (case ev of
    74                       | Notes A X  \<Rightarrow> parts {X} \<union> used evs)"
    72                       | Notes A X  \<Rightarrow> parts {X} \<union> used evs)"
    75     \<comment> \<open>The case for \<^term>\<open>Gets\<close> seems anomalous, but \<^term>\<open>Gets\<close> always
    73     \<comment> \<open>The case for \<^term>\<open>Gets\<close> seems anomalous, but \<^term>\<open>Gets\<close> always
    76         follows \<^term>\<open>Says\<close> in real protocols.  Seems difficult to change.
    74         follows \<^term>\<open>Says\<close> in real protocols.  Seems difficult to change.
    77         See \<open>Gets_correct\<close> in theory \<open>Guard/Extensions.thy\<close>.\<close>
    75         See \<open>Gets_correct\<close> in theory \<open>Guard/Extensions.thy\<close>.\<close>
    78 
    76 
    79 lemma Notes_imp_used [rule_format]: "Notes A X \<in> set evs \<longrightarrow> X \<in> used evs"
    77 lemma Notes_imp_used: "Notes A X \<in> set evs \<Longrightarrow> X \<in> used evs"
    80 apply (induct_tac evs)
    78   by (induct evs) (auto split: event.split) 
    81 apply (auto split: event.split) 
    79 
    82 done
    80 lemma Says_imp_used: "Says A B X \<in> set evs \<Longrightarrow> X \<in> used evs"
    83 
    81   by (induct evs) (auto split: event.split) 
    84 lemma Says_imp_used [rule_format]: "Says A B X \<in> set evs \<longrightarrow> X \<in> used evs"
       
    85 apply (induct_tac evs)
       
    86 apply (auto split: event.split) 
       
    87 done
       
    88 
    82 
    89 
    83 
    90 subsection\<open>Function \<^term>\<open>knows\<close>\<close>
    84 subsection\<open>Function \<^term>\<open>knows\<close>\<close>
    91 
    85 
    92 (*Simplifying   
    86 (*Simplifying   
    93  parts(insert X (knows Spy evs)) = parts{X} \<union> parts(knows Spy evs).
    87  parts(insert X (knows Spy evs)) = parts{X} \<union> parts(knows Spy evs).
    94   This version won't loop with the simplifier.*)
    88   This version won't loop with the simplifier.*)
    95 lemmas parts_insert_knows_A = parts_insert [of _ "knows A evs"] for A evs
    89 lemmas parts_insert_knows_A = parts_insert [of _ "knows A evs"] for A evs
    96 
    90 
    97 lemma knows_Spy_Says [simp]:
    91 lemma knows_Spy_Says [simp]:
    98      "knows Spy (Says A B X # evs) = insert X (knows Spy evs)"
    92   "knows Spy (Says A B X # evs) = insert X (knows Spy evs)"
    99 by simp
    93   by simp
   100 
    94 
   101 text\<open>Letting the Spy see "bad" agents' notes avoids redundant case-splits
    95 text\<open>Letting the Spy see "bad" agents' notes avoids redundant case-splits
   102       on whether \<^term>\<open>A=Spy\<close> and whether \<^term>\<open>A\<in>bad\<close>\<close>
    96       on whether \<^term>\<open>A=Spy\<close> and whether \<^term>\<open>A\<in>bad\<close>\<close>
   103 lemma knows_Spy_Notes [simp]:
    97 lemma knows_Spy_Notes [simp]:
   104      "knows Spy (Notes A X # evs) =  
    98   "knows Spy (Notes A X # evs) =  
   105           (if A\<in>bad then insert X (knows Spy evs) else knows Spy evs)"
    99           (if A\<in>bad then insert X (knows Spy evs) else knows Spy evs)"
   106 by simp
   100   by simp
   107 
   101 
   108 lemma knows_Spy_Gets [simp]: "knows Spy (Gets A X # evs) = knows Spy evs"
   102 lemma knows_Spy_Gets [simp]: "knows Spy (Gets A X # evs) = knows Spy evs"
   109 by simp
   103   by simp
   110 
   104 
   111 lemma knows_Spy_subset_knows_Spy_Says:
   105 lemma knows_Spy_subset_knows_Spy_Says:
   112      "knows Spy evs \<subseteq> knows Spy (Says A B X # evs)"
   106   "knows Spy evs \<subseteq> knows Spy (Says A B X # evs)"
   113 by (simp add: subset_insertI)
   107   by (simp add: subset_insertI)
   114 
   108 
   115 lemma knows_Spy_subset_knows_Spy_Notes:
   109 lemma knows_Spy_subset_knows_Spy_Notes:
   116      "knows Spy evs \<subseteq> knows Spy (Notes A X # evs)"
   110   "knows Spy evs \<subseteq> knows Spy (Notes A X # evs)"
   117 by force
   111   by force
   118 
   112 
   119 lemma knows_Spy_subset_knows_Spy_Gets:
   113 lemma knows_Spy_subset_knows_Spy_Gets:
   120      "knows Spy evs \<subseteq> knows Spy (Gets A X # evs)"
   114   "knows Spy evs \<subseteq> knows Spy (Gets A X # evs)"
   121 by (simp add: subset_insertI)
   115   by (simp add: subset_insertI)
   122 
   116 
   123 text\<open>Spy sees what is sent on the traffic\<close>
   117 text\<open>Spy sees what is sent on the traffic\<close>
   124 lemma Says_imp_knows_Spy [rule_format]:
   118 lemma Says_imp_knows_Spy:
   125      "Says A B X \<in> set evs \<longrightarrow> X \<in> knows Spy evs"
   119      "Says A B X \<in> set evs \<Longrightarrow> X \<in> knows Spy evs"
   126 apply (induct_tac "evs")
   120   by (induct evs) (auto split: event.split) 
   127 apply (simp_all (no_asm_simp) split: event.split)
       
   128 done
       
   129 
   121 
   130 lemma Notes_imp_knows_Spy [rule_format]:
   122 lemma Notes_imp_knows_Spy [rule_format]:
   131      "Notes A X \<in> set evs \<longrightarrow> A \<in> bad \<longrightarrow> X \<in> knows Spy evs"
   123      "Notes A X \<in> set evs \<Longrightarrow> A \<in> bad \<Longrightarrow> X \<in> knows Spy evs"
   132 apply (induct_tac "evs")
   124   by (induct evs) (auto split: event.split) 
   133 apply (simp_all (no_asm_simp) split: event.split)
       
   134 done
       
   135 
   125 
   136 
   126 
   137 text\<open>Elimination rules: derive contradictions from old Says events containing
   127 text\<open>Elimination rules: derive contradictions from old Says events containing
   138   items known to be fresh\<close>
   128   items known to be fresh\<close>
   139 lemmas Says_imp_parts_knows_Spy = 
   129 lemmas Says_imp_parts_knows_Spy = 
   151 
   141 
   152 
   142 
   153 subsection\<open>Knowledge of Agents\<close>
   143 subsection\<open>Knowledge of Agents\<close>
   154 
   144 
   155 lemma knows_subset_knows_Says: "knows A evs \<subseteq> knows A (Says A' B X # evs)"
   145 lemma knows_subset_knows_Says: "knows A evs \<subseteq> knows A (Says A' B X # evs)"
   156 by (simp add: subset_insertI)
   146   by (simp add: subset_insertI)
   157 
   147 
   158 lemma knows_subset_knows_Notes: "knows A evs \<subseteq> knows A (Notes A' X # evs)"
   148 lemma knows_subset_knows_Notes: "knows A evs \<subseteq> knows A (Notes A' X # evs)"
   159 by (simp add: subset_insertI)
   149   by (simp add: subset_insertI)
   160 
   150 
   161 lemma knows_subset_knows_Gets: "knows A evs \<subseteq> knows A (Gets A' X # evs)"
   151 lemma knows_subset_knows_Gets: "knows A evs \<subseteq> knows A (Gets A' X # evs)"
   162 by (simp add: subset_insertI)
   152   by (simp add: subset_insertI)
   163 
   153 
   164 text\<open>Agents know what they say\<close>
   154 text\<open>Agents know what they say\<close>
   165 lemma Says_imp_knows [rule_format]: "Says A B X \<in> set evs \<longrightarrow> X \<in> knows A evs"
   155 lemma Says_imp_knows [rule_format]: "Says A B X \<in> set evs \<Longrightarrow> X \<in> knows A evs"
   166 apply (induct_tac "evs")
   156   by (induct evs) (force split: event.split)+
   167 apply (simp_all (no_asm_simp) split: event.split)
       
   168 apply blast
       
   169 done
       
   170 
   157 
   171 text\<open>Agents know what they note\<close>
   158 text\<open>Agents know what they note\<close>
   172 lemma Notes_imp_knows [rule_format]: "Notes A X \<in> set evs \<longrightarrow> X \<in> knows A evs"
   159 lemma Notes_imp_knows [rule_format]: "Notes A X \<in> set evs \<Longrightarrow> X \<in> knows A evs"
   173 apply (induct_tac "evs")
   160   by (induct evs) (force split: event.split)+
   174 apply (simp_all (no_asm_simp) split: event.split)
       
   175 apply blast
       
   176 done
       
   177 
   161 
   178 text\<open>Agents know what they receive\<close>
   162 text\<open>Agents know what they receive\<close>
   179 lemma Gets_imp_knows_agents [rule_format]:
   163 lemma Gets_imp_knows_agents [rule_format]:
   180      "A \<noteq> Spy \<longrightarrow> Gets A X \<in> set evs \<longrightarrow> X \<in> knows A evs"
   164      "A \<noteq> Spy \<Longrightarrow> Gets A X \<in> set evs \<Longrightarrow> X \<in> knows A evs"
   181 apply (induct_tac "evs")
   165   by (induct evs) (force split: event.split)+
   182 apply (simp_all (no_asm_simp) split: event.split)
       
   183 done
       
   184 
       
   185 
   166 
   186 text\<open>What agents DIFFERENT FROM Spy know 
   167 text\<open>What agents DIFFERENT FROM Spy know 
   187   was either said, or noted, or got, or known initially\<close>
   168   was either said, or noted, or got, or known initially\<close>
   188 lemma knows_imp_Says_Gets_Notes_initState [rule_format]:
   169 lemma knows_imp_Says_Gets_Notes_initState:
   189      "\<lbrakk>X \<in> knows A evs; A \<noteq> Spy\<rbrakk> \<Longrightarrow> \<exists> B.
   170   "\<lbrakk>X \<in> knows A evs; A \<noteq> Spy\<rbrakk> \<Longrightarrow> 
   190   Says A B X \<in> set evs \<or> Gets A X \<in> set evs \<or> Notes A X \<in> set evs \<or> X \<in> initState A"
   171      \<exists>B. Says A B X \<in> set evs \<or> Gets A X \<in> set evs \<or> Notes A X \<in> set evs \<or> X \<in> initState A"
   191 apply (erule rev_mp)
   172   by(induct evs) (auto split: event.split_asm if_split_asm)
   192 apply (induct_tac "evs")
       
   193 apply (simp_all (no_asm_simp) split: event.split)
       
   194 apply blast
       
   195 done
       
   196 
   173 
   197 text\<open>What the Spy knows -- for the time being --
   174 text\<open>What the Spy knows -- for the time being --
   198   was either said or noted, or known initially\<close>
   175   was either said or noted, or known initially\<close>
   199 lemma knows_Spy_imp_Says_Notes_initState [rule_format]:
   176 lemma knows_Spy_imp_Says_Notes_initState:
   200      "X \<in> knows Spy evs \<Longrightarrow> \<exists>A B.
   177   "X \<in> knows Spy evs \<Longrightarrow> 
   201   Says A B X \<in> set evs \<or> Notes A X \<in> set evs \<or> X \<in> initState Spy"
   178     \<exists>A B. Says A B X \<in> set evs \<or> Notes A X \<in> set evs \<or> X \<in> initState Spy"
   202 apply (erule rev_mp)
   179   by(induct evs) (auto split: event.split_asm if_split_asm)
   203 apply (induct_tac "evs")
       
   204 apply (simp_all (no_asm_simp) split: event.split)
       
   205 apply blast
       
   206 done
       
   207 
   180 
   208 lemma parts_knows_Spy_subset_used: "parts (knows Spy evs) \<subseteq> used evs"
   181 lemma parts_knows_Spy_subset_used: "parts (knows Spy evs) \<subseteq> used evs"
   209 apply (induct_tac "evs", force)  
   182   by (induct evs) (auto simp: parts_insert_knows_A split: event.split_asm if_split_asm)
   210 apply (simp add: parts_insert_knows_A knows_Cons add: event.split, blast) 
       
   211 done
       
   212 
   183 
   213 lemmas usedI = parts_knows_Spy_subset_used [THEN subsetD, intro]
   184 lemmas usedI = parts_knows_Spy_subset_used [THEN subsetD, intro]
   214 
   185 
   215 lemma initState_into_used: "X \<in> parts (initState B) \<Longrightarrow> X \<in> used evs"
   186 lemma initState_into_used: "X \<in> parts (initState B) \<Longrightarrow> X \<in> used evs"
   216 apply (induct_tac "evs")
   187   by (induct evs) (auto simp: parts_insert_knows_A split: event.split)
   217 apply (simp_all add: parts_insert_knows_A split: event.split, blast)
   188 
   218 done
   189 text \<open>New simprules to replace the primitive ones for @{term used} and @{term knows}\<close>
   219 
   190 
   220 lemma used_Says [simp]: "used (Says A B X # evs) = parts{X} \<union> used evs"
   191 lemma used_Says [simp]: "used (Says A B X # evs) = parts{X} \<union> used evs"
   221 by simp
   192   by simp
   222 
   193 
   223 lemma used_Notes [simp]: "used (Notes A X # evs) = parts{X} \<union> used evs"
   194 lemma used_Notes [simp]: "used (Notes A X # evs) = parts{X} \<union> used evs"
   224 by simp
   195   by simp
   225 
   196 
   226 lemma used_Gets [simp]: "used (Gets A X # evs) = used evs"
   197 lemma used_Gets [simp]: "used (Gets A X # evs) = used evs"
   227 by simp
   198   by simp
   228 
   199 
   229 lemma used_nil_subset: "used [] \<subseteq> used evs"
   200 lemma used_nil_subset: "used [] \<subseteq> used evs"
   230 apply simp
   201   using initState_into_used by auto
   231 apply (blast intro: initState_into_used)
   202 
   232 done
   203 text\<open>NOTE REMOVAL: the laws above are cleaner, as they don't involve "case"\<close>
   233 
       
   234 text\<open>NOTE REMOVAL--laws above are cleaner, as they don't involve "case"\<close>
       
   235 declare knows_Cons [simp del]
   204 declare knows_Cons [simp del]
   236         used_Nil [simp del] used_Cons [simp del]
   205         used_Nil [simp del] used_Cons [simp del]
   237 
   206 
   238 
   207 
   239 text\<open>For proving theorems of the form \<^term>\<open>X \<notin> analz (knows Spy evs) \<longrightarrow> P\<close>
   208 text\<open>For proving theorems of the form \<^term>\<open>X \<notin> analz (knows Spy evs) \<longrightarrow> P\<close>
   246        knows_Spy_subset_knows_Spy_Notes [THEN analz_mono, THEN contra_subsetD]
   215        knows_Spy_subset_knows_Spy_Notes [THEN analz_mono, THEN contra_subsetD]
   247        knows_Spy_subset_knows_Spy_Gets [THEN analz_mono, THEN contra_subsetD]
   216        knows_Spy_subset_knows_Spy_Gets [THEN analz_mono, THEN contra_subsetD]
   248 
   217 
   249 
   218 
   250 lemma knows_subset_knows_Cons: "knows A evs \<subseteq> knows A (e # evs)"
   219 lemma knows_subset_knows_Cons: "knows A evs \<subseteq> knows A (e # evs)"
   251 by (cases e, auto simp: knows_Cons)
   220   by (cases e, auto simp: knows_Cons)
   252 
   221 
   253 lemma initState_subset_knows: "initState A \<subseteq> knows A evs"
   222 lemma initState_subset_knows: "initState A \<subseteq> knows A evs"
   254 apply (induct_tac evs, simp) 
   223   by (induct evs) (use knows_subset_knows_Cons in fastforce)+
   255 apply (blast intro: knows_subset_knows_Cons [THEN subsetD])
       
   256 done
       
   257 
       
   258 
   224 
   259 text\<open>For proving \<open>new_keys_not_used\<close>\<close>
   225 text\<open>For proving \<open>new_keys_not_used\<close>\<close>
   260 lemma keysFor_parts_insert:
   226 lemma keysFor_parts_insert:
   261      "\<lbrakk>K \<in> keysFor (parts (insert X G));  X \<in> synth (analz H)\<rbrakk> 
   227      "\<lbrakk>K \<in> keysFor (parts (insert X G));  X \<in> synth (analz H)\<rbrakk> 
   262       \<Longrightarrow> K \<in> keysFor (parts (G \<union> H)) | Key (invKey K) \<in> parts H"
   228       \<Longrightarrow> K \<in> keysFor (parts (G \<union> H)) | Key (invKey K) \<in> parts H"