set allowDiffPatterns = true.

(********   This file has been automatically generated using the tool UKano. It encodes the frame opacity condition. ********)

(**********)
(* THEORY *)
(**********)


(* public communication channel *)
free c : channel.
free ct : channel.
free cr : channel.

(* constant values *)
free error_mac : bitstring.
free init : bitstring.
free read : bitstring.
free ok : bitstring.
free tagPass : bitstring.
free tagReader : bitstring.
const g : bitstring [data].


(* Generation of a new paramater *)
fun gen(bitstring,bitstring) : bitstring.

(* Diffie-Hellman exponentiation: partial axiomatization
   as defined in the ProVerif 1.92's manual (p. 33) *)
fun exp (bitstring, bitstring) : bitstring.
equation forall x : bitstring, y : bitstring;
  exp(exp(g,x),y) = exp(exp(g,y),x).
equation forall x : bitstring, y : bitstring,
                a : bitstring, b : bitstring;
  exp(exp(gen(a,b),x),y) = exp(exp(gen(a,b),y),x).


fun enc (bitstring, bitstring) : bitstring.
fun dec (bitstring, bitstring) : bitstring.
equation forall x : bitstring, y : bitstring;
  dec(enc(x,y),y) = x.	       

 (* Mac (of pairs) *)
fun mac(bitstring, bitstring) : bitstring.

			       
(*************)
(*  *)


(* == PROTOCOL WITH IDEALISATION == *)
let SYSTEM =
( !
  new k : bitstring;
     !
      ((
        new s: bitstring;
        new hole__1_I_0: bitstring;
        out(ct, choice[enc(s,k),hole__1_I_0]);
        in(ct, choice[x1,x1id]: bitstring);
        new b1: bitstring;
        new hole__2_I_1: bitstring;
        out(ct, choice[exp(g,b1),hole__2_I_1]);
        in(ct, choice[x2,x2id]: bitstring);
        let (newG: bitstring) = gen(exp(g,s),exp(x1,b1)) in
        new b2: bitstring;
        new hole__3_I_2: bitstring;
        out(ct, choice[exp(newG,b2),hole__3_I_2]);
        in(ct, choice[x3,x3id]: bitstring);
        let (newKey: bitstring) = exp(x2,b2) in
        if (mac((tagReader,exp(newG,b2)),newKey) = x3) then
        new hole__newKey_I_3: bitstring;
        out(cr, choice[mac((tagPass,x2),newKey),mac((tagPass,x2id),hole__newKey_I_3)])
      )|(
        in(cr, choice[y1,y1id]: bitstring);
        new a1: bitstring;
        new hole__4_R_4: bitstring;
        out(cr, choice[exp(g,a1),hole__4_R_4]);
        in(cr, choice[y2,y2id]: bitstring);
        let (newG_58: bitstring) = gen(exp(g,dec(y1,k)),exp(y2,a1)) in
        new a2: bitstring;
        new hole__5_R_5: bitstring;
        out(cr, choice[exp(newG_58,a2),hole__5_R_5]);
        in(cr, choice[y3,y3id]: bitstring);
        if (y3 <> exp(newG_58,a2)) then
        let (newKey_59: bitstring) = exp(y3,a2) in
        new hole__newKey_R_6: bitstring;
        out(cr, choice[mac((tagReader,y3),newKey_59),mac((tagReader,y3id),hole__newKey_R_6)]);
        in(cr, choice[y4,y4id]: bitstring);
        if (mac((tagPass,exp(newG_58,a2)),newKey_59) = y4) then
        out(cr, ok)
      ))
)
.
process SYSTEM

(* EXPECTPV
RESULT Diff-equivalence is true.
2.092s (user 2.044s + system 0.048s), max rss 196040K
END *)
