Scalar-multiplication morphisms of elliptic curves#
This class provides an EllipticCurveHom
instantiation for
multiplication-by-\(m\) maps on elliptic curves.
EXAMPLES:
We can construct and evaluate scalar multiplications:
sage: from sage.schemes.elliptic_curves.hom_scalar import EllipticCurveHom_scalar
sage: E = EllipticCurve('77a1')
sage: phi = E.scalar_multiplication(5); phi
Scalar-multiplication endomorphism [5] of Elliptic Curve defined by y^2 + y = x^3 + 2*x over Rational Field
sage: P = E(2,3)
sage: phi(P)
(30 : 164 : 1)
The usual EllipticCurveHom
methods are supported:
sage: phi.degree()
25
sage: phi.kernel_polynomial()
x^12 + 124/5*x^10 + 19*x^9 - 84*x^8 + 24*x^7 - 483*x^6 - 696/5*x^5 - 448*x^4 - 37*x^3 - 332*x^2 - 84*x + 47/5
sage: phi.rational_maps()
((x^25 - 200*x^23 - 520*x^22 + 9000*x^21 + ... + 1377010*x^3 + 20360*x^2 - 39480*x + 2209),
(10*x^36*y - 620*x^36 + 3240*x^34*y - 44880*x^34 + ... + 424927560*x*y + 226380480*x + 42986410*y + 20974090)/(1250*x^36 + 93000*x^34 + 71250*x^33 + 1991400*x^32 + ... + 1212964050*x^3 + 138715800*x^2 - 27833400*x + 1038230))
sage: phi.dual()
Scalar-multiplication endomorphism [5] of Elliptic Curve defined by y^2 + y = x^3 + 2*x over Rational Field
sage: phi.dual() is phi
True
sage: phi.formal()
5*t - 310*t^4 - 2496*t^5 + 10540*t^7 + ... - 38140146674516*t^20 - 46800256902400*t^21 + 522178541079910*t^22 + O(t^23)
sage: phi.is_normalized()
False
sage: phi.is_separable()
True
sage: phi.is_injective()
False
sage: phi.is_surjective()
True
Contrary to constructing an EllipticCurveIsogeny
from
the division polynomial, EllipticCurveHom_scalar
can
deal with huge scalars very quickly:
sage: E = EllipticCurve(GF(2^127-1), [1,2,3,4,5])
sage: phi = E.scalar_multiplication(9^99); phi
Scalar-multiplication endomorphism [29512665430652752148753480226197736314359272517043832886063884637676943433478020332709411004889] of Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Finite Field of size 170141183460469231731687303715884105727
sage: phi(E(1,2))
(82124533143060719620799539030695848450 : 17016022038624814655722682134021402379 : 1)
Composition of scalar multiplications results in another scalar multiplication:
sage: E = EllipticCurve(GF(19), [4,4])
sage: phi = E.scalar_multiplication(-3); phi
Scalar-multiplication endomorphism [-3] of Elliptic Curve defined by y^2 = x^3 + 4*x + 4 over Finite Field of size 19
sage: psi = E.scalar_multiplication(7); psi
Scalar-multiplication endomorphism [7] of Elliptic Curve defined by y^2 = x^3 + 4*x + 4 over Finite Field of size 19
sage: phi * psi
Scalar-multiplication endomorphism [-21] of Elliptic Curve defined by y^2 = x^3 + 4*x + 4 over Finite Field of size 19
sage: psi * phi
Scalar-multiplication endomorphism [-21] of Elliptic Curve defined by y^2 = x^3 + 4*x + 4 over Finite Field of size 19
sage: phi * psi == psi * phi
True
sage: -phi == E.scalar_multiplication(-1) * phi
True
The zero endomorphism \([0]\) is supported:
sage: E = EllipticCurve(GF(71), [1,1])
sage: zero = E.scalar_multiplication(0); zero
Scalar-multiplication endomorphism [0] of Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 71
sage: zero.is_zero()
True
sage: zero.is_injective()
False
sage: zero.is_surjective()
False
sage: zero(E.random_point())
(0 : 1 : 0)
Due to a bug (trac ticket #6413), retrieving multiplication-by-\(m\) maps when \(m\) is divisible by the characteristic currently fails:
sage: E = EllipticCurve(GF(7), [1,0])
sage: phi = E.scalar_multiplication(7); phi
Scalar-multiplication endomorphism [7] of Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 7
sage: phi.rational_maps() # known bug -- #6413
(x^49, y^49)
sage: phi.x_rational_map()
x^49
sage: E = EllipticCurve(GF(7), [0,1])
sage: phi = E.scalar_multiplication(7); phi
Scalar-multiplication endomorphism [7] of Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 7
sage: phi.rational_maps() # known bug -- #6413
((-3*x^49 - x^28 - x^7)/(x^42 - x^21 + 2),
(-x^72*y - 3*x^69*y - 3*x^66*y - x^63*y + 3*x^51*y + 2*x^48*y + 2*x^45*y + 3*x^42*y - x^9*y - 3*x^6*y - 3*x^3*y - y)/(x^63 + 2*x^42 - x^21 - 1))
sage: phi.x_rational_map()
(4*x^49 + 6*x^28 + 6*x^7)/(x^42 + 6*x^21 + 2)
AUTHORS:
Lorenz Panny (2021): implement
EllipticCurveHom_scalar
- class sage.schemes.elliptic_curves.hom_scalar.EllipticCurveHom_scalar(E, m)#
Bases:
EllipticCurveHom
Construct a scalar-multiplication map on an elliptic curve.
- degree()#
Return the degree of this scalar-multiplication morphism.
The map \([m]\) has degree \(m^2\).
EXAMPLES:
sage: E = EllipticCurve(GF(23), [0,1]) sage: phi = E.scalar_multiplication(1111111) sage: phi.degree() 1234567654321
- dual()#
Return the dual isogeny of this scalar-multiplication map.
This method simply returns
self
as scalars are self-dual.EXAMPLES:
sage: E = EllipticCurve([5,5]) sage: phi = E.scalar_multiplication(5) sage: phi.dual() is phi True
- is_injective()#
Determine whether this scalar multiplication defines an injective map (over the algebraic closure).
Equivalently, return
True
if and only if this scalar multiplication is a purely inseparable isogeny.EXAMPLES:
sage: E = EllipticCurve(GF(23), [1,0]) sage: E.scalar_multiplication(4).is_injective() False sage: E.scalar_multiplication(5).is_injective() False sage: E.scalar_multiplication(1).is_injective() True sage: E.scalar_multiplication(-1).is_injective() True sage: E.scalar_multiplication(23).is_injective() True sage: E.scalar_multiplication(-23).is_injective() True sage: E.scalar_multiplication(0).is_injective() False
- is_separable()#
Determine whether this scalar-multiplication map is a separable isogeny. (This is the case if and only if the scalar \(m\) is coprime to the characteristic.)
EXAMPLES:
sage: E = EllipticCurve(GF(11), [4,4]) sage: E.scalar_multiplication(11).is_separable() False sage: E.scalar_multiplication(-11).is_separable() False sage: E.scalar_multiplication(777).is_separable() True sage: E.scalar_multiplication(-1).is_separable() True sage: E.scalar_multiplication(77).is_separable() False sage: E.scalar_multiplication(121).is_separable() False
- kernel_polynomial()#
Return the kernel polynomial of this scalar-multiplication map. (When \(m=0\), return \(0\).)
EXAMPLES:
sage: E = EllipticCurve(GF(997), [7,7,7,7,7]) sage: phi = E.scalar_multiplication(5) sage: phi.kernel_polynomial() x^12 + 77*x^11 + 380*x^10 + 198*x^9 + 840*x^8 + 376*x^7 + 946*x^6 + 848*x^5 + 246*x^4 + 778*x^3 + 77*x^2 + 518*x + 28
sage: E = EllipticCurve(GF(997), [5,6,7,8,9]) sage: phi = E.scalar_multiplication(11) sage: phi.kernel_polynomial() x^60 + 245*x^59 + 353*x^58 + 693*x^57 + 499*x^56 + 462*x^55 + 820*x^54 + 962*x^53 + ... + 736*x^7 + 939*x^6 + 429*x^5 + 267*x^4 + 116*x^3 + 770*x^2 + 491*x + 519
- rational_maps()#
Return the pair of explicit rational maps defining this scalar multiplication.
ALGORITHM:
EllipticCurve_generic.multiplication_by_m()
EXAMPLES:
sage: E = EllipticCurve('77a1') sage: phi = E.scalar_multiplication(5) sage: phi.rational_maps() ((x^25 - 200*x^23 - 520*x^22 + ... + 368660*x^2 + 163195*x + 16456)/(25*x^24 + 1240*x^22 + 950*x^21 + ... + 20360*x^2 - 39480*x + 2209), (10*x^36*y - 620*x^36 + 3240*x^34*y - ... + 226380480*x + 42986410*y + 20974090)/(1250*x^36 + 93000*x^34 + 71250*x^33 + ... + 138715800*x^2 - 27833400*x + 1038230)) sage: P = (2,3) sage: Q = tuple(r(P) for r in phi.rational_maps()); Q (30, 164) sage: E(Q) == 5*E(P) True
- scaling_factor()#
Return the Weierstrass scaling factor associated to this scalar multiplication.
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('11a1') sage: phi = E.scalar_multiplication(5) sage: u = phi.scaling_factor() sage: u == phi.formal()[1] True sage: u == E.multiplication_by_m_isogeny(5).scaling_factor() doctest:warning ... DeprecationWarning: ... True
The scaling factor lives in the base ring:
sage: E = EllipticCurve(GF(101^2), [5,5]) sage: phi = E.scalar_multiplication(123) sage: phi.scaling_factor() 22 sage: phi.scaling_factor().parent() Finite Field in z2 of size 101^2
ALGORITHM: The scaling factor equals the scalar that is being multiplied by.
- x_rational_map()#
Return the \(x\)-coordinate rational map of this scalar multiplication.
ALGORITHM:
EllipticCurve_generic.multiplication_by_m()
EXAMPLES:
sage: E = EllipticCurve(GF(65537), [1,2,3,4,5]) sage: phi = E.scalar_multiplication(7) sage: phi.x_rational_map() == phi.rational_maps()[0] True