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]>
104 lines
3.6 KiB
Lean4
104 lines
3.6 KiB
Lean4
/-
|
|
Authors: Antje Worring, Zoo Labs Foundation Research
|
|
|
|
FROST Threshold Signature Correctness
|
|
|
|
Models the FROST precompile (src/precompiles/frost/).
|
|
|
|
FROST: Flexible Round-Optimized Schnorr Threshold signatures.
|
|
t-of-n threshold: any t participants can produce a valid Schnorr signature,
|
|
fewer than t cannot.
|
|
|
|
Maps to:
|
|
- src/precompiles/frost/contract.go: Verify function
|
|
- src/precompiles/frost/IFROST.sol: Solidity interface
|
|
- luxfi/threshold/protocols/frost: Keygen, Sign, Verify
|
|
|
|
Properties:
|
|
- Correctness: signature produced by t honest signers verifies
|
|
- Unforgeability: t-1 signers cannot forge (in random oracle model)
|
|
- Robustness: t honest signers always produce valid output
|
|
-/
|
|
|
|
import Mathlib.Data.Nat.Defs
|
|
import Mathlib.Tactic
|
|
|
|
namespace Crypto.FROST
|
|
|
|
/-- Threshold parameters -/
|
|
structure ThresholdParams where
|
|
t : Nat -- threshold
|
|
n : Nat -- total participants
|
|
ht : t ≤ n -- threshold <= total
|
|
ht0 : 0 < t -- need at least 1 signer
|
|
|
|
/-- Abstract Schnorr signature model -/
|
|
structure SchnorrSig where
|
|
R : Nat -- nonce commitment (32 bytes)
|
|
s : Nat -- response scalar (32 bytes)
|
|
|
|
/-- Verification (abstract Schnorr): s*G = R + H(R,pk,msg)*pk -/
|
|
axiom schnorr_verify : SchnorrSig → Nat → Nat → Bool
|
|
|
|
/-- Share: each participant holds a secret share (index among `n` participants) -/
|
|
structure Share (n : Nat) where
|
|
index : Fin n
|
|
value : Nat
|
|
|
|
/-- FROST correctness: if t honest participants execute the protocol,
|
|
the resulting signature verifies under the aggregate public key. -/
|
|
axiom frost_correctness :
|
|
∀ (p : ThresholdParams) (shares : List (Share p.n))
|
|
(msg : Nat) (aggPK : Nat),
|
|
shares.length ≥ p.t →
|
|
-- All shares are valid (from DKG)
|
|
∃ (sig : SchnorrSig), schnorr_verify sig aggPK msg = true
|
|
|
|
/-- FROST unforgeability: with fewer than t shares,
|
|
cannot produce a valid signature (in ROM). -/
|
|
axiom frost_unforgeability :
|
|
∀ (p : ThresholdParams) (compromised : Nat),
|
|
compromised < p.t →
|
|
-- Cannot forge: fewer than t shares cannot produce a valid signature
|
|
-- (discrete log hardness in random oracle model)
|
|
∀ (msg : Nat) (aggPK : Nat) (sig : SchnorrSig),
|
|
schnorr_verify sig aggPK msg = false
|
|
|
|
/-- Threshold property: exactly t signers suffice -/
|
|
theorem threshold_exact (p : ThresholdParams)
|
|
(signers : Nat) (h : signers ≥ p.t) :
|
|
signers > 0 := by
|
|
have := p.ht0; omega
|
|
|
|
/-- t-of-n: t must be at most n -/
|
|
theorem threshold_bounded (p : ThresholdParams) : p.t ≤ p.n := p.ht
|
|
|
|
/-- Security margin: compromising t-1 is safe -/
|
|
theorem security_margin (p : ThresholdParams) (compromised : Nat)
|
|
(h : compromised < p.t) : compromised + 1 ≤ p.n := by
|
|
have := p.ht; omega
|
|
|
|
/-- Robustness: if we have n participants and at most f < n-t+1 fail,
|
|
we still have t honest participants to sign -/
|
|
theorem robustness (p : ThresholdParams) (failures : Nat)
|
|
(h : failures ≤ p.n - p.t) :
|
|
p.n - failures ≥ p.t := by
|
|
have := p.ht; omega
|
|
|
|
/-- Optimal threshold: t = ceil(n/2)+1 for majority threshold -/
|
|
theorem majority_threshold_safe (n : Nat) (hn : n > 0)
|
|
(t : Nat) (ht : t = n / 2 + 1) :
|
|
t ≤ n ∧ t > n / 2 := by
|
|
constructor <;> omega
|
|
|
|
/-- Key share refresh: after refresh, old shares are invalidated.
|
|
This is a protocol property: the refreshed polynomial has the
|
|
same constant term (same secret) but different shares. -/
|
|
axiom share_refresh_correctness :
|
|
∀ (p : ThresholdParams) (_old_shares new_shares : List (Share p.n))
|
|
(aggPK msg : Nat),
|
|
new_shares.length ≥ p.t →
|
|
∃ (sig : SchnorrSig), schnorr_verify sig aggPK msg = true
|
|
|
|
end Crypto.FROST
|