src/HOL/Auth/Public.thy
changeset 14207 f20fbb141673
parent 14200 d8598e24f8fa
child 14261 6c418d139f74
equal deleted inserted replaced
14206:77bf175f5145 14207:f20fbb141673
     7 
     7 
     8 Private and public keys; initial states of agents
     8 Private and public keys; initial states of agents
     9 *)
     9 *)
    10 
    10 
    11 theory Public = Event:
    11 theory Public = Event:
       
    12 
       
    13 lemma invKey_K: "K \<in> symKeys ==> invKey K = K"
       
    14 by (simp add: symKeys_def)
    12 
    15 
    13 subsection{*Asymmetric Keys*}
    16 subsection{*Asymmetric Keys*}
    14 
    17 
    15 consts
    18 consts
    16   (*the bool is TRUE if a signing key*)
    19   (*the bool is TRUE if a signing key*)
    49   @{term "True\<noteq>False"}, no agent has identical signing and encryption keys*}
    52   @{term "True\<noteq>False"}, no agent has identical signing and encryption keys*}
    50 specification (publicKey)
    53 specification (publicKey)
    51   injective_publicKey:
    54   injective_publicKey:
    52     "publicKey b A = publicKey c A' ==> b=c & A=A'"
    55     "publicKey b A = publicKey c A' ==> b=c & A=A'"
    53    apply (rule exI [of _ "%b A. 2 * agent_case 0 (\<lambda>n. n + 2) 1 A + (if b then 1 else 0)"]) 
    56    apply (rule exI [of _ "%b A. 2 * agent_case 0 (\<lambda>n. n + 2) 1 A + (if b then 1 else 0)"]) 
    54    apply (auto simp add: inj_on_def split: agent.split) 
    57    apply (auto simp add: inj_on_def split: agent.split, presburger+)
    55    apply presburger+
       
    56 (*faster would be this:
    58 (*faster would be this:
    57    apply (drule_tac f="%x. x mod 2" in arg_cong, simp add: mod_Suc)+
    59    apply (drule_tac f="%x. x mod 2" in arg_cong, simp add: mod_Suc)+
    58 *)
    60 *)
    59    done                       
    61    done                       
    60 
    62 
   135   sym_shrK [iff]: "shrK X \<in> symKeys" --{*All shared keys are symmetric*}
   137   sym_shrK [iff]: "shrK X \<in> symKeys" --{*All shared keys are symmetric*}
   136 
   138 
   137 (*Injectiveness: Agents' long-term keys are distinct.*)
   139 (*Injectiveness: Agents' long-term keys are distinct.*)
   138 declare inj_shrK [THEN inj_eq, iff]
   140 declare inj_shrK [THEN inj_eq, iff]
   139 
   141 
       
   142 lemma invKey_shrK [simp]: "invKey (shrK A) = shrK A"
       
   143 by (simp add: invKey_K) 
       
   144 
       
   145 lemma analz_shrK_Decrypt:
       
   146      "[| Crypt (shrK A) X \<in> analz H; Key(shrK A) \<in> analz H |] ==> X \<in> analz H"
       
   147 by auto
       
   148 
       
   149 lemma analz_Decrypt':
       
   150      "[| Crypt K X \<in> analz H; K \<in> symKeys; Key K \<in> analz H |] ==> X \<in> analz H"
       
   151 by (auto simp add: invKey_K)
       
   152 
   140 lemma priK_neq_shrK [iff]: "shrK A \<noteq> privateKey b C"
   153 lemma priK_neq_shrK [iff]: "shrK A \<noteq> privateKey b C"
   141 by (simp add: symKeys_neq_imp_neq)
   154 by (simp add: symKeys_neq_imp_neq)
   142 
   155 
   143 declare priK_neq_shrK [THEN not_sym, simp]
   156 declare priK_neq_shrK [THEN not_sym, simp]
   144 
   157 
   162 lemma shrK_notin_image_privateKey [simp]: "shrK x \<notin> invKey ` publicKey b ` AA" 
   175 lemma shrK_notin_image_privateKey [simp]: "shrK x \<notin> invKey ` publicKey b ` AA" 
   163 by auto
   176 by auto
   164 
   177 
   165 lemma shrK_image_eq [simp]: "(shrK x \<in> shrK ` AA) = (x \<in> AA)"
   178 lemma shrK_image_eq [simp]: "(shrK x \<in> shrK ` AA) = (x \<in> AA)"
   166 by auto
   179 by auto
       
   180 
       
   181 text{*For some reason, moving this up can make some proofs loop!*}
       
   182 declare invKey_K [simp]
   167 
   183 
   168 
   184 
   169 subsection{*Initial States of Agents*}
   185 subsection{*Initial States of Agents*}
   170 
   186 
   171 text{*Note: for all practical purposes, all that matters is the initial
   187 text{*Note: for all practical purposes, all that matters is the initial
   231 by (induct B, auto)
   247 by (induct B, auto)
   232 
   248 
   233 lemma Crypt_notin_used_empty [simp]: "Crypt K X \<notin> used []"
   249 lemma Crypt_notin_used_empty [simp]: "Crypt K X \<notin> used []"
   234 by (simp add: Crypt_notin_initState used_Nil)
   250 by (simp add: Crypt_notin_initState used_Nil)
   235 
   251 
   236 
       
   237 (*** Basic properties of shrK ***)
   252 (*** Basic properties of shrK ***)
   238 
   253 
   239 (*Agents see their own shared keys!*)
   254 (*Agents see their own shared keys!*)
   240 lemma shrK_in_initState [iff]: "Key (shrK A) \<in> initState A"
   255 lemma shrK_in_initState [iff]: "Key (shrK A) \<in> initState A"
   241 by (induct_tac "A", auto)
   256 by (induct_tac "A", auto)
   244 by (simp add: initState_subset_knows [THEN subsetD])
   259 by (simp add: initState_subset_knows [THEN subsetD])
   245 
   260 
   246 lemma shrK_in_used [iff]: "Key (shrK A) \<in> used evs"
   261 lemma shrK_in_used [iff]: "Key (shrK A) \<in> used evs"
   247 by (rule initState_into_used, blast)
   262 by (rule initState_into_used, blast)
   248 
   263 
       
   264 
   249 (** Fresh keys never clash with long-term shared keys **)
   265 (** Fresh keys never clash with long-term shared keys **)
   250 
   266 
   251 (*Used in parts_induct_tac and analz_Fake_tac to distinguish session keys
   267 (*Used in parts_induct_tac and analz_Fake_tac to distinguish session keys
   252   from long-term shared keys*)
   268   from long-term shared keys*)
   253 lemma Key_not_used: "Key K \<notin> used evs ==> K \<notin> range shrK"
   269 lemma Key_not_used [simp]: "Key K \<notin> used evs ==> K \<notin> range shrK"
   254 by blast
   270 by blast
   255 
   271 
   256 lemma shrK_neq: "Key K \<notin> used evs ==> shrK B \<noteq> K"
   272 lemma shrK_neq: "Key K \<notin> used evs ==> shrK B \<noteq> K"
   257 by blast
   273 by blast
   258 
   274 
       
   275 declare shrK_neq [THEN not_sym, simp]
   259 
   276 
   260 
   277 
   261 subsection{*Function @{term spies} *}
   278 subsection{*Function @{term spies} *}
   262 
   279 
   263 text{*Agents see their own private keys!*}
   280 text{*Agents see their own private keys!*}
   297 
   314 
   298 lemma privateKey_into_used [iff]: "Key (privateKey b A) \<in> used evs"
   315 lemma privateKey_into_used [iff]: "Key (privateKey b A) \<in> used evs"
   299 apply(rule initState_into_used)
   316 apply(rule initState_into_used)
   300 apply(rule priK_in_initState [THEN parts.Inj])
   317 apply(rule priK_in_initState [THEN parts.Inj])
   301 done
   318 done
       
   319 
       
   320 (*For case analysis on whether or not an agent is compromised*)
       
   321 lemma Crypt_Spy_analz_bad:
       
   322      "[| Crypt (shrK A) X \<in> analz (knows Spy evs);  A \<in> bad |]  
       
   323       ==> X \<in> analz (knows Spy evs)"
       
   324 by force
   302 
   325 
   303 
   326 
   304 subsection{*Fresh Nonces*}
   327 subsection{*Fresh Nonces*}
   305 
   328 
   306 lemma Nonce_notin_initState [iff]: "Nonce N \<notin> parts (initState B)"
   329 lemma Nonce_notin_initState [iff]: "Nonce N \<notin> parts (initState B)"
   342 val Key_not_used = thm "Key_not_used";
   365 val Key_not_used = thm "Key_not_used";
   343 val insert_Key_singleton = thm "insert_Key_singleton";
   366 val insert_Key_singleton = thm "insert_Key_singleton";
   344 val insert_Key_image = thm "insert_Key_image";
   367 val insert_Key_image = thm "insert_Key_image";
   345 *}
   368 *}
   346 
   369 
   347 (*
   370 
   348 val not_symKeys_pubK = thm "not_symKeys_pubK";
   371 lemma Crypt_imp_keysFor :"[|Crypt K X \<in> H; K \<in> symKeys|] ==> K \<in> keysFor H"
   349 val not_symKeys_priK = thm "not_symKeys_priK";
       
   350 val symKeys_neq_imp_neq = thm "symKeys_neq_imp_neq";
       
   351 val analz_symKeys_Decrypt = thm "analz_symKeys_Decrypt";
       
   352 val invKey_image_eq = thm "invKey_image_eq";
       
   353 val pubK_image_eq = thm "pubK_image_eq";
       
   354 val priK_pubK_image_eq = thm "priK_pubK_image_eq";
       
   355 val keysFor_parts_initState = thm "keysFor_parts_initState";
       
   356 val priK_in_initState = thm "priK_in_initState";
       
   357 val spies_pubK = thm "spies_pubK";
       
   358 val Spy_spies_bad = thm "Spy_spies_bad";
       
   359 val Nonce_notin_initState = thm "Nonce_notin_initState";
       
   360 val Nonce_notin_used_empty = thm "Nonce_notin_used_empty";
       
   361 
       
   362 *)
       
   363 
       
   364 
       
   365 lemma invKey_K [simp]: "K \<in> symKeys ==> invKey K = K"
       
   366 by (simp add: symKeys_def)
       
   367 
       
   368 lemma Crypt_imp_keysFor :"[|K \<in> symKeys; Crypt K X \<in> H|] ==> K \<in> keysFor H"
       
   369 by (drule Crypt_imp_invKey_keysFor, simp)
   372 by (drule Crypt_imp_invKey_keysFor, simp)
   370 
   373 
   371 
   374 text{*Lemma for the trivial direction of the if-and-only-if of the 
   372 subsection{*Specialized Methods for Possibility Theorems*}
   375 Session Key Compromise Theorem*}
       
   376 lemma analz_image_freshK_lemma:
       
   377      "(Key K \<in> analz (Key`nE \<union> H)) --> (K \<in> nE | Key K \<in> analz H)  ==>  
       
   378          (Key K \<in> analz (Key`nE \<union> H)) = (K \<in> nE | Key K \<in> analz H)"
       
   379 by (blast intro: analz_mono [THEN [2] rev_subsetD])
       
   380 
       
   381 lemmas analz_image_freshK_simps =
       
   382        simp_thms mem_simps --{*these two allow its use with @{text "only:"}*}
       
   383        disj_comms 
       
   384        image_insert [THEN sym] image_Un [THEN sym] empty_subsetI insert_subset
       
   385        analz_insert_eq Un_upper2 [THEN analz_mono, THEN subsetD]
       
   386        insert_Key_singleton 
       
   387        Key_not_used insert_Key_image Un_assoc [THEN sym]
   373 
   388 
   374 ML
   389 ML
   375 {*
   390 {*
   376 val Nonce_supply1 = thm "Nonce_supply1";
   391 val analz_image_freshK_lemma = thm "analz_image_freshK_lemma";
       
   392 val analz_image_freshK_simps = thms "analz_image_freshK_simps";
       
   393 
       
   394 val analz_image_freshK_ss = 
       
   395      simpset() delsimps [image_insert, image_Un]
       
   396 	       delsimps [imp_disjL]    (*reduces blow-up*)
       
   397 	       addsimps thms "analz_image_freshK_simps"
       
   398 *}
       
   399 
       
   400 method_setup analz_freshK = {*
       
   401     Method.no_args
       
   402      (Method.METHOD
       
   403       (fn facts => EVERY [REPEAT_FIRST (resolve_tac [allI, ballI, impI]),
       
   404                           REPEAT_FIRST (rtac analz_image_freshK_lemma),
       
   405                           ALLGOALS (asm_simp_tac analz_image_freshK_ss)])) *}
       
   406     "for proving the Session Key Compromise theorem"
       
   407 
       
   408 subsection{*Specialized Methods for Possibility Theorems*}
       
   409 
       
   410 ML
       
   411 {*
   377 val Nonce_supply = thm "Nonce_supply";
   412 val Nonce_supply = thm "Nonce_supply";
   378 
   413 
   379 (*Tactic for possibility theorems (Isar interface)*)
   414 (*Tactic for possibility theorems (Isar interface)*)
   380 fun gen_possibility_tac ss state = state |>
   415 fun gen_possibility_tac ss state = state |>
   381     REPEAT (*omit used_Says so that Nonces start from different traces!*)
   416     REPEAT (*omit used_Says so that Nonces start from different traces!*)
   384      REPEAT_FIRST (eq_assume_tac ORELSE' 
   419      REPEAT_FIRST (eq_assume_tac ORELSE' 
   385                    resolve_tac [refl, conjI, Nonce_supply]))
   420                    resolve_tac [refl, conjI, Nonce_supply]))
   386 
   421 
   387 (*Tactic for possibility theorems (ML script version)*)
   422 (*Tactic for possibility theorems (ML script version)*)
   388 fun possibility_tac state = gen_possibility_tac (simpset()) state
   423 fun possibility_tac state = gen_possibility_tac (simpset()) state
       
   424 
       
   425 (*For harder protocols (such as Recur) where we have to set up some
       
   426   nonces and keys initially*)
       
   427 fun basic_possibility_tac st = st |>
       
   428     REPEAT 
       
   429     (ALLGOALS (asm_simp_tac (simpset() setSolver safe_solver))
       
   430      THEN
       
   431      REPEAT_FIRST (resolve_tac [refl, conjI]))
   389 *}
   432 *}
   390 
   433 
   391 method_setup possibility = {*
   434 method_setup possibility = {*
   392     Method.ctxt_args (fn ctxt =>
   435     Method.ctxt_args (fn ctxt =>
   393         Method.METHOD (fn facts =>
   436         Method.METHOD (fn facts =>
   394             gen_possibility_tac (Simplifier.get_local_simpset ctxt))) *}
   437             gen_possibility_tac (Simplifier.get_local_simpset ctxt))) *}
   395     "for proving possibility theorems"
   438     "for proving possibility theorems"
   396 
   439 
   397 
       
   398 
       
   399 lemmas analz_image_freshK_simps =
       
   400        simp_thms mem_simps --{*these two allow its use with @{text "only:"}*}
       
   401        disj_comms 
       
   402        image_insert [THEN sym] image_Un [THEN sym] empty_subsetI insert_subset
       
   403        analz_insert_eq Un_upper2 [THEN analz_mono, THEN subsetD]
       
   404        insert_Key_singleton 
       
   405        Key_not_used insert_Key_image Un_assoc [THEN sym]
       
   406 
       
   407 ML
       
   408 {*
       
   409 val analz_image_freshK_ss =
       
   410      simpset() delsimps [image_insert, image_Un]
       
   411 	       delsimps [imp_disjL]    (*reduces blow-up*)
       
   412 	       addsimps thms"analz_image_freshK_simps"
       
   413 *}
       
   414 
       
   415 end
   440 end