Skip to content

Commit ebec96e

Browse files
oskgodfirsovdominique-unruh
authored
add Reflection theory (#794)
Adapted from Unruh, Firsov, "Reflection, rewinding, and coin-toss in EasyCrypt, CPP 2022, doi: 10.1145/3497775.35036 Co-authored-by: Denis Firsov <denis.firsov@gmail.com> Co-authored-by: Dominique Unruh <9913676+dominique-unruh@users.noreply.github.com>
1 parent e6c14f7 commit ebec96e

2 files changed

Lines changed: 108 additions & 0 deletions

File tree

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
(* Theory abstracting over the structure of procedures *)
2+
abstract theory Proc.
3+
type a. (* type of argument to the procedure *)
4+
type r. (* type of result of the procedure *)
5+
6+
(* Module type for procedure. Use wrapper to conform to the interface if needed *)
7+
module type Proc = {
8+
proc p(a: a): r
9+
}.
10+
end Proc.

theories/modules/Reflection.eca

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
(* Originally sourced from *)
2+
(* Unruh, Firsov, "Reflection, rewinding, and coin-toss in EasyCrypt",
3+
CPP 2022, doi: 10.1145/3497775.35036 *)
4+
require import Distr Real List StdBigop ModuleStructure.
5+
(*---*) import Bigreal.BRA.
6+
7+
clone import ModuleStructure.Proc.
8+
9+
section.
10+
11+
declare module P <: Proc.
12+
13+
local module P2 = {
14+
proc sampleFrom (d : (r * (glob P)) distr) = {
15+
var r;
16+
r <$ d;
17+
return r;
18+
}
19+
}.
20+
21+
local lemma gen_fact &m a (l : (r * (glob P)) list): uniq l
22+
=> Pr[ P.p(a) @ &m : (res , (glob P)) \in l ]
23+
= big predT (fun (x : (r * (glob P))) =>
24+
Pr[P.p(a) @ &m: res=x.`1 /\ (glob P) = x.`2])
25+
l.
26+
proof.
27+
move: l; apply list_ind => /= [|x l p1 [x_nin uniq_l]].
28+
- by rewrite Pr[mu_false] big_nil.
29+
rewrite Pr[mu_disjoint] 1:/# big_cons {1}/predT /= (p1 uniq_l).
30+
congr.
31+
rewrite Pr[mu_eq] /#.
32+
qed.
33+
34+
lemma reflection :
35+
exists (D : (glob P) -> a -> (r * glob P) distr),
36+
forall &m po a, mu (D (glob P){m} a) po = Pr[P.p(a) @ &m : po (res, glob P)].
37+
proof.
38+
pose PR := fun (g : glob P) (a : a) (x : r * glob P) =>
39+
choicebd (fun p => forall &m, (glob P){m} = g =>
40+
Pr[P.p(a) @ &m : res=x.`1 /\ (glob P) = x.`2 ] = p).
41+
pose D := (fun (g : glob P) (a : a) => mk (PR g a)).
42+
exists D.
43+
move => &m po a.
44+
have PRP: (PR (glob P){m}) a = fun (x : (r * (glob P)))
45+
=> Pr[P.p(a) @ &m: res = x.`1 /\ (glob P) = x.`2 ].
46+
- apply fun_ext => x.
47+
have /=chs:=choicebdP (fun p =>
48+
Pr[P.p(a) @ &m : res = x.`1 /\ (glob P) = x.`2] = p).
49+
rewrite chs.
50+
- by exists (Pr[P.p(a) @ &m : res = x.`1 /\ (glob P) = x.`2]).
51+
rewrite /PR.
52+
congr.
53+
apply fun_ext => p.
54+
rewrite eq_iff; split => [/#|<- &n gl_eq].
55+
byequiv (_: ={arg, glob P} ==> ={res, glob P})=> //; 1:sim; smt().
56+
have distr_PR: isdistr (PR (glob P){m} a).
57+
- have : (forall (s : ((r * (glob P)) list)), uniq s =>
58+
big predT (PR (glob P){m} a) s <= 1%r).
59+
+ rewrite PRP.
60+
apply list_ind => /=[|x l q1 q2].
61+
* by rewrite big_nil.
62+
by rewrite -(gen_fact &m a (x :: l)) 2:Pr[mu_le1]; 1:apply q2.
63+
move => fact1.
64+
have: (forall (x : r * (glob P)), 0%r <= PR (glob P){m} a x).
65+
+ by move => x; rewrite PRP /= Pr[mu_ge0].
66+
by move => fact2; split.
67+
have <-: Pr[ P2.sampleFrom((D (glob P){m} a)) @ &m : po res ]
68+
= mu (D (glob P){m} a) po.
69+
- byphoare (_ : d = (D (glob P){m} a) ==> _) => //.
70+
proc; rnd; auto => &hr /=.
71+
byequiv => //.
72+
conseq (_: _ ==> res{1}.`1 = res{2} /\ res{1}.`2 = (glob P){2}); 1:smt().
73+
bypr (res{1}) (res, glob P){2} => // &1 &2 aa [->][gl_eq ->].
74+
have <-: Pr[P.p(a) @ &m : res = aa.`1 /\ (glob P) = aa.`2]
75+
= Pr[P.p(a) @ &2 : (res , glob P) = aa].
76+
- byequiv (_: ={arg, glob P} ==> ={res, glob P})=> //; 1:sim; smt().
77+
byphoare (_ : d = (D (glob P){m} a) ==> _) => //.
78+
proc; rnd; skip => &hr /= -> />.
79+
rewrite muK //#.
80+
qed.
81+
82+
lemma reflection_glob : exists (D : (glob P) -> a -> (glob P) distr),
83+
forall &m po a, mu (D (glob P){m} a) po = Pr[P.p(a) @ &m : po (glob P)].
84+
proof.
85+
elim reflection => /> D DP.
86+
exists (fun ga i => dmap (D ga i) (fun (x : r * (glob P)) => x.`2)) => /> &m po a.
87+
by rewrite -(DP &m (fun (x : r * (glob P)) => po x.`2) a) dmapE.
88+
qed.
89+
90+
lemma reflection_res : exists (D : (glob P) -> a -> r distr),
91+
forall &m po a, mu (D (glob P){m} a) po = Pr[P.p(a) @ &m : po res ].
92+
proof.
93+
elim reflection => /> D DP.
94+
exists (fun ga i => dmap (D ga i) (fun (x : r * (glob P)) => x.`1)) => /> &m po a.
95+
by rewrite -(DP &m (fun (x : r * (glob P)) => po x.`1) a) dmapE.
96+
qed.
97+
98+
end section.

0 commit comments

Comments
 (0)