set allowDiffPatterns = true.

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

(* MODIFIED TO TEST A STRONG DEF OF UK using UKANO 
 * MINIMAL VERSION FOR DAA JOIN
 * Lucca Hirschi
 * 23/03/2016
 *)

(* REMARKS:
If basename may be equal between two sessions, conditions do not hold anymore nor unlinkability.
*)

(*
	Based on:

		Smyth, B., Ryan, M., & Chen, L. (2012) Formal analysis of anonymity in Direct Anonymous Attestation schemes.

	The script models the fixed RSA-based Direct Anonymous Attestation process specification <Join_RSA', Sign_RSA'>.

*)

(***************)
(* ==THEORY==  *)
(***************)
free c:channel.

fun accept () :bitstring.
fun zero() :bitstring.
fun one() :bitstring.
fun FJoin() :bitstring.
fun FSign() :bitstring.
fun hash(bitstring) :bitstring.
fun apk(bitstring) :bitstring.  (* Asymmetric Public bitstring *)
fun pk(bitstring) :bitstring.   (* Signature public bitstring *)
fun commit(bitstring,bitstring):bitstring.
fun circ(bitstring,bitstring):bitstring.
fun clcommit(bitstring,bitstring,bitstring) :bitstring.
fun spk(bitstring,bitstring,bitstring) :bitstring.
fun clsign(bitstring,bitstring,bitstring,bitstring):bitstring.
fun penc(bitstring,bitstring,bitstring) : bitstring.
fun dec(bitstring,bitstring) : bitstring.

fun bottom() :bitstring.
fun ok() :bitstring.
fun hole() :bitstring.


(* Assymetric encryption *)
equation forall k:bitstring, r:bitstring, m:bitstring;
   dec(k,penc(apk(k),r,m)) = m.

(* Signature + blind signtaure *)
reduc forall xsk:bitstring,xprime:bitstring,xrand:bitstring,xmsg:bitstring;
  clgetprime(clsign(xsk,xprime,xrand,xmsg)) = xprime.
reduc forall xsk:bitstring,xprime:bitstring,xrand:bitstring,xmsg:bitstring;
  clgetbitstring(clsign(xsk,xprime,xrand,xmsg)) = xrand.
reduc forall xsk:bitstring,xprime:bitstring,xrand:bitstring,xmsg:bitstring;
  checkclsign(pk(xsk),xmsg,clsign(xsk,xprime,xrand,xmsg)) 
				= accept.
fun clopen(bitstring,bitstring,bitstring):bitstring
reduc
forall xsk:bitstring,xrand:bitstring,yprime:bitstring,yrand:bitstring,xmsg:bitstring;
  clopen(pk(xsk),xrand,clsign(xsk,yprime,yrand,
  	clcommit(pk(xsk),xrand,xmsg))) = clsign(xsk,yprime,xrand,xmsg)
otherwise
forall x:bitstring,xrand:bitstring,xplain:bitstring;
  clopen(x,xrand,clcommit(x,xrand,xplain)) = xplain.

(* ZK of join *)
reduc forall xzeta:bitstring,xsk:bitstring,xtsk:bitstring,xw:bitstring,xe:bitstring,xv:bitstring,xrand:bitstring,yprime:bitstring,yrand:bitstring,xmsg:bitstring, xpk:bitstring;
    checkspk(FJoin,
             (xzeta,xpk,commit(xtsk,xzeta),clcommit(xpk,xv,xtsk),xmsg),
             spk(FJoin,
	         (xtsk,xv),
		 (xzeta,xpk,commit(xtsk,xzeta),
		 clcommit(xpk,xv,xtsk),xmsg)
		 )
	     )
	     = accept.

reduc forall x1:bitstring, x2:bitstring;
   fst((x1,x2)) = x1.
reduc forall x1:bitstring, x2:bitstring;
   snd((x1,x2)) = x2.

fun KI():bitstring.    (* Long-term public bitstring of Issuer *)
fun skI():bitstring [private].   (* Signature bitstring of Issuer *)
reduc getPubskI() = pk(skI).

(*
event END().
query event(END()).
*)

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


(* == PROTOCOL WITH IDEALISATION == *)
let SYSTEM =
( !
  new skM : bitstring;
  new DAASeed : bitstring;
     !
      ((
        new cnt: bitstring;
        new bsnI: bitstring;
        let (tsk: bitstring) = hash((hash((DAASeed,hash(KI))),cnt,zero)) in
        let (zeta: bitstring) = hash((zero,bsnI)) in
        new zetaIN: bitstring;
        new tskN: bitstring;
        new v': bitstring;
        out(c, choice[(commit(tsk,zeta),clcommit(pk(skI),v',tsk)),(commit(tskN,zetaIN),clcommit(pk(skI),v',tskN))]);
        in(c, choice[encNe: bitstring,encNeid: bitstring]);
        new hole_I_0: bitstring;
        out(c, choice[hash((clcommit(pk(skI),v',tsk),dec(skM,encNe))),hash((clcommit(pk(skI),v',tskN),hole_I_0))]);
        in(c, choice[ni: bitstring,niid: bitstring]);
        new nt: bitstring;
        out(c, choice[(nt,zeta,spk(FJoin,(tsk,v'),(zeta,pk(skI),commit(tsk,zeta),clcommit(pk(skI),v',tsk),(nt,ni)))),(nt,zetaIN,spk(FJoin,(tskN,v'),(zetaIN,pk(skI),commit(tskN,zetaIN),clcommit(pk(skI),v',tskN),(nt,niid))))]);
        in(c, choice[sig: bitstring,sigid: bitstring]);
        let (cre: bitstring) = clopen(pk(skI),v',sig) in
        let (=accept) = checkclsign(pk(skI),tsk,cre) in
        out(c, ok)
      )|(
        in(c, choice[x_155: bitstring,xid_155: bitstring]);
        let ((xNi: bitstring,xU: bitstring)) = x_155 in
        new n: bitstring;
        new ne: bitstring;
        new hole__1_R_1: bitstring;
        out(c, choice[penc(apk(skM),n,ne),hole__1_R_1]);
        in(c, choice[yau: bitstring,yauid: bitstring]);
        new ni_156: bitstring;
        out(c, ni_156);
        in(c, choice[z: bitstring,zid: bitstring]);
        let ((xnt: bitstring,xzetaI: bitstring,xspk: bitstring)) = z in
        if (yau = hash((xU,ne))) then
        let (=accept) = checkspk(FJoin,(xzetaI,pk(skI),xNi,xU,(xnt,ni_156)),xspk) in
        new r1: bitstring;
        new r2: bitstring;
        out(c, choice[clsign(skI,r1,r2,snd(x_155)),clsign(skI,r1,r2,snd(xid_155))])
      ))
)
.
process SYSTEM

(* EXPECTPV
RESULT Diff-equivalence is true.
3.564s (user 3.440s + system 0.124s), max rss 353560K
END *)
