doc-src/TutorialI/Protocol/Public.thy
author berghofe
Mon, 23 Jul 2007 14:31:34 +0200
changeset 23925 ee98c2528a8f
parent 16417 9bc16273c2d4
child 25341 ca3761e38a87
permissions -rw-r--r--
LaTeX code is now generated directly from theory files.
     1 (*  Title:      HOL/Auth/Public
     2     ID:         $Id$
     3     Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     4     Copyright   1996  University of Cambridge
     5 
     6 Theory of Public Keys (common to all public-key protocols)
     7 
     8 Private and public keys; initial states of agents
     9 *)(*<*)
    10 theory Public imports Event
    11 begin
    12 (*>*)
    13 
    14 text {*
    15 The function
    16 @{text pubK} maps agents to their public keys.  The function
    17 @{text priK} maps agents to their private keys.  It is defined in terms of
    18 @{text invKey} and @{text pubK} by a translation; therefore @{text priK} is
    19 not a proper constant, so we declare it using \isacommand{syntax}
    20 (cf.\ \S\ref{sec:syntax-translations}).
    21 *}
    22 
    23 consts pubK :: "agent => key"
    24 syntax priK :: "agent => key"
    25 translations "priK x" \<rightleftharpoons> "invKey(pubK x)"
    26 (*<*)
    27 primrec
    28         (*Agents know their private key and all public keys*)
    29   initState_Server:  "initState Server     =    
    30  		         insert (Key (priK Server)) (Key ` range pubK)"
    31   initState_Friend:  "initState (Friend i) =    
    32  		         insert (Key (priK (Friend i))) (Key ` range pubK)"
    33   initState_Spy:     "initState Spy        =    
    34  		         (Key`invKey`pubK`bad) Un (Key ` range pubK)"
    35 (*>*)
    36 
    37 text {*
    38 \noindent
    39 The set @{text bad} consists of those agents whose private keys are known to
    40 the spy.
    41 
    42 Two axioms are asserted about the public-key cryptosystem. 
    43 No two agents have the same public key, and no private key equals
    44 any public key.
    45 *}
    46 
    47 axioms
    48   inj_pubK:        "inj pubK"
    49   priK_neq_pubK:   "priK A ~= pubK B"
    50 (*<*)
    51 lemmas [iff] = inj_pubK [THEN inj_eq]
    52 
    53 lemma priK_inj_eq[iff]: "(priK A = priK B) = (A=B)"
    54   apply safe
    55   apply (drule_tac f=invKey in arg_cong)
    56   apply simp
    57   done
    58 
    59 lemmas [iff] = priK_neq_pubK priK_neq_pubK [THEN not_sym]
    60 
    61 lemma not_symKeys_pubK[iff]: "pubK A \<notin> symKeys"
    62   by (simp add: symKeys_def)
    63 
    64 lemma not_symKeys_priK[iff]: "priK A \<notin> symKeys"
    65   by (simp add: symKeys_def)
    66 
    67 lemma symKeys_neq_imp_neq: "(K \<in> symKeys) \<noteq> (K' \<in> symKeys) ==> K \<noteq> K'"
    68   by blast
    69 
    70 lemma analz_symKeys_Decrypt: "[| Crypt K X \<in> analz H;  K \<in> symKeys;  Key K \<in> analz H |]
    71      ==> X \<in> analz H"
    72   by (auto simp add: symKeys_def)
    73 
    74 
    75 (** "Image" equations that hold for injective functions **)
    76 
    77 lemma invKey_image_eq[simp]: "(invKey x : invKey`A) = (x:A)"
    78   by auto
    79 
    80 (*holds because invKey is injective*)
    81 lemma pubK_image_eq[simp]: "(pubK x : pubK`A) = (x:A)"
    82   by auto
    83 
    84 lemma priK_pubK_image_eq[simp]: "(priK x ~: pubK`A)"
    85   by auto
    86 
    87 
    88 (** Rewrites should not refer to  initState(Friend i) 
    89     -- not in normal form! **)
    90 
    91 lemma keysFor_parts_initState[simp]: "keysFor (parts (initState C)) = {}"
    92   apply (unfold keysFor_def)
    93   apply (induct C)
    94   apply (auto intro: range_eqI)
    95   done
    96 
    97 
    98 (*** Function "spies" ***)
    99 
   100 (*Agents see their own private keys!*)
   101 lemma priK_in_initState[iff]: "Key (priK A) : initState A"
   102   by (induct A) auto
   103 
   104 (*All public keys are visible*)
   105 lemma spies_pubK[iff]: "Key (pubK A) : spies evs"
   106   by (induct evs) (simp_all add: imageI knows_Cons split: event.split)
   107 
   108 (*Spy sees private keys of bad agents!*)
   109 lemma Spy_spies_bad[intro!]: "A: bad ==> Key (priK A) : spies evs"
   110   by (induct evs) (simp_all add: imageI knows_Cons split: event.split)
   111 
   112 lemmas [iff] = spies_pubK [THEN analz.Inj]
   113 
   114 
   115 (*** Fresh nonces ***)
   116 
   117 lemma Nonce_notin_initState[iff]: "Nonce N ~: parts (initState B)"
   118   by (induct B) auto
   119 
   120 lemma Nonce_notin_used_empty[simp]: "Nonce N ~: used []"
   121   by (simp add: used_Nil)
   122 
   123 
   124 (*** Supply fresh nonces for possibility theorems. ***)
   125 
   126 (*In any trace, there is an upper bound N on the greatest nonce in use.*)
   127 lemma Nonce_supply_lemma: "EX N. ALL n. N<=n --> Nonce n \<notin> used evs"
   128 apply (induct_tac "evs")
   129 apply (rule_tac x = 0 in exI)
   130 apply (simp_all (no_asm_simp) add: used_Cons split add: event.split)
   131 apply safe
   132 apply (rule msg_Nonce_supply [THEN exE], blast elim!: add_leE)+
   133 done
   134 
   135 lemma Nonce_supply1: "EX N. Nonce N \<notin> used evs"
   136 by (rule Nonce_supply_lemma [THEN exE], blast)
   137 
   138 lemma Nonce_supply: "Nonce (@ N. Nonce N \<notin> used evs) \<notin> used evs"
   139 apply (rule Nonce_supply_lemma [THEN exE])
   140 apply (rule someI, fast)
   141 done
   142 
   143 
   144 (*** Specialized rewriting for the analz_image_... theorems ***)
   145 
   146 lemma insert_Key_singleton: "insert (Key K) H = Key ` {K} Un H"
   147   by blast
   148 
   149 lemma insert_Key_image: "insert (Key K) (Key`KK Un C) = Key ` (insert K KK) Un C"
   150   by blast
   151 
   152 
   153 (*Specialized methods*)
   154 
   155 (*Tactic for possibility theorems*)
   156 ML {*
   157 fun possibility_tac st = st |>
   158     REPEAT (*omit used_Says so that Nonces start from different traces!*)
   159     (ALLGOALS (simp_tac (simpset() delsimps [used_Says]))
   160      THEN
   161      REPEAT_FIRST (eq_assume_tac ORELSE' 
   162                    resolve_tac [refl, conjI, @{thm Nonce_supply}]));
   163 *}
   164 
   165 method_setup possibility = {*
   166     Method.no_args (Method.METHOD (fn facts => possibility_tac)) *}
   167     "for proving possibility theorems"
   168 
   169 end
   170 (*>*)