src/HOL/Auth/Yahalom2.ML
changeset 2155 dc85854810eb
parent 2111 81c8d46edfa3
child 2160 ad4382e546fc
equal deleted inserted replaced
2154:913b4fc7670a 2155:dc85854810eb
    61 qed "YM4_analz_sees_Spy";
    61 qed "YM4_analz_sees_Spy";
    62 
    62 
    63 bind_thm ("YM4_parts_sees_Spy",
    63 bind_thm ("YM4_parts_sees_Spy",
    64           YM4_analz_sees_Spy RS (impOfSubs analz_subset_parts));
    64           YM4_analz_sees_Spy RS (impOfSubs analz_subset_parts));
    65 
    65 
    66 (*Relates to both YM4 and Revl*)
    66 (*Relates to both YM4 and Oops*)
    67 goal thy "!!evs. Says S A {|NB, Crypt {|B, K, NA|} (shrK A), X|} \
    67 goal thy "!!evs. Says S A {|NB, Crypt {|B, K, NA|} (shrK A), X|} \
    68 \                  : set_of_list evs ==> \
    68 \                  : set_of_list evs ==> \
    69 \                K : parts (sees lost Spy evs)";
    69 \                K : parts (sees lost Spy evs)";
    70 by (fast_tac (!claset addSEs partsEs
    70 by (fast_tac (!claset addSEs partsEs
    71                       addSDs [Says_imp_sees_Spy RS parts.Inj]) 1);
    71                       addSDs [Says_imp_sees_Spy RS parts.Inj]) 1);
   167 goal thy "!!evs. evs : yahalom lost ==> \
   167 goal thy "!!evs. evs : yahalom lost ==> \
   168 \                length evs <= length evs' --> \
   168 \                length evs <= length evs' --> \
   169 \                newK evs' ~: keysFor (UN C. parts (sees lost C evs))";
   169 \                newK evs' ~: keysFor (UN C. parts (sees lost C evs))";
   170 by (parts_induct_tac 1);
   170 by (parts_induct_tac 1);
   171 by (dresolve_tac [YM4_Key_parts_sees_Spy] 5);
   171 by (dresolve_tac [YM4_Key_parts_sees_Spy] 5);
   172 
       
   173 (*YM1, YM2 and YM3*)
   172 (*YM1, YM2 and YM3*)
   174 by (EVERY (map (fast_tac (!claset addDs [Suc_leD] addss (!simpset))) [4,3,2]));
   173 by (EVERY (map (fast_tac (!claset addDs [Suc_leD] addss (!simpset))) [4,3,2]));
   175 (*Fake and YM4: these messages send unknown (X) components*)
   174 (*Fake and YM4: these messages send unknown (X) components*)
   176 by (stac insert_commute 2);
   175 by (stac insert_commute 2);
   177 by (Simp_tac 2);
   176 by (Simp_tac 2);
   198            new_keys_not_used] MRS contra_subsetD);
   197            new_keys_not_used] MRS contra_subsetD);
   199 
   198 
   200 Addsimps [new_keys_not_used, new_keys_not_analzd];
   199 Addsimps [new_keys_not_used, new_keys_not_analzd];
   201 
   200 
   202 
   201 
   203 (*Describes the form of Key K when the following message is sent.  The use of
   202 (*Describes the form of K when the Server sends this message.  Useful for
   204   "parts" strengthens the induction hyp for proving the Fake case.  The
   203   Oops as well as main secrecy property.*)
   205   assumption A ~: lost prevents its being a Faked message.  (Based
   204 goal thy 
   206   on NS_Shared/Says_S_message_form) *)
   205  "!!evs. [| Says Server A {|NB', Crypt {|Agent B, K, NA|} (shrK A), X|} \
   207 goal thy
   206 \            : set_of_list evs;                                         \
   208  "!!evs. evs: yahalom lost ==>                                        \
   207 \           evs : yahalom lost |]                                       \
   209 \        Crypt {|B, Key K, NA|} (shrK A) : parts (sees lost Spy evs)  \
   208 \        ==> (EX evt: yahalom lost. K = Key(newK evt)) & A ~= B";
   210 \        --> A ~: lost --> (EX evt: yahalom lost. K = newK evt)";
   209 by (etac rev_mp 1);
   211 by (parts_induct_tac 1);
   210 by (etac yahalom.induct 1);
   212 by (Auto_tac());
   211 by (ALLGOALS (fast_tac (!claset addss (!simpset))));
   213 qed_spec_mp "Reveal_message_lemma";
   212 qed "Says_Server_message_form";
   214 
       
   215 (*EITHER describes the form of Key K when the following message is sent, 
       
   216   OR     reduces it to the Fake case.*)
       
   217 
       
   218 goal thy 
       
   219  "!!evs. [| Says S A {|NB, Crypt {|B, Key K, NA|} (shrK A), X|} \
       
   220 \           : set_of_list evs;                                  \
       
   221 \           evs : yahalom lost |]                               \
       
   222 \        ==> (EX evt: yahalom lost. K = newK evt)               \
       
   223 \          | Key K : analz (sees lost Spy evs)";
       
   224 br (Reveal_message_lemma RS disjCI) 1;
       
   225 ba 1;
       
   226 by (fast_tac (!claset addSDs [Says_imp_sees_Spy RS analz.Inj]
       
   227                       addDs [impOfSubs analz_subset_parts]) 1);
       
   228 by (fast_tac (!claset addSDs [Says_imp_sees_Spy RS analz.Inj]
       
   229                       addss (!simpset)) 1);
       
   230 qed "Reveal_message_form";
       
   231 
   213 
   232 
   214 
   233 (*For proofs involving analz.  We again instantiate the variable to "lost".*)
   215 (*For proofs involving analz.  We again instantiate the variable to "lost".*)
   234 val analz_Fake_tac = 
   216 val analz_Fake_tac = 
   235     dres_inst_tac [("lost","lost")] YM4_analz_sees_Spy 6 THEN
   217     dres_inst_tac [("lost","lost")] YM4_analz_sees_Spy 6 THEN
   236     forw_inst_tac [("lost","lost")] Reveal_message_form 7;
   218     forw_inst_tac [("lost","lost")] Says_Server_message_form 7 THEN
       
   219     assume_tac 7 THEN Full_simp_tac 7 THEN
       
   220     REPEAT ((eresolve_tac [bexE,conjE] ORELSE' hyp_subst_tac) 7);
   237 
   221 
   238 
   222 
   239 (****
   223 (****
   240  The following is to prove theorems of the form
   224  The following is to prove theorems of the form
   241 
   225 
   253 \  ALL K E. (Key K : analz (Key``(newK``E) Un (sees lost Spy evs))) = \
   237 \  ALL K E. (Key K : analz (Key``(newK``E) Un (sees lost Spy evs))) = \
   254 \           (K : newK``E | Key K : analz (sees lost Spy evs))";
   238 \           (K : newK``E | Key K : analz (sees lost Spy evs))";
   255 by (etac yahalom.induct 1);
   239 by (etac yahalom.induct 1);
   256 by analz_Fake_tac;
   240 by analz_Fake_tac;
   257 by (REPEAT_FIRST (resolve_tac [allI, analz_image_newK_lemma]));
   241 by (REPEAT_FIRST (resolve_tac [allI, analz_image_newK_lemma]));
   258 by (REPEAT ((eresolve_tac [bexE, disjE] ORELSE' hyp_subst_tac) 8));
       
   259 by (ALLGOALS  (*Takes 26 secs*)
   242 by (ALLGOALS  (*Takes 26 secs*)
   260     (asm_simp_tac 
   243     (asm_simp_tac 
   261      (!simpset addsimps ([insert_Key_singleton, insert_Key_image, pushKey_newK]
   244      (!simpset addsimps ([insert_Key_singleton, insert_Key_image, pushKey_newK]
   262                          @ pushes)
   245                          @ pushes)
   263                setloop split_tac [expand_if])));
   246                setloop split_tac [expand_if])));
   264 (** LEVEL 5 **)
   247 (*YM4, Fake*) 
   265 (*Reveal case 2, YM4, Fake*) 
   248 by (EVERY (map spy_analz_tac [4, 2]));
   266 by (EVERY (map spy_analz_tac [6, 4, 2]));
   249 (*Oops, YM3, Base*)
   267 (*Reveal case 1, YM3, Base*)
       
   268 by (REPEAT (fast_tac (!claset addIs [image_eqI] addss (!simpset)) 1));
   250 by (REPEAT (fast_tac (!claset addIs [image_eqI] addss (!simpset)) 1));
   269 qed_spec_mp "analz_image_newK";
   251 qed_spec_mp "analz_image_newK";
   270 
   252 
   271 goal thy
   253 goal thy
   272  "!!evs. evs : yahalom lost ==>                               \
   254  "!!evs. evs : yahalom lost ==>                               \
   280 
   262 
   281 (*** The Key K uniquely identifies the Server's  message. **)
   263 (*** The Key K uniquely identifies the Server's  message. **)
   282 
   264 
   283 goal thy 
   265 goal thy 
   284  "!!evs. evs : yahalom lost ==>                                     \
   266  "!!evs. evs : yahalom lost ==>                                     \
   285 \      EX A' B' NA' NB'. ALL A B NA NB.                             \
   267 \      EX A' B' NA' NB' X'. ALL A B NA NB X.                        \
   286 \          Says Server A                                            \
   268 \          Says Server A                                            \
   287 \           {|NB, Crypt {|Agent B, Key K, NA|} (shrK A),            \
   269 \           {|NB, Crypt {|Agent B, Key K, NA|} (shrK A), X|}        \
   288 \                 Crypt {|Agent A, Key K, NB, NB|} (shrK B)|}           \
   270 \          : set_of_list evs --> A=A' & B=B' & NA=NA' & NB=NB' & X=X'";
   289 \          : set_of_list evs --> A=A' & B=B' & NA=NA' & NB=NB'";
       
   290 by (etac yahalom.induct 1);
   271 by (etac yahalom.induct 1);
   291 by (ALLGOALS (asm_simp_tac (!simpset addsimps [all_conj_distrib])));
   272 by (ALLGOALS (asm_simp_tac (!simpset addsimps [all_conj_distrib])));
   292 by (Step_tac 1);
   273 by (Step_tac 1);
   293 (*Remaining case: YM3*)
   274 (*Remaining case: YM3*)
   294 by (expand_case_tac "K = ?y" 1);
   275 by (expand_case_tac "K = ?y" 1);
   299                       addss (!simpset addsimps [parts_insertI])) 1);
   280                       addss (!simpset addsimps [parts_insertI])) 1);
   300 val lemma = result();
   281 val lemma = result();
   301 
   282 
   302 goal thy 
   283 goal thy 
   303 "!!evs. [| Says Server A                                            \
   284 "!!evs. [| Says Server A                                            \
   304 \           {|NB, Crypt {|Agent B, Key K, NA|} (shrK A),            \
   285 \           {|NB, Crypt {|Agent B, Key K, NA|} (shrK A), X|}        \
   305 \                 Crypt {|Agent A, Key K, NB, NB|} (shrK B)|}           \
       
   306 \           : set_of_list evs;                                      \
   286 \           : set_of_list evs;                                      \
   307 \          Says Server A'                                           \
   287 \          Says Server A'                                           \
   308 \           {|NB', Crypt {|Agent B', Key K, NA'|} (shrK A'),        \
   288 \           {|NB', Crypt {|Agent B', Key K, NA'|} (shrK A'), X'|}   \
   309 \                  Crypt {|Agent A', Key K, NB', NB'|} (shrK B')|}       \
       
   310 \           : set_of_list evs;                                      \
   289 \           : set_of_list evs;                                      \
   311 \          evs : yahalom lost |]                                    \
   290 \          evs : yahalom lost |]                                    \
   312 \       ==> A=A' & B=B' & NA=NA' & NB=NB'";
   291 \       ==> A=A' & B=B' & NA=NA' & NB=NB'";
   313 by (dtac lemma 1);
   292 by (dtac lemma 1);
   314 by (REPEAT (etac exE 1));
   293 by (REPEAT (etac exE 1));
   316 by (forw_inst_tac [("psi", "ALL C.?P(C)")] asm_rl 1);
   295 by (forw_inst_tac [("psi", "ALL C.?P(C)")] asm_rl 1);
   317 by (fast_tac (!claset addSDs [spec]) 1);
   296 by (fast_tac (!claset addSDs [spec]) 1);
   318 qed "unique_session_keys";
   297 qed "unique_session_keys";
   319 
   298 
   320 
   299 
   321 (*If the encrypted message appears then it originated with the Server*)
       
   322 goal thy
       
   323  "!!evs. [| Crypt {|Agent B, Key K, Nonce NA|} (shrK A)                \
       
   324 \            : parts (sees lost Spy evs);                              \
       
   325 \           A ~: lost;  evs : yahalom lost |]                          \
       
   326 \         ==> EX NB. Says Server A                                            \
       
   327 \              {|NB, Crypt {|Agent B, Key K, Nonce NA|} (shrK A),            \
       
   328 \                    Crypt {|Agent A, Key K, NB, NB|} (shrK B)|}           \
       
   329 \             : set_of_list evs";
       
   330 by (etac rev_mp 1);
       
   331 by (parts_induct_tac 1);
       
   332 by (Fast_tac 1);
       
   333 qed "A_trust_YM3";
       
   334 
       
   335 
       
   336 (*Describes the form of K when the Server sends this message.*)
       
   337 goal thy 
       
   338  "!!evs. [| Says Server A                                           \
       
   339 \            {|NB, Crypt {|Agent B, K, NA|} (shrK A),           \
       
   340 \                  Crypt {|Agent A, K, NB, NB|} (shrK B)|}          \
       
   341 \            : set_of_list evs;   \
       
   342 \           evs : yahalom lost |]                                   \
       
   343 \        ==> (EX evt: yahalom lost. K = Key(newK evt))";
       
   344 by (etac rev_mp 1);
       
   345 by (etac yahalom.induct 1);
       
   346 by (ALLGOALS (fast_tac (!claset addss (!simpset))));
       
   347 qed "Says_Server_message_form";
       
   348 
       
   349 
       
   350 (** Crucial secrecy property: Spy does not see the keys sent in msg YM3 **)
   300 (** Crucial secrecy property: Spy does not see the keys sent in msg YM3 **)
   351 
   301 
   352 goal thy 
   302 goal thy 
   353  "!!evs. [| A ~: lost;  B ~: lost;                                \
   303  "!!evs. [| A ~: lost;  B ~: lost;  A ~= B;                          \
   354 \           evs : yahalom lost;  evt : yahalom lost |]            \
   304 \           evs : yahalom lost |]            \
   355 \        ==> Says Server A                                           \
   305 \        ==> Says Server A                                           \
   356 \              {|NB, Crypt {|Agent B, Key K, NA|} (shrK A),           \
   306 \              {|NB, Crypt {|Agent B, Key K, NA|} (shrK A),           \
   357 \                    Crypt {|Agent A, Key K, NB, NB|} (shrK B)|}          \
   307 \                    Crypt {|NB, Key K, Agent A|} (shrK B)|}          \
   358 \             : set_of_list evs -->                               \
   308 \             : set_of_list evs -->                               \
   359 \            Says A Spy {|NA, Key K|} ~: set_of_list evs -->  \
   309 \            Says A Spy {|NA, NB, Key K|} ~: set_of_list evs -->  \
   360 \            Key K ~: analz (sees lost Spy evs)";
   310 \            Key K ~: analz (sees lost Spy evs)";
   361 by (etac yahalom.induct 1);
   311 by (etac yahalom.induct 1);
   362 by analz_Fake_tac;
   312 by analz_Fake_tac;
   363 by (REPEAT_FIRST (eresolve_tac [asm_rl, bexE, disjE] ORELSE' hyp_subst_tac));
       
   364 by (ALLGOALS
   313 by (ALLGOALS
   365     (asm_simp_tac 
   314     (asm_simp_tac 
   366      (!simpset addsimps ([analz_subset_parts RS contra_subsetD,
   315      (!simpset addsimps ([analz_subset_parts RS contra_subsetD,
   367                           analz_insert_Key_newK] @ pushes)
   316                           analz_insert_Key_newK] @ pushes)
   368                setloop split_tac [expand_if])));
   317                setloop split_tac [expand_if])));
   369 (*YM3*)
   318 (*YM3*)
   370 by (fast_tac (!claset addIs [parts_insertI]
   319 by (fast_tac (!claset addIs [parts_insertI]
   371                       addEs [Says_imp_old_keys RS less_irrefl]
   320                       addEs [Says_imp_old_keys RS less_irrefl]
   372                       addss (!simpset)) 2);
   321                       addss (!simpset)) 2);
   373 (*Reveal case 2, OR4, Fake*) 
   322 (*OR4, Fake*) 
   374 by (REPEAT_FIRST (resolve_tac [conjI, impI] ORELSE' spy_analz_tac));
   323 by (REPEAT_FIRST (resolve_tac [conjI, impI] ORELSE' spy_analz_tac));
   375 (*Reveal case 1*) (** LEVEL 6 **)
   324 (*Oops*)
   376 by (case_tac "Aa : lost" 1);
       
   377 (*But this contradicts Key K ~: analz (sees lost Spy evsa) *)
       
   378 by (dtac (Says_imp_sees_Spy RS analz.Inj) 1);
       
   379 by (fast_tac (!claset addSDs [analz.Decrypt] addss (!simpset)) 1);
       
   380 (*So now we have  Aa ~: lost *)
       
   381 bd (Says_imp_sees_Spy RS parts.Inj) 1;
       
   382 by (fast_tac (!claset delrules [disjE] 
   325 by (fast_tac (!claset delrules [disjE] 
   383 	              addSEs [MPair_parts]
   326 		      addDs [unique_session_keys]
   384 		      addDs [A_trust_YM3, unique_session_keys]
       
   385 	              addss (!simpset)) 1);
   327 	              addss (!simpset)) 1);
   386 val lemma = result() RS mp RS mp RSN(2,rev_notE);
   328 val lemma = result() RS mp RS mp RSN(2,rev_notE);
   387 
   329 
   388 
   330 
   389 (*Final version: Server's message in the most abstract form*)
   331 (*Final version: Server's message in the most abstract form*)
   390 goal thy 
   332 goal thy 
   391  "!!evs. [| Says Server A                                         \
   333  "!!evs. [| Says Server A                                         \
   392 \              {|NB, Crypt {|Agent B, K, NA|} (shrK A),           \
   334 \              {|NB, Crypt {|Agent B, K, NA|} (shrK A),           \
   393 \                    Crypt {|Agent A, K, NB, NB|} (shrK B)|}      \
   335 \                    Crypt {|NB, K, Agent A|} (shrK B)|}          \
   394 \           : set_of_list evs;                                    \
   336 \           : set_of_list evs;                                    \
   395 \           Says A Spy {|NA, K|} ~: set_of_list evs;          \
   337 \           Says A Spy {|NA, NB, K|} ~: set_of_list evs;          \
   396 \           A ~: lost;  B ~: lost;  evs : yahalom lost |] ==>     \
   338 \           A ~: lost;  B ~: lost;  evs : yahalom lost |]         \
   397 \     K ~: analz (sees lost Spy evs)";
   339 \        ==> K ~: analz (sees lost Spy evs)";
   398 by (forward_tac [Says_Server_message_form] 1 THEN assume_tac 1);
   340 by (forward_tac [Says_Server_message_form] 1 THEN assume_tac 1);
   399 by (fast_tac (!claset addSEs [lemma]) 1);
   341 by (fast_tac (!claset addSEs [lemma]) 1);
   400 qed "Spy_not_see_encrypted_key";
   342 qed "Spy_not_see_encrypted_key";
   401 
   343 
   402 
   344 
   403 goal thy 
   345 goal thy 
   404  "!!evs. [| C ~: {A,B,Server};                                          \
   346  "!!evs. [| C ~: {A,B,Server};                                    \
   405 \           Says Server A                                         \
   347 \           Says Server A                                         \
   406 \              {|NB, Crypt {|Agent B, K, NA|} (shrK A),           \
   348 \              {|NB, Crypt {|Agent B, K, NA|} (shrK A),           \
   407 \                    Crypt {|Agent A, K, NB, NB|} (shrK B)|}          \
   349 \                    Crypt {|NB, K, Agent A|} (shrK B)|}          \
   408 \           : set_of_list evs;                                    \
   350 \           : set_of_list evs;                                    \
   409 \           Says A Spy {|NA, K|} ~: set_of_list evs;                \
   351 \           Says A Spy {|NA, NB, K|} ~: set_of_list evs;          \
   410 \           A ~: lost;  B ~: lost;  evs : yahalom lost |] ==>           \
   352 \           A ~: lost;  B ~: lost;  evs : yahalom lost |]         \
   411 \     K ~: analz (sees lost C evs)";
   353 \        ==> K ~: analz (sees lost C evs)";
   412 by (rtac (subset_insertI RS sees_mono RS analz_mono RS contra_subsetD) 1);
   354 by (rtac (subset_insertI RS sees_mono RS analz_mono RS contra_subsetD) 1);
   413 by (rtac (sees_lost_agent_subset_sees_Spy RS analz_mono RS contra_subsetD) 1);
   355 by (rtac (sees_lost_agent_subset_sees_Spy RS analz_mono RS contra_subsetD) 1);
   414 by (FIRSTGOAL (rtac Spy_not_see_encrypted_key));
   356 by (FIRSTGOAL (rtac Spy_not_see_encrypted_key));
   415 by (REPEAT_FIRST (fast_tac (!claset addIs [yahalom_mono RS subsetD])));
   357 by (REPEAT_FIRST (fast_tac (!claset addIs [yahalom_mono RS subsetD])));
   416 qed "Agent_not_see_encrypted_key";
   358 qed "Agent_not_see_encrypted_key";
   417 
   359 
   418 
   360 
   419 (*** Security Guarantee for B upon receiving YM4 ***)
   361 (*** Security Guarantees for A and B ***)
       
   362 
       
   363 (*If the encrypted message appears then it originated with the Server.*)
       
   364 goal thy
       
   365  "!!evs. [| Crypt {|Agent B, Key K, NA|} (shrK A)                \
       
   366 \            : parts (sees lost Spy evs);                              \
       
   367 \           A ~: lost;  evs : yahalom lost |]                          \
       
   368 \         ==> EX NB. Says Server A                                     \
       
   369 \                      {|NB, Crypt {|Agent B, Key K, NA|} (shrK A),    \
       
   370 \                            Crypt {|NB, Key K, Agent A|} (shrK B)|}   \
       
   371 \                    : set_of_list evs";
       
   372 by (etac rev_mp 1);
       
   373 by (parts_induct_tac 1);
       
   374 (*The nested conjunctions are entirely useless*)
       
   375 by (REPEAT_FIRST (rtac conjI ORELSE' fast_tac (!claset delrules [conjI])));
       
   376 qed "A_trust_YM3";
       
   377 
   420 
   378 
   421 (*B knows, by the first part of A's message, that the Server distributed 
   379 (*B knows, by the first part of A's message, that the Server distributed 
   422   the key for A and B.  But this part says nothing about nonces.*)
   380   the key for A and B. *)
   423 goal thy 
   381 goal thy 
   424  "!!evs. [| Crypt {|Agent A, Key K, Nonce NB, Nonce NB|} (shrK B)    \
   382  "!!evs. [| Crypt {|Nonce NB, Key K, Agent A|} (shrK B)              \
   425 \            : parts (sees lost Spy evs); \
   383 \            : parts (sees lost Spy evs);                            \
   426 \           B ~: lost;  evs : yahalom lost |]                           \
   384 \           B ~: lost;  evs : yahalom lost |]                        \
   427 \        ==> EX NA. Says Server A                                    \
   385 \        ==> EX NA. Says Server A                                    \
   428 \                    {|Nonce NB,                                   \
   386 \                    {|Nonce NB,                                     \
   429 \                      Crypt {|Agent B, Key K, Nonce NA|} (shrK A), \
   387 \                      Crypt {|Agent B, Key K, Nonce NA|} (shrK A),  \
   430 \                      Crypt {|Agent A, Key K, Nonce NB, Nonce NB|} (shrK B)|}\
   388 \                      Crypt {|Nonce NB, Key K, Agent A|} (shrK B)|} \
   431 \                       : set_of_list evs";
   389 \                       : set_of_list evs";
   432 by (etac rev_mp 1);
   390 by (etac rev_mp 1);
   433 by (parts_induct_tac 1);
   391 by (parts_induct_tac 1);
   434 (*YM3*)
   392 (*YM3*)
   435 by (Fast_tac 1);
   393 by (Fast_tac 1);
   437 
   395 
   438 (*With this variant we don't bother to use the 2nd part of YM4 at all, since
   396 (*With this variant we don't bother to use the 2nd part of YM4 at all, since
   439   Nonce NB is available in the first part.  However the 2nd part does assure B
   397   Nonce NB is available in the first part.  However the 2nd part does assure B
   440   of A's existence.*)
   398   of A's existence.*)
   441 
   399 
   442 (*What can B deduce from receipt of YM4?  Note how the two components of
   400 (*What can B deduce from receipt of YM4?  Stronger and simpler than Yahalom
   443   the message contribute to a single conclusion about the Server's message.*)
   401   because we do not have to show that NB is secret. *)
   444 goal thy 
   402 goal thy 
   445  "!!evs. [| Says A' B {|Crypt {|Agent A, Key K, Nonce NB, Nonce NB|} (shrK B),              \
   403  "!!evs. [| Says A' B {|Crypt {|Nonce NB, Key K, Agent A|} (shrK B),    \
   446 \                       Crypt (Nonce NB) K|} : set_of_list evs;         \
   404 \                       Crypt (Nonce NB) K|} : set_of_list evs;         \
   447 \           ALL N N'. Says A Spy {|N,N', Key K|} ~: set_of_list evs;    \
       
   448 \           A ~: lost;  B ~: lost;  evs : yahalom lost |]               \
   405 \           A ~: lost;  B ~: lost;  evs : yahalom lost |]               \
   449 \        ==> EX NA. Says Server A                                       \
   406 \        ==> EX NA. Says Server A                                       \
   450 \                    {|Nonce NB,                                   \
   407 \                    {|Nonce NB,                                        \
   451 \                      Crypt {|Agent B, Key K, Nonce NA|} (shrK A), \
   408 \                      Crypt {|Agent B, Key K, Nonce NA|} (shrK A),     \
   452 \                      Crypt {|Agent A, Key K, Nonce NB, Nonce NB|} (shrK B)|}\
   409 \                      Crypt {|Nonce NB, Key K, Agent A|} (shrK B)|}    \
   453 \                   : set_of_list evs";
   410 \                   : set_of_list evs";
   454 be (Says_imp_sees_Spy RS parts.Inj RS MPair_parts) 1;
   411 be (Says_imp_sees_Spy RS parts.Inj RS MPair_parts) 1;
   455 by (fast_tac (!claset addSDs [B_trusts_YM4_shrK]) 1);
   412 by (fast_tac (!claset addSDs [B_trusts_YM4_shrK]) 1);
   456 qed "B_trust_YM4";
   413 qed "B_trust_YM4";