Rational point sets on a Jacobian of a general hyperelliptic curve

AUTHORS:

  • Sabrina Kunzweiler, Gareth Ma, Giacomo Pope (2024): adapt to smooth model

class sage.schemes.hyperelliptic_curves.jacobian_homset_generic.HyperellipticJacobianHomset(Y, X, **kwds)[source]

Bases: SchemeHomset_points

Set of rational points of the Jacobian.

cantor_composition(u1, v1, u2, v2)[source]

Return the Cantor composition of (u1, v1) and (u2, v2).

EXAMPLES:

sage: R.<x> = GF(13)[]
sage: H = HyperellipticCurve(x^7 + x^5 + x + 1)
sage: JF = Jacobian(H).point_homset()
sage: (u1, v1) = (x^3 + 4*x^2, 10*x^2 + 7*x + 1)
sage: (u2, v2) = (x^3 + 8*x^2 + 11*x + 2, x^2 + 9*x + 10)
sage: JF.cantor_composition(u1, v1, u2, v2)
(x^6 + 12*x^5 + 4*x^4 + 7*x^3 + 8*x^2, 5*x^5 + 2*x^4 + 12*x^2 + 7*x + 1)
cantor_reduction(u0, v0)[source]

Apply one reduction step of Cantor’s algorithm to (u0, v0).

Note that, in general, several steps are necessary the representation of a reduced divisor.

EXAMPLES:

sage: R.<x> = GF(13)[]
sage: H = HyperellipticCurve(x^7 + x^5 + x + 1)
sage: g = H.genus()
sage: JF = Jacobian(H).point_homset()
sage: (u0, v0) = (x^6 + 12*x^5 + 4*x^4 + 7*x^3 + 8*x^2, 5*x^5 + 2*x^4 + 12*x^2 + 7*x + 1)
sage: (u1, v1) = JF.cantor_reduction(u0, v0)
sage: u1.degree() <= g
False
sage: (u2, v2) = JF.cantor_reduction(u1, v1)
sage: u2.degree() <= g
True

Applying the reduction step to a reduced divisor might have unintended output, as is illustrated below.

sage: (u3, v3) = JF.cantor_reduction(u2, v2) sage: u3.degree() >= g True

cardinality(extension_degree=1)[source]

Return \(|Jac(C) / \mathbb{F}_{q^n}|\).

EXAMPLES:

sage: R.<x> = GF(5)[]
sage: H = HyperellipticCurve(x^6 + x + 1)
sage: J = H.jacobian()
sage: J(GF(5)).cardinality()
31
sage: J(GF(5^2)).cardinality()
961
count_points(n=1)[source]

Count the number of points of the Jacobian over all finite extensions of the base fields of degree less than or equal to n.

INPUT:

  • n – a positive integer

EXAMPLES:

sage: R.<x> = GF(5)[]
sage: H = HyperellipticCurve(x^6 + x + 1)
sage: J = H.jacobian()
sage: J.count_points(10) == [J.change_ring(GF((5, k))).order() for k in range(1, 11)]
True
sage: J2 = J(GF((5, 2)))
sage: J2.count_points(5) == J.count_points(10)[1::2]
True
curve()[source]

On input the set of \(L\)-rational points of a Jacobian \(Jac(H)\) defined over \(K\), return the curve \(H\).

NOTE: The base field of \(H\) is not extended to \(L\).

EXAMPLES:

sage: R.<x> = QQ[]
sage: K.<omega> = QQ.extension(x^2+x+1)
sage: H = HyperellipticCurve(x^6-1)
sage: JK = Jacobian(H)(K); JK
Abelian group of points over Number Field in omega with defining polynomial x^2 + x + 1 on Jacobian of Hyperelliptic Curve over Rational Field defined by y^2 = x^6 - 1
sage: JK.curve()
Hyperelliptic Curve over Rational Field defined by y^2 = x^6 - 1
extended_curve()[source]

On input the set of \(L\)-rational points of a Jacobian \(Jac(H)\) defined over \(K\), return the curve \(H\) with base extended to \(L\).

EXAMPLES:

sage: R.<x> = QQ[]
sage: K.<omega> = QQ.extension(x^2+x+1)
sage: H = HyperellipticCurve(x^6-1)
sage: JK = Jacobian(H)(K); JK
Abelian group of points over Number Field in omega with defining polynomial x^2 + x + 1 on Jacobian of Hyperelliptic Curve over Rational Field defined by y^2 = x^6 - 1
sage: JK.extended_curve()
Hyperelliptic Curve over Number Field in omega with defining polynomial x^2 + x + 1 defined by y^2 = x^6 - 1
lift_u(u, all=False)[source]

Return one or all points with given \(u\)-coordinate.

This method is deterministic: it returns the same data each time when called with the same \(u\).

Currently only implemented for Jacobians over a finite field.

INPUT:

  • u – an element of the base ring of the Jacobian

  • all – boolean (default: False); if True, return a (possibly empty) list of all points with the given \(u\)-coordinate; if False, return just one point, or raise a ValueError if there are none.

OUTPUT:

A point on this Jacobian.

EXAMPLES:

sage: R.<x> = GF(1993)[]
sage: H = HyperellipticCurve(x^5 + x + 1)
sage: J = H.jacobian()
sage: P = J.lift_u(x^2 + 42*x + 270); P
(x^2 + 42*x + 270, 1837*x + 838)
order()[source]

Compute the order of the Jacobian.

EXAMPLES:

We compute the order of a superspecial hyperelliptic curve of genus 3:

sage: R.<x> = GF(7)[]
sage: H = HyperellipticCurve(x^8 - 1)
sage: J = H.jacobian()
sage: J(GF(7)).order() == (7+1)^3
True
sage: J(GF(7^2)).order() == (7+1)^6
True
sage: R.<x> = QQ[]
sage: H = HyperellipticCurve(x^8 - 1)
sage: J = H.jacobian()
sage: J.order()
Traceback (most recent call last):
...
NotImplementedError
point_to_mumford_coordinates(P)[source]

On input a point P, return the Mumford coordinates of (the affine part of) the divisor [P].

EXAMPLES:

sage: R.<x> = QQ[]
sage: H = HyperellipticCurve(x^5 - 2*x^4 + 2*x^3 - x^2, 1)
sage: P = H([2,3]); P
(2 : 3 : 1)
sage: JQ = H.jacobian()(QQ)
sage: JQ.point_to_mumford_coordinates(P)
(x - 2, 3)
points()[source]

Return all points on this Jacobian \(J(K)\).

Warning

This code is not efficient at all.

EXAMPLES:

sage: R.<x> = GF(3)[]
sage: H = HyperellipticCurve(x^7 + 2*x + 1)
sage: J3 = H.jacobian()(GF(3))
sage: Pts = J3.points()
sage: len(Pts)
94
sage: Pts[10]
(x^2 + 2, x)
sage: Pts[-1]
(x^3 + 2*x^2 + 2*x + 1, 1)
random_element(fast=False, *args, **kwargs)[source]

Returns a random element from the Jacobian. Distribution is NOT uniformly random.

INPUT:

  • fast – (boolean, default True) If set to True, a fast algorithm is used, but the output is NOT guaranteed to cover the entire Jacobian. See examples below. If set to False, a slower algorithm is used, but covers the entire Jacobian.

EXAMPLES:

sage: R.<x> = GF(5)[]
sage: f = x^5 + 2*x^4 + 4*x^3 + x^2 + 4*x + 3
sage: H = HyperellipticCurve(f)
sage: J = H.jacobian()

This example demonstrates that the fast algorithm is not necessarily surjective on the rational points of the Jacobian:

sage: JH = J.point_homset()
sage: len(set(JH.random_element(fast=True) for _ in range(300)))
8
sage: len(set(JH.random_element(fast=False) for _ in range(300)))
16
sage: J.order()
16
rational_points()[source]

alias of points().

zero(check=True)[source]

Return the zero element of this jacobian homset.

EXAMPLES:

sage: R.<x> = QQ[]
sage: H = HyperellipticCurve(x^5 + 1)
sage: JQ = H.jacobian()(QQ)
sage: JQ.zero()
(1, 0)