# Jacobians in Hess model#

This module implements Jacobian arithmetic based on divisor representation by ideals. This approach to Jacobian arithmetic implementation is attributed to Hess [Hes2002].

## Jacobian#

To create a Jacobian in Hess model, specify 'hess' model and provide a base divisor of degree $$g$$, which is the genus of the function field:

sage: P2.<x,y,z> = ProjectiveSpace(GF(29), 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: C.geometric_genus()
1
sage: B = C([0,1,0]).place()
sage: B.degree()
1
sage: J = C.jacobian(model='hess', base_div=B)
sage: J
Jacobian of Projective Plane Curve over Finite Field of size 29
defined by x^3 - y^2*z + 5*z^3 (Hess model)

>>> from sage.all import *
>>> P2 = ProjectiveSpace(GF(Integer(29)), Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> C.geometric_genus()
1
>>> B = C([Integer(0),Integer(1),Integer(0)]).place()
>>> B.degree()
1
>>> J = C.jacobian(model='hess', base_div=B)
>>> J
Jacobian of Projective Plane Curve over Finite Field of size 29
defined by x^3 - y^2*z + 5*z^3 (Hess model)


## Group of rational points#

The group of rational points of a Jacobian is created from the Jacobian. A point of the Jacobian group is determined by a divisor (of degree zero) of the form $$D - B$$ where $$D$$ is an effective divisor of degree $$g$$ and $$B$$ is the base divisor. Hence a point of the Jacobian group is represented by $$D$$.

sage: G = J.group()
sage: P1 = C([1,8,1]).place()
sage: P2 = C([2,10,1]).place()
sage: p1 = G(P1)
sage: p2 = G(P2)
sage: p1
[Place (y + 21, z + 28)]
sage: p2
[Place (y + 24, z + 14)]
sage: p1 + p2
[Place (y + 8, z + 28)]

>>> from sage.all import *
>>> G = J.group()
>>> P1 = C([Integer(1),Integer(8),Integer(1)]).place()
>>> P2 = C([Integer(2),Integer(10),Integer(1)]).place()
>>> p1 = G(P1)
>>> p2 = G(P2)
>>> p1
[Place (y + 21, z + 28)]
>>> p2
[Place (y + 24, z + 14)]
>>> p1 + p2
[Place (y + 8, z + 28)]


AUTHORS:

• Kwankyu Lee (2022-01-24): initial version

class sage.rings.function_field.jacobian_hess.Jacobian(function_field, base_div, **kwds)[source]#

Jacobians of function fields.

EXAMPLES:

sage: k = GF(17)
sage: P2.<x,y,z> = ProjectiveSpace(k, 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: b = C([0,1,0]).place()
sage: C.jacobian(model='hess', base_div=b)
Jacobian of Projective Plane Curve over Finite Field of size 17
defined by x^3 - y^2*z + 5*z^3 (Hess model)

>>> from sage.all import *
>>> k = GF(Integer(17))
>>> P2 = ProjectiveSpace(k, Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> b = C([Integer(0),Integer(1),Integer(0)]).place()
>>> C.jacobian(model='hess', base_div=b)
Jacobian of Projective Plane Curve over Finite Field of size 17
defined by x^3 - y^2*z + 5*z^3 (Hess model)

class sage.rings.function_field.jacobian_hess.JacobianGroup(parent, function_field, base_div)[source]#

Groups of rational points of a Jacobian.

INPUT:

• parent – a Jacobian

• function_field – a function field

• base_div – an effective divisor of the function field

EXAMPLES:

sage: P2.<x,y,z> = ProjectiveSpace(GF(17), 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: b = C([0,1,0]).place()
sage: J = C.jacobian(model='hess', base_div=b)
sage: J.group()
Group of rational points of Jacobian
over Finite Field of size 17 (Hess model)

>>> from sage.all import *
>>> P2 = ProjectiveSpace(GF(Integer(17)), Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> b = C([Integer(0),Integer(1),Integer(0)]).place()
>>> J = C.jacobian(model='hess', base_div=b)
>>> J.group()
Group of rational points of Jacobian
over Finite Field of size 17 (Hess model)

Element[source]#

alias of JacobianPoint

point(divisor)[source]#

Return the point represented by the divisor of degree zero.

EXAMPLES:

sage: P2.<x,y,z> = ProjectiveSpace(GF(17), 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: b = C([0,1,0]).place()
sage: J = C.jacobian(model='hess', base_div=b)
sage: G = J.group()
sage: p = C([-1,2,1]).place()
sage: G.point(p - b)
[Place (y + 2, z + 1)]

>>> from sage.all import *
>>> P2 = ProjectiveSpace(GF(Integer(17)), Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> b = C([Integer(0),Integer(1),Integer(0)]).place()
>>> J = C.jacobian(model='hess', base_div=b)
>>> G = J.group()
>>> p = C([-Integer(1),Integer(2),Integer(1)]).place()
>>> G.point(p - b)
[Place (y + 2, z + 1)]

zero()[source]#

Return the zero element of this group.

EXAMPLES:

sage: P2.<x,y,z> = ProjectiveSpace(GF(17), 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: b = C([0,1,0]).place()
sage: J = C.jacobian(model='hess', base_div=b)
sage: G = J.group()
sage: G.zero()
[Place (1/y, 1/y*z)]

>>> from sage.all import *
>>> P2 = ProjectiveSpace(GF(Integer(17)), Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> b = C([Integer(0),Integer(1),Integer(0)]).place()
>>> J = C.jacobian(model='hess', base_div=b)
>>> G = J.group()
>>> G.zero()
[Place (1/y, 1/y*z)]

class sage.rings.function_field.jacobian_hess.JacobianGroupEmbedding(base_group, extension_group)[source]#

Bases: Map

Embeddings between Jacobian groups.

INPUT:

• base_group – Jacobian group over a base field

• extension_group – Jacobian group over an extension field

EXAMPLES:

sage: k = GF(17)
sage: P2.<x,y,z> = ProjectiveSpace(k, 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: b = C([0,1,0]).place()
sage: J = C.jacobian(model='hess', base_div=b)
sage: G1 = J.group()
sage: K = k.extension(3)
sage: G3 = J.group(K)
sage: G3.coerce_map_from(G1)
Jacobian group embedding map:
From: Group of rational points of Jacobian
over Finite Field of size 17 (Hess model)
To:   Group of rational points of Jacobian
over Finite Field in z3 of size 17^3 (Hess model)

>>> from sage.all import *
>>> k = GF(Integer(17))
>>> P2 = ProjectiveSpace(k, Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> b = C([Integer(0),Integer(1),Integer(0)]).place()
>>> J = C.jacobian(model='hess', base_div=b)
>>> G1 = J.group()
>>> K = k.extension(Integer(3))
>>> G3 = J.group(K)
>>> G3.coerce_map_from(G1)
Jacobian group embedding map:
From: Group of rational points of Jacobian
over Finite Field of size 17 (Hess model)
To:   Group of rational points of Jacobian
over Finite Field in z3 of size 17^3 (Hess model)

class sage.rings.function_field.jacobian_hess.JacobianGroup_finite_field(parent, function_field, base_div)[source]#

Jacobian groups of function fields over finite fields

INPUT:

• parent – a Jacobian

• function_field – a function field

• base_div – an effective divisor of the function field

EXAMPLES:

sage: k = GF(17)
sage: P2.<x,y,z> = ProjectiveSpace(k, 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: b = C([0,1,0]).place()
sage: J = C.jacobian(model='hess', base_div=b)
sage: G1 = J.group()
sage: K = k.extension(3)
sage: G3 = J.group(K)
sage: G3.coerce_map_from(G1)
Jacobian group embedding map:
From: Group of rational points of Jacobian
over Finite Field of size 17 (Hess model)
To:   Group of rational points of Jacobian
over Finite Field in z3 of size 17^3 (Hess model)

>>> from sage.all import *
>>> k = GF(Integer(17))
>>> P2 = ProjectiveSpace(k, Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> b = C([Integer(0),Integer(1),Integer(0)]).place()
>>> J = C.jacobian(model='hess', base_div=b)
>>> G1 = J.group()
>>> K = k.extension(Integer(3))
>>> G3 = J.group(K)
>>> G3.coerce_map_from(G1)
Jacobian group embedding map:
From: Group of rational points of Jacobian
over Finite Field of size 17 (Hess model)
To:   Group of rational points of Jacobian
over Finite Field in z3 of size 17^3 (Hess model)

Element[source]#
class sage.rings.function_field.jacobian_hess.JacobianPoint(parent, dS, ds)[source]#

Points of Jacobians represented by a pair of ideals.

If a point of Jacobian is determined by $$D$$, then the divisor $$D$$ is represented by a pair of ideals in the finite maximal order and the infinite maximal order of the function field.

For efficiency reasons, the actual ideals stored are the inverted ideals of the ideals representing the divisor $$D$$.

INPUT:

• parent – Jacobian group

• dS – an ideal of the finite maximal order of a function field

• ds – an ideal of infinite maximal order of a function field

EXAMPLES:

sage: P2.<x,y,z> = ProjectiveSpace(GF(29), 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: b = C([0,1,0]).place()
sage: G = C.jacobian(model='hess', base_div=b).group()
sage: pl = C([1,8,1]).place()
sage: p = G.point(pl - b)
sage: dS, ds = p._data
sage: -(dS.divisor() + ds.divisor()) == pl
True

>>> from sage.all import *
>>> P2 = ProjectiveSpace(GF(Integer(29)), Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> b = C([Integer(0),Integer(1),Integer(0)]).place()
>>> G = C.jacobian(model='hess', base_div=b).group()
>>> pl = C([Integer(1),Integer(8),Integer(1)]).place()
>>> p = G.point(pl - b)
>>> dS, ds = p._data
>>> -(dS.divisor() + ds.divisor()) == pl
True


Return the addflip of this and other point.

EXAMPLES:

sage: P2.<x,y,z> = ProjectiveSpace(GF(29), 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: b = C([0,1,0]).place()
sage: G = C.jacobian(model='hess', base_div=b).group()
sage: pl1 = C([-1,2,1]).place()
sage: pl2 = C([2,19,1]).place()
sage: p1 = G.point(pl1 - b)
sage: p2 = G.point(pl2 - b)
[Place (y + 8, z + 27)]
sage: _ == -(p1 + p2)
True

>>> from sage.all import *
>>> P2 = ProjectiveSpace(GF(Integer(29)), Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> b = C([Integer(0),Integer(1),Integer(0)]).place()
>>> G = C.jacobian(model='hess', base_div=b).group()
>>> pl1 = C([-Integer(1),Integer(2),Integer(1)]).place()
>>> pl2 = C([Integer(2),Integer(19),Integer(1)]).place()
>>> p1 = G.point(pl1 - b)
>>> p2 = G.point(pl2 - b)
[Place (y + 8, z + 27)]
>>> _ == -(p1 + p2)
True

defining_divisor()[source]#

Return the effective divisor that defines this point.

EXAMPLES:

sage: P2.<x,y,z> = ProjectiveSpace(GF(29), 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: b = C([0,1,0]).place()
sage: G = C.jacobian(model='hess', base_div=b).group()
sage: pl = C([-1,2,1]).place()
sage: p = G.point(pl - b)
sage: p.defining_divisor() == pl
True

>>> from sage.all import *
>>> P2 = ProjectiveSpace(GF(Integer(29)), Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> b = C([Integer(0),Integer(1),Integer(0)]).place()
>>> G = C.jacobian(model='hess', base_div=b).group()
>>> pl = C([-Integer(1),Integer(2),Integer(1)]).place()
>>> p = G.point(pl - b)
>>> p.defining_divisor() == pl
True

divisor()[source]#

Return the divisor representing this point.

EXAMPLES:

sage: P2.<x,y,z> = ProjectiveSpace(GF(29), 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: b = C([0,1,0]).place()
sage: G = C.jacobian(model='hess', base_div=b).group()
sage: pl = C([-1,2,1]).place()
sage: p = G.point(pl - b)
sage: G.point(p.divisor()) == p
True

>>> from sage.all import *
>>> P2 = ProjectiveSpace(GF(Integer(29)), Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> b = C([Integer(0),Integer(1),Integer(0)]).place()
>>> G = C.jacobian(model='hess', base_div=b).group()
>>> pl = C([-Integer(1),Integer(2),Integer(1)]).place()
>>> p = G.point(pl - b)
>>> G.point(p.divisor()) == p
True

multiple(n)[source]#

Return the n-th multiple of this point.

EXAMPLES:

sage: P2.<x,y,z> = ProjectiveSpace(GF(29), 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: b = C([0,1,0]).place()
sage: G = C.jacobian(model='hess', base_div=b).group()
sage: pl = C([-1,2,1]).place()
sage: p = G.point(pl - b)
sage: p.multiple(100)
[Place (1/y, 1/y*z + 8)]

>>> from sage.all import *
>>> P2 = ProjectiveSpace(GF(Integer(29)), Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> b = C([Integer(0),Integer(1),Integer(0)]).place()
>>> G = C.jacobian(model='hess', base_div=b).group()
>>> pl = C([-Integer(1),Integer(2),Integer(1)]).place()
>>> p = G.point(pl - b)
>>> p.multiple(Integer(100))
[Place (1/y, 1/y*z + 8)]

order(bound=None)[source]#

Return the order of this point.

ALGORITHM: Shanks’ Baby Step Giant Step

EXAMPLES:

sage: P2.<x,y,z> = ProjectiveSpace(GF(29), 2)
sage: C = Curve(x^3 + 5*z^3 - y^2*z, P2)
sage: b = C([0,1,0]).place()
sage: G = C.jacobian(model='hess', base_div=b).group()
sage: p = C([-1,2,1]).place()
sage: pt = G.point(p - b)
sage: pt.order()
30

>>> from sage.all import *
>>> P2 = ProjectiveSpace(GF(Integer(29)), Integer(2), names=('x', 'y', 'z',)); (x, y, z,) = P2._first_ngens(3)
>>> C = Curve(x**Integer(3) + Integer(5)*z**Integer(3) - y**Integer(2)*z, P2)
>>> b = C([Integer(0),Integer(1),Integer(0)]).place()
>>> G = C.jacobian(model='hess', base_div=b).group()
>>> p = C([-Integer(1),Integer(2),Integer(1)]).place()
>>> pt = G.point(p - b)
>>> pt.order()
30

class sage.rings.function_field.jacobian_hess.JacobianPoint_finite_field(parent, dS, ds)[source]#

Points of Jacobians over finite fields