Theory System_Construction

section ‹Examples›

theory System_Construction imports
  "../../Constructive_Cryptography"
begin

subsection ‹Random oracle resource›

locale rorc =
  fixes range :: "'r set"
begin

fun rnd_oracle :: "('m ⇒ 'r option, 'm, 'r) oracle'" where
  "rnd_oracle f m = (case f m of
    (Some  r) ⇒ return_spmf (r, f)
  | None      ⇒ do { 
      r ← spmf_of_set (range); 
      return_spmf (r, f(m := Some r))})"

definition "res = RES (rnd_oracle ⊕O rnd_oracle) Map.empty"

end

subsection ‹Key resource›

locale key =
  fixes key_gen :: "'k spmf"
begin

fun key_oracle :: "('k option, unit, 'k) oracle'" where
  "key_oracle None     () =  do { k ← key_gen; return_spmf (k, Some k)}"
| "key_oracle (Some x) () =  return_spmf (x, Some x)"

definition "res = RES (key_oracle ⊕O key_oracle) None"

end


subsection ‹Channel resource›

datatype 'a cstate = Void | Fail | Store 'a | Collect 'a

datatype 'a aquery = Look | ForwardOrEdit (forward_or_edit: 'a) | Drop
type_synonym 'a insec_query = "'a option aquery"
type_synonym auth_query = "unit aquery"

consts Forward :: "'a aquery"
abbreviation Forward_auth :: auth_query where "Forward_auth ≡ ForwardOrEdit ()"
abbreviation Forward_insec :: "'a insec_query" where "Forward_insec ≡ ForwardOrEdit None"
abbreviation Edit :: "'a ⇒ 'a insec_query" where "Edit m ≡ ForwardOrEdit (Some m)"
adhoc_overloading Forward ⇌ Forward_auth
adhoc_overloading Forward ⇌ Forward_insec

translations
  (logic) "CONST Forward" <= (logic) "CONST ForwardOrEdit (CONST None)"
  (logic) "CONST Forward" <= (logic) "CONST ForwardOrEdit (CONST Product_Type.Unity)"
  (type) "auth_query" <= (type) "unit aquery"
  (type) "'a insec_query" <= (type) "'a option aquery"

subsubsection ‹Generic channel›

locale channel =
  fixes side_oracle :: "('m cstate, 'a, 'b option) oracle'"
begin

fun send_oracle :: "('m cstate, 'm, unit) oracle'" where
  "send_oracle Void m = return_spmf ((), Store m)"
| "send_oracle s    m = return_spmf ((), s)"

fun recv_oracle :: "('m cstate, unit, 'm option) oracle'" where
  "recv_oracle (Collect m) () = return_spmf (Some m, Fail)"
| "recv_oracle s           () = return_spmf (None, s)"

definition res :: "('a + 'm + unit, 'b option + unit + 'm option) resource" where
  "res ≡ RES (side_oracle ⊕O send_oracle ⊕O recv_oracle) Void"

end

subsubsection ‹Insecure channel›

locale insec_channel
begin

fun insec_oracle :: "('m cstate, 'm insec_query, 'm option) oracle'" where
  "insec_oracle Void      (Edit m') = return_spmf (None, Collect m')"
| "insec_oracle (Store m) (Edit m') = return_spmf (None, Collect m')"
| "insec_oracle (Store m) Forward   = return_spmf (None, Collect m)"
| "insec_oracle (Store m) Drop      = return_spmf (None, Fail)"
| "insec_oracle (Store m) Look      = return_spmf (Some m, Store m)"
| "insec_oracle s         _         = return_spmf (None, s)"

sublocale channel insec_oracle .

end

subsubsection ‹Authenticated channel›

locale auth_channel
begin

fun auth_oracle :: "('m cstate, auth_query, 'm option) oracle'" where
  "auth_oracle (Store m) Forward = return_spmf (None, Collect m)"
| "auth_oracle (Store m) Drop    = return_spmf (None, Fail)"
| "auth_oracle (Store m) Look    = return_spmf (Some m, Store m)"
| "auth_oracle s         _       = return_spmf (None, s)"

sublocale channel auth_oracle .

end

fun insec_query_of :: "auth_query ⇒ 'm insec_query" where
  "insec_query_of Forward = Forward"
| "insec_query_of Drop = Drop"
| "insec_query_of Look = Look"

abbreviation (input) auth_response_of :: "('mac × 'm) option ⇒ 'm option" 
  where "auth_response_of ≡ map_option snd"

abbreviation insec_auth_wiring :: "(auth_query, 'm option, ('mac × 'm) insec_query, ('mac × 'm) option) wiring"
  where "insec_auth_wiring ≡ (insec_query_of, auth_response_of)"


subsubsection ‹Secure channel›

locale sec_channel
begin

fun sec_oracle :: "('a list cstate, auth_query, nat option) oracle'" where
  "sec_oracle (Store m) Forward = return_spmf (None, Collect m)"
| "sec_oracle (Store m) Drop    = return_spmf (None, Fail)"
| "sec_oracle (Store m) Look    = return_spmf (Some (length m), Store m)"
| "sec_oracle s         _       = return_spmf (None, s)"

sublocale channel sec_oracle .

end

abbreviation (input) auth_query_of :: "auth_query ⇒ auth_query"
  where "auth_query_of ≡ id"

abbreviation (input) sec_response_of :: "'a list option ⇒ nat option"
  where "sec_response_of ≡ map_option length"

abbreviation auth_sec_wiring :: "(auth_query, nat option, auth_query, 'a list option) wiring"
  where "auth_sec_wiring ≡ (auth_query_of, sec_response_of)"

subsection ‹Cipher converter›

locale cipher =
  AUTH: auth_channel + KEY: key key_alg 
  for key_alg :: "'k spmf" +
  fixes enc_alg :: "'k ⇒ 'm ⇒ 'c spmf"
    and dec_alg :: "'k ⇒ 'c ⇒ 'm option"
begin

definition enc :: "('m, unit, unit + 'c, 'k + unit) converter" where
  "enc ≡ CNV (stateless_callee (λm. do {
    k ← Pause (Inl ()) Done;
    c ← lift_spmf (enc_alg (projl k) m);
    (_ :: 'k + unit) ← Pause (Inr c) Done;
    Done (()) 
  })) ()"

definition dec :: "(unit, 'm option, unit + unit, 'k + 'c option) converter" where
  "dec ≡ CNV (stateless_callee (λ_. Pause (Inr ()) (λc'. 
    case c' of Inr (Some c) ⇒ (do {
      k ← Pause (Inl ()) Done;
      Done (dec_alg (projl k) c) })
    | _ ⇒ Done None)
  )) ()"

definition πE :: "(auth_query, 'c option, auth_query, 'c option) converter" (‹πE›) where
  "πE ≡ 1C"

definition "routing ≡ (1C |= lassocrC) ⊙ swap_lassocr ⊙ (1C |= (1C |= swap_lassocr) ⊙ swap_lassocr) ⊙ rassoclC"

definition "res = (1C |= enc |= dec) ⊳ (1C |= parallel_wiring) ⊳ parallel_resource1_wiring ⊳ (KEY.res ∥ AUTH.res)"

lemma res_alt_def: "res = ((1C |= enc |= dec) ⊙ (1C |= parallel_wiring)) ⊳ parallel_resource1_wiring ⊳ (KEY.res ∥ AUTH.res)"
  by(simp add: res_def attach_compose)

end

subsection ‹Message authentication converter›

locale macode = 
  INSEC: insec_channel + RO: rorc range 
  for   range :: "'r set" +
  fixes mac_alg :: "'r ⇒ 'm ⇒ 'a spmf"
begin

definition enm :: "('m, unit, 'm + ('a × 'm), 'r + unit) converter" where
  "enm ≡ CNV (λbs m. if bs 
    then Done ((), True)
    else do {
      r ← Pause (Inl m) Done;
      a ← lift_spmf (mac_alg (projl r) m);
      (_ :: 'r + unit) ← Pause (Inr (a, m)) Done;
      Done ((), True)
    }) False"

definition dem :: "(unit, 'm option, 'm + unit, 'r + ('a × 'm) option) converter" where
  "dem ≡ CNV (stateless_callee (λ_. Pause (Inr ()) (λam'. 
    case am' of Inr (Some (a, m)) ⇒ (do {
      r ← Pause (Inl m) Done;
      a' ← lift_spmf (mac_alg (projl r) m);    
      Done (if a' = a then Some m else None) })
    | _ ⇒ Done None)
  )) ()"

definition πE :: "(('a × 'm) insec_query, ('a × 'm) option, ('a × 'm) insec_query, ('a × 'm) option) converter" (‹πE›) where
  "πE ≡ 1C"

definition "routing ≡ (1C |= lassocrC) ⊙ swap_lassocr ⊙ (1C |= (1C |= swap_lassocr) ⊙ swap_lassocr) ⊙ rassoclC"

definition "res = (1C |= enm |= dem) ⊳ (1C |= parallel_wiring) ⊳ parallel_resource1_wiring ⊳ (RO.res ∥ INSEC.res)"

end


lemma interface_wiring:
  "(cnv_advr |= cnv_send |= cnv_recv) ⊳ (1C |= parallel_wiring) ⊳ parallel_resource1_wiring ⊳ 
  (RES (res2_send ⊕O res2_recv) res2_s ∥ RES (res1_advr ⊕O res1_send ⊕O res1_recv) res1_s)
  =
  cnv_advr |= cnv_send |= cnv_recv ⊳
  RES (†res1_advr ⊕O (res2_send† ⊕O †res1_send) ⊕O res2_recv† ⊕O †res1_recv) (res2_s, res1_s)"
  (is "_ ⊳ ?L1 ⊳ ?L2 ⊳ ?L3 = _ ⊳ ?R")
proof -
  let ?wiring = "(id, id) |w  (lassocrw ∘w ((id, id) |w (rassoclw ∘w (swapw |w (id, id) ∘w lassocrw)) 
    ∘w rassoclw)) ∘w (rassoclw ∘w (swapw |w (id, id) ∘w lassocrw))"

  have "?L1 ⊳ ?L2 ⊳ ?L3 = ?L1 ⊙ ?L2 ⊳
    RES ((res2_send† ⊕O res2_recv†) ⊕O †res1_advr ⊕O †res1_send ⊕O †res1_recv) (res2_s, res1_s)" (is "_ = _ ⊳ RES(?O) ?S") 
    unfolding attach_compose[symmetric] resource_of_parallel_oracle[symmetric]
    by (simp only: parallel_oracle_conv_plus_oracle extend_state_oracle_plus_oracle extend_state_oracle2_plus_oracle)
  also have "… = RES(apply_wiring ?wiring ?O) ?S"
    by (rule attach_wiring_resource_of_oracle, simp only: parallel_wiring_def parallel_resource1_wiring_def swap_lassocr_def)
      ((rule wiring_intro WT_resource_of_oracle WT_plus_oracleI WT_callee_full)+, simp_all)
  also have "… = ?R" by simp
  finally show ?thesis by (rule arg_cong2[where f="attach", OF refl]) 
qed


(* prevent the simplifier from rewriting id and restructuring the equations *)
definition id' where "id' = id"

end