Fractional morphisms of elliptic curves

Algorithms involving advanced computations with endomorphisms or isogenies of elliptic curves sometimes involve divisions of elliptic-curve morphisms by integers. This operation yields another well-defined morphism whenever the kernel of the numerator contains the kernel of the denominator.

The class EllipticCurveHom_fractional represents symbolic fractions φ/n where φ:EE is any EllipticCurveHom whose kernel contains the n-torsion subgroup of E. Functionality for converting this fraction to a more explicit form is provided (to_isogeny_chain()).

EXAMPLES:

Division by an integer:

sage: E = EllipticCurve(GF(419), [-1, 0])
sage: phi = (E.frobenius_isogeny() + 1) / 2
sage: phi
Fractional elliptic-curve morphism of degree 105:
  Numerator:   Sum morphism:
    From: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
    To:   Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
    Via:  (Frobenius endomorphism of degree 419:
        From: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
        To:   Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419,
      Scalar-multiplication endomorphism [1]
        of Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419)
  Denominator: 2
sage: phi.degree()
105
sage: phi.to_isogeny_chain()
Composite morphism of degree 105 = 1*3*5*7:
  From: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
  To:   Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(419)), [-Integer(1), Integer(0)])
>>> phi = (E.frobenius_isogeny() + Integer(1)) / Integer(2)
>>> phi
Fractional elliptic-curve morphism of degree 105:
  Numerator:   Sum morphism:
    From: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
    To:   Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
    Via:  (Frobenius endomorphism of degree 419:
        From: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
        To:   Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419,
      Scalar-multiplication endomorphism [1]
        of Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419)
  Denominator: 2
>>> phi.degree()
105
>>> phi.to_isogeny_chain()
Composite morphism of degree 105 = 1*3*5*7:
  From: Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
  To:   Elliptic Curve defined by y^2 = x^3 + 418*x over Finite Field of size 419
E = EllipticCurve(GF(419), [-1, 0])
phi = (E.frobenius_isogeny() + 1) / 2
phi
phi.degree()
phi.to_isogeny_chain()

Right division of isogenies:

sage: E = EllipticCurve(GF(419), [1, 0])
sage: ker = E(125, 70)
sage: phi = E.isogeny(ker); phi
Isogeny of degree 35
  from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419
  to Elliptic Curve defined by y^2 = x^3 + 289*x + 323 over Finite Field of size 419
sage: psi = E.isogeny(5*ker); psi
Isogeny of degree 7
  from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419
  to Elliptic Curve defined by y^2 = x^3 + 285*x + 87 over Finite Field of size 419
sage: chi = phi.divide_right(psi); chi
Fractional elliptic-curve morphism of degree 5:
  Numerator:   Composite morphism of degree 245 = 7*35:
  From: Elliptic Curve defined by y^2 = x^3 + 285*x + 87 over Finite Field of size 419
  To:   Elliptic Curve defined by y^2 = x^3 + 289*x + 323 over Finite Field of size 419
  Denominator: 7
sage: phi == chi * psi
True
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(419)), [Integer(1), Integer(0)])
>>> ker = E(Integer(125), Integer(70))
>>> phi = E.isogeny(ker); phi
Isogeny of degree 35
  from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419
  to Elliptic Curve defined by y^2 = x^3 + 289*x + 323 over Finite Field of size 419
>>> psi = E.isogeny(Integer(5)*ker); psi
Isogeny of degree 7
  from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419
  to Elliptic Curve defined by y^2 = x^3 + 285*x + 87 over Finite Field of size 419
>>> chi = phi.divide_right(psi); chi
Fractional elliptic-curve morphism of degree 5:
  Numerator:   Composite morphism of degree 245 = 7*35:
  From: Elliptic Curve defined by y^2 = x^3 + 285*x + 87 over Finite Field of size 419
  To:   Elliptic Curve defined by y^2 = x^3 + 289*x + 323 over Finite Field of size 419
  Denominator: 7
>>> phi == chi * psi
True
E = EllipticCurve(GF(419), [1, 0])
ker = E(125, 70)
phi = E.isogeny(ker); phi
psi = E.isogeny(5*ker); psi
chi = phi.divide_right(psi); chi
phi == chi * psi

Left division of isogenies:

sage: E = EllipticCurve(GF(419), [1, 0])
sage: ker = E(125, 70)
sage: phi = E.isogeny(ker); phi
Isogeny of degree 35
  from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419
  to Elliptic Curve defined by y^2 = x^3 + 289*x + 323 over Finite Field of size 419
sage: tmp = E.isogeny(7*ker)
sage: psi = tmp.codomain().isogeny(tmp(ker)); psi
Isogeny of degree 7
  from Elliptic Curve defined by y^2 = x^3 + 269*x + 82 over Finite Field of size 419
  to Elliptic Curve defined by y^2 = x^3 + 289*x + 323 over Finite Field of size 419
sage: chi = phi.divide_left(psi); chi
Fractional elliptic-curve morphism of degree 5:
  Numerator:   Composite morphism of degree 245 = 35*7:
  From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419
  To:   Elliptic Curve defined by y^2 = x^3 + 269*x + 82 over Finite Field of size 419
  Denominator: 7
sage: phi == psi * chi
True
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(419)), [Integer(1), Integer(0)])
>>> ker = E(Integer(125), Integer(70))
>>> phi = E.isogeny(ker); phi
Isogeny of degree 35
  from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419
  to Elliptic Curve defined by y^2 = x^3 + 289*x + 323 over Finite Field of size 419
>>> tmp = E.isogeny(Integer(7)*ker)
>>> psi = tmp.codomain().isogeny(tmp(ker)); psi
Isogeny of degree 7
  from Elliptic Curve defined by y^2 = x^3 + 269*x + 82 over Finite Field of size 419
  to Elliptic Curve defined by y^2 = x^3 + 289*x + 323 over Finite Field of size 419
>>> chi = phi.divide_left(psi); chi
Fractional elliptic-curve morphism of degree 5:
  Numerator:   Composite morphism of degree 245 = 35*7:
  From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419
  To:   Elliptic Curve defined by y^2 = x^3 + 269*x + 82 over Finite Field of size 419
  Denominator: 7
>>> phi == psi * chi
True
E = EllipticCurve(GF(419), [1, 0])
ker = E(125, 70)
phi = E.isogeny(ker); phi
tmp = E.isogeny(7*ker)
psi = tmp.codomain().isogeny(tmp(ker)); psi
chi = phi.divide_left(psi); chi
phi == psi * chi

AUTHORS:

  • Lorenz Panny (2024)

class sage.schemes.elliptic_curves.hom_fractional.EllipticCurveHom_fractional(phi, d, *, check=True)[source]

Bases: EllipticCurveHom

This class represents a (symbolic) quotient of an isogeny divided by an integer.

EXAMPLES:

sage: from sage.schemes.elliptic_curves.hom_fractional import EllipticCurveHom_fractional
sage: phi = EllipticCurve([1,1]).scalar_multiplication(-2)
sage: EllipticCurveHom_fractional(phi, 2)
Fractional elliptic-curve morphism of degree 1:
  Numerator:   Scalar-multiplication endomorphism [-2]
                 of Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field
  Denominator: 2
sage: EllipticCurveHom_fractional(phi, 3)
Traceback (most recent call last):
...
ValueError: Scalar-multiplication endomorphism [-2]
  of Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field
  is not divisible by 3
>>> from sage.all import *
>>> from sage.schemes.elliptic_curves.hom_fractional import EllipticCurveHom_fractional
>>> phi = EllipticCurve([Integer(1),Integer(1)]).scalar_multiplication(-Integer(2))
>>> EllipticCurveHom_fractional(phi, Integer(2))
Fractional elliptic-curve morphism of degree 1:
  Numerator:   Scalar-multiplication endomorphism [-2]
                 of Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field
  Denominator: 2
>>> EllipticCurveHom_fractional(phi, Integer(3))
Traceback (most recent call last):
...
ValueError: Scalar-multiplication endomorphism [-2]
  of Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field
  is not divisible by 3
from sage.schemes.elliptic_curves.hom_fractional import EllipticCurveHom_fractional
phi = EllipticCurve([1,1]).scalar_multiplication(-2)
EllipticCurveHom_fractional(phi, 2)
EllipticCurveHom_fractional(phi, 3)
dual()[source]

Return the dual of this fractional isogeny.

EXAMPLES:

sage: E = EllipticCurve(GF(419), [1,0])
sage: phi = E.isogeny(E(185, 73))
sage: ((phi + phi) / 2).dual() == phi.dual()
True
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(419)), [Integer(1),Integer(0)])
>>> phi = E.isogeny(E(Integer(185), Integer(73)))
>>> ((phi + phi) / Integer(2)).dual() == phi.dual()
True
E = EllipticCurve(GF(419), [1,0])
phi = E.isogeny(E(185, 73))
((phi + phi) / 2).dual() == phi.dual()
formal(*args)[source]

Return the formal isogeny corresponding to this fractional isogeny as a power series in the variable t=x/y on the domain curve.

EXAMPLES:

sage: E = EllipticCurve(GF(419), [-1,0])
sage: pi = E.frobenius_isogeny()
sage: ((1 + pi) / 2).formal()
210*t + 26*t^5 + 254*t^9 + 227*t^13 + 36*t^17 + 74*t^21 + O(t^23)
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(419)), [-Integer(1),Integer(0)])
>>> pi = E.frobenius_isogeny()
>>> ((Integer(1) + pi) / Integer(2)).formal()
210*t + 26*t^5 + 254*t^9 + 227*t^13 + 36*t^17 + 74*t^21 + O(t^23)
E = EllipticCurve(GF(419), [-1,0])
pi = E.frobenius_isogeny()
((1 + pi) / 2).formal()
inseparable_degree()[source]

Return the inseparable degree of this morphism.

EXAMPLES:

sage: E = EllipticCurve(GF(419), [-1,0])
sage: pi = E.frobenius_isogeny()
sage: ((1 + pi) / 2).inseparable_degree()
1
sage: E = EllipticCurve(GF(419), [-1,0])
sage: pi = E.frobenius_isogeny()
sage: ((3*pi - pi) / 2).inseparable_degree()
419
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(419)), [-Integer(1),Integer(0)])
>>> pi = E.frobenius_isogeny()
>>> ((Integer(1) + pi) / Integer(2)).inseparable_degree()
1
>>> E = EllipticCurve(GF(Integer(419)), [-Integer(1),Integer(0)])
>>> pi = E.frobenius_isogeny()
>>> ((Integer(3)*pi - pi) / Integer(2)).inseparable_degree()
419
E = EllipticCurve(GF(419), [-1,0])
pi = E.frobenius_isogeny()
((1 + pi) / 2).inseparable_degree()
E = EllipticCurve(GF(419), [-1,0])
pi = E.frobenius_isogeny()
((3*pi - pi) / 2).inseparable_degree()
kernel_polynomial()[source]

Return the kernel polynomial of this fractional isogeny.

EXAMPLES:

sage: E = EllipticCurve(GF(419), [1,0])
sage: phi = E.isogeny(E(185, 73)); phi.kernel_polynomial()
x^2 + 304*x + 39
sage: ((phi + phi) / 2).kernel_polynomial()
x^2 + 304*x + 39
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(419)), [Integer(1),Integer(0)])
>>> phi = E.isogeny(E(Integer(185), Integer(73))); phi.kernel_polynomial()
x^2 + 304*x + 39
>>> ((phi + phi) / Integer(2)).kernel_polynomial()
x^2 + 304*x + 39
E = EllipticCurve(GF(419), [1,0])
phi = E.isogeny(E(185, 73)); phi.kernel_polynomial()
((phi + phi) / 2).kernel_polynomial()
rational_maps()[source]

Return the pair of explicit rational maps defining this fractional isogeny.

EXAMPLES:

sage: E = EllipticCurve(GF(419), [1,0])
sage: phi = E.isogeny(E(185, 73)); phi.rational_maps()
((x^5 + 189*x^4 + 9*x^3 + 114*x^2 + 11*x + 206)/(x^4 + 189*x^3 - 105*x^2 - 171*x - 155),
 (x^6*y + 74*x^5*y - 127*x^4*y + 148*x^3*y + 182*x^2*y + 115*x*y + 43*y)/(x^6 + 74*x^5 - 13*x^4 + x^3 - 88*x^2 - 157*x - 179))
sage: ((phi + phi) / 2).rational_maps()
((x^5 + 189*x^4 + 9*x^3 + 114*x^2 + 11*x + 206)/(x^4 + 189*x^3 - 105*x^2 - 171*x - 155),
 (x^6*y + 74*x^5*y - 127*x^4*y + 148*x^3*y + 182*x^2*y + 115*x*y + 43*y)/(x^6 + 74*x^5 - 13*x^4 + x^3 - 88*x^2 - 157*x - 179))
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(419)), [Integer(1),Integer(0)])
>>> phi = E.isogeny(E(Integer(185), Integer(73))); phi.rational_maps()
((x^5 + 189*x^4 + 9*x^3 + 114*x^2 + 11*x + 206)/(x^4 + 189*x^3 - 105*x^2 - 171*x - 155),
 (x^6*y + 74*x^5*y - 127*x^4*y + 148*x^3*y + 182*x^2*y + 115*x*y + 43*y)/(x^6 + 74*x^5 - 13*x^4 + x^3 - 88*x^2 - 157*x - 179))
>>> ((phi + phi) / Integer(2)).rational_maps()
((x^5 + 189*x^4 + 9*x^3 + 114*x^2 + 11*x + 206)/(x^4 + 189*x^3 - 105*x^2 - 171*x - 155),
 (x^6*y + 74*x^5*y - 127*x^4*y + 148*x^3*y + 182*x^2*y + 115*x*y + 43*y)/(x^6 + 74*x^5 - 13*x^4 + x^3 - 88*x^2 - 157*x - 179))
E = EllipticCurve(GF(419), [1,0])
phi = E.isogeny(E(185, 73)); phi.rational_maps()
((phi + phi) / 2).rational_maps()
scaling_factor()[source]

Return the Weierstrass scaling factor associated to this fractional isogeny.

The scaling factor is the constant u (in the base field) such that φω2=uω1, where φ:E1E2 is this morphism and ωi are the standard Weierstrass differentials on Ei defined by dx/(2y+a1x+a3).

EXAMPLES:

sage: E = EllipticCurve(GF(419), [-1,0])
sage: pi = E.frobenius_isogeny()
sage: ((1 + pi) / 2).scaling_factor()
210
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(419)), [-Integer(1),Integer(0)])
>>> pi = E.frobenius_isogeny()
>>> ((Integer(1) + pi) / Integer(2)).scaling_factor()
210
E = EllipticCurve(GF(419), [-1,0])
pi = E.frobenius_isogeny()
((1 + pi) / 2).scaling_factor()
to_isogeny_chain()[source]

Convert this fractional elliptic-curve morphism into a (non-fractional) EllipticCurveHom_composite object representing the same morphism.

EXAMPLES:

sage: p = 419
sage: E = EllipticCurve(GF(p^2), [1,0])
sage: iota = E.automorphisms()[2]   # sqrt(-1)
sage: pi = E.frobenius_isogeny()    # sqrt(-p)
sage: endo = (iota + pi) / 2
sage: endo.degree()
105
sage: endo.to_isogeny_chain()
Composite morphism of degree 105 = 1*3*5*7:
  From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 419^2
  To:   Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 419^2
sage: endo.to_isogeny_chain() == endo
True
>>> from sage.all import *
>>> p = Integer(419)
>>> E = EllipticCurve(GF(p**Integer(2)), [Integer(1),Integer(0)])
>>> iota = E.automorphisms()[Integer(2)]   # sqrt(-1)
>>> pi = E.frobenius_isogeny()    # sqrt(-p)
>>> endo = (iota + pi) / Integer(2)
>>> endo.degree()
105
>>> endo.to_isogeny_chain()
Composite morphism of degree 105 = 1*3*5*7:
  From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 419^2
  To:   Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 419^2
>>> endo.to_isogeny_chain() == endo
True
p = 419
E = EllipticCurve(GF(p^2), [1,0])
iota = E.automorphisms()[2]   # sqrt(-1)
pi = E.frobenius_isogeny()    # sqrt(-p)
endo = (iota + pi) / 2
endo.degree()
endo.to_isogeny_chain()
endo.to_isogeny_chain() == endo
x_rational_map()[source]

Return the x-coordinate rational map of this fractional isogeny.

EXAMPLES:

sage: E = EllipticCurve(GF(419), [1,0])
sage: phi = E.isogeny(E(185, 73)); phi.x_rational_map()
(x^5 + 189*x^4 + 9*x^3 + 114*x^2 + 11*x + 206)/(x^4 + 189*x^3 + 314*x^2 + 248*x + 264)
sage: ((phi + phi) / 2).x_rational_map()
(x^5 + 189*x^4 + 9*x^3 + 114*x^2 + 11*x + 206)/(x^4 + 189*x^3 + 314*x^2 + 248*x + 264)
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(419)), [Integer(1),Integer(0)])
>>> phi = E.isogeny(E(Integer(185), Integer(73))); phi.x_rational_map()
(x^5 + 189*x^4 + 9*x^3 + 114*x^2 + 11*x + 206)/(x^4 + 189*x^3 + 314*x^2 + 248*x + 264)
>>> ((phi + phi) / Integer(2)).x_rational_map()
(x^5 + 189*x^4 + 9*x^3 + 114*x^2 + 11*x + 206)/(x^4 + 189*x^3 + 314*x^2 + 248*x + 264)
E = EllipticCurve(GF(419), [1,0])
phi = E.isogeny(E(185, 73)); phi.x_rational_map()
((phi + phi) / 2).x_rational_map()