Skip to content

Commit dba6b2d

Browse files
committed
feat: computational hiding complete
1 parent aad7979 commit dba6b2d

1 file changed

Lines changed: 25 additions & 105 deletions

File tree

VerifiedCommitments/ElgamalCommitments.lean

Lines changed: 25 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -48,50 +48,6 @@ def Assumption (ε : ENNReal) : Prop := (Game0 G g q D 1) - (Game1 G g q D 1)
4848

4949
end DDH
5050

51-
namespace PKE
52-
variable {K M C O A_state: Type} [DecidableEq M]
53-
(setup : PMF (K × O))
54-
(commit : K → M → PMF (C × O))
55-
(verify : K → M → C → O → ZMod 2)
56-
(adversary : TwoStageAdversary K M C)
57-
58-
/-
59-
Executes the a public-key protocol defined by keygen,
60-
encrypt, and decrypt
61-
-/
62-
noncomputable def commit_verify (m : M) : PMF (ZMod 2) :=
63-
do
64-
let (h, _) ← setup
65-
let (c, o) ← commit h m
66-
pure (verify h m c o)
67-
68-
/-
69-
A public-key encryption protocol is correct if decryption undoes
70-
encryption with probability 1
71-
-/
72-
def pke_correctness : Prop := ∀ (m : M), commit_verify setup commit verify m = pure 1
73-
74-
/-
75-
The semantic security game.
76-
Returns 1 if the attacker A2 guesses the correct bit
77-
-/
78-
-- noncomputable def ComputationalHidingGame : PMF (ZMod 2):=
79-
-- do
80-
-- let (h, _) ← setup
81-
-- let ((m, m'), a_state) ← adversary.stage1 h
82-
-- let b ← PMF.uniformOfFintype (ZMod 2)
83-
-- let (c, _) ← commit h (if b = 0 then m else m')
84-
-- let b' ← adversary.stage2 c a_state
85-
-- pure (1 + b + b')
86-
87-
88-
-- SSG(A) denotes the event that A wins the semantic security game
89-
--local notation `Pr[SSG(A)]` := (SSG keygen encrypt A1 A2 1 : ℝ)
90-
91-
-- def pke_semantic_security (ε : ENNReal) : Prop := (ComputationalHidingGame setup commit adversary 1) - 1/2 ≤ ε
92-
93-
end PKE
94-
9551
namespace Elgamal
9652

9753
class ElgamalParameters (G : Type) extends
@@ -105,7 +61,6 @@ class ElgamalParameters (G : Type) extends
10561
card_eq : Fintype.card G = q
10662
g_gen_G : ∀ (x : G), x ∈ Subgroup.zpowers g
10763
G_card_q : Fintype.card G = q
108-
adversary : TwoStageAdversary G G (G × G)
10964

11065
-- Make instances available
11166
variable {G : Type} [params : ElgamalParameters G]
@@ -131,27 +86,12 @@ noncomputable def scheme : CommitmentScheme G (G × G) (ZMod params.q) G :=
13186
commit := commit,
13287
verify := verify
13388
}
134-
135-
def pke_semantic_security' (ε : ENNReal) : Prop := (Commitment.comp_hiding_game scheme params.adversary) 1 - 1/2 ≤ ε
136-
137-
13889
/-
13990
-----------------------------------------------------------
14091
Proof of correctness of ElGamal
14192
-----------------------------------------------------------
14293
-/
14394

144-
theorem elgamal_pke_correctness : @PKE.pke_correctness G G (G × G) (ZMod params.q) setup commit verify := by
145-
intro m
146-
unfold setup commit verify PKE.commit_verify
147-
simp only [bind_pure_comp, Functor.map_map, bind_map_left]
148-
apply bind_skip_const'
149-
intro x
150-
apply bind_skip_const'
151-
intro y
152-
simp only [Function.comp_apply]
153-
rfl
154-
15595
theorem elgamal_commitment_correctness : Commitment.correctness (@scheme G params) := by
15696
intro h m
15797
show PMF.bind (scheme.commit h m) _ = _
@@ -166,14 +106,6 @@ theorem elgamal_commitment_correctness : Commitment.correctness (@scheme G param
166106
-----------------------------------------------------------
167107
-/
168108

169-
noncomputable def D (gx gy gz : G) : PMF (ZMod 2) :=
170-
do
171-
let ((m₀, m₁), a_state) ← params.adversary.stage1 gx
172-
let b ← PMF.uniformOfFintype (ZMod 2)
173-
let mb ← pure (if b = 0 then m₀ else m₁)
174-
let b' ← params.adversary.stage2 ⟨gy, (gz * mb)⟩ a_state
175-
pure (1 + b + b')
176-
177109
noncomputable def D_from_adversary (A : TwoStageAdversary G G (G × G)) : G → G → G → PMF (ZMod 2) :=
178110
fun gx gy gz => do
179111
let ((m₀, m₁), state) ← A.stage1 gx
@@ -187,8 +119,8 @@ noncomputable def D_from_adversary (A : TwoStageAdversary G G (G × G)) : G →
187119
winning the semantic security game (i.e. guessing the correct bit),
188120
w.r.t. ElGamal is equal to the probability of D winning the game DDH0.
189121
-/
190-
theorem ComputationalHiding_DDH0 : Commitment.comp_hiding_game scheme params.adversary = DDH.Game0 G params.g params.q D := by
191-
simp only [Commitment.comp_hiding_game, DDH.Game0, bind, scheme, setup, commit, D]
122+
theorem ComputationalHiding_DDH0 (A : TwoStageAdversary G G (G × G)) : Commitment.comp_hiding_game scheme A = DDH.Game0 G params.g params.q (D_from_adversary A) := by
123+
simp only [Commitment.comp_hiding_game, DDH.Game0, bind, scheme, setup, commit, D_from_adversary]
192124
simp_rw [PMF.bind_bind (PMF.uniformOfFintype (ZMod params.q))]
193125
apply bind_skip'
194126
intro x
@@ -202,29 +134,29 @@ theorem ComputationalHiding_DDH0 : Commitment.comp_hiding_game scheme params.adv
202134
intro y
203135
rw [pow_mul params.g x.val y.val]
204136

205-
noncomputable def Game1 : PMF (ZMod 2) :=
137+
noncomputable def Game1 (A : TwoStageAdversary G G (G × G)) : PMF (ZMod 2) :=
206138
do
207139
let x ← PMF.uniformOfFintype (ZMod params.q)
208140
let y ← PMF.uniformOfFintype (ZMod params.q)
209-
let ((m₀, m₁), a_state) ← params.adversary.stage1 (params.g^x.val)
141+
let ((m₀, m₁), a_state) ← A.stage1 (params.g^x.val)
210142
let b ← PMF.uniformOfFintype (ZMod 2)
211143
let ζ ← (do
212144
let z ← PMF.uniformOfFintype (ZMod params.q)
213145
let mb ← pure (if b = 0 then m₀ else m₁)
214146
pure (params.g^z.val * mb))
215-
let b' ← params.adversary.stage2 ⟨(params.g^y.val), ζ⟩ a_state
147+
let b' ← A.stage2 ⟨(params.g^y.val), ζ⟩ a_state
216148
pure (1 + b + b')
217149

218-
noncomputable def Game2 : PMF (ZMod 2) :=
150+
noncomputable def Game2 (A : TwoStageAdversary G G (G × G)) : PMF (ZMod 2) :=
219151
do
220152
let x ← PMF.uniformOfFintype (ZMod params.q)
221153
let y ← PMF.uniformOfFintype (ZMod params.q)
222-
let (_, a_state) ← params.adversary.stage1 (params.g^x.val)
154+
let (_, a_state) ← A.stage1 (params.g^x.val)
223155
let b ← PMF.uniformOfFintype (ZMod 2)
224156
let ζ ← (do
225157
let z ← PMF.uniformOfFintype (ZMod params.q)
226158
pure (params.g^z.val))
227-
let b' ← params.adversary.stage2 ⟨(params.g^y.val), ζ⟩ a_state
159+
let b' ← A.stage2 ⟨(params.g^y.val), ζ⟩ a_state
228160
pure (1 + b + b')
229161

230162

@@ -233,29 +165,29 @@ do
233165
winning Game1 (i.e. guessing the correct bit) is equal to the
234166
probability of D winning the game DDH1.
235167
-/
236-
theorem Game1_DDH1 : @Game1 G params = DDH.Game1 G params.g params.q D := by
237-
simp only [DDH.Game1, Game1, bind, D]
168+
theorem Game1_DDH1 (A : TwoStageAdversary G G (G × G)) : @Game1 G params A = DDH.Game1 G params.g params.q (D_from_adversary A):= by
169+
simp only [DDH.Game1, Game1, bind, D_from_adversary]
170+
simp only [PMF.bind_bind, mul_ite]
238171
apply bind_skip'
239172
intro x
240173
apply bind_skip'
241174
intro y
242-
simp_rw [PMF.bind_bind (params.adversary.stage1 _)]
175+
-- simp_rw [PMF.bind_bind (A.stage1 _)]
243176
conv_rhs => rw [PMF.bind_comm (PMF.uniformOfFintype (ZMod params.q))]
244177
apply bind_skip'
245178
intro m
246-
simp_rw [PMF.bind_bind (PMF.uniformOfFintype (ZMod params.q))]
179+
-- simp_rw [PMF.bind_bind (PMF.uniformOfFintype (ZMod params.q))]
247180
conv_lhs => rw [PMF.bind_comm (PMF.uniformOfFintype (ZMod 2))]
248181
apply bind_skip'
249182
intro z
250-
conv_rhs => rw [PMF.bind_bind (PMF.uniformOfFintype (ZMod 2))]
183+
-- conv_rhs => rw [PMF.bind_bind (PMF.uniformOfFintype (ZMod 2))]
251184
apply bind_skip'
252185
intro b
253-
simp_rw [PMF.bind_bind]
254-
apply bind_skip'
255-
intro mb
186+
-- simp_rw [PMF.bind_bind]
187+
-- apply bind_skip'
188+
-- intro mb
256189
simp [pure]
257190

258-
259191
lemma exp_bij : Function.Bijective (fun (z : ZMod params.q) => params.g ^ z.val) := by
260192
apply (Fintype.bijective_iff_surjective_and_card _).mpr
261193
simp [params.card_eq]
@@ -340,7 +272,7 @@ lemma G1_G2_lemma3 (m : PMF G) :
340272
winning Game1 (i.e. guessing the correct bit) is equal to the
341273
probability of the attacker winning Game2.
342274
-/
343-
theorem Game1_Game2 : @Game1 G params = @Game2 G params := by
275+
theorem Game1_Game2 (A : TwoStageAdversary G G (G × G)) : @Game1 G params A = @Game2 G params A := by
344276
simp only [Game1, Game2]
345277
apply bind_skip'
346278
intro x
@@ -406,7 +338,7 @@ lemma G2_uniform_lemma (b' : ZMod 2) : (PMF.uniformOfFintype (ZMod 2)).bind (fun
406338
The probability of the attacker (i.e. the composition of A1 and A2)
407339
winning Game2 (i.e. guessing the correct bit) is equal to a coin flip.
408340
-/
409-
theorem Game2_uniform : @Game2 G params = PMF.uniformOfFintype (ZMod 2) := by
341+
theorem Game2_uniform (A : TwoStageAdversary G G (G × G)) : @Game2 G params A = PMF.uniformOfFintype (ZMod 2) := by
410342
simp [Game2, bind]
411343
apply bind_skip_const'
412344
intro x
@@ -435,39 +367,27 @@ variable (ε : ENNReal)
435367
-/
436368

437369

438-
theorem elgamal_semantic_security (DDH_G : DDH.Assumption G params.g params.q D ε) :
439-
@pke_semantic_security' G params ε := by
440-
simp only [pke_semantic_security']
370+
theorem hiding_from_ddh_single_adversary
371+
(A : TwoStageAdversary G G (G × G))
372+
(DDH_assumption : DDH.Assumption G params.g params.q (D_from_adversary A) ε) :
373+
Commitment.comp_hiding_game scheme A 1 - 1/2 ≤ ε := by
441374
rw [ComputationalHiding_DDH0]
442375
have h : ((PMF.uniformOfFintype (ZMod 2)) 1) = 1/2 := by
443376
simp only [PMF.uniformOfFintype_apply, ZMod.card, Nat.cast_ofNat, one_div]
444377
rw [← h]
445378
rw [← @Game2_uniform G params]
446379
rw [← Game1_Game2]
447380
rw [Game1_DDH1]
448-
exact DDH_G
449-
450-
451-
452-
theorem hiding_from_ddh_single_adversary
453-
(A : TwoStageAdversary G G (G × G))
454-
(DDH_assumption : DDH.Assumption G params.g params.q (D_from_adversary A) ε) :
455-
Commitment.comp_hiding_game scheme A 1 - 1/2 ≤ ε := by
456-
simp only [Commitment.comp_hiding_game]
457-
-- unfold Commitment.comp_hiding_game
458-
simp only [PMF.bind_apply, PMF.uniformOfFintype_apply, ZMod.card, Nat.cast_ofNat, tsum_fintype,
459-
one_div, tsub_le_iff_right]
381+
exact le_of_eq_of_le rfl DDH_assumption
460382

461-
sorry
462383

463384
theorem computational_hiding_from_ddh (ε : ENNReal)
464385
(DDH_hard : ∀ (D : G → G → G → PMF (ZMod 2)), DDH.Assumption G params.g params.q D ε) :
465386
Commitment.computational_hiding (@scheme G params) ε := by
466387
unfold Commitment.computational_hiding
467388
intro hA
468389
apply hiding_from_ddh_single_adversary
469-
sorry
470-
-- exact DDH_hard D
390+
exact DDH_hard (D_from_adversary hA)
471391

472392

473393
end Elgamal

0 commit comments

Comments
 (0)