(*  This is an attempt to model GDH.1 protocol of Michael Steiner et al for 3 participants *)

(*      p0 send {g^n0} to p1. 
	p1 sends {g^n0, g^(n0*n1)} to p2.
	p2 sets group key to g^(n0*n1*n2).
	p2 sends {g^n2, g^(n2*n0)} to p1. p1 sets group key to g^(n0*n1*n2).
	p1 sends {g^(n1*n2)} to p0. p0 sets group key to g^(n0*n1*n2). 
*)


free c. 

private free m, success, fail_symb, honest.


(* Check if attacker can recover m*)
 
 query attacker:m.

 
 
(* Shared key cryptography *)

fun enc/2.
fun dec/2.
equation dec(enc(x,y),y) = x.


(* Diffie-Hellman functions *)
(* Exponential and Diffie-Hellman *)

data g/0.

fun exp/2.

equation exp(exp(g,x),y) = exp(exp(g,y),x).

(* This equations seem to be the reason why ProVerif fails to prove! Reason: comment out the equation below and ProVerif succeeds in proving. *)
  equation exp(exp(exp(g,y),z),x)=exp(exp(exp(g,y),x),z). 


(* Is this last equation really neeeded?
 equation exp(exp(exp(g,y),z),x)=exp(exp(exp(g,x),y),z). 
 *)



(* processes *)
(* honestC is a private channel on which honest principals communicate the exact messages they communicate on the public channels c01, c10, c12, and c21. Lousy way of ensuring that attacker does not behave as an "honest" participant *)

let p0 = new n0; 
	(let gn0 = exp(g,n0) in
         out(c0,gn0); in(c0,x1); let k = exp(x1,n0) in out(c01, enc(m,k))).

let p1 = new n1; 
         in(c0,x0); 
         let k = exp(x0,n1) in 
                         out(c0,(x0,k));
			 in(c0,(v,w));
			 out(c0,exp(v,n1)).

			
let p2 = new n2;
	( in(c0,(t,u));
		 out(c0,(exp(g,n2),exp(t,n2)));
		 let comk2=exp(u,n2) in
		 0).

process  new c0; ( p0 | p1 | p2 |
  !in(c0, x); out(c, x) )


(* EXPECTPV
RESULT not attacker:m[] cannot be proved.
0.108s (user 0.096s + system 0.012s), max rss 9856K
END *)
