Skip to content

Commit bf7ca55

Browse files
authored
Merge branch 'main' into eHoare-example
2 parents 38521aa + 7640b32 commit bf7ca55

23 files changed

+1847
-209
lines changed
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
(* GlobalHybridExamp1.ec *)
2+
3+
(* We use theories/crypto/GlobalHybrid.ec to relate the probabilities
4+
of a "real" and an "ideal" game returning true.
5+
6+
The real game initializes a boolean to true, and then loops m - 1
7+
times, where at each iteration it has a 1 / 2^n probability of
8+
setting the boolean to false. Once the loop terminates, it returns
9+
the boolean.
10+
11+
The ideal game always returns true. *)
12+
13+
require import AllCore Real Distr StdOrder StdBigop GlobalHybrid.
14+
import RealOrder Bigreal BRA.
15+
16+
op n : {int | 1 <= n} as ge1_n.
17+
18+
type t. (* we want t to have 2 ^ n elements, including def *)
19+
20+
op def : t.
21+
22+
op [lossless] dt : t distr.
23+
24+
axiom mu1_dt (x : t) : mu1 dt x = 1%r / (2 ^ n)%r.
25+
26+
lemma dt_uni : is_uniform dt.
27+
proof. move => x y _ _; by rewrite !mu1_dt. qed.
28+
29+
lemma dt_fu : is_full dt.
30+
proof.
31+
rewrite funi_ll_full.
32+
move => x y; by rewrite !mu1_dt.
33+
rewrite dt_ll.
34+
qed.
35+
36+
op m : {int | 1 <= m} as ge1_m.
37+
38+
module GReal = {
39+
proc main() : bool = {
40+
var b <- true;
41+
var i : int <- 1;
42+
var x : t;
43+
while (i < m) {
44+
x <$ dt;
45+
if (x = def) {
46+
b <- false;
47+
}
48+
i <- i + 1;
49+
}
50+
return b;
51+
}
52+
}.
53+
54+
module GIdeal = {
55+
proc main() : bool = {
56+
return true;
57+
}
58+
}.
59+
60+
(* we want to prove:
61+
62+
lemma GReal_GIdeal &m :
63+
`|Pr[GReal.main() @ &m : res] - Pr[GIdeal.main() @ &m : res]| <=
64+
(m - 1)%r * (1%r / (2 ^ n)%r).
65+
*)
66+
67+
module Hybrid : HYBRID = {
68+
proc main(i : int) : bool = {
69+
var b <- true;
70+
var x : t;
71+
(* start from i: *)
72+
while (i < m) {
73+
x <$ dt;
74+
if (x = def) {
75+
b <- false;
76+
}
77+
i <- i + 1;
78+
}
79+
return b;
80+
}
81+
}.
82+
83+
lemma GReal_Hybrid_1 &m :
84+
Pr[GReal.main() @ &m : res] = Pr[Hybrid.main(1) @ &m : res].
85+
proof.
86+
byequiv => //; proc.
87+
seq 2 1 : (={b, i} /\ i{1} = 1); first auto.
88+
sim.
89+
qed.
90+
91+
lemma Hybrid_m &m :
92+
Pr[Hybrid.main(m) @ &m : res] = Pr[GIdeal.main() @ &m : res].
93+
proof.
94+
byequiv => //; proc; sp 1 0.
95+
rcondf{1} 1; auto.
96+
qed.
97+
98+
(* we use upto bad reasoning *)
99+
100+
module GBad1 = {
101+
var bad : bool (* bad event *)
102+
103+
proc main(i : int) : bool = {
104+
var b <- true;
105+
var x : t;
106+
bad <- false;
107+
x <$ dt;
108+
if (x = def) {
109+
bad <- true; (* bad event *)
110+
b <- false; (* assignment to b *)
111+
}
112+
i <- i + 1;
113+
while (i < m) { (* rest as usual *)
114+
x <$ dt;
115+
if (x = def) {
116+
b <- false;
117+
}
118+
i <- i + 1;
119+
}
120+
return b;
121+
}
122+
}.
123+
124+
module GBad2 = {
125+
var bad : bool
126+
127+
proc main(i : int) : bool = {
128+
var b <- true;
129+
var x : t;
130+
bad <- false;
131+
x <$ dt;
132+
if (x = def) {
133+
bad <- true; (* bad event *)
134+
(* but no assignment to b *)
135+
}
136+
i <- i + 1;
137+
while (i < m) { (* rest as usual *)
138+
x <$ dt;
139+
if (x = def) {
140+
b <- false;
141+
}
142+
i <- i + 1;
143+
}
144+
return b;
145+
}
146+
}.
147+
148+
lemma Hybrid_step (i' : int) &m :
149+
1 <= i' < m =>
150+
`|Pr[Hybrid.main(i') @ &m : res] - Pr[Hybrid.main(i' + 1) @ &m : res]| <=
151+
1%r / (2 ^ n)%r.
152+
proof.
153+
move => [ge1_i' lt_i'_m].
154+
have -> : Pr[Hybrid.main(i') @ &m : res] = Pr[GBad1.main(i') @ &m : res].
155+
byequiv => //; proc; sp 1 2.
156+
rcondt{1} 1; first auto.
157+
sim.
158+
have -> : Pr[Hybrid.main(i' + 1) @ &m : res] = Pr[GBad2.main(i') @ &m : res].
159+
byequiv => //; proc; sp 1 2.
160+
seq 0 3 : (={i, b}); first auto.
161+
sim.
162+
rewrite (ler_trans Pr[GBad2.main(i') @ &m : GBad2.bad]).
163+
byequiv
164+
(_ :
165+
={i} ==> GBad1.bad{1} = GBad2.bad{2} /\ (! GBad2.bad{2} => ={res})) :
166+
GBad1.bad => //.
167+
proc.
168+
seq 5 5 :
169+
(GBad1.bad{1} = GBad2.bad{2} /\ ={i} /\
170+
(!GBad2.bad{2} => ={b})); first auto.
171+
case (GBad1.bad{1}).
172+
while (={i}); auto.
173+
while (={i, b}); auto; smt().
174+
smt().
175+
byphoare => //; proc; sp.
176+
seq 3 :
177+
GBad2.bad
178+
(1%r / (2 ^ n)%r)
179+
1%r
180+
(1%r - (1%r / (2 ^ n)%r))
181+
0%r.
182+
auto.
183+
wp; rnd (pred1 def); auto; smt(mu1_dt).
184+
conseq (_ : _ ==> _ : = 1%r).
185+
while (true) (m - i) => [z |].
186+
auto; smt(dt_ll).
187+
auto; smt().
188+
hoare; while (true); auto.
189+
trivial.
190+
qed.
191+
192+
lemma GReal_GIdeal &m :
193+
`|Pr[GReal.main() @ &m : res] - Pr[GIdeal.main() @ &m : res]| <=
194+
(m - 1)%r * (1%r / (2 ^ n)%r).
195+
proof.
196+
rewrite (GReal_Hybrid_1 &m) -(Hybrid_m &m).
197+
rewrite (hybrid_simp _ _ Hybrid) 1:ge1_m => i ge1_i_lt_m.
198+
by rewrite Hybrid_step.
199+
qed.

0 commit comments

Comments
 (0)