Theory Proto
section‹Other Protocol-Independent Results›
theory Proto imports Guard_Public begin
subsection‹protocols›
type_synonym rule = "event set * event"
abbreviation
msg' :: "rule => msg" where
"msg' R == msg (snd R)"
type_synonym proto = "rule set"
definition wdef :: "proto => bool" where
"wdef p ≡ ∀R k. R ∈ p ⟶ Number k ∈ parts {msg' R}
⟶ Number k ∈ parts (msg`(fst R))"
subsection‹substitutions›
record subs =
agent :: "agent => agent"
nonce :: "nat => nat"
nb :: "nat => msg"
key :: "key => key"
primrec apm :: "subs => msg => msg" where
"apm s (Agent A) = Agent (agent s A)"
| "apm s (Nonce n) = Nonce (nonce s n)"
| "apm s (Number n) = nb s n"
| "apm s (Key K) = Key (key s K)"
| "apm s (Hash X) = Hash (apm s X)"
| "apm s (Crypt K X) = (
if (∃A. K = pubK A) then Crypt (pubK (agent s (agt K))) (apm s X)
else if (∃A. K = priK A) then Crypt (priK (agent s (agt K))) (apm s X)
else Crypt (key s K) (apm s X))"
| "apm s ⦃X,Y⦄ = ⦃apm s X, apm s Y⦄"
lemma apm_parts: "X ∈ parts {Y} ⟹ apm s X ∈ parts {apm s Y}"
apply (erule parts.induct, simp_all, blast)
apply (erule parts.Fst)
apply (erule parts.Snd)
by (erule parts.Body)+
lemma Nonce_apm [rule_format]: "Nonce n ∈ parts {apm s X} ⟹
(∀k. Number k ∈ parts {X} ⟶ Nonce n ∉ parts {nb s k}) ⟶
(∃k. Nonce k ∈ parts {X} ∧ nonce s k = n)"
by (induct X, simp_all, blast)
lemma wdef_Nonce: "⟦Nonce n ∈ parts {apm s X}; R ∈ p; msg' R = X; wdef p;
Nonce n ∉ parts (apm s `(msg `(fst R)))⟧ ⟹
(∃k. Nonce k ∈ parts {X} ∧ nonce s k = n)"
apply (erule Nonce_apm, unfold wdef_def)
apply (drule_tac x=R in spec, drule_tac x=k in spec, clarsimp)
apply (drule_tac x=x in bspec, simp)
apply (drule_tac Y="msg x" and s=s in apm_parts, simp)
by (blast dest: parts_parts)
primrec ap :: "subs ⇒ event ⇒ event" where
"ap s (Says A B X) = Says (agent s A) (agent s B) (apm s X)"
| "ap s (Gets A X) = Gets (agent s A) (apm s X)"
| "ap s (Notes A X) = Notes (agent s A) (apm s X)"
abbreviation
ap' :: "subs ⇒ rule ⇒ event" where
"ap' s R ≡ ap s (snd R)"
abbreviation
apm' :: "subs ⇒ rule ⇒ msg" where
"apm' s R ≡ apm s (msg' R)"
abbreviation
priK' :: "subs ⇒ agent ⇒ key" where
"priK' s A ≡ priK (agent s A)"
abbreviation
pubK' :: "subs ⇒ agent ⇒ key" where
"pubK' s A ≡ pubK (agent s A)"
subsection‹nonces generated by a rule›
definition newn :: "rule ⇒ nat set" where
"newn R ≡ {n. Nonce n ∈ parts {msg (snd R)} ∧ Nonce n ∉ parts (msg`(fst R))}"
lemma newn_parts: "n ∈ newn R ⟹ Nonce (nonce s n) ∈ parts {apm' s R}"
by (auto simp: newn_def dest: apm_parts)
subsection‹traces generated by a protocol›
definition ok :: "event list ⇒ rule ⇒ subs ⇒ bool" where
"ok evs R s ≡ ((∀x. x ∈ fst R ⟶ ap s x ∈ set evs)
∧ (∀n. n ∈ newn R ⟶ Nonce (nonce s n) ∉ used evs))"
inductive_set
tr :: "proto => event list set"
for p :: proto
where
Nil [intro]: "[] ∈ tr p"
| Fake [intro]: "⟦evsf ∈ tr p; X ∈ synth (analz (spies evsf))⟧
⟹ Says Spy B X # evsf ∈ tr p"
| Proto [intro]: "⟦evs ∈ tr p; R ∈ p; ok evs R s⟧ ⟹ ap' s R # evs ∈ tr p"
subsection‹general properties›
lemma one_step_tr [iff]: "one_step (tr p)"
apply (unfold one_step_def, clarify)
by (ind_cases "ev # evs ∈ tr p" for ev evs, auto)
definition has_only_Says' :: "proto => bool" where
"has_only_Says' p ≡ ∀R. R ∈ p ⟶ is_Says (snd R)"
lemma has_only_Says'D: "⟦R ∈ p; has_only_Says' p⟧
⟹ (∃A B X. snd R = Says A B X)"
by (unfold has_only_Says'_def is_Says_def, blast)
lemma has_only_Says_tr [simp]: "has_only_Says' p ⟹ has_only_Says (tr p)"
unfolding has_only_Says_def
apply (rule allI, rule allI, rule impI)
apply (erule tr.induct)
apply (auto simp: has_only_Says'_def ok_def)
by (drule_tac x=a in spec, auto simp: is_Says_def)
lemma has_only_Says'_in_trD: "⟦has_only_Says' p; list @ ev # evs1 ∈ tr p⟧
⟹ (∃A B X. ev = Says A B X)"
by (drule has_only_Says_tr, auto)
lemma ok_not_used: "⟦Nonce n ∉ used evs; ok evs R s;
∀x. x ∈ fst R ⟶ is_Says x⟧ ⟹ Nonce n ∉ parts (apm s `(msg `(fst R)))"
apply (unfold ok_def, clarsimp)
apply (drule_tac x=x in spec, drule_tac x=x in spec)
by (auto simp: is_Says_def dest: Says_imp_spies not_used_not_spied parts_parts)
lemma ok_is_Says: "⟦evs' @ ev # evs ∈ tr p; ok evs R s; has_only_Says' p;
R ∈ p; x ∈ fst R⟧ ⟹ is_Says x"
apply (unfold ok_def is_Says_def, clarify)
apply (drule_tac x=x in spec, simp)
apply (subgoal_tac "one_step (tr p)")
apply (drule trunc, simp, drule one_step_Cons, simp)
apply (drule has_only_SaysD, simp+)
by (clarify, case_tac x, auto)
subsection‹types›
type_synonym keyfun = "rule ⇒ subs ⇒ nat ⇒ event list ⇒ key set"
type_synonym secfun = "rule ⇒ nat ⇒ subs ⇒ key set ⇒ msg"
subsection‹introduction of a fresh guarded nonce›
definition fresh :: "proto ⇒ rule ⇒ subs ⇒ nat ⇒ key set ⇒ event list
⇒ bool" where
"fresh p R s n Ks evs ≡ (∃evs1 evs2. evs = evs2 @ ap' s R # evs1
∧ Nonce n ∉ used evs1 ∧ R ∈ p ∧ ok evs1 R s ∧ Nonce n ∈ parts {apm' s R}
∧ apm' s R ∈ guard n Ks)"
lemma freshD: "fresh p R s n Ks evs ⟹ (∃evs1 evs2.
evs = evs2 @ ap' s R # evs1 ∧ Nonce n ∉ used evs1 ∧ R ∈ p ∧ ok evs1 R s
∧ Nonce n ∈ parts {apm' s R} ∧ apm' s R ∈ guard n Ks)"
unfolding fresh_def by blast
lemma freshI [intro]: "⟦Nonce n ∉ used evs1; R ∈ p; Nonce n ∈ parts {apm' s R};
ok evs1 R s; apm' s R ∈ guard n Ks⟧
⟹ fresh p R s n Ks (list @ ap' s R # evs1)"
unfolding fresh_def by blast
lemma freshI': "⟦Nonce n ∉ used evs1; (l,r) ∈ p;
Nonce n ∈ parts {apm s (msg r)}; ok evs1 (l,r) s; apm s (msg r) ∈ guard n Ks⟧
⟹ fresh p (l,r) s n Ks (evs2 @ ap s r # evs1)"
by (drule freshI, simp+)
lemma fresh_used: "⟦fresh p R' s' n Ks evs; has_only_Says' p⟧
⟹ Nonce n ∈ used evs"
apply (unfold fresh_def, clarify)
apply (drule has_only_Says'D)
by (auto intro: parts_used_app)
lemma fresh_newn: "⟦evs' @ ap' s R # evs ∈ tr p; wdef p; has_only_Says' p;
Nonce n ∉ used evs; R ∈ p; ok evs R s; Nonce n ∈ parts {apm' s R}⟧
⟹ ∃k. k ∈ newn R ∧ nonce s k = n"
apply (drule wdef_Nonce, simp+)
apply (frule ok_not_used, simp+)
apply (clarify, erule ok_is_Says, simp+)
apply (clarify, rule_tac x=k in exI, simp add: newn_def)
apply (clarify, drule_tac Y="msg x" and s=s in apm_parts)
apply (drule ok_not_used, simp+)
by (clarify, erule ok_is_Says, simp_all)
lemma fresh_rule: "⟦evs' @ ev # evs ∈ tr p; wdef p; Nonce n ∉ used evs;
Nonce n ∈ parts {msg ev}⟧ ⟹ ∃R s. R ∈ p ∧ ap' s R = ev"
apply (drule trunc, simp, ind_cases "ev # evs ∈ tr p", simp)
by (drule_tac x=X in in_sub, drule parts_sub, simp, simp, blast+)
lemma fresh_ruleD: "⟦fresh p R' s' n Ks evs; keys R' s' n evs ⊆ Ks; wdef p;
has_only_Says' p; evs ∈ tr p; ∀R k s. nonce s k = n ⟶ Nonce n ∈ used evs ⟶
R ∈ p ⟶ k ∈ newn R ⟶ Nonce n ∈ parts {apm' s R} ⟶ apm' s R ∈ guard n Ks ⟶
apm' s R ∈ parts (spies evs) ⟶ keys R s n evs ⊆ Ks ⟶ P⟧ ⟹ P"
apply (frule fresh_used, simp)
apply (unfold fresh_def, clarify)
apply (drule_tac x=R' in spec)
apply (drule fresh_newn, simp+, clarify)
apply (drule_tac x=k in spec)
apply (drule_tac x=s' in spec)
apply (subgoal_tac "apm' s' R' ∈ parts (spies (evs2 @ ap' s' R' # evs1))")
apply (case_tac R', drule has_only_Says'D, simp, clarsimp)
apply (case_tac R', drule has_only_Says'D, simp, clarsimp)
apply (rule_tac Y="apm s' X" in parts_parts, blast)
by (rule parts.Inj, rule Says_imp_spies, simp, blast)
subsection‹safe keys›
definition safe :: "key set ⇒ msg set ⇒ bool" where
"safe Ks G ≡ ∀K. K ∈ Ks ⟶ Key K ∉ analz G"
lemma safeD [dest]: "⟦safe Ks G; K ∈ Ks⟧ ⟹ Key K ∉ analz G"
unfolding safe_def by blast
lemma safe_insert: "safe Ks (insert X G) ⟹ safe Ks G"
unfolding safe_def by blast
lemma Guard_safe: "⟦Guard n Ks G; safe Ks G⟧ ⟹ Nonce n ∉ analz G"
by (blast dest: Guard_invKey)
subsection‹guardedness preservation›
definition preserv :: "proto ⇒ keyfun ⇒ nat ⇒ key set ⇒ bool" where
"preserv p keys n Ks ≡ (∀evs R' s' R s. evs ∈ tr p ⟶
Guard n Ks (spies evs) ⟶ safe Ks (spies evs) ⟶ fresh p R' s' n Ks evs ⟶
keys R' s' n evs ⊆ Ks ⟶ R ∈ p ⟶ ok evs R s ⟶ apm' s R ∈ guard n Ks)"
lemma preservD: "⟦preserv p keys n Ks; evs ∈ tr p; Guard n Ks (spies evs);
safe Ks (spies evs); fresh p R' s' n Ks evs; R ∈ p; ok evs R s;
keys R' s' n evs ⊆ Ks⟧ ⟹ apm' s R ∈ guard n Ks"
unfolding preserv_def by blast
lemma preservD': "⟦preserv p keys n Ks; evs ∈ tr p; Guard n Ks (spies evs);
safe Ks (spies evs); fresh p R' s' n Ks evs; (l,Says A B X) ∈ p;
ok evs (l,Says A B X) s; keys R' s' n evs ⊆ Ks⟧ ⟹ apm s X ∈ guard n Ks"
by (drule preservD, simp+)
subsection‹monotonic keyfun›
definition monoton :: "proto => keyfun => bool" where
"monoton p keys ≡ ∀R' s' n ev evs. ev # evs ∈ tr p ⟶
keys R' s' n evs ⊆ keys R' s' n (ev # evs)"
lemma monotonD [dest]: "⟦keys R' s' n (ev # evs) ⊆ Ks; monoton p keys;
ev # evs ∈ tr p⟧ ⟹ keys R' s' n evs ⊆ Ks"
unfolding monoton_def by blast
subsection‹guardedness theorem›
lemma Guard_tr [rule_format]: "⟦evs ∈ tr p; has_only_Says' p;
preserv p keys n Ks; monoton p keys; Guard n Ks (initState Spy)⟧ ⟹
safe Ks (spies evs) ⟶ fresh p R' s' n Ks evs ⟶ keys R' s' n evs ⊆ Ks ⟶
Guard n Ks (spies evs)"
apply (erule tr.induct)
apply simp
apply (clarify, drule freshD, clarsimp)
apply (case_tac evs2)
apply (frule has_only_Says'D, simp)
apply (clarsimp, blast)
apply (clarsimp, rule conjI)
apply (blast dest: safe_insert)
apply (rule in_synth_Guard, simp, rule Guard_analz)
apply (blast dest: safe_insert)
apply (drule safe_insert, simp add: safe_def)
apply (clarify, drule freshD, clarify)
apply (case_tac evs2)
apply (frule has_only_Says'D, simp)
apply (frule_tac R=R' in has_only_Says'D, simp)
apply (case_tac R', clarsimp, blast)
apply (frule has_only_Says'D, simp)
apply (clarsimp, rule conjI)
apply (drule Proto, simp+, blast dest: safe_insert)
apply (frule Proto, simp+)
apply (erule preservD', simp+)
apply (blast dest: safe_insert)
apply (blast dest: safe_insert)
by (blast, simp, simp, blast)
subsection‹useful properties for guardedness›
lemma newn_neq_used: "⟦Nonce n ∈ used evs; ok evs R s; k ∈ newn R⟧
⟹ n ≠ nonce s k"
by (auto simp: ok_def)
lemma ok_Guard: "⟦ok evs R s; Guard n Ks (spies evs); x ∈ fst R; is_Says x⟧
⟹ apm s (msg x) ∈ parts (spies evs) ∧ apm s (msg x) ∈ guard n Ks"
apply (unfold ok_def is_Says_def, clarify)
apply (drule_tac x="Says A B X" in spec, simp)
by (drule Says_imp_spies, auto intro: parts_parts)
lemma ok_parts_not_new: "⟦Y ∈ parts (spies evs); Nonce (nonce s n) ∈ parts {Y};
ok evs R s⟧ ⟹ n ∉ newn R"
by (auto simp: ok_def dest: not_used_not_spied parts_parts)
subsection‹unicity›
definition uniq :: "proto ⇒ secfun ⇒ bool" where
"uniq p secret ≡ ∀evs R R' n n' Ks s s'. R ∈ p ⟶ R' ∈ p ⟶
n ∈ newn R ⟶ n' ∈ newn R' ⟶ nonce s n = nonce s' n' ⟶
Nonce (nonce s n) ∈ parts {apm' s R} ⟶ Nonce (nonce s n) ∈ parts {apm' s' R'} ⟶
apm' s R ∈ guard (nonce s n) Ks ⟶ apm' s' R' ∈ guard (nonce s n) Ks ⟶
evs ∈ tr p ⟶ Nonce (nonce s n) ∉ analz (spies evs) ⟶
secret R n s Ks ∈ parts (spies evs) ⟶ secret R' n' s' Ks ∈ parts (spies evs) ⟶
secret R n s Ks = secret R' n' s' Ks"
lemma uniqD: "⟦uniq p secret; evs ∈ tr p; R ∈ p; R' ∈ p; n ∈ newn R; n' ∈ newn R';
nonce s n = nonce s' n'; Nonce (nonce s n) ∉ analz (spies evs);
Nonce (nonce s n) ∈ parts {apm' s R}; Nonce (nonce s n) ∈ parts {apm' s' R'};
secret R n s Ks ∈ parts (spies evs); secret R' n' s' Ks ∈ parts (spies evs);
apm' s R ∈ guard (nonce s n) Ks; apm' s' R' ∈ guard (nonce s n) Ks⟧ ⟹
secret R n s Ks = secret R' n' s' Ks"
unfolding uniq_def by blast
definition ord :: "proto ⇒ (rule ⇒ rule ⇒ bool) ⇒ bool" where
"ord p inff ≡ ∀R R'. R ∈ p ⟶ R' ∈ p ⟶ ¬ inff R R' ⟶ inff R' R"
lemma ordD: "⟦ord p inff; ¬ inff R R'; R ∈ p; R' ∈ p⟧ ⟹ inff R' R"
unfolding ord_def by blast
definition uniq' :: "proto ⇒ (rule ⇒ rule ⇒ bool) ⇒ secfun ⇒ bool" where
"uniq' p inff secret ≡ ∀evs R R' n n' Ks s s'. R ∈ p ⟶ R' ∈ p ⟶
inff R R' ⟶ n ∈ newn R ⟶ n' ∈ newn R' ⟶ nonce s n = nonce s' n' ⟶
Nonce (nonce s n) ∈ parts {apm' s R} ⟶ Nonce (nonce s n) ∈ parts {apm' s' R'} ⟶
apm' s R ∈ guard (nonce s n) Ks ⟶ apm' s' R' ∈ guard (nonce s n) Ks ⟶
evs ∈ tr p ⟶ Nonce (nonce s n) ∉ analz (spies evs) ⟶
secret R n s Ks ∈ parts (spies evs) ⟶ secret R' n' s' Ks ∈ parts (spies evs) ⟶
secret R n s Ks = secret R' n' s' Ks"
lemma uniq'D: "⟦uniq' p inff secret; evs ∈ tr p; inff R R'; R ∈ p; R' ∈ p; n ∈ newn R;
n' ∈ newn R'; nonce s n = nonce s' n'; Nonce (nonce s n) ∉ analz (spies evs);
Nonce (nonce s n) ∈ parts {apm' s R}; Nonce (nonce s n) ∈ parts {apm' s' R'};
secret R n s Ks ∈ parts (spies evs); secret R' n' s' Ks ∈ parts (spies evs);
apm' s R ∈ guard (nonce s n) Ks; apm' s' R' ∈ guard (nonce s n) Ks⟧ ⟹
secret R n s Ks = secret R' n' s' Ks"
by (unfold uniq'_def, blast)
lemma uniq'_imp_uniq: "⟦uniq' p inff secret; ord p inff⟧ ⟹ uniq p secret"
unfolding uniq_def
apply (rule allI)+
apply (case_tac "inff R R'")
apply (blast dest: uniq'D)
by (auto dest: ordD uniq'D intro: sym)
subsection‹Needham-Schroeder-Lowe›
definition a :: agent where "a == Friend 0"
definition b :: agent where "b == Friend 1"
definition a' :: agent where "a' == Friend 2"
definition b' :: agent where "b' == Friend 3"
definition Na :: nat where "Na == 0"
definition Nb :: nat where "Nb == 1"
abbreviation
ns1 :: rule where
"ns1 == ({}, Says a b (Crypt (pubK b) ⦃Nonce Na, Agent a⦄))"
abbreviation
ns2 :: rule where
"ns2 == ({Says a' b (Crypt (pubK b) ⦃Nonce Na, Agent a⦄)},
Says b a (Crypt (pubK a) ⦃Nonce Na, Nonce Nb, Agent b⦄))"
abbreviation
ns3 :: rule where
"ns3 == ({Says a b (Crypt (pubK b) ⦃Nonce Na, Agent a⦄),
Says b' a (Crypt (pubK a) ⦃Nonce Na, Nonce Nb, Agent b⦄)},
Says a b (Crypt (pubK b) (Nonce Nb)))"
inductive_set ns :: proto where
[iff]: "ns1 ∈ ns"
| [iff]: "ns2 ∈ ns"
| [iff]: "ns3 ∈ ns"
abbreviation (input)
ns3a :: event where
"ns3a == Says a b (Crypt (pubK b) ⦃Nonce Na, Agent a⦄)"
abbreviation (input)
ns3b :: event where
"ns3b == Says b' a (Crypt (pubK a) ⦃Nonce Na, Nonce Nb, Agent b⦄)"
definition keys :: "keyfun" where
"keys R' s' n evs == {priK' s' a, priK' s' b}"
lemma "monoton ns keys"
by (simp add: keys_def monoton_def)
definition secret :: "secfun" where
"secret R n s Ks ==
(if R=ns1 then apm s (Crypt (pubK b) ⦃Nonce Na, Agent a⦄)
else if R=ns2 then apm s (Crypt (pubK a) ⦃Nonce Na, Nonce Nb, Agent b⦄)
else Number 0)"
definition inf :: "rule => rule => bool" where
"inf R R' == (R=ns1 | (R=ns2 & R'~=ns1) | (R=ns3 & R'=ns3))"
lemma inf_is_ord [iff]: "ord ns inf"
apply (unfold ord_def inf_def)
apply (rule allI)+
apply (rule impI)
apply (simp add: split_paired_all)
by (rule impI, erule ns.cases, simp_all)+
subsection‹general properties›
lemma ns_has_only_Says' [iff]: "has_only_Says' ns"
apply (unfold has_only_Says'_def)
apply (rule allI, rule impI)
apply (simp add: split_paired_all)
by (erule ns.cases, auto)
lemma newn_ns1 [iff]: "newn ns1 = {Na}"
by (simp add: newn_def)
lemma newn_ns2 [iff]: "newn ns2 = {Nb}"
by (auto simp: newn_def Na_def Nb_def)
lemma newn_ns3 [iff]: "newn ns3 = {}"
by (auto simp: newn_def)
lemma ns_wdef [iff]: "wdef ns"
by (auto simp: wdef_def elim: ns.cases)
subsection‹guardedness for NSL›
lemma "uniq ns secret ⟹ preserv ns keys n Ks"
unfolding preserv_def
apply (rule allI)+
apply (rule impI, rule impI, rule impI, rule impI, rule impI)
apply (erule fresh_ruleD, simp, simp, simp, simp)
apply (rule allI)+
apply (rule impI, rule impI, rule impI)
apply (simp add: split_paired_all)
apply (erule ns.cases)
apply (rule impI, rule impI, rule impI, rule impI, rule impI, rule impI)
apply (erule ns.cases)
apply clarsimp
apply (frule newn_neq_used, simp, simp)
apply (rule No_Nonce, simp)
apply clarsimp
apply (frule newn_neq_used, simp, simp)
apply (case_tac "nonce sa Na = nonce s Na")
apply (frule Guard_safe, simp)
apply (frule Crypt_guard_invKey, simp)
apply (frule ok_Guard, simp, simp, simp, clarsimp)
apply (frule_tac K="pubK' s b" in Crypt_guard_invKey, simp)
apply (frule_tac R=ns1 and R'=ns1 and Ks=Ks and s=sa and s'=s in uniqD, simp+)
apply (simp add: secret_def, simp add: secret_def, force, force)
apply (simp add: secret_def keys_def, blast)
apply (rule No_Nonce, simp)
apply clarsimp
apply (case_tac "nonce sa Na = nonce s Nb")
apply (frule Guard_safe, simp)
apply (frule Crypt_guard_invKey, simp)
apply (frule_tac x=ns3b in ok_Guard, simp, simp, simp, clarsimp)
apply (frule_tac K="pubK' s a" in Crypt_guard_invKey, simp)
apply (frule_tac R=ns1 and R'=ns2 and Ks=Ks and s=sa and s'=s in uniqD, simp+)
apply (simp add: secret_def, simp add: secret_def, force, force)
apply (simp add: secret_def, rule No_Nonce, simp)
apply (rule impI, rule impI, rule impI, rule impI, rule impI, rule impI)
apply (erule ns.cases)
apply clarsimp
apply (frule newn_neq_used, simp, simp)
apply (rule No_Nonce, simp)
apply clarsimp
apply (frule newn_neq_used, simp, simp)
apply (case_tac "nonce sa Nb = nonce s Na")
apply (frule Guard_safe, simp)
apply (frule Crypt_guard_invKey, simp)
apply (frule ok_Guard, simp, simp, simp, clarsimp)
apply (frule_tac K="pubK' s b" in Crypt_guard_invKey, simp)
apply (frule_tac R=ns2 and R'=ns1 and Ks=Ks and s=sa and s'=s in uniqD, simp+)
apply (simp add: secret_def, simp add: secret_def, force, force)
apply (simp add: secret_def, rule No_Nonce, simp)
apply clarsimp
apply (case_tac "nonce sa Nb = nonce s Nb")
apply (frule Guard_safe, simp)
apply (frule Crypt_guard_invKey, simp)
apply (frule_tac x=ns3b in ok_Guard, simp, simp, simp, clarsimp)
apply (frule_tac K="pubK' s a" in Crypt_guard_invKey, simp)
apply (frule_tac R=ns2 and R'=ns2 and Ks=Ks and s=sa and s'=s in uniqD, simp+)
apply (simp add: secret_def, simp add: secret_def, force, force)
apply (simp add: secret_def keys_def, blast)
apply (rule No_Nonce, simp)
by simp
subsection‹unicity for NSL›
lemma "uniq' ns inf secret"
apply (unfold uniq'_def)
apply (rule allI)+
apply (simp add: split_paired_all)
apply (rule impI, erule ns.cases)
apply (rule impI, erule ns.cases)
apply (rule impI, rule impI, rule impI, rule impI)
apply (rule impI, rule impI, rule impI, rule impI)
apply (rule impI, erule tr.induct)
apply (simp add: secret_def)
apply (clarify, simp add: secret_def)
apply (drule notin_analz_insert)
apply (drule Crypt_insert_synth, simp, simp, simp)
apply (drule Crypt_insert_synth, simp, simp, simp, simp)
apply (erule_tac P="ok evsa R sa" in rev_mp)
apply (simp add: split_paired_all)
apply (erule ns.cases)
apply (clarify, simp add: secret_def)
apply (erule disjE, erule disjE, clarsimp)
apply (drule ok_parts_not_new, simp, simp, simp)
apply (clarify, drule ok_parts_not_new, simp, simp, simp)
apply (simp add: secret_def)
apply (simp add: secret_def)
apply (rule impI, rule impI, rule impI, rule impI)
apply (rule impI, rule impI, rule impI, rule impI)
apply (rule impI, erule tr.induct)
apply (simp add: secret_def)
apply (clarify, simp add: secret_def)
apply (drule notin_analz_insert)
apply (drule Crypt_insert_synth, simp, simp, simp)
apply (drule_tac n="nonce s' Nb" in Crypt_insert_synth, simp, simp, simp, simp)
apply (erule_tac P="ok evsa R sa" in rev_mp)
apply (simp add: split_paired_all)
apply (erule ns.cases)
apply (clarify, simp add: secret_def)
apply (drule_tac s=sa and n=Na in ok_parts_not_new, simp, simp, simp)
apply (clarify, simp add: secret_def)
apply (drule_tac s=sa and n=Nb in ok_parts_not_new, simp, simp, simp)
apply (simp add: secret_def)
apply simp
apply (rule impI, erule ns.cases)
apply (simp only: inf_def, blast)
apply (rule impI, rule impI, rule impI, rule impI)
apply (rule impI, rule impI, rule impI, rule impI)
apply (rule impI, erule tr.induct)
apply (simp add: secret_def)
apply (clarify, simp add: secret_def)
apply (drule notin_analz_insert)
apply (drule_tac n="nonce s' Nb" in Crypt_insert_synth, simp, simp, simp)
apply (drule_tac n="nonce s' Nb" in Crypt_insert_synth, simp, simp, simp, simp)
apply (erule_tac P="ok evsa R sa" in rev_mp)
apply (simp add: split_paired_all)
apply (erule ns.cases)
apply (simp add: secret_def)
apply (clarify, simp add: secret_def)
apply (erule disjE, erule disjE, clarsimp, clarsimp)
apply (drule_tac s=sa and n=Nb in ok_parts_not_new, simp, simp, simp)
apply (erule disjE, clarsimp)
apply (drule_tac s=sa and n=Nb in ok_parts_not_new, simp, simp, simp)
by (simp_all add: secret_def)
end