49 | "freenonces (DECRYPT K X) = freenonces X" |
49 | "freenonces (DECRYPT K X) = freenonces X" |
50 |
50 |
51 theorem msgrel_imp_eq_freenonces: |
51 theorem msgrel_imp_eq_freenonces: |
52 assumes a: "U \<sim> V" |
52 assumes a: "U \<sim> V" |
53 shows "freenonces U = freenonces V" |
53 shows "freenonces U = freenonces V" |
54 using a by (induct) (auto) |
54 using a by (induct) (auto) |
55 |
55 |
56 subsubsection{*The Left Projection*} |
56 subsubsection{*The Left Projection*} |
57 |
57 |
58 text{*A function to return the left part of the top pair in a message. It will |
58 text{*A function to return the left part of the top pair in a message. It will |
59 be lifted to the initial algrebra, to serve as an example of that process.*} |
59 be lifted to the initial algrebra, to serve as an example of that process.*} |
68 text{*This theorem lets us prove that the left function respects the |
68 text{*This theorem lets us prove that the left function respects the |
69 equivalence relation. It also helps us prove that MPair |
69 equivalence relation. It also helps us prove that MPair |
70 (the abstract constructor) is injective*} |
70 (the abstract constructor) is injective*} |
71 lemma msgrel_imp_eqv_freeleft_aux: |
71 lemma msgrel_imp_eqv_freeleft_aux: |
72 shows "freeleft U \<sim> freeleft U" |
72 shows "freeleft U \<sim> freeleft U" |
73 by (induct rule: freeleft.induct) (auto) |
73 by (induct rule: freeleft.induct) (auto) |
74 |
74 |
75 theorem msgrel_imp_eqv_freeleft: |
75 theorem msgrel_imp_eqv_freeleft: |
76 assumes a: "U \<sim> V" |
76 assumes a: "U \<sim> V" |
77 shows "freeleft U \<sim> freeleft V" |
77 shows "freeleft U \<sim> freeleft V" |
78 using a |
78 using a |
79 by (induct)(auto intro: msgrel_imp_eqv_freeleft_aux) |
79 by (induct) (auto intro: msgrel_imp_eqv_freeleft_aux) |
80 |
80 |
81 subsubsection{*The Right Projection*} |
81 subsubsection{*The Right Projection*} |
82 |
82 |
83 text{*A function to return the right part of the top pair in a message.*} |
83 text{*A function to return the right part of the top pair in a message.*} |
84 fun |
84 fun |
92 text{*This theorem lets us prove that the right function respects the |
92 text{*This theorem lets us prove that the right function respects the |
93 equivalence relation. It also helps us prove that MPair |
93 equivalence relation. It also helps us prove that MPair |
94 (the abstract constructor) is injective*} |
94 (the abstract constructor) is injective*} |
95 lemma msgrel_imp_eqv_freeright_aux: |
95 lemma msgrel_imp_eqv_freeright_aux: |
96 shows "freeright U \<sim> freeright U" |
96 shows "freeright U \<sim> freeright U" |
97 by (induct rule: freeright.induct) (auto) |
97 by (induct rule: freeright.induct) (auto) |
98 |
98 |
99 theorem msgrel_imp_eqv_freeright: |
99 theorem msgrel_imp_eqv_freeright: |
100 assumes a: "U \<sim> V" |
100 assumes a: "U \<sim> V" |
101 shows "freeright U \<sim> freeright V" |
101 shows "freeright U \<sim> freeright V" |
102 using a |
102 using a |
103 by (induct) (auto intro: msgrel_imp_eqv_freeright_aux) |
103 by (induct) (auto intro: msgrel_imp_eqv_freeright_aux) |
104 |
104 |
105 subsubsection{*The Discriminator for Constructors*} |
105 subsubsection{*The Discriminator for Constructors*} |
106 |
106 |
107 text{*A function to distinguish nonces, mpairs and encryptions*} |
107 text{*A function to distinguish nonces, mpairs and encryptions*} |
108 fun |
108 fun |
115 |
115 |
116 text{*This theorem helps us prove @{term "Nonce N \<noteq> MPair X Y"}*} |
116 text{*This theorem helps us prove @{term "Nonce N \<noteq> MPair X Y"}*} |
117 theorem msgrel_imp_eq_freediscrim: |
117 theorem msgrel_imp_eq_freediscrim: |
118 assumes a: "U \<sim> V" |
118 assumes a: "U \<sim> V" |
119 shows "freediscrim U = freediscrim V" |
119 shows "freediscrim U = freediscrim V" |
120 using a by (induct, auto) |
120 using a by (induct) (auto) |
121 |
121 |
122 subsection{*The Initial Algebra: A Quotiented Message Type*} |
122 subsection{*The Initial Algebra: A Quotiented Message Type*} |
123 |
123 |
124 quotient_type msg = freemsg / msgrel |
124 quotient_type msg = freemsg / msgrel |
125 by (rule equiv_msgrel) |
125 by (rule equiv_msgrel) |
153 lemma [quot_respect]: |
153 lemma [quot_respect]: |
154 shows "(op = ===> op \<sim> ===> op \<sim>) DECRYPT DECRYPT" |
154 shows "(op = ===> op \<sim> ===> op \<sim>) DECRYPT DECRYPT" |
155 by (auto intro: DECRYPT) |
155 by (auto intro: DECRYPT) |
156 |
156 |
157 text{*Establishing these two equations is the point of the whole exercise*} |
157 text{*Establishing these two equations is the point of the whole exercise*} |
158 theorem CD_eq [simp]: "Crypt K (Decrypt K X) = X" |
158 theorem CD_eq [simp]: |
159 by (lifting CD) |
159 shows "Crypt K (Decrypt K X) = X" |
160 |
160 by (lifting CD) |
161 theorem DC_eq [simp]: "Decrypt K (Crypt K X) = X" |
161 |
162 by (lifting DC) |
162 theorem DC_eq [simp]: |
|
163 shows "Decrypt K (Crypt K X) = X" |
|
164 by (lifting DC) |
163 |
165 |
164 subsection{*The Abstract Function to Return the Set of Nonces*} |
166 subsection{*The Abstract Function to Return the Set of Nonces*} |
165 |
167 |
166 quotient_definition |
168 quotient_definition |
167 "nonces:: msg \<Rightarrow> nat set" |
169 "nonces:: msg \<Rightarrow> nat set" |
170 |
172 |
171 text{*Now prove the four equations for @{term nonces}*} |
173 text{*Now prove the four equations for @{term nonces}*} |
172 |
174 |
173 lemma [quot_respect]: |
175 lemma [quot_respect]: |
174 shows "(op \<sim> ===> op =) freenonces freenonces" |
176 shows "(op \<sim> ===> op =) freenonces freenonces" |
175 by (simp add: msgrel_imp_eq_freenonces) |
177 by (simp add: msgrel_imp_eq_freenonces) |
176 |
178 |
177 lemma [quot_respect]: |
179 lemma [quot_respect]: |
178 shows "(op = ===> op \<sim>) NONCE NONCE" |
180 shows "(op = ===> op \<sim>) NONCE NONCE" |
179 by (simp add: NONCE) |
181 by (simp add: NONCE) |
180 |
182 |
181 lemma nonces_Nonce [simp]: |
183 lemma nonces_Nonce [simp]: |
182 shows "nonces (Nonce N) = {N}" |
184 shows "nonces (Nonce N) = {N}" |
183 by (lifting freenonces.simps(1)) |
185 by (lifting freenonces.simps(1)) |
184 |
186 |
185 lemma [quot_respect]: |
187 lemma [quot_respect]: |
186 shows " (op \<sim> ===> op \<sim> ===> op \<sim>) MPAIR MPAIR" |
188 shows " (op \<sim> ===> op \<sim> ===> op \<sim>) MPAIR MPAIR" |
187 by (simp add: MPAIR) |
189 by (simp add: MPAIR) |
188 |
190 |
189 lemma nonces_MPair [simp]: |
191 lemma nonces_MPair [simp]: |
190 shows "nonces (MPair X Y) = nonces X \<union> nonces Y" |
192 shows "nonces (MPair X Y) = nonces X \<union> nonces Y" |
191 by (lifting freenonces.simps(2)) |
193 by (lifting freenonces.simps(2)) |
192 |
194 |
193 lemma nonces_Crypt [simp]: |
195 lemma nonces_Crypt [simp]: |
194 shows "nonces (Crypt K X) = nonces X" |
196 shows "nonces (Crypt K X) = nonces X" |
195 by (lifting freenonces.simps(3)) |
197 by (lifting freenonces.simps(3)) |
196 |
198 |
197 lemma nonces_Decrypt [simp]: "nonces (Decrypt K X) = nonces X" |
199 lemma nonces_Decrypt [simp]: |
198 by (lifting freenonces.simps(4)) |
200 shows "nonces (Decrypt K X) = nonces X" |
|
201 by (lifting freenonces.simps(4)) |
199 |
202 |
200 subsection{*The Abstract Function to Return the Left Part*} |
203 subsection{*The Abstract Function to Return the Left Part*} |
201 |
204 |
202 quotient_definition |
205 quotient_definition |
203 "left:: msg \<Rightarrow> msg" |
206 "left:: msg \<Rightarrow> msg" |
204 as |
207 as |
205 "freeleft" |
208 "freeleft" |
206 |
209 |
207 lemma [quot_respect]: |
210 lemma [quot_respect]: |
208 shows "(op \<sim> ===> op \<sim>) freeleft freeleft" |
211 shows "(op \<sim> ===> op \<sim>) freeleft freeleft" |
209 by (simp add: msgrel_imp_eqv_freeleft) |
212 by (simp add: msgrel_imp_eqv_freeleft) |
210 |
213 |
211 lemma left_Nonce [simp]: |
214 lemma left_Nonce [simp]: |
212 shows "left (Nonce N) = Nonce N" |
215 shows "left (Nonce N) = Nonce N" |
213 by (lifting freeleft.simps(1)) |
216 by (lifting freeleft.simps(1)) |
214 |
217 |
215 lemma left_MPair [simp]: |
218 lemma left_MPair [simp]: |
216 shows "left (MPair X Y) = X" |
219 shows "left (MPair X Y) = X" |
217 by (lifting freeleft.simps(2)) |
220 by (lifting freeleft.simps(2)) |
218 |
221 |
219 lemma left_Crypt [simp]: |
222 lemma left_Crypt [simp]: |
220 shows "left (Crypt K X) = left X" |
223 shows "left (Crypt K X) = left X" |
221 by (lifting freeleft.simps(3)) |
224 by (lifting freeleft.simps(3)) |
222 |
225 |
223 lemma left_Decrypt [simp]: |
226 lemma left_Decrypt [simp]: |
224 shows "left (Decrypt K X) = left X" |
227 shows "left (Decrypt K X) = left X" |
225 by (lifting freeleft.simps(4)) |
228 by (lifting freeleft.simps(4)) |
226 |
229 |
227 subsection{*The Abstract Function to Return the Right Part*} |
230 subsection{*The Abstract Function to Return the Right Part*} |
228 |
231 |
229 quotient_definition |
232 quotient_definition |
230 "right:: msg \<Rightarrow> msg" |
233 "right:: msg \<Rightarrow> msg" |
233 |
236 |
234 text{*Now prove the four equations for @{term right}*} |
237 text{*Now prove the four equations for @{term right}*} |
235 |
238 |
236 lemma [quot_respect]: |
239 lemma [quot_respect]: |
237 shows "(op \<sim> ===> op \<sim>) freeright freeright" |
240 shows "(op \<sim> ===> op \<sim>) freeright freeright" |
238 by (simp add: msgrel_imp_eqv_freeright) |
241 by (simp add: msgrel_imp_eqv_freeright) |
239 |
242 |
240 lemma right_Nonce [simp]: |
243 lemma right_Nonce [simp]: |
241 shows "right (Nonce N) = Nonce N" |
244 shows "right (Nonce N) = Nonce N" |
242 by (lifting freeright.simps(1)) |
245 by (lifting freeright.simps(1)) |
243 |
246 |
244 lemma right_MPair [simp]: |
247 lemma right_MPair [simp]: |
245 shows "right (MPair X Y) = Y" |
248 shows "right (MPair X Y) = Y" |
246 by (lifting freeright.simps(2)) |
249 by (lifting freeright.simps(2)) |
247 |
250 |
248 lemma right_Crypt [simp]: |
251 lemma right_Crypt [simp]: |
249 shows "right (Crypt K X) = right X" |
252 shows "right (Crypt K X) = right X" |
250 by (lifting freeright.simps(3)) |
253 by (lifting freeright.simps(3)) |
251 |
254 |
252 lemma right_Decrypt [simp]: |
255 lemma right_Decrypt [simp]: |
253 shows "right (Decrypt K X) = right X" |
256 shows "right (Decrypt K X) = right X" |
254 by (lifting freeright.simps(4)) |
257 by (lifting freeright.simps(4)) |
255 |
258 |
256 subsection{*Injectivity Properties of Some Constructors*} |
259 subsection{*Injectivity Properties of Some Constructors*} |
257 |
260 |
258 lemma NONCE_imp_eq: |
261 lemma NONCE_imp_eq: |
259 shows "NONCE m \<sim> NONCE n \<Longrightarrow> m = n" |
262 shows "NONCE m \<sim> NONCE n \<Longrightarrow> m = n" |
260 by (drule msgrel_imp_eq_freenonces, simp) |
263 by (drule msgrel_imp_eq_freenonces, simp) |
261 |
264 |
262 text{*Can also be proved using the function @{term nonces}*} |
265 text{*Can also be proved using the function @{term nonces}*} |
263 lemma Nonce_Nonce_eq [iff]: |
266 lemma Nonce_Nonce_eq [iff]: |
264 shows "(Nonce m = Nonce n) = (m = n)" |
267 shows "(Nonce m = Nonce n) = (m = n)" |
265 proof |
268 proof |
270 then show "Nonce m = Nonce n" by simp |
273 then show "Nonce m = Nonce n" by simp |
271 qed |
274 qed |
272 |
275 |
273 lemma MPAIR_imp_eqv_left: |
276 lemma MPAIR_imp_eqv_left: |
274 shows "MPAIR X Y \<sim> MPAIR X' Y' \<Longrightarrow> X \<sim> X'" |
277 shows "MPAIR X Y \<sim> MPAIR X' Y' \<Longrightarrow> X \<sim> X'" |
275 by (drule msgrel_imp_eqv_freeleft) (simp) |
278 by (drule msgrel_imp_eqv_freeleft) (simp) |
276 |
279 |
277 lemma MPair_imp_eq_left: |
280 lemma MPair_imp_eq_left: |
278 assumes eq: "MPair X Y = MPair X' Y'" |
281 assumes eq: "MPair X Y = MPair X' Y'" |
279 shows "X = X'" |
282 shows "X = X'" |
280 using eq by (lifting MPAIR_imp_eqv_left) |
283 using eq by (lifting MPAIR_imp_eqv_left) |
281 |
284 |
282 lemma MPAIR_imp_eqv_right: |
285 lemma MPAIR_imp_eqv_right: |
283 shows "MPAIR X Y \<sim> MPAIR X' Y' \<Longrightarrow> Y \<sim> Y'" |
286 shows "MPAIR X Y \<sim> MPAIR X' Y' \<Longrightarrow> Y \<sim> Y'" |
284 by (drule msgrel_imp_eqv_freeright) (simp) |
287 by (drule msgrel_imp_eqv_freeright) (simp) |
285 |
288 |
286 lemma MPair_imp_eq_right: |
289 lemma MPair_imp_eq_right: |
287 shows "MPair X Y = MPair X' Y' \<Longrightarrow> Y = Y'" |
290 shows "MPair X Y = MPair X' Y' \<Longrightarrow> Y = Y'" |
288 by (lifting MPAIR_imp_eqv_right) |
291 by (lifting MPAIR_imp_eqv_right) |
289 |
292 |
290 theorem MPair_MPair_eq [iff]: |
293 theorem MPair_MPair_eq [iff]: |
291 shows "(MPair X Y = MPair X' Y') = (X=X' & Y=Y')" |
294 shows "(MPair X Y = MPair X' Y') = (X=X' & Y=Y')" |
292 by (blast dest: MPair_imp_eq_left MPair_imp_eq_right) |
295 by (blast dest: MPair_imp_eq_left MPair_imp_eq_right) |
293 |
296 |
294 lemma NONCE_neqv_MPAIR: |
297 lemma NONCE_neqv_MPAIR: |
295 shows "\<not>(NONCE m \<sim> MPAIR X Y)" |
298 shows "\<not>(NONCE m \<sim> MPAIR X Y)" |
296 by (auto dest: msgrel_imp_eq_freediscrim) |
299 by (auto dest: msgrel_imp_eq_freediscrim) |
297 |
300 |
298 theorem Nonce_neq_MPair [iff]: |
301 theorem Nonce_neq_MPair [iff]: |
299 shows "Nonce N \<noteq> MPair X Y" |
302 shows "Nonce N \<noteq> MPair X Y" |
300 by (lifting NONCE_neqv_MPAIR) |
303 by (lifting NONCE_neqv_MPAIR) |
301 |
304 |
302 text{*Example suggested by a referee*} |
305 text{*Example suggested by a referee*} |
303 |
306 |
304 lemma CRYPT_NONCE_neq_NONCE: |
307 lemma CRYPT_NONCE_neq_NONCE: |
305 shows "\<not>(CRYPT K (NONCE M) \<sim> NONCE N)" |
308 shows "\<not>(CRYPT K (NONCE M) \<sim> NONCE N)" |
306 by (auto dest: msgrel_imp_eq_freediscrim) |
309 by (auto dest: msgrel_imp_eq_freediscrim) |
307 |
310 |
308 theorem Crypt_Nonce_neq_Nonce: |
311 theorem Crypt_Nonce_neq_Nonce: |
309 shows "Crypt K (Nonce M) \<noteq> Nonce N" |
312 shows "Crypt K (Nonce M) \<noteq> Nonce N" |
310 by (lifting CRYPT_NONCE_neq_NONCE) |
313 by (lifting CRYPT_NONCE_neq_NONCE) |
311 |
314 |
312 text{*...and many similar results*} |
315 text{*...and many similar results*} |
313 lemma CRYPT2_NONCE_neq_NONCE: |
316 lemma CRYPT2_NONCE_neq_NONCE: |
314 shows "\<not>(CRYPT K (CRYPT K' (NONCE M)) \<sim> NONCE N)" |
317 shows "\<not>(CRYPT K (CRYPT K' (NONCE M)) \<sim> NONCE N)" |
315 by (auto dest: msgrel_imp_eq_freediscrim) |
318 by (auto dest: msgrel_imp_eq_freediscrim) |
316 |
319 |
317 theorem Crypt2_Nonce_neq_Nonce: |
320 theorem Crypt2_Nonce_neq_Nonce: |
318 shows "Crypt K (Crypt K' (Nonce M)) \<noteq> Nonce N" |
321 shows "Crypt K (Crypt K' (Nonce M)) \<noteq> Nonce N" |
319 by (lifting CRYPT2_NONCE_neq_NONCE) |
322 by (lifting CRYPT2_NONCE_neq_NONCE) |
320 |
323 |
321 theorem Crypt_Crypt_eq [iff]: |
324 theorem Crypt_Crypt_eq [iff]: |
322 shows "(Crypt K X = Crypt K X') = (X=X')" |
325 shows "(Crypt K X = Crypt K X') = (X=X')" |
323 proof |
326 proof |
324 assume "Crypt K X = Crypt K X'" |
327 assume "Crypt K X = Crypt K X'" |
343 lemma msg_induct_aux: |
346 lemma msg_induct_aux: |
344 shows "\<lbrakk>\<And>N. P (Nonce N); |
347 shows "\<lbrakk>\<And>N. P (Nonce N); |
345 \<And>X Y. \<lbrakk>P X; P Y\<rbrakk> \<Longrightarrow> P (MPair X Y); |
348 \<And>X Y. \<lbrakk>P X; P Y\<rbrakk> \<Longrightarrow> P (MPair X Y); |
346 \<And>K X. P X \<Longrightarrow> P (Crypt K X); |
349 \<And>K X. P X \<Longrightarrow> P (Crypt K X); |
347 \<And>K X. P X \<Longrightarrow> P (Decrypt K X)\<rbrakk> \<Longrightarrow> P msg" |
350 \<And>K X. P X \<Longrightarrow> P (Decrypt K X)\<rbrakk> \<Longrightarrow> P msg" |
348 by (lifting freemsg.induct) |
351 by (lifting freemsg.induct) |
349 |
352 |
350 lemma msg_induct [case_names Nonce MPair Crypt Decrypt, cases type: msg]: |
353 lemma msg_induct [case_names Nonce MPair Crypt Decrypt, cases type: msg]: |
351 assumes N: "\<And>N. P (Nonce N)" |
354 assumes N: "\<And>N. P (Nonce N)" |
352 and M: "\<And>X Y. \<lbrakk>P X; P Y\<rbrakk> \<Longrightarrow> P (MPair X Y)" |
355 and M: "\<And>X Y. \<lbrakk>P X; P Y\<rbrakk> \<Longrightarrow> P (MPair X Y)" |
353 and C: "\<And>K X. P X \<Longrightarrow> P (Crypt K X)" |
356 and C: "\<And>K X. P X \<Longrightarrow> P (Crypt K X)" |
354 and D: "\<And>K X. P X \<Longrightarrow> P (Decrypt K X)" |
357 and D: "\<And>K X. P X \<Longrightarrow> P (Decrypt K X)" |
355 shows "P msg" |
358 shows "P msg" |
356 using N M C D by (rule msg_induct_aux) |
359 using N M C D by (rule msg_induct_aux) |
357 |
360 |
358 subsection{*The Abstract Discriminator*} |
361 subsection{*The Abstract Discriminator*} |
359 |
362 |
360 text{*However, as @{text Crypt_Nonce_neq_Nonce} above illustrates, we don't |
363 text{*However, as @{text Crypt_Nonce_neq_Nonce} above illustrates, we don't |
361 need this function in order to prove discrimination theorems.*} |
364 need this function in order to prove discrimination theorems.*} |
367 |
370 |
368 text{*Now prove the four equations for @{term discrim}*} |
371 text{*Now prove the four equations for @{term discrim}*} |
369 |
372 |
370 lemma [quot_respect]: |
373 lemma [quot_respect]: |
371 shows "(op \<sim> ===> op =) freediscrim freediscrim" |
374 shows "(op \<sim> ===> op =) freediscrim freediscrim" |
372 by (auto simp add: msgrel_imp_eq_freediscrim) |
375 by (auto simp add: msgrel_imp_eq_freediscrim) |
373 |
376 |
374 lemma discrim_Nonce [simp]: |
377 lemma discrim_Nonce [simp]: |
375 shows "discrim (Nonce N) = 0" |
378 shows "discrim (Nonce N) = 0" |
376 by (lifting freediscrim.simps(1)) |
379 by (lifting freediscrim.simps(1)) |
377 |
380 |
378 lemma discrim_MPair [simp]: |
381 lemma discrim_MPair [simp]: |
379 shows "discrim (MPair X Y) = 1" |
382 shows "discrim (MPair X Y) = 1" |
380 by (lifting freediscrim.simps(2)) |
383 by (lifting freediscrim.simps(2)) |
381 |
384 |
382 lemma discrim_Crypt [simp]: |
385 lemma discrim_Crypt [simp]: |
383 shows "discrim (Crypt K X) = discrim X + 2" |
386 shows "discrim (Crypt K X) = discrim X + 2" |
384 by (lifting freediscrim.simps(3)) |
387 by (lifting freediscrim.simps(3)) |
385 |
388 |
386 lemma discrim_Decrypt [simp]: |
389 lemma discrim_Decrypt [simp]: |
387 shows "discrim (Decrypt K X) = discrim X - 2" |
390 shows "discrim (Decrypt K X) = discrim X - 2" |
388 by (lifting freediscrim.simps(4)) |
391 by (lifting freediscrim.simps(4)) |
389 |
392 |
390 end |
393 end |
391 |
394 |