Skip to content
11 changes: 11 additions & 0 deletions Cslib.lean
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ public import Cslib.Computability.URM.Defs
public import Cslib.Computability.URM.Execution
public import Cslib.Computability.URM.StandardForm
public import Cslib.Computability.URM.StraightLine
public import Cslib.Crypto.Primitives.ECC.Basic
public import Cslib.Crypto.Primitives.ECC.TwistedEdwardsCurve
public import Cslib.Crypto.Protocols.PerfectSecrecy.Basic
public import Cslib.Crypto.Protocols.PerfectSecrecy.Defs
public import Cslib.Crypto.Protocols.PerfectSecrecy.Encryption
Expand All @@ -64,6 +66,15 @@ public import Cslib.Crypto.Protocols.SecretSharing.Defs
public import Cslib.Crypto.Protocols.SecretSharing.Scheme
public import Cslib.Crypto.Protocols.SecretSharing.Shamir
public import Cslib.Crypto.Protocols.SecretSharing.Shamir.Polynomial
public import Cslib.Crypto.Systems.Elligator.Basic
public import Cslib.Crypto.Systems.Elligator.Context
public import Cslib.Crypto.Systems.Elligator.Elligator1.AuxiliaryCoordinates
public import Cslib.Crypto.Systems.Elligator.Elligator1.CurveParameters
public import Cslib.Crypto.Systems.Elligator.Elligator1.EdwardsCurve
public import Cslib.Crypto.Systems.Elligator.Elligator1.Map
public import Cslib.Crypto.Systems.Elligator.Elligator1.OutputCoordinates
public import Cslib.Crypto.Systems.Elligator.FiniteFieldBasic
public import Cslib.Crypto.Systems.Elligator.LegendreSymbol
public import Cslib.Foundations.Combinatorics.InfiniteGraphRamsey
public import Cslib.Foundations.Control.Monad.Free
public import Cslib.Foundations.Control.Monad.Free.Effects
Expand Down
9 changes: 9 additions & 0 deletions Cslib/Crypto/Primitives/ECC/Basic.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/-
Copyright (c) 2026 Chris Anto Fröschl. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Anto Fröschl
-/

module

public import Cslib.Init
120 changes: 120 additions & 0 deletions Cslib/Crypto/Primitives/ECC/TwistedEdwardsCurve.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/-
Copyright (c) 2026 Chris Anto Fröschl. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Anto Fröschl
-/

module

public import Cslib.Crypto.Primitives.ECC.Basic
public import Mathlib.Algebra.Ring.Commute
public import Mathlib.Data.Set.Defs

/-!
# Twisted Edwards curves

This file contains the curve-level definitions that are independent of any specific Elligator.
A twisted Edwards curve with coefficients `a` and `d` has affine equation
`a * x ^ 2 + y ^ 2 = 1 + d * x ^ 2 * y ^ 2`.

The definitions are made over a commutative ring. Finiteness and the hypotheses used by a
particular cryptographic construction belong in that construction, rather than in the definition
of a curve or its affine points.

Mathlib's elliptic-curve API is currently centred on Weierstrass models. A twisted Edwards model
is not itself a Weierstrass equation, so using `WeierstrassCurve.Affine.Equation` here would require
a birational coordinate conversion and extra invertibility hypotheses. The API below follows the
same useful separation as that API: coefficients, an affine equation, a set of affine points, and
a bundled point type.

## Main definitions

* `TwistedEdwardsCurve`: the coefficients `a`, `d` of a twisted Edwards model, with its equation
`TwistedEdwardsCurve.Equation`, its affine points `TwistedEdwardsCurve.affinePoints` and the
nonsingularity condition `TwistedEdwardsCurve.IsValid`.
* `edwardsCurve d`: the untwisted Edwards curve `x ^ 2 + y ^ 2 = 1 + d * x ^ 2 * y ^ 2`.

## TODO

- Move into mathlib next to Mathlib.AlgebraicGeometry.EllipticCurve.Weierstrass

## References

* [Bernstein2007a], Section 2.
* [Bernstein2008a], Section 2, Definition 2.1.

-/

@[expose] public section
namespace Cslib.Crypto.Primitives.ECC

/-- Coefficients of the twisted Edwards equation
`a * x ^ 2 + y ^ 2 = 1 + d * x ^ 2 * y ^ 2`. -/
@[ext]
structure TwistedEdwardsCurve (R : Type*) where
/-- left hand side coefficient -/
a : R
/-- right hand side coefficient -/
d : R

variable {R : Type*} [CommRing R]

namespace TwistedEdwardsCurve

/-- The proposition that `(x, y)` is an affine point of a twisted Edwards curve. -/
def Equation (E : TwistedEdwardsCurve R) (x y : R) : Prop :=
E.a * x ^ 2 + y ^ 2 = 1 + E.d * x ^ 2 * y ^ 2

/-- The set of affine coordinate pairs on a twisted Edwards curve. -/
def affinePoints (E : TwistedEdwardsCurve R) : Set (R × R) := {p | E.Equation p.1 p.2}

/-- A bundled affine point on a twisted Edwards curve. -/
abbrev Point (E : TwistedEdwardsCurve R) := {p : R × R // p ∈ E.affinePoints}

/-- The neutral affine coordinate pair `(0, 1)`. It lies on every twisted Edwards equation. -/
def zero : R × R := (0, 1)

lemma zero_mem_affinePoints (E : TwistedEdwardsCurve R) : zero ∈ E.affinePoints := by
change E.a * 0 ^ 2 + 1 ^ 2 = 1 + E.d * 0 ^ 2 * 1 ^ 2
simp

/-- The neutral point, bundled as an affine point of `E`. -/
def zeroPoint (E : TwistedEdwardsCurve R) : E.Point := ⟨zero, E.zero_mem_affinePoints⟩

/-- Negation of affine coordinates on a twisted Edwards curve. -/
def neg (p : R × R) : R × R := (-p.1, p.2)

lemma neg_mem_affinePoints (E : TwistedEdwardsCurve R) (p : R × R) :
neg p ∈ E.affinePoints ↔ p ∈ E.affinePoints := by
change E.a * (-p.1) ^ 2 + p.2 ^ 2 = 1 + E.d * (-p.1) ^ 2 * p.2 ^ 2 ↔
E.a * p.1 ^ 2 + p.2 ^ 2 = 1 + E.d * p.1 ^ 2 * p.2 ^ 2
rw [neg_sq]

/-- The usual coefficient conditions for a nonsingular twisted Edwards model over a field.
Keeping this predicate separate from `TwistedEdwardsCurve` permits the equation and its points to
be used over more general rings and also permits partially specified curves during developments.
-/
def IsValid (E : TwistedEdwardsCurve R) : Prop := E.a ≠ 0 ∧ E.d ≠ 0 ∧ E.a ≠ E.d

end TwistedEdwardsCurve

/-- The (untwisted) Edwards curve with coefficient `d`, obtained by setting `a = 1`. -/
def edwardsCurve (d : R) : TwistedEdwardsCurve R where
a := 1
d := d

/-- The equation of `edwardsCurve d`, written out. -/
lemma edwardsCurve_equation_iff (d x y : R) :
(edwardsCurve d).Equation x y ↔ x ^ 2 + y ^ 2 = 1 + d * x ^ 2 * y ^ 2 := by
simp [TwistedEdwardsCurve.Equation, edwardsCurve]

/-- `edwardsCurve d` is a valid (nonsingular) model exactly when `d ≠ 0` and `d ≠ 1`. -/
lemma edwardsCurve_isValid_iff [Nontrivial R] (d : R) :
(edwardsCurve d).IsValid ↔ d ≠ 0 ∧ d ≠ 1 := by
constructor
· rintro ⟨_, hd, had⟩
exact ⟨hd, fun h ↦ had h.symm⟩
· rintro ⟨hd, hd1⟩
exact ⟨one_ne_zero, hd, fun h ↦ hd1 h.symm⟩

end Cslib.Crypto.Primitives.ECC
10 changes: 10 additions & 0 deletions Cslib/Crypto/Systems/Elligator/Basic.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/-
Copyright (c) 2026 Chris Anto Fröschl. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Anto Fröschl
-/
module

public import Cslib.Init
public import Mathlib.Algebra.Field.Defs
public import Mathlib.FieldTheory.Finite.Basic
98 changes: 98 additions & 0 deletions Cslib/Crypto/Systems/Elligator/Context.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/-
Copyright (c) 2026 Chris Anto Fröschl. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Anto Fröschl
-/
module

public import Cslib.Crypto.Systems.Elligator.Basic

/-!
# Bundled data and hypotheses for Elligator

Almost every statement of the Elligator 1 development repeats the same variables and the same
standing hypotheses:

* a finite field `F` whose cardinality `q` satisfies `q % 4 = 3`,
* a curve parameter `s`, sometimes with `s ≠ 0`, sometimes with `(s ^ 2 - 2) * (s ^ 2 + 2) ≠ 0`,
* an input `t ∉ {1, -1}` or a point `P` of `E(F)`.

This file provides two independent mechanisms for getting rid of this repetition:

1. *the variables are bundled* into a small inheritance hierarchy of `structure`s carrying data
only (`ParamData`, `InputData`, `MapData`, `PointData`), which is what makes dot notation such
as `M.u`, `M.v`, `M.X` available;
2. *the hypotheses are unbundled* into one `class` per hypothesis (`IsCardThreeModFour`,
`IsPrimeCard`, `IsNonzeroParam`, `IsRegularParam`), which a statement lists individually and
which are found by instance resolution instead of being passed by hand.
-/

@[expose] public section

namespace Cslib.Crypto.Systems.Elligator

variable {F : Type*} [Field F]

/-- The base field has cardinality `q ≡ 3 (mod 4)`. -/
class IsCardThreeModFour (F : Type*) [Fintype F] : Prop where
/-- The cardinality of `F` is congruent to `3` modulo `4`. -/
card_mod_four : Fintype.card F % 4 = 3

/-- The base field has prime cardinality; this is the extra assumption of Theorem 4. -/
class IsPrimeCard (F : Type*) [Fintype F] : Prop where
/-- The cardinality of `F` is prime. -/
card_prime : Prime (Fintype.card F)

/-- The curve parameter `s` is nonzero. -/
class IsNonzeroParam {F : Type*} [Field F] (s : F) : Prop where
/-- The parameter `s` is nonzero. -/
s_ne_zero : s ≠ 0

/-- The curve parameter `s` satisfies `s ^ 2 ≠ ± 2`. -/
class IsRegularParam {F : Type*} [Field F] (s : F) : Prop where
/-- The parameter `s` satisfies `(s ^ 2 - 2) * (s ^ 2 + 2) ≠ 0`. -/
s_sq_ne_pm_two : (s ^ 2 - 2) * (s ^ 2 + 2) ≠ 0

export IsCardThreeModFour (card_mod_four)
export IsPrimeCard (card_prime)
export IsNonzeroParam (s_ne_zero)
export IsRegularParam (s_sq_ne_pm_two)

/-- The curve parameter `s` of Theorem 1, bundled.

No hypotheses: the quantities `c`, `r`, `d` and the curve `E` are defined for every `s`. -/
structure ParamData (F : Type*) [Field F] where
/-- The Elligator 1 curve parameter. -/
s : F

/-- An admissible input `t ∉ {1, -1}` of the Elligator 1 map, bundled.

The two disequalities are data rather than hypotheses: they are exactly the subtype
`{n : F // n ≠ 1 ∧ n ≠ -1}` on which the unbundled definitions are given, i.e. the domain of `u`. -/
structure InputData (F : Type*) [Field F] where
/-- The input of the Elligator 1 map. -/
t : F
/-- The input is not `1`. -/
t_ne_one : t ≠ 1
/-- The input is not `-1`. -/
t_ne_neg_one : t ≠ -1

/-- A curve parameter together with an admissible input: the data of Theorem 1. -/
structure MapData (F : Type*) [Field F] extends ParamData F, InputData F

/-- A curve parameter together with a point of the plane: the data of Theorem 3. -/
structure PointData (F : Type*) [Field F] extends ParamData F where
/-- The point. -/
P : F × F

namespace InputData

variable (I : InputData F)

/-- The input, as an element of the subtype `{n : F // n ≠ 1 ∧ n ≠ -1}` on which the unbundled
definitions are given. -/
def tSub : {n : F // n ≠ 1 ∧ n ≠ -1} := ⟨I.t, I.t_ne_one, I.t_ne_neg_one⟩

end InputData

end Cslib.Crypto.Systems.Elligator
Loading
Loading