--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc-src/TutorialI/Protocol/Message.thy Wed Apr 11 11:53:54 2001 +0200
@@ -0,0 +1,147 @@
+(* Title: HOL/Auth/Message
+ ID: $Id$
+ Author: Lawrence C Paulson, Cambridge University Computer Laboratory
+ Copyright 1996 University of Cambridge
+
+Datatypes of agents and messages;
+Inductive relations "parts", "analz" and "synth"
+*)
+
+theory Message = Main
+files ("Message_lemmas.ML"):
+
+(*Needed occasionally with spy_analz_tac, e.g. in analz_insert_Key_newK*)
+lemma [simp] : "A Un (B Un A) = B Un A"
+by blast
+
+types
+ key = nat
+
+consts
+ invKey :: "key=>key"
+
+axioms
+ invKey [simp] : "invKey (invKey K) = K"
+
+ (*The inverse of a symmetric key is itself;
+ that of a public key is the private key and vice versa*)
+
+constdefs
+ symKeys :: "key set"
+ "symKeys == {K. invKey K = K}"
+
+datatype (*We allow any number of friendly agents*)
+ agent = Server | Friend nat | Spy
+
+datatype
+ msg = Agent agent (*Agent names*)
+ | Number nat (*Ordinary integers, timestamps, ...*)
+ | Nonce nat (*Unguessable nonces*)
+ | Key key (*Crypto keys*)
+ | Hash msg (*Hashing*)
+ | MPair msg msg (*Compound messages*)
+ | Crypt key msg (*Encryption, public- or shared-key*)
+
+
+(*Concrete syntax: messages appear as {|A,B,NA|}, etc...*)
+syntax
+ "@MTuple" :: "['a, args] => 'a * 'b" ("(2{|_,/ _|})")
+
+syntax (xsymbols)
+ "@MTuple" :: "['a, args] => 'a * 'b" ("(2\<lbrace>_,/ _\<rbrace>)")
+
+translations
+ "{|x, y, z|}" == "{|x, {|y, z|}|}"
+ "{|x, y|}" == "MPair x y"
+
+
+constdefs
+ (*Message Y, paired with a MAC computed with the help of X*)
+ HPair :: "[msg,msg] => msg" ("(4Hash[_] /_)" [0, 1000])
+ "Hash[X] Y == {| Hash{|X,Y|}, Y|}"
+
+ (*Keys useful to decrypt elements of a message set*)
+ keysFor :: "msg set => key set"
+ "keysFor H == invKey ` {K. \<exists>X. Crypt K X \<in> H}"
+
+(** Inductive definition of all "parts" of a message. **)
+
+consts parts :: "msg set => msg set"
+inductive "parts H"
+ intros
+ Inj [intro]: "X \<in> H ==> X \<in> parts H"
+ Fst: "{|X,Y|} \<in> parts H ==> X \<in> parts H"
+ Snd: "{|X,Y|} \<in> parts H ==> Y \<in> parts H"
+ Body: "Crypt K X \<in> parts H ==> X \<in> parts H"
+
+
+(*Monotonicity*)
+lemma parts_mono: "G<=H ==> parts(G) <= parts(H)"
+apply auto
+apply (erule parts.induct)
+apply (auto dest: Fst Snd Body)
+done
+
+
+(** Inductive definition of "analz" -- what can be broken down from a set of
+ messages, including keys. A form of downward closure. Pairs can
+ be taken apart; messages decrypted with known keys. **)
+
+consts analz :: "msg set => msg set"
+inductive "analz H"
+ intros
+ Inj [intro,simp] : "X \<in> H ==> X \<in> analz H"
+ Fst: "{|X,Y|} \<in> analz H ==> X \<in> analz H"
+ Snd: "{|X,Y|} \<in> analz H ==> Y \<in> analz H"
+ Decrypt [dest]:
+ "[|Crypt K X \<in> analz H; Key(invKey K): analz H|] ==> X \<in> analz H"
+
+
+(*Monotonicity; Lemma 1 of Lowe's paper*)
+lemma analz_mono: "G<=H ==> analz(G) <= analz(H)"
+apply auto
+apply (erule analz.induct)
+apply (auto dest: Fst Snd)
+done
+
+(** Inductive definition of "synth" -- what can be built up from a set of
+ messages. A form of upward closure. Pairs can be built, messages
+ encrypted with known keys. Agent names are public domain.
+ Numbers can be guessed, but Nonces cannot be. **)
+
+consts synth :: "msg set => msg set"
+inductive "synth H"
+ intros
+ Inj [intro]: "X \<in> H ==> X \<in> synth H"
+ Agent [intro]: "Agent agt \<in> synth H"
+ Number [intro]: "Number n \<in> synth H"
+ Hash [intro]: "X \<in> synth H ==> Hash X \<in> synth H"
+ MPair [intro]: "[|X \<in> synth H; Y \<in> synth H|] ==> {|X,Y|} \<in> synth H"
+ Crypt [intro]: "[|X \<in> synth H; Key(K) \<in> H|] ==> Crypt K X \<in> synth H"
+
+(*Monotonicity*)
+lemma synth_mono: "G<=H ==> synth(G) <= synth(H)"
+apply auto
+apply (erule synth.induct)
+apply (auto dest: Fst Snd Body)
+done
+
+(*NO Agent_synth, as any Agent name can be synthesized. Ditto for Number*)
+inductive_cases Nonce_synth [elim!]: "Nonce n \<in> synth H"
+inductive_cases Key_synth [elim!]: "Key K \<in> synth H"
+inductive_cases Hash_synth [elim!]: "Hash X \<in> synth H"
+inductive_cases MPair_synth [elim!]: "{|X,Y|} \<in> synth H"
+inductive_cases Crypt_synth [elim!]: "Crypt K X \<in> synth H"
+
+use "Message_lemmas.ML"
+
+lemma Fake_parts_insert_in_Un:
+ "[|Z \<in> parts (insert X H); X: synth (analz H)|]
+ ==> Z \<in> synth (analz H) \<union> parts H";
+by (blast dest: Fake_parts_insert [THEN subsetD, dest])
+
+method_setup spy_analz = {*
+ Method.no_args (Method.METHOD (fn facts => spy_analz_tac 1)) *}
+ "for proving the Fake case when analz is involved"
+
+end