Skip to content

Commit

Permalink
implement Bröker's algorithm for constructing supersingular curves
Browse files Browse the repository at this point in the history
  • Loading branch information
yyyyx4 committed Nov 6, 2023
1 parent ebef87a commit 71e7ca5
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/doc/en/reference/references/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1231,6 +1231,9 @@ REFERENCES:
:doi:`10.1109/SFCS.1989.63516`,
<http://www.cs.cmu.edu/~15859n/RelatedWork/Broder-GenRanSpanningTrees.pdf>_
.. [Bro2009] \R. Bröker: *Constructing supersingular elliptic curves*.
Journal of Combinatorics and Number Theory 1.3 (2009), pp. 269--273.
.. [Broder2000] Broder, A.Z., Kumar, R., Maghoul, F., Raghavan, P., Rajagopalan,
S., Stata, R., Tomkins, A., Wiener, J.L.: Graph structure in
the web. Computer Networks 33(1-6), 309–320 (2000)
Expand Down
2 changes: 2 additions & 0 deletions src/sage/schemes/elliptic_curves/all.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
lazy_import('sage.schemes.elliptic_curves.ell_rational_field',
['cremona_curves', 'cremona_optimal_curves'])

lazy_import('sage.schemes.elliptic_curves.ell_finite_field', 'special_supersingular_curve')

from .cm import ( cm_orders,
cm_j_invariants,
cm_j_invariants_and_orders,
Expand Down
171 changes: 171 additions & 0 deletions src/sage/schemes/elliptic_curves/ell_finite_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
- Mariah Lenox (2011-03): Added ``set_order`` method
- Lorenz Panny, John Cremona (2023-02): ``.twists()``
- Lorenz Panny (2023): ``special_supersingular_curve()``
"""

# ****************************************************************************
Expand Down Expand Up @@ -2414,3 +2416,172 @@ def is_j_supersingular(j, proof=True):
# expensive since it involves counting the number of points on E):

return E.trace_of_frobenius() % p == 0

def special_supersingular_curve(F, *, endomorphism=False):
r"""
Given a finite field ``F`` of degree `1` or `2`, construct a
"special" supersingular elliptic curve `E` defined over ``F``.
Such a curve
- has coefficients in `\FF_p`;
- has group structure `E(\FF_p) \cong \ZZ/(p+1)` and
`E(\FF_{p^2}) \cong \ZZ/(p+1) \times \ZZ/(p+1)`;
- has an endomorphism `\vartheta` of small degree `q` that
anticommutes with the `\FF_p`-Frobenius on `E`.
(The significance of `\vartheta` is that any such endomorphism,
together with the `\FF_p`-Frobenius, generates the endomorphism
algebra `\End(E) \otimes \QQ`.)
INPUT:
- ``F`` -- finite field `\FF_{p^r}` of degree `r \in \{1,2\}`.
- ``endomorphism`` -- boolean (optional, default ``False``):
When set to ``True``, it is required that `r=2`, and the
function then additionally returns `\vartheta`.
EXAMPLES::
sage: special_supersingular_curve(GF(1013^2), endomorphism=True)
(Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in z2 of size 1013^2,
Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in z2 of size 1013^2 to Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in z2 of size 1013^2)
sage: special_supersingular_curve(GF(1019^2), endomorphism=True)
(Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 1019^2,
Elliptic-curve endomorphism of Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 1019^2
Via: (u,r,s,t) = (389*z2 + 241, 0, 0, 0))
sage: special_supersingular_curve(GF(1021^2), endomorphism=True)
(Elliptic Curve defined by y^2 = x^3 + 785*x + 794 over Finite Field in z2 of size 1021^2,
Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 785*x + 794 over Finite Field in z2 of size 1021^2 to Elliptic Curve defined by y^2 = x^3 + 785*x + 794 over Finite Field in z2 of size 1021^2)
sage: special_supersingular_curve(GF(1031^2), endomorphism=True)
(Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 1031^2,
Elliptic-curve endomorphism of Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 1031^2
Via: (u,r,s,t) = (747*z2 + 284, 0, 0, 0))
sage: special_supersingular_curve(GF(1033^2), endomorphism=True)
(Elliptic Curve defined by y^2 = x^3 + 53*x + 980 over Finite Field in z2 of size 1033^2,
Isogeny of degree 11 from Elliptic Curve defined by y^2 = x^3 + 53*x + 980 over Finite Field in z2 of size 1033^2 to Elliptic Curve defined by y^2 = x^3 + 53*x + 980 over Finite Field in z2 of size 1033^2)
sage: special_supersingular_curve(GF(1039^2), endomorphism=True)
(Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 1039^2,
Elliptic-curve endomorphism of Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 1039^2
Via: (u,r,s,t) = (626*z2 + 200, 0, 0, 0))
sage: special_supersingular_curve(GF(1049^2), endomorphism=True)
(Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in z2 of size 1049^2,
Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in z2 of size 1049^2 to Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in z2 of size 1049^2)
sage: special_supersingular_curve(GF(1051^2), endomorphism=True)
(Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 1051^2,
Elliptic-curve endomorphism of Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 1051^2
Via: (u,r,s,t) = (922*z2 + 129, 0, 0, 0))
TESTS::
sage: p = random_prime(1000)
sage: E = special_supersingular_curve(GF(p))
sage: E.is_supersingular()
True
sage: E.order() == p + 1
True
sage: F.<t> = GF((p,2))
sage: E, endo = special_supersingular_curve(F, endomorphism=True)
sage: E.is_supersingular()
True
sage: E.j_invariant() in GF(p)
True
sage: E.abelian_group().invariants() == (p+1, p+1)
True
sage: endo.domain() is endo.codomain() is E
True
sage: endo.trace()
0
sage: pi = E.frobenius_isogeny()
sage: pi.codomain() is pi.domain() is E
True
sage: pi * endo == -endo * pi
True
.. NOTE::
This function makes no guarantees about the distribution of
the output. The current implementation is deterministic in
many cases.
ALGORITHM: [Bro2009]_, Algorithm 2.4
"""
if not isinstance(F, FiniteField) or (deg := F.degree()) > 2:
raise TypeError('input must be a finite field of degree 1 or 2')

Check warning on line 2520 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#L2520

Added line #L2520 was not covered by tests
p = F.characteristic()

if endomorphism and deg % 2:
raise ValueError('endomorphism was requested but is not defined over given field')

Check warning on line 2524 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#L2524

Added line #L2524 was not covered by tests

E = None

if p == 2:
q = 3
E = EllipticCurve(F, [0,0,1,0,0])

Check warning on line 2530 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#L2529-L2530

Added lines #L2529 - L2530 were not covered by tests

elif p % 4 == 3:
q = 1
E = EllipticCurve(F, [1,0])

elif p % 3 == 2:
q = 3
E = EllipticCurve(F, [0,1])

elif p % 8 == 5:
q = 2
E = EllipticCurve(F, [-4320, 96768])

else:
from sage.arith.misc import legendre_symbol
for q in map(ZZ, range(3,p,4)):
if not q.is_prime():
continue

Check warning on line 2548 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#L2548

Added line #L2548 was not covered by tests
if legendre_symbol(-q, p) == -1:
break
else:
assert False # should never happen

Check warning on line 2552 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#L2552

Added line #L2552 was not covered by tests

if E is None:
from sage.arith.misc import fundamental_discriminant
from sage.schemes.elliptic_curves.cm import hilbert_class_polynomial
H = hilbert_class_polynomial(fundamental_discriminant(-q))
j = H.change_ring(GF(p)).any_root()
a = 27 * j / (4 * (1728-j))
E = EllipticCurve(F, [a,-a])

E.set_order((p+1)**deg)

if not endomorphism:
return E

if q == 1 or p <= 13:
if q == 1:
endos = E.automorphisms()
else:
endos = (iso*phi for phi in E.isogenies_prime_degree(q)

Check warning on line 2571 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#L2571

Added line #L2571 was not covered by tests
for iso in phi.codomain().isomorphisms(E))
endo = next(endo for endo in endos if endo.trace().is_zero())

else:
from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism
iso = WeierstrassIsomorphism(None, (F(-q).sqrt(),0,0,0), E)
if q == 3 and E.a_invariants() == (0,0,0,0,1):
# workaround for #21883
endo = E.isogeny(E(0,1))
else:
endo = E.isogeny(None, iso.domain(), degree=q)
endo = iso * endo

endo._degree = ZZ(q)
endo.trace.set_cache(ZZ.zero())
return E, endo

0 comments on commit 71e7ca5

Please sign in to comment.