https://github.com/EasyCrypt/easycrypt
Revision f0e15c248eb7b9e7eae2ec84f7b78d8bae827899 authored by Romain Tetley on 15 June 2023, 14:57:04 UTC, committed by GitHub on 15 June 2023, 14:57:04 UTC
* Turned the files in src into a lib called core. * Removed reference to dead code in dune file The file ecCoreHiPhl was removed as dead code, no need to exclude it in the dune file anymore. --------- Co-authored-by: Romain Tetley <rtetley@inria.fr>
1 parent 8232d04
Tip revision: f0e15c248eb7b9e7eae2ec84f7b78d8bae827899 authored by Romain Tetley on 15 June 2023, 14:57:04 UTC
Turned the files in src into a lib called Core. (#397)
Turned the files in src into a lib called Core. (#397)
Tip revision: f0e15c2
upto_syntaxtic.ec
require import AllCore Distr StdOrder.
module M = {
var bad : bool
proc set_bad () = {
var r;
r <- 0;
bad <- true;
r <- r + 1;
return r;
}
proc set_bad_if (x:int) = {
var r;
r <- 0;
if (x = 0) {
bad <- true;
r <@ set_bad ();
r <- r + 1;
}
return r;
}
proc set_bad_while (x:int) = {
var r, i;
r <- 0;
i <- 0;
while (i <= 10) {
r <@ set_bad();
r <@ set_bad_if(r);
if (i = x) {
bad <- true;
r <- 100;
}
}
return r;
}
proc main() = {
var x;
x <- 0;
bad <- false;
x <- 1;
x <@ set_bad();
set_bad_if(100);
set_bad_while(x);
return x;
}
proc main_noinit (x:int) = {
x <@ set_bad();
set_bad_if(100);
set_bad_while(x);
return x;
}
}.
module M' = {
import var M
proc set_bad () = {
var r;
r <- 0;
bad <- true;
return r;
}
proc set_bad_if (x:int) = {
var r;
r <- 0;
if (x = 0) {
bad <- true;
r <@ set_bad ();
r <- r + 2;
r <- r + 10;
r <@ set_bad();
}
return r;
}
proc set_bad_while (x:int) = {
var r, i;
r <- 0;
i <- 0;
while (i <= 10) {
r <@ set_bad();
r <@ set_bad_if(r);
if (i = x) {
bad <- true;
}
}
return r;
}
proc main() = {
var x;
x <- 0;
bad <- false;
x <- 1;
x <@ set_bad();
set_bad_if(100);
set_bad_while(x);
return x;
}
proc main_noinit (x:int) = {
x <@ set_bad();
set_bad_if(100);
set_bad_while(x);
return x;
}
}.
lemma Pr_main_E &m :
Pr[M.main() @ &m : res = 0 /\ !M.bad] = Pr[M'.main() @ &m : res = 0 /\ !M.bad].
proof. byupto. qed.
lemma Pr_main_nbad &m :
Pr[M.main() @ &m : !M.bad] = Pr[M'.main() @ &m : !M.bad].
proof. byupto. qed.
lemma Pr_noinit_E &m :
Pr[M.main_noinit(10) @ &m : res = 0 /\ !M.bad] = Pr[M'.main_noinit(10) @ &m : res = 0 /\ !M.bad].
proof. byupto. qed.
lemma Pr_noinit_nbad &m :
Pr[M.main_noinit(7) @ &m : !M.bad] = Pr[M'.main_noinit(7) @ &m : !M.bad].
proof. byupto. qed.
module type OT = {
proc set_bad () : int
proc set_bad_if (x:int) : int
proc set_bad_while (x:int) : int
}.
module type Adv (O:OT) = {
proc main () : int
}.
lemma test (A<:Adv {-M} ) &m :
Pr[A(M).main () @ &m : res = 100 /\ !M.bad] = Pr[A(M').main () @ &m : res = 100 /\ !M.bad].
proof. byupto. qed.
(* ------------------------------------------- *)
lemma abs_upto1 &m :
Pr[M.main() @ &m : res = 0] - Pr[M'.main() @ &m : res = 0] <= Pr[M.main() @ &m : res = 0 /\ M.bad].
proof.
rewrite Pr[mu_split M.bad].
have -> : Pr[M'.main() @ &m : res = 0] =
Pr[M'.main() @ &m : res = 0 /\ M.bad] + Pr[M'.main() @ &m : res = 0 /\ !M.bad] by rewrite Pr[mu_split M.bad].
have -> : Pr[M'.main() @ &m : res = 0 /\ !M.bad] = Pr[M.main() @ &m : res = 0 /\ !M.bad].
+ byupto.
smt(mu_bounded).
qed.
(* remove [res = 0] *)
lemma abs_upto2 &m :
Pr[M.main() @ &m : res = 0] - Pr[M'.main() @ &m : res = 0] <= Pr[M.main() @ &m : M.bad].
proof.
rewrite Pr[mu_split M.bad].
have -> : Pr[M'.main() @ &m : res = 0] =
Pr[M'.main() @ &m : res = 0 /\ M.bad] + Pr[M'.main() @ &m : res = 0 /\ !M.bad] by rewrite Pr[mu_split M.bad].
have -> : Pr[M'.main() @ &m : res = 0 /\ !M.bad] = Pr[M.main() @ &m : res = 0 /\ !M.bad].
+ byupto.
have : Pr[M.main() @ &m : res = 0 /\ M.bad] <= Pr[M.main() @ &m : M.bad].
+ by rewrite Pr[mu_sub].
smt(mu_bounded).
qed.
require import StdOrder.
import RealOrder.
(* abs value *)
lemma abs_upto_max1 &m :
`| Pr[M.main() @ &m : res = 0] - Pr[M'.main() @ &m : res = 0]| <=
maxr Pr[M.main() @ &m : res = 0 /\ M.bad] Pr[M'.main() @ &m : res = 0 /\ M.bad].
proof.
rewrite Pr[mu_split M.bad].
have -> : Pr[M'.main() @ &m : res = 0] =
Pr[M'.main() @ &m : res = 0 /\ M.bad] + Pr[M'.main() @ &m : res = 0 /\ !M.bad] by rewrite Pr[mu_split M.bad].
have -> : Pr[M'.main() @ &m : res = 0 /\ !M.bad] = Pr[M.main() @ &m : res = 0 /\ !M.bad].
+ byupto.
smt(mu_bounded).
qed.
(* abs value : remove [res = 0] *)
lemma abs_upto_max2 &m :
`| Pr[M.main() @ &m : res = 0] - Pr[M'.main() @ &m : res = 0]| <=
maxr Pr[M.main() @ &m : M.bad] Pr[M'.main() @ &m : M.bad].
proof.
have := abs_upto_max1 &m.
have : Pr[M.main() @ &m : res = 0 /\ M.bad] <= Pr[M.main() @ &m : M.bad] by rewrite Pr[mu_sub].
have /#: Pr[M'.main() @ &m : res = 0 /\ M.bad] <= Pr[M'.main() @ &m : M.bad] by rewrite Pr[mu_sub].
qed.
(* This is the core tactic *)
(* [1: E /\ !bad] = [2: E /\ !bad] *)
lemma test1 &m :
Pr[M.main() @ &m : res = 0 /\ !M.bad] = Pr[M'.main() @ &m : res = 0 /\ !M.bad].
byupto.
qed.
(* This are build on top of the core tactic *)
lemma test1_sub &m :
Pr[M.main() @ &m : res = 0] - Pr[M'.main() @ &m : res = 0] =
Pr[M.main() @ &m : res = 0 /\ M.bad] - Pr[M'.main() @ &m : res = 0 /\ M.bad].
byupto.
qed.
(* [1: E] <= [1: E /\ !BAD] + [1: E /\ BAD] *)
lemma test2 &m :
Pr[M.main() @ &m : res = 0] <=
Pr[M.main() @ &m : res = 0 /\ !M.bad] + Pr[M.main() @ &m : res = 0 /\ M.bad].
byupto.
qed.
(* [1: E] <= [2: E /\ !BAD] + [1: E /\ BAD] *)
lemma test3 &m :
Pr[M.main() @ &m : res = 0] <=
Pr[M'.main() @ &m : res = 0 /\ !M.bad] + Pr[M.main() @ &m : res = 0 /\ M.bad].
byupto.
qed.
(* [1: E] <= [2: E] + [1: E /\ BAD] *)
lemma test4 &m :
Pr[M.main() @ &m : res = 0] <=
Pr[M'.main() @ &m : res = 0] + Pr[M.main() @ &m : res = 0 /\ M.bad].
byupto.
qed.
(* [1: E] <= [2: E /\ !BAD] + [1:BAD] *)
lemma test5 &m :
Pr[M.main() @ &m : res = 0] <=
Pr[M'.main() @ &m : res = 0 /\ !M.bad] + Pr[M.main() @ &m : M.bad].
byupto.
qed.
(* [1: E] <= [2: E] + [1:BAD] *)
lemma test6 &m :
Pr[M.main() @ &m : res = 0] <=
Pr[M'.main() @ &m : res = 0] + Pr[M.main() @ &m : M.bad].
byupto.
qed.
(* `| [1: E] - [2: E]| < `| [1: E /\ bad] - [2: E /\ bad]| *)
lemma test7 &m :
`| Pr[M.main() @ &m : res = 0] - Pr[M'.main() @ &m : res = 0] | <=
`| Pr[M.main() @ &m : res = 0 /\ M.bad] - Pr[M'.main() @ &m : res = 0 /\ M.bad ] |.
byupto.
qed.
(* `| [1: E] - [2: E]| < maxr [1: E /\ bad] [2: E /\ bad] *)
lemma test8 &m :
`| Pr[M.main() @ &m : res = 0] - Pr[M'.main() @ &m : res = 0] | <=
maxr Pr[M.main() @ &m : res = 0 /\ M.bad] Pr[M'.main() @ &m : res = 0 /\ M.bad ].
byupto.
qed.
(* `| [1: E] - [2: E]| < maxr [1: bad] [2: E /\ bad] *)
lemma test9 &m :
`| Pr[M.main() @ &m : res = 0] - Pr[M'.main() @ &m : res = 0] | <=
maxr Pr[M.main() @ &m : M.bad] Pr[M'.main() @ &m : res = 0 /\ M.bad ].
byupto.
qed.
(* `| [1: E] - [2: E]| < maxr [1: E /\ bad] [2: bad] *)
lemma test10 &m :
`| Pr[M.main() @ &m : res = 0] - Pr[M'.main() @ &m : res = 0] | <=
maxr Pr[M.main() @ &m : res = 0 /\ M.bad] Pr[M'.main() @ &m : M.bad ].
byupto.
qed.
(* `| [1: E] - [2: E]| < maxr [1: E] [2: bad] *)
lemma test12 &m :
`| Pr[M.main() @ &m : res = 0] - Pr[M'.main() @ &m : res = 0] | <=
maxr Pr[M.main() @ &m : M.bad] Pr[M'.main() @ &m : M.bad ].
byupto.
qed.
Computing file changes ...