Definitions/Def_TateCurve_XMultAlignment.lean
Symmetric addition hypotheses and the Tate-curve -ladder
Over a complete, nontrivially normed ultrametric field K of characteristic zero, with Tate parameter q, the module's main definition is the Prop-valued structure SymAddHyps q, a bundle of three universally quantified identities for the x-coordinate function u \mapsto pointX q u of the Tate curve curve q (whose b-invariants are b_2 = 1, b_4 = 2a_4(q), b_6 = 4a_6(q)). The field sum asserts, for all u,v satisfying AddParams q u v (that is, q,u,v \ne 0 and each of u, v, uv, uv^{-1} off the lattice, q^n w \ne 1 for all n \in \mathbb{Z}), that (X(uv)+X(uv^{-1}))(X(u)-X(v))^2 equals symSumNum q (X u) (X v) = 2x_1x_2(x_1+x_2)+x_1x_2+2a_4(q)(x_1+x_2)+4a_6(q); the field prod asserts the companion identity for the product X(uv)X(uv^{-1})(X(u)-X(v))^2 with symProdNum; the field dbl asserts, for u \ne 0 with u and u^2 off the lattice, the cleared duplication formula X(u^2)\,\Psi_2^{\mathrm{Sq}}(X(u)) = \Phi_2(X(u)).
Alongside this the module records: primed restatements, for a Weierstrass curve W over a field via its affine model, of the identity for \mathrm{addX} times (x_1-x_2)^2 and of the sum of the two \mathrm{addX} values obtained from y_2 and -y_2 - a_1x_2 - a_3; that (X(u),Y(u)) satisfies the affine Weierstrass equation of curve q and is nonsingular when 0 \ne \|q\|_+ < 1 and u is off the lattice; a Bézout argument showing u^j is off the lattice for 0 < j < p when u^p = q^s and p is prime; the ladder theorem that, granting SymAddHyps q and m \cdot P \ne 0 for 2 \le m \le N, the multiples j \cdot P of P = (X(u),Y(u)) are affine with x-coordinate X(u^j) for 1 \le j \le N; and, for odd prime p with u^p = q^s, that either p \cdot P = 0 or m \cdot P = 0 for some 2 \le m \le p-1.
Relation to Mathlib
addX, slope, negY, Ψ₂Sq, Φ, the point group and Point.xOrZero are Mathlib's; the Tate-curve data (curve, pointX, pointY, OffLattice, AddParams, symSumNum, symProdNum) and the hypothesis bundle SymAddHyps are the project's own. The two primed lemmas repeat, for W : WeierstrassCurve F through W.toAffine, statements the project also records for an affine curve.
Where it is used
These identities and the ladder are used to show that the Tate-curve point attached to a parameter u with u^p \in q^{\mathbb{Z}} is a p-torsion point, towards an explicit description of the p-torsion of a Tate curve and thence the local analysis at p in the level-lowering argument.
References
- J. H. Silverman, Advanced Topics in the Arithmetic of Elliptic Curves, Graduate Texts in Mathematics 151, Springer, 1994, Chapter V
- J. H. Silverman, The Arithmetic of Elliptic Curves, Graduate Texts in Mathematics 106, Springer, 1986, Chapter III
References are suggested automatically and have not been individually verified.
English text generated automatically from the Lean source; the Lean statement is authoritative.
- 332 lines
- 15 declarations
- used in the statements of 3 theorems and imported by 0 proofs
- imports 4 definition modules, and the statements of 3 theorems
Source file: Definitions/Def_TateCurve_XMultAlignment.lean
Imports
Def_TateCurve_XMultStructureDef_TateCurve_TateParameterDef_WeierstrassCurve_AddFormulaDef_NetPairing_Basic
Theorems imported by this definition module
Declarations
- lemma
WeierstrassCurve.Affine.addX_mul_sq_of_X_ne' - theorem
WeierstrassCurve.Affine.addX_add_addX_negY_mul_sq' - structure
TateCurve.SymAddHyps - field
TateCurve.SymAddHyps.sum - field
TateCurve.SymAddHyps.prod - field
TateCurve.SymAddHyps.dbl - lemma
TateCurve.equation_point - lemma
TateCurve.nonsingular_point - lemma
TateCurve.pow_succ_mul_inv - lemma
TateCurve.addParams_pow - lemma
TateCurve.offLattice_pow_of_prime - theorem
TateCurve.xOrZero_nsmul_of_forall_ne_zero - lemma
TateCurve.pointX_pow_pred_eq - theorem
TateCurve.nsmul_prime_eq_zero_of_forall_ne_zero - theorem
TateCurve.nsmul_prime_eq_zero_or_exists_nsmul_eq_zero
Source
import Mathlib import Definitions.Def_TateCurve_XMultStructure import Definitions.Def_TateCurve_TateParameter import Definitions.Def_WeierstrassCurve_AddFormula import Definitions.Def_NetPairing_Basic import Theorems.Thm_TateCurve_equation_pointX_pointY import Theorems.Thm_TateCurve_pointX_inv import Theorems.Thm_TateCurve_pointX_zpow_mul set_option autoImplicit false set_option linter.unusedSectionVars false namespace WeierstrassCurve.Affine variable {F : Type*} [Field F] {W : WeierstrassCurve F} lemma addX_mul_sq_of_X_ne' [DecidableEq F] {x₁ x₂ : F} (y₁ y₂ : F) (hx : x₁ ≠ x₂) : W.toAffine.addX x₁ x₂ (W.toAffine.slope x₁ x₂ y₁ y₂) * (x₁ - x₂) ^ 2 = (y₁ - y₂) ^ 2 + W.a₁ * (y₁ - y₂) * (x₁ - x₂) - (W.a₂ + x₁ + x₂) * (x₁ - x₂) ^ 2 := by have hd : x₁ - x₂ ≠ 0 := sub_ne_zero.mpr hx rw [slope_of_X_ne hx, addX] field_simp ring theorem addX_add_addX_negY_mul_sq' [DecidableEq F] {x₁ x₂ y₁ y₂ : F} (h₁ : W.toAffine.Equation x₁ y₁) (h₂ : W.toAffine.Equation x₂ y₂) (hx : x₁ ≠ x₂) : (W.toAffine.addX x₁ x₂ (W.toAffine.slope x₁ x₂ y₁ y₂) + W.toAffine.addX x₁ x₂ (W.toAffine.slope x₁ x₂ y₁ (W.toAffine.negY x₂ y₂))) * (x₁ - x₂) ^ 2 = 2 * (x₁ * x₂) * (x₁ + x₂) + W.b₂ * (x₁ * x₂) + W.b₄ * (x₁ + x₂) + W.b₆ := by have e₁ := addX_mul_sq_of_X_ne' (W := W) y₁ y₂ hx have e₂ := addX_mul_sq_of_X_ne' (W := W) y₁ (W.toAffine.negY x₂ y₂) hx rw [W.toAffine.equation_iff x₁ y₁] at h₁ rw [W.toAffine.equation_iff x₂ y₂] at h₂ rw [add_mul, e₁, e₂, negY, b₂, b₄, b₆] linear_combination 2 * h₁ + 2 * h₂ end WeierstrassCurve.Affine set_option linter.unusedSectionVars false open WeierstrassCurve.Affine open Polynomial namespace TateCurve variable {K : Type*} [NontriviallyNormedField K] [IsUltrametricDist K] [CompleteSpace K] [CharZero K] [DecidableEq K] variable {q u : K} structure SymAddHyps (q : K) : Prop where sum : ∀ u v : K, AddParams q u v → (pointX q (u * v) + pointX q (u * v⁻¹)) * (pointX q u - pointX q v) ^ 2 = symSumNum q (pointX q u) (pointX q v) prod : ∀ u v : K, AddParams q u v → pointX q (u * v) * pointX q (u * v⁻¹) * (pointX q u - pointX q v) ^ 2 = symProdNum q (pointX q u) (pointX q v) dbl : ∀ u : K, u ≠ 0 → OffLattice q u → OffLattice q (u ^ 2) → pointX q (u ^ 2) * ((curve q).Ψ₂Sq).eval (pointX q u) = ((curve q).Φ 2).eval (pointX q u) section TatePoint lemma equation_point (hq0 : q ≠ 0) (hq : ‖q‖₊ < 1) (hu0 : u ≠ 0) (hu : OffLattice q u) : (curve q).toAffine.Equation (pointX q u) (pointY q u) := by have h := equation_pointX_pointY hq0 hq hu0 hu rw [WeierstrassCurve.Affine.equation_iff] show pointY q u ^ 2 + (curve q).a₁ * pointX q u * pointY q u + (curve q).a₃ * pointY q u = pointX q u ^ 3 + (curve q).a₂ * pointX q u ^ 2 + (curve q).a₄ * pointX q u + (curve q).a₆ rw [curve_a₁, curve_a₂, curve_a₃, curve_a₄, curve_a₆] linear_combination h lemma nonsingular_point (hq0 : q ≠ 0) (hq : ‖q‖₊ < 1) (hu0 : u ≠ 0) (hu : OffLattice q u) : (curve q).toAffine.Nonsingular (pointX q u) (pointY q u) := (WeierstrassCurve.Affine.equation_iff_nonsingular_of_Δ_ne_zero (Δ_ne_zero hq0 hq)).mp (equation_point hq0 hq hu0 hu) end TatePoint section PowerBookkeeping private lemma pow_succ_mul_inv (hu0 : u ≠ 0) (k : ℕ) : u ^ (k + 1) * u⁻¹ = u ^ k := by rw [pow_succ, mul_assoc, mul_inv_cancel₀ hu0, mul_one] private lemma addParams_pow (hq0 : q ≠ 0) (hu0 : u ≠ 0) {N k : ℕ} (hk : k + 3 ≤ N) (hoff : ∀ j : ℕ, 1 ≤ j → j ≤ N → OffLattice q (u ^ j)) : AddParams q (u ^ (k + 2)) u := by have h1 : OffLattice q u := by have h := hoff 1 le_rfl (by omega); rwa [pow_one] at h have hmul : OffLattice q (u ^ (k + 2) * u) := by have h := hoff (k + 2 + 1) (by omega) (by omega) rwa [pow_succ] at h have hdiv : OffLattice q (u ^ (k + 2) * u⁻¹) := by have h := hoff (k + 1) (by omega) (by omega) have heq : u ^ (k + 2) * u⁻¹ = u ^ (k + 1) := pow_succ_mul_inv hu0 (k + 1) rwa [heq] exact ⟨hq0, pow_ne_zero _ hu0, hu0, hoff (k + 2) (by omega) (by omega), h1, hmul, hdiv⟩ lemma offLattice_pow_of_prime {p j : ℕ} {s : ℤ} (hq0 : q ≠ 0) (hu0 : u ≠ 0) (hu : OffLattice q u) (hpow : u ^ p = q ^ s) (hp : p.Prime) (hj0 : 0 < j) (hjp : j < p) : OffLattice q (u ^ j) := by intro n hn have hju : u ^ ((j : ℕ) : ℤ) = q ^ (-n) := by rw [zpow_natCast] have h1 : q ^ (-n) * (q ^ n * u ^ j) = q ^ (-n) * 1 := by rw [hn] rwa [← mul_assoc, ← zpow_add₀ hq0, neg_add_cancel, zpow_zero, one_mul, mul_one] at h1 have hpz : u ^ ((p : ℕ) : ℤ) = q ^ s := by rw [zpow_natCast]; exact hpow have hcop : Nat.Coprime p j := (Nat.Prime.coprime_iff_not_dvd hp).mpr (fun hdvd => absurd (Nat.le_of_dvd hj0 hdvd) (by omega)) have hbez : (1 : ℤ) = (p : ℤ) * Nat.gcdA p j + (j : ℤ) * Nat.gcdB p j := by have h := Nat.gcd_eq_gcd_ab p j rwa [hcop.gcd_eq_one, Nat.cast_one] at h have hkey : u = q ^ (s * Nat.gcdA p j + (-n) * Nat.gcdB p j) := by have h1 : u = (u ^ ((p : ℕ) : ℤ)) ^ Nat.gcdA p j * (u ^ ((j : ℕ) : ℤ)) ^ Nat.gcdB p j := by rw [← zpow_mul, ← zpow_mul, ← zpow_add₀ hu0, ← hbez, zpow_one] rw [h1, hpz, hju, ← zpow_mul, ← zpow_mul, ← zpow_add₀ hq0] exact hu (-(s * Nat.gcdA p j + (-n) * Nat.gcdB p j)) (by rw [hkey, ← zpow_add₀ hq0, neg_add_cancel, zpow_zero]) end PowerBookkeeping section Ladder theorem xOrZero_nsmul_of_forall_ne_zero (hyps : SymAddHyps q) (hq0 : q ≠ 0) (hu0 : u ≠ 0) {N : ℕ} (hoff : ∀ j : ℕ, 1 ≤ j → j ≤ N → OffLattice q (u ^ j)) (hns : (curve q).toAffine.Nonsingular (pointX q u) (pointY q u)) (htor : ∀ m : ℕ, 2 ≤ m → m ≤ N → m • (Point.some (pointX q u) (pointY q u) hns : (curve q).toAffine.Point) ≠ 0) : ∀ j : ℕ, 1 ≤ j → j ≤ N → j • (Point.some (pointX q u) (pointY q u) hns : (curve q).toAffine.Point) ≠ 0 ∧ (j • (Point.some (pointX q u) (pointY q u) hns : (curve q).toAffine.Point)).xOrZero = pointX q (u ^ j) := by set P : (curve q).toAffine.Point := Point.some (pointX q u) (pointY q u) hns with hP intro j induction j using Nat.strong_induction_on with | _ j ih => intro hj1 hjN rcases lt_or_ge j 3 with hj3 | hj3 · interval_cases j · refine ⟨by rw [one_nsmul, hP]; exact Point.some_ne_zero hns, ?_⟩ rw [one_nsmul, hP, Point.xOrZero_some, pow_one] · have hoff1 : OffLattice q u := by have h := hoff 1 le_rfl (by omega); rwa [pow_one] at h have hoff2 : OffLattice q (u ^ 2) := hoff 2 (by omega) hjN by_cases hy : pointY q u = (curve q).toAffine.negY (pointX q u) (pointY q u) · exact absurd (by rw [two_nsmul, hP]; exact Point.add_self_of_Y_eq hy) (htor 2 le_rfl hjN) · have hT : ((curve q).toAffine.Ψ₂Sq).eval (pointX q u) ≠ 0 := by have hsq := WeierstrassCurve.Affine.sq_sub_negY_eq_eval_Ψ₂Sq (W := (curve q).toAffine) hns.left rw [← hsq] exact pow_ne_zero 2 (sub_ne_zero.mpr hy) have hcurve := WeierstrassCurve.Affine.addX_self_mul_Ψ₂Sq (W := (curve q).toAffine) hns.left hy have hser : pointX q (u ^ 2) * ((curve q).toAffine.Ψ₂Sq).eval (pointX q u) = (((curve q).toAffine.Φ 2)).eval (pointX q u) := hyps.dbl u hu0 hoff1 hoff2 have hx2 : (curve q).toAffine.addX (pointX q u) (pointX q u) ((curve q).toAffine.slope (pointX q u) (pointX q u) (pointY q u) (pointY q u)) = pointX q (u ^ 2) := mul_right_cancel₀ hT (hcurve.trans hser.symm) refine ⟨?_, ?_⟩ · rw [two_nsmul, hP, Point.add_self_of_Y_ne hy] exact Point.some_ne_zero _ · rw [two_nsmul, hP, Point.add_self_of_Y_ne hy, Point.xOrZero_some] exact hx2 · obtain ⟨k, rfl⟩ : ∃ k, j = k + 3 := ⟨j - 3, by omega⟩ obtain ⟨hQne, hQx⟩ := ih (k + 2) (by omega) (by omega) (by omega) obtain ⟨hRne, hRx⟩ := ih (k + 1) (by omega) (by omega) (by omega) obtain ⟨xj, yj, hj, hQeq⟩ : ∃ (xj yj : K) (hj : (curve q).toAffine.Nonsingular xj yj), (k + 2) • P = Point.some xj yj hj := by cases hQP : (k + 2) • P with | zero => exact absurd hQP hQne | @some a b hc => exact ⟨a, b, hc, rfl⟩ have hxj : xj = pointX q (u ^ (k + 2)) := by rw [hQeq, Point.xOrZero_some] at hQx exact hQx by_cases hxx : xj = pointX q u · exfalso rcases Y_eq_of_X_eq hj.left hns.left hxx with hyy | hyy · have hQP : (k + 2) • P = P := by rw [hQeq, hP] subst hxx; subst hyy rw [Subsingleton.elim hj hns] have hsucc : (k + 2) • P = (k + 1) • P + P := succ_nsmul P (k + 1) have h0 : (k + 1) • P + P = 0 + P := by rw [zero_add, ← hsucc, hQP] exact hRne (add_right_cancel h0) · have hQP : (k + 2) • P = -P := by rw [hQeq, hP, Point.neg_some] subst hxx; subst hyy exact congrArg _ (Subsingleton.elim _ _) have hk3 : (k + 3) • P = 0 := by have hsucc : (k + 3) • P = (k + 2) • P + P := succ_nsmul P (k + 2) rw [hsucc, hQP, neg_add_cancel] exact htor (k + 3) (by omega) hjN hk3 · have hap : AddParams q (u ^ (k + 2)) u := addParams_pow hq0 hu0 hjN hoff have hS1 := hyps.sum (u ^ (k + 2)) u hap rw [show u ^ (k + 2) * u = u ^ (k + 2 + 1) from (pow_succ u (k + 2)).symm, show u ^ (k + 2) * u⁻¹ = u ^ (k + 1) from pow_succ_mul_inv hu0 (k + 1), symSumNum_eq_b, ← hxj] at hS1 have hsum := WeierstrassCurve.Affine.addX_add_addX_negY_mul_sq' (W := curve q) hj.left hns.left hxx have hAm : (curve q).toAffine.addX xj (pointX q u) ((curve q).toAffine.slope xj (pointX q u) yj ((curve q).toAffine.negY (pointX q u) (pointY q u))) = pointX q (u ^ (k + 1)) := by have h1 := hRx have hsucc2 : (k + 2) • P = (k + 1) • P + P := succ_nsmul P (k + 1) have hrearr : (k + 1) • P = (k + 2) • P + -P := by rw [hsucc2, add_neg_cancel_right] rw [hrearr, hQeq, hP, Point.neg_some, Point.add_of_X_ne hxx, Point.xOrZero_some] at h1 exact h1 have hD2 : (xj - pointX q u) ^ 2 ≠ 0 := pow_ne_zero 2 (sub_ne_zero.mpr hxx) have hcomb := mul_right_cancel₀ hD2 (hsum.trans hS1.symm) rw [hAm] at hcomb have hfinal : (curve q).toAffine.addX xj (pointX q u) ((curve q).toAffine.slope xj (pointX q u) yj (pointY q u)) = pointX q (u ^ (k + 2 + 1)) := add_right_cancel hcomb have hsucc : (k + 3) • P = (k + 2) • P + P := succ_nsmul P (k + 2) refine ⟨?_, ?_⟩ · rw [hsucc, hQeq, hP, Point.add_of_X_ne hxx] exact Point.some_ne_zero _ · rw [hsucc, hQeq, hP, Point.add_of_X_ne hxx, Point.xOrZero_some] exact hfinal end Ladder section Endgame lemma pointX_pow_pred_eq (hq0 : q ≠ 0) (hu0 : u ≠ 0) (hu : OffLattice q u) {p : ℕ} (hp1 : 1 ≤ p) {s : ℤ} (hpow : u ^ p = q ^ s) : pointX q (u ^ (p - 1)) = pointX q u := by have h1 : u ^ p = u ^ (p - 1) * u := by conv_lhs => rw [show p = (p - 1) + 1 by omega] rw [pow_succ] have h2 : u ^ (p - 1) = q ^ s * u⁻¹ := by rw [← hpow, h1, mul_assoc, mul_inv_cancel₀ hu0, mul_one] rw [h2, pointX_zpow_mul hq0, pointX_inv hq0 hu0 hu] theorem nsmul_prime_eq_zero_of_forall_ne_zero {p : ℕ} (hyps : SymAddHyps q) (hq0 : q ≠ 0) (hu0 : u ≠ 0) (hu : OffLattice q u) {s : ℤ} (hpow : u ^ p = q ^ s) (hp : p.Prime) (hodd : Odd p) (hns : (curve q).toAffine.Nonsingular (pointX q u) (pointY q u)) (htor : ∀ m : ℕ, 2 ≤ m → m ≤ p - 1 → m • (Point.some (pointX q u) (pointY q u) hns : (curve q).toAffine.Point) ≠ 0) : p • (Point.some (pointX q u) (pointY q u) hns : (curve q).toAffine.Point) = 0 := by set P : (curve q).toAffine.Point := Point.some (pointX q u) (pointY q u) hns with hP have hp3 : 3 ≤ p := by have h2 := hp.two_le rcases hodd with ⟨t, ht⟩ omega have hoff : ∀ j : ℕ, 1 ≤ j → j ≤ p - 1 → OffLattice q (u ^ j) := fun j hj1 hj2 => offLattice_pow_of_prime hq0 hu0 hu hpow hp (by omega) (by omega) have halign := xOrZero_nsmul_of_forall_ne_zero hyps hq0 hu0 hoff hns htor obtain ⟨hne, hx⟩ := halign (p - 1) (by omega) le_rfl have hXp : pointX q (u ^ (p - 1)) = pointX q u := pointX_pow_pred_eq hq0 hu0 hu (by omega) hpow obtain ⟨x', y', h', hQeq⟩ : ∃ (x' y' : K) (h' : (curve q).toAffine.Nonsingular x' y'), (p - 1) • P = Point.some x' y' h' := by cases hQP : (p - 1) • P with | zero => exact absurd hQP hne | @some a b hc => exact ⟨a, b, hc, rfl⟩ have hx' : x' = pointX q u := by rw [hQeq, Point.xOrZero_some] at hx rw [hx, hXp] rcases Y_eq_of_X_eq h'.left hns.left hx' with hyy | hyy · exfalso have hQP : (p - 1) • P = P := by rw [hQeq, hP] subst hx'; subst hyy rw [Subsingleton.elim h' hns] obtain ⟨hne2, _⟩ := halign (p - 2) (by omega) (by omega) have h0 : (p - 2) • P + P = 0 + P := by rw [zero_add, ← succ_nsmul, show p - 2 + 1 = p - 1 by omega, hQP] exact hne2 (add_right_cancel h0) · have hQP : (p - 1) • P = -P := by rw [hQeq, hP, Point.neg_some] subst hx'; subst hyy exact congrArg _ (Subsingleton.elim _ _) have hsucc : p • P = (p - 1) • P + P := by conv_lhs => rw [show p = (p - 1) + 1 by omega] exact succ_nsmul P (p - 1) rw [hsucc, hQP, neg_add_cancel] theorem nsmul_prime_eq_zero_or_exists_nsmul_eq_zero {p : ℕ} (hyps : SymAddHyps q) (hq0 : q ≠ 0) (hu0 : u ≠ 0) (hu : OffLattice q u) {s : ℤ} (hpow : u ^ p = q ^ s) (hp : p.Prime) (hodd : Odd p) (hns : (curve q).toAffine.Nonsingular (pointX q u) (pointY q u)) : p • (Point.some (pointX q u) (pointY q u) hns : (curve q).toAffine.Point) = 0 ∨ ∃ m : ℕ, 2 ≤ m ∧ m ≤ p - 1 ∧ m • (Point.some (pointX q u) (pointY q u) hns : (curve q).toAffine.Point) = 0 := by by_cases h : ∃ m : ℕ, 2 ≤ m ∧ m ≤ p - 1 ∧ m • (Point.some (pointX q u) (pointY q u) hns : (curve q).toAffine.Point) = 0 · exact Or.inr h · refine Or.inl (nsmul_prime_eq_zero_of_forall_ne_zero hyps hq0 hu0 hu hpow hp hodd hns (fun m hm1 hm2 hm0 => h ⟨m, hm1, hm2, hm0⟩)) end Endgame end TateCurve
Statements phrased using this module (3)
- Unconditional p-torsion parametrisation of the Tate curve
TateCurve.eq_zero_or_eq_tateParam_unconditional38 below · depth 13 - p-torsion of the Tate curve under `SymAddHyps`
TateCurve.eq_zero_or_eq_tateParam_of_prime_nsmul_eq_zero5 below · depth 14 - Unconditional symmetric addition relations for the Tate curve
TateCurve.symAddHyps_unconditional31 below · depth 20