src/HOL/Auth/NS_Shared.ML
changeset 2516 4d68fbe6378b
parent 2451 ce85a2aafc7a
child 2529 e40ca839758d
equal deleted inserted replaced
2515:6ff9bd353121 2516:4d68fbe6378b
    20 goal thy 
    20 goal thy 
    21  "!!A B. [| A ~= B; A ~= Server; B ~= Server |]   \
    21  "!!A B. [| A ~= B; A ~= Server; B ~= Server |]   \
    22 \        ==> EX N K. EX evs: ns_shared lost.          \
    22 \        ==> EX N K. EX evs: ns_shared lost.          \
    23 \               Says A B (Crypt K {|Nonce N, Nonce N|}) : set_of_list evs";
    23 \               Says A B (Crypt K {|Nonce N, Nonce N|}) : set_of_list evs";
    24 by (REPEAT (resolve_tac [exI,bexI] 1));
    24 by (REPEAT (resolve_tac [exI,bexI] 1));
    25 by (rtac (ns_shared.Nil RS ns_shared.NS1 RS ns_shared.NS2 RS ns_shared.NS3 RS ns_shared.NS4 RS ns_shared.NS5) 2);
    25 by (rtac (ns_shared.Nil RS ns_shared.NS1 RS ns_shared.NS2 RS 
    26 by (ALLGOALS (simp_tac (!simpset setsolver safe_solver)));
    26           ns_shared.NS3 RS ns_shared.NS4 RS ns_shared.NS5) 2);
    27 by (REPEAT_FIRST (resolve_tac [refl, conjI]));
    27 by possibility_tac;
    28 by (ALLGOALS (fast_tac (!claset addss (!simpset setsolver safe_solver))));
       
    29 result();
    28 result();
    30 
    29 
    31 
    30 
    32 (**** Inductive proofs about ns_shared ****)
    31 (**** Inductive proofs about ns_shared ****)
    33 
    32 
    50 AddSEs   [not_Says_to_self RSN (2, rev_notE)];
    49 AddSEs   [not_Says_to_self RSN (2, rev_notE)];
    51 
    50 
    52 (*For reasoning about the encrypted portion of message NS3*)
    51 (*For reasoning about the encrypted portion of message NS3*)
    53 goal thy "!!evs. Says S A (Crypt KA {|N, B, K, X|}) : set_of_list evs \
    52 goal thy "!!evs. Says S A (Crypt KA {|N, B, K, X|}) : set_of_list evs \
    54 \                ==> X : parts (sees lost Spy evs)";
    53 \                ==> X : parts (sees lost Spy evs)";
    55 by (fast_tac (!claset addSEs partsEs
    54 by (fast_tac (!claset addSEs sees_Spy_partsEs) 1);
    56                       addSDs [Says_imp_sees_Spy RS parts.Inj]) 1);
       
    57 qed "NS3_msg_in_parts_sees_Spy";
    55 qed "NS3_msg_in_parts_sees_Spy";
    58                               
    56                               
    59 goal thy
    57 goal thy
    60     "!!evs. Says Server A (Crypt (shrK A) {|NA, B, K, X|}) : set_of_list evs \
    58     "!!evs. Says Server A (Crypt (shrK A) {|NA, B, K, X|}) : set_of_list evs \
    61 \           ==> K : parts (sees lost Spy evs)";
    59 \           ==> K : parts (sees lost Spy evs)";
    62 by (fast_tac (!claset addSEs partsEs
    60 by (fast_tac (!claset addSEs sees_Spy_partsEs) 1);
    63                       addSDs [Says_imp_sees_Spy RS parts.Inj]) 1);
       
    64 qed "Oops_parts_sees_Spy";
    61 qed "Oops_parts_sees_Spy";
    65 
    62 
    66 val parts_Fake_tac = 
    63 val parts_Fake_tac = 
    67     dres_inst_tac [("lost","lost")] NS3_msg_in_parts_sees_Spy 5 THEN
    64     dres_inst_tac [("lost","lost")] NS3_msg_in_parts_sees_Spy 5 THEN
    68     forw_inst_tac [("lost","lost")] Oops_parts_sees_Spy 8;
    65     forw_inst_tac [("lost","lost")] Oops_parts_sees_Spy 8;
   105 
   102 
   106 bind_thm ("Spy_analz_shrK_D", analz_subset_parts RS subsetD RS Spy_see_shrK_D);
   103 bind_thm ("Spy_analz_shrK_D", analz_subset_parts RS subsetD RS Spy_see_shrK_D);
   107 AddSDs [Spy_see_shrK_D, Spy_analz_shrK_D];
   104 AddSDs [Spy_see_shrK_D, Spy_analz_shrK_D];
   108 
   105 
   109 
   106 
   110 (*** Future keys can't be seen or used! ***)
   107 (*Nobody can have used non-existent keys!*)
   111 
       
   112 (*Nobody can have SEEN keys that will be generated in the future. *)
       
   113 goal thy "!!evs. evs : ns_shared lost ==>      \
   108 goal thy "!!evs. evs : ns_shared lost ==>      \
   114 \               length evs <= i --> Key (newK i) ~: parts (sees lost Spy evs)";
   109 \         Key K ~: used evs --> K ~: keysFor (parts (sees lost Spy evs))";
   115 by (parts_induct_tac 1);
   110 by (parts_induct_tac 1);
   116 by (ALLGOALS (fast_tac (!claset addEs [leD RS notE]
   111 (*Fake*)
   117 				addDs [impOfSubs analz_subset_parts,
   112 by (best_tac
   118                                        impOfSubs parts_insert_subset_Un,
   113       (!claset addIs [impOfSubs analz_subset_parts]
   119                                        Suc_leD]
   114                addDs [impOfSubs (analz_subset_parts RS keysFor_mono),
   120                                 addss (!simpset))));
   115                       impOfSubs (parts_insert_subset_Un RS keysFor_mono)]
   121 qed_spec_mp "new_keys_not_seen";
   116                addss (!simpset)) 1);
   122 Addsimps [new_keys_not_seen];
   117 (*NS2, NS4, NS5*)
   123 
   118 by (REPEAT (fast_tac (!claset addSEs sees_Spy_partsEs addss (!simpset)) 1));
   124 (*Variant: old messages must contain old keys!*)
       
   125 goal thy 
       
   126  "!!evs. [| Says A B X : set_of_list evs;          \
       
   127 \           Key (newK i) : parts {X};              \
       
   128 \           evs : ns_shared lost                   \
       
   129 \        |] ==> i < length evs";
       
   130 by (rtac ccontr 1);
       
   131 by (dtac leI 1);
       
   132 by (fast_tac (!claset addSDs [new_keys_not_seen, Says_imp_sees_Spy]
       
   133                       addIs  [impOfSubs parts_mono]) 1);
       
   134 qed "Says_imp_old_keys";
       
   135 
       
   136 
       
   137 
       
   138 (*** Future nonces can't be seen or used! ***)
       
   139 
       
   140 goal thy "!!evs. evs : ns_shared lost ==>     \
       
   141 \             length evs <= i --> Nonce (newN i) ~: parts (sees lost Spy evs)";
       
   142 by (parts_induct_tac 1);
       
   143 by (REPEAT_FIRST
       
   144     (fast_tac (!claset addSEs partsEs
       
   145                        addSDs  [Says_imp_sees_Spy RS parts.Inj]
       
   146                        addEs [leD RS notE]
       
   147 				addDs  [impOfSubs analz_subset_parts,
       
   148                                impOfSubs parts_insert_subset_Un, Suc_leD]
       
   149                        addss (!simpset))));
       
   150 qed_spec_mp "new_nonces_not_seen";
       
   151 Addsimps [new_nonces_not_seen];
       
   152 
       
   153 
       
   154 (*Nobody can have USED keys that will be generated in the future.
       
   155   ...very like new_keys_not_seen*)
       
   156 goal thy "!!evs. evs : ns_shared lost ==>      \
       
   157 \                length evs <= i -->           \
       
   158 \                newK i ~: keysFor (parts (sees lost Spy evs))";
       
   159 by (parts_induct_tac 1);
       
   160 (*NS1 and NS2*)
       
   161 by (EVERY (map (fast_tac (!claset addDs [Suc_leD] addss (!simpset))) [3,2]));
       
   162 (*Fake and NS3*)
       
   163 by (EVERY 
       
   164     (map
       
   165      (best_tac
       
   166       (!claset addDs [impOfSubs (analz_subset_parts RS keysFor_mono),
       
   167                       impOfSubs (parts_insert_subset_Un RS keysFor_mono),
       
   168                       Suc_leD]
       
   169                addEs [new_keys_not_seen RS not_parts_not_analz RSN(2,rev_notE)]
       
   170                addss (!simpset)))
       
   171      [2,1]));
       
   172 (*NS4 and NS5: nonce exchange*)
       
   173 by (ALLGOALS (deepen_tac (!claset addSDs [Says_imp_old_keys]
       
   174                                   addIs  [less_SucI, impOfSubs keysFor_mono]
       
   175                                   addss (!simpset addsimps [le_def])) 1));
       
   176 qed_spec_mp "new_keys_not_used";
   119 qed_spec_mp "new_keys_not_used";
   177 
   120 
   178 bind_thm ("new_keys_not_analzd",
   121 bind_thm ("new_keys_not_analzd",
   179           [analz_subset_parts RS keysFor_mono,
   122           [analz_subset_parts RS keysFor_mono,
   180            new_keys_not_used] MRS contra_subsetD);
   123            new_keys_not_used] MRS contra_subsetD);
   184 
   127 
   185 (** Lemmas concerning the form of items passed in messages **)
   128 (** Lemmas concerning the form of items passed in messages **)
   186 
   129 
   187 (*Describes the form of K, X and K' when the Server sends this message.*)
   130 (*Describes the form of K, X and K' when the Server sends this message.*)
   188 goal thy 
   131 goal thy 
   189  "!!evs. [| Says Server A (Crypt K' {|N, Agent B, K, X|}) : set_of_list evs; \
   132  "!!evs. [| Says Server A (Crypt K' {|N, Agent B, Key K, X|}) \
   190 \           evs : ns_shared lost |]                       \
   133 \             : set_of_list evs;                              \
   191 \        ==> (EX i. K = Key(newK i) &                     \
   134 \           evs : ns_shared lost |]                           \
   192 \                   X = (Crypt (shrK B) {|K, Agent A|}) & \
   135 \        ==> K ~: range shrK &                                \
   193 \                   K' = shrK A)";
   136 \            X = (Crypt (shrK B) {|Key K, Agent A|}) &        \
       
   137 \            K' = shrK A";
   194 by (etac rev_mp 1);
   138 by (etac rev_mp 1);
   195 by (etac ns_shared.induct 1);
   139 by (etac ns_shared.induct 1);
   196 by (ALLGOALS (fast_tac (!claset addss (!simpset))));
   140 by (Auto_tac());
   197 qed "Says_Server_message_form";
   141 qed "Says_Server_message_form";
   198 
   142 
   199 
   143 
   200 (*If the encrypted message appears then it originated with the Server*)
   144 (*If the encrypted message appears then it originated with the Server*)
   201 goal thy
   145 goal thy
   217   OR     reduces it to the Fake case.
   161   OR     reduces it to the Fake case.
   218   Use Says_Server_message_form if applicable.*)
   162   Use Says_Server_message_form if applicable.*)
   219 goal thy 
   163 goal thy 
   220  "!!evs. [| Says S A (Crypt (shrK A) {|Nonce NA, Agent B, Key K, X|})      \
   164  "!!evs. [| Says S A (Crypt (shrK A) {|Nonce NA, Agent B, Key K, X|})      \
   221 \            : set_of_list evs;  evs : ns_shared lost |]                   \
   165 \            : set_of_list evs;  evs : ns_shared lost |]                   \
   222 \        ==> (EX i. K = newK i & i < length evs &                  \
   166 \        ==> (K ~: range shrK & X = (Crypt (shrK B) {|Key K, Agent A|}))  \
   223 \                   X = (Crypt (shrK B) {|Key K, Agent A|}))       \
   167 \            | X : analz (sees lost Spy evs)";
   224 \          | X : analz (sees lost Spy evs)";
       
   225 by (case_tac "A : lost" 1);
   168 by (case_tac "A : lost" 1);
   226 by (fast_tac (!claset addSDs [Says_imp_sees_Spy RS analz.Inj]
   169 by (fast_tac (!claset addSDs [Says_imp_sees_Spy RS analz.Inj]
   227                       addss (!simpset)) 1);
   170                       addss (!simpset)) 1);
   228 by (forward_tac [Says_imp_sees_Spy RS parts.Inj] 1);
   171 by (forward_tac [Says_imp_sees_Spy RS parts.Inj] 1);
   229 by (fast_tac (!claset addEs  partsEs
   172 by (fast_tac (!claset addEs  partsEs
   230                       addSDs [A_trusts_NS2, Says_Server_message_form]
   173                       addSDs [A_trusts_NS2, Says_Server_message_form]
   231                       addIs [Says_imp_old_keys]
       
   232                       addss (!simpset)) 1);
   174                       addss (!simpset)) 1);
   233 qed "Says_S_message_form";
   175 qed "Says_S_message_form";
   234 
   176 
   235 
   177 
   236 (*For proofs involving analz.  We again instantiate the variable to "lost".*)
   178 (*For proofs involving analz.  We again instantiate the variable to "lost".*)
   237 val analz_Fake_tac = 
   179 val analz_Fake_tac = 
   238     forw_inst_tac [("lost","lost")] Says_Server_message_form 8 THEN
   180     forw_inst_tac [("lost","lost")] Says_Server_message_form 8 THEN
   239     forw_inst_tac [("lost","lost")] Says_S_message_form 5 THEN 
   181     forw_inst_tac [("lost","lost")] Says_S_message_form 5 THEN 
   240     Full_simp_tac 7 THEN
   182     REPEAT_FIRST (eresolve_tac [asm_rl, conjE, disjE] ORELSE' hyp_subst_tac);
   241     REPEAT_FIRST (eresolve_tac [asm_rl, exE, disjE] ORELSE' hyp_subst_tac);
       
   242 
   183 
   243 
   184 
   244 (****
   185 (****
   245  The following is to prove theorems of the form
   186  The following is to prove theorems of the form
   246 
   187 
   247   Key K : analz (insert (Key (newK i)) (sees lost Spy evs)) ==>
   188   Key K : analz (insert (Key KAB) (sees lost Spy evs)) ==>
   248   Key K : analz (sees lost Spy evs)
   189   Key K : analz (sees lost Spy evs)
   249 
   190 
   250  A more general formula must be proved inductively.
   191  A more general formula must be proved inductively.
   251 
   192 
   252 ****)
   193 ****)
   254 
   195 
   255 (*NOT useful in this form, but it says that session keys are not used
   196 (*NOT useful in this form, but it says that session keys are not used
   256   to encrypt messages containing other keys, in the actual protocol.
   197   to encrypt messages containing other keys, in the actual protocol.
   257   We require that agents should behave like this subsequently also.*)
   198   We require that agents should behave like this subsequently also.*)
   258 goal thy 
   199 goal thy 
   259  "!!evs. evs : ns_shared lost ==> \
   200  "!!evs. [| evs : ns_shared lost;  Kab ~: range shrK |] ==> \
   260 \        (Crypt (newK i) X) : parts (sees lost Spy evs) & \
   201 \        (Crypt KAB X) : parts (sees lost Spy evs) & \
   261 \        Key K : parts {X} --> Key K : parts (sees lost Spy evs)";
   202 \        Key K : parts {X} --> Key K : parts (sees lost Spy evs)";
   262 by (etac ns_shared.induct 1);
   203 by (etac ns_shared.induct 1);
   263 by parts_Fake_tac;
   204 by parts_Fake_tac;
   264 by (ALLGOALS Asm_simp_tac);
   205 by (ALLGOALS Asm_simp_tac);
   265 (*Deals with Faked messages*)
   206 (*Deals with Faked messages*)
   274 (** Session keys are not used to encrypt other session keys **)
   215 (** Session keys are not used to encrypt other session keys **)
   275 
   216 
   276 (*The equality makes the induction hypothesis easier to apply*)
   217 (*The equality makes the induction hypothesis easier to apply*)
   277 goal thy  
   218 goal thy  
   278  "!!evs. evs : ns_shared lost ==> \
   219  "!!evs. evs : ns_shared lost ==> \
   279 \  ALL K E. (Key K : analz (Key``(newK``E) Un (sees lost Spy evs))) = \
   220 \  ALL K KK. KK <= Compl (range shrK) -->                      \
   280 \           (K : newK``E | Key K : analz (sees lost Spy evs))";
   221 \            (Key K : analz (Key``KK Un (sees lost Spy evs))) = \
       
   222 \            (K : KK | Key K : analz (sees lost Spy evs))";
   281 by (etac ns_shared.induct 1);
   223 by (etac ns_shared.induct 1);
   282 by analz_Fake_tac;
   224 by analz_Fake_tac;
   283 by (REPEAT_FIRST (resolve_tac [allI, analz_image_newK_lemma]));
   225 by (REPEAT_FIRST (resolve_tac [allI, impI]));
   284 by (ALLGOALS (*Takes 18 secs*)
   226 by (REPEAT_FIRST (rtac analz_image_freshK_lemma ));
   285     (asm_simp_tac 
   227 (*Takes 24 secs*)
   286      (!simpset addsimps [Un_assoc RS sym, 
   228 by (ALLGOALS (asm_simp_tac analz_image_freshK_ss));
   287 			 insert_Key_singleton, insert_Key_image, pushKey_newK]
       
   288                setloop split_tac [expand_if])));
       
   289 (*NS4, Fake*) 
   229 (*NS4, Fake*) 
   290 by (EVERY (map spy_analz_tac [5,2]));
   230 by (EVERY (map spy_analz_tac [3,2]));
   291 (*NS3, NS2, Base*)
   231 (*Base*)
   292 by (REPEAT (fast_tac (!claset addIs [image_eqI] addss (!simpset)) 1));
   232 by (fast_tac (!claset addIs [image_eqI] addss (!simpset)) 1);
   293 qed_spec_mp "analz_image_newK";
   233 qed_spec_mp "analz_image_freshK";
   294 
   234 
   295 
   235 
   296 goal thy
   236 goal thy
   297  "!!evs. evs : ns_shared lost ==>                               \
   237  "!!evs. [| evs : ns_shared lost;  KAB ~: range shrK |] ==>     \
   298 \        Key K : analz (insert (Key(newK i)) (sees lost Spy evs)) = \
   238 \        Key K : analz (insert (Key KAB) (sees lost Spy evs)) = \
   299 \        (K = newK i | Key K : analz (sees lost Spy evs))";
   239 \        (K = KAB | Key K : analz (sees lost Spy evs))";
   300 by (asm_simp_tac (HOL_ss addsimps [pushKey_newK, analz_image_newK, 
   240 by (asm_simp_tac (analz_image_freshK_ss addsimps [analz_image_freshK]) 1);
   301                                    insert_Key_singleton]) 1);
   241 qed "analz_insert_freshK";
   302 by (Fast_tac 1);
       
   303 qed "analz_insert_Key_newK";
       
   304 
   242 
   305 
   243 
   306 (** The session key K uniquely identifies the message, if encrypted
   244 (** The session key K uniquely identifies the message, if encrypted
   307     with a secure key **)
   245     with a secure key **)
   308 
   246 
   318 by (ex_strip_tac 2);
   256 by (ex_strip_tac 2);
   319 by (Fast_tac 2);
   257 by (Fast_tac 2);
   320 (*NS2: it can't be a new key*)
   258 (*NS2: it can't be a new key*)
   321 by (expand_case_tac "K = ?y" 1);
   259 by (expand_case_tac "K = ?y" 1);
   322 by (REPEAT (ares_tac [refl,exI,impI,conjI] 2));
   260 by (REPEAT (ares_tac [refl,exI,impI,conjI] 2));
   323 by (fast_tac (!claset addEs [Says_imp_old_keys RS less_irrefl]
   261 by (fast_tac (!claset delrules [conjI]    (*prevent split-up into 4 subgoals*)
   324                       delrules [conjI]    (*prevent split-up into 4 subgoals*)
   262                       addSEs sees_Spy_partsEs
   325                       addss (!simpset addsimps [parts_insertI])) 1);
   263                       addss (!simpset addsimps [parts_insertI])) 1);
   326 val lemma = result();
   264 val lemma = result();
   327 
   265 
   328 (*In messages of this form, the session key uniquely identifies the rest*)
   266 (*In messages of this form, the session key uniquely identifies the rest*)
   329 goal thy 
   267 goal thy 
   350 \        Key K ~: analz (sees lost Spy evs)";
   288 \        Key K ~: analz (sees lost Spy evs)";
   351 by (etac ns_shared.induct 1);
   289 by (etac ns_shared.induct 1);
   352 by analz_Fake_tac;
   290 by analz_Fake_tac;
   353 by (ALLGOALS 
   291 by (ALLGOALS 
   354     (asm_simp_tac 
   292     (asm_simp_tac 
   355      (!simpset addsimps ([not_parts_not_analz,
   293      (!simpset addsimps ([not_parts_not_analz, analz_insert_freshK] @ pushes)
   356                           analz_insert_Key_newK] @ pushes)
       
   357                setloop split_tac [expand_if])));
   294                setloop split_tac [expand_if])));
       
   295 (*NS4, Fake*) 
       
   296 by (EVERY (map spy_analz_tac [4,1]));
   358 (*NS2*)
   297 (*NS2*)
   359 by (fast_tac (!claset addIs [parts_insertI]
   298 by (fast_tac (!claset addSEs sees_Spy_partsEs
   360                       addEs [Says_imp_old_keys RS less_irrefl]
   299                       addIs [parts_insertI, impOfSubs analz_subset_parts]
   361                       addss (!simpset)) 2);
   300                       addss (!simpset)) 1);
   362 (*NS4, Fake*) 
       
   363 by (EVERY (map spy_analz_tac [3,1]));
       
   364 (*NS3 and Oops subcases*) (**LEVEL 5 **)
   301 (*NS3 and Oops subcases*) (**LEVEL 5 **)
   365 by (step_tac (!claset delrules [impCE]) 1);
   302 by (step_tac (!claset delrules [impCE]) 1);
   366 by (full_simp_tac (!simpset addsimps [all_conj_distrib]) 2);
   303 by (full_simp_tac (!simpset addsimps [all_conj_distrib]) 2);
   367 by (etac conjE 2);
   304 by (etac conjE 2);
   368 by (mp_tac 2);
   305 by (mp_tac 2);
   380 
   317 
   381 
   318 
   382 (*Final version: Server's message in the most abstract form*)
   319 (*Final version: Server's message in the most abstract form*)
   383 goal thy 
   320 goal thy 
   384  "!!evs. [| Says Server A                                               \
   321  "!!evs. [| Says Server A                                               \
   385 \            (Crypt K' {|NA, Agent B, K, X|}) : set_of_list evs;        \
   322 \            (Crypt K' {|NA, Agent B, Key K, X|}) : set_of_list evs;    \
   386 \           (ALL NB. Says A Spy {|NA, NB, K|} ~: set_of_list evs);      \
   323 \           (ALL NB. Says A Spy {|NA, NB, Key K|} ~: set_of_list evs);  \
   387 \           A ~: lost;  B ~: lost;  evs : ns_shared lost                \
   324 \           A ~: lost;  B ~: lost;  evs : ns_shared lost                \
   388 \        |] ==> K ~: analz (sees lost Spy evs)";
   325 \        |] ==> Key K ~: analz (sees lost Spy evs)";
   389 by (forward_tac [Says_Server_message_form] 1 THEN assume_tac 1);
   326 by (forward_tac [Says_Server_message_form] 1 THEN assume_tac 1);
   390 by (fast_tac (!claset addSEs [lemma]) 1);
   327 by (fast_tac (!claset addSEs [lemma]) 1);
   391 qed "Spy_not_see_encrypted_key";
   328 qed "Spy_not_see_encrypted_key";
   392 
   329 
   393 
   330 
   394 goal thy 
   331 goal thy 
   395  "!!evs. [| C ~: {A,B,Server};                                          \
   332  "!!evs. [| C ~: {A,B,Server};                                          \
   396 \           Says Server A                                               \
   333 \           Says Server A                                               \
   397 \            (Crypt K' {|NA, Agent B, K, X|}) : set_of_list evs;        \
   334 \            (Crypt K' {|NA, Agent B, Key K, X|}) : set_of_list evs;    \
   398 \           (ALL NB. Says A Spy {|NA, NB, K|} ~: set_of_list evs);      \
   335 \           (ALL NB. Says A Spy {|NA, NB, Key K|} ~: set_of_list evs);  \
   399 \           A ~: lost;  B ~: lost;  evs : ns_shared lost |]             \
   336 \           A ~: lost;  B ~: lost;  evs : ns_shared lost |]             \
   400 \        ==> K ~: analz (sees lost C evs)";
   337 \        ==> Key K ~: analz (sees lost C evs)";
   401 by (rtac (subset_insertI RS sees_mono RS analz_mono RS contra_subsetD) 1);
   338 by (rtac (subset_insertI RS sees_mono RS analz_mono RS contra_subsetD) 1);
   402 by (rtac (sees_lost_agent_subset_sees_Spy RS analz_mono RS contra_subsetD) 1);
   339 by (rtac (sees_lost_agent_subset_sees_Spy RS analz_mono RS contra_subsetD) 1);
   403 by (FIRSTGOAL (rtac Spy_not_see_encrypted_key));
   340 by (FIRSTGOAL (rtac Spy_not_see_encrypted_key));
   404 by (REPEAT_FIRST (fast_tac (!claset addIs [ns_shared_mono RS subsetD])));
   341 by (REPEAT_FIRST (fast_tac (!claset addIs [ns_shared_mono RS subsetD])));
   405 qed "Agent_not_see_encrypted_key";
   342 qed "Agent_not_see_encrypted_key";
   447 (**LEVEL 6**)
   384 (**LEVEL 6**)
   448 by (fast_tac (!claset addSDs [Crypt_Fake_parts_insert]
   385 by (fast_tac (!claset addSDs [Crypt_Fake_parts_insert]
   449                       addDs [impOfSubs analz_subset_parts]) 1);
   386                       addDs [impOfSubs analz_subset_parts]) 1);
   450 by (Fast_tac 2);
   387 by (Fast_tac 2);
   451 by (REPEAT_FIRST (rtac impI ORELSE' etac conjE ORELSE' hyp_subst_tac));
   388 by (REPEAT_FIRST (rtac impI ORELSE' etac conjE ORELSE' hyp_subst_tac));
   452 (*Contradiction from the assumption   
   389 (*Subgoal 1: contradiction from the assumptions  
   453    Crypt (newK(length evsa)) (Nonce NB) : parts (sees lost Spy evsa) *)
   390   Key K ~: used evsa  and Crypt K (Nonce NB) : parts (sees lost Spy evsa) *)
   454 by (dtac Crypt_imp_invKey_keysFor 1);
   391 by (dtac Crypt_imp_invKey_keysFor 1);
   455 (**LEVEL 10**)
   392 (**LEVEL 10**)
   456 by (Asm_full_simp_tac 1);
   393 by (Asm_full_simp_tac 1);
   457 by (rtac disjI1 1);
   394 by (rtac disjI1 1);
   458 by (thin_tac "?PP-->?QQ" 1);
   395 by (thin_tac "?PP-->?QQ" 1);
   459 by (case_tac "Ba : lost" 1);
   396 by (case_tac "Ba : lost" 1);
   460 by (dtac Says_Crypt_lost 1 THEN assume_tac 1 THEN Fast_tac 1);
   397 by (dtac Says_Crypt_lost 1 THEN assume_tac 1 THEN Fast_tac 1);
   461 by (dtac (Says_imp_sees_Spy RS parts.Inj RS B_trusts_NS3) 1 THEN 
   398 by (dtac (Says_imp_sees_Spy RS parts.Inj RS B_trusts_NS3) 1 THEN 
   462     REPEAT (assume_tac 1));
   399     REPEAT (assume_tac 1));
   463 by (fast_tac (!claset addDs [unique_session_keys]) 1);
   400 by (best_tac (!claset addDs [unique_session_keys]) 1);
   464 val lemma = result();
   401 val lemma = result();
   465 
   402 
   466 goal thy
   403 goal thy
   467  "!!evs. [| Crypt K (Nonce NB) : parts (sees lost Spy evs);           \
   404  "!!evs. [| Crypt K (Nonce NB) : parts (sees lost Spy evs);           \
   468 \           Says Server A (Crypt (shrK A) {|NA, Agent B, Key K, X|})  \
   405 \           Says Server A (Crypt (shrK A) {|NA, Agent B, Key K, X|})  \