text‹By freeness of agents, no two agents have the same key. Since term‹True≠False›, no agent has identical signing and encryption keys› specification (publicKey)
injective_publicKey: "publicKey b A = publicKey c A' ==> b=c ∧ A=A'" apply (rule exI [of _ "λb A. 2 * case_agent 0 (λn. n + 2) 1 A + case_keymode 0 1 b"]) apply (auto simp add: inj_on_def split: agent.split keymode.split) apply presburger apply presburger done
axiomatizationwhere (*No private key equals any public key (essential to ensure that private
keys are private!) *)
privateKey_neq_publicKey [iff]: "privateKey b A ≠ publicKey c A'"
lemma priEK_noteq_shrK [simp]: "priEK A ≠ shrK B" by auto
lemma publicKey_notin_image_shrK [simp]: "publicKey b x ∉ shrK ` AA" by auto
lemma privateKey_notin_image_shrK [simp]: "privateKey b x ∉ shrK ` AA" by auto
lemma shrK_notin_image_publicKey [simp]: "shrK x ∉ publicKey b ` AA" by auto
lemma shrK_notin_image_privateKey [simp]: "shrK x ∉ invKey ` publicKey b ` AA" by auto
lemma shrK_image_eq [simp]: "(shrK x ∈ shrK ` AA) = (x ∈ AA)" by auto
text‹For some reason, moving this up can make some proofs loop!› declare invKey_K [simp]
subsection‹Initial States of Agents›
text‹Note: for all practical purposes, all that matters is the initial
of the Spy. All other agents are automata, merely following the
.›
overloading
initState ≡ initState begin
primrec initState where (*Agents know their private key and all public keys*)
initState_Server: "initState Server = {Key (priEK Server), Key (priSK Server)} ∪ (Key ` range pubEK) ∪ (Key ` range pubSK) ∪ (Key ` range shrK)"
text‹These lemmas allow reasoning about term‹used evs› rather than term‹knows Spy evs›, which is useful when there are private Notes.
Because they depend upon the definition of term‹initState›, they cannot
be moved up.›
lemma MPair_used_D: "{X,Y}∈ used H ==> X ∈ used H ∧ Y ∈ used H" by (drule used_parts_subset_parts, simp, blast)
text‹There was a similar theorem in Event.thy, so perhaps this one can
be moved up if proved directly by induction.› lemma MPair_used [elim!]: "[{X,Y}∈ used H; [X ∈ used H; Y ∈ used H]==> P] ==> P" by (blast dest: MPair_used_D)
text‹Rewrites should not refer to term‹initState(Friend i)› because
that expression is not in normal form.›
lemma Crypt_notin_initState: "Crypt K X ∉ parts (initState B)" by (induct B, auto)
lemma Crypt_notin_used_empty [simp]: "Crypt K X ∉ used []" by (simp add: Crypt_notin_initState used_Nil)
(*** Basic properties of shrK ***)
(*Agents see their own shared keys!*) lemma shrK_in_initState [iff]: "Key (shrK A) ∈ initState A" by (induct_tac "A", auto)
lemma shrK_in_knows [iff]: "Key (shrK A) ∈ knows A evs" by (simp add: initState_subset_knows [THEN subsetD])
lemma shrK_in_used [iff]: "Key (shrK A) ∈ used evs" by (rule initState_into_used, blast)
(** Fresh keys never clash with long-term shared keys **)
(*Used in parts_induct_tac and analz_Fake_tac to distinguish session keys
from long-term shared keys*) lemma Key_not_used [simp]: "Key K ∉ used evs ==> K ∉ range shrK" by blast
lemma shrK_neq: "Key K ∉ used evs ==> shrK B ≠ K" by blast
text‹Spy sees private keys of bad agents!› lemma Spy_spies_bad_privateKey [intro!]: "A ∈ bad ==> Key (privateKey b A) ∈ spies evs" apply (induct_tac "evs") apply (auto simp add: imageI knows_Cons split: event.split) done
text‹Spy sees long-term shared keys of bad agents!› lemma Spy_spies_bad_shrK [intro!]: "A ∈ bad ==> Key (shrK A) ∈ spies evs" apply (induct_tac "evs") apply (simp_all add: imageI knows_Cons split: event.split) done
lemma publicKey_into_used [iff] :"Key (publicKey b A) ∈ used evs" apply (rule initState_into_used) apply (rule publicKey_in_initState [THEN parts.Inj]) done
lemma privateKey_into_used [iff]: "Key (privateKey b A) ∈ used evs" apply(rule initState_into_used) apply(rule priK_in_initState [THEN parts.Inj]) done
(*For case analysis on whether or not an agent is compromised*) lemma Crypt_Spy_analz_bad: "[Crypt (shrK A) X ∈ analz (knows Spy evs); A ∈ bad] ==> X ∈ analz (knows Spy evs)" by force
subsection‹Fresh Nonces›
lemma Nonce_notin_initState [iff]: "Nonce N ∉ parts (initState B)" by (induct_tac "B", auto)
lemma Nonce_notin_used_empty [simp]: "Nonce N ∉ used []" by (simp add: used_Nil)
subsection‹Supply fresh nonces for possibility theorems›
text‹In any trace, there is an upper bound N on the greatest nonce in use› lemma Nonce_supply_lemma: "∃N. ∀n. N≤n ⟶ Nonce n ∉ used evs" apply (induct_tac "evs") apply (rule_tac x = 0in exI) apply (simp_all (no_asm_simp) add: used_Cons split: event.split) apply safe apply (rule msg_Nonce_supply [THEN exE], blast elim!: add_leE)+ done
lemma Nonce_supply1: "∃N. Nonce N ∉ used evs" by (rule Nonce_supply_lemma [THEN exE], blast)
lemma Nonce_supply: "Nonce (SOME N. Nonce N ∉ used evs) ∉ used evs" apply (rule Nonce_supply_lemma [THEN exE]) apply (rule someI, fast) done
subsection‹Specialized Rewriting for Theorems About term‹analz› and Image›
lemma insert_Key_singleton: "insert (Key K) H = Key ` {K} ∪ H" by blast
lemma insert_Key_image: "insert (Key K) (Key`KK ∪ C) = Key ` (insert K KK) ∪ C" by blast
lemma Crypt_imp_keysFor :"[Crypt K X ∈ H; K ∈ symKeys]==> K ∈ keysFor H" by (drule Crypt_imp_invKey_keysFor, simp)
text‹Lemma for the trivial direction of the if-and-only-if of the
Key Compromise Theorem› lemma analz_image_freshK_lemma: "(Key K ∈ analz (Key`nE ∪ H)) ⟶ (K ∈ nE | Key K ∈ analz H) ==> (Key K ∈ analz (Key`nE ∪ H)) = (K ∈ nE | Key K ∈ analz H)" by (blast intro: analz_mono [THEN [2] rev_subsetD])
lemmas analz_image_freshK_simps =
simp_thms mem_simps ― ‹these two allow its use with ‹only:››
disj_comms
image_insert [THEN sym] image_Un [THEN sym] empty_subsetI insert_subset
analz_insert_eq Un_upper2 [THEN analz_mono, THEN subsetD]
insert_Key_singleton
Key_not_used insert_Key_image Un_assoc [THEN sym]
(*Tactic for possibility theorems*) fun possibility_tac ctxt =
REPEAT (*omit used_Says so that Nonces start from different traces!*)
(ALLGOALS (simp_tac (ctxt |> Simplifier.set_unsafe_solver safe_solver |> Simplifier.del_simp @{thm used_Says})) THEN
REPEAT_FIRST (eq_assume_tac ORELSE'
resolve_tac ctxt [refl, conjI, @{thm Nonce_supply}]))
(*For harder protocols (such as Recur) where we have to set up some
nonces and keys initially*) fun basic_possibility_tac ctxt =
REPEAT
(ALLGOALS (asm_simp_tac (ctxt |> Simplifier.set_unsafe_solver safe_solver)) THEN
REPEAT_FIRST (resolve_tac ctxt [refl, conjI]))
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.