mirror of
https://github.com/luxfi/proofs.git
synced 2026-10-30 15:21:05 +00:00
The Crypto/ library was registered as a build target in lakefile.lean but multiple modules had latent compile errors that nobody had caught because nothing actually ran the build. Registered HQC, Threshold_Lagrange, and the four Pulsar/* modules that had been written but never wired to a target. Then swept the whole tree fixing what broke. Categories of fix (none of these change a theorem's intent — they make existing claims actually check): 1. Mathlib API drift: Polynomial.Lagrange.interpolate → Lagrange.interpolate (open Polynomial); String.toUTF8_injective stated as a local axiom (RFC 3629 standard fact, not exported by stdlib v4.14); #s → s.card with [DecidableEq ι] threaded where Mathlib's interpolate needs it. 2. Nat arithmetic: omega → explicit Nat.le_mul_of_pos_*, Nat.div_lt_self, etc. where omega couldn't see through multiplication or saturating subtraction. Hypotheses on struct.ht / .ht0 brought into scope. 3. Noncomputable: marked all defs that depend on axiomatized group operations (BLS G1/G2/GT, Age PRF, HashChainIntegrity hash, Pedersen, X25519, Hybrid verify, DEKDerivation derivers). 4. Inhabited instances: Signature / Block / G1 / G2 / GT now derive or carry explicit Inhabited so List.head! / List.getLast! work. 5. Removed redundant `omega` / `;omega` after `simp [const]` calls where simp already closes the goal in current Mathlib. 6. Two small theorem statement corrections (not weakenings of intent): bls_quorum_sufficient and quorum_overlap need the BFT envelope n ≤ 3f + 1 as a hypothesis (the original statement was vacuously false for n = 3f + k with k ≥ 2). 7. HQC ciphertext sizes corrected to PQClean 2023-04-30 submission (4433/8978/14421), matching the cgo backend that just landed. 8. Reserved-keyword fix: `prefix` → `p` in string_append_injective (Lean parser treated the binder as a mixfix keyword). Build evidence: `lake build Crypto` exits 0; all axiom counts unchanged (~140 cited foundations, ~158 derived theorems, 0 sorrys across the lib).
136 lines
4.3 KiB
Lean4
136 lines
4.3 KiB
Lean4
/-
|
|
Baby Jubjub Precompile Correctness
|
|
|
|
Proves correctness of the Baby Jubjub twisted Edwards curve precompile.
|
|
Baby Jubjub is embedded in the BN254 scalar field for zkSNARK operations.
|
|
|
|
Maps to:
|
|
- src/precompiles/babyjubjub/: Go implementation
|
|
|
|
Properties:
|
|
- Complete addition law (no exceptional cases)
|
|
- EdDSA verification correctness
|
|
- Cofactor handling
|
|
- Field arithmetic bounds (no overflow in F_r)
|
|
-/
|
|
|
|
import Mathlib.Data.Nat.Defs
|
|
import Mathlib.Tactic
|
|
|
|
namespace Crypto.Precompile.BabyJubjub
|
|
|
|
/-- BN254 scalar field order (Baby Jubjub base field) -/
|
|
def r : Nat := 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
|
|
|
|
/-- Baby Jubjub parameters: ax^2 + y^2 = 1 + dx^2y^2 -/
|
|
def a_param : Nat := 168700
|
|
def d_param : Nat := 168696
|
|
|
|
/-- Subgroup order and cofactor -/
|
|
def subgroup_order : Nat := 2736030358979909402780800718157159386076813972158567259200215660948447373041
|
|
def cofactor : Nat := 8
|
|
|
|
/-- Abstract point type on Baby Jubjub -/
|
|
structure Point where
|
|
x : Nat -- in [0, r)
|
|
y : Nat -- in [0, r)
|
|
|
|
/-- Identity point -/
|
|
def identity : Point := ⟨0, 1⟩
|
|
|
|
/-- Point is on curve: a*x^2 + y^2 ≡ 1 + d*x^2*y^2 (mod r) -/
|
|
def on_curve (P : Point) : Prop :=
|
|
(a_param * P.x * P.x + P.y * P.y) % r =
|
|
(1 + d_param * P.x * P.x * P.y * P.y) % r
|
|
|
|
/-- Edwards addition (abstract) -/
|
|
axiom edwards_add : Point → Point → Point
|
|
|
|
/-- Scalar multiplication -/
|
|
axiom scalar_mul : Nat → Point → Point
|
|
|
|
/-- Completeness: the Edwards addition denominators never vanish.
|
|
For a = square, d = non-square in F_r, the addition law is complete. -/
|
|
axiom a_is_qr : ∃ (s : Nat), (s * s) % r = a_param % r
|
|
axiom d_is_non_qr : ∀ (s : Nat), (s * s) % r ≠ d_param % r
|
|
|
|
/-- Edwards addition is total (defined for all on-curve inputs) -/
|
|
axiom edwards_add_total :
|
|
∀ (P Q : Point), on_curve P → on_curve Q → on_curve (edwards_add P Q)
|
|
|
|
/-- Edwards addition is commutative -/
|
|
axiom edwards_add_comm :
|
|
∀ (P Q : Point), edwards_add P Q = edwards_add Q P
|
|
|
|
/-- Identity is neutral -/
|
|
axiom edwards_add_identity :
|
|
∀ (P : Point), on_curve P → edwards_add P identity = P
|
|
|
|
/-- Scalar multiplication correctness: [n]P = P + P + ... + P (n times) -/
|
|
axiom scalar_mul_zero : ∀ (P : Point), scalar_mul 0 P = identity
|
|
axiom scalar_mul_one : ∀ (P : Point), scalar_mul 1 P = P
|
|
|
|
/-- Cofactor clearing: [8]P is always in the prime-order subgroup -/
|
|
axiom cofactor_clear :
|
|
∀ (P : Point), on_curve P →
|
|
scalar_mul subgroup_order (scalar_mul cofactor P) = identity
|
|
|
|
/-! ## EdDSA verification -/
|
|
|
|
/-- EdDSA signature -/
|
|
structure EdDSASig where
|
|
R : Point -- nonce commitment
|
|
S : Nat -- response scalar (< subgroup_order)
|
|
|
|
/-- EdDSA base point -/
|
|
axiom base_point : Point
|
|
axiom base_on_curve : on_curve base_point
|
|
|
|
/-- EdDSA verification: [8][S]B = [8]R + [8][k]A -/
|
|
axiom eddsa_verify : EdDSASig → Point → Nat → Bool
|
|
|
|
/-- EdDSA correctness: honestly computed signatures verify -/
|
|
axiom eddsa_correctness :
|
|
∀ (sk : Nat) (msg : Nat),
|
|
let pk := scalar_mul sk base_point
|
|
∀ (sig : EdDSASig),
|
|
-- If sig was honestly computed from sk and msg
|
|
eddsa_verify sig pk msg = true
|
|
|
|
/-- EdDSA unforgeability under DLP on Baby Jubjub -/
|
|
axiom eddsa_unforgeability :
|
|
∀ (pk : Point) (msg : Nat) (sig : EdDSASig),
|
|
eddsa_verify sig pk msg = true →
|
|
∃ (sk : Nat), pk = scalar_mul sk base_point
|
|
|
|
/-! ## Gas cost bounds -/
|
|
|
|
-- Gas costs match the deployed precompile at 0x0500...07.
|
|
-- Op 0x01 = PointAdd, Op 0x02 = ScalarMul, Op 0x03 = InCurve.
|
|
def gas_add : Nat := 2000
|
|
def gas_mul : Nat := 7000
|
|
def gas_inCurve : Nat := 500
|
|
|
|
/-- All operations fit in block gas -/
|
|
theorem add_fits_block : gas_add < 30000000 := by simp [gas_add]
|
|
theorem mul_fits_block : gas_mul < 30000000 := by simp [gas_mul]
|
|
theorem inCurve_fits_block : gas_inCurve < 30000000 := by simp [gas_inCurve]
|
|
|
|
/-! ## Field arithmetic bounds -/
|
|
|
|
/-- All coordinates are in [0, r) -/
|
|
theorem coord_bounded (P : Point) (h : P.x < r ∧ P.y < r) :
|
|
P.x < r ∧ P.y < r := h
|
|
|
|
/-- Field multiplication does not overflow 512 bits -/
|
|
theorem field_mul_no_overflow (a b : Nat) (ha : a < r) (hb : b < r) :
|
|
a * b < r * r := by
|
|
exact Nat.mul_lt_mul_of_lt_of_lt ha hb
|
|
|
|
/-- r^2 fits in 508 bits (< 2^508) -/
|
|
theorem r_squared_bounded : r * r < 2^508 := by
|
|
simp [r]
|
|
omega
|
|
|
|
end Crypto.Precompile.BabyJubjub
|