6 - Guard is replaced by GuardK, guard by guardK, Nonce by Key |
6 - Guard is replaced by GuardK, guard by guardK, Nonce by Key |
7 - some scripts are slightly modified (+ keyset_in, kparts_parts) |
7 - some scripts are slightly modified (+ keyset_in, kparts_parts) |
8 - the hypothesis Key n ~:G (keyset G) is added |
8 - the hypothesis Key n ~:G (keyset G) is added |
9 *) |
9 *) |
10 |
10 |
11 section{*protocol-independent confidentiality theorem on keys*} |
11 section\<open>protocol-independent confidentiality theorem on keys\<close> |
12 |
12 |
13 theory GuardK |
13 theory GuardK |
14 imports Analz Extensions |
14 imports Analz Extensions |
15 begin |
15 begin |
16 |
16 |
26 No_Key [intro]: "Key n ~:parts {X} ==> X:guardK n Ks" |
26 No_Key [intro]: "Key n ~:parts {X} ==> X:guardK n Ks" |
27 | Guard_Key [intro]: "invKey K:Ks ==> Crypt K X:guardK n Ks" |
27 | Guard_Key [intro]: "invKey K:Ks ==> Crypt K X:guardK n Ks" |
28 | Crypt [intro]: "X:guardK n Ks ==> Crypt K X:guardK n Ks" |
28 | Crypt [intro]: "X:guardK n Ks ==> Crypt K X:guardK n Ks" |
29 | Pair [intro]: "[| X:guardK n Ks; Y:guardK n Ks |] ==> {|X,Y|}:guardK n Ks" |
29 | Pair [intro]: "[| X:guardK n Ks; Y:guardK n Ks |] ==> {|X,Y|}:guardK n Ks" |
30 |
30 |
31 subsection{*basic facts about @{term guardK}*} |
31 subsection\<open>basic facts about @{term guardK}\<close> |
32 |
32 |
33 lemma Nonce_is_guardK [iff]: "Nonce p:guardK n Ks" |
33 lemma Nonce_is_guardK [iff]: "Nonce p:guardK n Ks" |
34 by auto |
34 by auto |
35 |
35 |
36 lemma Agent_is_guardK [iff]: "Agent A:guardK n Ks" |
36 lemma Agent_is_guardK [iff]: "Agent A:guardK n Ks" |
75 |
75 |
76 lemma guardK_extand: "[| X:guardK n Ks; Ks <= Ks'; |
76 lemma guardK_extand: "[| X:guardK n Ks; Ks <= Ks'; |
77 [| K:Ks'; K ~:Ks |] ==> Key K ~:parts {X} |] ==> X:guardK n Ks'" |
77 [| K:Ks'; K ~:Ks |] ==> Key K ~:parts {X} |] ==> X:guardK n Ks'" |
78 by (erule guardK.induct, auto) |
78 by (erule guardK.induct, auto) |
79 |
79 |
80 subsection{*guarded sets*} |
80 subsection\<open>guarded sets\<close> |
81 |
81 |
82 definition GuardK :: "nat => key set => msg set => bool" where |
82 definition GuardK :: "nat => key set => msg set => bool" where |
83 "GuardK n Ks H == ALL X. X:H --> X:guardK n Ks" |
83 "GuardK n Ks H == ALL X. X:H --> X:guardK n Ks" |
84 |
84 |
85 subsection{*basic facts about @{term GuardK}*} |
85 subsection\<open>basic facts about @{term GuardK}\<close> |
86 |
86 |
87 lemma GuardK_empty [iff]: "GuardK n Ks {}" |
87 lemma GuardK_empty [iff]: "GuardK n Ks {}" |
88 by (simp add: GuardK_def) |
88 by (simp add: GuardK_def) |
89 |
89 |
90 lemma Key_notin_kparts [simplified]: "GuardK n Ks H ==> Key n ~:kparts H" |
90 lemma Key_notin_kparts [simplified]: "GuardK n Ks H ==> Key n ~:kparts H" |
150 |
150 |
151 lemma GuardK_extand: "[| GuardK n Ks G; Ks <= Ks'; |
151 lemma GuardK_extand: "[| GuardK n Ks G; Ks <= Ks'; |
152 [| K:Ks'; K ~:Ks |] ==> Key K ~:parts G |] ==> GuardK n Ks' G" |
152 [| K:Ks'; K ~:Ks |] ==> Key K ~:parts G |] ==> GuardK n Ks' G" |
153 by (auto simp: GuardK_def dest: guardK_extand parts_sub) |
153 by (auto simp: GuardK_def dest: guardK_extand parts_sub) |
154 |
154 |
155 subsection{*set obtained by decrypting a message*} |
155 subsection\<open>set obtained by decrypting a message\<close> |
156 |
156 |
157 abbreviation (input) |
157 abbreviation (input) |
158 decrypt :: "msg set => key => msg => msg set" where |
158 decrypt :: "msg set => key => msg => msg set" where |
159 "decrypt H K Y == insert Y (H - {Crypt K Y})" |
159 "decrypt H K Y == insert Y (H - {Crypt K Y})" |
160 |
160 |
166 done |
166 done |
167 |
167 |
168 lemma parts_decrypt: "[| Crypt K Y:H; X:parts (decrypt H K Y) |] ==> X:parts H" |
168 lemma parts_decrypt: "[| Crypt K Y:H; X:parts (decrypt H K Y) |] ==> X:parts H" |
169 by (erule parts.induct, auto intro: parts.Fst parts.Snd parts.Body) |
169 by (erule parts.induct, auto intro: parts.Fst parts.Snd parts.Body) |
170 |
170 |
171 subsection{*number of Crypt's in a message*} |
171 subsection\<open>number of Crypt's in a message\<close> |
172 |
172 |
173 fun crypt_nb :: "msg => nat" where |
173 fun crypt_nb :: "msg => nat" where |
174 "crypt_nb (Crypt K X) = Suc (crypt_nb X)" | |
174 "crypt_nb (Crypt K X) = Suc (crypt_nb X)" | |
175 "crypt_nb {|X,Y|} = crypt_nb X + crypt_nb Y" | |
175 "crypt_nb {|X,Y|} = crypt_nb X + crypt_nb Y" | |
176 "crypt_nb X = 0" (* otherwise *) |
176 "crypt_nb X = 0" (* otherwise *) |
177 |
177 |
178 subsection{*basic facts about @{term crypt_nb}*} |
178 subsection\<open>basic facts about @{term crypt_nb}\<close> |
179 |
179 |
180 lemma non_empty_crypt_msg: "Crypt K Y:parts {X} ==> crypt_nb X \<noteq> 0" |
180 lemma non_empty_crypt_msg: "Crypt K Y:parts {X} ==> crypt_nb X \<noteq> 0" |
181 by (induct X, simp_all, safe, simp_all) |
181 by (induct X, simp_all, safe, simp_all) |
182 |
182 |
183 subsection{*number of Crypt's in a message list*} |
183 subsection\<open>number of Crypt's in a message list\<close> |
184 |
184 |
185 primrec cnb :: "msg list => nat" where |
185 primrec cnb :: "msg list => nat" where |
186 "cnb [] = 0" | |
186 "cnb [] = 0" | |
187 "cnb (X#l) = crypt_nb X + cnb l" |
187 "cnb (X#l) = crypt_nb X + cnb l" |
188 |
188 |
189 subsection{*basic facts about @{term cnb}*} |
189 subsection\<open>basic facts about @{term cnb}\<close> |
190 |
190 |
191 lemma cnb_app [simp]: "cnb (l @ l') = cnb l + cnb l'" |
191 lemma cnb_app [simp]: "cnb (l @ l') = cnb l + cnb l'" |
192 by (induct l, auto) |
192 by (induct l, auto) |
193 |
193 |
194 lemma mem_cnb_minus: "x \<in> set l ==> cnb l = crypt_nb x + (cnb l - crypt_nb x)" |
194 lemma mem_cnb_minus: "x \<in> set l ==> cnb l = crypt_nb x + (cnb l - crypt_nb x)" |
205 by (erule parts.induct, auto simp: in_set_conv_decomp) |
205 by (erule parts.induct, auto simp: in_set_conv_decomp) |
206 |
206 |
207 lemma non_empty_crypt: "Crypt K Y:parts (set l) ==> cnb l \<noteq> 0" |
207 lemma non_empty_crypt: "Crypt K Y:parts (set l) ==> cnb l \<noteq> 0" |
208 by (induct l, auto dest: non_empty_crypt_msg parts_insert_substD) |
208 by (induct l, auto dest: non_empty_crypt_msg parts_insert_substD) |
209 |
209 |
210 subsection{*list of kparts*} |
210 subsection\<open>list of kparts\<close> |
211 |
211 |
212 lemma kparts_msg_set: "EX l. kparts {X} = set l & cnb l = crypt_nb X" |
212 lemma kparts_msg_set: "EX l. kparts {X} = set l & cnb l = crypt_nb X" |
213 apply (induct X, simp_all) |
213 apply (induct X, simp_all) |
214 apply (rename_tac agent, rule_tac x="[Agent agent]" in exI, simp) |
214 apply (rename_tac agent, rule_tac x="[Agent agent]" in exI, simp) |
215 apply (rename_tac nat, rule_tac x="[Number nat]" in exI, simp) |
215 apply (rename_tac nat, rule_tac x="[Number nat]" in exI, simp) |
226 apply (subgoal_tac "EX l''. kparts {a} = set l'' & cnb l'' = crypt_nb a", clarify) |
226 apply (subgoal_tac "EX l''. kparts {a} = set l'' & cnb l'' = crypt_nb a", clarify) |
227 apply (rule_tac x="l''@l'" in exI, simp) |
227 apply (rule_tac x="l''@l'" in exI, simp) |
228 apply (rule kparts_insert_substI, simp) |
228 apply (rule kparts_insert_substI, simp) |
229 by (rule kparts_msg_set) |
229 by (rule kparts_msg_set) |
230 |
230 |
231 subsection{*list corresponding to "decrypt"*} |
231 subsection\<open>list corresponding to "decrypt"\<close> |
232 |
232 |
233 definition decrypt' :: "msg list => key => msg => msg list" where |
233 definition decrypt' :: "msg list => key => msg => msg list" where |
234 "decrypt' l K Y == Y # remove l (Crypt K Y)" |
234 "decrypt' l K Y == Y # remove l (Crypt K Y)" |
235 |
235 |
236 declare decrypt'_def [simp] |
236 declare decrypt'_def [simp] |
237 |
237 |
238 subsection{*basic facts about @{term decrypt'}*} |
238 subsection\<open>basic facts about @{term decrypt'}\<close> |
239 |
239 |
240 lemma decrypt_minus: "decrypt (set l) K Y <= set (decrypt' l K Y)" |
240 lemma decrypt_minus: "decrypt (set l) K Y <= set (decrypt' l K Y)" |
241 by (induct l, auto) |
241 by (induct l, auto) |
242 |
242 |
243 text{*if the analysis of a finite guarded set gives n then it must also give |
243 text\<open>if the analysis of a finite guarded set gives n then it must also give |
244 one of the keys of Ks*} |
244 one of the keys of Ks\<close> |
245 |
245 |
246 lemma GuardK_invKey_by_list [rule_format]: "ALL l. cnb l = p |
246 lemma GuardK_invKey_by_list [rule_format]: "ALL l. cnb l = p |
247 --> GuardK n Ks (set l) --> Key n:analz (set l) |
247 --> GuardK n Ks (set l) --> Key n:analz (set l) |
248 --> (EX K. K:Ks & Key K:analz (set l))" |
248 --> (EX K. K:Ks & Key K:analz (set l))" |
249 apply (induct p) |
249 apply (induct p) |
287 |
287 |
288 lemma GuardK_invKey: "[| Key n:analz G; GuardK n Ks G |] |
288 lemma GuardK_invKey: "[| Key n:analz G; GuardK n Ks G |] |
289 ==> EX K. K:Ks & Key K:analz G" |
289 ==> EX K. K:Ks & Key K:analz G" |
290 by (auto dest: analz_needs_only_finite GuardK_invKey_finite) |
290 by (auto dest: analz_needs_only_finite GuardK_invKey_finite) |
291 |
291 |
292 text{*if the analyse of a finite guarded set and a (possibly infinite) set of |
292 text\<open>if the analyse of a finite guarded set and a (possibly infinite) set of |
293 keys gives n then it must also gives Ks*} |
293 keys gives n then it must also gives Ks\<close> |
294 |
294 |
295 lemma GuardK_invKey_keyset: "[| Key n:analz (G Un H); GuardK n Ks G; finite G; |
295 lemma GuardK_invKey_keyset: "[| Key n:analz (G Un H); GuardK n Ks G; finite G; |
296 keyset H; Key n ~:H |] ==> EX K. K:Ks & Key K:analz (G Un H)" |
296 keyset H; Key n ~:H |] ==> EX K. K:Ks & Key K:analz (G Un H)" |
297 apply (frule_tac P="%G. Key n:G" and G=G in analz_keyset_substD, simp_all) |
297 apply (frule_tac P="%G. Key n:G" and G=G in analz_keyset_substD, simp_all) |
298 apply (drule_tac G="G Un (H Int keysfor G)" in GuardK_invKey_finite) |
298 apply (drule_tac G="G Un (H Int keysfor G)" in GuardK_invKey_finite) |