Theory Key

theory Key
  imports
    "../Fused_Resource"
begin


section ‹Key specification›

locale ideal_key =
  fixes valid_keys :: "'key set"
begin

subsection ‹Data-types for Parties, State, Events, Input, and Output›

datatype party = Alice | Bob

type_synonym s_shell = "party set"
datatype 'key' s_kernel = PState_Store | State_Store 'key'
type_synonym 'key' state = "'key' s_kernel × s_shell"

datatype event = Event_Shell party | Event_Kernel

datatype iadv = Inp_Adversary

datatype iusr_alice = Inp_Alice
datatype iusr_bob = Inp_Bob
type_synonym iusr = "iusr_alice + iusr_bob"

datatype oadv = Out_Adversary

datatype 'key' ousr_alice = Out_Alice 'key'
datatype 'key' ousr_bob = Out_Bob 'key'
type_synonym 'key' ousr = "'key' ousr_alice + 'key' ousr_bob"


subsubsection ‹Basic lemmas for automated handling of party sets (i.e. @{text s_shell})›

lemma Alice_neq_iff [simp]: "Alice  x  x = Bob"
  by(cases x) simp_all

lemma neq_Alice_iff [simp]: "x  Alice  x = Bob"
  by(cases x) simp_all

lemma Bob_neq_iff [simp]: "Bob  x  x = Alice"
  by(cases x) simp_all

lemma neq_Bob_iff [simp]: "x  Bob  x = Alice"
  by(cases x) simp_all

lemma Alice_in_iff_nonempty: "Alice  A  A  {}" if "Bob  A"
  using that by(auto)(metis (full_types) party.exhaust)

lemma Bob_in_iff_nonempty: "Bob  A  A  {}" if "Alice  A"
  using that by(auto)(metis (full_types) party.exhaust)


subsection ‹Defining the event handler›

fun poke :: "('key state, event) handler"
  where
    "poke (s_kernel, parties) (Event_Shell party) = 
      (if party  parties then 
        return_pmf None
      else 
        return_spmf (s_kernel, insert party parties))"
  | "poke (PState_Store, s_shell) (Event_Kernel) = do {
      key  spmf_of_set valid_keys;
      return_spmf (State_Store key, s_shell)  } "
  | "poke _ _ = return_pmf None"

lemma in_set_spmf_poke:
  "s'  set_spmf (poke s x) 
  (s_kernel parties party. s = (s_kernel, parties)  x = Event_Shell party  party  parties  s' = (s_kernel, insert party parties)) 
  (s_shell key. s = (PState_Store, s_shell)  x = Event_Kernel  key  valid_keys  finite valid_keys  s' = (State_Store key, s_shell))"
  by(cases "(s, x)" rule: poke.cases)(auto simp add: set_spmf_of_set)

lemma foldl_poke_invar:
  " (s_kernel', parties')  set_spmf (foldl_spmf poke p events); (s_kernel, parties)set_spmf p. set_s_kernel s_kernel  valid_keys 
   set_s_kernel s_kernel'  valid_keys"
  by(induction events arbitrary: parties' rule: rev_induct)
    (auto 4 3 simp add: split_def foldl_spmf_append in_set_spmf_poke dest: bspec)

subsection ‹Defining the adversary interface›

fun iface_adv :: "('key state, iadv, oadv) oracle'"
  where
   "iface_adv state _ = return_spmf (Out_Adversary, state)"


subsection ‹Defining the user interfaces›

context
begin

private fun iface_usr_func :: "party  _  _  'inp  ('wrap_key × 'key state) spmf"
  where
    "iface_usr_func party wrap (State_Store key, parties) inp = 
      (if party  parties then
        return_spmf (wrap key, State_Store key, parties)
      else
        return_pmf None)"
  | "iface_usr_func _ _ _ _ = return_pmf None"

abbreviation iface_alice :: "('key state, iusr_alice, 'key ousr_alice) oracle'"
  where
    "iface_alice  iface_usr_func Alice Out_Alice"

abbreviation iface_bob :: "('key state, iusr_bob, 'key ousr_bob) oracle'"
  where
    "iface_bob  iface_usr_func Bob Out_Bob"

abbreviation iface_usr :: "('key state, iusr, 'key ousr) oracle'"
  where
    "iface_usr  plus_oracle iface_alice iface_bob"

lemma in_set_iface_usr_func [simp]:
  "x  set_spmf (iface_usr_func party wrap state inp) 
   (key parties. state = (State_Store key, parties)  party  parties  x = (wrap key, State_Store key, parties))"
  by(cases "(party, wrap, state, inp)" rule: iface_usr_func.cases) auto

end


subsection ‹Defining the Fuse Resource›

primcorec core :: "('key state, event, iadv, iusr, oadv,'key ousr) core" 
  where
    "cpoke core = poke"
  | "cfunc_adv core = iface_adv"
  | "cfunc_usr core = iface_usr"

sublocale fused_resource core "(PState_Store, {})" .


subsubsection ‹Lemma showing that the resulting resource is well-typed›

lemma WT_core [WT_intro]: 
  "WT_core ℐ_full (ℐ_uniform UNIV (Out_Alice ` valid_keys)  ℐ_uniform UNIV (Out_Bob ` valid_keys))
     (pred_prod (pred_s_kernel (λkey. key  valid_keys)) (λ_. True)) core"
  apply (rule WT_core.intros)
  subgoal for s e s' by(cases "(s, e)" rule: poke.cases)(auto split: if_split_asm simp add: set_spmf_of_set)
  by auto

lemma WT_fuse [WT_intro]: 
  assumes [WT_intro]: "WT_rest ℐ_adv_rest ℐ_usr_rest I_rest rest"
  shows "(ℐ_full  ℐ_adv_rest)  ((ℐ_uniform UNIV (Out_Alice ` valid_keys)  ℐ_uniform UNIV (Out_Bob ` valid_keys))  ℐ_usr_rest) ⊢res resource rest "
  by(rule WT_intro)+ simp
 
end

end