(* Kerberos, modified by Gong et al,
   Version taken from Delaune, Jacquemard, LSV-04-1

   The unrecognizable tuples lead to non-termination.
   Try to solve this!

   Simplified version of kerberos-gl2 to investigate the termination 
   problem. *)

(* param selFun = NounifsetMaxsize. *)
param movenew = false.
(* param verboseRules = yes. *)


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.

(* Public key cryptography *)

fun penc/2.
fun pk/1.
reduc pdec(penc(x,pk(y)),y) = x.

(* Unrecognizable pairs and triples.
   An implementation is concatenation, when the elements have known lengths *)

fun pair/2.
fun fst/1.
fun snd/1.
equation fst(pair(x,y)) = x.
equation snd(pair(x,y)) = y.
equation pair(fst(x), snd(x)) = x.


fun triple/2.
fun fst3/1.
fun snd3/1.
equation fst3(triple(x,y)) = x.
equation snd3(triple(x,y)) = y.
equation triple(fst3(x),snd3(x)) = x.

(* PA = pw(A,S), PB = pw(B, S) *)

free hostA, hostB.
private free PA, PB.
weaksecret PA.
weaksecret PB.

let processA = 
	in(c, hostX);
	new N1;
	new N2;
	out(c, penc((hostA, hostX, N1, N2), pkS));
	in(c, (m1, m2));
	let p1 = dec(m1, PA) in
        if N1 = fst(p1) then
	let m3 = snd(p1) in
	let K = sdec(m3, N2) in
	out(c, m2).

let processB =
	in(c, m4);
	let t1 = dec(m4, PB) in
	let hostY = fst3(t1) in
	let k = snd3(t1) in
	0.

let processS = 
	in(c, m5);
	let (=hostA, =hostB, N1, N2) = pdec(m5, skS) in
	new K;
	out(c, (enc(pair(N1, senc(K, N2)), PA), enc(triple(hostA, K), PB))).
	    
process new skS;
	let pkS = pk(skS) in
	out(c, pkS);
	(!processA) | (!processB) | (!processS)

(* EXPECTPV
RESULT Weak secret PA is false.
RESULT Weak secret PB is false.
0.112s (user 0.072s + system 0.040s), max rss 9820K
END *)
