You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
/-- A CommitmentScheme is a structure over four spaces:
8
+
M: Message space
9
+
C: Commitment space
10
+
O: Opening value space
11
+
K: Key space
12
+
13
+
And that contains three algorithms:
14
+
setup: returns a public parameter and associated randomness
15
+
commit: given the public parameter and a message produces a commitment and an opening value
16
+
verify: given the public parameter, message and associated commit and opening value returns 1 when the commit opens to the given message and 0 otherwise.-/
7
17
structureCommitmentScheme (M C O K : Type) where
8
18
setup : PMF (K × O)
9
19
commit : K → M → PMF (C × O)
10
20
verify : K → M → C → O → ZMod 2
11
21
22
+
23
+
/-- The structure of binding adversary guesses for use in the computational binding game.-/
12
24
structureBindingGuess (M C O : Type) where
13
25
c : C
14
26
m : M
15
27
m' : M
16
28
o : O
17
-
o': O
29
+
o': O
18
30
31
+
/-- The structure of the hiding adversary for use in the computational hiding game.-/
19
32
structureTwoStageAdversary (K M C : Type) where
20
-
State : Type
21
-
stage1 : K → PMF ((M × M) × State)
22
-
stage2 : C → State → PMF (ZMod 2)
33
+
state : Type
34
+
stage1 : K → PMF ((M × M) × state)
35
+
stage2 : C → state → PMF (ZMod 2)
23
36
24
37
namespace Commitment
25
38
26
-
noncomputablesection
27
39
variable {M C O K : Type}
28
-
variable (scheme : CommitmentScheme M C O K)
29
40
41
+
/-- For any public parameters `h` and any message `m` if `commit` outputs a commitment `c` and opening value `o`, then `verify h m c o` accepts with probability 1.-/
30
42
defcorrectness (scheme : CommitmentScheme M C O K) : Prop :=
31
-
∀ (h : K) (m : M),
32
-
PMF.bind (scheme.commit h m) (fun (commit, opening_val) => pure $ scheme.verify h m commit opening_val) = pure 1
43
+
∀ (h : K) (m : M), (scheme.commit h m |>.bind fun (c, o) =>
44
+
pure <| scheme.verify h m c o) = pure 1
33
45
34
-
-- Perfect binding
46
+
/-- A commitment scheme with public parameter `h` is perfectly binding if no commitment `c` can be opened to two different messages. For two purported openings `(m,o)` and `(m',o')` both verifying for the same `c`, the messages must be equal (`m = m'`). -/
35
47
defperfect_binding (scheme : CommitmentScheme M C O K) : Prop :=
36
48
∀ (h : K) (c : C) (m m' : M) (o o' : O),
37
49
scheme.verify h m c o = 1 →
38
-
scheme.verify h m' c o' = 1 →
39
-
m = m'
40
-
-- Equivalent to:
41
-
--if scheme.verify h m c o = scheme.verify h m' c o' then true else false
42
-
43
-
-- Computational binding game
44
-
-- Security depends on generating the parameters correctly, but at this level probably alright to have the group and generator fixed
45
-
-- h should be inside the game, because its unique to a specific run
46
-
defcomp_binding_game (scheme : CommitmentScheme M C O K)
47
-
(A' : K → PMF (BindingGuess M C O)) : PMF $ ZMod 2 :=
48
-
openscoped Classical in
49
-
PMF.bind scheme.setup (fun (h, _) =>
50
-
PMF.bind (A' h) (fun guess =>
51
-
if scheme.verify h guess.m guess.c guess.o = 1 ∧ scheme.verify h guess.m' guess.c guess.o' = 1 ∧ guess.m ≠ guess.m' then pure 1else pure 0 ))
52
-
53
-
defcomputational_binding [DecidableEq M] (scheme : CommitmentScheme M C O K) (ε : ENNReal) : Prop :=
54
-
∀ (A' : K → PMF (BindingGuess M C O )), comp_binding_game scheme A' 1 ≤ ε
55
-
56
-
57
-
-- Perfect hiding
58
-
defdo_commit (scheme: CommitmentScheme M C O K) (m : M) : PMF C :=
59
-
PMF.bind scheme.setup (fun (h, _) =>
60
-
PMF.bind (scheme.commit h m) (fun (c, _) => pure c))
50
+
scheme.verify h m' c o' = 1 →
51
+
m = m'
61
52
53
+
/-- A commitment scheme is perfectly hiding if for any messages `m` and `m'`, the induced distribution on commitments is the same. Sampling `h ← setup` and then committing to `m` or `m'` under `h` yields identical commitment distributions. -/
62
54
defperfect_hiding (scheme: CommitmentScheme M C O K) : Prop :=
63
-
∀ (m m' : M) (c : C), (do_commit scheme m) c = (do_commit scheme m') c
64
-
65
-
-- Computational hiding game
66
-
defcomp_hiding_game (scheme : CommitmentScheme M C O K) (A : TwoStageAdversary K M C) :=
67
-
PMF.bind scheme.setup (fun (h, _) =>
68
-
PMF.bind (A.stage1 h) (fun ((m₀, m₁), state) =>
69
-
PMF.bind (PMF.uniformOfFintype (ZMod 2)) (fun b =>
70
-
PMF.bind (scheme.commit h (if b = 0then m₀ else m₁)) (fun (c, _) =>
71
-
PMF.bind (A.stage2 c state) (fun b' =>
72
-
pure (1 + b + b'))))))
55
+
∀ (m m' : M) (c : C),
56
+
PMF.bind scheme.setup (fun (h, _) =>
57
+
PMF.bind (scheme.commit h m) (fun (c, _) =>
58
+
pure c)) c
59
+
=
60
+
PMF.bind scheme.setup (fun (h, _) =>
61
+
PMF.bind (scheme.commit h m') (fun (c, _) =>
62
+
pure c)) c
63
+
64
+
/- Computational Binding -/
65
+
66
+
/-- For any adversary `A` that accepts `h ← setup` and outputs a single commitment `c` together with two purported openings `(m,o)` and `(m',o')`, the computational binding game outputs `1` if `c` opens to both `(m,o)` and `(m',o') and the messages differ (`m ≠ m'`). -/
67
+
noncomputabledefcomp_binding_game
68
+
[DecidableEq M] (scheme : CommitmentScheme M C O K)
69
+
(A : K → PMF (BindingGuess M C O)) : PMF (ZMod 2) := do
70
+
let (h, _) ← scheme.setup
71
+
let guess ← A h
72
+
pure (
73
+
if scheme.verify h guess.m guess.c guess.o = 1 ∧
74
+
scheme.verify h guess.m' guess.c guess.o' = 1 ∧
75
+
guess.m ≠ guess.m'
76
+
then1else0 )
77
+
78
+
/-- A commitment scheme is computationally binding if every adversary’s probability of winning the computational binding game is at most `ε`. -/
79
+
defcomputational_binding [DecidableEq M] (scheme : CommitmentScheme M C O K)
80
+
(ε : ENNReal) : Prop :=
81
+
∀ (A' : K → PMF (BindingGuess M C O )), comp_binding_game scheme A' 1 ≤ ε
73
82
83
+
/- Computational Hiding -/
84
+
85
+
/-- For any `TwoStageAdversary` `A`, sample `h ← setup` and give `h` to the adversary’s first stage to produce two challenge messages `m₀, m₁. The computational hiding game samples a uniform bit `b`, computes a commitment to `m_b`, and gives the commitment `c` to the adversary’s second stage. The game outputs a bit indicating whether the adversary’s guess matches `b`. -/
86
+
noncomputabledefcomp_hiding_game
87
+
(scheme : CommitmentScheme M C O K)
88
+
(A : TwoStageAdversary K M C) := do
89
+
let (h, _) ← scheme.setup
90
+
let ((m₀, m₁), state) ← A.stage1 h
91
+
let b ← PMF.uniformOfFintype (ZMod 2)
92
+
let (c, _) ← scheme.commit h (if b = 0then m₀ else m₁)
93
+
let b' ← A.stage2 c state
94
+
pure (1 + b + b')
95
+
96
+
/-- A commitment scheme is computationally hiding if every adversary’s advantage
97
+
over random guessing in the hiding game is at most `ε`. -/
74
98
defcomputational_hiding (scheme : CommitmentScheme M C O K) (ε : ENNReal) : Prop :=
75
99
∀ (A : TwoStageAdversary K M C), comp_hiding_game scheme A 1 - 1/2 ≤ ε
0 commit comments