| author | bulwahn | 
| Mon, 13 Sep 2010 16:44:17 +0200 | |
| changeset 39310 | 17ef4415b17c | 
| parent 36866 | 426d5781bb25 | 
| child 39758 | b8a53e3a0ee2 | 
| permissions | -rw-r--r-- | 
| 33028 | 1 | (* Title: HOL/SET_Protocol/Public_SET.thy | 
| 32960 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 2 | Author: Giampaolo Bella | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 3 | Author: Fabio Massacci | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 4 | Author: Lawrence C Paulson | 
| 14199 | 5 | *) | 
| 6 | ||
| 7 | header{*The Public-Key Theory, Modified for SET*}
 | |
| 8 | ||
| 33028 | 9 | theory Public_SET | 
| 10 | imports Event_SET | |
| 11 | begin | |
| 14199 | 12 | |
| 13 | subsection{*Symmetric and Asymmetric Keys*}
 | |
| 14 | ||
| 15 | text{*definitions influenced by the wish to assign asymmetric keys 
 | |
| 16 | - since the beginning - only to RCA and CAs, namely we need a partial | |
| 17 | function on type Agent*} | |
| 18 | ||
| 19 | ||
| 20 | text{*The SET specs mention two signature keys for CAs - we only have one*}
 | |
| 21 | ||
| 22 | consts | |
| 23 | publicKey :: "[bool, agent] => key" | |
| 24 |     --{*the boolean is TRUE if a signing key*}
 | |
| 25 | ||
| 35068 | 26 | abbreviation "pubEK == publicKey False" | 
| 27 | abbreviation "pubSK == publicKey True" | |
| 14199 | 28 | |
| 35068 | 29 | (*BEWARE!! priEK, priSK DON'T WORK with inj, range, image, etc.*) | 
| 30 | abbreviation "priEK A == invKey (pubEK A)" | |
| 31 | abbreviation "priSK A == invKey (pubSK A)" | |
| 14199 | 32 | |
| 33 | text{*By freeness of agents, no two agents have the same key. Since
 | |
| 34 |  @{term "True\<noteq>False"}, no agent has the same signing and encryption keys.*}
 | |
| 35 | ||
| 36 | specification (publicKey) | |
| 37 | injective_publicKey: | |
| 38 | "publicKey b A = publicKey c A' ==> b=c & A=A'" | |
| 14218 | 39 | (*<*) | 
| 14199 | 40 | apply (rule exI [of _ "%b A. 2 * nat_of_agent A + (if b then 1 else 0)"]) | 
| 41 | apply (auto simp add: inj_on_def inj_nat_of_agent [THEN inj_eq] split: agent.split) | |
| 42 | apply (drule_tac f="%x. x mod 2" in arg_cong, simp add: mod_Suc)+ | |
| 43 | (*or this, but presburger won't abstract out the function applications | |
| 44 | apply presburger+ | |
| 45 | *) | |
| 46 | done | |
| 14218 | 47 | (*>*) | 
| 14199 | 48 | |
| 49 | axioms | |
| 50 | (*No private key equals any public key (essential to ensure that private | |
| 51 | keys are private!) *) | |
| 52 | privateKey_neq_publicKey [iff]: | |
| 53 | "invKey (publicKey b A) \<noteq> publicKey b' A'" | |
| 54 | ||
| 55 | declare privateKey_neq_publicKey [THEN not_sym, iff] | |
| 56 | ||
| 57 | ||
| 58 | subsection{*Initial Knowledge*}
 | |
| 59 | ||
| 60 | text{*This information is not necessary.  Each protocol distributes any needed
 | |
| 61 | certificates, and anyway our proofs require a formalization of the Spy's | |
| 62 | knowledge only. However, the initial knowledge is as follows: | |
| 63 | All agents know RCA's public keys; | |
| 64 | RCA and CAs know their own respective keys; | |
| 65 | RCA (has already certified and therefore) knows all CAs public keys; | |
| 66 | Spy knows all keys of all bad agents.*} | |
| 67 | primrec | |
| 14218 | 68 | (*<*) | 
| 14199 | 69 | initState_CA: | 
| 70 | "initState (CA i) = | |
| 71 |        (if i=0 then Key ` ({priEK RCA, priSK RCA} Un
 | |
| 32960 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 72 | pubEK ` (range CA) Un pubSK ` (range CA)) | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 73 |         else {Key (priEK (CA i)), Key (priSK (CA i)),
 | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 74 | Key (pubEK (CA i)), Key (pubSK (CA i)), | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 75 | Key (pubEK RCA), Key (pubSK RCA)})" | 
| 14199 | 76 | |
| 77 | initState_Cardholder: | |
| 78 | "initState (Cardholder i) = | |
| 79 |        {Key (priEK (Cardholder i)), Key (priSK (Cardholder i)),
 | |
| 32960 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 80 | Key (pubEK (Cardholder i)), Key (pubSK (Cardholder i)), | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 81 | Key (pubEK RCA), Key (pubSK RCA)}" | 
| 14199 | 82 | |
| 83 | initState_Merchant: | |
| 84 | "initState (Merchant i) = | |
| 85 |        {Key (priEK (Merchant i)), Key (priSK (Merchant i)),
 | |
| 32960 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 86 | Key (pubEK (Merchant i)), Key (pubSK (Merchant i)), | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 87 | Key (pubEK RCA), Key (pubSK RCA)}" | 
| 14199 | 88 | |
| 89 | initState_PG: | |
| 90 | "initState (PG i) = | |
| 91 |        {Key (priEK (PG i)), Key (priSK (PG i)),
 | |
| 32960 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 92 | Key (pubEK (PG i)), Key (pubSK (PG i)), | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 93 | Key (pubEK RCA), Key (pubSK RCA)}" | 
| 14218 | 94 | (*>*) | 
| 14199 | 95 | initState_Spy: | 
| 96 | "initState Spy = Key ` (invKey ` pubEK ` bad Un | |
| 32960 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 97 | invKey ` pubSK ` bad Un | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 98 | range pubEK Un range pubSK)" | 
| 14199 | 99 | |
| 100 | ||
| 101 | text{*Injective mapping from agents to PANs: an agent can have only one card*}
 | |
| 102 | ||
| 103 | consts pan :: "agent => nat" | |
| 104 | ||
| 105 | specification (pan) | |
| 106 | inj_pan: "inj pan" | |
| 107 |   --{*No two agents have the same PAN*}
 | |
| 14218 | 108 | (*<*) | 
| 14199 | 109 | apply (rule exI [of _ "nat_of_agent"]) | 
| 110 | apply (simp add: inj_on_def inj_nat_of_agent [THEN inj_eq]) | |
| 111 | done | |
| 14218 | 112 | (*>*) | 
| 14199 | 113 | |
| 114 | declare inj_pan [THEN inj_eq, iff] | |
| 115 | ||
| 116 | consts | |
| 117 |   XOR :: "nat*nat => nat"  --{*no properties are assumed of exclusive-or*}
 | |
| 118 | ||
| 119 | ||
| 120 | subsection{*Signature Primitives*}
 | |
| 121 | ||
| 36866 | 122 | definition | 
| 14199 | 123 | (* Signature = Message + signed Digest *) | 
| 124 | sign :: "[key, msg]=>msg" | |
| 36866 | 125 |   where "sign K X = {|X, Crypt K (Hash X) |}"
 | 
| 14199 | 126 | |
| 36866 | 127 | definition | 
| 14199 | 128 | (* Signature Only = signed Digest Only *) | 
| 129 | signOnly :: "[key, msg]=>msg" | |
| 36866 | 130 | where "signOnly K X = Crypt K (Hash X)" | 
| 14199 | 131 | |
| 36866 | 132 | definition | 
| 14199 | 133 | (* Signature for Certificates = Message + signed Message *) | 
| 134 | signCert :: "[key, msg]=>msg" | |
| 36866 | 135 |   where "signCert K X = {|X, Crypt K X |}"
 | 
| 14199 | 136 | |
| 36866 | 137 | definition | 
| 14199 | 138 | (* Certification Authority's Certificate. | 
| 139 | Contains agent name, a key, a number specifying the key's target use, | |
| 140 | a key to sign the entire certificate. | |
| 141 | ||
| 142 | Should prove if signK=priSK RCA and C=CA i, | |
| 143 | then Ka=pubEK i or pubSK i depending on T ?? | |
| 144 | *) | |
| 145 | cert :: "[agent, key, msg, key] => msg" | |
| 36866 | 146 |   where "cert A Ka T signK = signCert signK {|Agent A, Key Ka, T|}"
 | 
| 14199 | 147 | |
| 36866 | 148 | definition | 
| 14199 | 149 | (* Cardholder's Certificate. | 
| 150 | Contains a PAN, the certified key Ka, the PANSecret PS, | |
| 151 | a number specifying the target use for Ka, the signing key signK. | |
| 152 | *) | |
| 153 | certC :: "[nat, key, nat, msg, key] => msg" | |
| 36866 | 154 | where "certC PAN Ka PS T signK = | 
| 155 |     signCert signK {|Hash {|Nonce PS, Pan PAN|}, Key Ka, T|}"
 | |
| 14199 | 156 | |
| 35068 | 157 | (*cert and certA have no repeated elements, so they could be abbreviations, | 
| 158 | but that's tricky and makes proofs slower*) | |
| 14199 | 159 | |
| 35068 | 160 | abbreviation "onlyEnc == Number 0" | 
| 161 | abbreviation "onlySig == Number (Suc 0)" | |
| 162 | abbreviation "authCode == Number (Suc (Suc 0))" | |
| 14199 | 163 | |
| 164 | subsection{*Encryption Primitives*}
 | |
| 165 | ||
| 35416 
d8d7d1b785af
replaced a couple of constsdefs by definitions (also some old primrecs by modern ones)
 haftmann parents: 
35068diff
changeset | 166 | definition EXcrypt :: "[key,key,msg,msg] => msg" where | 
| 14199 | 167 |   --{*Extra Encryption*}
 | 
| 168 | (*K: the symmetric key EK: the public encryption key*) | |
| 36866 | 169 | "EXcrypt K EK M m = | 
| 14199 | 170 |        {|Crypt K {|M, Hash m|}, Crypt EK {|Key K, m|}|}"
 | 
| 171 | ||
| 35416 
d8d7d1b785af
replaced a couple of constsdefs by definitions (also some old primrecs by modern ones)
 haftmann parents: 
35068diff
changeset | 172 | definition EXHcrypt :: "[key,key,msg,msg] => msg" where | 
| 14199 | 173 |   --{*Extra Encryption with Hashing*}
 | 
| 174 | (*K: the symmetric key EK: the public encryption key*) | |
| 36866 | 175 | "EXHcrypt K EK M m = | 
| 14199 | 176 |        {|Crypt K {|M, Hash m|}, Crypt EK {|Key K, m, Hash M|}|}"
 | 
| 177 | ||
| 35416 
d8d7d1b785af
replaced a couple of constsdefs by definitions (also some old primrecs by modern ones)
 haftmann parents: 
35068diff
changeset | 178 | definition Enc :: "[key,key,key,msg] => msg" where | 
| 14199 | 179 |   --{*Simple Encapsulation with SIGNATURE*}
 | 
| 180 | (*SK: the sender's signing key | |
| 181 | K: the symmetric key | |
| 182 | EK: the public encryption key*) | |
| 36866 | 183 | "Enc SK K EK M = | 
| 14199 | 184 |        {|Crypt K (sign SK M), Crypt EK (Key K)|}"
 | 
| 185 | ||
| 35416 
d8d7d1b785af
replaced a couple of constsdefs by definitions (also some old primrecs by modern ones)
 haftmann parents: 
35068diff
changeset | 186 | definition EncB :: "[key,key,key,msg,msg] => msg" where | 
| 14199 | 187 |   --{*Encapsulation with Baggage.  Keys as above, and baggage b.*}
 | 
| 36866 | 188 | "EncB SK K EK M b = | 
| 14199 | 189 |        {|Enc SK K EK {|M, Hash b|}, b|}"
 | 
| 190 | ||
| 191 | ||
| 192 | subsection{*Basic Properties of pubEK, pubSK, priEK and priSK *}
 | |
| 193 | ||
| 194 | lemma publicKey_eq_iff [iff]: | |
| 195 | "(publicKey b A = publicKey b' A') = (b=b' & A=A')" | |
| 196 | by (blast dest: injective_publicKey) | |
| 197 | ||
| 198 | lemma privateKey_eq_iff [iff]: | |
| 199 | "(invKey (publicKey b A) = invKey (publicKey b' A')) = (b=b' & A=A')" | |
| 200 | by auto | |
| 201 | ||
| 202 | lemma not_symKeys_publicKey [iff]: "publicKey b A \<notin> symKeys" | |
| 203 | by (simp add: symKeys_def) | |
| 204 | ||
| 205 | lemma not_symKeys_privateKey [iff]: "invKey (publicKey b A) \<notin> symKeys" | |
| 206 | by (simp add: symKeys_def) | |
| 207 | ||
| 208 | lemma symKeys_invKey_eq [simp]: "K \<in> symKeys ==> invKey K = K" | |
| 209 | by (simp add: symKeys_def) | |
| 210 | ||
| 211 | lemma symKeys_invKey_iff [simp]: "(invKey K \<in> symKeys) = (K \<in> symKeys)" | |
| 212 | by (unfold symKeys_def, auto) | |
| 213 | ||
| 214 | text{*Can be slow (or even loop) as a simprule*}
 | |
| 215 | lemma symKeys_neq_imp_neq: "(K \<in> symKeys) \<noteq> (K' \<in> symKeys) ==> K \<noteq> K'" | |
| 216 | by blast | |
| 217 | ||
| 218 | text{*These alternatives to @{text symKeys_neq_imp_neq} don't seem any better
 | |
| 219 | in practice.*} | |
| 220 | lemma publicKey_neq_symKey: "K \<in> symKeys ==> publicKey b A \<noteq> K" | |
| 221 | by blast | |
| 222 | ||
| 223 | lemma symKey_neq_publicKey: "K \<in> symKeys ==> K \<noteq> publicKey b A" | |
| 224 | by blast | |
| 225 | ||
| 226 | lemma privateKey_neq_symKey: "K \<in> symKeys ==> invKey (publicKey b A) \<noteq> K" | |
| 227 | by blast | |
| 228 | ||
| 229 | lemma symKey_neq_privateKey: "K \<in> symKeys ==> K \<noteq> invKey (publicKey b A)" | |
| 230 | by blast | |
| 231 | ||
| 232 | lemma analz_symKeys_Decrypt: | |
| 233 | "[| Crypt K X \<in> analz H; K \<in> symKeys; Key K \<in> analz H |] | |
| 234 | ==> X \<in> analz H" | |
| 235 | by auto | |
| 236 | ||
| 237 | ||
| 238 | subsection{*"Image" Equations That Hold for Injective Functions *}
 | |
| 239 | ||
| 240 | lemma invKey_image_eq [iff]: "(invKey x \<in> invKey`A) = (x\<in>A)" | |
| 241 | by auto | |
| 242 | ||
| 243 | text{*holds because invKey is injective*}
 | |
| 244 | lemma publicKey_image_eq [iff]: | |
| 245 | "(publicKey b A \<in> publicKey c ` AS) = (b=c & A\<in>AS)" | |
| 246 | by auto | |
| 247 | ||
| 248 | lemma privateKey_image_eq [iff]: | |
| 249 | "(invKey (publicKey b A) \<in> invKey ` publicKey c ` AS) = (b=c & A\<in>AS)" | |
| 250 | by auto | |
| 251 | ||
| 252 | lemma privateKey_notin_image_publicKey [iff]: | |
| 253 | "invKey (publicKey b A) \<notin> publicKey c ` AS" | |
| 254 | by auto | |
| 255 | ||
| 256 | lemma publicKey_notin_image_privateKey [iff]: | |
| 257 | "publicKey b A \<notin> invKey ` publicKey c ` AS" | |
| 258 | by auto | |
| 259 | ||
| 260 | lemma keysFor_parts_initState [simp]: "keysFor (parts (initState C)) = {}"
 | |
| 261 | apply (simp add: keysFor_def) | |
| 262 | apply (induct_tac "C") | |
| 263 | apply (auto intro: range_eqI) | |
| 264 | done | |
| 265 | ||
| 266 | text{*for proving @{text new_keys_not_used}*}
 | |
| 267 | lemma keysFor_parts_insert: | |
| 268 | "[| K \<in> keysFor (parts (insert X H)); X \<in> synth (analz H) |] | |
| 269 | ==> K \<in> keysFor (parts H) | Key (invKey K) \<in> parts H" | |
| 14218 | 270 | by (force dest!: | 
| 14199 | 271 | parts_insert_subset_Un [THEN keysFor_mono, THEN [2] rev_subsetD] | 
| 272 | analz_subset_parts [THEN keysFor_mono, THEN [2] rev_subsetD] | |
| 273 | intro: analz_into_parts) | |
| 274 | ||
| 275 | lemma Crypt_imp_keysFor [intro]: | |
| 276 | "[|K \<in> symKeys; Crypt K X \<in> H|] ==> K \<in> keysFor H" | |
| 277 | by (drule Crypt_imp_invKey_keysFor, simp) | |
| 278 | ||
| 279 | text{*Agents see their own private keys!*}
 | |
| 280 | lemma privateKey_in_initStateCA [iff]: | |
| 281 | "Key (invKey (publicKey b A)) \<in> initState A" | |
| 282 | by (case_tac "A", auto) | |
| 283 | ||
| 284 | text{*Agents see their own public keys!*}
 | |
| 285 | lemma publicKey_in_initStateCA [iff]: "Key (publicKey b A) \<in> initState A" | |
| 286 | by (case_tac "A", auto) | |
| 287 | ||
| 288 | text{*RCA sees CAs' public keys! *}
 | |
| 289 | lemma pubK_CA_in_initState_RCA [iff]: | |
| 290 | "Key (publicKey b (CA i)) \<in> initState RCA" | |
| 291 | by auto | |
| 292 | ||
| 293 | ||
| 294 | text{*Spy knows all public keys*}
 | |
| 295 | lemma knows_Spy_pubEK_i [iff]: "Key (publicKey b A) \<in> knows Spy evs" | |
| 296 | apply (induct_tac "evs") | |
| 297 | apply (simp_all add: imageI knows_Cons split add: event.split) | |
| 298 | done | |
| 299 | ||
| 300 | declare knows_Spy_pubEK_i [THEN analz.Inj, iff] | |
| 301 | (*needed????*) | |
| 302 | ||
| 303 | text{*Spy sees private keys of bad agents! [and obviously public keys too]*}
 | |
| 304 | lemma knows_Spy_bad_privateKey [intro!]: | |
| 305 | "A \<in> bad ==> Key (invKey (publicKey b A)) \<in> knows Spy evs" | |
| 14206 
77bf175f5145
Tidying of SET's "possibility theorems" (removal of Key_supply_ax)
 paulson parents: 
14199diff
changeset | 306 | by (rule initState_subset_knows [THEN subsetD], simp) | 
| 14199 | 307 | |
| 308 | ||
| 309 | subsection{*Fresh Nonces for Possibility Theorems*}
 | |
| 310 | ||
| 311 | lemma Nonce_notin_initState [iff]: "Nonce N \<notin> parts (initState B)" | |
| 312 | by (induct_tac "B", auto) | |
| 313 | ||
| 314 | lemma Nonce_notin_used_empty [simp]: "Nonce N \<notin> used []" | |
| 315 | by (simp add: used_Nil) | |
| 316 | ||
| 317 | text{*In any trace, there is an upper bound N on the greatest nonce in use.*}
 | |
| 318 | lemma Nonce_supply_lemma: "\<exists>N. \<forall>n. N<=n --> Nonce n \<notin> used evs" | |
| 319 | apply (induct_tac "evs") | |
| 320 | apply (rule_tac x = 0 in exI) | |
| 321 | apply (simp_all add: used_Cons split add: event.split, safe) | |
| 322 | apply (rule msg_Nonce_supply [THEN exE], blast elim!: add_leE)+ | |
| 323 | done | |
| 324 | ||
| 325 | lemma Nonce_supply1: "\<exists>N. Nonce N \<notin> used evs" | |
| 326 | by (rule Nonce_supply_lemma [THEN exE], blast) | |
| 327 | ||
| 328 | lemma Nonce_supply: "Nonce (@ N. Nonce N \<notin> used evs) \<notin> used evs" | |
| 329 | apply (rule Nonce_supply_lemma [THEN exE]) | |
| 330 | apply (rule someI, fast) | |
| 331 | done | |
| 332 | ||
| 333 | ||
| 334 | subsection{*Specialized Methods for Possibility Theorems*}
 | |
| 335 | ||
| 336 | ML | |
| 337 | {*
 | |
| 30607 
c3d1590debd8
eliminated global SIMPSET, CLASET etc. -- refer to explicit context;
 wenzelm parents: 
30549diff
changeset | 338 | (*Tactic for possibility theorems*) | 
| 
c3d1590debd8
eliminated global SIMPSET, CLASET etc. -- refer to explicit context;
 wenzelm parents: 
30549diff
changeset | 339 | fun possibility_tac ctxt = | 
| 14199 | 340 | REPEAT (*omit used_Says so that Nonces start from different traces!*) | 
| 32149 
ef59550a55d3
renamed simpset_of to global_simpset_of, and local_simpset_of to simpset_of -- same for claset and clasimpset;
 wenzelm parents: 
30607diff
changeset | 341 |     (ALLGOALS (simp_tac (simpset_of ctxt delsimps [@{thm used_Says}, @{thm used_Notes}]))
 | 
| 14199 | 342 | THEN | 
| 343 | REPEAT_FIRST (eq_assume_tac ORELSE' | |
| 24123 | 344 |                    resolve_tac [refl, conjI, @{thm Nonce_supply}]))
 | 
| 14199 | 345 | |
| 346 | (*For harder protocols (such as SET_CR!), where we have to set up some | |
| 347 | nonces and keys initially*) | |
| 30607 
c3d1590debd8
eliminated global SIMPSET, CLASET etc. -- refer to explicit context;
 wenzelm parents: 
30549diff
changeset | 348 | fun basic_possibility_tac ctxt = | 
| 14199 | 349 | REPEAT | 
| 32149 
ef59550a55d3
renamed simpset_of to global_simpset_of, and local_simpset_of to simpset_of -- same for claset and clasimpset;
 wenzelm parents: 
30607diff
changeset | 350 | (ALLGOALS (asm_simp_tac (simpset_of ctxt setSolver safe_solver)) | 
| 14199 | 351 | THEN | 
| 352 | REPEAT_FIRST (resolve_tac [refl, conjI])) | |
| 353 | *} | |
| 354 | ||
| 355 | method_setup possibility = {*
 | |
| 33028 | 356 | Scan.succeed (SIMPLE_METHOD o possibility_tac) *} | 
| 14199 | 357 | "for proving possibility theorems" | 
| 358 | ||
| 30607 
c3d1590debd8
eliminated global SIMPSET, CLASET etc. -- refer to explicit context;
 wenzelm parents: 
30549diff
changeset | 359 | method_setup basic_possibility = {*
 | 
| 33028 | 360 | Scan.succeed (SIMPLE_METHOD o basic_possibility_tac) *} | 
| 30607 
c3d1590debd8
eliminated global SIMPSET, CLASET etc. -- refer to explicit context;
 wenzelm parents: 
30549diff
changeset | 361 | "for proving possibility theorems" | 
| 14199 | 362 | |
| 363 | ||
| 364 | subsection{*Specialized Rewriting for Theorems About @{term analz} and Image*}
 | |
| 365 | ||
| 366 | lemma insert_Key_singleton: "insert (Key K) H = Key ` {K} Un H"
 | |
| 367 | by blast | |
| 368 | ||
| 369 | lemma insert_Key_image: | |
| 370 | "insert (Key K) (Key`KK Un C) = Key ` (insert K KK) Un C" | |
| 371 | by blast | |
| 372 | ||
| 373 | text{*Needed for @{text DK_fresh_not_KeyCryptKey}*}
 | |
| 374 | lemma publicKey_in_used [iff]: "Key (publicKey b A) \<in> used evs" | |
| 375 | by auto | |
| 376 | ||
| 377 | lemma privateKey_in_used [iff]: "Key (invKey (publicKey b A)) \<in> used evs" | |
| 378 | by (blast intro!: initState_into_used) | |
| 379 | ||
| 380 | text{*Reverse the normal simplification of "image" to build up (not break down)
 | |
| 381 |   the set of keys.  Based on @{text analz_image_freshK_ss}, but simpler.*}
 | |
| 382 | lemmas analz_image_keys_simps = | |
| 383 |        simp_thms mem_simps --{*these two allow its use with @{text "only:"}*}
 | |
| 384 | image_insert [THEN sym] image_Un [THEN sym] | |
| 385 | rangeI symKeys_neq_imp_neq | |
| 386 | insert_Key_singleton insert_Key_image Un_assoc [THEN sym] | |
| 387 | ||
| 388 | ||
| 389 | (*General lemmas proved by Larry*) | |
| 390 | ||
| 391 | subsection{*Controlled Unfolding of Abbreviations*}
 | |
| 392 | ||
| 393 | text{*A set is expanded only if a relation is applied to it*}
 | |
| 394 | lemma def_abbrev_simp_relation: | |
| 36866 | 395 | "A = B ==> (A \<in> X) = (B \<in> X) & | 
| 14199 | 396 | (u = A) = (u = B) & | 
| 397 | (A = u) = (B = u)" | |
| 398 | by auto | |
| 399 | ||
| 400 | text{*A set is expanded only if one of the given functions is applied to it*}
 | |
| 401 | lemma def_abbrev_simp_function: | |
| 36866 | 402 | "A = B | 
| 14199 | 403 | ==> parts (insert A X) = parts (insert B X) & | 
| 404 | analz (insert A X) = analz (insert B X) & | |
| 405 | keysFor (insert A X) = keysFor (insert B X)" | |
| 406 | by auto | |
| 407 | ||
| 408 | subsubsection{*Special Simplification Rules for @{term signCert}*}
 | |
| 409 | ||
| 410 | text{*Avoids duplicating X and its components!*}
 | |
| 411 | lemma parts_insert_signCert: | |
| 412 | "parts (insert (signCert K X) H) = | |
| 413 |       insert {|X, Crypt K X|} (parts (insert (Crypt K X) H))"
 | |
| 414 | by (simp add: signCert_def insert_commute [of X]) | |
| 415 | ||
| 416 | text{*Avoids a case split! [X is always available]*}
 | |
| 417 | lemma analz_insert_signCert: | |
| 418 | "analz (insert (signCert K X) H) = | |
| 419 |       insert {|X, Crypt K X|} (insert (Crypt K X) (analz (insert X H)))"
 | |
| 420 | by (simp add: signCert_def insert_commute [of X]) | |
| 421 | ||
| 422 | lemma keysFor_insert_signCert: "keysFor (insert (signCert K X) H) = keysFor H" | |
| 423 | by (simp add: signCert_def) | |
| 424 | ||
| 425 | text{*Controlled rewrite rules for @{term signCert}, just the definitions
 | |
| 426 | of the others. Encryption primitives are just expanded, despite their huge | |
| 427 | redundancy!*} | |
| 428 | lemmas abbrev_simps [simp] = | |
| 429 | parts_insert_signCert analz_insert_signCert keysFor_insert_signCert | |
| 32960 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 430 | sign_def [THEN def_abbrev_simp_relation] | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 431 | sign_def [THEN def_abbrev_simp_function] | 
| 14199 | 432 | signCert_def [THEN def_abbrev_simp_relation] | 
| 433 | signCert_def [THEN def_abbrev_simp_function] | |
| 32960 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 434 | certC_def [THEN def_abbrev_simp_relation] | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 435 | certC_def [THEN def_abbrev_simp_function] | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 436 | cert_def [THEN def_abbrev_simp_relation] | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 437 | cert_def [THEN def_abbrev_simp_function] | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 438 | EXcrypt_def [THEN def_abbrev_simp_relation] | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 439 | EXcrypt_def [THEN def_abbrev_simp_function] | 
| 14199 | 440 | EXHcrypt_def [THEN def_abbrev_simp_relation] | 
| 441 | EXHcrypt_def [THEN def_abbrev_simp_function] | |
| 32960 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 442 | Enc_def [THEN def_abbrev_simp_relation] | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 443 | Enc_def [THEN def_abbrev_simp_function] | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 444 | EncB_def [THEN def_abbrev_simp_relation] | 
| 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 445 | EncB_def [THEN def_abbrev_simp_function] | 
| 14199 | 446 | |
| 447 | ||
| 448 | subsubsection{*Elimination Rules for Controlled Rewriting *}
 | |
| 449 | ||
| 450 | lemma Enc_partsE: | |
| 451 | "!!R. [|Enc SK K EK M \<in> parts H; | |
| 452 | [|Crypt K (sign SK M) \<in> parts H; | |
| 453 | Crypt EK (Key K) \<in> parts H|] ==> R|] | |
| 454 | ==> R" | |
| 455 | ||
| 456 | by (unfold Enc_def, blast) | |
| 457 | ||
| 458 | lemma EncB_partsE: | |
| 459 | "!!R. [|EncB SK K EK M b \<in> parts H; | |
| 460 |              [|Crypt K (sign SK {|M, Hash b|}) \<in> parts H;  
 | |
| 461 | Crypt EK (Key K) \<in> parts H; | |
| 462 | b \<in> parts H|] ==> R|] | |
| 463 | ==> R" | |
| 464 | by (unfold EncB_def Enc_def, blast) | |
| 465 | ||
| 466 | lemma EXcrypt_partsE: | |
| 467 | "!!R. [|EXcrypt K EK M m \<in> parts H; | |
| 468 |              [|Crypt K {|M, Hash m|} \<in> parts H;  
 | |
| 469 |                Crypt EK {|Key K, m|} \<in> parts H|] ==> R|]  
 | |
| 470 | ==> R" | |
| 471 | by (unfold EXcrypt_def, blast) | |
| 472 | ||
| 473 | ||
| 474 | subsection{*Lemmas to Simplify Expressions Involving @{term analz} *}
 | |
| 475 | ||
| 476 | lemma analz_knows_absorb: | |
| 477 | "Key K \<in> analz (knows Spy evs) | |
| 478 | ==> analz (Key ` (insert K H) \<union> knows Spy evs) = | |
| 479 | analz (Key ` H \<union> knows Spy evs)" | |
| 480 | by (simp add: analz_insert_eq Un_upper2 [THEN analz_mono, THEN subsetD]) | |
| 481 | ||
| 482 | lemma analz_knows_absorb2: | |
| 483 | "Key K \<in> analz (knows Spy evs) | |
| 484 | ==> analz (Key ` (insert X (insert K H)) \<union> knows Spy evs) = | |
| 485 | analz (Key ` (insert X H) \<union> knows Spy evs)" | |
| 486 | apply (subst insert_commute) | |
| 487 | apply (erule analz_knows_absorb) | |
| 488 | done | |
| 489 | ||
| 490 | lemma analz_insert_subset_eq: | |
| 491 | "[|X \<in> analz (knows Spy evs); knows Spy evs \<subseteq> H|] | |
| 492 | ==> analz (insert X H) = analz H" | |
| 493 | apply (rule analz_insert_eq) | |
| 494 | apply (blast intro: analz_mono [THEN [2] rev_subsetD]) | |
| 495 | done | |
| 496 | ||
| 497 | lemmas analz_insert_simps = | |
| 498 | analz_insert_subset_eq Un_upper2 | |
| 32960 
69916a850301
eliminated hard tabulators, guessing at each author's individual tab-width;
 wenzelm parents: 
32149diff
changeset | 499 | subset_insertI [THEN [2] subset_trans] | 
| 14199 | 500 | |
| 501 | ||
| 502 | subsection{*Freshness Lemmas*}
 | |
| 503 | ||
| 504 | lemma in_parts_Says_imp_used: | |
| 505 |      "[|Key K \<in> parts {X}; Says A B X \<in> set evs|] ==> Key K \<in> used evs"
 | |
| 506 | by (blast intro: parts_trans dest!: Says_imp_knows_Spy [THEN parts.Inj]) | |
| 507 | ||
| 508 | text{*A useful rewrite rule with @{term analz_image_keys_simps}*}
 | |
| 509 | lemma Crypt_notin_image_Key: "Crypt K X \<notin> Key ` KK" | |
| 510 | by auto | |
| 511 | ||
| 512 | lemma fresh_notin_analz_knows_Spy: | |
| 513 | "Key K \<notin> used evs ==> Key K \<notin> analz (knows Spy evs)" | |
| 514 | by (auto dest: analz_into_parts) | |
| 515 | ||
| 516 | end |