Skip to content

Commit

Permalink
Fix #6413
Browse files Browse the repository at this point in the history
Compute pth multiplication coordinate maps by using isogenies.

Thanks @yyyyx4 for the idea!
  • Loading branch information
grhkm21 committed Jan 18, 2024
1 parent 439065e commit 2fe08b6
Showing 1 changed file with 67 additions and 6 deletions.
73 changes: 67 additions & 6 deletions src/sage/schemes/elliptic_curves/ell_generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
# ****************************************************************************

import math
from sage.arith.misc import valuation

import sage.rings.abc
from sage.rings.finite_rings.integer_mod import mod
Expand All @@ -65,6 +66,7 @@
import sage.groups.generic as generic

from sage.arith.functions import lcm
from sage.functions.generalized import sgn
from sage.rings.integer import Integer
from sage.rings.big_oh import O
from sage.rings.infinity import Infinity as oo
Expand Down Expand Up @@ -2019,6 +2021,30 @@ def division_polynomial(self, m, x=None, two_torsion_multiplicity=2, force_evalu

torsion_polynomial = division_polynomial

@cached_method
def multiplication_by_p_isogeny(self):
r"""
Return the multiplication-by-\(p\) isogeny.
EXAMPLES::
sage: p = 23
sage: K.<a> = GF(p^3)
sage: E = EllipticCurve(K, [K.random_element(), K.random_element()])
sage: phi = E.multiplication_by_p_isogeny()
sage: assert phi.degree() == p**2
sage: P = E.random_element()
sage: assert phi(P) == P * p
"""
from sage.rings.finite_rings.finite_field_base import FiniteField as FiniteField_generic

K = self.base_ring()
if not isinstance(K, FiniteField_generic):
raise ValueError(f"Base ring (={K}) is not a finite field.")

frob = self.frobenius_isogeny()
return frob.dual() * frob

def _multiple_x_numerator(self, n, x=None):
r"""
Return the numerator of the `x`-coordinate of the `n\th` multiple of a
Expand Down Expand Up @@ -2333,6 +2359,20 @@ def multiplication_by_m(self, m, x_only=False):
sage: my_eval = lambda f,P: [fi(P[0],P[1]) for fi in f]
sage: f = E.multiplication_by_m(2)
sage: assert(E(eval(f,P)) == 2*P)
The following test shows that :trac:`6413` is indeed fixed::
sage: p = 7
sage: K.<a> = GF(p^2)
sage: E = EllipticCurve(K, [a + 3, 5 - a])
sage: k = p^2 * 3
sage: f, g = E.multiplication_by_m(k)
sage: for _ in range(100):
....: P = E.random_point()
....: if P * k == 0:
....: continue
....: Qx = f.subs(x=P[0])
....: Qy = g.subs(x=P[0], y=P[1])
....: assert (P * k).xy() == (Qx, Qy)
"""
# Coerce the input m to be an integer
m = Integer(m)
Expand All @@ -2352,30 +2392,51 @@ def multiplication_by_m(self, m, x_only=False):
return x

# Grab curve invariants
a1, a2, a3, a4, a6 = self.a_invariants()
a1, _, a3, _, _ = self.a_invariants()

if m == -1:
if not x_only:
return (x, -y-a1*x-a3)
else:
return x

# the x-coordinate does not depend on the sign of m. The work
# Inseparable cases
# Special case of multiplication by p is easy. Kind of.
p = Integer(self.base_ring().characteristic())

v_p = 0 if p == 0 else valuation(m.abs(), p)
m //= p**v_p

# the x-coordinate does not depend on the sign of m. The work
# here is done by functions defined earlier:

mx = (x.parent()(self._multiple_x_numerator(m.abs(), x))
/ x.parent()(self._multiple_x_denominator(m.abs(), x)))


if x_only:
# slow.
if v_p > 0:
p_endo = self.multiplication_by_p_isogeny()
isog = p_endo**v_p
fx = isog.x_rational_map()
# slow.
mx = mx.subs(x=fx)
# Return it if the optional parameter x_only is set.
return mx

# Consideration of the invariant differential
# w=dx/(2*y+a1*x+a3) shows that m*w = d(mx)/(2*my+a1*mx+a3)
# and hence 2*my+a1*mx+a3 = (1/m)*(2*y+a1*x+a3)*d(mx)/dx

# Consideration of the invariant differential
# w=dx/(2*y+a1*x+a3) shows that m*w = d(mx)/(2*my+a1*mx+a3)
# and hence 2*my+a1*mx+a3 = (1/m)*(2*y+a1*x+a3)*d(mx)/dx
my = ((2*y+a1*x+a3)*mx.derivative(x)/m - a1*mx-a3)/2

if v_p > 0:
frob = self.frobenius_isogeny()
isog = (frob.dual() * frob)**v_p
fx, fy = isog.rational_maps()
# slow...
my = my.subs(x=fx, y=fy)

return mx, my

def multiplication_by_m_isogeny(self, m):
Expand Down

0 comments on commit 2fe08b6

Please sign in to comment.