(* LO-Ratchet: Message Key Secrecy (Theorem 3)
 *
 * Given a fresh epoch key ek (from Theorem 1 + KDF_Root), proves that
 * message keys mk = KDF_MsgKey(ek, counter) are indistinguishable from
 * random. Combined with AEAD security under random keys (standard
 * composition via [BN00]), this gives full message secrecy.
 *
 * Reduces to: HMAC-SHA3-256 PRF.
 *)

param N_msg.

(* ---------- Types ---------- *)

type epoch_key [large, fixed].
type msg_key [large, fixed].
type counter [fixed].

(* ---------- KDF_MsgKey as PRF ---------- *)

proba P_prf.

expand PRF_large(epoch_key, counter, msg_key, kdf_msgkey, P_prf).

(* ---------- Security query ---------- *)

query secret test_mk [cv_onesession].

(* ---------- Channels ---------- *)

channel c_start, c_ready, c_test_in, c_test_out.

(* ---------- Process ---------- *)
(* Single derivation: ek is fresh, derive mk at one counter.
 * The PRF transformation replaces kdf_msgkey(ek, ctr) with a random value.
 * No oracle needed — the PRF_large game handles multi-query internally. *)

process
  in(c_start, ());
  new ek: epoch_key;
  out(c_ready, ());
  in(c_test_in, ctr: counter);
  let test_mk: msg_key = kdf_msgkey(ek, ctr) in
  out(c_test_out, ())
