(* Bellovin, Merritt, Oakland 92, section 3.1
   Version in which A and B talk to anybody *)

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)).

(* Host *)

data host/2.

param verboseRules  = yes.

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

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


let processB =
	in(c, (=hostX, m));
	let gRA = dec(m, P) in
	new RB;
	let K = f(RB, gRA) in
	new challengeB;
	out(c, (enc(g(RB), P), senc(challengeB, K)));
	in(c,m3);
	let (challengeA,=challengeB) = sdec(m3, K) in
	out(c, senc((challengeA), K)).

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.784s (user 0.600s + system 0.184s), max rss 14672K
END *)
