libsoliton/cryptoverif/LO_Auth.cv
Kamal Tufekcic 3acaa0fa3f
CryptoVerif and Tamarin models, minor doc updates
Signed-off-by: Kamal Tufekcic <kamal@lo.sh>
2026-04-23 15:52:23 +03:00

121 lines
3.9 KiB
Text

(* LO-Auth: Key Possession Proof (Theorem 6)
*
* Protocol (§6):
* Server → Client: c, where (c, ss) ← XWing.Encaps(pk_IK_client[XWing])
* Client → Server: proof = MAC(key=ss, data="lo-auth-v1")
* Server: accept iff proof = token, where token = MAC(key=ss, data="lo-auth-v1")
*
* Security claims:
* 1. Correspondence: ServerAccepts ==> ClientResponds (Theorem 6)
* 2. Injective correspondence: each acceptance maps to a distinct client
* response (single-use, matching Tamarin's Auth_Single_Use)
*
* Reduces to: X-Wing IND-CCA2 + HMAC-SHA3-256 SUF-CMA.
*
* Decaps oracle (§8.3 compositional note): In the Tamarin model, an explicit
* DecapsOracle rule models the adversary's ability to submit arbitrary
* ciphertexts and observe MAC(Decaps(sk_IK, c), "lo-auth-v1"). In CryptoVerif,
* this is subsumed by the IND-CCA2 KEM assumption, which already provides the
* adversary with a raw decapsulation oracle returning ss directly — strictly
* more powerful than the MAC-wrapped output. The Nc parameter counts all
* client-side decapsulation queries (both legitimate responses and adversarial
* oracle use); the IND-CCA2 advantage bound P_kem(time, 1, Ns, Nc) accounts
* for all such queries.
*)
(* Session counts *)
param Ns. (* Server challenge sessions *)
param Nc. (* Client response sessions (includes §8.3 Decaps oracle queries) *)
(* ---------- Type declarations ---------- *)
type kem_keyseed [large, fixed].
type kem_pkey [bounded].
type kem_skey [bounded].
type kem_secret [large, fixed].
type kem_ciphertext [bounded].
type kem_encapoutput [bounded].
type macres [fixed].
type label [fixed].
(* ---------- X-Wing KEM (IND-CCA2) ---------- *)
proba P_kem.
proba P_kem_keycoll.
proba P_kem_ctxtcoll.
expand IND_CCA2_KEM(
kem_keyseed, kem_pkey, kem_skey,
kem_secret, kem_ciphertext, kem_encapoutput,
kem_pkgen, kem_skgen, kem_encap, kem_pair, kem_decap,
injbot_kem, P_kem, P_kem_keycoll, P_kem_ctxtcoll
).
(* ---------- HMAC-SHA3-256 as SUF-CMA deterministic MAC ---------- *)
proba P_mac.
expand SUF_CMA_det_mac(kem_secret, label, macres, mac_auth, mac_check, P_mac).
const lo_auth_label: label.
(* ---------- Events ---------- *)
event ServerAccepts(kem_pkey, kem_ciphertext).
event ClientResponds(kem_pkey, kem_ciphertext).
(* ---------- Security queries ---------- *)
(* Theorem 6 (Key Possession): If the server accepts for a challenge
* ciphertext ct, then the client responded to that same ct. *)
query pk: kem_pkey, ct: kem_ciphertext;
event(ServerAccepts(pk, ct)) ==> event(ClientResponds(pk, ct)).
(* Single-use (Tamarin: Auth_Single_Use): Each server acceptance maps to
* a distinct client response — no replay of a single client response can
* satisfy two server sessions. *)
query pk: kem_pkey, ct: kem_ciphertext;
inj-event(ServerAccepts(pk, ct)) ==> inj-event(ClientResponds(pk, ct)).
(* ---------- Channels ---------- *)
channel c_start, c_srv_start, c_srv_out, c_srv_recv,
c_cli_in, c_cli_out, c_pub.
(* ---------- Server process ---------- *)
let Server(pk_client: kem_pkey) =
foreach i_s <= Ns do
in(c_srv_start, ());
let kem_pair(ss: kem_secret, ct: kem_ciphertext) = kem_encap(pk_client) in
let token: macres = mac_auth(lo_auth_label, ss) in
out(c_srv_out, ct);
in(c_srv_recv, p: macres);
if p = token then (
event ServerAccepts(pk_client, ct)
).
(* ---------- Client process ---------- *)
let Client(sk_client: kem_skey, pk_client: kem_pkey) =
foreach i_c <= Nc do
in(c_cli_in, ct: kem_ciphertext);
let injbot_kem(ss: kem_secret) = kem_decap(ct, sk_client) in
let tag: macres = mac_auth(lo_auth_label, ss) in
event ClientResponds(pk_client, ct);
out(c_cli_out, tag).
(* ---------- Main process ---------- *)
process
in(c_start, ());
new kem_seed: kem_keyseed;
let pk_client = kem_pkgen(kem_seed) in
let sk_client = kem_skgen(kem_seed) in
out(c_pub, pk_client);
(Server(pk_client) | Client(sk_client, pk_client))
(* EXPECTED
All queries proved.
END *)