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