Skip to content

Commit

Permalink
compute the endomorphism order of an elliptic curve over a finite fie…
Browse files Browse the repository at this point in the history
…ld (for the rank-2 case)
  • Loading branch information
yyyyx4 committed Aug 10, 2024
1 parent 20c13a0 commit 94262db
Showing 1 changed file with 119 additions and 7 deletions.
126 changes: 119 additions & 7 deletions src/sage/schemes/elliptic_curves/ell_finite_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,10 @@ def frobenius_order(self):
This computes the curve cardinality, which may be
time-consuming.
.. SEEALSO::
:meth:`endomorphism_order`
EXAMPLES::
sage: E = EllipticCurve(GF(11),[3,3])
Expand Down Expand Up @@ -1527,7 +1531,11 @@ def _fetch_cached_order(self, other):

def height_above_floor(self, ell, e):
r"""
Return the height of the `j`-invariant of this ordinary elliptic curve on its `\ell`-volcano.
Return the height of the `j`-invariant of this elliptic curve on its `\ell`-volcano.
The curve must have a rational endomorphism ring of rank 2: This includes all
ordinary elliptic curves over finite fields as well as those supersingular
elliptic curves with Frobenius not in `\ZZ`.
INPUT:
Expand All @@ -1538,12 +1546,12 @@ def height_above_floor(self, ell, e):
.. NOTE::
For an ordinary `E/\GF{q}`, and a prime `\ell`, the height
`e` of the `\ell`-volcano containing `j(E)` is the `\ell`-adic
For a suitable `E/\GF{q}`, and a prime `\ell`, the height
`e` of the `\ell`-volcano containing `E` is the `\ell`-adic
valuation of the conductor of the order generated by the
Frobenius `\pi_E`; the height of `j(E)` on its
`\GF{q}`-Frobenius `\pi_E`; the height of `E` on its
ell-volcano is the `\ell`-adic valuation of the conductor
of the order `\text{End}(E)`.
of the order `\text{End}_{\GF{q}}(E)`.
ALGORITHM:
Expand All @@ -1560,10 +1568,51 @@ def height_above_floor(self, ell, e):
sage: E.height_above_floor(2,8)
5
"""
if self.is_supersingular():
raise ValueError("{} is not ordinary".format(self))
pi = self.frobenius()
if pi in ZZ:
raise ValueError("{} has a (rational) endomorphism ring of rank 4".format(self))

Check warning on line 1573 in src/sage/schemes/elliptic_curves/ell_finite_field.py

View check run for this annotation

Codecov / codecov/patch

src/sage/schemes/elliptic_curves/ell_finite_field.py#L1573

Added line #L1573 was not covered by tests

e = ZZ(e)
if not e:
return ZZ.zero()

Check warning on line 1577 in src/sage/schemes/elliptic_curves/ell_finite_field.py

View check run for this annotation

Codecov / codecov/patch

src/sage/schemes/elliptic_curves/ell_finite_field.py#L1577

Added line #L1577 was not covered by tests

if self.is_supersingular():
if ell == self.base_field().characteristic():
# In this (exceptional) case, the Frobenius can always be divided
# by the maximal possible power of the characteristic. The reason
# is that Frobenius must be of the form phi o [p^k] where phi is
# a purely inseparable isogeny of degree 1 or p, hence this [p^k]
# can always be divided out while retaining an endomorphism.
assert (ell**(2*e)).divides(self.base_field().cardinality())
return e

# In the supersingular case, the j-invariant alone does not determine
# the level in the volcano. (The underlying reason is that there can
# be multiple non-F_q-isomorphic curves with a given j-invariant in
# the isogeny graph.)
# Example: y^2 = x^3 ± x over F_p with p congruent to 3 modulo 4 have
# distinct (rational) endomorphism rings.
# Thus we run the "probing the depths" algorithm with F_q-isomorphism
# classes of curves instead.
E0 = [self] * 3
E1 = [phi.codomain() for phi in self.isogenies_prime_degree(ell)]
assert E1
if len(E1) == 1:
return ZZ.zero()
assert len(E1) == ell + 1
h = ZZ.one()
while True:
for i in range(3):
isogs = E1[i].isogenies_prime_degree(ell)
try:
step = next(phi for phi in isogs if not phi.codomain().is_isomorphic(E0[i]))
except StopIteration:
return h
E0[i], E1[i] = step.domain(), step.codomain()
h += 1
assert h <= e

Check warning on line 1613 in src/sage/schemes/elliptic_curves/ell_finite_field.py

View check run for this annotation

Codecov / codecov/patch

src/sage/schemes/elliptic_curves/ell_finite_field.py#L1611-L1613

Added lines #L1611 - L1613 were not covered by tests
raise NotImplementedError

j = self.j_invariant()
if j in [0, 1728]:
return e
Expand Down Expand Up @@ -1668,6 +1717,69 @@ def endomorphism_discriminant_from_class_number(self, h):
return (v//cs[0])**2 * D0
raise ValueError("Incorrect class number {}".format(h))

def endomorphism_order(self):
r"""
Return a quadratic order isomorphic to the endomorphism ring
of this elliptic curve, assuming the order has rank two.
.. NOTE::
In the future, this method will hopefully be extended to return a
:class:`~sage.algebras.quatalg.quaternion_algebra.QuaternionOrder`
object in the rank-4 case, but this has not been implemented yet.
.. SEEALSO::
:meth:`frobenius_order`
EXAMPLES::
sage: E = EllipticCurve(GF(11), [3,3])
sage: E.endomorphism_order()
Maximal Order generated by 1/2*pi + 1/2 in Number Field in pi with defining polynomial x^2 - 4*x + 11
It also works for supersingular elliptic curves provided that Frobenius
is not in `\ZZ`::
sage: E = EllipticCurve(GF(11), [1,0])
sage: E.is_supersingular()
True
sage: E.endomorphism_order()
Order of conductor 2 generated by pi in Number Field in pi with defining polynomial x^2 + 11
::
sage: E = EllipticCurve(GF(11), [-1,0])
sage: E.is_supersingular()
True
sage: E.endomorphism_order()
Maximal Order generated by 1/2*pi + 1/2 in Number Field in pi with defining polynomial x^2 + 11
There are some exceptional cases where Frobenius itself is divisible
by the characteristic::
sage: EllipticCurve([GF(7^2).gen(), 0]).endomorphism_order()
Gaussian Integers generated by 1/7*pi in Number Field in pi with defining polynomial x^2 + 49
sage: EllipticCurve(GF(3^5), [1, 0]).endomorphism_order()
Order of conductor 2 generated by 1/9*pi in Number Field in pi with defining polynomial x^2 + 243
sage: EllipticCurve(GF(7^3), [-1, 0]).endomorphism_order()
Maximal Order generated by 1/14*pi + 1/2 in Number Field in pi with defining polynomial x^2 + 343
"""
pi = self.frobenius()
if pi in ZZ:
raise NotImplementedError('the rank-4 case is not supported yet')

Check warning on line 1770 in src/sage/schemes/elliptic_curves/ell_finite_field.py

View check run for this annotation

Codecov / codecov/patch

src/sage/schemes/elliptic_curves/ell_finite_field.py#L1770

Added line #L1770 was not covered by tests

O = self.frobenius_order()
f0 = O.conductor()

f = 1
for l,e in f0.factor():
h = self.height_above_floor(l, e)
f *= l**(e-h)

K = O.number_field()
return K.order_of_conductor(f)

def twists(self):
r"""
Return a list of `k`-isomorphism representatives of all
Expand Down

0 comments on commit 94262db

Please sign in to comment.