(* This file is generated automatically by protocol transformer from test *)

fun o/0.
fun s/1.
fun p/1.

fun exp/4.
fun mult/4.

fun add_G1/2.
fun mult_GT/2.

fun inv_G1/1.
fun inv_GT/1.

fun a/0.
fun b/0.
fun c/0.
fun d/0.

fun secret/0.
fun na/0.
fun nb/0.
fun msk/0.
fun e/2.
fun sk/1.
fun pk/1.
fun enc/2.
fun sign/2.
fun cert/2.

fun hash/1.

pred nexp/3 elimVar,decompData.
pred nrexp/3 elimVar,decompData.
pred nmult/3 elimVar,decompData.
pred nrmult/3 elimVar,decompData.

pred norm_s/1 elimVar,decompData.
pred norm_p/1 elimVar,decompData.
pred next/2 elimVar,decompData.
pred add/3 elimVar,decompData.

pred i/1 elimVar,decompData.
nounif i:x.
pred i0/1 elimVar,decompData.
nounif i0:x.

equation e(x,y) = e(y,x).

equation add_G1(x,y) = add_G1(y,x).
equation mult_GT(x,y) = mult_GT(y,x).

query i0:secret.

reduc

(***** Phase rules: *****)

(***** Intruder rules: *****)

i0:o;
i0:x -> i0:s(x);
i0:x -> i0:p(x);
i0:exp(x, o, o, o)  ->  i0:x;
i0:x  ->  i0:exp(x, o, o, o);
i0:(na, y1, exp(x, x1, x2, x3))  ->  i0:exp(x, y1, x2, x3);
i0:(nb, y2, exp(x, x1, x2, x3))  ->  i0:exp(x, x1, y2, x3);
i0:(msk, y3, exp(x, x1, x2, x3))  ->  i0:exp(x, x1, x2, y3);

i0:mult(x, o, o, o)  ->  i0:x;
i0:x  ->  i0:mult(x, o, o, o);
i0:(na, y1, mult(x, x1, x2, x3))  ->  i0:mult(x, y1, x2, x3);
i0:(nb, y2, mult(x, x1, x2, x3))  ->  i0:mult(x, x1, y2, x3);
i0:(msk, y3, mult(x, x1, x2, x3))  ->  i0:mult(x, x1, x2, y3);

add: x1,y1,z1 & add: x2,y2,z2 & add: x3,y3,z3 &
i0:mult(x, x1, x2, x3) & i0:mult(y, y1, y2, y3) -> i0:exp(e(x,y), z1, z2, z3);

i0:(x,y) -> i0:add_G1(x,y);
i0:(x,y) -> i0:mult_GT(x,y);

i0:add_G1(x,y) & i0:x  -> i0:y;
i0:mult_GT(x,y) & i0:x  -> i0:y;

i0:add_G1(x,inv_G1(x));
i0:mult_GT(x,inv_GT(x));
i0:e(y,add_G1(x,inv_G1(x)));

i0:x -> i0:inv_G1(x);
i0:x -> i0:inv_GT(x);

i0:inv_G1(x) -> i0:x;
i0:inv_GT(x) -> i0:x;

(***** Normalisation rules: *****)

nexp: x, na, exp(x, s(o), o, o); 
nexp: exp(x, p(o), o, o), na, x; 
nexp: exp(x, x1, x2, x3), na, exp(x, s(x1), x2, x3); 
nexp: exp(x, p(x1), x2, x3), na, exp(x, x1, x2, x3); 
nexp: x, nb, exp(x, o, s(o), o); 
nexp: exp(x, o, p(o), o), nb, x; 
nexp: exp(x, x1, x2, x3), nb, exp(x, x1, s(x2), x3); 
nexp: exp(x, x1, p(x2), x3), nb, exp(x, x1, x2, x3); 
nexp: x, msk, exp(x, o, o, s(o)); 
nexp: exp(x, o, o, p(o)), msk, x; 
nexp: exp(x, x1, x2, x3), msk, exp(x, x1, x2, s(x3)); 
nexp: exp(x, x1, x2, p(x3)), msk, exp(x, x1, x2, x3); 

nrexp: x, na, exp(x, p(o), o, o); 
nrexp: exp(x, s(o), o, o), na, x; 
nrexp: exp(x, x1, x2, x3), na, exp(x, p(x1), x2, x3); 
nrexp: exp(x, s(x1), x2, x3), na, exp(x, x1, x2, x3); 
nrexp: x, nb, exp(x, o, p(o), o); 
nrexp: exp(x, o, s(o), o), nb, x; 
nrexp: exp(x, x1, x2, x3), nb, exp(x, x1, p(x2), x3); 
nrexp: exp(x, x1, s(x2), x3), nb, exp(x, x1, x2, x3); 
nrexp: x, msk, exp(x, o, o, p(o)); 
nrexp: exp(x, o, o, s(o)), msk, x; 
nrexp: exp(x, x1, x2, x3), msk, exp(x, x1, x2, p(x3)); 
nrexp: exp(x, x1, x2, s(x3)), msk, exp(x, x1, x2, x3); 

nmult: x, na, mult(x, s(o), o, o); 
nmult: mult(x, p(o), o, o), na, x; 
nmult: mult(x, x1, x2, x3), na, mult(x, s(x1), x2, x3); 
nmult: mult(x, p(x1), x2, x3), na, mult(x, x1, x2, x3); 
nmult: x, nb, mult(x, o, s(o), o); 
nmult: mult(x, o, p(o), o), nb, x; 
nmult: mult(x, x1, x2, x3), nb, mult(x, x1, s(x2), x3); 
nmult: mult(x, x1, p(x2), x3), nb, mult(x, x1, x2, x3); 
nmult: x, msk, mult(x, o, o, s(o)); 
nmult: mult(x, o, o, p(o)), msk, x; 
nmult: mult(x, x1, x2, x3), msk, mult(x, x1, x2, s(x3)); 
nmult: mult(x, x1, x2, p(x3)), msk, mult(x, x1, x2, x3); 

nrmult: x, na, mult(x, p(o), o, o); 
nrmult: mult(x, s(o), o, o), na, x; 
nrmult: mult(x, x1, x2, x3), na, mult(x, p(x1), x2, x3); 
nrmult: mult(x, s(x1), x2, x3), na, mult(x, x1, x2, x3); 
nrmult: x, nb, mult(x, o, p(o), o); 
nrmult: mult(x, o, s(o), o), nb, x; 
nrmult: mult(x, x1, x2, x3), nb, mult(x, x1, p(x2), x3); 
nrmult: mult(x, x1, s(x2), x3), nb, mult(x, x1, x2, x3); 
nrmult: x, msk, mult(x, o, o, p(o)); 
nrmult: mult(x, o, o, s(o)), msk, x; 
nrmult: mult(x, x1, x2, x3), msk, mult(x, x1, x2, p(x3)); 
nrmult: mult(x, x1, x2, s(x3)), msk, mult(x, x1, x2, x3); 

norm_s: o;
norm_s: x -> norm_s: s(x);

norm_p: o;
norm_p: x -> norm_p: p(x);

norm_s: x -> next: x, s(x);
norm_p: x -> next: p(x), x;

add: x, o, x;

add: x, y, z & next: z, w & norm_s: y -> add: x, s(y), w;
add: x, y, z & next: w, z & norm_p: y -> add: x, p(y), w;

npair: x, y, e(x,y);
npair: mult(x, x1, x2, x3), y, exp(e(x,y), x1, x2, x3);
npair: y, mult(x, x1, x2, x3), exp(e(x,y), x1, x2, x3);

add: x1,y1,z1 & add: x2,y2,z2 & add: x3,y3,z3 ->
npair: mult(x, x1, x2, x3), mult(y, y1, y2, y3), exp(e(x,y), z1, z2, z3);

npair: x, z, v & npair: y, z, w ->
npair: add_G1(x,y), z, mult_GT(v,w);

npair: x, y, v & npair: x, z, w ->
npair: x, add_G1(y,z), mult_GT(v,w);

(***** User rules: *****)


(*

CA issues the following private keys for Alice and Bob respectively: 

SA = s*QA where QA = H(A)
SB = s*QB where QB = H(B).

s - master secret key of CA
Ps = point*s - the public key generated by CA

Alice and Bob each randomly choose: na, nb
They then exchange the public keys as follows:
TA = point*na
TB = point*nb
    M1: A -> B: TA
    M2: B -> A: TB
Alice computes KAB = e(SA, TB) * e(aQB, Ps),
Bob computes KBA = KBA = e(SB, TA) * e(bQA, Ps).

shared secret: K = KAB = KBA= e(bQA + aQB, Ps).

*)

i0: x -> i0: hash(x);
i0: a;
i0: b;

(* everyone knows sP *)
i0: mult(point, o, o, s(o));

(*
Secret keys that Alice and Bob get from the CA (and the nonces)
If the attacker knows any of them, he should get the secret

i0: na;
i0: nb;
i0: mult(hash(b),o,o,s(o));
i0: mult(hash(a),o,o,s(o));
*)

(* TA and TB *)
i0: mult(point,s(o),o,o);
i0: mult(point,o,s(o),o);

(* Key generated by Alice *)
npair: mult(hash(a), o, o, s(o)), TB, x1 & npair: mult(hash(b), s(o), o, o), mult(point, o, o, s(o)), x2 &
i0:mult_GT(x1,x2) -> i0:secret();

(* Key generated by Bob *)
npair: mult(hash(b), o, o, s(o)), TA, x1 & npair: mult(hash(a), o, s(o), o), mult(point, o, o, s(o)), x2 &
i0:mult_GT(x1,x2) -> i0:secret();

(* Test if the attacker is able to construct the key (without protocol details)
i0:mult_GT(exp(e(hash(a),point), o, s(o), s(o)), exp(e(hash(b),point), s(o), o, s(o))) -> i0:secret();
*)

(***** End of User rules *****)
i:x -> i:x.
