free c:channel.
free s:bitstring [private].

fun h(nat,bitstring):bitstring.

type stamp.

free id:stamp [private].

event Counter(channel,stamp,stamp,nat).

query i:nat,i1:nat,st:stamp,st1:stamp,st2:stamp,d:channel;
  attacker(s) ==>
        event(Counter(d,st2,st,i1)) && event(Counter(d,st2,st,i)) && i1 <> i
    ||  event(Counter(d,st2,st,i1)) && event(Counter(d,st2,st1,i1)) && st <> st1.

process
  !(
  new d:channel;
  new k:bitstring;
  (
    !(
    in(d,i:nat);
    new st[]:stamp;
    event Counter(d,id,st,i);
    out(c,h(i,k));
    out(d,i + 1);
    0
    )  ) | (
    !(
    in(d,i:nat);
    new st[]:stamp;
    event Counter(d,id,st,i);
    in(c,y:bitstring);
    if h(i,k) = y
    then
      out(c,s);
      out(d,i + 1);
      0
    else
      out(d,i + 1);
      0
    )  ) | (
    out(d,0);
    0
  ) | (
    !(
    in(d,x:nat);
    out(d,x);
    0
    )  )
  )

(* EXPECTPV
RESULT attacker(s[]) ==> (event(Counter(d_1,st2,st_2,i1)) && event(Counter(d_1,st2,st_2,i_2)) && i1 ≠ i_2) || (event(Counter(d_1,st2,st_2,i1)) && event(Counter(d_1,st2,st1,i1)) && st_2 ≠ st1) is true.
0.012s (user 0.012s + system 0.000s), max rss 7724K
END *)
