(* 

A -> B : A
B -> A : B, N_1, N_2
A -> B : A, { N_1, N_2, M }_pkB received as { N_1, X, Y }_pkB
B -> A : N_1, X, { X, Y, N_1 }_pkB

*)

(* Public key cryptography *)

fun pk/1.
fun encrypt/2.
reduc decrypt(encrypt(x,pk(y)),y) = x.

(* Function from secrets to host names *)

fun host/1.

free c.
private free M.

query attacker:M.

let processA = 
	out(c, hostA);
	in(c,(=hostB, n1, n2));
	out(c, (hostA, encrypt(( n1, n2, M ), pkB))).

let processB = 
	in(c, =hostA);
	new n1; new n2;
	out(c, (hostB, n1, n2));
	in(c, (=hostA, mes));
	let (=n1, x, y) = decrypt(mes, skB) in
	out(c, (n1, x, encrypt((x, y, n1), pkB))).

process 
        new skB; let pkB = pk(skB) in
        out(c, pkB);
	let hostB = host(skB) in
	out(c, hostB);
        new skA; let pkA = pk(skA) in
        out(c, pkA);
	let hostA = host(skA) in
	out(c, hostA);
	((!processA) | (!processB))
