# Frobenius isogenies of elliptic curves#

Frobenius isogenies only exist in positive characteristic $$p$$. They are given by $$\pi_n:(x,y)\mapsto (x^{p^n},y^{p^n})$$.

This class implements $$\pi_n$$ for $$n \geq 0$$. Together with existing tools for composing isogenies (see EllipticCurveHom_composite), we can therefore represent arbitrary inseparable isogenies in Sage.

EXAMPLES:

Constructing a Frobenius isogeny is straightforward:

sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius
sage: z5, = GF(17^5).gens()
sage: E = EllipticCurve([z5,1])
sage: pi = EllipticCurveHom_frobenius(E); pi
Frobenius isogeny of degree 17:
From: Elliptic Curve defined by y^2 = x^3 + z5*x + 1
over Finite Field in z5 of size 17^5
To:   Elliptic Curve defined by y^2 = x^3 + (9*z5^4+7*z5^3+10*z5^2+z5+14)*x + 1
over Finite Field in z5 of size 17^5


By passing $$n$$, we can also construct higher-power Frobenius maps, such as the Frobenius endomorphism:

sage: z5, = GF(7^5).gens()
sage: E = EllipticCurve([z5,1])
sage: pi = EllipticCurveHom_frobenius(E, 5); pi
Frobenius endomorphism of degree 16807 = 7^5:
From: Elliptic Curve defined by y^2 = x^3 + z5*x + 1
over Finite Field in z5 of size 7^5
To:   Elliptic Curve defined by y^2 = x^3 + z5*x + 1
over Finite Field in z5 of size 7^5


The usual EllipticCurveHom methods are supported:

sage: z5, = GF(7^5).gens()
sage: E = EllipticCurve([z5,1])
sage: pi = EllipticCurveHom_frobenius(E,5)
sage: pi.degree()
16807
sage: pi.rational_maps()
(x^16807, y^16807)
sage: pi.formal()                   # known bug
...
sage: pi.is_normalized()            # known bug
...
sage: pi.is_separable()
False
sage: pi.is_injective()
True
sage: pi.is_surjective()
True


Computing the dual of Frobenius is supported as well:

sage: E = EllipticCurve([GF(17^6).gen(), 0])
sage: pi = EllipticCurveHom_frobenius(E)
sage: pihat = pi.dual(); pihat
Isogeny of degree 17
from Elliptic Curve defined by y^2 = x^3 + (15*z6^5+5*z6^4+8*z6^3+12*z6^2+11*z6+7)*x
over Finite Field in z6 of size 17^6
to Elliptic Curve defined by y^2 = x^3 + z6*x
over Finite Field in z6 of size 17^6
sage: pihat.is_separable()
True
sage: pihat * pi == EllipticCurveHom_scalar(E,17)   # known bug -- #6413
True


A supersingular example (with purely inseparable dual):

sage: E = EllipticCurve([0, GF(17^6).gen()])
sage: E.is_supersingular()
True
sage: pi1 = EllipticCurveHom_frobenius(E)
sage: pi1hat = pi1.dual(); pi1hat
Composite morphism of degree 17 = 17*1:
From: Elliptic Curve defined by y^2 = x^3 + (15*z6^5+5*z6^4+8*z6^3+12*z6^2+11*z6+7)
over Finite Field in z6 of size 17^6
To:   Elliptic Curve defined by y^2 = x^3 + z6
over Finite Field in z6 of size 17^6
sage: pi6 = EllipticCurveHom_frobenius(E,6)
sage: pi6hat = pi6.dual(); pi6hat
Composite morphism of degree 24137569 = 24137569*1:
From: Elliptic Curve defined by y^2 = x^3 + z6
over Finite Field in z6 of size 17^6
To:   Elliptic Curve defined by y^2 = x^3 + z6
over Finite Field in z6 of size 17^6
sage: pi6hat.factors()
(Frobenius endomorphism of degree 24137569 = 17^6:
From: Elliptic Curve defined by y^2 = x^3 + z6
over Finite Field in z6 of size 17^6
To:   Elliptic Curve defined by y^2 = x^3 + z6
over Finite Field in z6 of size 17^6,
Elliptic-curve endomorphism of
Elliptic Curve defined by y^2 = x^3 + z6 over Finite Field in z6 of size 17^6
Via:  (u,r,s,t) = (2*z6^5 + 10*z6^3 + z6^2 + 8, 0, 0, 0))


AUTHORS:

class sage.schemes.elliptic_curves.hom_frobenius.EllipticCurveHom_frobenius(E, power=1)#

Construct a Frobenius isogeny on a given curve with a given power of the base-ring characteristic.

Writing $$n$$ for the parameter power (default: $$1$$), the isogeny is defined by $$(x,y) \to (x^{p^n}, y^{p^n})$$ where $$p$$ is the characteristic of the base ring.

EXAMPLES:

sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius
sage: E = EllipticCurve(j=GF(11^2).gen())
sage: EllipticCurveHom_frobenius(E)
Frobenius isogeny of degree 11:
From: Elliptic Curve defined by y^2 = x^3 + (2*z2+6)*x + (8*z2+8) over Finite Field in z2 of size 11^2
To:   Elliptic Curve defined by y^2 = x^3 + (9*z2+3)*x + (3*z2+7) over Finite Field in z2 of size 11^2
sage: EllipticCurveHom_frobenius(E, 2)
Frobenius endomorphism of degree 121 = 11^2:
From: Elliptic Curve defined by y^2 = x^3 + (2*z2+6)*x + (8*z2+8) over Finite Field in z2 of size 11^2
To:   Elliptic Curve defined by y^2 = x^3 + (2*z2+6)*x + (8*z2+8) over Finite Field in z2 of size 11^2

degree()#

Return the degree of this Frobenius isogeny.

EXAMPLES:

sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius
sage: E = EllipticCurve(GF(11), [1,1])
sage: pi = EllipticCurveHom_frobenius(E, 4)
sage: pi.degree()
14641

dual()#

Compute the dual of this Frobenius isogeny.

This method returns an EllipticCurveHom object.

EXAMPLES:

An ordinary example:

sage: from sage.schemes.elliptic_curves.hom_scalar import EllipticCurveHom_scalar
sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius
sage: E = EllipticCurve(GF(31), [0,1])
sage: f = EllipticCurveHom_frobenius(E)
sage: f.dual() * f == EllipticCurveHom_scalar(f.domain(), 31)
True
sage: f * f.dual() == EllipticCurveHom_scalar(f.codomain(), 31)
True


A supersingular example:

sage: E = EllipticCurve(GF(31), [1,0])
sage: f = EllipticCurveHom_frobenius(E)
sage: f.dual() * f == EllipticCurveHom_scalar(f.domain(), 31)
True
sage: f * f.dual() == EllipticCurveHom_scalar(f.codomain(), 31)
True


ALGORITHM:

• For supersingular curves, the dual of Frobenius is again purely inseparable, so we start out with a Frobenius isogeny of equal degree in the opposite direction.

• For ordinary curves, we immediately reduce to the case of prime degree. The kernel of the dual is the unique subgroup of size $$p$$, which we compute from the $$p$$-division polynomial.

In both cases, we then search for the correct post-isomorphism using find_post_isomorphism().

is_injective()#

Determine whether or not this Frobenius isogeny has trivial kernel.

Since Frobenius isogenies are purely inseparable, this method always returns True.

EXAMPLES:

sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius
sage: E = EllipticCurve(GF(11), [1,1])
sage: pi = EllipticCurveHom_frobenius(E, 5)
sage: pi.is_injective()
True

is_separable()#

Determine whether or not this Frobenius isogeny is separable.

Since Frobenius isogenies are purely inseparable, this method returns True if and only if the degree is $$1$$.

EXAMPLES:

sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius
sage: E = EllipticCurve(GF(11), [1,1])
sage: pi = EllipticCurveHom_frobenius(E)
sage: pi.degree()
11
sage: pi.is_separable()
False
sage: pi = EllipticCurveHom_frobenius(E, 0)
sage: pi.degree()
1
sage: pi.is_separable()
True

kernel_polynomial()#

Return the kernel polynomial of this Frobenius isogeny as a polynomial in $$x$$. This method always returns $$1$$.

EXAMPLES:

sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius
sage: E = EllipticCurve(GF(11), [1,1])
sage: pi = EllipticCurveHom_frobenius(E, 5)
sage: pi.kernel_polynomial()
1

rational_maps()#

Return the explicit rational maps defining this Frobenius isogeny as (sparse) bivariate rational maps in $$x$$ and $$y$$.

EXAMPLES:

sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius
sage: E = EllipticCurve(GF(11), [1,1])
sage: pi = EllipticCurveHom_frobenius(E, 4)
sage: pi.rational_maps()
(x^14641, y^14641)

scaling_factor()#

Return the Weierstrass scaling factor associated to this Frobenius 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: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius
sage: E = EllipticCurve(GF(11), [1,1])
sage: pi = EllipticCurveHom_frobenius(E)
sage: pi.formal()
t^11 + O(t^33)
sage: pi.scaling_factor()
0
sage: pi = EllipticCurveHom_frobenius(E, 3)
sage: pi.formal()
t^1331 + O(t^1353)
sage: pi.scaling_factor()
0
sage: pi = EllipticCurveHom_frobenius(E, 0)
sage: pi == E.scalar_multiplication(1)
True
sage: pi.scaling_factor()
1


The scaling factor lives in the base ring:

sage: pi.scaling_factor().parent()
Finite Field of size 11


ALGORITHM: Inseparable isogenies of degree $$>1$$ have scaling factor $$0$$.

x_rational_map()#

Return the $$x$$-coordinate rational map of this Frobenius isogeny as a (sparse) univariate rational map in $$x$$.

EXAMPLES:

sage: from sage.schemes.elliptic_curves.hom_frobenius import EllipticCurveHom_frobenius
sage: E = EllipticCurve(GF(11), [1,1])
sage: pi = EllipticCurveHom_frobenius(E, 4)
sage: pi.x_rational_map()
x^14641