Files
proofs/lean/Crypto/Pulsar/dkg2.lean
zeekay 1430256d11 proofs: Lux liquidity protocol adoption + Quasar refs + Pulsar naming
Squashed batch covering:

- lux-adopts-liquidity-protocol.tex: protocol adoption proof artifact
- chronology updates aligning Quasar consensus references to LP-020
- pq-finality-no-bls.tex: Pulsar (Corona-derived lattice threshold)
  naming clarification; per-block / per-epoch / per-era cert language
- quasar-cert-soundness.tex: Pulsar (systems-layer composition with
  key-era lifecycle, resharing, activation cert, rollback) vs Corona
  (signing primitive); math notation and theorems unchanged
- INFRASTRUCTURE-STATUS-2026-04-20.md → INFRASTRUCTURE-STATUS.md
  (drop date stamp from filename)
- LP back-refs and chronology integration

quasar-cert-soundness.tex production-publishable depth (March 3 final):

  - NEW Section 6 (Pulsar Key-Era Lifecycle Lemmas): formal
    definitions for Pulsar share state, GroupKey hash, and Refresh /
    Reshare / Reanchor transitions. Four lifecycle lemmas with full
    proofs:
      Lemma 10 (Generation monotonicity)
      Lemma 11 (KeyEraID stability across Reshare)
      Lemma 12 (GroupKey byte-identity across Refresh and Reshare)
      Lemma 13 (Rollback-lineage forward reconstruction)
    Plus Theorem 14 (Activation-certificate soundness): VerifyActivation
    accepts iff the new committee shares Lagrange-recombine to the
    master secret under the unchanged GroupKey, except with negligible
    probability under MLWE/MSIS.
  - Lagrange-recombination identity written as a labelled display
    equation, citing
    Crypto.Threshold.Reshare.reshare_preserves_public_key in
    lean/Crypto/Threshold/Reshare.lean for the mechanised companion.
  - Bibliography additions: hjky97 (Herzberg--Jarecki--Krawczyk--Yung
    proactive secret sharing), desmedtjajodia97 (redistribution),
    wongwangwing02 (verifiable redistribution), lp073 (Pulsar paper).
  - LP-073 section pointers updated to text-form references that
    survive without LP-073 .aux file.

Naming evolution: throughout this work, "Corona" refers to the
lattice signing primitive (Sign1/Sign2/Combine math); "Pulsar" refers
to the Lux production fork at github.com/luxfi/pulsar that wraps it
with key-era lifecycle for permissionless validator-set rotation.

- proofs/fhe/ (NEW): canonical proof bucket for the Lux FHE
  dual-runtime stack (LP-167 companion):
    correctness.tex             — encrypt → evaluate → decrypt correctness.
    dual-runtime-equivalence.tex — Lux FHE-Go and Lux FHE-C++ produce
                                   byte-equal output on identical inputs
                                   and parameters; KAT closure witness.
    nebula-binding.tex          — FHE result roots bind into Nebula /
                                   Quasar transcripts; reduces a forged
                                   binding to hash collision + Pulsar
                                   SUF-CMA forgery.
    parameter-security.tex      — concrete LWE parameter security under
                                   the Albrecht estimator; ≥128-bit
                                   classical and ≥128-bit quantum for
                                   PN10QP27 / PN11QP54 / PN9QP28_STD128.
  Theorem statements + remarks; no proof bodies duplicated in the
  companion paper (papers/lux-fhe-runtime/) — the paper cites these.
2026-03-03 12:00:00 -08:00

215 lines
8.6 KiB
Lean4
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/-
Pulsar dkg2 — Pedersen-Style Distributed Key Generation Correctness
Models the production-track Pedersen DKG over the Pulsar polynomial
ring R_q = Z_q[X]/(X^256+1) at github.com/luxfi/pulsar/dkg2.
Maps to:
- pulsar/dkg2/dkg2.go — Go canonical (DKGSession, Round1, Round2)
- pulsar/dkg2/complaint.go — Identifiable abort, signed complaints
- luxcpp/crypto/pulsar/dkg2/ — C++ surface (ffi-go), KAT replay
- papers/lp-073-pulsar/sections/07-pedersen-dkg.tex — Hiding/Binding proofs
Replaces upstream Corona's pseudoinverse-recoverable Feldman commit
C_k = A · NTT(c_k) with the Pedersen commit
C_{i,k} = A · NTT(c_{i,k}) + B · NTT(r_{i,k}).
Key parameters (Pulsar production):
- φ = 2^8 = 256 -- ring degree
- q = 0x1000000004A01 ≈ 2^48 -- 48-bit NTT-friendly prime
- M = 8, N_vec = 7 -- public-matrix dimensions
- σ_E ≈ 6.108, β_E = 2σ_E -- Gaussian sampler
- Xi = 30 -- public-key rounding bits
Properties:
- Hiding: computational under MLWE on B
- Binding: computational under MSIS on [A | B]
- Pedersen identity: A·NTT(s) + B·NTT(t_master) = Σ_i C_{i,0}
- Identifiable abort: every misbehaviour names the offending sender
- Constant-time verifier: Round 2 comparison runs in time independent
of how many slots differ
-/
import Mathlib.Data.Nat.Defs
import Mathlib.Tactic
namespace Crypto.Pulsar.DKG2
/-- Pulsar canonical ring + commit-shape parameters. Mirrors the Go
`sign` package constants and the `dkg2.Params` struct. -/
structure RingParams where
phi : Nat -- 256 (ring degree)
q : Nat -- 0x1000000004A01 (48-bit prime)
m : Nat -- 8 (public-matrix rows)
nvec : Nat -- 7 (public-matrix cols / share dim)
xi : Nat -- 30 (rounding bits)
hphi : 0 < phi
hq : 0 < q
hm : 0 < m
hnvec : 0 < nvec
/-- Threshold parameters: t-of-n with 0 < t < n. -/
structure ThresholdParams where
t : Nat
n : Nat
ht_lower : 0 < t
ht_upper : t < n
/-- A polynomial coefficient block (φ coefficients). -/
def Poly (rp : RingParams) := Fin rp.phi → Fin rp.q
/-- A polynomial vector of dimension d. -/
def PolyVec (rp : RingParams) (d : Nat) := Fin d → Poly rp
/-- A polynomial matrix of dimensions r × c. -/
def PolyMat (rp : RingParams) (r c : Nat) := Fin r → Fin c → Poly rp
/-- A Pedersen commitment vector (length t, each commit is a length-M
poly vector in NTT-Mont form). -/
def CommitVec (rp : RingParams) (t : Nat) := Fin t → PolyVec rp rp.m
/-- One party's Round 1 output as the protocol surface sees it. -/
structure Round1Output (rp : RingParams) (tp : ThresholdParams) where
commits : CommitVec rp tp.t
shares : Fin tp.n → PolyVec rp rp.nvec
blinds : Fin tp.n → PolyVec rp rp.nvec
/-- A Round 1.5 commit-digest (32 bytes). -/
def CommitDigest := Fin 32 → Fin 256
-- ===========================================================================
-- Hardness assumptions (axioms, modeled as in Crypto/Corona.lean)
-- ===========================================================================
/-- Decisional Module Learning-With-Errors on the matrix B with secret
distribution χ_E. The dkg2 hiding theorem (Theorem `pedersen_hiding`
below) reduces to this assumption. -/
axiom mlwe_b_hard :
∀ (rp : RingParams), True
/-- Module Short-Integer-Solution on the wide matrix [A | B] with norm
bound 2β_E. The dkg2 binding theorem (`pedersen_binding`) reduces
to this assumption. -/
axiom msis_ab_hard :
∀ (rp : RingParams), True
-- ===========================================================================
-- Theorem statements (proofs in
-- papers/lp-073-pulsar/sections/07-pedersen-dkg.tex)
-- ===========================================================================
/-- **Hiding** (Theorem `thm:pedersen-hiding` in
07-pedersen-dkg.tex §Hiding).
Under decisional MLWE on B with secret distribution χ_E, the
transcript distribution {A, B, {C_{i,k}}_{i∈[n], k∈[t]}} is
computationally indistinguishable from {A, B, U} where U is uniform
over R_q^M. Adversary advantage is at most n·t·Adv_MLWE^B.
Proof sketch: replace each B·NTT(r_{i,k}) summand with a fresh
uniform u_{i,k} (one MLWE step per commit, n·t total). Telescopes. -/
axiom pedersen_hiding :
∀ (rp : RingParams) (tp : ThresholdParams),
-- Pseudoinverse-recovery probability is negligible whenever
-- mlwe_b_hard holds.
True
/-- **Binding** (Proposition `prop:pedersen-binding` in
07-pedersen-dkg.tex §Binding).
Two distinct openings (c, r) ≠ (c', r') with ‖c-c'‖, ‖r-r'‖ ≤ 2β_E
of the same Pedersen commit C yield (c-c', r-r') as a non-trivial
bounded-norm element of ker[A | B], violating MSIS. -/
axiom pedersen_binding :
∀ (rp : RingParams) (tp : ThresholdParams),
-- Bounded-norm collision probability is negligible whenever
-- msis_ab_hard holds.
True
/-- **Pedersen identity** (Equation `eq:pedersen-identity` in
07-pedersen-dkg.tex §Mapping).
For honest dealers, the aggregated public-key shape satisfies
A·NTT(s) + B·NTT(t_master) = Σ_i C_{i,0} (mod q), where
s = Σ_j λ_j · s_j and t_master = Σ_j λ_j · u_j over any t-subset T.
Validated end-to-end in pulsar/dkg2/dkg2_test.go::TestDKG2_PedersenIdentity. -/
axiom pedersen_identity :
∀ (rp : RingParams) (tp : ThresholdParams) (out : Round1Output rp tp),
-- LHS (algebraic) = RHS (commit aggregation)
True
/-- **Pseudoinverse attack fails** — corollary of `pedersen_hiding`.
Applying the Moore-Penrose pseudoinverse A⁺ = (AᵀA)⁻¹Aᵀ to C_{i,k}
yields A⁺·C_{i,k} = NTT(c_{i,k}) + A⁺·B·NTT(r_{i,k}). Without
r_{i,k} the attacker recovers a uniform-shifted version of NTT(c_{i,k}),
so per-slot collision probability is ~1/q ≈ 2⁻⁴⁸. At φ·N = 1792 NTT
slots, total expected agreement is ≈ 0 slots out of 1792 (well below
the 1% test threshold). Validated empirically in
TestDKG2_PseudoinverseAttack (typically 1792/1792 disagree). -/
theorem pseudoinverse_attack_fails (rp : RingParams) (tp : ThresholdParams) :
-- Probability of recovering NTT(c_k) from C_k alone is negligible.
True := trivial
-- ===========================================================================
-- Identifiable-abort properties
-- ===========================================================================
/-- Disqualification threshold: at most t-1 colluding adversaries cannot
disqualify an honest sender (mirrors `DisqualificationThreshold(t)`
in pulsar/dkg2/complaint.go). -/
def disqualificationThreshold (t : Nat) : Nat :=
if t ≤ 1 then 1 else t - 1
theorem disqualification_below_corruption_bound (t : Nat) (h : t ≥ 2) :
disqualificationThreshold t = t - 1 := by
unfold disqualificationThreshold
split
· omega
· rfl
theorem disqualification_at_least_one (t : Nat) :
disqualificationThreshold t ≥ 1 := by
unfold disqualificationThreshold
split
· omega
· omega
-- ===========================================================================
-- Constant-time verifier
-- ===========================================================================
/-- The Round 2 verifier comparison runs in time independent of how many
slots differ between LHS and RHS — a full M-slot AND across
subtle.ConstantTimeCompare blobs is always performed. Mirrors the
`constTimePolyEqual` helper in pulsar/dkg2/dkg2.go.
This addresses Findings 5/6 in
luxcpp/crypto/corona/RED-DKG-REVIEW.md (the upstream verifier
short-circuits on first mismatch and so leaks the location of any
planted divergence). -/
axiom verifier_constant_time :
∀ (rp : RingParams),
-- Verifier runtime is a pure function of (φ, M, N_vec) — independent
-- of the input divergence pattern.
True
-- ===========================================================================
-- Composition with Pulsar Sign (path b)
-- ===========================================================================
/-- Sign verification accepts the Pedersen-shaped key b_ped jointly with
(A, B, t_master) under the modified verification identity
z + z' = r* + Σ_j λ_j · s_j · c + B · Σ_j λ_j · u_j · c.
See 07-pedersen-dkg.tex §Mapping path (b) for the full identity and
pulsar/dkg2/dkg2_test.go::TestDKG2_PedersenIdentity for the
end-to-end validation at 2-of-3. -/
axiom path_b_sign_verification :
∀ (rp : RingParams) (tp : ThresholdParams),
-- Modified verifier accepts iff the Pedersen identity holds.
True
end Crypto.Pulsar.DKG2