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]

Bases: Jacobian_base, UniqueRepresentation

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]

Bases: UniqueRepresentation, JacobianGroup_base

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]

Bases: JacobianGroup, JacobianGroup_finite_field_base

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]

alias of JacobianPoint_finite_field

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

Bases: JacobianPoint_base

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
addflip(other)[source]

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)
sage: p1.addflip(p2)
[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)
>>> p1.addflip(p2)
[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]

Bases: JacobianPoint, JacobianPoint_finite_field_base

Points of Jacobians over finite fields