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" |