8 From page 257 of |
8 From page 257 of |
9 Burrows, Abadi and Needham. A Logic of Authentication. |
9 Burrows, Abadi and Needham. A Logic of Authentication. |
10 Proc. Royal Soc. 426 (1989) |
10 Proc. Royal Soc. 426 (1989) |
11 *) |
11 *) |
12 |
12 |
13 open OtwayRees; |
13 open Yahalom; |
14 |
14 |
15 proof_timing:=true; |
15 proof_timing:=true; |
16 HOL_quantifiers := false; |
16 HOL_quantifiers := false; |
|
17 |
|
18 |
|
19 (** Weak liveness: there are traces that reach the end **) |
|
20 |
|
21 goal thy |
|
22 "!!A B. [| A ~= B; A ~= Server; B ~= Server |] \ |
|
23 \ ==> EX X NB K. EX evs: yahalom. \ |
|
24 \ Says A B {|X, Crypt (Nonce NB) K|} : set_of_list evs"; |
|
25 by (REPEAT (resolve_tac [exI,bexI] 1)); |
|
26 br (yahalom.Nil RS yahalom.YM1 RS yahalom.YM2 RS yahalom.YM3 RS yahalom.YM4) 2; |
|
27 by (ALLGOALS (simp_tac (!simpset setsolver safe_solver))); |
|
28 by (ALLGOALS Fast_tac); |
|
29 qed "weak_liveness"; |
|
30 |
17 |
31 |
18 (**** Inductive proofs about yahalom ****) |
32 (**** Inductive proofs about yahalom ****) |
19 |
33 |
20 (*The Enemy can see more than anybody else, except for their initial state*) |
34 (*The Enemy can see more than anybody else, except for their initial state*) |
21 goal thy |
35 goal thy |
43 AddSEs [not_Notes RSN (2, rev_notE)]; |
57 AddSEs [not_Notes RSN (2, rev_notE)]; |
44 |
58 |
45 |
59 |
46 (** For reasoning about the encrypted portion of messages **) |
60 (** For reasoning about the encrypted portion of messages **) |
47 |
61 |
48 goal thy "!!evs. (Says A' B {|N, Agent A, Agent B, X|}) : set_of_list evs ==> \ |
62 (*Lets us treat YM4 using a similar argument as for the Fake case.*) |
49 \ X : analz (sees Enemy evs)"; |
63 goal thy "!!evs. Says S A {|Crypt Y (shrK A), X|} : set_of_list evs ==> \ |
50 by (fast_tac (!claset addSDs [Says_imp_sees_Enemy RS analz.Inj]) 1); |
|
51 qed "YM2_analz_sees_Enemy"; |
|
52 |
|
53 goal thy "!!evs. (Says S B {|N, X, X'|}) : set_of_list evs ==> \ |
|
54 \ X : analz (sees Enemy evs)"; |
64 \ X : analz (sees Enemy evs)"; |
55 by (fast_tac (!claset addSDs [Says_imp_sees_Enemy RS analz.Inj]) 1); |
65 by (fast_tac (!claset addSDs [Says_imp_sees_Enemy RS analz.Inj]) 1); |
56 qed "YM4_analz_sees_Enemy"; |
66 qed "YM4_analz_sees_Enemy"; |
57 |
67 |
58 goal thy "!!evs. (Says B' A {|N, Crypt {|N,K|} K'|}) : set_of_list evs ==> \ |
68 goal thy "!!evs. Says S A {|Crypt {|B, K, NA, NB|} (shrK A), X|} \ |
|
69 \ : set_of_list evs ==> \ |
59 \ K : parts (sees Enemy evs)"; |
70 \ K : parts (sees Enemy evs)"; |
60 by (fast_tac (!claset addSEs partsEs |
71 by (fast_tac (!claset addSEs partsEs |
61 addSDs [Says_imp_sees_Enemy RS parts.Inj]) 1); |
72 addSDs [Says_imp_sees_Enemy RS parts.Inj]) 1); |
62 qed "YM5_parts_sees_Enemy"; |
73 qed "YM4_parts_sees_Enemy"; |
63 |
74 |
64 (*YM2_analz... and YM4_analz... let us treat those cases using the same |
|
65 argument as for the Fake case. This is possible for most, but not all, |
|
66 proofs: Fake does not invent new nonces (as in YM2), and of course Fake |
|
67 messages originate from the Enemy. *) |
|
68 |
|
69 val YM2_YM4_tac = |
|
70 dtac (YM2_analz_sees_Enemy RS (impOfSubs analz_subset_parts)) 4 THEN |
|
71 dtac (YM4_analz_sees_Enemy RS (impOfSubs analz_subset_parts)) 6; |
|
72 |
75 |
73 |
76 |
74 (*** Shared keys are not betrayed ***) |
77 (*** Shared keys are not betrayed ***) |
75 |
78 |
76 (*Enemy never sees another agent's shared key! (unless it is leaked at start)*) |
79 (*Enemy never sees another agent's shared key! (unless it is leaked at start)*) |
77 goal thy |
80 goal thy |
78 "!!evs. [| evs : yahalom; A ~: bad |] ==> \ |
81 "!!evs. [| evs : yahalom; A ~: bad |] ==> \ |
79 \ Key (shrK A) ~: parts (sees Enemy evs)"; |
82 \ Key (shrK A) ~: parts (sees Enemy evs)"; |
80 be yahalom.induct 1; |
83 be yahalom.induct 1; |
81 by YM2_YM4_tac; |
84 bd (YM4_analz_sees_Enemy RS synth.Inj) 6; |
|
85 by (ALLGOALS Asm_simp_tac); |
|
86 by (stac insert_commute 3); |
82 by (Auto_tac()); |
87 by (Auto_tac()); |
83 (*Deals with Fake message*) |
88 (*Fake and YM4 are similar*) |
84 by (best_tac (!claset addDs [impOfSubs analz_subset_parts, |
89 by (ALLGOALS (best_tac (!claset addSDs [impOfSubs analz_subset_parts, |
85 impOfSubs Fake_parts_insert]) 1); |
90 impOfSubs Fake_parts_insert]))); |
86 qed "Enemy_not_see_shrK"; |
91 qed "Enemy_not_see_shrK"; |
87 |
92 |
88 bind_thm ("Enemy_not_analz_shrK", |
93 bind_thm ("Enemy_not_analz_shrK", |
89 [analz_subset_parts, Enemy_not_see_shrK] MRS contra_subsetD); |
94 [analz_subset_parts, Enemy_not_see_shrK] MRS contra_subsetD); |
90 |
95 |
119 induction! *) |
124 induction! *) |
120 goal thy "!!evs. evs : yahalom ==> \ |
125 goal thy "!!evs. evs : yahalom ==> \ |
121 \ length evs <= length evs' --> \ |
126 \ length evs <= length evs' --> \ |
122 \ Key (newK evs') ~: (UN C. parts (sees C evs))"; |
127 \ Key (newK evs') ~: (UN C. parts (sees C evs))"; |
123 be yahalom.induct 1; |
128 be yahalom.induct 1; |
124 by YM2_YM4_tac; |
129 bd (YM4_analz_sees_Enemy RS synth.Inj) 6; |
125 (*auto_tac does not work here, as it performs safe_tac first*) |
|
126 by (ALLGOALS Asm_simp_tac); |
|
127 by (REPEAT_FIRST (best_tac (!claset addDs [impOfSubs analz_subset_parts, |
130 by (REPEAT_FIRST (best_tac (!claset addDs [impOfSubs analz_subset_parts, |
128 impOfSubs parts_insert_subset_Un, |
131 impOfSubs parts_insert_subset_Un, |
129 Suc_leD] |
132 Suc_leD] |
130 addss (!simpset)))); |
133 addss (!simpset)))); |
131 val lemma = result(); |
134 val lemma = result(); |
132 |
135 |
133 (*Variant needed for the main theorem below*) |
136 (*Variant needed for the main theorem below*) |
134 goal thy |
137 goal thy |
135 "!!evs. [| evs : yahalom; length evs <= length evs' |] ==> \ |
138 "!!evs. [| evs : yahalom; length evs <= length evs' |] ==> \ |
154 ...very like new_keys_not_seen*) |
157 ...very like new_keys_not_seen*) |
155 goal thy "!!evs. evs : yahalom ==> \ |
158 goal thy "!!evs. evs : yahalom ==> \ |
156 \ length evs <= length evs' --> \ |
159 \ length evs <= length evs' --> \ |
157 \ newK evs' ~: keysFor (UN C. parts (sees C evs))"; |
160 \ newK evs' ~: keysFor (UN C. parts (sees C evs))"; |
158 be yahalom.induct 1; |
161 be yahalom.induct 1; |
159 by YM2_YM4_tac; |
162 by (forward_tac [YM4_parts_sees_Enemy] 6); |
160 bd YM5_parts_sees_Enemy 7; |
163 bd (YM4_analz_sees_Enemy RS synth.Inj) 6; |
161 by (ALLGOALS Asm_simp_tac); |
164 by (ALLGOALS Asm_full_simp_tac); |
162 (*YM1 and YM3*) |
165 (*YM1, YM2 and YM3*) |
163 by (EVERY (map (fast_tac (!claset addDs [Suc_leD] addss (!simpset))) [4,2])); |
166 by (EVERY (map (fast_tac (!claset addDs [Suc_leD] addss (!simpset))) [4,3,2])); |
164 (*Fake, YM2, YM4: these messages send unknown (X) components*) |
167 (*Fake and YM4: these messages send unknown (X) components*) |
165 by (EVERY |
168 by (stac insert_commute 2); |
166 (map |
169 by (Simp_tac 2); |
|
170 (*YM4: the only way K could have been used is if it had been seen, |
|
171 contradicting new_keys_not_seen*) |
|
172 by (ALLGOALS |
167 (best_tac |
173 (best_tac |
168 (!claset addSDs [newK_invKey] |
174 (!claset addDs [impOfSubs (analz_subset_parts RS keysFor_mono), |
169 addDs [impOfSubs (analz_subset_parts RS keysFor_mono), |
|
170 impOfSubs (parts_insert_subset_Un RS keysFor_mono), |
175 impOfSubs (parts_insert_subset_Un RS keysFor_mono), |
171 Suc_leD] |
176 Suc_leD] |
172 addEs [new_keys_not_seen RS not_parts_not_analz RSN(2,rev_notE)] |
177 addDs [impOfSubs analz_subset_parts] |
173 addss (!simpset))) |
178 addEs [new_keys_not_seen RSN(2,rev_notE)] |
174 [3,2,1])); |
179 addss (!simpset)))); |
175 (*YM5: dummy message*) |
|
176 by (best_tac (!claset addSDs [newK_invKey] |
|
177 addEs [new_keys_not_seen RSN(2,rev_notE)] |
|
178 addIs [less_SucI, impOfSubs keysFor_mono] |
|
179 addss (!simpset addsimps [le_def])) 1); |
|
180 val lemma = result(); |
180 val lemma = result(); |
181 |
181 |
182 goal thy |
182 goal thy |
183 "!!evs. [| evs : yahalom; length evs <= length evs' |] ==> \ |
183 "!!evs. [| evs : yahalom; length evs <= length evs' |] ==> \ |
184 \ newK evs' ~: keysFor (parts (sees C evs))"; |
184 \ newK evs' ~: keysFor (parts (sees C evs))"; |
212 goal thy |
212 goal thy |
213 "!!evs. evs : yahalom ==> \ |
213 "!!evs. evs : yahalom ==> \ |
214 \ (Crypt X (newK evt)) : parts (sees Enemy evs) & \ |
214 \ (Crypt X (newK evt)) : parts (sees Enemy evs) & \ |
215 \ Key K : parts {X} --> Key K : parts (sees Enemy evs)"; |
215 \ Key K : parts {X} --> Key K : parts (sees Enemy evs)"; |
216 be yahalom.induct 1; |
216 be yahalom.induct 1; |
217 by YM2_YM4_tac; |
217 bd (YM4_analz_sees_Enemy RS synth.Inj) 6; |
218 by (ALLGOALS (asm_simp_tac (!simpset addsimps pushes))); |
218 by (ALLGOALS (asm_simp_tac (!simpset addsimps pushes))); |
219 (*Deals with Faked messages*) |
219 (*Deals with Faked messages*) |
220 by (best_tac (!claset addSEs partsEs |
220 by (EVERY |
221 addDs [impOfSubs analz_subset_parts, |
221 (map (best_tac (!claset addSEs partsEs |
222 impOfSubs parts_insert_subset_Un] |
222 addDs [impOfSubs analz_subset_parts, |
223 addss (!simpset)) 2); |
223 impOfSubs parts_insert_subset_Un] |
224 (*Base case and YM5*) |
224 addss (!simpset))) |
|
225 [3,2])); |
|
226 (*Base case*) |
225 by (Auto_tac()); |
227 by (Auto_tac()); |
226 result(); |
228 result(); |
227 |
229 |
228 |
230 |
229 (** Specialized rewriting for this proof **) |
231 (** Specialized rewriting for this proof **) |
257 |
259 |
258 |
260 |
259 |
261 |
260 (** Session keys are not used to encrypt other session keys **) |
262 (** Session keys are not used to encrypt other session keys **) |
261 |
263 |
262 (*Could generalize this so that the X component doesn't have to be first |
|
263 in the message?*) |
|
264 val enemy_analz_tac = |
|
265 SELECT_GOAL |
|
266 (EVERY [REPEAT (resolve_tac [impI,notI] 1), |
|
267 dtac (impOfSubs Fake_analz_insert) 1, |
|
268 eresolve_tac [asm_rl, synth.Inj] 1, |
|
269 Fast_tac 1, |
|
270 Asm_full_simp_tac 1, |
|
271 IF_UNSOLVED (deepen_tac (!claset addIs [impOfSubs analz_mono]) 0 1) |
|
272 ]); |
|
273 |
|
274 |
|
275 (*Lemma for the trivial direction of the if-and-only-if*) |
264 (*Lemma for the trivial direction of the if-and-only-if*) |
276 goal thy |
265 goal thy |
277 "!!evs. (Key K : analz (Key``nE Un sEe)) --> \ |
266 "!!evs. (Key K : analz (Key``nE Un sEe)) --> \ |
278 \ (K : nE | Key K : analz sEe) ==> \ |
267 \ (K : nE | Key K : analz sEe) ==> \ |
279 \ (Key K : analz (Key``nE Un sEe)) = (K : nE | Key K : analz sEe)"; |
268 \ (Key K : analz (Key``nE Un sEe)) = (K : nE | Key K : analz sEe)"; |
284 goal thy |
273 goal thy |
285 "!!evs. evs : yahalom ==> \ |
274 "!!evs. evs : yahalom ==> \ |
286 \ ALL K E. (Key K : analz (Key``(newK``E) Un (sees Enemy evs))) = \ |
275 \ ALL K E. (Key K : analz (Key``(newK``E) Un (sees Enemy evs))) = \ |
287 \ (K : newK``E | Key K : analz (sees Enemy evs))"; |
276 \ (K : newK``E | Key K : analz (sees Enemy evs))"; |
288 be yahalom.induct 1; |
277 be yahalom.induct 1; |
289 bd YM2_analz_sees_Enemy 4; |
|
290 bd YM4_analz_sees_Enemy 6; |
278 bd YM4_analz_sees_Enemy 6; |
291 by (REPEAT_FIRST (resolve_tac [allI, lemma])); |
279 by (REPEAT_FIRST (resolve_tac [allI, lemma])); |
292 by (ALLGOALS (*Takes 35 secs*) |
280 by (ALLGOALS |
293 (asm_simp_tac |
281 (asm_simp_tac |
294 (!simpset addsimps ([insert_Key_singleton, insert_Key_image, pushKey_newK] |
282 (!simpset addsimps ([insert_Key_singleton, insert_Key_image, pushKey_newK] |
295 @ pushes) |
283 @ pushes) |
296 setloop split_tac [expand_if]))); |
284 setloop split_tac [expand_if]))); |
297 (*YM4*) |
285 (*YM4*) |
298 by (enemy_analz_tac 5); |
286 by (enemy_analz_tac 4); |
299 (*YM3*) |
287 (*YM3*) |
300 by (Fast_tac 4); |
288 by (Fast_tac 3); |
301 (*YM2*) (** LEVEL 7 **) |
289 (*Fake case*) |
302 by (res_inst_tac [("x1","X"), ("y1", "{|?XX,?YY|}")] |
|
303 (insert_commute RS ssubst) 3); |
|
304 by (res_inst_tac [("x1","X"), ("y1", "{|?XX,?YY|}")] |
|
305 (insert_commute RS ssubst) 3); |
|
306 by (asm_simp_tac (!simpset setloop split_tac [expand_if]) 3); |
|
307 by (enemy_analz_tac 3); |
|
308 (*Fake case*) (** LEVEL 11 **) |
|
309 by (res_inst_tac [("y1","X"), ("A1", "?G Un (?H::msg set)")] |
|
310 (insert_commute RS ssubst) 2); |
|
311 by (enemy_analz_tac 2); |
290 by (enemy_analz_tac 2); |
312 (*Base case*) |
291 (*Base case*) |
313 by (fast_tac (!claset addIs [image_eqI] addss (!simpset)) 1); |
292 by (fast_tac (!claset addIs [image_eqI] addss (!simpset)) 1); |
314 qed_spec_mp "analz_image_newK"; |
293 qed_spec_mp "analz_image_newK"; |
315 |
|
316 |
294 |
317 goal thy |
295 goal thy |
318 "!!evs. evs : yahalom ==> \ |
296 "!!evs. evs : yahalom ==> \ |
319 \ Key K : analz (insert (Key (newK evt)) (sees Enemy evs)) = \ |
297 \ Key K : analz (insert (Key (newK evt)) (sees Enemy evs)) = \ |
320 \ (K = newK evt | Key K : analz (sees Enemy evs))"; |
298 \ (K = newK evt | Key K : analz (sees Enemy evs))"; |
324 qed "analz_insert_Key_newK"; |
302 qed "analz_insert_Key_newK"; |
325 |
303 |
326 |
304 |
327 (*Describes the form *and age* of K when the following message is sent*) |
305 (*Describes the form *and age* of K when the following message is sent*) |
328 goal thy |
306 goal thy |
329 "!!evs. [| Says Server B \ |
307 "!!evs. [| Says Server A \ |
330 \ {|NA, Crypt {|NA, K|} (shrK A), \ |
308 \ {|Crypt {|Agent B, K, NA, NB|} (shrK A), \ |
331 \ Crypt {|NB, K|} (shrK B)|} : set_of_list evs; \ |
309 \ Crypt {|Agent A, K|} (shrK B)|} : set_of_list evs; \ |
332 \ evs : yahalom |] \ |
310 \ evs : yahalom |] \ |
333 \ ==> (EX evt:yahalom. K = Key(newK evt) & \ |
311 \ ==> (EX evt:yahalom. K = Key(newK evt) & \ |
334 \ length evt < length evs) & \ |
312 \ length evt < length evs)"; |
335 \ (EX i. NA = Nonce i)"; |
|
336 be rev_mp 1; |
313 be rev_mp 1; |
337 be yahalom.induct 1; |
314 be yahalom.induct 1; |
338 by (ALLGOALS (fast_tac (!claset addIs [less_SucI] addss (!simpset)))); |
315 by (ALLGOALS (fast_tac (!claset addIs [less_SucI] addss (!simpset)))); |
339 qed "Says_Server_message_form"; |
316 qed "Says_Server_message_form"; |
340 |
317 |
341 |
318 |
342 (*Crucial secrecy property: Enemy does not see the keys sent in msg YM3*) |
319 (*Crucial secrecy property: Enemy does not see the keys sent in msg YM3 |
|
320 As with Otway-Rees, proof does not need uniqueness of session keys.*) |
343 goal thy |
321 goal thy |
344 "!!evs. [| Says Server A \ |
322 "!!evs. [| Says Server A \ |
345 \ {|NA, Crypt {|NA, K|} (shrK B), \ |
323 \ {|Crypt {|Agent B, K, NA, NB|} (shrK A), \ |
346 \ Crypt {|NB, K|} (shrK A)|} : set_of_list evs; \ |
324 \ Crypt {|Agent A, K|} (shrK B)|} : set_of_list evs; \ |
347 \ A ~: bad; B ~: bad; evs : yahalom |] ==> \ |
325 \ A ~: bad; B ~: bad; evs : yahalom |] ==> \ |
348 \ K ~: analz (sees Enemy evs)"; |
326 \ K ~: analz (sees Enemy evs)"; |
349 be rev_mp 1; |
327 be rev_mp 1; |
350 be yahalom.induct 1; |
328 be yahalom.induct 1; |
351 bd YM2_analz_sees_Enemy 4; |
|
352 bd YM4_analz_sees_Enemy 6; |
329 bd YM4_analz_sees_Enemy 6; |
353 by (ALLGOALS Asm_simp_tac); |
330 by (ALLGOALS Asm_simp_tac); |
354 (*Next 3 steps infer that K has the form "Key (newK evs'" ... *) |
331 (*Next 3 steps infer that K has the form "Key (newK evs'" ... *) |
355 by (REPEAT_FIRST (resolve_tac [conjI, impI])); |
332 by (REPEAT_FIRST (resolve_tac [conjI, impI])); |
356 by (TRYALL (forward_tac [Says_Server_message_form] THEN' assume_tac)); |
333 by (TRYALL (forward_tac [Says_Server_message_form] THEN' assume_tac)); |
358 by (ALLGOALS |
335 by (ALLGOALS |
359 (asm_full_simp_tac |
336 (asm_full_simp_tac |
360 (!simpset addsimps ([analz_subset_parts RS contra_subsetD, |
337 (!simpset addsimps ([analz_subset_parts RS contra_subsetD, |
361 analz_insert_Key_newK] @ pushes) |
338 analz_insert_Key_newK] @ pushes) |
362 setloop split_tac [expand_if]))); |
339 setloop split_tac [expand_if]))); |
|
340 (*YM4*) |
|
341 by (enemy_analz_tac 3); |
363 (*YM3*) |
342 (*YM3*) |
364 by (fast_tac (!claset addSEs [less_irrefl]) 3); |
343 by (fast_tac (!claset addSEs [less_irrefl]) 2); |
365 (*Fake*) (** LEVEL 10 **) |
344 (*Fake*) (** LEVEL 10 **) |
366 by (res_inst_tac [("y1","X"), ("x1", "Key ?K")] (insert_commute RS ssubst) 1); |
|
367 by (enemy_analz_tac 1); |
|
368 (*YM4*) |
|
369 by (mp_tac 2); |
|
370 by (enemy_analz_tac 2); |
|
371 (*YM2*) |
|
372 by (mp_tac 1); |
|
373 by (res_inst_tac [("x1","X"), ("y1", "{|?XX,?YY|}")] |
|
374 (insert_commute RS ssubst) 1); |
|
375 by (asm_simp_tac (!simpset setloop split_tac [expand_if]) 1); |
|
376 by (enemy_analz_tac 1); |
345 by (enemy_analz_tac 1); |
377 qed "Enemy_not_see_encrypted_key"; |
346 qed "Enemy_not_see_encrypted_key"; |
378 |
|
379 |
|
380 |
|
381 (*** Session keys are issued at most once, and identify the principals ***) |
|
382 |
|
383 (** First, two lemmas for the Fake, YM2 and YM4 cases **) |
|
384 |
|
385 goal thy |
|
386 "!!evs. [| X : synth (analz (sees Enemy evs)); \ |
|
387 \ Crypt X' (shrK C) : parts{X}; \ |
|
388 \ C ~: bad; evs : yahalom |] \ |
|
389 \ ==> Crypt X' (shrK C) : parts (sees Enemy evs)"; |
|
390 by (best_tac (!claset addSEs [impOfSubs analz_subset_parts] |
|
391 addDs [impOfSubs parts_insert_subset_Un] |
|
392 addss (!simpset)) 1); |
|
393 qed "Crypt_Fake_parts"; |
|
394 |
|
395 goal thy |
|
396 "!!evs. [| Crypt X' K : parts (sees A evs); evs : yahalom |] \ |
|
397 \ ==> EX S S' Y. Says S S' Y : set_of_list evs & \ |
|
398 \ Crypt X' K : parts {Y}"; |
|
399 bd parts_singleton 1; |
|
400 by (fast_tac (!claset addSDs [seesD] addss (!simpset)) 1); |
|
401 qed "Crypt_parts_singleton"; |
|
402 |
|
403 fun ex_strip_tac i = REPEAT (ares_tac [exI, conjI] i) THEN assume_tac (i+1); |
|
404 |
|
405 (*The Key K uniquely identifies a pair of senders in the message encrypted by |
|
406 C, but if C=Enemy then he could send all sorts of nonsense.*) |
|
407 goal thy |
|
408 "!!evs. evs : yahalom ==> \ |
|
409 \ EX A B. ALL C. \ |
|
410 \ C ~: bad --> \ |
|
411 \ (ALL S S' X. Says S S' X : set_of_list evs --> \ |
|
412 \ (EX NA. Crypt {|NA, Key K|} (shrK C) : parts{X}) --> C=A | C=B)"; |
|
413 by (Simp_tac 1); |
|
414 be yahalom.induct 1; |
|
415 bd YM2_analz_sees_Enemy 4; |
|
416 bd YM4_analz_sees_Enemy 6; |
|
417 by (ALLGOALS |
|
418 (asm_simp_tac (!simpset addsimps [all_conj_distrib, imp_conj_distrib]))); |
|
419 by (REPEAT_FIRST (etac exE)); |
|
420 (*YM4*) |
|
421 by (ex_strip_tac 4); |
|
422 by (fast_tac (!claset addSDs [synth.Inj RS Crypt_Fake_parts, |
|
423 Crypt_parts_singleton]) 4); |
|
424 (*YM3: Case split propagates some context to other subgoal...*) |
|
425 (** LEVEL 8 **) |
|
426 by (excluded_middle_tac "K = newK evsa" 3); |
|
427 by (Asm_simp_tac 3); |
|
428 by (REPEAT (ares_tac [exI] 3)); |
|
429 (*...we prove this case by contradiction: the key is too new!*) |
|
430 by (fast_tac (!claset addIs [impOfSubs (subset_insertI RS parts_mono)] |
|
431 addSEs partsEs |
|
432 addEs [Says_imp_old_keys RS less_irrefl] |
|
433 addss (!simpset)) 3); |
|
434 (*YM2*) (** LEVEL 12 **) |
|
435 by (ex_strip_tac 2); |
|
436 by (res_inst_tac [("x1","X"), ("y1", "{|?XX,?YY|}")] |
|
437 (insert_commute RS ssubst) 2); |
|
438 by (Simp_tac 2); |
|
439 by (fast_tac (!claset addSDs [synth.Inj RS Crypt_Fake_parts, |
|
440 Crypt_parts_singleton]) 2); |
|
441 (*Fake*) (** LEVEL 16 **) |
|
442 by (ex_strip_tac 1); |
|
443 by (fast_tac (!claset addSDs [Crypt_Fake_parts, Crypt_parts_singleton]) 1); |
|
444 qed "unique_session_keys"; |
|
445 |
|
446 (*It seems strange but this theorem is NOT needed to prove the main result!*) |
|