Skip to content

Commit 69d654e

Browse files
committed
compute duals of Îlu isogenies correctly in all cases
1 parent 28a7d04 commit 69d654e

File tree

1 file changed

+58
-2
lines changed

1 file changed

+58
-2
lines changed

src/sage/schemes/elliptic_curves/hom_velusqrt.py

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,6 +1072,39 @@ def kernel_polynomial(self):
10721072
return R(h).monic()
10731073

10741074
@cached_method
1075+
def as_EllipticCurveIsogeny(self):
1076+
r"""
1077+
Return the mathematically identical isogeny represented as a
1078+
:class:`EllipticCurveIsogeny` object.
1079+
1080+
.. NOTE::
1081+
1082+
The result is computed by :class:`EllipticCurveIsogeny`,
1083+
hence it obviously does not benefit from the square-root
1084+
Vélu speedup.
1085+
1086+
EXAMPLES::
1087+
1088+
sage: E = EllipticCurve(GF(101^2), [1, 1, 1, 1, 1])
1089+
sage: K = E.cardinality() // 11 * E.gens()[0]
1090+
sage: phi = E.isogeny(K, algorithm='velusqrt'); phi
1091+
Elliptic-curve isogeny (using square-root Vélu) of degree 11:
1092+
From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2
1093+
To: Elliptic Curve defined by y^2 = x^3 + 39*x + 40 over Finite Field in z2 of size 101^2
1094+
sage: psi = phi.as_EllipticCurveIsogeny(); psi
1095+
Isogeny of degree 11
1096+
from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2
1097+
to Elliptic Curve defined by y^2 = x^3 + 39*x + 40 over Finite Field in z2 of size 101^2
1098+
sage: phi == psi
1099+
True
1100+
"""
1101+
ker = self.kernel_polynomial()
1102+
phi = self.domain().isogeny(ker, degree=self.degree(), codomain=self.codomain(), check=False)
1103+
from sage.schemes.elliptic_curves.hom import find_post_isomorphism
1104+
iso = find_post_isomorphism(self, phi)
1105+
return iso * phi
1106+
1107+
# not explicitly cached here since .as_EllipticCurveIsogeny() and EllipticCurveIsogeny.dual() already cache their results
10751108
def dual(self):
10761109
r"""
10771110
Return the dual of this square-root Vélu
@@ -1082,6 +1115,8 @@ def dual(self):
10821115
The dual is computed by :class:`EllipticCurveIsogeny`,
10831116
hence it does not benefit from the square-root Vélu speedup.
10841117
1118+
ALGORITHM: :meth:`as_EllipticCurveIsogeny()`, then :meth:`EllipticCurveIsogeny.dual()`.
1119+
10851120
EXAMPLES::
10861121
10871122
sage: E = EllipticCurve(GF(101^2), [1, 1, 1, 1, 1])
@@ -1091,13 +1126,34 @@ def dual(self):
10911126
From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2
10921127
To: Elliptic Curve defined by y^2 = x^3 + 39*x + 40 over Finite Field in z2 of size 101^2
10931128
sage: phi.dual()
1094-
Isogeny of degree 11 from Elliptic Curve defined by y^2 = x^3 + 39*x + 40 over Finite Field in z2 of size 101^2 to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2
1129+
Isogeny of degree 11
1130+
from Elliptic Curve defined by y^2 = x^3 + 39*x + 40 over Finite Field in z2 of size 101^2
1131+
to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2
10951132
sage: phi.dual() * phi == phi.domain().scalar_multiplication(11)
10961133
True
10971134
sage: phi * phi.dual() == phi.codomain().scalar_multiplication(11)
10981135
True
1136+
1137+
Inseparable duals are computed correctly::
1138+
1139+
sage: # needs sage.rings.finite_rings
1140+
sage: z2 = GF(71^2).gen()
1141+
sage: E = EllipticCurve(j=57*z2+51)
1142+
sage: E.isogeny(3*E.lift_x(0), algorithm='velusqrt').dual()
1143+
Composite morphism of degree 71 = 71*1^2:
1144+
From: Elliptic Curve defined by y^2 = x^3 + (8*z2+70)*x + (3*z2+49) over Finite Field in z2 of size 71^2
1145+
To: Elliptic Curve defined by y^2 = x^3 + (41*z2+56)*x + (18*z2+42) over Finite Field in z2 of size 71^2
1146+
sage: E.isogeny(E.lift_x(0), algorithm='velusqrt').dual()
1147+
Composite morphism of degree 213 = 71*3:
1148+
From: Elliptic Curve defined by y^2 = x^3 + (50*z2+61)*x + (22*z2+25) over Finite Field in z2 of size 71^2
1149+
To: Elliptic Curve defined by y^2 = x^3 + (41*z2+56)*x + (18*z2+42) over Finite Field in z2 of size 71^2
10991150
"""
1100-
# FIXME: This code fails if the degree is divisible by the characteristic.
1151+
if self.base_ring().characteristic().divides(self.degree()):
1152+
# The dual is inseparable.
1153+
#TODO: This is a lazy workaround; it could be optimized more.
1154+
return self.as_EllipticCurveIsogeny().dual()
1155+
1156+
# The dual is separable.
11011157
F = self._raw_domain.base_ring()
11021158
from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism
11031159
isom = ~WeierstrassIsomorphism(self._raw_domain, (~F(self._degree), 0, 0, 0))

0 commit comments

Comments
 (0)