Creation Functions

Contents

Creation of an Elliptic Curve

An elliptic curve E may be created by specifying Weierstrass coordinates for the curve over a field K, where integer coordinates are interpreted as elements of Q. Note that the coordinate ring K defines the base point set of E, and points defined over an extension field of K must be created in the appropriate point set.

EllipticCurve([a, b]) : [ RngElt ] -> CrvEll
EllipticCurve([a1, a2, a3, a4, a6]) : [ RngElt ] -> CrvEll
Given a sequence of elements of a ring K, this function creates the elliptic curve E over K defined by taking the elements of the sequence as Weierstrass coefficients. The length of the sequence must either be two, that is s=[a, b], in which case E is defined by y2 = x3 + ax + b, or five, that is s=[a1, a2, a3, a4, a6], in which case E is given by y2 + a1xy + a3y=x3 + a2x2 + a4x + a6. Currently K must be field; if integers are given then they will be coerced into Q. The given coefficients must define a nonsingular curve; that is, the discriminant of the curve must be nonzero.
EllipticCurve(f) : RngUPolElt -> CrvEll
EllipticCurve(f, h) : RngUPolElt, RngUPolElt -> CrvEll
Given univariate polynomials f and h, this function creates the elliptic curve defined by y2 + h(x)y = f(x), or by y2 = f(x) if h is not given. The polynomial f must be monic of degree 3 and h must have degree at most 1.
EllipticCurveFromjInvariant(j) : RngElt -> CrvEll
EllipticCurveWithjInvariant(j) : RngElt -> CrvEll
Given a ring element j, this function creates an elliptic curve E over K with j-invariant equal to j defined as follows: If j = 0 and K does not have characteristic 3 then E is defined by y2 + y = x3; if j = 1728 then E is defined by y2 = x3 + x (which covers the case where j = 0 and K has characteristic 3); otherwise j - 1728 is invertible in K and E is defined by y2 + xy = x3 - (36/(j - 1728))x - 1/(j - 1728).

Example CrvEll_Creation (H128E1)

We create one particular elliptic curve over Q in three different ways:
> EllipticCurve([1, 0]);
Elliptic Curve defined by y^2 = x^3 + x over Rational Field
> Qx<x> := PolynomialRing(Rationals());
> EllipticCurve(x^3 + x);
Elliptic Curve defined by y^2 = x^3 + x over Rational Field
> EllipticCurveWithjInvariant(1728);
Elliptic Curve defined by y^2 = x^3 + x over Rational Field
EllipticCurve(C) : Sch -> CrvEll, MapSch
    SetVerbose("EllModel", n):          Maximum: 3
Given a scheme C describing a curve of genus 1 with an easily recognised rational point, this function returns an elliptic curve E together with a birational map from C to E. If there is no "obvious" rational point then this routine will fail. C must belong to one of the following classes:
(i)
Hyperelliptic curves of genus 1 of the form C: y2 + h(x)y=f(x) with f of degree 3 or 4 and h of degree at most 1. If the function x on C has a rational branch point then that point is sent to the origin on E. Otherwise, if C has a rational point at x=∞ then that point is used.

(ii)
Nonsingular plane curves of degree 3. If the curve is already in general Weierstrass form up to a permutation of the variables then this is recognised and used as a model for the elliptic curve. Otherwise the base field of the curve must have characteristic different from 2 and 3; in this case, the curve is tested for having a rational flex. If it has then a linear transformation suffices to get the curve into general Weierstrass form, and this is used.

(iii)
Singular plane curves of degree 4 over a base field of characteristic different from 2 with a unique cusp, with the tangent cone meeting the curve only at that point. Up to linear transformation, these are curves of type y2=f(x), with f of degree 4. Such curves are brought into the standard form above. If either a rational point exists with x=0 or the curve intersects the line at infinity in a rational point then that point is used to put the curve in general Weierstrass form.

EllipticCurve(C, P) : Crv, Pt -> CrvEll, MapSch
    SetVerbose("EllModel", n):          Maximum: 3
Given a scheme C describing a curve of genus 1 with a nonsingular rational point P, this function returns an elliptic curve E together with a birational map sending the supplied point to the origin on E.

If C is a plane curve of degree 3 over a base field having characteristic different from 2 and 3 then particular tricks are tried. If the supplied point is a flex then a linear transformation is used. Otherwise, Nagell's algorithm [Nag28], also described in [Cas91], is used.

If C is a plane curve of degree 4 over a base field of characteristic different from 2 with a unique cusp and a tangent cone that meets the curve only in that cusp, then a construction in [Cas91] is used.

In all other cases, C has to be a plane curve and a Riemann--Roch computation is used. This is potentially very expensive.

EllipticCurve(C, pl) : Crv, PlcCrvElt -> CrvEll, MapSch
    SetVerbose("EllModel", n):          Maximum: 3
Given a plane curve C of genus 1 and a place pl of degree 1, this function returns an elliptic curve E together with a birational map from C to E.

This routine uses a (potentially expensive) Riemann--Roch computation. This is different to the routine that takes a point instead of a place, which uses special methods when the curve has degree 3 or 4.

SupersingularEllipticCurve(K) : FldFin -> CrvEll
Given a finite field K, this function returns a representative supersingular elliptic curve over K.

Example CrvEll_CreationFromCurve (H128E2)

In the following example Nagell's algorithm is applied.
> P2<X, Y, Z> := ProjectiveSpace(Rationals(), 2);
> C := Curve(P2, X^3 + Y^2*Z - X*Y*Z - Z^3);
> pt := C![0, 1, 1];
> time E1, phi1 := EllipticCurve(C, pt);
Time: 0.070
> E1;
Elliptic Curve defined by y^2 = x^3 - 5/16*x^2 + 1/32*x + 15/1024 over Rational
Field
Whereas this next call (given a place) is forced to do the Riemann--Roch computation.
> time E2, phi2 := EllipticCurve(C, Place(pt));
Time: 0.120
> E2;
Elliptic Curve defined by y^2 + 1024*y = x^3 + 16*x^2 over Rational Field
> phi1;
Mapping from: CrvPln: C to CrvEll: E1
with equations :
9/8*X^2 - 1/4*X*Y
-1/8*X^2 + 1/4*X*Y + 13/16*X*Z - 1/8*Y*Z - 1/8*Z^2
X^2 - 2*X*Y + 2*X*Z
and inverse
$.1^2 - 3/16*$.1*$.3 + 1/128*$.3^2
1/2*$.1^2 + $.1*$.2 - 15/32*$.1*$.3 + 9/256*$.3^2
$.1*$.2 + 1/8*$.1*$.3 - 1/8*$.2*$.3 - 1/64*$.3^2
> phi2;
Mapping from: CrvPln: C to CrvEll: E2
with equations :
-64*X^2*Y + 64*X^2*Z - 128*X*Y^2 + 256*X*Y*Z - 128*X*Z^2 + 64*Y^2*Z - 64*Y*Z^2
256*X^2*Y + 256*X^2*Z + 1024*X*Y*Z - 1024*X*Z^2 + 1792*Y^2*Z - 4352*Y*Z^2 +
    2048*Z^3
Y^3 - 3*Y^2*Z + 3*Y*Z^2 - Z^3

Example CrvEll_CreationFromCurve2 (H128E3)

In this example the starting curve is less clearly elliptic. Since this curve does not match any of the special forms described the Riemann--Roch computation will be used.
> P2<X, Y, Z> := ProjectiveSpace(Rationals(), 2);
> C := Curve(P2, X^3*Y^2 + X^3*Z^2 - Z^5);
> Genus(C);
1
> pt := C![1, 0, 1];
> E, toE := EllipticCurve(C, pt);
> E;
Elliptic Curve defined by y^2 = x^3 + 3*x^2 + 3*x over Rational Field
> toE;
Mapping from: CrvPln: C to CrvEll: E

Creation Predicates

IsEllipticCurve([a, b]) : [ RngElt ] -> BoolElt, CrvEll
IsEllipticCurve([a1, a2, a3, a4, a6]) : [ RngElt ] -> BoolElt, CrvEll
The function returns true if the given sequence of ring elements defines an elliptic curve (in other words, if the discriminant is nonzero). When true, the elliptic curve is also returned.
IsEllipticCurve(C) : CrvHyp -> BoolElt, CrvEll, MapIsoSch, MapIsoSch
Given a hyperelliptic curve, the function returns true if C has degree 3. When true, the function also returns the elliptic curve, and isomorphisms to and from it. This function is deprecated and will be removed in a later release. Instead, use Degree(C) eq 3 and EllipticCurve(C).

Example CrvEll_CreationTest (H128E4)

We check a few small primes to see which ones make certain coefficients define an elliptic curve.
> S := [ p : p in [1..20] | IsPrime(p) ];
> for p in S do
>     ok, E := IsEllipticCurve([GF(p) | 1, 1, 0, -3, -17 ]);
>     if ok then print E; end if;
> end for;
Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 1 over GF(3)
Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 10*x + 9 over GF(13)
Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 14*x over GF(17)

Changing the Base Ring

The following general scheme functions provide a convenient way to generate a new elliptic curve similar to an old one but defined over a different field. Some care must be taken, however: If the result is not a valid elliptic curve then the functions will still succeed but the object returned will be a general curve rather than an elliptic curve.

BaseChange(E, K) : CrvEll, Rng -> CrvEll
BaseExtend(E, K) : CrvEll, Rng -> CrvEll
Given an elliptic curve E defined over a field k, and a field K which is an extension of k, returns an elliptic curve E' over K using the natural inclusion of k in K to map the coefficients of E into K.
ChangeRing(E, K) : CrvEll, Rng -> CrvEll
Given an elliptic curve E defined over a field k, and a field K, returns an elliptic curve E' over K by using the standard coercion from k to K to map the coefficients of E into K. This is useful when there is no appropriate ring homomorphism between k and K (e.g., when k=Q and K is a finite field).
BaseChange(E, h) : CrvEll, Map -> CrvEll
BaseExtend(E, h) : CrvEll, Map -> CrvEll
Given an elliptic curve E over a field k and a ring map h : k -> K, returns an elliptic curve E' over K by applying h to the coefficients of E.
BaseChange(E, n) : CrvEll, RngIntElt -> CrvEll
BaseExtend(E, n) : CrvEll, RngIntElt -> CrvEll
Given an elliptic curve E defined over a finite field K, returns the base extension of E to the degree n extension of K.

Example CrvEll_BaseExtend (H128E5)

> K1 := GF(23);
> K2 := GF(23, 2);
> f := hom<K1 -> K2 | >;
> E1 := EllipticCurve([K1 | 1, 1]);
> E2 := EllipticCurve([K2 | 1, 1]);
> assert E2 eq BaseExtend(E1, K2);
> assert E2 eq BaseExtend(E1, f);
> assert E2 eq BaseExtend(E1, 2);
> // this is illegal, since K1 is not an extension of K2
> BaseExtend(E2, K1);
>> BaseExtend(E2, K1);
             ^
Runtime error in 'BaseExtend': Coercion of equations is not possible
> assert E1 eq ChangeRing(E2, K1);  // but this is OK

Alternative Models

Given an elliptic curve E, there are standard alternative models for E that may be of interest. Each of the functions in this section returns an isomorphic curve E' that is the desired model, together with the isomorphisms E -> E' and E' -> E.

Note: The second isomorphism is now completely redundant as it is the inverse of the first; in a later release only the first will be returned.

WeierstrassModel(E) : CrvEll -> CrvEll, Map, Map
Given an elliptic curve E, this function returns an isomorphic elliptic curve E' in simplified Weierstrass form y2 = x3 + ax + b. It does not apply when the base ring of E has characteristic 2 or 3 (in which case such a simplified form may not exist).
IntegralModel(E) : CrvEll -> CrvEll, Map, Map
Given an elliptic curve E defined over a number field K (which may be Q), this function returns an isomorphic elliptic curve E' defined over K with integral coefficients.
SimplifiedModel(E): CrvEll -> CrvEll, Map, Map
A simplified model of the elliptic curve E is returned. If E is defined over Q this has the same effect as MinimalModel below. Otherwise, if the characteristic of the base ring is different from 2 and 3, the simplified model agrees with the WeierstrassModel. For characteristics 2 and 3 the situation is more complicated; see chapter 4 of [Con99] for the definition for curves defined over finite fields.
MinimalModel(E) : CrvEll -> CrvEll, Map, Map
Given an elliptic curve E defined over Q or a number field K with class number one, returns a global minimal model E' for E. By definition, the global minimal model E' is an integral model isomorphic to E over K such that the discriminant of E' has minimal valuation at all non-zero prime ideals π of K. (For Q, this means that it has minimal p-adic valuation at all primes p.)

Such a global minimal model is only guaranteed to exist when the class number of K is 1 (and so one always exists when K = Q); depending on the curve, however, such a model may exist even when this is not the case. If no such minimal model exists then a runtime error will occur.

MinimalModel(E, p) : CrvEll, RngIntElt -> CrvEll, Map, Map
MinimalModel(E, P : parameters) : CrvEll, RngOrdIdl -> CrvEll, Map
Given an elliptic curve E defined over a number field K, and a prime ideal P, returns a curve isomorphic to E which is minimal at P. If K is Q then the ideal may be specified by the appropriate (integer) prime p.

For curves over number fields, when the parameter UseGeneratorAsUniformiser is set to true then Magma will check whether the ideal is principal; if so, an ideal generator will be used as the uniformising element. This means that at other primes the returned model will remain integral, or minimal, if the given model was.

Predicates on Curve Models

IsWeierstrassModel(E) : CrvEll -> BoolElt
Returns true if and only if the elliptic curve E is in simplified Weierstrass form.
IsIntegralModel(E) : CrvEll -> BoolElt
Returns true if and only if the elliptic curve E is an integral model.
IsSimplifiedModel(E) : CrvEll -> BoolElt
Returns true if and only if the elliptic curve E is a simplified model.
IsMinimalModel(E) : CrvEll -> BoolElt
Returns true if and only if the elliptic curve E is a minimal model.
IsIntegralModel(E, P) : CrvEll, RngOrdIdl -> BoolElt
Returns true if the defining coefficients of the elliptic curve E, a curve over a number field, have non-negative valuation at the prime ideal P, which must be an ideal of an order of the coefficient ring of E.

Example CrvEll_Models (H128E6)

We define an elliptic curve over the rationals and then find an integral model, a minimal model, and an integral model for the short Weierstrass form.
> E := EllipticCurve([1/2, 1/2, 1, 1/3, 4]);
> E;
Elliptic Curve defined by y^2 + 1/2*x*y + y = x^3 + 1/2*x^2 + 1/3*x + 4
over Rational Field
> IE := IntegralModel(E);
> IE;
Elliptic Curve defined by y^2 + 3*x*y + 216*y = x^3 + 18*x^2 + 432*x +
186624 over Rational Field
> ME := MinimalModel(IE);
> ME;
Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 + 619*x + 193645
over Rational Field
> WE := WeierstrassModel(E);
> WE;
Elliptic Curve defined by y^2 = x^3 + 9909/16*x + 6201603/32 over
Rational Field
> IWE := IntegralModel(WE);
> IWE;
Elliptic Curve defined by y^2 = x^3 + 649396224*x + 208091266154496
over Rational Field
> IsIsomorphic(IWE, ME);
true

Twists of Elliptic Curves

In the following, all twists will be returned in the form of simplified models.

QuadraticTwist(E, d) : CrvEll, RngElt -> CrvEll
Given an elliptic curve E and an element d of the base ring, returns the quadratic twist by d. This is isomorphic to E if and only if either the characteristic is 2 and the trace of d is 0, or the characteristic is not 2 and d is a square. The routine does not always work in characteristic 2.
QuadraticTwist(E) : CrvEll -> CrvEll
Given an elliptic curve E over a finite field, returns a quadratic twist; that is, a nonisomorphic curve whose trace is the negation of Trace(E).
QuadraticTwists(E) : CrvEll -> SeqEnum
Given an elliptic curve E over a finite field, returns the sequence of nonisomorphic quadratic twists. The first of these curves is isomorphic to E.
Twists(E) : CrvEll -> SeqEnum
Given an elliptic curve over a finite field K, returns the sequence of all nonisomorphic elliptic curves over K which are isomorphic over an extension field. The first of these curves is isomorphic to E.

Example CrvEll_QuadraticTwists (H128E7)

In this example we compute the quadratic twists of an elliptic curve over the finite field F13 and verify that they fall in two isomorphism classes over the base field.
> E1 := EllipticCurve([GF(13) | 3, 1]);
> E5 := QuadraticTwist(E1, 5);
> E5;
Elliptic Curve defined by y^2 = x^3 + 10*x + 8 over GF(13)
> S := QuadraticTwists(E1);
> S;
[
    Elliptic Curve defined by y^2 = x^3 + 3*x + 1 over GF(13),
    Elliptic Curve defined by y^2 = x^3 + 12*x + 5 over GF(13)
]
> [ IsIsomorphic(E1, E) : E in S ];
[ true, false ]
> [ IsIsomorphic(E5, E) : E in S ];
[ false, true ]
IsTwist(E, F) : CrvEll, CrvEll -> BoolElt
Returns true if and only if the elliptic curves E and F are isomorphic over an extension field --- this function only tests the j-invariants of the curves.
IsQuadraticTwist(E, F) : CrvEll, CrvEll -> BoolElt, RngElt
Returns true if and only if the elliptic curves E and F are isomorphic over a quadratic extension field; if so, returns an element d of the base field such that F is isomorphic to QuadraticTwist(E, d).

Example CrvEll_NonquadraticTwists (H128E8)

In this example we take curves of j-invariant 0 and 123 = 12 over the finite field F13, and compute all twists. Since the automorphism groups are nontrivial the number of twists is larger than the number of quadratic twists. By computing the numbers of points we see that the curves are indeed pairwise nonisomorphic over the base field.
> E3 := EllipticCurve([GF(13) | 0, 1]);
> jInvariant(E3);
0
> E4 := EllipticCurve([GF(13) | 1, 0]);
> jInvariant(E4);
12
> T3 := Twists(E3);
> T3;
[
    Elliptic Curve defined by y^2 = x^3 + 1 over GF(13),
    Elliptic Curve defined by y^2 = x^3 + 2 over GF(13),
    Elliptic Curve defined by y^2 = x^3 + 4 over GF(13),
    Elliptic Curve defined by y^2 = x^3 + 8 over GF(13),
    Elliptic Curve defined by y^2 = x^3 + 3 over GF(13),
    Elliptic Curve defined by y^2 = x^3 + 6 over GF(13)
]
> [ #E : E in T3 ];
[ 12, 19, 21, 16, 9, 7 ]
> T4 := Twists(E4);
> T4;
[
    Elliptic Curve defined by y^2 = x^3 + x over GF(13),
    Elliptic Curve defined by y^2 = x^3 + 2*x over GF(13),
    Elliptic Curve defined by y^2 = x^3 + 4*x over GF(13),
    Elliptic Curve defined by y^2 = x^3 + 8*x over GF(13)
]
> [ #E : E in T4 ];
[ 20, 10, 8, 18 ]
Observe that exactly two of the twists are quadratic twists (as must always be the case).
> [ IsQuadraticTwist(E3, E) : E in T3 ];
[ true, false, false, true, false, false ]
> [ IsQuadraticTwist(E4, E) : E in T4 ];
[ true, false, true, false ]
MinimalQuadraticTwist(E) : CrvEll -> CrvEll, RngIntElt
Determine the minimal twist of the rational elliptic curve E. This is defined locally prime-by-prime, and the algorithm for finding it is based on this observation. For each odd prime p of bad reduction the algorithm iteratively replaces the curve by its twist by p if the latter has smaller discriminant.

For p=2 there is no accepted definition of minimal, and the prime at infinity also plays a role. After having handled all the odd primes there are only twists by -1, 2, and -2 left to consider. The algorithm implemented in Magma first chooses a twist with minimal 2-valuation of the conductor; this is unique precisely when this 2-valuation is less than 5. [Note that others have chosen instead to minimise the 2-valuation of Δ.]

The prime 2 can be eliminated at this point as was done in the case of the odd primes, leaving only the consideration of twisting the curve by -1. Here the algorithm arbitrarily chooses the curve that has ( - 1)v2(c6)(odd)(c6) congruent to 3 mod 4. The function returns as its second argument the integer d by which the curve was twisted to obtain the minimal twist.

Example CrvEll_min_twist (H128E9)

> E:=EllipticCurve([0, 1, 0, 135641131, 1568699095683]);
> M, tw := MinimalQuadraticTwist(E);
> M, tw;
Elliptic Curve defined by y^2 + y = x^3 + x^2 + 3*x + 5 over Rational Field
7132
> MinimalModel(QuadraticTwist(M, tw));
Elliptic Curve defined by y^2 = x^3 + x^2 + 135641131*x + 1568699095683 over
Rational Field
V2.28, 13 July 2023