(* Private Authentication
   Taken from Delaune, Jacquemard, CSFW'04 *)

set ignoreTypes = true.

(* shared-key encryption as equation *)

fun aenc(bitstring, bitstring): bitstring.
fun pk(bitstring): bitstring.

reduc forall x: bitstring, y: bitstring; adec(aenc(x,pk(y)),y) = x.

(* declaration of public name*)

free c: channel.

(* declaration of biprocess *)

let processA(sk_a:bitstring,sk_b:bitstring) =
	new n_a: bitstring;
	out(c, aenc((n_a,pk(sk_a)),pk(sk_b)));
	in(c, x:bitstring);
	0.

let processB(sk_b:bitstring,sk_a:bitstring) =
	in(c, x:bitstring);
	new n_b:bitstring;

	let (n_a:bitstring,pub_a:bitstring) = adec(x, sk_b) in
	  if pub_a = pk(sk_a)
	  then
	    out(c,aenc((n_a,n_b,pk(sk_b)),pk(sk_a)))
	  else
	    out(c,aenc(n_b,pk(sk_b)))
	else
	  out(c,aenc(n_b,pk(sk_b))).
	  
let system(sk_a:bitstring,sk_b:bitstring) = processA(sk_a,sk_b) | processB(sk_b,sk_a).

equivalence
	new sk_b:bitstring; new sk_a:bitstring; out(c,pk(sk_b)); out(c,pk(sk_a));
	  (
	    (! new sk_c:bitstring;! system(sk_c,sk_b))
	  |
	    (! new sk_c:bitstring;! system(sk_c,sk_b))
	  )
	  
	new sk_b:bitstring; new sk_a:bitstring; out(c,pk(sk_b)); out(c,pk(sk_a));
	  (
	    (! new sk_c:bitstring;! system(sk_c,sk_b))
	  |
	    !system(sk_a,sk_b)
	  )


(* EXPECTPV
RESULT Observational equivalence is true.
0.112s (user 0.108s + system 0.004s), max rss 10304K
END *)
