2. Secret Sharing Scheme
We now define a general secret sharing scheme over
a set of n participants \mathcal{P} = \{P_1, \dots, P_n\}.
Let \mathcal{S} denote the domain of possible secrets,
where |\mathcal{S}| \ge 2. Each participant P_i
receives a share from a finite set \mathcal{V}_i.
The scheme is randomized, utilizing a finite set of
random strings \mathcal{R} equipped with a probability
distribution \mu. Unless otherwise stated, we assume
\mu is the uniform distribution over \mathcal{R}.
We assume that the variable Secret has type u, while the
random element Random has type v.
import Mathlib.Tactic import Mathlib.Data.Fintype.Basic import Mathlib.Probability.ProbabilityMassFunction.Basic import Mathlib.Probability.Distributions.Uniform
section SecretSharingScheme
universe u v
The data structure for secret sharing scheme.
/--
A secret sharing scheme with `n` participants consist
of the following data.
`Secret` is a finite type and has size at least 2
`Random` is another finite type that is nonempty
The share of participant `i` has type `Share i`,
for i = 0,1,..., n-1.
We assume that `Share i` is a finite type for all `i`.
Share is a function that maps `Fin n` to `Type u`,
representing the share of the `n` participants
A `dealer` is a function that maps a pair of `Secret`
and `Random` to the `n` shares.
-/
structure SecretSharingScheme (n : ℕ) where
Secret : Type u
Random : Type v
[hSecret : Fintype Secret]
hSecret_card : Fintype.card Secret ≥ 2
: Fin n → Type u
[ : ∀ i, Fintype (Share i)]
[hRandom : Fintype Random]
[hRandomNonempty : Nonempty Random]
μ : PMF Random := PMF.uniformOfFintype Random
dealer : Secret → Random → (∀ i, Share i)
We define the API Secret Sharing Scheme in the namespace
SecretSharingScheme.
namespace SecretSharingScheme
open AccessStructure
/--
Given a share s and a random string `r`, the restriction
of `Π(s,r)` to `A` is denoted `shares_of_set`.
We may also denote it by `Π_A(s,r)`
`shares_of_set` is a function that maps `s`, `r`, and `A`
to a function from `A` to the shares associated with the
participants in `A`
-/
def {n : ℕ} (scheme : SecretSharingScheme n)
(s : scheme.Secret)
(r : scheme.Random)
(A : Set (Fin n)) : (i : A) → scheme.Share i :=
fun i => scheme.dealer s r i
/-- Reconstruction algorithm
For every authorized subset `B`, the reconstruction
algorithm is a function that takes the shares in
`B` as input and return a term of type `Secret`
-/
def ReconstructionAlgorithm {n : ℕ}
(scheme : SecretSharingScheme n)
(Γ : AccessStructure n) :=
∀ (B : Set (Fin n)), B ∈ Γ.auth → ((i : B)
→ scheme.Share i) → scheme.Secret
/--
Correctness means that for every authorized set `B ∈ Γ`,
and secret `s ∈ S`, the participants in `B` can
reconstruct the secret correctly with probability 1.
-/
def Correctness {n : ℕ}
(S : SecretSharingScheme n)
(Γ : AccessStructure n)
(recon : ReconstructionAlgorithm S Γ) :=
∀ (s : S.Secret) (r : S.Random) (B : Set (Fin n))
(hB : B ∈ Γ.auth), recon B hB (shares_of_set S s r B) = s
For every unauthorized set B ∉ Γ, the shares held by B
reveal no information about the secret.
Fix an unauthorized set B. For each secret s,
(sharesofset S s r B) with r random
gives a distribution on |B|-tuple of shares.
Perfect security requires that this distribution is
the same for all secret s. The equation in the condition
becomes
\Pr(\Pi_T(s_1,r) = \langle s_j\rangle_{j\in T}) =
\Pr(\Pi_T(s_2,r) = \langle s_j\rangle_{j\in T} )
def PerfectSecurity {n : ℕ}
(S : SecretSharingScheme n)
(Γ : AccessStructure n) :=
∀ (B : Set (Fin n)) (_hB : B ∉ Γ.auth) (s s' : S.Secret),
(S.μ.map (fun r => shares_of_set S s r B )) =
(S.μ.map (fun r => shares_of_set S s' r B))
/--
A structure representing a secret sharing scheme that
realizes a given access structure Γ.
-/
structure RealizedSecretSharingScheme
(n : ℕ) (Γ : AccessStructure n)
extends SecretSharingScheme n where
/- The reconstruction algorithm for the scheme. -/
recon : ReconstructionAlgorithm toSecretSharingScheme Γ
/- Proof of correctness:
authorized sets can reconstruct the secret. -/
h_correctness : Correctness toSecretSharingScheme Γ recon
/- Proof of perfect security:
unauthorized sets learn nothing about the secret. -/
h_security : PerfectSecurity toSecretSharingScheme Γ
/--
The size of secret is log(|S|).
-/
noncomputable def secret_size {n : ℕ}
(scheme : SecretSharingScheme n) : ℝ :=
letI _ := scheme.hSecret
Real.log (Fintype.card scheme.Secret)
/--
The size of the share of participant i is log(|Si|).
-/
noncomputable def {n : ℕ}
(scheme : SecretSharingScheme n) (i : Fin n) : ℝ :=
letI _ := scheme.hShare i
Real.log (Fintype.card (scheme.Share i))
/--
The maximum share size is max_j log(|Sj|).
-/
noncomputable def {n : ℕ}
(scheme : SecretSharingScheme n) : ℝ :=
letI _ := scheme.hShare
(Finset.univ.image (fun i =>
share_size scheme i)).max.getD 0
/--
The Total share size is sum_j log(|Sj|).
-/
noncomputable def {n : ℕ}
(scheme : SecretSharingScheme n) : ℝ :=
letI := scheme.hShare
Finset.sum Finset.univ (fun i => share_size scheme i)
/--
The information ratio is max_j log(|Sj|) / log(|S|).
-/
noncomputable def information_ratio {n : ℕ}
(scheme : SecretSharingScheme n) : ℝ :=
(max_share_size scheme) / (secret_size scheme)
To verify perfect security, we only need to verify the condition for maximally unauthorized set.
theorem PerfectSecurity_iff_maximal {n : ℕ}
(scheme : SecretSharingScheme n) (Γ : AccessStructure n) :
PerfectSecurity scheme Γ ↔
∀ (T : Set (Fin n)), isMaximallyUnauthorized Γ T →
∀ (s1 s2 : scheme.Secret),
(scheme.μ.map (fun r =>
shares_of_set scheme s1 r T)) =
(scheme.μ.map (fun r =>
shares_of_set scheme s2 r T)) := n:ℕscheme:SecretSharingScheme nΓ:AccessStructure n⊢ scheme.PerfectSecurity Γ ↔
∀ (T : Set (Fin n)),
Γ.isMaximallyUnauthorized T →
∀ (s1 s2 : scheme.Secret),
PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ =
PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μ
n:ℕscheme:SecretSharingScheme nΓ:AccessStructure n⊢ scheme.PerfectSecurity Γ →
∀ (T : Set (Fin n)),
Γ.isMaximallyUnauthorized T →
∀ (s1 s2 : scheme.Secret),
PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ =
PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μn:ℕscheme:SecretSharingScheme nΓ:AccessStructure nh:∀ (T : Set (Fin n)),
Γ.isMaximallyUnauthorized T →
∀ (s1 s2 : scheme.Secret),
PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μ⊢ scheme.PerfectSecurity Γ;
n:ℕscheme:SecretSharingScheme nΓ:AccessStructure n⊢ scheme.PerfectSecurity Γ →
∀ (T : Set (Fin n)),
Γ.isMaximallyUnauthorized T →
∀ (s1 s2 : scheme.Secret),
PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ =
PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μ All goals completed! 🐙
n:ℕscheme:SecretSharingScheme nΓ:AccessStructure nh:∀ (T : Set (Fin n)),
Γ.isMaximallyUnauthorized T →
∀ (s1 s2 : scheme.Secret),
PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μ⊢ scheme.PerfectSecurity Γ -- For any unauthorized set T, there exists a
-- maximally unauthorized set T'
-- such that T is a subset of T'.
have h_max_unauthorized :
∀ T : Set (Fin n), T ∉ Γ.auth → ∃ T' : Set (Fin n),
isMaximallyUnauthorized Γ T' ∧ T ⊆ T' := n:ℕscheme:SecretSharingScheme nΓ:AccessStructure n⊢ scheme.PerfectSecurity Γ ↔
∀ (T : Set (Fin n)),
Γ.isMaximallyUnauthorized T →
∀ (s1 s2 : scheme.Secret),
PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ =
PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μ
intro T n:ℕscheme:SecretSharingScheme nΓ:AccessStructure nh:∀ (T : Set (Fin n)),
Γ.isMaximallyUnauthorized T →
∀ (s1 s2 : scheme.Secret),
PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μT:Set (Fin n)hT:T ∉ Γ.auth⊢ ∃ T', Γ.isMaximallyUnauthorized T' ∧ T ⊆ T';
-- Since `T` is unauthorized, there exists a
-- maximally unauthorized set `T'`
-- that contains `T`.
obtain ⟨T', hT'⟩ :
∃ T' : Set (Fin n), T ⊆ T' ∧ T' ∉ Γ.auth
∧ ∀ B : Set (Fin n), T' ⊂ B → B ∈ Γ.auth := n:ℕscheme:SecretSharingScheme nΓ:AccessStructure nh:∀ (T : Set (Fin n)),
Γ.isMaximallyUnauthorized T →
∀ (s1 s2 : scheme.Secret),
PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μT:Set (Fin n)hT:T ∉ Γ.auth⊢ ∃ T', T ⊆ T' ∧ T' ∉ Γ.auth ∧ ∀ (B : Set (Fin n)), T' ⊂ B → B ∈ Γ.auth
have h_max :
∃ T' : Set (Fin n), T ⊆ T' ∧ T' ∉ Γ.auth
∧ ∀ B : Set (Fin n), T' ⊂ B →
B ∈ Γ.auth := n:ℕscheme:SecretSharingScheme nΓ:AccessStructure nh:∀ (T : Set (Fin n)),
Γ.isMaximallyUnauthorized T →
∀ (s1 s2 : scheme.Secret),
PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μT:Set (Fin n)hT:T ∉ Γ.auth⊢ ∃ T', T ⊆ T' ∧ T' ∉ Γ.auth ∧ ∀ (B : Set (Fin n)), T' ⊂ B → B ∈ Γ.auth
have h_finite : Set.Finite {B : Set (Fin n) |
T ⊆ B ∧ B ∉ Γ.auth} := n:ℕscheme:SecretSharingScheme nΓ:AccessStructure nh:∀ (T : Set (Fin n)),
Γ.isMaximallyUnauthorized T →
∀ (s1 s2 : scheme.Secret),
PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μT:Set (Fin n)hT:T ∉ Γ.auth⊢ ∃ T', T ⊆ T' ∧ T' ∉ Γ.auth ∧ ∀ (B : Set (Fin n)), T' ⊂ B → B ∈ Γ.auth
All goals completed! 🐙
obtain ⟨T', hT'_max⟩ :
∃ T' ∈ {B : Set (Fin n) | T ⊆ B ∧ B ∉ Γ.auth},
∀ B ∈ {B : Set (Fin n) | T ⊆ B ∧ B ∉ Γ.auth},
T'.ncard ≥ B.ncard := n:ℕscheme:SecretSharingScheme nΓ:AccessStructure nh:∀ (T : Set (Fin n)),
Γ.isMaximallyUnauthorized T →
∀ (s1 s2 : scheme.Secret),
PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μT:Set (Fin n)hT:T ∉ Γ.authh_finite:{B | T ⊆ B ∧ B ∉ Γ.auth}.Finite⊢ ∃ T' ∈ {B | T ⊆ B ∧ B ∉ Γ.auth}, ∀ B ∈ {B | T ⊆ B ∧ B ∉ Γ.auth}, T'.ncard ≥ B.ncard
n:ℕscheme:SecretSharingScheme nΓ:AccessStructure nh:∀ (T : Set (Fin n)),
Γ.isMaximallyUnauthorized T →
∀ (s1 s2 : scheme.Secret),
PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μT:Set (Fin n)hT:T ∉ Γ.authh_finite:{B | T ⊆ B ∧ B ∉ Γ.auth}.Finite⊢ {B | T ⊆ B ∧ B ∉ Γ.auth}.Nonempty
All goals completed! 🐙
All goals completed! 🐙
All goals completed! 🐙
All goals completed! 🐙
-- By combining the results from `h_max`_unauthorized
-- and `h`, we can conclude the proof.
n:ℕscheme:SecretSharingScheme nΓ:AccessStructure nh:∀ (T : Set (Fin n)),
Γ.isMaximallyUnauthorized T →
∀ (s1 s2 : scheme.Secret),
PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μh_max_unauthorized:∀ T ∉ Γ.auth, ∃ T', Γ.isMaximallyUnauthorized T' ∧ T ⊆ T'T:Set (Fin n)hT:T ∉ Γ.auths1:scheme.Secrets2:scheme.Secret⊢ PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μ
n:ℕscheme:SecretSharingScheme nΓ:AccessStructure nh:∀ (T : Set (Fin n)),
Γ.isMaximallyUnauthorized T →
∀ (s1 s2 : scheme.Secret),
PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μh_max_unauthorized:∀ T ∉ Γ.auth, ∃ T', Γ.isMaximallyUnauthorized T' ∧ T ⊆ T'T:Set (Fin n)hT:T ∉ Γ.auths1:scheme.Secrets2:scheme.SecretT':Set (Fin n)hT':Γ.isMaximallyUnauthorized T'hT'_superset:T ⊆ T'⊢ PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μ
have h_eq :
(scheme.μ.map (fun r => shares_of_set scheme s1 r T'))
= (scheme.μ.map (fun r => shares_of_set scheme s2 r T'))
:= n:ℕscheme:SecretSharingScheme nΓ:AccessStructure n⊢ scheme.PerfectSecurity Γ ↔
∀ (T : Set (Fin n)),
Γ.isMaximallyUnauthorized T →
∀ (s1 s2 : scheme.Secret),
PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ =
PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μ All goals completed! 🐙
n:ℕscheme:SecretSharingScheme nΓ:AccessStructure nh:∀ (T : Set (Fin n)),
Γ.isMaximallyUnauthorized T →
∀ (s1 s2 : scheme.Secret),
PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μh_max_unauthorized:∀ T ∉ Γ.auth, ∃ T', Γ.isMaximallyUnauthorized T' ∧ T ⊆ T'T:Set (Fin n)hT:T ∉ Γ.auths1:scheme.Secrets2:scheme.SecretT':Set (Fin n)hT':Γ.isMaximallyUnauthorized T'hT'_superset:T ⊆ T'h_eq:PMF.map (fun r => scheme.shares_of_set s1 r T') scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T') scheme.μ⊢ PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ =
PMF.map (fun x i => x ⟨↑i, ⋯⟩) (PMF.map (fun r => scheme.shares_of_set s1 r T') scheme.μ)n:ℕscheme:SecretSharingScheme nΓ:AccessStructure nh:∀ (T : Set (Fin n)),
Γ.isMaximallyUnauthorized T →
∀ (s1 s2 : scheme.Secret),
PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μh_max_unauthorized:∀ T ∉ Γ.auth, ∃ T', Γ.isMaximallyUnauthorized T' ∧ T ⊆ T'T:Set (Fin n)hT:T ∉ Γ.auths1:scheme.Secrets2:scheme.SecretT':Set (Fin n)hT':Γ.isMaximallyUnauthorized T'hT'_superset:T ⊆ T'h_eq:PMF.map (fun r => scheme.shares_of_set s1 r T') scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T') scheme.μ⊢ PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μ =
PMF.map (fun x i => x ⟨↑i, ⋯⟩) (PMF.map (fun r => scheme.shares_of_set s2 r T') scheme.μ) n:ℕscheme:SecretSharingScheme nΓ:AccessStructure nh:∀ (T : Set (Fin n)),
Γ.isMaximallyUnauthorized T →
∀ (s1 s2 : scheme.Secret),
PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μh_max_unauthorized:∀ T ∉ Γ.auth, ∃ T', Γ.isMaximallyUnauthorized T' ∧ T ⊆ T'T:Set (Fin n)hT:T ∉ Γ.auths1:scheme.Secrets2:scheme.SecretT':Set (Fin n)hT':Γ.isMaximallyUnauthorized T'hT'_superset:T ⊆ T'h_eq:PMF.map (fun r => scheme.shares_of_set s1 r T') scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T') scheme.μ⊢ PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ =
PMF.map (fun x i => x ⟨↑i, ⋯⟩) (PMF.map (fun r => scheme.shares_of_set s1 r T') scheme.μ)n:ℕscheme:SecretSharingScheme nΓ:AccessStructure nh:∀ (T : Set (Fin n)),
Γ.isMaximallyUnauthorized T →
∀ (s1 s2 : scheme.Secret),
PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μh_max_unauthorized:∀ T ∉ Γ.auth, ∃ T', Γ.isMaximallyUnauthorized T' ∧ T ⊆ T'T:Set (Fin n)hT:T ∉ Γ.auths1:scheme.Secrets2:scheme.SecretT':Set (Fin n)hT':Γ.isMaximallyUnauthorized T'hT'_superset:T ⊆ T'h_eq:PMF.map (fun r => scheme.shares_of_set s1 r T') scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T') scheme.μ⊢ PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μ =
PMF.map (fun x i => x ⟨↑i, ⋯⟩) (PMF.map (fun r => scheme.shares_of_set s2 r T') scheme.μ) n:ℕscheme:SecretSharingScheme nΓ:AccessStructure nh:∀ (T : Set (Fin n)),
Γ.isMaximallyUnauthorized T →
∀ (s1 s2 : scheme.Secret),
PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μh_max_unauthorized:∀ T ∉ Γ.auth, ∃ T', Γ.isMaximallyUnauthorized T' ∧ T ⊆ T'T:Set (Fin n)hT:T ∉ Γ.auths1:scheme.Secrets2:scheme.SecretT':Set (Fin n)hT':Γ.isMaximallyUnauthorized T'hT'_superset:T ⊆ T'h_eq:PMF.map (fun r => scheme.shares_of_set s1 r T') scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T') scheme.μ⊢ scheme.μ.bind (PMF.pure ∘ fun r => scheme.shares_of_set s2 r T) =
scheme.μ.bind fun a => PMF.pure fun i => scheme.shares_of_set s2 a T' ⟨↑i, ⋯⟩;
n:ℕscheme:SecretSharingScheme nΓ:AccessStructure nh:∀ (T : Set (Fin n)),
Γ.isMaximallyUnauthorized T →
∀ (s1 s2 : scheme.Secret),
PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μh_max_unauthorized:∀ T ∉ Γ.auth, ∃ T', Γ.isMaximallyUnauthorized T' ∧ T ⊆ T'T:Set (Fin n)hT:T ∉ Γ.auths1:scheme.Secrets2:scheme.SecretT':Set (Fin n)hT':Γ.isMaximallyUnauthorized T'hT'_superset:T ⊆ T'h_eq:PMF.map (fun r => scheme.shares_of_set s1 r T') scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T') scheme.μ⊢ scheme.μ.bind (PMF.pure ∘ fun r => scheme.shares_of_set s1 r T) =
scheme.μ.bind fun a => PMF.pure fun i => scheme.shares_of_set s1 a T' ⟨↑i, ⋯⟩ All goals completed! 🐙
n:ℕscheme:SecretSharingScheme nΓ:AccessStructure nh:∀ (T : Set (Fin n)),
Γ.isMaximallyUnauthorized T →
∀ (s1 s2 : scheme.Secret),
PMF.map (fun r => scheme.shares_of_set s1 r T) scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T) scheme.μh_max_unauthorized:∀ T ∉ Γ.auth, ∃ T', Γ.isMaximallyUnauthorized T' ∧ T ⊆ T'T:Set (Fin n)hT:T ∉ Γ.auths1:scheme.Secrets2:scheme.SecretT':Set (Fin n)hT':Γ.isMaximallyUnauthorized T'hT'_superset:T ⊆ T'h_eq:PMF.map (fun r => scheme.shares_of_set s1 r T') scheme.μ = PMF.map (fun r => scheme.shares_of_set s2 r T') scheme.μ⊢ scheme.μ.bind (PMF.pure ∘ fun r => scheme.shares_of_set s2 r T) =
scheme.μ.bind fun a => PMF.pure fun i => scheme.shares_of_set s2 a T' ⟨↑i, ⋯⟩ All goals completed! 🐙
end SecretSharingScheme -- namespace
end SecretSharingScheme -- section