(* This is a bug against injective agreement.
   The system should not prove injective agreement,
   because the message send from A to B is in fact
   equal to f(c1,g(c0)), so it does not depend on n.
   Then an attacker gets encrypt(f(c1,g(c0)),k) from
   B, and reuse this message in all future sessions of A
   to trigger the end event many times without executing
   the begin event. *)

(* Was a bug in attack reconstruction because f
   introduces a new variable (z) on its right-hand side *)

fun encrypt/2.
reduc decrypt(encrypt(x,y),y) = x.

fun f/2.
fun g/1.
fun h/3.

equation f(x,g(y)) = h(y,z,x).

free c,c0,c1.
query evinj:endauth(x) ==> evinj:beginauth(x).

let processA = 
  new n;
  out(c, h(c0,n,c1));
  in(c, x);
  let y = decrypt(x,k) in
  if y = h(c0,n,c1) then
  event endauth(h(c0,n,c1)).

let processB =
  in(c,x);
  event beginauth(x);
  out(c, encrypt(x,k)).

process
	new k;
        ((!processA) | (!processB))

(* EXPECTPV
Error in equation: h(y,z,x) = h(y,z_1,x)
Error: All variables of the right-hand side of an equation
xtime: error in child process (status : 2)
END *)
