| 14199 |      1 | (*  Title:      HOL/Auth/SET/EventSET
 | 
|  |      2 |     ID:         $Id$
 | 
|  |      3 |     Authors:     Giampaolo Bella, Fabio Massacci, Lawrence C Paulson
 | 
|  |      4 | *)
 | 
|  |      5 | 
 | 
|  |      6 | header{*Theory of Events for SET*}
 | 
|  |      7 | 
 | 
| 16417 |      8 | theory EventSET imports MessageSET begin
 | 
| 14199 |      9 | 
 | 
|  |     10 | text{*The Root Certification Authority*}
 | 
|  |     11 | syntax        RCA :: agent
 | 
|  |     12 | translations "RCA" == "CA 0"
 | 
|  |     13 | 
 | 
|  |     14 | 
 | 
|  |     15 | text{*Message events*}
 | 
|  |     16 | datatype
 | 
|  |     17 |   event = Says  agent agent msg
 | 
|  |     18 | 	| Gets  agent	    msg
 | 
|  |     19 |         | Notes agent       msg
 | 
|  |     20 | 
 | 
|  |     21 | 
 | 
|  |     22 | text{*compromised agents: keys known, Notes visible*}
 | 
|  |     23 | consts bad :: "agent set"
 | 
|  |     24 | 
 | 
|  |     25 | text{*Spy has access to his own key for spoof messages, but RCA is secure*}
 | 
|  |     26 | specification (bad)
 | 
|  |     27 |   Spy_in_bad     [iff]: "Spy \<in> bad"
 | 
|  |     28 |   RCA_not_bad [iff]: "RCA \<notin> bad"
 | 
|  |     29 |     by (rule exI [of _ "{Spy}"], simp)
 | 
|  |     30 | 
 | 
|  |     31 | 
 | 
|  |     32 | subsection{*Agents' Knowledge*}
 | 
|  |     33 | 
 | 
|  |     34 | consts  (*Initial states of agents -- parameter of the construction*)
 | 
|  |     35 |   initState :: "agent => msg set"
 | 
|  |     36 |   knows  :: "[agent, event list] => msg set"
 | 
|  |     37 | 
 | 
|  |     38 | (* Message reception does not extend spy's knowledge because of
 | 
|  |     39 |    reception invariant enforced by Reception rule in protocol definition*)
 | 
|  |     40 | primrec
 | 
|  |     41 | 
 | 
|  |     42 | knows_Nil:
 | 
|  |     43 |   "knows A []       = initState A"
 | 
|  |     44 | knows_Cons:
 | 
|  |     45 |     "knows A (ev # evs) =
 | 
|  |     46 |        (if A = Spy then
 | 
|  |     47 | 	(case ev of
 | 
|  |     48 | 	   Says A' B X => insert X (knows Spy evs)
 | 
|  |     49 | 	 | Gets A' X => knows Spy evs
 | 
|  |     50 | 	 | Notes A' X  =>
 | 
|  |     51 | 	     if A' \<in> bad then insert X (knows Spy evs) else knows Spy evs)
 | 
|  |     52 | 	else
 | 
|  |     53 | 	(case ev of
 | 
|  |     54 | 	   Says A' B X =>
 | 
|  |     55 | 	     if A'=A then insert X (knows A evs) else knows A evs
 | 
|  |     56 | 	 | Gets A' X    =>
 | 
|  |     57 | 	     if A'=A then insert X (knows A evs) else knows A evs
 | 
|  |     58 | 	 | Notes A' X    =>
 | 
|  |     59 | 	     if A'=A then insert X (knows A evs) else knows A evs))"
 | 
|  |     60 | 
 | 
|  |     61 | 
 | 
|  |     62 | subsection{*Used Messages*}
 | 
|  |     63 | 
 | 
|  |     64 | consts
 | 
|  |     65 |   (*Set of items that might be visible to somebody:
 | 
|  |     66 |     complement of the set of fresh items*)
 | 
|  |     67 |   used :: "event list => msg set"
 | 
|  |     68 | 
 | 
|  |     69 | (* As above, message reception does extend used items *)
 | 
|  |     70 | primrec
 | 
|  |     71 |   used_Nil:  "used []         = (UN B. parts (initState B))"
 | 
|  |     72 |   used_Cons: "used (ev # evs) =
 | 
|  |     73 | 	         (case ev of
 | 
|  |     74 | 		    Says A B X => parts {X} Un (used evs)
 | 
|  |     75 |          	  | Gets A X   => used evs
 | 
|  |     76 | 		  | Notes A X  => parts {X} Un (used evs))"
 | 
|  |     77 | 
 | 
|  |     78 | 
 | 
|  |     79 | 
 | 
|  |     80 | (* Inserted by default but later removed.  This declaration lets the file
 | 
|  |     81 | be re-loaded. Addsimps [knows_Cons, used_Nil, *)
 | 
|  |     82 | 
 | 
|  |     83 | (** Simplifying   parts (insert X (knows Spy evs))
 | 
|  |     84 |       = parts {X} Un parts (knows Spy evs) -- since general case loops*)
 | 
|  |     85 | 
 | 
|  |     86 | lemmas parts_insert_knows_A = parts_insert [of _ "knows A evs", standard]
 | 
|  |     87 | 
 | 
|  |     88 | lemma knows_Spy_Says [simp]:
 | 
|  |     89 |      "knows Spy (Says A B X # evs) = insert X (knows Spy evs)"
 | 
|  |     90 | by auto
 | 
|  |     91 | 
 | 
|  |     92 | text{*Letting the Spy see "bad" agents' notes avoids redundant case-splits
 | 
|  |     93 |       on whether @{term "A=Spy"} and whether @{term "A\<in>bad"}*}
 | 
|  |     94 | lemma knows_Spy_Notes [simp]:
 | 
|  |     95 |      "knows Spy (Notes A X # evs) =
 | 
|  |     96 |           (if A:bad then insert X (knows Spy evs) else knows Spy evs)"
 | 
|  |     97 | apply auto
 | 
|  |     98 | done
 | 
|  |     99 | 
 | 
|  |    100 | lemma knows_Spy_Gets [simp]: "knows Spy (Gets A X # evs) = knows Spy evs"
 | 
|  |    101 | by auto
 | 
|  |    102 | 
 | 
|  |    103 | lemma initState_subset_knows: "initState A <= knows A evs"
 | 
|  |    104 | apply (induct_tac "evs")
 | 
|  |    105 | apply (auto split: event.split) 
 | 
|  |    106 | done
 | 
|  |    107 | 
 | 
|  |    108 | lemma knows_Spy_subset_knows_Spy_Says:
 | 
|  |    109 |      "knows Spy evs <= knows Spy (Says A B X # evs)"
 | 
|  |    110 | by auto
 | 
|  |    111 | 
 | 
|  |    112 | lemma knows_Spy_subset_knows_Spy_Notes:
 | 
|  |    113 |      "knows Spy evs <= knows Spy (Notes A X # evs)"
 | 
|  |    114 | by auto
 | 
|  |    115 | 
 | 
|  |    116 | lemma knows_Spy_subset_knows_Spy_Gets:
 | 
|  |    117 |      "knows Spy evs <= knows Spy (Gets A X # evs)"
 | 
|  |    118 | by auto
 | 
|  |    119 | 
 | 
|  |    120 | (*Spy sees what is sent on the traffic*)
 | 
|  |    121 | lemma Says_imp_knows_Spy [rule_format]:
 | 
|  |    122 |      "Says A B X \<in> set evs --> X \<in> knows Spy evs"
 | 
|  |    123 | apply (induct_tac "evs")
 | 
|  |    124 | apply (auto split: event.split) 
 | 
|  |    125 | done
 | 
|  |    126 | 
 | 
|  |    127 | (*Use with addSEs to derive contradictions from old Says events containing
 | 
|  |    128 |   items known to be fresh*)
 | 
|  |    129 | lemmas knows_Spy_partsEs =
 | 
|  |    130 |      Says_imp_knows_Spy [THEN parts.Inj, THEN revcut_rl, standard] 
 | 
|  |    131 |      parts.Body [THEN revcut_rl, standard]
 | 
|  |    132 | 
 | 
|  |    133 | 
 | 
|  |    134 | subsection{*The Function @{term used}*}
 | 
|  |    135 | 
 | 
|  |    136 | lemma parts_knows_Spy_subset_used: "parts (knows Spy evs) <= used evs"
 | 
|  |    137 | apply (induct_tac "evs")
 | 
|  |    138 | apply (auto simp add: parts_insert_knows_A split: event.split) 
 | 
|  |    139 | done
 | 
|  |    140 | 
 | 
|  |    141 | lemmas usedI = parts_knows_Spy_subset_used [THEN subsetD, intro]
 | 
|  |    142 | 
 | 
|  |    143 | lemma initState_subset_used: "parts (initState B) <= used evs"
 | 
|  |    144 | apply (induct_tac "evs")
 | 
|  |    145 | apply (auto split: event.split) 
 | 
|  |    146 | done
 | 
|  |    147 | 
 | 
|  |    148 | lemmas initState_into_used = initState_subset_used [THEN subsetD]
 | 
|  |    149 | 
 | 
|  |    150 | lemma used_Says [simp]: "used (Says A B X # evs) = parts{X} Un used evs"
 | 
|  |    151 | by auto
 | 
|  |    152 | 
 | 
|  |    153 | lemma used_Notes [simp]: "used (Notes A X # evs) = parts{X} Un used evs"
 | 
|  |    154 | by auto
 | 
|  |    155 | 
 | 
|  |    156 | lemma used_Gets [simp]: "used (Gets A X # evs) = used evs"
 | 
|  |    157 | by auto
 | 
|  |    158 | 
 | 
|  |    159 | 
 | 
|  |    160 | lemma Notes_imp_parts_subset_used [rule_format]:
 | 
|  |    161 |      "Notes A X \<in> set evs --> parts {X} <= used evs"
 | 
|  |    162 | apply (induct_tac "evs")
 | 
|  |    163 | apply (induct_tac [2] "a", auto)
 | 
|  |    164 | done
 | 
|  |    165 | 
 | 
|  |    166 | text{*NOTE REMOVAL--laws above are cleaner, as they don't involve "case"*}
 | 
|  |    167 | declare knows_Cons [simp del]
 | 
|  |    168 |         used_Nil [simp del] used_Cons [simp del]
 | 
|  |    169 | 
 | 
|  |    170 | 
 | 
|  |    171 | text{*For proving theorems of the form @{term "X \<notin> analz (knows Spy evs) --> P"}
 | 
|  |    172 |   New events added by induction to "evs" are discarded.  Provided 
 | 
|  |    173 |   this information isn't needed, the proof will be much shorter, since
 | 
|  |    174 |   it will omit complicated reasoning about @{term analz}.*}
 | 
|  |    175 | 
 | 
|  |    176 | lemmas analz_mono_contra =
 | 
|  |    177 |        knows_Spy_subset_knows_Spy_Says [THEN analz_mono, THEN contra_subsetD]
 | 
|  |    178 |        knows_Spy_subset_knows_Spy_Notes [THEN analz_mono, THEN contra_subsetD]
 | 
|  |    179 |        knows_Spy_subset_knows_Spy_Gets [THEN analz_mono, THEN contra_subsetD]
 | 
|  |    180 | ML
 | 
|  |    181 | {*
 | 
|  |    182 | val analz_mono_contra_tac = 
 | 
|  |    183 |   let val analz_impI = inst "P" "?Y \<notin> analz (knows Spy ?evs)" impI
 | 
| 14218 |    184 |   in rtac analz_impI THEN' 
 | 
| 24123 |    185 |      REPEAT1 o (dresolve_tac @{thms analz_mono_contra}) THEN'
 | 
| 14218 |    186 |      mp_tac
 | 
| 14199 |    187 |   end
 | 
|  |    188 | *}
 | 
|  |    189 | 
 | 
|  |    190 | method_setup analz_mono_contra = {*
 | 
| 21588 |    191 |     Method.no_args (Method.SIMPLE_METHOD (REPEAT_FIRST analz_mono_contra_tac)) *}
 | 
| 14199 |    192 |     "for proving theorems of the form X \<notin> analz (knows Spy evs) --> P"
 | 
|  |    193 | 
 | 
|  |    194 | end
 |