set timeout=12. Typed-check process:

null

Added action dependencies lemmas:


System after processing:

null

System Empty registered with actions (init).
[warning>Loaded "Prelude.sp".
<]

YUBIKEY

The YubiKey is a simple physical authentication device with a unique button. This device, manufactured by Yubico, allows users to securely authenticate to their accounts by issuing a one-time password (OTP).

In its typical configuration, the YubiKey generates a random OTP by encrypting a secret value and a counter. This message is accepted by the server only if it decrypts under the correct key to a valid secret value containing a counter whose value is larger than the last value accepted by the server for that YubiKey.

In this model, we analyze the security of the protocol as described in [1], assuming that the server remains secure.

Yubico assigns a key k, as well as a public and a secret identifier pid, sid to each YubiKey. The counter cpt inside the YubiKey is incremented whenever the YubiKey is plugged in, as well as when an OTP is generated, i.e. when the button of the YubiKey is pressed. This OTP is obtained by encrypting the counter value and the sid of the YubiKey with the key k.

  • YubiKey -> Server : <pid,<nonce,senc(<sid,cpt>,npr,k)>>

Here, npr is the encryption randomness. The server accepts this message if it decrypts with a legitimate key k, and leads to a valid secret value sid. Lastly, the counter value obtained through decryption has to be larger than the current value stored in the server database. After this exchange, the server updates its counter with the value just received.

COMMENTS

  • The OTP is an encryption of a triple <sid, cpt, npr>. It is modelled here as a randomized encryption of a pair <sid, cpt>. According to the specification in [1], AES is used.

  • In [1], they “over-approximate in the case that the Yubikey increases the session token by allowing the adversary to instantiate the rule for any counter value that is higher than the previous one”. Here, we model the incrementation by 1 of the counter.

SECURITY PROPERTIES

The 3 security properties as stated in [1].

  • Property 1: absence of replay attacks.
  • Property 2: injective correspondence.
  • Property 3: monotonicity.

[1] R. Künnemann, “Foundations for analyzing security APIs in the symbolic and computational model’, 2014.

abstract startplug : message
abstract endplug : message
abstract startpress : message
abstract accept : message
abstract pid : index -> message

name sid : index -> message
name nonce: index * index -> message.
global axiom namelength_sid {'P:system} @system:(set:'P; equiv:None) :
[forall (i:index), len (sid i) = namelength_message]
global axiom namelength_nonce {'P:system} @system:(set:'P; equiv:None) :
[forall (i:index * index), len (nonce i) = namelength_message]

Public constants (abstract) and names used in the protocol.

senc enc,dec
name k : index -> message
name npr: index * index -> message.
global axiom namelength_k {'P:system} @system:(set:'P; equiv:None) :
[forall (i:index), len (k i) = namelength_message]
global axiom namelength_npr {'P:system} @system:(set:'P; equiv:None) :
[forall (i:index * index), len (npr i) = namelength_message]

Symmetric encryption scheme, using the secret key k (with index arity 1 so that each YubiKey is associated to a key) and the random npr (with index arity 2 so that each session of a YubiKey uses a new random name).

abstract myzero : message
abstract myone : message
abstract mySucc : message -> message
abstract orderOk : message
abstract (~<) : message -> message -> message.

Public constants and public functions used to model counter values.

mutable YCpt(i:index): message = myzero
mutable SCpt(i:index): message = myzero.

Mutable cells for the YubiKey and the server, initialized with myzero.

channel cT
channel cR.

Communication channels used in the protocol.

process yubikeyplug(i:index,j:index) =
in(cT, x1);
if x1 = startplug then
YCpt(i) := mySucc(YCpt(i));
out(cT,endplug).
process yubikeyplug (i,j:index) =
in(cT,x1);
if x1 = startplug then
YCpt(i) := mySucc (YCpt i@τ); out(cT,endplug); null

When the key is plugged, its counter is incremented.

process yubikeypress(i:index,j:index) =
in(cT,x2);
if x2 = startpress then
let cpt = YCpt(i) in
YCpt(i) := mySucc(YCpt(i));
out(cT,<pid(i),<nonce(i,j),enc(<sid(i),cpt>,npr(i,j),k(i))>>).
process yubikeypress (i,j:index) =
in(cT,x2);
if x2 = startpress then
let cpt : message = YCpt i@τ in
YCpt(i) := mySucc (YCpt i@τ);
out(cT,<pid i,<nonce (i, j),enc (<sid i,cpt>, npr (i, j), k i)>>);
null

When the key is pressed, an OTP is sent with the current value of the counter and the counter is incremented.

process server(ii:index) =
in(cR,y1);
try find i such that fst(y1) = pid(i) in
(if dec(snd(snd(y1)),k(i)) <> fail
&& SCpt(i) ~< snd(dec(snd(snd(y1)),k(i))) = orderOk
then
SCpt(i) := snd(dec(snd(snd(y1)),k(i)));
out(cR,accept)).
process server (ii:index) =
in(cR,y1);
find (i) such that fst y1 = pid i in
if dec (snd (snd y1), k i) <> fail &&
SCpt i@τ ~< snd (dec (snd (snd y1), k i)) = orderOk then
SCpt(i) := snd (dec (snd (snd y1), k i)); out(cR,accept); null

When the server receives a message, it checks whether it corresponds to a pid in its database, and checks also that the counter inside the OTP is strictly greater than the counter associated to the token. If so, the value inside the OTP is used to update the database. Now, the counter value associated to this token is this new value.

system
((!_i !_j Plug: yubikeyplug(i,j))
| (!_i !_j Press: yubikeypress(i,j))
| (!_ii S: server(ii))).
Typed-check process:

( !_i( !_j( Plug: yubikeyplug i j)) ) |
( !_i( !_j( Press: yubikeypress i j)) ) |
!_ii( S: server ii)

Added action dependencies lemmas:

axiom mutex_S2_S1 {'P:system[like default]} @system:(set:'P; equiv:None) :
forall (ii,i:index), not happens(S2(ii)) || not happens(S1(ii, i))
axiom mutex_S2_S {'P:system[like default]} @system:(set:'P; equiv:None) :
forall (ii,i:index), not happens(S2(ii)) || not happens(S(ii, i))
axiom mutex_S1_S2 {'P:system[like default]} @system:(set:'P; equiv:None) :
forall (ii,i:index), not happens(S1(ii, i)) || not happens(S2(ii))
axiom mutex_S1_S {'P:system[like default]} @system:(set:'P; equiv:None) :
forall (ii,i,i0:index), not happens(S1(ii, i)) || not happens(S(ii, i0))
axiom mutex_S_S2 {'P:system[like default]} @system:(set:'P; equiv:None) :
forall (ii,i:index), not happens(S(ii, i)) || not happens(S2(ii))
axiom mutex_S_S1 {'P:system[like default]} @system:(set:'P; equiv:None) :
forall (ii,i,i0:index), not happens(S(ii, i)) || not happens(S1(ii, i0))
axiom mutex_Press1_Press {'P:system[like default]}
@system:(set:'P; equiv:None) :
forall (i,j:index), not happens(Press1(i, j)) || not happens(Press(i, j))
axiom mutex_Press_Press1 {'P:system[like default]}
@system:(set:'P; equiv:None) :
forall (i,j:index), not happens(Press(i, j)) || not happens(Press1(i, j))
axiom mutex_Plug1_Plug {'P:system[like default]} @system:(set:'P; equiv:None)
: forall (i,j:index), not happens(Plug1(i, j)) || not happens(Plug(i, j))
axiom mutex_Plug_Plug1 {'P:system[like default]} @system:(set:'P; equiv:None)
: forall (i,j:index), not happens(Plug(i, j)) || not happens(Plug1(i, j))
axiom depends_init_S2 {'P:system[like default]} @system:(set:'P; equiv:None)
: forall (ii:index), happens(S2(ii)) => init < S2(ii)
axiom depends_init_S1 {'P:system[like default]} @system:(set:'P; equiv:None)
: forall (ii,i:index), happens(S1(ii, i)) => init < S1(ii, i)
axiom depends_init_S {'P:system[like default]} @system:(set:'P; equiv:None) :
forall (ii,i:index), happens(S(ii, i)) => init < S(ii, i)
axiom depends_init_Press1 {'P:system[like default]}
@system:(set:'P; equiv:None) :
forall (i,j:index), happens(Press1(i, j)) => init < Press1(i, j)
axiom depends_init_Press {'P:system[like default]}
@system:(set:'P; equiv:None) :
forall (i,j:index), happens(Press(i, j)) => init < Press(i, j)
axiom depends_init_Plug1 {'P:system[like default]}
@system:(set:'P; equiv:None) :
forall (i,j:index), happens(Plug1(i, j)) => init < Plug1(i, j)
axiom depends_init_Plug {'P:system[like default]}
@system:(set:'P; equiv:None) :
forall (i,j:index), happens(Plug(i, j)) => init < Plug(i, j)

System after processing:

( !_i(
!_j(
in(cT,x1);
if x1 = startplug then
YCpt(i) := mySucc (YCpt i@τ); Plug: out(cT,endplug); null
else
Plug1: null)) ) |
( !_i(
!_j(
in(cT,x2);
if x2 = startpress then
let cpt : message = YCpt i@τ in
YCpt(i) := mySucc (YCpt i@τ);
Press: out(cT,
<pid i,
<nonce (i, j),enc (<sid i,cpt i j@τ>, npr (i, j), k i)>>);
null
else
Press1: null)) ) |
!_ii(
in(cR,y1);
find (i) such that fst y1 = pid i in
if dec (snd (snd y1), k i) <> fail &&
SCpt i@τ ~< snd (dec (snd (snd y1), k i)) = orderOk then
SCpt(i) := snd (dec (snd (snd y1), k i)); S: out(cR,accept); null
else
S1: null
else
S2: null)

System Empty registered with actions (init).
System default registered with actions
(init,Plug,Plug1,Press,Press1,S,S1,S2).

In the final system, processes can play in parallel an unbounded number of sessions.

include Core. op assoc ['a] (f:'a -> 'a -> 'a) : bool =
forall (x,y,z:'a), f (f x y) z = f x (f y z)
axiom eq_iff {'P:system} @system:(set:'P; equiv:None) :
forall (x,y:bool), (x = y) = (x <=> y)
axiom eq_not {'P:system} @system:(set:'P; equiv:None) :
forall (x,y:bool), (not x = not y) = (x = y)
Goal eq_sym :
(x = y) = (y = x)
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: x,y:'a
----------------------------------------
(x = y) = (y = x)

[> Line 12: by (rewrite) [goal> lemma eq_sym is proved

lemma eq_sym {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (x,y:'a), (x = y) = (y = x)
Exiting proof mode.

Goal neq_sym :
(x <> y) = (y <> x)
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: x,y:'a
----------------------------------------
(x <> y) = (y <> x)

[> Line 15: by (rewrite) [goal> lemma neq_sym is proved

lemma neq_sym {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (x,y:'a), (x <> y) = (y <> x)
Exiting proof mode.

Goal eq_refl_e :
(x = x) = true
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: x:'a
----------------------------------------
(x = x) = true

[> Line 20: by (rewrite) [goal> lemma eq_refl_e is proved

lemma eq_refl_e {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (x:'a), (x = x) = true
Exiting proof mode.

Goal eq_refl :
x = x
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: x:'a
----------------------------------------
x = x

[> Line 26: by (rewrite) [goal> lemma eq_refl is proved

lemma eq_refl {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (x:'a), x = x
Exiting proof mode.

Goal neq_irrefl :
x <> x <=> false
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: x:'a
----------------------------------------
x <> x <=> false

[> Line 29: by (split) [goal> lemma neq_irrefl is proved

lemma neq_irrefl {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (x:'a), x <> x <=> false
Exiting proof mode.

Goal eq_assoc :
((b0 = b1) = b2) = (b0 = (b1 = b2))
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b0,b1,b2:bool
----------------------------------------
((b0 = b1) = b2) = (b0 = (b1 = b2))

[> Line 37: ((have); 1: by (rewrite)) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b0,b1,b2:bool[const]
true_false: (true = false) = false
----------------------------------------
((b0 = b1) = b2) = (b0 = (b1 = b2))

[> Line 38: ((have); 1: by (rewrite)) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b0,b1,b2:bool[const]
false_true: (false = true) = false
true_false: (true = false) = false
----------------------------------------
((b0 = b1) = b2) = (b0 = (b1 = b2))

[> Line 38: ((case);((case);((case);(try (auto))))) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b0,b1,b2:bool[const]
false_true: (false = true) = false
true_false: (true = false) = false
----------------------------------------
not b2 => not b1 => b0 => ((true = false) = false) = (true = (false = false))

[> Line 38: by (rewrite) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b0,b1,b2:bool[const]
false_true: (false = true) = false
true_false: (true = false) = false
----------------------------------------
b2 => not b1 => not b0 => ((false = false) = true) = (false = (false = true))

[> Line 38: by (rewrite) [goal> lemma eq_assoc is proved

lemma eq_assoc {'P:system} @system:(set:'P; equiv:None) :
forall (b0,b1,b2:bool), ((b0 = b1) = b2) = (b0 = (b1 = b2))
Exiting proof mode.

axiom fun_ext {'P:system} @system:(set:'P; equiv:None) ['a 'b] :
forall (f,g:'a -> 'b), (forall (x:'a), f x = g x) => f = g
Goal true_false :
(true = false) = false
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
----------------------------------------
(true = false) = false

[> Line 51: by (rewrite) [goal> lemma true_false is proved

lemma true_false {'P:system} @system:(set:'P; equiv:None) :
(true = false) = false
Exiting proof mode.

Goal false_true :
(false = true) = false
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
----------------------------------------
(false = true) = false

[> Line 57: by (rewrite) [goal> lemma false_true is proved

lemma false_true {'P:system} @system:(set:'P; equiv:None) :
(false = true) = false
Exiting proof mode.

Goal eq_true :
(b = true) = b
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b:bool
----------------------------------------
(b = true) = b

[> Line 61: by (case) [goal> lemma eq_true is proved

lemma eq_true {'P:system} @system:(set:'P; equiv:None) :
forall (b:bool), (b = true) = b
Exiting proof mode.

Goal eq_true2 :
(true = b) = b
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b:bool
----------------------------------------
(true = b) = b

[> Line 65: by (case) [goal> lemma eq_true2 is proved

lemma eq_true2 {'P:system} @system:(set:'P; equiv:None) :
forall (b:bool), (true = b) = b
Exiting proof mode.

axiom not_true {'P:system} @system:(set:'P; equiv:None) : not true = false
axiom not_false {'P:system} @system:(set:'P; equiv:None) : not false = true
Goal not_not :
not (not b) = b
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b:bool
----------------------------------------
not (not b) = b

[> Line 81: by (case) [goal> lemma not_not is proved

lemma not_not {'P:system} @system:(set:'P; equiv:None) :
forall (b:bool), not (not b) = b
Exiting proof mode.

Goal not_eq :
not (x = y) = (x <> y)
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: x,y:'a
----------------------------------------
not (x = y) = (x <> y)

[> Line 86: by (rewrite) [goal> lemma not_eq is proved

lemma not_eq {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (x,y:'a), not (x = y) = (x <> y)
Exiting proof mode.

Goal not_neq :
not (x <> y) = (x = y)
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: x,y:'a
----------------------------------------
not (x <> y) = (x = y)

[> Line 92: by (rewrite) [goal> lemma not_neq is proved

lemma not_neq {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (x,y:'a), not (x <> y) = (x = y)
Exiting proof mode.

Goal not_eqfalse :
(b = false) = not b
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b:bool
----------------------------------------
(b = false) = not b

[> Line 99: by (case) [goal> lemma not_eqfalse is proved

lemma not_eqfalse {'P:system} @system:(set:'P; equiv:None) :
forall (b:bool), (b = false) = not b
Exiting proof mode.

Goal not_impl :
not (a => b) = (a && not b)
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: a,b:bool
----------------------------------------
not (a => b) = (a && not b)

[> Line 104: ((rewrite);((split);(intro))) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Variables: a,b:bool[const]
H: not (a => b)
----------------------------------------
a && not b

[> Line 104: (split) [goal> Focused goal (1/3):
System variables: 'P
System: (set:'P; equiv:None)
Variables: a,b:bool[const]
H: not (a => b)
----------------------------------------
a

[> Line 106: (rewrite) [goal> Focused goal (1/3):
System variables: 'P
System: (set:'P; equiv:None)
Variables: a,b:bool[const]
H: not (a => b)
----------------------------------------
not (not a)

[> Line 107: (intro) [goal> Focused goal (1/3):
System variables: 'P
System: (set:'P; equiv:None)
Variables: a,b:bool[const]
H: not (a => b)
Hna: not a
----------------------------------------
false

[> Line 108: by (apply) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Variables: a,b:bool[const]
H: not (a => b)
----------------------------------------
not b

[> Line 109: (intro) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Variables: a,b:bool[const]
H: not (a => b)
Hb: b
----------------------------------------
false

[> Line 110: by (apply) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: a,b:bool[const]
H: a && not b
----------------------------------------
not (a => b)

[> Line 111: (intro) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: a,b:bool[const]
H: a && not b
Hi: a => b
----------------------------------------
false

[> Line 112: (destruct) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: a,b:bool[const]
Ha: a
Hi: a => b
Hnb: not b
----------------------------------------
false

[> Line 113: (apply) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: a,b:bool[const]
Ha: a
Hi: a => b
Hnb: not b
----------------------------------------
b

[> Line 114: by (apply) [goal> lemma not_impl is proved

lemma not_impl {'P:system} @system:(set:'P; equiv:None) :
forall (a,b:bool), not (a => b) = (a && not b)
Exiting proof mode.

Goal eq_false :
((x = y) = false) = (x <> y)
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: x,y:'a
----------------------------------------
((x = y) = false) = (x <> y)

[> Line 121: (rewrite) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: x,y:'a
----------------------------------------
((x = y) = false) = not (x = y)

[> Line 121: ((case);(intro)) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: x,y:'a
_: x = y
----------------------------------------
(true = false) = not true

[> Line 121: (simpl) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: x,y:'a
_: x = y
----------------------------------------
true

[> Line 122: (auto) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: x,y:'a
_: not (x = y)
----------------------------------------
(false = false) = not false

[> Line 122: by (rewrite) [goal> lemma eq_false is proved

lemma eq_false {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (x,y:'a), ((x = y) = false) = (x <> y)
Exiting proof mode.

axiom and_comm {'P:system} @system:(set:'P; equiv:None) :
forall (b,b':bool), (b && b') = (b' && b)
Goal and_dist :
((b0 || b1) && b2) = (b0 && b2 || b1 && b2)
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b0,b1,b2:bool
----------------------------------------
((b0 || b1) && b2) = (b0 && b2 || b1 && b2)

[> Line 132: (rewrite) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b0,b1,b2:bool[const]
----------------------------------------
(b0 || b1) && b2 <=> b0 && b2 || b1 && b2

[> Line 132: by (split) [goal> lemma and_dist is proved

lemma and_dist {'P:system} @system:(set:'P; equiv:None) :
forall (b0,b1,b2:bool), ((b0 || b1) && b2) = (b0 && b2 || b1 && b2)
Exiting proof mode.

axiom and_true_l {'P:system} @system:(set:'P; equiv:None) :
forall (b:bool), (true && b) = b
Goal and_true_r :
(b && true) = b
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b:bool
----------------------------------------
(b && true) = b

[> Line 138: by (rewrite) [goal> lemma and_true_r is proved

lemma and_true_r {'P:system} @system:(set:'P; equiv:None) :
forall (b:bool), (b && true) = b
Exiting proof mode.

axiom and_false_l {'P:system} @system:(set:'P; equiv:None) :
forall (b:bool), (false && b) = false
Goal and_false_r :
(b && false) = false
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b:bool
----------------------------------------
(b && false) = false

[> Line 145: by (rewrite) [goal> lemma and_false_r is proved

lemma and_false_r {'P:system} @system:(set:'P; equiv:None) :
forall (b:bool), (b && false) = false
Exiting proof mode.

Goal and_double :
(b && b) = b
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b:bool
----------------------------------------
(b && b) = b

[> Line 150: by (case) [goal> lemma and_double is proved

lemma and_double {'P:system} @system:(set:'P; equiv:None) :
forall (b:bool), (b && b) = b
Exiting proof mode.

axiom or_comm {'P:system} @system:(set:'P; equiv:None) :
forall (b,b':bool), (b || b') = (b' || b)
Goal or_dist :
((b0 || b2) && (b1 || b2)) = (b0 && b1 || b2)
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b0,b1,b2:bool
----------------------------------------
((b0 || b2) && (b1 || b2)) = (b0 && b1 || b2)

[> Line 158: (rewrite) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b0,b1,b2:bool[const]
----------------------------------------
(b0 || b2) && (b1 || b2) <=> b0 && b1 || b2

[> Line 158: by (split) [goal> lemma or_dist is proved

lemma or_dist {'P:system} @system:(set:'P; equiv:None) :
forall (b0,b1,b2:bool), ((b0 || b2) && (b1 || b2)) = (b0 && b1 || b2)
Exiting proof mode.

axiom or_false_l {'P:system} @system:(set:'P; equiv:None) :
forall (b:bool), (false || b) = b
Goal or_false_r :
(b || false) = b
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b:bool
----------------------------------------
(b || false) = b

[> Line 164: by (rewrite) [goal> lemma or_false_r is proved

lemma or_false_r {'P:system} @system:(set:'P; equiv:None) :
forall (b:bool), (b || false) = b
Exiting proof mode.

axiom or_true_l {'P:system} @system:(set:'P; equiv:None) :
forall (b:bool), (true || b) = true
Goal or_true_r :
(b || true) = true
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b:bool
----------------------------------------
(b || true) = true

[> Line 171: by (rewrite) [goal> lemma or_true_r is proved

lemma or_true_r {'P:system} @system:(set:'P; equiv:None) :
forall (b:bool), (b || true) = true
Exiting proof mode.

Goal or_double :
(b || b) = b
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b:bool
----------------------------------------
(b || b) = b

[> Line 175: by (case) [goal> lemma or_double is proved

lemma or_double {'P:system} @system:(set:'P; equiv:None) :
forall (b:bool), (b || b) = b
Exiting proof mode.

Goal impl_charac :
(b => b') = (not b || b')
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b,b':bool
----------------------------------------
(b => b') = (not b || b')

[> Line 182: (((rewrite);((split);((case);(case))));(intro)) [goal> lemma impl_charac is proved

lemma impl_charac {'P:system} @system:(set:'P; equiv:None) :
forall (b,b':bool), (b => b') = (not b || b')
Exiting proof mode.

Goal impl_false_l :
(false => b) = true
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b:bool
----------------------------------------
(false => b) = true

[> Line 186: by ((rewrite);(case)) [goal> lemma impl_false_l is proved

lemma impl_false_l {'P:system} @system:(set:'P; equiv:None) :
forall (b:bool), (false => b) = true
Exiting proof mode.

Goal impl_true_r :
(b => true) = true
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b:bool
----------------------------------------
(b => true) = true

[> Line 190: (auto) [goal> lemma impl_true_r is proved

lemma impl_true_r {'P:system} @system:(set:'P; equiv:None) :
forall (b:bool), (b => true) = true
Exiting proof mode.

Goal impl_true_l :
(true => b) = b
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b:bool
----------------------------------------
(true => b) = b

[> Line 194: by (rewrite) [goal> lemma impl_true_l is proved

lemma impl_true_l {'P:system} @system:(set:'P; equiv:None) :
forall (b:bool), (true => b) = b
Exiting proof mode.

Goal impl_contra :
(b => c) = (not c => not b)
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b,c:bool
----------------------------------------
(b => c) = (not c => not b)

[> Line 200: (rewrite) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b,c:bool[const]
----------------------------------------
(not b || c) = (c || not b)

[> Line 201: by (rewrite) [goal> lemma impl_contra is proved

lemma impl_contra {'P:system} @system:(set:'P; equiv:None) :
forall (b,c:bool), (b => c) = (not c => not b)
Exiting proof mode.

Goal not_and :
not (a && b) = (not a || not b)
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: a,b:bool
----------------------------------------
not (a && b) = (not a || not b)

[> Line 208: (rewrite) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: a,b:bool[const]
----------------------------------------
not (a && b) <=> not a || not b

[> Line 210: (((case);(case));(intro)) [goal> lemma not_and is proved

lemma not_and {'P:system} @system:(set:'P; equiv:None) :
forall (a,b:bool), not (a && b) = (not a || not b)
Exiting proof mode.

Goal not_or :
not (a || b) = (not a && not b)
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: a,b:bool
----------------------------------------
not (a || b) = (not a && not b)

[> Line 214: (rewrite) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: a,b:bool[const]
----------------------------------------
not (a || b) <=> not a && not b

[> Line 216: (((case);(case));(intro)) [goal> lemma not_or is proved

lemma not_or {'P:system} @system:(set:'P; equiv:None) :
forall (a,b:bool), not (a || b) = (not a && not b)
Exiting proof mode.

Goal if_true :
b => if b then x else y = x
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: b:bool,x,y:'a
----------------------------------------
b => if b then x else y = x

[> Line 225: (intro) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: b:bool[const],x,y:'a
H: b
----------------------------------------
if b then x else y = x

[> Line 226: (case) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: b:bool[const],x,y:'a
H: b
----------------------------------------
b && if b then x else y = x => x = x

[> Line 227: (auto) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: b:bool[const],x,y:'a
H: b
----------------------------------------
not b && if b then x else y = y => y = x

[> Line 227: (intro) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: b:bool[const],x,y:'a
H: b
HH: not b
_: if b then x else y = y
----------------------------------------
y = x

[> Line 228: by (have) [goal> lemma if_true is proved

lemma if_true {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (b:bool,x,y:'a), b => if b then x else y = x
Exiting proof mode.

Goal if_true0 :
if true then x else y = x
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: x,y:'a
----------------------------------------
if true then x else y = x

[> Line 233: by (rewrite) [goal> lemma if_true0 is proved

lemma if_true0 {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (x,y:'a), if true then x else y = x
Exiting proof mode.

Goal if_false :
not b => if b then x else y = y
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: b:bool,x,y:'a
----------------------------------------
not b => if b then x else y = y

[> Line 241: ((intro);(case)) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: b:bool[const],x,y:'a
H: not b
----------------------------------------
b && if b then x else y = x => x = y

[> Line 241: (intro) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: b:bool[const],x,y:'a
H: not b
H1: b
H2: if b then x else y = x
----------------------------------------
x = y

[> Line 242: by (rewrite) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: b:bool[const],x,y:'a
H: not b
----------------------------------------
not b && if b then x else y = y => y = y

[> Line 244: (auto) [goal> lemma if_false is proved

lemma if_false {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (b:bool,x,y:'a), not b => if b then x else y = y
Exiting proof mode.

Goal if_false0 :
if false then x else y = y
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: x,y:'a
----------------------------------------
if false then x else y = y

[> Line 250: by (rewrite) [goal> lemma if_false0 is proved

lemma if_false0 {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (x,y:'a), if false then x else y = y
Exiting proof mode.

Goal if_then_then :
if b then (if b' then x else y) else y = if (b && b') then x else y
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: b,b':bool,x,y:'a
----------------------------------------
if b then (if b' then x else y) else y = if (b && b') then x else y

[> Line 257: by ((case);(case)) [goal> lemma if_then_then is proved

lemma if_then_then {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (b,b':bool,x,y:'a),
if b then (if b' then x else y) else y = if (b && b') then x else y
Exiting proof mode.

Goal if_then_or :
if b0 then m0 else if b1 then m0 else m1 = if (b0 || b1) then m0 else m1
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b0,b1:bool,m0,m1:message
----------------------------------------
if b0 then m0 else if b1 then m0 else m1 = if (b0 || b1) then m0 else m1

[> Line 264: ((have); 1: by (auto)) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b0,b1:bool[const],m0,m1:message
_: b0
----------------------------------------
if b0 then m0 else if b1 then m0 else m1 = if (b0 || b1) then m0 else m1

[> Line 264: ((rewrite);(intro)) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b0,b1:bool[const],m0,m1:message
_: b0
----------------------------------------
m0 = if (b0 || b1) then m0 else m1

[> Line 264: ((rewrite);(intro)) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b0,b1:bool[const],m0,m1:message
_: not b0
----------------------------------------
if b0 then m0 else if b1 then m0 else m1 = if (b0 || b1) then m0 else m1

[> Line 265: ((have); 1: by (auto)) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b0,b1:bool[const],m0,m1:message
_: b1
_: not b0
----------------------------------------
if b0 then m0 else if b1 then m0 else m1 = if (b0 || b1) then m0 else m1

[> Line 265: ((rewrite);(intro)) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b0,b1:bool[const],m0,m1:message
_: b1
_: not b0
----------------------------------------
if b1 then m0 else m1 = if (b0 || b1) then m0 else m1

[> Line 265: ((rewrite);(intro)) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b0,b1:bool[const],m0,m1:message
_: not b1
_: not b0
----------------------------------------
if b0 then m0 else if b1 then m0 else m1 = if (b0 || b1) then m0 else m1

[> Line 267: ((rewrite);(intro)) [goal> lemma if_then_or is proved

lemma if_then_or {'P:system} @system:(set:'P; equiv:None) :
forall (b0,b1:bool,m0,m1:message),
if b0 then m0 else if b1 then m0 else m1 = if (b0 || b1) then m0 else m1
Exiting proof mode.

Goal if_then_implies :
if b then (if b' then x else y) else z =
if b then (if (b => b') then x else y) else z
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: b,b':bool,x,y,z:'a
----------------------------------------
if b then (if b' then x else y) else z =
if b then (if (b => b') then x else y) else z

[> Line 273: ((case);((intro);((case);((intro);((simpl);(try (auto))))))) [goal> lemma if_then_implies is proved

lemma if_then_implies {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (b,b':bool,x,y,z:'a),
if b then (if b' then x else y) else z =
if b then (if (b => b') then x else y) else z
Exiting proof mode.

Goal if_same :
if b then x else x = x
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: b:bool,x:'a
----------------------------------------
if b then x else x = x

[> Line 280: by (case) [goal> lemma if_same is proved

lemma if_same {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (b:bool,x:'a), if b then x else x = x
Exiting proof mode.

Goal if_then :
b = b' => if b then (if b' then x else y) else z = if b then x else z
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: b,b':bool,x,y,z:'a
----------------------------------------
b = b' => if b then (if b' then x else y) else z = if b then x else z

[> Line 289: by ((intro);(case)) [goal> lemma if_then is proved

lemma if_then {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (b,b':bool,x,y,z:'a),
b = b' => if b then (if b' then x else y) else z = if b then x else z
Exiting proof mode.

Goal if_then_inv :
if b then m0 else m1 = if b then (if b then m0) else m1
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b:bool,m0,m1:message
----------------------------------------
if b then m0 else m1 = if b then (if b then m0) else m1

[> Line 295: (auto) [goal> lemma if_then_inv is proved

lemma if_then_inv {'P:system} @system:(set:'P; equiv:None) :
forall (b:bool,m0,m1:message),
if b then m0 else m1 = if b then (if b then m0) else m1
Exiting proof mode.

Goal if_else :
b = b' => if b then x else if b' then y else z = if b then x else z
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: b,b':bool,x,y,z:'a
----------------------------------------
b = b' => if b then x else if b' then y else z = if b then x else z

[> Line 303: by ((intro);(case)) [goal> lemma if_else is proved

lemma if_else {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (b,b':bool,x,y,z:'a),
b = b' => if b then x else if b' then y else z = if b then x else z
Exiting proof mode.

Goal if_else_inv :
if b then m0 else m1 = if b then m0 else if not b then m1
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b:bool,m0,m1:message
----------------------------------------
if b then m0 else m1 = if b then m0 else if not b then m1

[> Line 308: by (case) [goal> lemma if_else_inv is proved

lemma if_else_inv {'P:system} @system:(set:'P; equiv:None) :
forall (b:bool,m0,m1:message),
if b then m0 else m1 = if b then m0 else if not b then m1
Exiting proof mode.

Goal if_push :
if b then m0 else m1 = if b then (if b then m0) else if not b then m1
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: b:bool,m0,m1:message
----------------------------------------
if b then m0 else m1 = if b then (if b then m0) else if not b then m1

[> Line 312: by (rewrite) [goal> lemma if_push is proved

lemma if_push {'P:system} @system:(set:'P; equiv:None) :
forall (b:bool,m0,m1:message),
if b then m0 else m1 = if b then (if b then m0) else if not b then m1
Exiting proof mode.

Goal if_then_not :
b = not b' => if b then (if b' then x else y) else z = if b then y else z
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: b,b':bool,x,y,z:'a
----------------------------------------
b = not b' => if b then (if b' then x else y) else z = if b then y else z

[> Line 320: by ((intro);(case)) [goal> lemma if_then_not is proved

lemma if_then_not {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (b,b':bool,x,y,z:'a),
b = not b' => if b then (if b' then x else y) else z = if b then y else z
Exiting proof mode.

Goal if_else_not :
b = not b' => if b then x else if b' then y else z = if b then x else y
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: b,b':bool,x,y,z:'a
----------------------------------------
b = not b' => if b then x else if b' then y else z = if b then x else y

[> Line 329: by ((intro);(case)) [goal> lemma if_else_not is proved

lemma if_else_not {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (b,b':bool,x,y,z:'a),
b = not b' => if b then x else if b' then y else z = if b then x else y
Exiting proof mode.

Goal if_app :
f (if c then x else y) = if c then f x else f y
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: c:bool,f:'a -> 'b,x,y:'a
----------------------------------------
f (if c then x else y) = if c then f x else f y

[> Line 334: by (case) [goal> lemma if_app is proved

lemma if_app {'P:system} @system:(set:'P; equiv:None) ['a 'b] :
forall (f:'a -> 'b,c:bool,x,y:'a),
f (if c then x else y) = if c then f x else f y
Exiting proof mode.

Goal fst_pair :
fst <x,y> = x
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: x,y:message
----------------------------------------
fst <x,y> = x

[> Line 340: (auto) [goal> lemma fst_pair is proved

lemma fst_pair {'P:system} @system:(set:'P; equiv:None) :
forall (x,y:message), fst <x,y> = x
Exiting proof mode.

Goal snd_pair :
snd <x,y> = y
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: x,y:message
----------------------------------------
snd <x,y> = y

[> Line 344: (auto) [goal> lemma snd_pair is proved

lemma snd_pair {'P:system} @system:(set:'P; equiv:None) :
forall (x,y:message), snd <x,y> = y
Exiting proof mode.

Goal iff_def :
(x <=> y) = ((x => y) && (y => x))
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: x,y:bool
----------------------------------------
(x <=> y) = ((x => y) && (y => x))

[> Line 353: ((rewrite);(split)) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Variables: x,y:bool[const]
----------------------------------------
x <=> y => (x => y) && (y => x)

[> Line 353: by (intro) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: x,y:bool[const]
----------------------------------------
(x => y) && (y => x) => x <=> y

[> Line 355: (auto) [goal> lemma iff_def is proved

lemma iff_def {'P:system} @system:(set:'P; equiv:None) :
forall (x,y:bool), (x <=> y) = ((x => y) && (y => x))
Exiting proof mode.

Goal iff_refl :
(x <=> x) = true
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: x:bool
----------------------------------------
(x <=> x) = true

[> Line 359: by (rewrite) [goal> lemma iff_refl is proved

lemma iff_refl {'P:system} @system:(set:'P; equiv:None) :
forall (x:bool), (x <=> x) = true
Exiting proof mode.

Goal iff_sym :
(x <=> y) = (y <=> x)
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: x,y:bool
----------------------------------------
(x <=> y) = (y <=> x)

[> Line 366: by (rewrite) [goal> lemma iff_sym is proved

lemma iff_sym {'P:system} @system:(set:'P; equiv:None) :
forall (x,y:bool), (x <=> y) = (y <=> x)
Exiting proof mode.

Goal true_iff_false :
(true <=> false) = false
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
----------------------------------------
(true <=> false) = false

[> Line 370: by (rewrite) [goal> lemma true_iff_false is proved

lemma true_iff_false {'P:system} @system:(set:'P; equiv:None) :
(true <=> false) = false
Exiting proof mode.

Goal false_iff_true :
(false <=> true) = false
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
----------------------------------------
(false <=> true) = false

[> Line 376: by (rewrite) [goal> lemma false_iff_true is proved

lemma false_iff_true {'P:system} @system:(set:'P; equiv:None) :
(false <=> true) = false
Exiting proof mode.

Goal contra_iff :
(not x <=> y) = (x <=> not y)
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: x,y:bool
----------------------------------------
(not x <=> y) = (x <=> not y)

[> Line 384: (rewrite) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: x,y:bool[const]
----------------------------------------
(not x <=> y) <=> (x <=> not y)

[> Line 385: ((split);by (rewrite)) [goal> lemma contra_iff is proved

lemma contra_iff {'P:system} @system:(set:'P; equiv:None) :
forall (x,y:bool), (not x <=> y) = (x <=> not y)
Exiting proof mode.

Goal exists_false1 :
(exists (a:'a), false) = false
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
----------------------------------------
(exists (a:'a), false) = false

[> Line 392: by (rewrite) [goal> lemma exists_false1 is proved

lemma exists_false1 {'P:system} @system:(set:'P; equiv:None) ['a] :
(exists (a:'a), false) = false
Exiting proof mode.

Goal exists_false2 :
(exists (a:'a,b:'b), false) = false
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
----------------------------------------
(exists (a:'a,b:'b), false) = false

[> Line 396: by (rewrite) [goal> lemma exists_false2 is proved

lemma exists_false2 {'P:system} @system:(set:'P; equiv:None) ['a 'b] :
(exists (a:'a,b:'b), false) = false
Exiting proof mode.

Goal exists_false3 :
(exists (a:'a,b:'b,c:'c), false) = false
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b, 'c
----------------------------------------
(exists (a:'a,b:'b,c:'c), false) = false

[> Line 400: by (rewrite) [goal> lemma exists_false3 is proved

lemma exists_false3 {'P:system} @system:(set:'P; equiv:None) ['a 'b 'c] :
(exists (a:'a,b:'b,c:'c), false) = false
Exiting proof mode.

Goal exists_false4 :
(exists (a:'a,b:'b,c:'c,d:'d), false) = false
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b, 'c, 'd
----------------------------------------
(exists (a:'a,b:'b,c:'c,d:'d), false) = false

[> Line 404: by (rewrite) [goal> lemma exists_false4 is proved

lemma exists_false4 {'P:system} @system:(set:'P; equiv:None) ['a 'b 'c 'd] :
(exists (a:'a,b:'b,c:'c,d:'d), false) = false
Exiting proof mode.

Goal exists_false5 :
(exists (a:'a,b:'b,c:'c,d:'d,e:'e), false) = false
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b, 'c, 'd, 'e
----------------------------------------
(exists (a:'a,b:'b,c:'c,d:'d,e:'e), false) = false

[> Line 408: by (rewrite) [goal> lemma exists_false5 is proved

lemma exists_false5 {'P:system} @system:(set:'P; equiv:None)
['a 'b 'c 'd 'e] : (exists (a:'a,b:'b,c:'c,d:'d,e:'e), false) = false
Exiting proof mode.

Goal exists_false6 :
(exists (a:'a,b:'b,c:'c,d:'d,e:'e,f:'f), false) = false
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b, 'c, 'd, 'e, 'f
----------------------------------------
(exists (a:'a,b:'b,c:'c,d:'d,e:'e,f:'f), false) = false

[> Line 412: by (rewrite) [goal> lemma exists_false6 is proved

lemma exists_false6 {'P:system} @system:(set:'P; equiv:None)
['a 'b 'c 'd 'e 'f] :
(exists (a:'a,b:'b,c:'c,d:'d,e:'e,f:'f), false) = false
Exiting proof mode.

Goal forall_true1 :
(forall (a:'a), true) = true
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
----------------------------------------
(forall (a:'a), true) = true

[> Line 422: (auto) [goal> lemma forall_true1 is proved

lemma forall_true1 {'P:system} @system:(set:'P; equiv:None) ['a] :
(forall (a:'a), true) = true
Exiting proof mode.

Goal forall_true2 :
(forall (a:'a,b:'b), true) = true
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
----------------------------------------
(forall (a:'a,b:'b), true) = true

[> Line 426: (auto) [goal> lemma forall_true2 is proved

lemma forall_true2 {'P:system} @system:(set:'P; equiv:None) ['a 'b] :
(forall (a:'a,b:'b), true) = true
Exiting proof mode.

Goal forall_true3 :
(forall (a:'a,b:'b,c:'c), true) = true
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b, 'c
----------------------------------------
(forall (a:'a,b:'b,c:'c), true) = true

[> Line 430: (auto) [goal> lemma forall_true3 is proved

lemma forall_true3 {'P:system} @system:(set:'P; equiv:None) ['a 'b 'c] :
(forall (a:'a,b:'b,c:'c), true) = true
Exiting proof mode.

Goal forall_true4 :
(forall (a:'a,b:'b,c:'c,d:'d), true) = true
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b, 'c, 'd
----------------------------------------
(forall (a:'a,b:'b,c:'c,d:'d), true) = true

[> Line 434: (auto) [goal> lemma forall_true4 is proved

lemma forall_true4 {'P:system} @system:(set:'P; equiv:None) ['a 'b 'c 'd] :
(forall (a:'a,b:'b,c:'c,d:'d), true) = true
Exiting proof mode.

Goal forall_true5 :
(forall (a:'a,b:'b,c:'c,d:'d,e:'e), true) = true
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b, 'c, 'd, 'e
----------------------------------------
(forall (a:'a,b:'b,c:'c,d:'d,e:'e), true) = true

[> Line 438: (auto) [goal> lemma forall_true5 is proved

lemma forall_true5 {'P:system} @system:(set:'P; equiv:None)
['a 'b 'c 'd 'e] : (forall (a:'a,b:'b,c:'c,d:'d,e:'e), true) = true
Exiting proof mode.

Goal forall_true6 :
(forall (a:'a,b:'b,c:'c,d:'d,e:'e,f:'f), true) = true
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b, 'c, 'd, 'e, 'f
----------------------------------------
(forall (a:'a,b:'b,c:'c,d:'d,e:'e,f:'f), true) = true

[> Line 442: (auto) [goal> lemma forall_true6 is proved

lemma forall_true6 {'P:system} @system:(set:'P; equiv:None)
['a 'b 'c 'd 'e 'f] : (forall (a:'a,b:'b,c:'c,d:'d,e:'e,f:'f), true) = true
Exiting proof mode.

axiom len_zeroes {'P:system} @system:(set:'P; equiv:None) :
forall (x:message), len (zeroes x) = len x
Goal f_apply :
x = y => f x = f y
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: f:'a -> 'b,x,y:'a
----------------------------------------
x = y => f x = f y

[> Line 455: by (intro) [goal> lemma f_apply is proved

lemma f_apply {'P:system} @system:(set:'P; equiv:None) ['a 'b] :
forall (f:'a -> 'b,x,y:'a), x = y => f x = f y
Exiting proof mode.

Goal not_exists_1 :
not exists (a:'a), phi a = forall (a:'a), not (phi a)
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:'a -> bool
----------------------------------------
not exists (a:'a), phi a = forall (a:'a), not (phi a)

[> Line 461: (rewrite) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:'a -> bool
----------------------------------------
not exists (a:'a), phi a <=> forall (a:'a), not (phi a)

[> Line 462: (split) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:'a -> bool
----------------------------------------
not exists (a:'a), phi a => forall (a:'a), not (phi a)

[> Line 463: (intro) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: a:'a,phi:'a -> bool
H: not exists (a:'a), phi a
Hp: phi a
----------------------------------------
false

[> Line 463: (apply) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: a:'a,phi:'a -> bool
H: not exists (a:'a), phi a
Hp: phi a
----------------------------------------
exists (a:'a), phi a

[> Line 465: by (exists) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:'a -> bool
----------------------------------------
(forall (a:'a), not (phi a)) => not exists (a:'a), phi a

[> Line 465: (intro) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: a:'a,phi:'a -> bool
H: forall (a:'a), not (phi a)
Hp: phi a
----------------------------------------
false

[> Line 467: by (have) [goal> lemma not_exists_1 is proved

lemma not_exists_1 {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (phi:'a -> bool),
not exists (a:'a), phi a = forall (a:'a), not (phi a)
Exiting proof mode.

Goal not_exists_2 :
not exists (a:'a,b:'b), phi a b = forall (a:'a,b:'b), not (phi a b)
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: phi:'a -> 'b -> bool
----------------------------------------
not exists (a:'a,b:'b), phi a b = forall (a:'a,b:'b), not (phi a b)

[> Line 473: (rewrite) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: phi:'a -> 'b -> bool
----------------------------------------
not exists (a:'a,b:'b), phi a b <=> forall (a:'a,b:'b), not (phi a b)

[> Line 474: (split) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: phi:'a -> 'b -> bool
----------------------------------------
not exists (a:'a,b:'b), phi a b => forall (a:'a,b:'b), not (phi a b)

[> Line 475: (intro) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: a:'a,b:'b,phi:'a -> 'b -> bool
H: not exists (a:'a,b:'b), phi a b
Hp: phi a b
----------------------------------------
false

[> Line 475: (apply) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: a:'a,b:'b,phi:'a -> 'b -> bool
H: not exists (a:'a,b:'b), phi a b
Hp: phi a b
----------------------------------------
exists (a:'a,b:'b), phi a b

[> Line 477: by (exists) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: phi:'a -> 'b -> bool
----------------------------------------
(forall (a:'a,b:'b), not (phi a b)) => not exists (a:'a,b:'b), phi a b

[> Line 477: (intro) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: a:'a,b:'b,phi:'a -> 'b -> bool
H: forall (a:'a,b:'b), not (phi a b)
Hp: phi a b
----------------------------------------
false

[> Line 479: by (have) [goal> lemma not_exists_2 is proved

lemma not_exists_2 {'P:system} @system:(set:'P; equiv:None) ['a 'b] :
forall (phi:'a -> 'b -> bool),
not exists (a:'a,b:'b), phi a b = forall (a:'a,b:'b), not (phi a b)
Exiting proof mode.

axiom not_forall_1 {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (phi:'a -> bool),
not forall (a:'a), phi a = exists (a:'a), not (phi a)
axiom not_forall_2 {'P:system} @system:(set:'P; equiv:None) ['a 'b] :
forall (phi:'a -> 'b -> bool),
not forall (a:'a,b:'b), phi a b = exists (a:'a,b:'b), not (phi a b)
axiom try_carac_1 {'P:system} @system:(set:'P; equiv:None) ['a 'b] :
forall (phi:'a -> bool,f:'a -> 'b,g:'b),
try find x:'a such that phi x in f x else g =
if (exists (x:'a), phi x) then f (choose phi) else g
Goal choose_spec :
phi x => phi (choose phi)
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:'a -> bool,x:'a
----------------------------------------
phi x => phi (choose phi)

[> Line 505: (intro) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:'a -> bool,x:'a
H: phi x
----------------------------------------
phi (choose phi)

[> Line 508: (have) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:'a -> bool,x:'a
H: phi x
----------------------------------------
phi (choose phi) = if (exists (x:'a), phi x) then phi (choose phi) else false

[> Line 509: ?? [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:'a -> bool,x:'a
H: phi x
----------------------------------------
phi (choose phi) = if (exists (x:'a), phi x) then phi (choose phi) else false

[> Line 509: ((rewrite);(intro)) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:'a -> bool,x:'a
H: phi x
----------------------------------------
exists (x:'a), phi x

[> Line 510: by (exists) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:'a -> bool,x:'a
H: phi x
----------------------------------------
if (exists (x:'a), phi x) then phi (choose phi) else false

[> Line 511: ?? [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:'a -> bool,x:'a
H: phi x
----------------------------------------
if (exists (x:'a), phi x) then phi (choose phi) else false

[> Line 512: (rewrite) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:'a -> bool,x:'a
H: phi x
----------------------------------------
try find x:'a such that phi x in phi x else false

[> Line 513: (case) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:'a -> bool,x:'a
H: phi x
----------------------------------------
(exists (x:'a),
phi x && try find x:'a such that phi x in phi x else false = phi x)
=> try find x:'a such that phi x in phi x else false

[> Line 514: (auto) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:'a -> bool,x:'a
H: phi x
----------------------------------------
(forall (x:'a), not (phi x)) &&
try find x:'a such that phi x in phi x else false = false =>
try find x:'a such that phi x in phi x else false

[> Line 515: ((intro);by (have)) [goal> lemma choose_spec is proved

lemma choose_spec {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (phi:'a -> bool,x:'a), phi x => phi (choose phi)
Exiting proof mode.

Goal try_choose :
phi x => try find x:'a such that phi x in f x else g = f (choose phi)
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: f:'a -> 'b,g:'b,phi:'a -> bool,x:'a
----------------------------------------
phi x => try find x:'a such that phi x in f x else g = f (choose phi)

[> Line 524: (intro) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: f:'a -> 'b,g:'b,phi:'a -> bool,x:'a
H: phi x
----------------------------------------
try find x:'a such that phi x in f x else g = f (choose phi)

[> Line 525: (rewrite) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: f:'a -> 'b,g:'b,phi:'a -> bool,x:'a
H: phi x
----------------------------------------
if (exists (x:'a), phi x) then f (choose phi) else g = f (choose phi)

[> Line 526: ((rewrite);(intro)) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: f:'a -> 'b,g:'b,phi:'a -> bool,x:'a
H: phi x
----------------------------------------
exists (x:'a), phi x

[> Line 527: by (exists) [goal> lemma try_choose is proved

lemma try_choose {'P:system} @system:(set:'P; equiv:None) ['a 'b] :
forall (phi:'a -> bool,f:'a -> 'b,g:'b,x:'a),
phi x => try find x:'a such that phi x in f x else g = f (choose phi)
Exiting proof mode.

Goal forall_exists :
(forall (x:'a), exists (y:'b), phi x y) =
exists (y':'a -> 'b), forall (x:'a), phi x (y' x)
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: phi:'a -> 'b -> bool
----------------------------------------
(forall (x:'a), exists (y:'b), phi x y) =
exists (y':'a -> 'b), forall (x:'a), phi x (y' x)

[> Line 536: ((rewrite);(split)) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: phi:'a -> 'b -> bool
----------------------------------------
(forall (x:'a), exists (y:'b), phi x y) =>
exists (y':'a -> 'b), forall (x:'a), phi x (y' x)

[> Line 537: (intro) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: phi:'a -> 'b -> bool
H: forall (x:'a), exists (y:'b), phi x y
----------------------------------------
exists (y':'a -> 'b), forall (x:'a), phi x (y' x)

[> Line 538: (exists) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: phi:'a -> 'b -> bool
H: forall (x:'a), exists (y:'b), phi x y
----------------------------------------
forall (x:'a), phi x ((fun (x:'a) => choose (fun (y:'b) => phi x y)) x)

[> Line 539: ((intro);(simpl)) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: phi:'a -> 'b -> bool,x:'a
H: forall (x:'a), exists (y:'b), phi x y
----------------------------------------
phi x (choose (fun (y:'b) => phi x y))

[> Line 540: (have) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: phi:'a -> 'b -> bool,x:'a,y:'b
H: forall (x:'a), exists (y:'b), phi x y
Hy: phi x y
----------------------------------------
phi x (choose (fun (y:'b) => phi x y))

[> Line 544: ((have); 1: by (auto)) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: phi:'a -> 'b -> bool,x:'a,y:'b
H: forall (x:'a), exists (y:'b), phi x y
Hy: phi x y
----------------------------------------
(fun (y:'b) => phi x y) (choose (fun (y:'b) => phi x y))

[> Line 545: (apply) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: phi:'a -> 'b -> bool,x:'a,y:'b
H: forall (x:'a), exists (y:'b), phi x y
Hy: phi x y
----------------------------------------
(fun (y:'b) => phi x y) y

[> Line 546: ((simpl);(assumption)) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: phi:'a -> 'b -> bool
----------------------------------------
(exists (y':'a -> 'b), forall (x:'a), phi x (y' x)) =>
forall (x:'a), exists (y:'b), phi x y

[> Line 547: (intro) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: phi:'a -> 'b -> bool,x:'a,y':'a -> 'b
H: forall (x:'a), phi x (y' x)
----------------------------------------
exists (y:'b), phi x y

[> Line 548: (exists) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a, 'b
Variables: phi:'a -> 'b -> bool,x:'a,y':'a -> 'b
H: forall (x:'a), phi x (y' x)
----------------------------------------
phi x (y' x)

[> Line 549: by (apply) [goal> lemma forall_exists is proved

lemma forall_exists {'P:system} @system:(set:'P; equiv:None) ['a 'b] :
forall (phi:'a -> 'b -> bool),
(forall (x:'a), exists (y:'b), phi x y) =
exists (y':'a -> 'b), forall (x:'a), phi x (y' x)
Exiting proof mode.

Goal implies_exists :
(phi => exists (j:'a), psi j) = exists (x:'a), phi => psi x
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:bool,psi:'a -> bool
----------------------------------------
(phi => exists (j:'a), psi j) = exists (x:'a), phi => psi x

[> Line 556: ((rewrite);(split)) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:bool[const],psi:'a -> bool
----------------------------------------
(phi => exists (j:'a), psi j) => exists (x:'a), phi => psi x

[> Line 557: (intro) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:bool[const],psi:'a -> bool
H: phi => exists (j:'a), psi j
----------------------------------------
exists (x:'a), phi => psi x

[> Line 558: (case) [goal> Focused goal (1/3):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:bool[const],psi:'a -> bool
H: phi => exists (j:'a), psi j
----------------------------------------
phi => exists (x:'a), true => psi x

[> Line 559: (intro) [goal> Focused goal (1/3):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:bool[const],psi:'a -> bool
H: phi => exists (j:'a), psi j
phi: phi
----------------------------------------
exists (x:'a), true => psi x

[> Line 560: ((have); 1: by (apply)) [goal> Focused goal (1/3):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:bool[const],psi:'a -> bool,x:'a
H: phi => exists (j:'a), psi j
_: psi x
phi: phi
----------------------------------------
exists (x:'a), true => psi x

[> Line 561: by (exists) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:bool[const],psi:'a -> bool
H: phi => exists (j:'a), psi j
----------------------------------------
not phi => exists (x:'a), false => psi x

[> Line 562: (intro) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:bool[const],psi:'a -> bool
H: phi => exists (j:'a), psi j
_: not phi
----------------------------------------
exists (x:'a), false => psi x

[> Line 563: by (exists) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:bool[const],psi:'a -> bool
----------------------------------------
(exists (x:'a), phi => psi x) => phi => exists (j:'a), psi j

[> Line 564: (intro) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: phi:bool[const],psi:'a -> bool,x:'a
H: phi => psi x
H': phi
----------------------------------------
exists (j:'a), psi j

[> Line 565: by (exists) [goal> lemma implies_exists is proved

lemma implies_exists {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (phi:bool,psi:'a -> bool),
(phi => exists (j:'a), psi j) = exists (x:'a), phi => psi x
Exiting proof mode.

axiom le_trans {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (x,y,z:'a), x <= y => y <= z => x <= z
axiom lt_trans {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (x,y,z:'a), x < y => y < z => x < z
axiom lt_le_trans {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (x,y,z:'a), x < y => y <= z => x < z
axiom le_lt_trans {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (x,y,z:'a), x <= y => y < z => x < z
axiom lt_charac {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (x,y:'a), x < y <=> x <> y && x <= y
axiom le_not_lt_impl_eq {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (x,y:'a), x <= y => not (x < y) => x = y
Goal lt_impl_le :
x < y => x <= y
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: x,y:'a
----------------------------------------
x < y => x <= y

[> Line 580: by (rewrite) [goal> lemma lt_impl_le is proved

lemma lt_impl_le {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (x,y:'a), x < y => x <= y
Exiting proof mode.

Goal not_lt_refl :
not (x < x)
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: x:'a
----------------------------------------
not (x < x)

[> Line 583: (auto) [goal> lemma not_lt_refl is proved

lemma not_lt_refl {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (x:'a), not (x < x)
Exiting proof mode.

Goal lt_irrefl :
x < x <=> false
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Type variables: 'a
Variables: x:'a
----------------------------------------
x < x <=> false

[> Line 586: (auto) [goal> lemma lt_irrefl is proved

lemma lt_irrefl {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (x:'a), x < x <=> false
Exiting proof mode.

axiom le_impl_eq_lt {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (x,y:'a), x <= y => x = y || x < y
axiom le_refl_index {'P:system} @system:(set:'P; equiv:None) :
forall (x:index), x <= x
Goal le_refl_index_eq :
x <= x = true
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: x:index
----------------------------------------
x <= x = true

[> Line 599: by (rewrite) [goal> lemma le_refl_index_eq is proved

lemma le_refl_index_eq {'P:system} @system:(set:'P; equiv:None) :
forall (x:index), x <= x = true
Exiting proof mode.

Goal le_pred_lt :
t <= pred t' = t < t'
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: t,t':timestamp
----------------------------------------
t <= pred t' = t < t'

[> Line 603: by (rewrite) [goal> lemma le_pred_lt is proved

lemma le_pred_lt {'P:system} @system:(set:'P; equiv:None) :
forall (t,t':timestamp), t <= pred t' = t < t'
Exiting proof mode.

Goal neq_le_pred_le :
t <> t' => t <= t' = t <= pred t'
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: t,t':timestamp
----------------------------------------
t <> t' => t <= t' = t <= pred t'

[> Line 607: by (rewrite) [goal> lemma neq_le_pred_le is proved

lemma neq_le_pred_le {'P:system} @system:(set:'P; equiv:None) :
forall (t,t':timestamp), t <> t' => t <= t' = t <= pred t'
Exiting proof mode.

axiom le_lt {'P:system} @system:(set:'P; equiv:None) ['a] :
forall (x,x':'a), x <> x' => x <= x' = x < x'
[warning>Loaded "Logic.sp".
<]axiom empty_set_is_empty {'P:system} @system:(set:'P; equiv:None) :
forall (x:message), not (mem x empty_set)
[warning>Loaded "Set.sp".
<]new predicate:
predicate (|>) {set:system} ['a 'b] {set: u:'a,m:'b} =
Exists (f:'a -> 'b[adv, glob]), [f u = m]
new predicate:
predicate (|1>) {set:system} ['a 'b 'c] {set: u:'a -> 'b,m:'a -> 'c} =
Exists (f:'b -> 'c[adv, glob]), [forall (x:'a), f (u x) = m x]
[warning>Loaded "DeductionSyntax.sp".
<]Goal unnamed1 :
forall u:'b[glob],v:'a -> 'c[glob],
Let u0 = fun (_x:'a) => u in
$(u0 |1>{Empty} fun (x:'a) => v x) -> $(u |>{Empty} fun (x:'a) => v x)
[goal> Focused goal (1/1):
Systems: Empty
Type variables: 'a, 'b, 'c
Variables: u:'b[glob],v:'a -> 'c[glob]
----------------------------------------
Let u0 = fun (_x:'a) => u in
$(u0 |1> fun (x:'a) => v x) -> $(u |> fun (x:'a) => v x)

[> Line 11: (intro) [goal> Focused goal (1/1):
Systems: Empty
Type variables: 'a, 'b, 'c
Variables: u:'b[glob],v:'a -> 'c[glob]
H: $(u0 |1> fun (x:'a) => v x)
u0 := fun (_x:'a) => u
----------------------------------------
$(u |> fun (x:'a) => v x)

[> Line 12: (rewrite) [goal> Focused goal (1/1):
Systems: Empty
Type variables: 'a, 'b, 'c
Variables: u:'b[glob],v:'a -> 'c[glob]
H: $(u0 |1> fun (x:'a) => v x)
u0 := fun (_x:'a) => u
----------------------------------------
Exists (f:'b -> 'a -> 'c[adv, glob]), [f u = (fun (x:'a) => v x)]

[> Line 13: (rewrite) [goal> Focused goal (1/1):
Systems: Empty
Type variables: 'a, 'b, 'c
Variables: u:'b[glob],v:'a -> 'c[glob]
H: Exists (f:'b -> 'c[adv, glob]),
[forall (x:'a), f (u0 x) = (fun (x:'a) => v x) x]
u0 := fun (_x:'a) => u
----------------------------------------
Exists (f:'b -> 'a -> 'c[adv, glob]), [f u = (fun (x:'a) => v x)]

[> Line 14: (destruct) [goal> Focused goal (1/1):
Systems: Empty
Type variables: 'a, 'b, 'c
Variables: f:'b -> 'c[adv, glob],u:'b[glob],v:'a -> 'c[glob]
H: [forall (x:'a), f (u0 x) = (fun (x:'a) => v x) x]
u0 := fun (_x:'a) => u
----------------------------------------
Exists (f:'b -> 'a -> 'c[adv, glob]), [f u = (fun (x:'a) => v x)]

[> Line 14: ((exists);(intro)) [goal> Focused goal (1/1):
System: Empty
Type variables: 'a, 'b, 'c
Variables: f:'b -> 'c[adv, glob],u:'b[glob],v:'a -> 'c[glob]
H: [forall (x:'a), f (u0 x) = v x]
u0 := fun (_x:'a) => u
----------------------------------------
(fun (x:'a) => f u) = (fun (x:'a) => v x)

[> Line 16: ((apply);(intro)) [goal> Focused goal (1/1):
System: Empty
Type variables: 'a, 'b, 'c
Variables: f:'b -> 'c[adv, glob],u:'b[glob],v:'a -> 'c[glob],x:'a
H: [forall (x:'a), f (u0 x) = v x]
u0 := fun (_x:'a) => u
----------------------------------------
f u = v x

[> Line 17: (rewrite) [goal> Focused goal (1/1):
System: Empty
Type variables: 'a, 'b, 'c
Variables: f:'b -> 'c[adv, glob],u:'b[glob],v:'a -> 'c[glob],x:'a
H: [forall (x:'a), f u = v x]
u0 := fun (_x:'a) => u
----------------------------------------
f u = v x

[> Line 18: (apply) [goal> lemma unnamed1 is proved

global lemma unnamed1 @system:Empty ['a 'b 'c] :
Forall (u:'b[glob],v:'a -> 'c[glob]),
Let u0 = fun (_x:'a) => u in
$(u0 |1>{Empty} fun (x:'a) => v x) -> $(u |>{Empty} fun (x:'a) => v x)
Exiting proof mode.

global axiom frame_from_frame {P:system} @system:(set:P; equiv:None) :
$(fun (t:timestamp) => frame@t |1>{P}
fun (t,t':timestamp) => if (t' <= t) then frame@t')
New deduction hint frame_from_frame :
∀{P:system} , @system:(P), ∀ x ⊢ frame@x ▷ λ t' ⇒ (frame@t' |
t' <= x)
global axiom exec_from_frame {P:system} @system:(set:P; equiv:None) :
$(fun (t:timestamp) => frame@t |1>{P}
fun (t,t':timestamp) => if (t' <= t) then exec@t' else witness)
New deduction hint exec_from_frame :
∀{P:system} , @system:(P), ∀ x ⊢ frame@x ▷ λ t' ⇒ (exec@t' |
t' <= x)
global axiom output_from_frame {P:system} @system:(set:P; equiv:None) :
$(fun (t:timestamp) => frame@t |1>{P}
fun (t,t':timestamp) => if (t' <= t && exec@t') then output@t')
New deduction hint output_from_frame :
∀{P:system} , @system:(P), ∀ x ⊢ frame@x ▷ λ t' ⇒ (output@t' |
t' <= x && exec@t')
global axiom input_from_frame {P:system} @system:(set:P; equiv:None) :
$(fun (t:timestamp) => frame@t |1>{P}
fun (t,t':timestamp) => if (pred t' <= t) then input@t')
New deduction hint input_from_frame :
∀{P:system} , @system:(P), ∀ x ⊢ frame@x ▷ λ t' ⇒ (input@t' |
pred t' <= x)
global axiom exec_from_frame {P:system} @system:(set:P; equiv:None) :
$(fun (t:timestamp) => frame@t |1>{P}
fun (t,t':timestamp) => if (t' <= t) then exec@t' else witness)
New deduction hint exec_from_frame :
∀{P:system} , @system:(P), ∀ x ⊢ frame@x ▷ λ t' ⇒ (exec@t' |
t' <= x)
global axiom output_from_frame {P:system} @system:(set:P; equiv:None) :
$(fun (t:timestamp) => frame@t |1>{P}
fun (t,t':timestamp) => if (t' <= t && exec@t') then output@t')
New deduction hint output_from_frame :
∀{P:system} , @system:(P), ∀ x ⊢ frame@x ▷ λ t' ⇒ (output@t' |
t' <= x && exec@t')
global axiom input_from_frame {P:system} @system:(set:P; equiv:None) :
$(fun (t:timestamp) => frame@t |1>{P}
fun (t,t':timestamp) => if (pred t' <= t) then input@t')
New deduction hint input_from_frame :
∀{P:system} , @system:(P), ∀ x ⊢ frame@x ▷ λ t' ⇒ (input@t' |
pred t' <= x)
global axiom transcript_from_frame {P:system} @system:(set:P; equiv:None) :
$(fun (t:timestamp) => frame@t |1>{P}
fun (t,t':timestamp) => if (t' <= t) then transcript@t')
New deduction hint transcript_from_frame :
∀{P:system} , @system:(P), ∀ x ⊢ frame@x ▷ λ t' ⇒ (transcript@t' |
t' <= x)
global axiom transcript_from_transcript {P:system}
@system:(set:P; equiv:None) :
$(fun (t:timestamp) => transcript@t |1>{P}
fun (t,t':timestamp) => if (t' <= t) then transcript@t')
New deduction hint transcript_from_transcript :
∀{P:system} , @system:(P), ∀ x ⊢ transcript@x ▷ λ t' ⇒ (
transcript@t' |
t' <= x)
global axiom exec_from_transcript {P:system} @system:(set:P; equiv:None) :
$(fun (t:timestamp) => transcript@t |1>{P}
fun (t,t':timestamp) => if (t' <= t) then exec@t' else witness)
New deduction hint exec_from_transcript :
∀{P:system} , @system:(P), ∀ x ⊢ transcript@x ▷ λ t' ⇒ (
exec@t' | t' <= x)
global axiom output_from_transcript {P:system} @system:(set:P; equiv:None) :
$(fun (t:timestamp) => transcript@t |1>{P}
fun (t,t':timestamp) => if (t' <= t && exec@t') then output@t')
New deduction hint output_from_transcript :
∀{P:system} , @system:(P), ∀ x ⊢ transcript@x ▷ λ t' ⇒ (
output@t' |
t' <= x && exec@t')
global axiom input_from_transcript {P:system} @system:(set:P; equiv:None) :
$(fun (t:timestamp) => transcript@t |1>{P}
fun (t,t':timestamp) => if (pred t' <= t) then input@t')
New deduction hint input_from_transcript :
∀{P:system} , @system:(P), ∀ x ⊢ transcript@x ▷ λ t' ⇒ (
input@t' |
pred t' <= x)
[warning>Loaded "Deduction.sp".
<]axiom exec_not_init {'P:system} @system:(set:'P; equiv:None) :
forall (tau:timestamp),
init < tau => exec@tau = (exec@pred tau && cond@tau)
axiom exec_init {'P:system} @system:(set:'P; equiv:None) :
forall (tau:timestamp), tau = init => exec@tau = true
axiom cond_init {'P:system} @system:(set:'P; equiv:None) :
forall (tau:timestamp), tau = init => cond@tau = true
Goal exec_le :
tau' <= tau => exec@tau => exec@tau'
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: tau,tau':timestamp
----------------------------------------
tau' <= tau => exec@tau => exec@tau'

[> Line 17: ((induction);(intro)) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: tau,tau':timestamp[const]
Hexec: exec@tau
Hle: tau' <= tau
IH: forall (tau0:timestamp),
tau0 < tau => tau' <= tau0 => exec@tau0 => exec@tau'
----------------------------------------
exec@tau'

[> Line 18: (case) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Variables: tau,tau':timestamp[const]
Hexec: exec@tau
Hle: tau' <= tau
IH: forall (tau0:timestamp),
tau0 < tau => tau' <= tau0 => exec@tau0 => exec@tau'
----------------------------------------
tau = tau' => exec@tau'

[> Line 19: (auto) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: tau,tau':timestamp[const]
Hexec: exec@tau
Hle: tau' <= tau
IH: forall (tau0:timestamp),
tau0 < tau => tau' <= tau0 => exec@tau0 => exec@tau'
----------------------------------------
not (tau = tau') => exec@tau'

[> Line 20: (intro) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: tau,tau':timestamp[const]
Hexec: exec@tau
Hle: tau' <= tau
Hneq: not (tau = tau')
IH: forall (tau0:timestamp),
tau0 < tau => tau' <= tau0 => exec@tau0 => exec@tau'
----------------------------------------
exec@tau'

[> Line 21: (rewrite) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: tau,tau':timestamp[const]
Hexec: exec@pred tau && cond@tau
Hle: tau' <= tau
Hneq: not (tau = tau')
IH: forall (tau0:timestamp),
tau0 < tau => tau' <= tau0 => exec@tau0 => exec@tau'
----------------------------------------
exec@tau'

[> Line 22: by (apply) [goal> lemma exec_le is proved

lemma exec_le {'P:system} @system:(set:'P; equiv:None) :
forall (tau,tau':timestamp), tau' <= tau => exec@tau => exec@tau'
Exiting proof mode.

Goal exec_cond :
happens(tau) => exec@tau => cond@tau
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: tau:timestamp
----------------------------------------
happens(tau) => exec@tau => cond@tau

[> Line 27: (intro) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: tau:timestamp[const]
Hap: happens(tau)
Hexec: exec@tau
----------------------------------------
cond@tau

[> Line 28: ((case);(intro)) [goal> Focused goal (1/2):
System variables: 'P
System: (set:'P; equiv:None)
Variables: tau:timestamp[const]
Hap: happens(tau)
Hexec: exec@tau
_: init < tau
----------------------------------------
cond@tau

[> Line 29: by (rewrite) [goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: tau:timestamp[const]
Hap: happens(tau)
Hexec: exec@tau
_: not (init < tau)
----------------------------------------
cond@tau

[> Line 30: by (rewrite) [goal> lemma exec_cond is proved

lemma exec_cond {'P:system} @system:(set:'P; equiv:None) :
forall (tau:timestamp), happens(tau) => exec@tau => cond@tau
Exiting proof mode.

axiom executability {'P:system} @system:(set:'P; equiv:None) :
forall (t:timestamp),
happens(t) => exec@t => forall (t0:timestamp), t0 <= t => exec@t0
[warning>Loaded "Classic.sp".
<][warning>Loaded "Core.sp".
<]

LIBRARIES

We include here some libraries, useful to help the tool with automated reasoning.



lemma [any] dec_enc (x,y,z:message) : dec(enc(x,z,y),y) = x.
Goal dec_enc :
dec (enc (x, z, y), y) = x

Proof.
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: x,y,z:message
----------------------------------------
dec (enc (x, z, y), y) = x

auto. [> Line 140: (auto) [goal> lemma dec_enc is proved

Qed. lemma dec_enc {'P:system} @system:(set:'P; equiv:None) :
forall (x,y,z:message), dec (enc (x, z, y), y) = x
Exiting proof mode.


hint rewrite dec_enc.


lemma [any] fst_apply (x,y : message) : x = y => fst(x) = fst(y).
Goal fst_apply :
x = y => fst x = fst y

Proof.
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: x,y:message
----------------------------------------
x = y => fst x = fst y

auto. [> Line 144: (auto) [goal> lemma fst_apply is proved

Qed. lemma fst_apply {'P:system} @system:(set:'P; equiv:None) :
forall (x,y:message), x = y => fst x = fst y
Exiting proof mode.



lemma [any] snd_apply (x,y : message) : x = y => snd(x) = snd(y).
Goal snd_apply :
x = y => snd x = snd y

Proof.
[goal> Focused goal (1/1):
System variables: 'P
System: (set:'P; equiv:None)
Variables: x,y:message
----------------------------------------
x = y => snd x = snd y

auto. [> Line 147: (auto) [goal> lemma snd_apply is proved

Qed. lemma snd_apply {'P:system} @system:(set:'P; equiv:None) :
forall (x,y:message), x = y => snd x = snd y
Exiting proof mode.



lemma dec_apply (x,y,x1,y1 : message) :
x = y => x1 = y1 => dec(x,x1) = dec(y,y1).
Goal dec_apply :
x = y => x1 = y1 => dec (x, x1) = dec (y, y1)

Proof.
[goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: x,x1,y,y1:message
----------------------------------------
x = y => x1 = y1 => dec (x, x1) = dec (y, y1)

auto. [> Line 151: (auto) [goal> lemma dec_apply is proved

Qed. lemma dec_apply @system:(set:default; equiv:None) :
forall (x,y,x1,y1:message), x = y => x1 = y1 => dec (x, x1) = dec (y, y1)
Exiting proof mode.

axiom orderTrans (n1,n2,n3:message):
n1 ~< n2 = orderOk => n2 ~< n3 = orderOk => n1 ~< n3 = orderOk.
axiom orderTrans @system:(set:default; equiv:None) :
forall (n1,n2,n3:message),
n1 ~< n2 = orderOk => n2 ~< n3 = orderOk => n1 ~< n3 = orderOk

AXIOMS

The following axioms are used to reason on counter values.



axiom orderStrict (n1,n2:message):
n1 = n2 => n1 ~< n2 <> orderOk.
axiom orderStrict @system:(set:default; equiv:None) :
forall (n1,n2:message), n1 = n2 => n1 ~< n2 <> orderOk


axiom orderSucc (n1,n2:message):
n1 = n2 => n1 ~< mySucc(n2) = orderOk.
axiom orderSucc @system:(set:default; equiv:None) :
forall (n1,n2:message), n1 = n2 => n1 ~< mySucc n2 = orderOk
lemma counterIncreaseStrictly (ii,i:index):
happens(S(ii,i)) =>
cond@S(ii,i) =>
SCpt(i)@pred(S(ii,i)) ~< SCpt(i)@S(ii,i) = orderOk.
Goal counterIncreaseStrictly :
happens(S(ii, i)) =>
cond@S(ii, i) => SCpt i@pred (S(ii, i)) ~< SCpt i@S(ii, i) = orderOk

HELPING LEMMAS

We now prove some properties on the counter on the server side, used later in the proofs of the security properties.


The counter SCpt(i) strictly increases at each action S performed by the server with tag i.

Proof. [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii:index
----------------------------------------
happens(S(ii, i)) =>
cond@S(ii, i) => SCpt i@pred (S(ii, i)) ~< SCpt i@S(ii, i) = orderOk

The proof is automatically done by Squirrel.

auto. [> Line 180: (auto) [goal> lemma counterIncreaseStrictly is proved

Qed. lemma counterIncreaseStrictly @system:(set:default; equiv:None) :
forall (ii,i:index),
happens(S(ii, i)) =>
cond@S(ii, i) => SCpt i@pred (S(ii, i)) ~< SCpt i@S(ii, i) = orderOk
Exiting proof mode.

lemma counterIncrease (t:timestamp, i : index) :
happens(t) =>
(t > init && exec@t) =>
(SCpt(i)@pred(t) ~< SCpt(i)@t = orderOk) ||
SCpt(i)@t = SCpt(i)@pred(t).
Goal counterIncrease :
happens(t) =>
t > init && exec@t =>
SCpt i@pred t ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@pred t

The counter SCpt(i) increases (not strictly) between pred(t) and t.


Proof.
[goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i:index,t:timestamp
----------------------------------------
happens(t) =>
t > init && exec@t =>
SCpt i@pred t ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@pred t

intro Hap [Ht Hexec]. [> Line 196: (intro) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i:index[const],t:timestamp[const]
Hap: happens(t)
Hexec: exec@t
Ht: t > init
----------------------------------------
SCpt i@pred t ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@pred t

After having introduced the hypotheses, we perform a case analysis on all possible values that the timestamp t can take. Most cases are trivial and automatically handled by Squirrel (=> //) because most actions do not update SCpt(i) so we automatically have that SCpt(i)@t = SCpt(i)@pred(t).


case t => //.
[> Line 197: ((case);(intro)) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i:index[const],t:timestamp[const]
Hap: happens(t)
Hexec: exec@t
Ht: t > init
----------------------------------------
(exists (ii,i0:index), t = S(ii, i0)) =>
SCpt i@pred t ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@pred t

intro [ii i0 _]. [> Line 203: (intro) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,i0,ii:index[const],t:timestamp[const]
Hap: happens(t)
Hexec: exec@t
Ht: t > init
_: t = S(ii, i0)
----------------------------------------
SCpt i@pred t ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@pred t

Case where t = S(ii,i0): This is the interesting case, where t is an action that updates the mutable cell SCpt(i0). We distinguish two cases: i = i0 and i <> i0.


case (i = i0) => _.
[> Line 204: ((case);(intro)) [goal> Focused goal (1/2):
System: (set:default; equiv:None)
Variables: i,i0,ii:index[const],t:timestamp[const]
Hap: happens(t)
Hexec: exec@t
Ht: t > init
_: i = i0
_: t = S(ii, i0)
----------------------------------------
SCpt i@pred t ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@pred t

+ by rewrite if_true //. [> Line 207: by (rewrite) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,i0,ii:index[const],t:timestamp[const]
Hap: happens(t)
Hexec: exec@t
Ht: t > init
_: not (i = i0)
_: t = S(ii, i0)
----------------------------------------
SCpt i@pred t ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@pred t

The case i = i0 corresponds to the left disjunct, which is a direct consequence of the condition of the action SCpt(i). This is done automatically by Squirrel.

+ right. [> Line 214: (right) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,i0,ii:index[const],t:timestamp[const]
Hap: happens(t)
Hexec: exec@t
Ht: t > init
_: not (i = i0)
_: t = S(ii, i0)
----------------------------------------
SCpt i@t = SCpt i@pred t

The case i <> i0 corresponds to the right disjunct. When expanding the macro SCpt(i)@t, we notice that it is an if _ then _ else _ term with a condition that is always false. This can be simplified using the rewrite tactic with lemma if_false (which is included in the Basic library.


by rewrite if_false.
[> Line 215: by (rewrite) [goal> lemma counterIncrease is proved

Qed. lemma counterIncrease @system:(set:default; equiv:None) :
forall (t:timestamp,i:index),
happens(t) =>
t > init && exec@t =>
SCpt i@pred t ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@pred t
Exiting proof mode.

The two previous tactics can be merged into a single one: by rewrite /SCpt if_false.

lemma counterIncreaseBis:
forall (t:timestamp), forall (t':timestamp), forall (i:index),
happens(t) =>
exec@t && t' < t =>
(SCpt(i)@t' ~< SCpt(i)@t = orderOk || SCpt(i)@t = SCpt(i)@t').
Goal counterIncreaseBis :
forall (t,t':timestamp,i:index),
happens(t) =>
exec@t && t' < t =>
SCpt i@t' ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@t'

The counter SCpt(i) increases (not strictly) between t' and t when t' < t.

Proof. [goal> Focused goal (1/1):
System: (set:default; equiv:None)
----------------------------------------
forall (t,t':timestamp,i:index),
happens(t) =>
exec@t && t' < t => SCpt i@t' ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@t'


This proof is done by induction, relying on the previous counterIncrease lemma to prove the induction step.


induction.
[> Line 230: (induction) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
----------------------------------------
forall (t:timestamp),
(forall (t0,t':timestamp,i:index),
t0 < t =>
happens(t0) =>
exec@t0 && t' < t0 =>
SCpt i@t' ~< SCpt i@t0 = orderOk || SCpt i@t0 = SCpt i@t') =>
forall (t':timestamp,i:index),
happens(t) =>
exec@t && t' < t =>
SCpt i@t' ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@t'



intro t IH0 t' i Hap [Hexec Ht'].
[> Line 231: (intro) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i:index[const],t,t':timestamp[const]
Hap: happens(t)
Hexec: exec@t
Ht': t' < t
IH0: forall (t0,t':timestamp,i:index),
t0 < t =>
happens(t0) =>
exec@t0 && t' < t0 =>
SCpt i@t' ~< SCpt i@t0 = orderOk || SCpt i@t0 = SCpt i@t'
----------------------------------------
SCpt i@t' ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@t'

assert (t' = pred(t) || t' < pred(t)) as H0;
1: constraints.
[> Line 236: ((have); 1: (constraints)) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i:index[const],t,t':timestamp[const]
H0: t' = pred t || t' < pred t
Hap: happens(t)
Hexec: exec@t
Ht': t' < t
IH0: forall (t0,t':timestamp,i:index),
t0 < t =>
happens(t0) =>
exec@t0 && t' < t0 =>
SCpt i@t' ~< SCpt i@t0 = orderOk || SCpt i@t0 = SCpt i@t'
----------------------------------------
SCpt i@t' ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@t'

We introduce a case disjunction t'. Since we already have that t' < t then the constraints tactic allows to close the lemma showing that (t' = pred(t) || t' < pred(t)) is indeed satisfied.


case H0.
[> Line 237: (case) [goal> Focused goal (1/2):
System: (set:default; equiv:None)
Variables: i:index[const],t,t':timestamp[const]
H0: t' = pred t
Hap: happens(t)
Hexec: exec@t
Ht': t' < t
IH0: forall (t0,t':timestamp,i:index),
t0 < t =>
happens(t0) =>
exec@t0 && t' < t0 =>
SCpt i@t' ~< SCpt i@t0 = orderOk || SCpt i@t0 = SCpt i@t'
----------------------------------------
SCpt i@t' ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@t'

+ rewrite !H0. [> Line 244: (rewrite) [goal> Focused goal (1/2):
System: (set:default; equiv:None)
Variables: i:index[const],t,t':timestamp[const]
H0: t' = pred t
Hap: happens(t)
Hexec: exec@t
Ht': t' < t
IH0: forall (t0,t':timestamp,i:index),
t0 < t =>
happens(t0) =>
exec@t0 && t' < t0 =>
SCpt i@t' ~< SCpt i@t0 = orderOk || SCpt i@t0 = SCpt i@t'
----------------------------------------
SCpt i@pred t ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@pred t

Case t’ = pred(t). We first rewrite the conclusion using the equality in H0. The ! mark is here to indicate that the rewriting must be done as much as possible and at least once. Then, it is a direct consequence of the counterIncrease lemma.


by apply counterIncrease.
[> Line 245: by (apply) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i:index[const],t,t':timestamp[const]
H0: t' < pred t
Hap: happens(t)
Hexec: exec@t
Ht': t' < t
IH0: forall (t0,t':timestamp,i:index),
t0 < t =>
happens(t0) =>
exec@t0 && t' < t0 =>
SCpt i@t' ~< SCpt i@t0 = orderOk || SCpt i@t0 = SCpt i@t'
----------------------------------------
SCpt i@t' ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@t'

+ use IH0 with pred(t),t',i as H1 => //. [> Line 254: ((have);(intro)) [goal> Focused goal (1/2):
System: (set:default; equiv:None)
Variables: i:index[const],t,t':timestamp[const]
H0: t' < pred t
H1: SCpt i@t' ~< SCpt i@pred t = orderOk || SCpt i@pred t = SCpt i@t'
Hap: happens(t)
Hexec: exec@t
Ht': t' < t
IH0: forall (t0,t':timestamp,i:index),
t0 < t =>
happens(t0) =>
exec@t0 && t' < t0 =>
SCpt i@t' ~< SCpt i@t0 = orderOk || SCpt i@t0 = SCpt i@t'
----------------------------------------
SCpt i@t' ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@t'

Case t’ < pred(t). We first apply the induction hypothesis with t' < pred(t) to obtain a relation between SCpt(i)@t' and SCpt(i)@pred(t). We then use the counterIncrease lemma, this time to obtain a relation between SCpt(i)@pred(t) and SCpt(i)@t. We will then be able to conclude by transitivity.


- use counterIncrease with t,i as H3 => //.
[> Line 255: ((have);(intro)) [goal> Focused goal (1/2):
System: (set:default; equiv:None)
Variables: i:index[const],t,t':timestamp[const]
H0: t' < pred t
H1: SCpt i@t' ~< SCpt i@pred t = orderOk || SCpt i@pred t = SCpt i@t'
H3: SCpt i@pred t ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@pred t
Hap: happens(t)
Hexec: exec@t
Ht': t' < t
IH0: forall (t0,t':timestamp,i:index),
t0 < t =>
happens(t0) =>
exec@t0 && t' < t0 =>
SCpt i@t' ~< SCpt i@t0 = orderOk || SCpt i@t0 = SCpt i@t'
----------------------------------------
SCpt i@t' ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@t'


case H1 => //.
[> Line 256: ((case);(intro)) [goal> Focused goal (1/3):
System: (set:default; equiv:None)
Variables: i:index[const],t,t':timestamp[const]
H0: t' < pred t
H1: SCpt i@t' ~< SCpt i@pred t = orderOk
H3: SCpt i@pred t ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@pred t
Hap: happens(t)
Hexec: exec@t
Ht': t' < t
IH0: forall (t0,t':timestamp,i:index),
t0 < t =>
happens(t0) =>
exec@t0 && t' < t0 =>
SCpt i@t' ~< SCpt i@t0 = orderOk || SCpt i@t0 = SCpt i@t'
----------------------------------------
SCpt i@t' ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@t'


* (* case H1 - 1/2 *)
case H3 => //.
[> Line 258: ((case);(intro)) [goal> Focused goal (1/3):
System: (set:default; equiv:None)
Variables: i:index[const],t,t':timestamp[const]
H0: t' < pred t
H1: SCpt i@t' ~< SCpt i@pred t = orderOk
H3: SCpt i@pred t ~< SCpt i@t = orderOk
Hap: happens(t)
Hexec: exec@t
Ht': t' < t
IH0: forall (t0,t':timestamp,i:index),
t0 < t =>
happens(t0) =>
exec@t0 && t' < t0 =>
SCpt i@t' ~< SCpt i@t0 = orderOk || SCpt i@t0 = SCpt i@t'
----------------------------------------
SCpt i@t' ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@t'


by left; apply orderTrans _ (SCpt(i)@pred(t)) _.
[> Line 259: by ((left);(apply)) [goal> Focused goal (1/2):
System: (set:default; equiv:None)
Variables: i:index[const],t,t':timestamp[const]
H0: t' < pred t
H1: SCpt i@pred t = SCpt i@t'
H3: SCpt i@pred t ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@pred t
Hap: happens(t)
Hexec: exec@t
Ht': t' < t
IH0: forall (t0,t':timestamp,i:index),
t0 < t =>
happens(t0) =>
exec@t0 && t' < t0 =>
SCpt i@t' ~< SCpt i@t0 = orderOk || SCpt i@t0 = SCpt i@t'
----------------------------------------
SCpt i@t' ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@t'


* (* case H1 - 2/2 *)
by case H3; [1: left | 2 : right].
[> Line 261: by ((case); [1: (left)|2: (right)]) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i:index[const],t,t':timestamp[const]
H0: t' < pred t
Hap: happens(t)
Hexec: exec@t
Ht': t' < t
IH0: forall (t0,t':timestamp,i:index),
t0 < t =>
happens(t0) =>
exec@t0 && t' < t0 =>
SCpt i@t' ~< SCpt i@t0 = orderOk || SCpt i@t0 = SCpt i@t'
----------------------------------------
exec@pred t && t' < pred t

- simpl. [> Line 265: (simpl) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i:index[const],t,t':timestamp[const]
H0: t' < pred t
Hap: happens(t)
Hexec: exec@t
Ht': t' < t
IH0: forall (t0,t':timestamp,i:index),
t0 < t =>
happens(t0) =>
exec@t0 && t' < t0 =>
SCpt i@t' ~< SCpt i@t0 = orderOk || SCpt i@t0 = SCpt i@t'
----------------------------------------
exec@pred t

It remains to show that the premises of the induction hypothesis IH0 were satisfied, relying on the fact that exec@t => exec@pred(t).


executable t => // H1.
[> Line 266: ((executable);(intro)) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i:index[const],t,t':timestamp[const]
H0: t' < pred t
H1: forall (t0:timestamp), t0 <= t => exec@t0
Hap: happens(t)
Hexec: exec@t
Ht': t' < t
IH0: forall (t0,t':timestamp,i:index),
t0 < t =>
happens(t0) =>
exec@t0 && t' < t0 =>
SCpt i@t' ~< SCpt i@t0 = orderOk || SCpt i@t0 = SCpt i@t'
----------------------------------------
exec@pred t


by apply H1.
[> Line 267: by (apply) [goal> lemma counterIncreaseBis is proved


Qed.
lemma counterIncreaseBis @system:(set:default; equiv:None) :
forall (t,t':timestamp,i:index),
happens(t) =>
exec@t && t' < t =>
SCpt i@t' ~< SCpt i@t = orderOk || SCpt i@t = SCpt i@t'
Exiting proof mode.

lemma noreplayInv (ii, ii1, i:index):
happens(S(ii1,i),S(ii,i)) =>
exec@S(ii1,i) && S(ii,i) < S(ii1,i) =>
SCpt(i)@S(ii,i) ~< SCpt(i)@S(ii1,i) = orderOk.
Goal noreplayInv :
happens(S(ii, i), S(ii1, i)) =>
exec@S(ii1, i) && S(ii, i) < S(ii1, i) =>
SCpt i@S(ii, i) ~< SCpt i@S(ii1, i) = orderOk

SECURITY PROPERTIES

We now state and prove the 3 following security properties:

  • Property 1: absence of replay attacks.
  • Property 2: injective correspondence.
  • Property 3: monotonicity.

Property 1: absence of replay attacks

This property states that the server never accepts for the same YubiKey the same counter twice, i.e. if the trace is executable up until S(ii1,i), then there cannot exist a previous action S(ii,i) in the trace such that ii <> ii1 and SCpt(i)@S(ii,i) = SCpt(i)@S(ii1,i).

Note that proving this property does not rely on any assumption on cryptographic primitives: it relies only on reasonings about counter values.

We start by proving an invariant (noreplayInv) that will be useful in the main proof. This intermediate lemma states that whenever the server accepts for a given YubiKey (represented by the index i), the counter value must have increased compared to the last time the server accepted for this YubiKey.

Proof. [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii1:index
----------------------------------------
happens(S(ii, i), S(ii1, i)) =>
exec@S(ii1, i) && S(ii, i) < S(ii1, i) =>
SCpt i@S(ii, i) ~< SCpt i@S(ii1, i) = orderOk

The proof relies on the previous helping lemmas reasoning on counter values.


intro Hap [Hexec Ht].
[> Line 306: (intro) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii1:index[const]
Hap: happens(S(ii, i), S(ii1, i))
Hexec: exec@S(ii1, i)
Ht: S(ii, i) < S(ii1, i)
----------------------------------------
SCpt i@S(ii, i) ~< SCpt i@S(ii1, i) = orderOk


assert (S(ii,i) = pred(S(ii1,i)) || S(ii,i) < pred(S(ii1,i))) as H1;
1: constraints.
[> Line 308: ((have); 1: (constraints)) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii1:index[const]
H1: S(ii, i) = pred (S(ii1, i)) || S(ii, i) < pred (S(ii1, i))
Hap: happens(S(ii, i), S(ii1, i))
Hexec: exec@S(ii1, i)
Ht: S(ii, i) < S(ii1, i)
----------------------------------------
SCpt i@S(ii, i) ~< SCpt i@S(ii1, i) = orderOk


case H1.
[> Line 309: (case) [goal> Focused goal (1/2):
System: (set:default; equiv:None)
Variables: i,ii,ii1:index[const]
H1: S(ii, i) = pred (S(ii1, i))
Hap: happens(S(ii, i), S(ii1, i))
Hexec: exec@S(ii1, i)
Ht: S(ii, i) < S(ii1, i)
----------------------------------------
SCpt i@S(ii, i) ~< SCpt i@S(ii1, i) = orderOk


+ (* Case S(ii,i) = pred(S(ii1,i)). *)
by use counterIncreaseStrictly with ii1, i as M0.
[> Line 311: by (have) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii1:index[const]
H1: S(ii, i) < pred (S(ii1, i))
Hap: happens(S(ii, i), S(ii1, i))
Hexec: exec@S(ii1, i)
Ht: S(ii, i) < S(ii1, i)
----------------------------------------
SCpt i@S(ii, i) ~< SCpt i@S(ii1, i) = orderOk



+ (* Case S(ii,i) < pred(S(ii1,i)). *)
use counterIncreaseBis with pred(S(ii1,i)),S(ii,i),i as H2 => //.
[> Line 314: ((have);(intro)) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii1:index[const]
H1: S(ii, i) < pred (S(ii1, i))
H2: SCpt i@S(ii, i) ~< SCpt i@pred (S(ii1, i)) = orderOk ||
SCpt i@pred (S(ii1, i)) = SCpt i@S(ii, i)
Hap: happens(S(ii, i), S(ii1, i))
Hexec: exec@S(ii1, i)
Ht: S(ii, i) < S(ii1, i)
----------------------------------------
SCpt i@S(ii, i) ~< SCpt i@S(ii1, i) = orderOk


case H2 => //.
[> Line 315: ((case);(intro)) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii1:index[const]
H1: S(ii, i) < pred (S(ii1, i))
H2: SCpt i@S(ii, i) ~< SCpt i@pred (S(ii1, i)) = orderOk
Hap: happens(S(ii, i), S(ii1, i))
Hexec: exec@S(ii1, i)
Ht: S(ii, i) < S(ii1, i)
----------------------------------------
SCpt i@S(ii, i) ~< SCpt i@S(ii1, i) = orderOk


by apply orderTrans _ (SCpt(i)@pred(S(ii1,i))) _.
[> Line 316: by (apply) [goal> lemma noreplayInv is proved


Qed.
lemma noreplayInv @system:(set:default; equiv:None) :
forall (ii,ii1,i:index),
happens(S(ii, i), S(ii1, i)) =>
exec@S(ii1, i) && S(ii, i) < S(ii1, i) =>
SCpt i@S(ii, i) ~< SCpt i@S(ii1, i) = orderOk
Exiting proof mode.



lemma noreplay (ii, ii1, i:index):
happens(S(ii1,i)) =>
exec@S(ii1,i) && S(ii,i) <= S(ii1,i) && SCpt(i)@S(ii,i) = SCpt(i)@S(ii1,i) =>
ii = ii1.
Goal noreplay :
happens(S(ii1, i)) =>
exec@S(ii1, i) &&
S(ii, i) <= S(ii1, i) && SCpt i@S(ii, i) = SCpt i@S(ii1, i) => ii = ii1

Proof.
[goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii1:index
----------------------------------------
happens(S(ii1, i)) =>
exec@S(ii1, i) && S(ii, i) <= S(ii1, i) && SCpt i@S(ii, i) = SCpt i@S(ii1, i)
=> ii = ii1


intro Hap [Hexec Ht Meq].
[> Line 324: (intro) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii1:index[const]
Hap: happens(S(ii1, i))
Hexec: exec@S(ii1, i)
Ht: S(ii, i) <= S(ii1, i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii1, i)
----------------------------------------
ii = ii1


assert (S(ii,i) = S(ii1,i) || S(ii,i) < S(ii1,i)) as H1;
1: constraints.
[> Line 326: ((have); 1: (constraints)) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii1:index[const]
H1: S(ii, i) = S(ii1, i) || S(ii, i) < S(ii1, i)
Hap: happens(S(ii1, i))
Hexec: exec@S(ii1, i)
Ht: S(ii, i) <= S(ii1, i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii1, i)
----------------------------------------
ii = ii1

case H1 => //. [> Line 331: ((case);(intro)) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii1:index[const]
H1: S(ii, i) < S(ii1, i)
Hap: happens(S(ii1, i))
Hexec: exec@S(ii1, i)
Ht: S(ii, i) <= S(ii1, i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii1, i)
----------------------------------------
ii = ii1

The case where S(ii,i) = S(ii1,i) is trivial and automatically handled by Squirrel. For the case where S(ii,i) < S(ii1,i), we use the invariant to show that there is a contradiction with the hypothesis Meq.


use noreplayInv with ii, ii1, i as M1 => //.
[> Line 332: ((have);(intro)) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii1:index[const]
H1: S(ii, i) < S(ii1, i)
Hap: happens(S(ii1, i))
Hexec: exec@S(ii1, i)
Ht: S(ii, i) <= S(ii1, i)
M1: SCpt i@S(ii, i) ~< SCpt i@S(ii1, i) = orderOk
Meq: SCpt i@S(ii, i) = SCpt i@S(ii1, i)
----------------------------------------
ii = ii1


by apply orderStrict in Meq.
[> Line 333: by (apply) [goal> lemma noreplay is proved


Qed.
lemma noreplay @system:(set:default; equiv:None) :
forall (ii,ii1,i:index),
happens(S(ii1, i)) =>
exec@S(ii1, i) &&
S(ii, i) <= S(ii1, i) && SCpt i@S(ii, i) = SCpt i@S(ii1, i) => ii = ii1
Exiting proof mode.

lemma injective_correspondence (ii,i:index):
happens(S(ii,i)) =>
exec@S(ii,i) =>
exists (j:index),
Press(i,j) < S(ii,i) && cpt i j@Press(i,j) = SCpt(i)@S(ii,i) &&
forall (ii1:index),
happens(S(ii1,i)) =>
exec@S(ii1,i) =>
cpt i j@Press(i,j) = SCpt(i)@S(ii1,i) =>
ii1 = ii.
Goal injective_correspondence :
happens(S(ii, i)) =>
exec@S(ii, i) =>
exists (j:index),
Press(i, j) < S(ii, i) &&
cpt i j@Press(i, j) = SCpt i@S(ii, i) &&
forall (ii1:index),
happens(S(ii1, i)) =>
exec@S(ii1, i) => cpt i j@Press(i, j) = SCpt i@S(ii1, i) => ii1 = ii

Property 2: injective correspondence

This property states that a successful login for the YubiKey pid(i) (i.e. the execution of action S(ii,i)) must have been preceded by a button press on this YubiKey for the same counter value (P(i,j) with cpt(i,j)@Press(i,j) = SCpt(i)@S(ii,i)), and this counter value is not involved in another successful login.

Proving this property requires to reason on counter values, but also requires the use of the INT-CTXT cryptographic assumption.

Proof. [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii:index
----------------------------------------
happens(S(ii, i)) =>
exec@S(ii, i) =>
exists (j:index),
Press(i, j) < S(ii, i) &&
cpt i j@Press(i, j) = SCpt i@S(ii, i) &&
forall (ii1:index),
happens(S(ii1, i)) =>
exec@S(ii1, i) => cpt i j@Press(i, j) = SCpt i@S(ii1, i) => ii1 = ii


The high-level idea of this proof is to use the INT-CTXT assumption: if the message received by the server is a valid ciphertext, then it must be equal to an encryption that took place before.

Since the action Press(i,j) is the only one that outputs an encryption, we thus have the existence of such an action before in the trace. Then, the unicity is proved using lemmas on counter values.


intro Hap Hexec.
[> Line 366: (intro) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii:index[const]
Hap: happens(S(ii, i))
Hexec: exec@S(ii, i)
----------------------------------------
exists (j:index),
Press(i, j) < S(ii, i) &&
cpt i j@Press(i, j) = SCpt i@S(ii, i) &&
forall (ii1:index),
happens(S(ii1, i)) =>
exec@S(ii1, i) => cpt i j@Press(i, j) = SCpt i@S(ii1, i) => ii1 = ii



executable S(ii,i) => //.
[> Line 367: ((executable);(intro)) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii:index[const]
Hap: happens(S(ii, i))
Hexec: exec@S(ii, i)
----------------------------------------
(forall (t:timestamp), t <= S(ii, i) => exec@t) =>
exists (j:index),
Press(i, j) < S(ii, i) &&
cpt i j@Press(i, j) = SCpt i@S(ii, i) &&
forall (ii1:index),
happens(S(ii1, i)) =>
exec@S(ii1, i) => cpt i j@Press(i, j) = SCpt i@S(ii1, i) => ii1 = ii



intro Hexec'.
[> Line 367: (intro) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii:index[const]
Hap: happens(S(ii, i))
Hexec: exec@S(ii, i)
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
----------------------------------------
exists (j:index),
Press(i, j) < S(ii, i) &&
cpt i j@Press(i, j) = SCpt i@S(ii, i) &&
forall (ii1:index),
happens(S(ii1, i)) =>
exec@S(ii1, i) => cpt i j@Press(i, j) = SCpt i@S(ii1, i) => ii1 = ii



rewrite /exec /cond in Hexec.
[> Line 369: (rewrite) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii:index[const]
Hap: happens(S(ii, i))
Hexec: exec@pred (S(ii, i)) &&
(dec (snd (snd (input@S(ii, i))), k i) <> fail &&
SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk) &&
fst (input@S(ii, i)) = pid i
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
----------------------------------------
exists (j:index),
Press(i, j) < S(ii, i) &&
cpt i j@Press(i, j) = SCpt i@S(ii, i) &&
forall (ii1:index),
happens(S(ii1, i)) =>
exec@S(ii1, i) => cpt i j@Press(i, j) = SCpt i@S(ii1, i) => ii1 = ii



destruct Hexec as [Hexecpred [Mneq Hcpt] Hpid].
[> Line 370: (destruct) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii:index[const]
Hap: happens(S(ii, i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
exists (j:index),
Press(i, j) < S(ii, i) &&
cpt i j@Press(i, j) = SCpt i@S(ii, i) &&
forall (ii1:index),
happens(S(ii1, i)) =>
exec@S(ii1, i) => cpt i j@Press(i, j) = SCpt i@S(ii1, i) => ii1 = ii


intctxt Mneq => //. [> Line 373: ((intctxt);(intro))
Indirect randomness in other actions:
npr((i, j))
(collision with npr((i, j)))
in action Press(i, j)
in term
(happens(Press(i, j)),
<pid i,
<nonce (i, j),enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)>>)

Total: 1 occurrence
0 of them are subsumed by another
1 occurrence remaining

among which 1 trivial randomness occurrence is ignored
1 possible ciphertext found.
[goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii:index[const]
Hap: happens(S(ii, i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
(exists (j:index),
Press(i, j) < S(ii, i) &&
snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)) =>
exists (j:index),
Press(i, j) < S(ii, i) &&
cpt i j@Press(i, j) = SCpt i@S(ii, i) &&
forall (ii1:index),
happens(S(ii1, i)) =>
exec@S(ii1, i) => cpt i j@Press(i, j) = SCpt i@S(ii1, i) => ii1 = ii


We apply the INT-CTXT assumption, which directly gives the existence of an action Press(i,j) that happens before S(ii,i).


(* randomness condition *)
++ intro [j [Ht M1]].
[> Line 374: (intro) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,j:index[const]
Hap: happens(S(ii, i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
exists (j:index),
Press(i, j) < S(ii, i) &&
cpt i j@Press(i, j) = SCpt i@S(ii, i) &&
forall (ii1:index),
happens(S(ii1, i)) =>
exec@S(ii1, i) => cpt i j@Press(i, j) = SCpt i@S(ii1, i) => ii1 = ii



exists j.
[> Line 376: (exists) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,j:index[const]
Hap: happens(S(ii, i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
Press(i, j) < S(ii, i) &&
cpt i j@Press(i, j) = SCpt i@S(ii, i) &&
forall (ii1:index),
happens(S(ii1, i)) =>
exec@S(ii1, i) => cpt i j@Press(i, j) = SCpt i@S(ii1, i) => ii1 = ii


simpl. [> Line 380: (simpl) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,j:index[const]
Hap: happens(S(ii, i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
cpt i j@Press(i, j) = SCpt i@S(ii, i) &&
forall (ii1:index),
happens(S(ii1, i)) =>
exec@S(ii1, i) => cpt i j@Press(i, j) = SCpt i@S(ii1, i) => ii1 = ii


The two first conjucts of the conclusion are automatically proved by Squirrel (the equality of counter values is a consequence of M1 once we have expanded the macros cpt and SCpt.


split; 1: auto.
[> Line 382: ((split); 1: (auto)) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,j:index[const]
Hap: happens(S(ii, i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
forall (ii1:index),
happens(S(ii1, i)) =>
exec@S(ii1, i) => cpt i j@Press(i, j) = SCpt i@S(ii1, i) => ii1 = ii


intro ii' Hap' Hexec1 Eq. [> Line 387: (intro) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii

It now remains to show that the counter value cpt(i,j)@Press(i,j) is not involved in another successful login. We first show if this second successful login S(ii',i) had happened, then we must have SCpt(i)@S(ii,i) = SCpt(i)@S(ii',i).


assert (SCpt(i)@S(ii,i) = SCpt(i)@S(ii',i)) => //.
[> Line 388: ((have);(intro)) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii

assert (S(ii,i) = S(ii',i) || S(ii,i) < S(ii',i) || S(ii,i) > S(ii',i)) => //. [> Line 393: ((have);(intro)) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) = S(ii', i) || S(ii, i) < S(ii', i) || S(ii, i) > S(ii', i)
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii

The proof now relies only on lemmas about counter values to show that we cannot have SCpt(i)@S(ii,i) = SCpt(i)@S(ii',i) and S(ii,i) <> S(ii',i). We therefore a case disjunction (the first case corresponds to what we want to prove, and we will show that the 2 other cases are impossible).


case H; 1:auto.
[> Line 393: ((case); 1: (auto)) [goal> Focused goal (1/2):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) < S(ii', i)
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii



+ (* 1st case: S(ii,i) < S(ii',i) *)
assert (S(ii,i) = pred(S(ii',i)) || S(ii,i) < pred(S(ii',i))) by auto.
[> Line 396: ((have); 1: by (auto)) [goal> Focused goal (1/2):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) < S(ii', i)
H0: S(ii, i) = pred (S(ii', i)) || S(ii, i) < pred (S(ii', i))
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii


case H0.
[> Line 398: (case) [goal> Focused goal (1/3):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) < S(ii', i)
H0: S(ii, i) = pred (S(ii', i))
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii



- (* S(ii,i) = pred(S(ii',i) < S(ii',i) *)
use counterIncreaseStrictly with ii',i; 2: auto.
[> Line 400: ((have); 2: (auto)) [goal> Focused goal (1/4):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) < S(ii', i)
H0: S(ii, i) = pred (S(ii', i))
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Meq0: SCpt i@pred (S(ii', i)) ~< SCpt i@S(ii', i) = orderOk
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii


* subst S(ii,i), pred(S(ii',i)) => //.
[> Line 402: ((subst);(intro)) [goal> Focused goal (1/4):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: pred (S(ii', i)) < S(ii', i)
Hap: happens(pred (S(ii', i)))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (pred (S(ii', i))) ~<
snd (dec (snd (snd (input@pred (S(ii', i)))), k i)) = orderOk
Hexec': forall (t:timestamp), t <= pred (S(ii', i)) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (pred (S(ii', i)))
Hpid: fst (input@pred (S(ii', i))) = pid i
Ht: Press(i, j) < pred (S(ii', i))
M1: snd (snd (input@pred (S(ii', i)))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@pred (S(ii', i)) = SCpt i@S(ii', i)
Meq0: SCpt i@pred (S(ii', i)) ~< SCpt i@S(ii', i) = orderOk
Mneq: dec (snd (snd (input@pred (S(ii', i)))), k i) <> fail
----------------------------------------
ii' = ii


by use orderStrict with SCpt(i)@pred(S(ii',i)), SCpt(i)@S(ii',i) => //.
[> Line 403: (by (have);(intro)) [goal> Focused goal (1/3):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) < S(ii', i)
H0: S(ii, i) = pred (S(ii', i))
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
cond@S(ii', i)


* rewrite /cond.
[> Line 404: (rewrite) [goal> Focused goal (1/3):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) < S(ii', i)
H0: S(ii, i) = pred (S(ii', i))
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
(dec (snd (snd (input@S(ii', i))), k i) <> fail &&
SCpt i@pred (S(ii', i)) ~< snd (dec (snd (snd (input@S(ii', i))), k i))
= orderOk) &&
fst (input@S(ii', i)) = pid i


rewrite /exec /cond in Hexec1.
[> Line 405: (rewrite) [goal> Focused goal (1/3):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) < S(ii', i)
H0: S(ii, i) = pred (S(ii', i))
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@pred (S(ii', i)) &&
(dec (snd (snd (input@S(ii', i))), k i) <> fail &&
SCpt i@pred (S(ii', i)) ~<
snd (dec (snd (snd (input@S(ii', i))), k i)) = orderOk) &&
fst (input@S(ii', i)) = pid i
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
(dec (snd (snd (input@S(ii', i))), k i) <> fail &&
SCpt i@pred (S(ii', i)) ~< snd (dec (snd (snd (input@S(ii', i))), k i))
= orderOk) &&
fst (input@S(ii', i)) = pid i


destruct Hexec1 as [H1 [H2 H22] H3].
[> Line 405: (destruct) [goal> Focused goal (1/3):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) < S(ii', i)
H0: S(ii, i) = pred (S(ii', i))
H1: exec@pred (S(ii', i))
H2: dec (snd (snd (input@S(ii', i))), k i) <> fail
H22: SCpt i@pred (S(ii', i)) ~< snd (dec (snd (snd (input@S(ii', i))), k i))
= orderOk
H3: fst (input@S(ii', i)) = pid i
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
(dec (snd (snd (input@S(ii', i))), k i) <> fail &&
SCpt i@pred (S(ii', i)) ~< snd (dec (snd (snd (input@S(ii', i))), k i))
= orderOk) &&
fst (input@S(ii', i)) = pid i


clear Eq H H0 Mneq Meq M1 Ht Hexec' Hap Hap' Hexecpred.
[> Line 407: (clear) [goal> Focused goal (1/3):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
H1: exec@pred (S(ii', i))
H2: dec (snd (snd (input@S(ii', i))), k i) <> fail
H22: SCpt i@pred (S(ii', i)) ~< snd (dec (snd (snd (input@S(ii', i))), k i))
= orderOk
H3: fst (input@S(ii', i)) = pid i
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hpid: fst (input@S(ii, i)) = pid i
----------------------------------------
(dec (snd (snd (input@S(ii', i))), k i) <> fail &&
SCpt i@pred (S(ii', i)) ~< snd (dec (snd (snd (input@S(ii', i))), k i))
= orderOk) &&
fst (input@S(ii', i)) = pid i


auto.
[> Line 408: (auto) [goal> Focused goal (1/2):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) < S(ii', i)
H0: S(ii, i) < pred (S(ii', i))
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii



- (* S(ii,i) < pred(S(ii',i)) < S(ii',i) *)
use counterIncreaseStrictly with ii',i; 2,3: auto.
[> Line 410: ((have); 2,3: (auto)) [goal> Focused goal (1/2):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) < S(ii', i)
H0: S(ii, i) < pred (S(ii', i))
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Meq0: SCpt i@pred (S(ii', i)) ~< SCpt i@S(ii', i) = orderOk
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii


use counterIncreaseBis with pred(S(ii',i)), S(ii,i), i; 2,3:auto.
[> Line 411: ((have); 2,3: (auto)) [goal> Focused goal (1/2):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) < S(ii', i)
H0: S(ii, i) < pred (S(ii', i))
H1: SCpt i@S(ii, i) ~< SCpt i@pred (S(ii', i)) = orderOk ||
SCpt i@pred (S(ii', i)) = SCpt i@S(ii, i)
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Meq0: SCpt i@pred (S(ii', i)) ~< SCpt i@S(ii', i) = orderOk
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii


case H1.
[> Line 413: (case) [goal> Focused goal (1/3):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) < S(ii', i)
H0: S(ii, i) < pred (S(ii', i))
H1: SCpt i@S(ii, i) ~< SCpt i@pred (S(ii', i)) = orderOk
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Meq0: SCpt i@pred (S(ii', i)) ~< SCpt i@S(ii', i) = orderOk
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii


* use orderTrans with
SCpt(i)@S(ii,i), SCpt(i)@pred(S(ii',i)), SCpt(i)@S(ii',i);
2,3: auto.
[> Line 415: ((have); 2,3: (auto)) [goal> Focused goal (1/3):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) < S(ii', i)
H0: S(ii, i) < pred (S(ii', i))
H1: SCpt i@S(ii, i) ~< SCpt i@pred (S(ii', i)) = orderOk
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Meq0: SCpt i@pred (S(ii', i)) ~< SCpt i@S(ii', i) = orderOk
Meq1: SCpt i@S(ii, i) ~< SCpt i@S(ii', i) = orderOk
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii


by use orderStrict with SCpt(i)@S(ii,i), SCpt(i)@S(ii',i).
[> Line 416: by (have) [goal> Focused goal (1/2):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) < S(ii', i)
H0: S(ii, i) < pred (S(ii', i))
H1: SCpt i@pred (S(ii', i)) = SCpt i@S(ii, i)
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Meq0: SCpt i@pred (S(ii', i)) ~< SCpt i@S(ii', i) = orderOk
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii


* subst SCpt(i)@pred(S(ii',i)), SCpt(i)@S(ii,i).
[> Line 418: (subst) [goal> Focused goal (1/2):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) < S(ii', i)
H0: S(ii, i) < pred (S(ii', i))
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Meq0: SCpt i@S(ii, i) ~< SCpt i@S(ii', i) = orderOk
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii


by use orderStrict with SCpt(i)@S(ii,i), SCpt(i)@S(ii',i).
[> Line 418: by (have) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) > S(ii', i)
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii



+ (* 2nd case: S(ii,i) > S(ii',i) *)
assert (pred(S(ii,i)) = S(ii',i) || pred(S(ii,i)) > S(ii',i)) by auto.
[> Line 421: ((have); 1: by (auto)) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) > S(ii', i)
H0: pred (S(ii, i)) = S(ii', i) || pred (S(ii, i)) > S(ii', i)
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii


case H0.
[> Line 423: (case) [goal> Focused goal (1/2):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) > S(ii', i)
H0: pred (S(ii, i)) = S(ii', i)
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii



- (* S(ii,i) > pred(S(ii,i)) = S(ii',i) *)
use counterIncreaseStrictly with ii,i; 2,3:auto.
[> Line 425: ((have); 2,3: (auto)) [goal> Focused goal (1/2):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) > S(ii', i)
H0: pred (S(ii, i)) = S(ii', i)
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Meq0: SCpt i@pred (S(ii, i)) ~< SCpt i@S(ii, i) = orderOk
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii


subst S(ii',i), pred(S(ii,i)).
[> Line 427: (subst) [goal> Focused goal (1/2):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@pred (S(ii, i))
H: S(ii, i) > pred (S(ii, i))
Hap: happens(S(ii, i))
Hap': happens(pred (S(ii, i)))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@pred (S(ii, i))
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@pred (S(ii, i))
Meq0: SCpt i@pred (S(ii, i)) ~< SCpt i@S(ii, i) = orderOk
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii


by use orderStrict with SCpt(i)@pred(S(ii,i)), SCpt(i)@S(ii,i).
[> Line 428: by (have) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) > S(ii', i)
H0: pred (S(ii, i)) > S(ii', i)
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii



- (* S(ii,i) > pred(S(ii,i)) > S(ii',i) *)
use counterIncreaseStrictly with ii,i; 2,3: auto.
[> Line 430: ((have); 2,3: (auto)) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) > S(ii', i)
H0: pred (S(ii, i)) > S(ii', i)
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Meq0: SCpt i@pred (S(ii, i)) ~< SCpt i@S(ii, i) = orderOk
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii


use counterIncreaseBis with pred(S(ii,i)), S(ii',i), i; 2,3:auto.
[> Line 431: ((have); 2,3: (auto)) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) > S(ii', i)
H0: pred (S(ii, i)) > S(ii', i)
H1: SCpt i@S(ii', i) ~< SCpt i@pred (S(ii, i)) = orderOk ||
SCpt i@pred (S(ii, i)) = SCpt i@S(ii', i)
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Meq0: SCpt i@pred (S(ii, i)) ~< SCpt i@S(ii, i) = orderOk
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii


case H1.
[> Line 433: (case) [goal> Focused goal (1/2):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) > S(ii', i)
H0: pred (S(ii, i)) > S(ii', i)
H1: SCpt i@S(ii', i) ~< SCpt i@pred (S(ii, i)) = orderOk
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Meq0: SCpt i@pred (S(ii, i)) ~< SCpt i@S(ii, i) = orderOk
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii


* use orderTrans
with SCpt(i)@S(ii',i), SCpt(i)@pred(S(ii,i)), SCpt(i)@S(ii,i);
2,3:auto.
[> Line 435: ((have); 2,3: (auto)) [goal> Focused goal (1/2):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) > S(ii', i)
H0: pred (S(ii, i)) > S(ii', i)
H1: SCpt i@S(ii', i) ~< SCpt i@pred (S(ii, i)) = orderOk
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Meq0: SCpt i@pred (S(ii, i)) ~< SCpt i@S(ii, i) = orderOk
Meq1: SCpt i@S(ii', i) ~< SCpt i@S(ii, i) = orderOk
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii


by use orderStrict with SCpt(i)@S(ii',i), SCpt(i)@S(ii,i).
[> Line 436: by (have) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) > S(ii', i)
H0: pred (S(ii, i)) > S(ii', i)
H1: SCpt i@pred (S(ii, i)) = SCpt i@S(ii', i)
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@pred (S(ii, i)) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Meq0: SCpt i@pred (S(ii, i)) ~< SCpt i@S(ii, i) = orderOk
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii


* subst SCpt(i)@pred(S(ii,i)), SCpt(i)@S(ii',i).
[> Line 438: (subst) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii',j:index[const]
Eq: cpt i j@Press(i, j) = SCpt i@S(ii', i)
H: S(ii, i) > S(ii', i)
H0: pred (S(ii, i)) > S(ii', i)
Hap: happens(S(ii, i))
Hap': happens(S(ii', i))
Hcpt: SCpt i@S(ii', i) ~< snd (dec (snd (snd (input@S(ii, i))), k i))
= orderOk
Hexec': forall (t:timestamp), t <= S(ii, i) => exec@t
Hexec1: exec@S(ii', i)
Hexecpred: exec@pred (S(ii, i))
Hpid: fst (input@S(ii, i)) = pid i
Ht: Press(i, j) < S(ii, i)
M1: snd (snd (input@S(ii, i))) =
enc (<sid i,cpt i j@Press(i, j)>, npr (i, j), k i)
Meq: SCpt i@S(ii, i) = SCpt i@S(ii', i)
Meq0: SCpt i@S(ii', i) ~< SCpt i@S(ii, i) = orderOk
Mneq: dec (snd (snd (input@S(ii, i))), k i) <> fail
----------------------------------------
ii' = ii


by use orderStrict with SCpt(i)@S(ii',i), SCpt(i)@S(ii,i).
[> Line 439: by (have) [goal> lemma injective_correspondence is proved


Qed.
lemma injective_correspondence @system:(set:default; equiv:None) :
forall (ii,i:index),
happens(S(ii, i)) =>
exec@S(ii, i) =>
exists (j:index),
Press(i, j) < S(ii, i) &&
cpt i j@Press(i, j) = SCpt i@S(ii, i) &&
forall (ii1:index),
happens(S(ii1, i)) =>
exec@S(ii1, i) => cpt i j@Press(i, j) = SCpt i@S(ii1, i) => ii1 = ii
Exiting proof mode.

lemma monotonicity (ii, ii1, i:index):
happens(S(ii1,i),S(ii,i)) =>
exec@S(ii1,i) && exec@S(ii,i)
&& SCpt(i)@S(ii,i) ~< SCpt(i)@S(ii1,i) = orderOk =>
S(ii,i) < S(ii1,i).
Goal monotonicity :
happens(S(ii, i), S(ii1, i)) =>
exec@S(ii1, i) &&
exec@S(ii, i) && SCpt i@S(ii, i) ~< SCpt i@S(ii1, i) = orderOk =>
S(ii, i) < S(ii1, i)

Property 3: monotonicity

This property states that the counter values associated to successful logins are monotonically increasing in time.

Note that proving this property does not rely on any assumption on cryptographic primitives: it relies only on reasonings about counter values.


Proof.
[goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii1:index
----------------------------------------
happens(S(ii, i), S(ii1, i)) =>
exec@S(ii1, i) &&
exec@S(ii, i) && SCpt i@S(ii, i) ~< SCpt i@S(ii1, i) = orderOk =>
S(ii, i) < S(ii1, i)


intro Hap [Hexec H].
[> Line 457: (intro) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii1:index[const]
H: exec@S(ii, i) && SCpt i@S(ii, i) ~< SCpt i@S(ii1, i) = orderOk
Hap: happens(S(ii, i), S(ii1, i))
Hexec: exec@S(ii1, i)
----------------------------------------
S(ii, i) < S(ii1, i)

assert
(S(ii,i) = S(ii1,i) || S(ii,i) < S(ii1,i) || S(ii,i) > S(ii1,i)) as Ht;
1: constraints.
[> Line 463: ((have); 1: (constraints)) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii1:index[const]
H: exec@S(ii, i) && SCpt i@S(ii, i) ~< SCpt i@S(ii1, i) = orderOk
Hap: happens(S(ii, i), S(ii1, i))
Hexec: exec@S(ii1, i)
Ht: S(ii, i) = S(ii1, i) || S(ii, i) < S(ii1, i) || S(ii, i) > S(ii1, i)
----------------------------------------
S(ii, i) < S(ii1, i)

We introduce a case disjunction, and we will show that the cases S(ii,i) = S(ii1,i) and S(ii,i) > S(ii1,i) are not possible, relying on previous lemmas and axioms on counter values.


case Ht.
[> Line 464: (case) [goal> Focused goal (1/3):
System: (set:default; equiv:None)
Variables: i,ii,ii1:index[const]
H: exec@S(ii, i) && SCpt i@S(ii, i) ~< SCpt i@S(ii1, i) = orderOk
Hap: happens(S(ii, i), S(ii1, i))
Hexec: exec@S(ii1, i)
Ht: S(ii, i) = S(ii1, i)
----------------------------------------
S(ii, i) < S(ii1, i)



+ (* case S(ii,i) = S(ii1,i) *)
by use orderStrict with SCpt(i)@S(ii,i),SCpt(i)@S(ii,i).
[> Line 467: by (have) [goal> Focused goal (1/2):
System: (set:default; equiv:None)
Variables: i,ii,ii1:index[const]
H: exec@S(ii, i) && SCpt i@S(ii, i) ~< SCpt i@S(ii1, i) = orderOk
Hap: happens(S(ii, i), S(ii1, i))
Hexec: exec@S(ii1, i)
Ht: S(ii, i) < S(ii1, i)
----------------------------------------
S(ii, i) < S(ii1, i)



+ (* case S(ii,i) < S(ii1,i) *)
assumption.
[> Line 470: (assumption) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii1:index[const]
H: exec@S(ii, i) && SCpt i@S(ii, i) ~< SCpt i@S(ii1, i) = orderOk
Hap: happens(S(ii, i), S(ii1, i))
Hexec: exec@S(ii1, i)
Ht: S(ii, i) > S(ii1, i)
----------------------------------------
S(ii, i) < S(ii1, i)



+ (* case S(ii,i) > S(ii1,i) *)
use noreplayInv with ii1, ii, i as Meq => //.
[> Line 473: ((have);(intro)) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii1:index[const]
H: exec@S(ii, i) && SCpt i@S(ii, i) ~< SCpt i@S(ii1, i) = orderOk
Hap: happens(S(ii, i), S(ii1, i))
Hexec: exec@S(ii1, i)
Ht: S(ii, i) > S(ii1, i)
Meq: SCpt i@S(ii1, i) ~< SCpt i@S(ii, i) = orderOk
----------------------------------------
S(ii, i) < S(ii1, i)


use orderTrans with SCpt(i)@S(ii,i),SCpt(i)@S(ii1,i), SCpt(i)@S(ii,i) => //.
[> Line 474: ((have);(intro)) [goal> Focused goal (1/1):
System: (set:default; equiv:None)
Variables: i,ii,ii1:index[const]
H: exec@S(ii, i) && SCpt i@S(ii, i) ~< SCpt i@S(ii1, i) = orderOk
Hap: happens(S(ii, i), S(ii1, i))
Hexec: exec@S(ii1, i)
Ht: S(ii, i) > S(ii1, i)
Meq: SCpt i@S(ii1, i) ~< SCpt i@S(ii, i) = orderOk
Meq0: SCpt i@S(ii, i) ~< SCpt i@S(ii, i) = orderOk
----------------------------------------
S(ii, i) < S(ii1, i)


by use orderStrict with SCpt(i)@S(ii,i),SCpt(i)@S(ii,i).
[> Line 475: by (have) [goal> lemma monotonicity is proved


Qed.
lemma monotonicity @system:(set:default; equiv:None) :
forall (ii,ii1,i:index),
happens(S(ii, i), S(ii1, i)) =>
exec@S(ii1, i) &&
exec@S(ii, i) && SCpt i@S(ii, i) ~< SCpt i@S(ii1, i) = orderOk =>
S(ii, i) < S(ii1, i)
Exiting proof mode.

Press the left and right arrows to do and undo an instruction.

Alternatively, you can double-click on an instruction.

This zone shows a Squirrel file. You can double-click on a comment to collapse it for better readabilility.

This zone shows the output given by Squirrel.

This zone shows the output of the previous instruction, to help identifying the change caused by the instruction.

Previously: