Sums of morphisms of elliptic curves

The set \(\mathrm{Hom}(E,E')\) of morphisms between two elliptic curves forms an abelian group under pointwise addition. An important special case is the endomorphism ring \(\mathrm{End}(E) = \mathrm{Hom}(E,E)\). However, it is not immediately obvious how to compute some properties of the sum \(\varphi+\psi\) of two isogenies, even when both are given explicitly. This class provides functionality for representing sums of elliptic-curve morphisms (in particular, isogenies and endomorphisms) formally, and explicitly computing important properties (such as the degree or the kernel polynomial) from the formal representation.

EXAMPLES:

sage: E = EllipticCurve(GF(101), [5,5])
sage: phi = E.isogenies_prime_degree(7)[0]
sage: phi + phi
Sum morphism:
  From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101
  To:   Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101
  Via:  (Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101, Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101)
sage: phi + phi == phi * E.scalar_multiplication(2)
True
sage: phi + phi + phi == phi * E.scalar_multiplication(3)
True
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(101)), [Integer(5),Integer(5)])
>>> phi = E.isogenies_prime_degree(Integer(7))[Integer(0)]
>>> phi + phi
Sum morphism:
  From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101
  To:   Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101
  Via:  (Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101, Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101)
>>> phi + phi == phi * E.scalar_multiplication(Integer(2))
True
>>> phi + phi + phi == phi * E.scalar_multiplication(Integer(3))
True
E = EllipticCurve(GF(101), [5,5])
phi = E.isogenies_prime_degree(7)[0]
phi + phi
phi + phi == phi * E.scalar_multiplication(2)
phi + phi + phi == phi * E.scalar_multiplication(3)

An example of computing with a supersingular endomorphism ring:

sage: E = EllipticCurve(GF(419^2), [1,0])
sage: i = E.automorphisms()[-1]
sage: j = E.frobenius_isogeny()
sage: i * j == - j * i                          # i,j anticommute
True
sage: (i + j) * i == i^2 - i*j                  # distributive law
True
sage: (j - E.scalar_multiplication(1)).degree() # point counting!
420
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(419)**Integer(2)), [Integer(1),Integer(0)])
>>> i = E.automorphisms()[-Integer(1)]
>>> j = E.frobenius_isogeny()
>>> i * j == - j * i                          # i,j anticommute
True
>>> (i + j) * i == i**Integer(2) - i*j                  # distributive law
True
>>> (j - E.scalar_multiplication(Integer(1))).degree() # point counting!
420
E = EllipticCurve(GF(419^2), [1,0])
i = E.automorphisms()[-1]
j = E.frobenius_isogeny()
i * j == - j * i                          # i,j anticommute
(i + j) * i == i^2 - i*j                  # distributive law
(j - E.scalar_multiplication(1)).degree() # point counting!

AUTHORS:

  • Lorenz Panny (2023)

class sage.schemes.elliptic_curves.hom_sum.EllipticCurveHom_sum(phis, domain=None, codomain=None)[source]

Bases: EllipticCurveHom

Construct a sum morphism of elliptic curves from its summands. (For empty sums, the domain and codomain curves must be given.)

EXAMPLES:

sage: from sage.schemes.elliptic_curves.hom_sum import EllipticCurveHom_sum
sage: E = EllipticCurve(GF(101), [5,5])
sage: phi = E.isogenies_prime_degree(7)[0]
sage: EllipticCurveHom_sum([phi, phi])
Sum morphism:
  From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101
  To:   Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101
  Via:  (Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101, Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101)
>>> from sage.all import *
>>> from sage.schemes.elliptic_curves.hom_sum import EllipticCurveHom_sum
>>> E = EllipticCurve(GF(Integer(101)), [Integer(5),Integer(5)])
>>> phi = E.isogenies_prime_degree(Integer(7))[Integer(0)]
>>> EllipticCurveHom_sum([phi, phi])
Sum morphism:
  From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101
  To:   Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101
  Via:  (Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101, Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101)
from sage.schemes.elliptic_curves.hom_sum import EllipticCurveHom_sum
E = EllipticCurve(GF(101), [5,5])
phi = E.isogenies_prime_degree(7)[0]
EllipticCurveHom_sum([phi, phi])

The zero morphism can be constructed even between non-isogenous curves:

sage: E1 = EllipticCurve(GF(101), [5,5])
sage: E2 = EllipticCurve(GF(101), [7,7])
sage: E1.is_isogenous(E2)
False
sage: EllipticCurveHom_sum([], E1, E2)
Sum morphism:
  From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101
  To:   Elliptic Curve defined by y^2 = x^3 + 7*x + 7 over Finite Field of size 101
  Via:  ()
>>> from sage.all import *
>>> E1 = EllipticCurve(GF(Integer(101)), [Integer(5),Integer(5)])
>>> E2 = EllipticCurve(GF(Integer(101)), [Integer(7),Integer(7)])
>>> E1.is_isogenous(E2)
False
>>> EllipticCurveHom_sum([], E1, E2)
Sum morphism:
  From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101
  To:   Elliptic Curve defined by y^2 = x^3 + 7*x + 7 over Finite Field of size 101
  Via:  ()
E1 = EllipticCurve(GF(101), [5,5])
E2 = EllipticCurve(GF(101), [7,7])
E1.is_isogenous(E2)
EllipticCurveHom_sum([], E1, E2)
degree()[source]

Return the degree of this sum morphism.

EXAMPLES:

sage: E = EllipticCurve(GF(101), [5,5])
sage: phi = E.isogenies_prime_degree(7)[0]
sage: (phi + phi).degree()
28
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(101)), [Integer(5),Integer(5)])
>>> phi = E.isogenies_prime_degree(Integer(7))[Integer(0)]
>>> (phi + phi).degree()
28
E = EllipticCurve(GF(101), [5,5])
phi = E.isogenies_prime_degree(7)[0]
(phi + phi).degree()

This method yields a simple toy point-counting algorithm:

sage: E = EllipticCurve(GF(101), [5,5])
sage: m1 = E.scalar_multiplication(1)
sage: pi = E.frobenius_endomorphism()
sage: (pi - m1).degree()
119
sage: E.count_points()
119
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(101)), [Integer(5),Integer(5)])
>>> m1 = E.scalar_multiplication(Integer(1))
>>> pi = E.frobenius_endomorphism()
>>> (pi - m1).degree()
119
>>> E.count_points()
119
E = EllipticCurve(GF(101), [5,5])
m1 = E.scalar_multiplication(1)
pi = E.frobenius_endomorphism()
(pi - m1).degree()
E.count_points()

ALGORITHM: Essentially Schoof’s algorithm; see _compute_degree().

dual()[source]

Return the dual of this sum morphism.

EXAMPLES:

sage: E = EllipticCurve(GF(101), [5,5])
sage: phi = E.isogenies_prime_degree(7)[0]
sage: (phi + phi).dual()
Sum morphism:
  From: Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101
  To:   Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101
  Via:  (Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101, Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101)
sage: (phi + phi).dual() == phi.dual() + phi.dual()
True
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(101)), [Integer(5),Integer(5)])
>>> phi = E.isogenies_prime_degree(Integer(7))[Integer(0)]
>>> (phi + phi).dual()
Sum morphism:
  From: Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101
  To:   Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101
  Via:  (Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101, Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101)
>>> (phi + phi).dual() == phi.dual() + phi.dual()
True
E = EllipticCurve(GF(101), [5,5])
phi = E.isogenies_prime_degree(7)[0]
(phi + phi).dual()
(phi + phi).dual() == phi.dual() + phi.dual()

sage: E = EllipticCurve(GF(431^2), [1,0])
sage: iota = E.automorphisms()[2]
sage: m2 = E.scalar_multiplication(2)
sage: endo = m2 + iota
sage: endo.dual()
Sum morphism:
  From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 431^2
  To:   Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 431^2
  Via:  (Scalar-multiplication endomorphism [2] of Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 431^2, Elliptic-curve endomorphism of Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 431^2
  Via:  (u,r,s,t) = (8*z2 + 427, 0, 0, 0))
sage: endo.dual() == (m2 - iota)
True
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(431)**Integer(2)), [Integer(1),Integer(0)])
>>> iota = E.automorphisms()[Integer(2)]
>>> m2 = E.scalar_multiplication(Integer(2))
>>> endo = m2 + iota
>>> endo.dual()
Sum morphism:
  From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 431^2
  To:   Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 431^2
  Via:  (Scalar-multiplication endomorphism [2] of Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 431^2, Elliptic-curve endomorphism of Elliptic Curve defined by y^2 = x^3 + x over Finite Field in z2 of size 431^2
  Via:  (u,r,s,t) = (8*z2 + 427, 0, 0, 0))
>>> endo.dual() == (m2 - iota)
True
E = EllipticCurve(GF(431^2), [1,0])
iota = E.automorphisms()[2]
m2 = E.scalar_multiplication(2)
endo = m2 + iota
endo.dual()
endo.dual() == (m2 - iota)

ALGORITHM: Taking the dual distributes over addition.

inseparable_degree()[source]

Compute the inseparable degree of this sum morphism.

EXAMPLES:

sage: E = EllipticCurve(GF(7), [0,1])
sage: m3 = E.scalar_multiplication(3)
sage: m3.inseparable_degree()
1
sage: m4 = E.scalar_multiplication(4)
sage: m7 = m3 + m4; m7
Sum morphism:
  From: Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7
  To:   Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7
  Via:  (Scalar-multiplication endomorphism [3] of Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7, Scalar-multiplication endomorphism [4] of Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7)
sage: m7.degree()
49
sage: m7.inseparable_degree()
7
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(7)), [Integer(0),Integer(1)])
>>> m3 = E.scalar_multiplication(Integer(3))
>>> m3.inseparable_degree()
1
>>> m4 = E.scalar_multiplication(Integer(4))
>>> m7 = m3 + m4; m7
Sum morphism:
  From: Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7
  To:   Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7
  Via:  (Scalar-multiplication endomorphism [3] of Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7, Scalar-multiplication endomorphism [4] of Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7)
>>> m7.degree()
49
>>> m7.inseparable_degree()
7
E = EllipticCurve(GF(7), [0,1])
m3 = E.scalar_multiplication(3)
m3.inseparable_degree()
m4 = E.scalar_multiplication(4)
m7 = m3 + m4; m7
m7.degree()
m7.inseparable_degree()

A supersingular example:

sage: E = EllipticCurve(GF(7), [1,0])
sage: m3 = E.scalar_multiplication(3)
sage: m3.inseparable_degree()
1
sage: m4 = E.scalar_multiplication(4)
sage: m7 = m3 + m4; m7
Sum morphism:
  From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 7
  To:   Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 7
  Via:  (Scalar-multiplication endomorphism [3] of Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 7, Scalar-multiplication endomorphism [4] of Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 7)
sage: m7.inseparable_degree()
49
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(7)), [Integer(1),Integer(0)])
>>> m3 = E.scalar_multiplication(Integer(3))
>>> m3.inseparable_degree()
1
>>> m4 = E.scalar_multiplication(Integer(4))
>>> m7 = m3 + m4; m7
Sum morphism:
  From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 7
  To:   Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 7
  Via:  (Scalar-multiplication endomorphism [3] of Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 7, Scalar-multiplication endomorphism [4] of Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 7)
>>> m7.inseparable_degree()
49
E = EllipticCurve(GF(7), [1,0])
m3 = E.scalar_multiplication(3)
m3.inseparable_degree()
m4 = E.scalar_multiplication(4)
m7 = m3 + m4; m7
m7.inseparable_degree()
kernel_polynomial()[source]

Return the kernel polynomial of this sum morphism.

EXAMPLES:

sage: E = EllipticCurve(GF(101), [5,5])
sage: phi = E.isogenies_prime_degree(7)[0]
sage: (phi + phi).kernel_polynomial()
x^15 + 75*x^14 + 16*x^13 + 59*x^12 + 28*x^11 + 60*x^10 + 69*x^9 + 79*x^8 + 79*x^7 + 52*x^6 + 35*x^5 + 11*x^4 + 37*x^3 + 69*x^2 + 66*x + 63
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(101)), [Integer(5),Integer(5)])
>>> phi = E.isogenies_prime_degree(Integer(7))[Integer(0)]
>>> (phi + phi).kernel_polynomial()
x^15 + 75*x^14 + 16*x^13 + 59*x^12 + 28*x^11 + 60*x^10 + 69*x^9 + 79*x^8 + 79*x^7 + 52*x^6 + 35*x^5 + 11*x^4 + 37*x^3 + 69*x^2 + 66*x + 63
E = EllipticCurve(GF(101), [5,5])
phi = E.isogenies_prime_degree(7)[0]
(phi + phi).kernel_polynomial()

sage: E = EllipticCurve(GF(11), [5,5])
sage: pi = E.frobenius_endomorphism()
sage: m1 = E.scalar_multiplication(1)
sage: (pi - m1).kernel_polynomial()
x^9 + 7*x^8 + 2*x^7 + 4*x^6 + 10*x^4 + 4*x^3 + 9*x^2 + 7*x
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(11)), [Integer(5),Integer(5)])
>>> pi = E.frobenius_endomorphism()
>>> m1 = E.scalar_multiplication(Integer(1))
>>> (pi - m1).kernel_polynomial()
x^9 + 7*x^8 + 2*x^7 + 4*x^6 + 10*x^4 + 4*x^3 + 9*x^2 + 7*x
E = EllipticCurve(GF(11), [5,5])
pi = E.frobenius_endomorphism()
m1 = E.scalar_multiplication(1)
(pi - m1).kernel_polynomial()

ALGORITHM: to_isogeny_chain().

rational_maps()[source]

Return the rational maps of this sum morphism.

EXAMPLES:

sage: E = EllipticCurve(GF(101), [5,5])
sage: phi = E.isogenies_prime_degree(7)[0]
sage: (phi + phi).rational_maps()
((5*x^28 + 43*x^27 + 26*x^26 - ... + 7*x^2 - 23*x + 38)/(23*x^27 + 16*x^26 + 9*x^25 + ... - 43*x^2 - 22*x + 37),
 (42*x^42*y - 44*x^41*y - 22*x^40*y + ... - 26*x^2*y - 50*x*y - 18*y)/(-24*x^42 - 47*x^41 - 12*x^40 + ... + 18*x^2 - 48*x + 18))
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(101)), [Integer(5),Integer(5)])
>>> phi = E.isogenies_prime_degree(Integer(7))[Integer(0)]
>>> (phi + phi).rational_maps()
((5*x^28 + 43*x^27 + 26*x^26 - ... + 7*x^2 - 23*x + 38)/(23*x^27 + 16*x^26 + 9*x^25 + ... - 43*x^2 - 22*x + 37),
 (42*x^42*y - 44*x^41*y - 22*x^40*y + ... - 26*x^2*y - 50*x*y - 18*y)/(-24*x^42 - 47*x^41 - 12*x^40 + ... + 18*x^2 - 48*x + 18))
E = EllipticCurve(GF(101), [5,5])
phi = E.isogenies_prime_degree(7)[0]
(phi + phi).rational_maps()

ALGORITHM: to_isogeny_chain().

scaling_factor()[source]

Return the Weierstrass scaling factor associated to this sum morphism.

The scaling factor is the constant \(u\) (in the base field) such that \(\varphi^* \omega_2 = u \omega_1\), where \(\varphi: E_1\to E_2\) is this morphism and \(\omega_i\) are the standard Weierstrass differentials on \(E_i\) defined by \(\mathrm dx/(2y+a_1x+a_3)\).

EXAMPLES:

sage: E = EllipticCurve(GF(101), [5,5])
sage: phi = E.isogenies_prime_degree(7)[0]
sage: phi.scaling_factor()
84
sage: (phi + phi).scaling_factor()
67
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(101)), [Integer(5),Integer(5)])
>>> phi = E.isogenies_prime_degree(Integer(7))[Integer(0)]
>>> phi.scaling_factor()
84
>>> (phi + phi).scaling_factor()
67
E = EllipticCurve(GF(101), [5,5])
phi = E.isogenies_prime_degree(7)[0]
phi.scaling_factor()
(phi + phi).scaling_factor()

ALGORITHM: The scaling factor is additive under addition of elliptic-curve morphisms, so we simply add together the scaling factors of the summands().

summands()[source]

Return the individual summands making up this sum morphism.

EXAMPLES:

sage: E = EllipticCurve(j=5)
sage: m2 = E.scalar_multiplication(2)
sage: m3 = E.scalar_multiplication(3)
sage: m2 + m3
Sum morphism:
  From: Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 180*x + 17255 over Rational Field
  To:   Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 180*x + 17255 over Rational Field
  Via:  (Scalar-multiplication endomorphism [2] of Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 180*x + 17255 over Rational Field, Scalar-multiplication endomorphism [3] of Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 180*x + 17255 over Rational Field)
>>> from sage.all import *
>>> E = EllipticCurve(j=Integer(5))
>>> m2 = E.scalar_multiplication(Integer(2))
>>> m3 = E.scalar_multiplication(Integer(3))
>>> m2 + m3
Sum morphism:
  From: Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 180*x + 17255 over Rational Field
  To:   Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 180*x + 17255 over Rational Field
  Via:  (Scalar-multiplication endomorphism [2] of Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 180*x + 17255 over Rational Field, Scalar-multiplication endomorphism [3] of Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 180*x + 17255 over Rational Field)
E = EllipticCurve(j=5)
m2 = E.scalar_multiplication(2)
m3 = E.scalar_multiplication(3)
m2 + m3
to_isogeny_chain()[source]

Convert this formal sum of elliptic-curve morphisms into a EllipticCurveHom_composite object representing the same morphism.

EXAMPLES:

sage: E = EllipticCurve(GF(101), [5,5])
sage: phi = E.isogenies_prime_degree(7)[0]
sage: (phi + phi).to_isogeny_chain()
Composite morphism of degree 28 = 4*1*7:
  From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101
  To:   Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(101)), [Integer(5),Integer(5)])
>>> phi = E.isogenies_prime_degree(Integer(7))[Integer(0)]
>>> (phi + phi).to_isogeny_chain()
Composite morphism of degree 28 = 4*1*7:
  From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 101
  To:   Elliptic Curve defined by y^2 = x^3 + 12*x + 98 over Finite Field of size 101
E = EllipticCurve(GF(101), [5,5])
phi = E.isogenies_prime_degree(7)[0]
(phi + phi).to_isogeny_chain()

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
sage: endo.degree()
420
sage: endo.to_isogeny_chain()
Composite morphism of degree 420 = 4*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
>>> 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
>>> endo.degree()
420
>>> endo.to_isogeny_chain()
Composite morphism of degree 420 = 4*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
p = 419
E = EllipticCurve(GF(p^2), [1,0])
iota = E.automorphisms()[2]   # sqrt(-1)
pi = E.frobenius_isogeny()    # sqrt(-p)
endo = iota + pi
endo.degree()
endo.to_isogeny_chain()

The decomposition is impossible for the constant zero map:

sage: endo = iota*pi + pi*iota
sage: endo.degree()
0
sage: endo.to_isogeny_chain()
Traceback (most recent call last):
...
ValueError: zero morphism cannot be written as a composition of isogenies
>>> from sage.all import *
>>> endo = iota*pi + pi*iota
>>> endo.degree()
0
>>> endo.to_isogeny_chain()
Traceback (most recent call last):
...
ValueError: zero morphism cannot be written as a composition of isogenies
endo = iota*pi + pi*iota
endo.degree()
endo.to_isogeny_chain()

Isomorphisms are supported as well:

sage: E = EllipticCurve(j=5); E
Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 180*x + 17255 over Rational Field
sage: m2 = E.scalar_multiplication(2)
sage: m3 = E.scalar_multiplication(3)
sage: (m2 - m3).to_isogeny_chain()
Composite morphism of degree 1 = 1^2:
  From: Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 180*x + 17255 over Rational Field
  To:   Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 180*x + 17255 over Rational Field
sage: (m2 - m3).rational_maps()
(x, -x - y)
>>> from sage.all import *
>>> E = EllipticCurve(j=Integer(5)); E
Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 180*x + 17255 over Rational Field
>>> m2 = E.scalar_multiplication(Integer(2))
>>> m3 = E.scalar_multiplication(Integer(3))
>>> (m2 - m3).to_isogeny_chain()
Composite morphism of degree 1 = 1^2:
  From: Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 180*x + 17255 over Rational Field
  To:   Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 180*x + 17255 over Rational Field
>>> (m2 - m3).rational_maps()
(x, -x - y)
E = EllipticCurve(j=5); E
m2 = E.scalar_multiplication(2)
m3 = E.scalar_multiplication(3)
(m2 - m3).to_isogeny_chain()
(m2 - m3).rational_maps()
x_rational_map()[source]

Return the \(x\)-coordinate rational map of this sum morphism.

EXAMPLES:

sage: E = EllipticCurve(GF(101), [5,5])
sage: phi = E.isogenies_prime_degree(7)[0]
sage: (phi + phi).x_rational_map()
(9*x^28 + 37*x^27 + 67*x^26 + ... + 53*x^2 + 100*x + 28)/(x^27 + 49*x^26 + 97*x^25 + ... + 64*x^2 + 21*x + 6)
>>> from sage.all import *
>>> E = EllipticCurve(GF(Integer(101)), [Integer(5),Integer(5)])
>>> phi = E.isogenies_prime_degree(Integer(7))[Integer(0)]
>>> (phi + phi).x_rational_map()
(9*x^28 + 37*x^27 + 67*x^26 + ... + 53*x^2 + 100*x + 28)/(x^27 + 49*x^26 + 97*x^25 + ... + 64*x^2 + 21*x + 6)
E = EllipticCurve(GF(101), [5,5])
phi = E.isogenies_prime_degree(7)[0]
(phi + phi).x_rational_map()

ALGORITHM: to_isogeny_chain().