(* Augmented EKE, Bellovin, Merritt,
   Section 3
   One knows whether one decrypts { challengeA, challengeB }_K
   and similar messages correctly.   *)


free c.

(* Symmetric cryptography
   One does not know whether decryption succeeds or not
   For use with weak secrets *)

fun enc/2.
fun dec/2.
equation dec(enc(x,y),y) = x.
equation enc(dec(x,y),y) = x.

(* Symmetric cryptography
   One knows whether decryption succeeds or not *)

fun senc/2.
reduc sdec(senc(x,y),y) = x.

(* Diffie-Hellman *)

fun g/1.
fun f/2.
equation f(x,g(y)) = f(y,g(x)).

(* Hash function *)

fun h/1.

(* One-way function *)

fun F/2.

(* Predicate *)

data true/0.
reduc T(h(x), F(x,y), y) = true.

(* Host *)

data host/2.


free hostA, hostB.
private free P.
weaksecret P.

let processA = 
	new RA;
	out(c, (hostA, enc(g(RA), h(P))));
	in(c, (m1, m2));
	let gRB = dec(m1, h(P)) in
	let K = f(RA, gRB) in
	let (challengeB) = sdec(m2, K) in
	new challengeA;
	out(c, senc((challengeA, challengeB), K));
	in(c, m3);
	if (challengeA) = sdec(m3, K) then
	out(c, senc(F(P,K), K)).


let processB =
	in(c, (=hostX, m)); 
	let gRA = dec(m, h(P)) in
	new RB;
	let K = f(RB, gRA) in
	new challengeB;
	out(c, (enc(g(RB), h(P)), senc(challengeB, K)));
	in(c, m4);
	let (challengeA, =challengeB) = sdec(m4, K) in
	out(c, senc(challengeA, K));
	in(c, m5);
	let fr = sdec(m5, K) in
	if T(h(P), fr, K) = true then
	0.

let processAtalkingX =
	in(c, (PA,PB));
	let hostX = host(PA,PB) in
	let P = PA in
	processA.

let processBtalkingX =
	in(c, (PA,PB));
	let hostX = host(PA,PB) in
	let P = PB in
	processB.

process
	(!let hostX = hostB in processA)
	| (!let hostX = hostA in processB)
	| (!processAtalkingX) | (!processBtalkingX)

(* EXPECTPV
RESULT Weak secret P is true.
0.232s (user 0.224s + system 0.008s), max rss 12876K
END *)
