free usb : channel.
(* Definitions for key signature and mac *)

type id.
type pkey.
type skey.
type stamp.

free counter1:channel [private].
free counter2:channel [private].
free lock:channel [private].
free st0:stamp.

fun pk(skey) :  pkey.


event Counter(channel,stamp,nat).

set inductionLemmas = true.

axiom i:nat,i1:nat,i2:nat,st:stamp,st1:stamp,st2:stamp,d:channel;
  event(Counter(d,st,i1)) && event(Counter(d,st,i2)) ==> i1 = i2 || st = st0;
  event(Counter(d,st1,i)) && event(Counter(d,st2,i)) ==> st1 = st2 || st1 = st0 || st2 = st0.

lemma l:nat,i:nat,j:nat,st:stamp,st1:stamp,st2:stamp,d:channel;
  event(Counter(lock,st,l)) && event(Counter(counter1,st1,i)) ==> (i = 0 && st1 = st0) || (l = i && st1 <> st0);
  event(Counter(lock,st,l)) && event(Counter(counter2,st1,i)) ==> (i = 0 && st1 = st0) || (l = i && st1 <> st0).

let T_auth2( ) =

    	   in(lock,l:nat);
	   new st[]:stamp;
	   event Counter(lock,st,l+1);

	   in(counter1,i:nat);
	   new st1[]:stamp;
	   event Counter(counter1,choice[st1,st0],choice[i+1,i]);
	   out(counter1,choice[i+1,i]);

	   in(counter2,j:nat);
	   new st2[]:stamp;
	   event Counter(counter2,choice[st0,st2],choice[j,j+1]);
	   out(counter2,choice[j,j+1]);

	   out(lock,l+1);

	   out(usb,choice[i,j]).



process
(! in (counter1, x:nat) ; out(counter1,x); 0 ) |
(! in (counter2, x:nat) ; out(counter2,x); 0 ) |
(! in (lock, x:nat) ; out(lock,x); 0 ) |

(
out(counter1, 0);
out(counter2, 0);
out(lock, 0);
  (
   !T_auth2( )
  )
)

(*
ski is the master key of yubikey_i
we associate the counteri to yubikey_i

Check whether two accounts (id1, id2) on the same yubikey sk1 with the same counter
is distinguishable from two accounts (id1, id2) on two different yubikeys (with different counters)
*)

(* EXPECTPV
RESULT event(Counter(lock[],st_1,l_1)) && event(Counter(counter1[],st1_1,i_1)) ==> (i_1 = 0 && st1_1 = st0[]) || (l_1 = i_1 && st1_1 ≠ st0[]) cannot be proved.
RESULT event(Counter(lock[],st_1,l_1)) && event(Counter(counter2[],st1_1,i_1)) ==> (i_1 = 0 && st1_1 = st0[]) || (l_1 = i_1 && st1_1 ≠ st0[]) cannot be proved.
0.128s (user 0.112s + system 0.016s), max rss 10448K
END *)
