Hyperelliptic curves (smooth model) over a finite field - Elliptic curves

Skip to content
Back to top
View this page
Edit this page

# Hyperelliptic curves (smooth model) over a finite field

AUTHORS:

- David Kohel (2006): initial version

- Robert Bradshaw (2007)

- Alyson Deines, Marina Gresham, Gagan Sekhon, (2010)

- Daniel Krenn (2011)

- Jean-Pierre Flori, Jan Tuitman (2013)

- Kiran Kedlaya (2016)

- Dean Bisogno (2017): Fixed Hasse-Witt computation

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

class sage.schemes.hyperelliptic_curves.hyperelliptic_finite_field.HyperellipticCurve_finite_field(projective_model, f, h, genus: Integer, names=['x', 'y'])

  Bases: `HyperellipticCurve_generic`

  Class of hyperelliptic curves (smooth model) over a finite field.

  EXAMPLES:

  Sage

      sage: R.<x> = GF(5)[]
      sage: H = HyperellipticCurve(x^8 + x^2 + 1); H
      Hyperelliptic Curve over Finite Field of size 5 defined by y^2 = x^8 + x^2 + 1
      sage: type(H)
      <class 'sage.schemes.hyperelliptic_curves.hyperelliptic_finite_field.HyperellipticCurve_finite_field_with_category'>

  Python

      >>> from sage.all import *
      >>> R = GF(Integer(5))['x']; (x,) = R._first_ngens(1)
      >>> H = HyperellipticCurve(x**Integer(8) + x**Integer(2) + Integer(1)); H
      Hyperelliptic Curve over Finite Field of size 5 defined by y^2 = x^8 + x^2 + 1
      >>> type(H)
      <class 'sage.schemes.hyperelliptic_curves.hyperelliptic_finite_field.HyperellipticCurve_finite_field_with_category'>

  Over finite fields, there are methods to construct random points on a hyperelliptic curve, find all rational points of the curve, or compute the cardinality over different field extensions:

  Sage

      sage: R.<x> = GF(7)[]
      sage: H = HyperellipticCurve(x^6 + x + 1)
      sage: H.random_point() # random
      (6 : 1 : 1)
      sage: H.rational_points()
      [(1 : 1 : 0),
       (1 : 6 : 0),
       (0 : 1 : 1),
       (0 : 6 : 1),
       (2 : 2 : 1),
       (2 : 5 : 1),
       (5 : 0 : 1),
       (6 : 1 : 1),
       (6 : 6 : 1)]
      sage: H.count_points(4)
      [9, 67, 339, 2443]

  [Python]

      >>> from sage.all import *
      >>> R = GF(Integer(7))['x']; (x,) = R._first_ngens(1)
      >>> H = HyperellipticCurve(x**Integer(6) + x + Integer(1))
      >>> H.random_point() # random
      (6 : 1 : 1)
      >>> H.rational_points()
      [(1 : 1 : 0),
       (1 : 6 : 0),
       (0 : 1 : 1),
       (0 : 6 : 1),
       (2 : 2 : 1),
       (2 : 5 : 1),
       (5 : 0 : 1),
       (6 : 1 : 1),
       (6 : 6 : 1)]
      >>> H.count_points(Integer(4))
      [9, 67, 339, 2443]

  These methods also work in characteristic 2 and 3:

  Sage

      sage: R.<x> = GF(4)[]
      sage: H = HyperellipticCurve(x^5+1, x^2+1)
      sage: H.rational_points()
      [(1 : 0 : 0), (0 : z2 : 1), (0 : z2 + 1 : 1), (1 : 0 : 1)]
      sage: H.count_points(4)
      [4, 24, 64, 288]

  Python

      >>> from sage.all import *
      >>> R = GF(Integer(4))['x']; (x,) = R._first_ngens(1)
      >>> H = HyperellipticCurve(x**Integer(5)+Integer(1), x**Integer(2)+Integer(1))
      >>> H.rational_points()
      [(1 : 0 : 0), (0 : z2 : 1), (0 : z2 + 1 : 1), (1 : 0 : 1)]
      >>> H.count_points(Integer(4))
      [4, 24, 64, 288]

  Cartier_matrix()

    Return the Cartier matrix of the hyperelliptic curve.

    INPUT:

    - `H` : Hyperelliptic Curve of the form \(y^2 = f(x)\) over a finite field, \(\GF{q}\)

    OUTPUT:

    - `M`: The matrix \(M = (c_{pi-j})\), where \(c_i\) are the coefficients of \(f(x)^{(p-1)/2} = \sum c_i x^i\)

    REFERENCES:

    14. Yui. On the Jacobian varieties of hyperelliptic curves over fields of characteristic \(p > 2\).

    EXAMPLES:

    Sage

        sage: K.<x> = GF(9,'x')[]
        sage: C = HyperellipticCurve(x^7 - 1, 0)
        sage: C.Cartier_matrix()
        [0 0 2]
        [0 0 0]
        [0 1 0]

        sage: K.<x> = GF(49, 'x')[]
        sage: C = HyperellipticCurve(x^5 + 1, 0)
        sage: C.Cartier_matrix()
        [0 3]
        [0 0]

        sage: P.<x> = GF(9, 'a')[]
        sage: E = HyperellipticCurve(x^29 + 1, 0)
        sage: E.Cartier_matrix()
        [0 0 1 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 1 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 1 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 1 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [1 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 1 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 1 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 1 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 1 0]

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(9),'x')['x']; (x,) = K._first_ngens(1)
        >>> C = HyperellipticCurve(x**Integer(7) - Integer(1), Integer(0))
        >>> C.Cartier_matrix()
        [0 0 2]
        [0 0 0]
        [0 1 0]

        >>> K = GF(Integer(49), 'x')['x']; (x,) = K._first_ngens(1)
        >>> C = HyperellipticCurve(x**Integer(5) + Integer(1), Integer(0))
        >>> C.Cartier_matrix()
        [0 3]
        [0 0]

        >>> P = GF(Integer(9), 'a')['x']; (x,) = P._first_ngens(1)
        >>> E = HyperellipticCurve(x**Integer(29) + Integer(1), Integer(0))
        >>> E.Cartier_matrix()
        [0 0 1 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 1 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 1 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 1 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [1 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 1 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 1 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 1 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 1 0]

  Hasse_Witt()

    Return the Hasse–Witt matrix of the hyperelliptic curve.

    INPUT:

    - `H` : Hyperelliptic Curve of the form \(y^2 = f(x)\) over a finite field, \(\GF{q}\)

    OUTPUT:

    - `N` : The matrix \(N = M M^p \dots M^{p^{g-1}}\) where \(M = c_{pi-j}\), and \(f(x)^{(p-1)/2} = \sum c_i x^i\)

    Reference-N. Yui. On the Jacobian varieties of hyperelliptic curves over fields of characteristic \(p > 2\).

    EXAMPLES:

    Sage

        sage: K.<x> = GF(9, 'x')[]
        sage: C = HyperellipticCurve(x^7 - 1, 0)
        sage: C.Hasse_Witt()
        [0 0 0]
        [0 0 0]
        [0 0 0]

        sage: K.<x> = GF(49, 'x')[]
        sage: C = HyperellipticCurve(x^5 + 1, 0)
        sage: C.Hasse_Witt()
        [0 0]
        [0 0]

        sage: P.<x> = GF(9, 'a')[]
        sage: E = HyperellipticCurve(x^29 + 1, 0)
        sage: E.Hasse_Witt()
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(9), 'x')['x']; (x,) = K._first_ngens(1)
        >>> C = HyperellipticCurve(x**Integer(7) - Integer(1), Integer(0))
        >>> C.Hasse_Witt()
        [0 0 0]
        [0 0 0]
        [0 0 0]

        >>> K = GF(Integer(49), 'x')['x']; (x,) = K._first_ngens(1)
        >>> C = HyperellipticCurve(x**Integer(5) + Integer(1), Integer(0))
        >>> C.Hasse_Witt()
        [0 0]
        [0 0]

        >>> P = GF(Integer(9), 'a')['x']; (x,) = P._first_ngens(1)
        >>> E = HyperellipticCurve(x**Integer(29) + Integer(1), Integer(0))
        >>> E.Hasse_Witt()
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]
        [0 0 0 0 0 0 0 0 0 0 0 0 0 0]

  a_number()

    Return the \(a\)-number of the hyperelliptic curve.

    INPUT:

    - `E`: Hyperelliptic Curve of the form \(y^2 = f(x)\) over a finite field, \(\GF{q}\)

    OUTPUT:

    - `a` : a-number

    EXAMPLES:

    Sage

        sage: K.<x> = GF(49, 'x')[]
        sage: C = HyperellipticCurve(x^5 + 1, 0)
        sage: C.a_number()
        1

        sage: K.<x> = GF(9, 'x')[]
        sage: C = HyperellipticCurve(x^7 - 1, 0)
        sage: C.a_number()
        1

        sage: P.<x> = GF(9, 'a')[]
        sage: E = HyperellipticCurve(x^29 + 1, 0)
        sage: E.a_number()
        5

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(49), 'x')['x']; (x,) = K._first_ngens(1)
        >>> C = HyperellipticCurve(x**Integer(5) + Integer(1), Integer(0))
        >>> C.a_number()
        1

        >>> K = GF(Integer(9), 'x')['x']; (x,) = K._first_ngens(1)
        >>> C = HyperellipticCurve(x**Integer(7) - Integer(1), Integer(0))
        >>> C.a_number()
        1

        >>> P = GF(Integer(9), 'a')['x']; (x,) = P._first_ngens(1)
        >>> E = HyperellipticCurve(x**Integer(29) + Integer(1), Integer(0))
        >>> E.a_number()
        5

  cardinality(extension_degree=1)

    Return the cardinality of the curve over an extension of degree `extension_degree`.

    INPUT:

    - `self` - Hyperelliptic Curve over a finite field, \(\GF{q}\)

    - `extensions_degree` - positive integer (default: `1``)

    OUTPUT:

    - The cardinality of `self` over an extension of degree `extension_degree`.

    EXAMPLES:

    Sage

        sage: K = GF(101)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^9 + 3*t^5 + 5)
        sage: H.cardinality()
        106
        sage: H.cardinality(15)
        1160968955369992567076405831000
        sage: H.cardinality(100)
        270481382942152609326719471080753083367793838278100277689020104911710151430673927943945601434674459120495370826289654897190781715493352266982697064575800553229661690000887425442240414673923744999504000

        sage: K = GF(37)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^9 + 3*t^5 + 5)
        sage: H.cardinality()
        40
        sage: H.cardinality(2)
        1408
        sage: H.cardinality(3)
        50116

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(101))
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(9) + Integer(3)*t**Integer(5) + Integer(5))
        >>> H.cardinality()
        106
        >>> H.cardinality(Integer(15))
        1160968955369992567076405831000
        >>> H.cardinality(Integer(100))
        270481382942152609326719471080753083367793838278100277689020104911710151430673927943945601434674459120495370826289654897190781715493352266982697064575800553229661690000887425442240414673923744999504000

        >>> K = GF(Integer(37))
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(9) + Integer(3)*t**Integer(5) + Integer(5))
        >>> H.cardinality()
        40
        >>> H.cardinality(Integer(2))
        1408
        >>> H.cardinality(Integer(3))
        50116

    The following example shows that Issue #20391 has been resolved:

    Sage

        sage: F=GF(23)
        sage: x=polygen(F)
        sage: C=HyperellipticCurve(x^8+1)
        sage: C.cardinality()
        24

    [Python]

        >>> from sage.all import *
        >>> F=GF(Integer(23))
        >>> x=polygen(F)
        >>> C=HyperellipticCurve(x**Integer(8)+Integer(1))
        >>> C.cardinality()
        24

  cardinality_exhaustive(extension_degree=1)

    Count points on a single extension of the base field by enumerating over x and solving the resulting quadratic equation for y.

    EXAMPLES:

    Sage

        sage: K.<a> = GF(9, 'a')
        sage: x = polygen(K)
        sage: C = HyperellipticCurve(x^7 - 1, x^2 + a)
        sage: C.cardinality_exhaustive()
        7

        sage: K = GF(next_prime(2**10))
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^7 + 3*t^5 + 5)
        sage: H.cardinality_exhaustive()
        1025

        sage: P.<x> = PolynomialRing(GF(9,'a'))
        sage: H = HyperellipticCurve(x^5+x^2+1)
        sage: H.count_points(5)
        [18, 78, 738, 6366, 60018]

        sage: F.<a> = GF(4); P.<x> = F[]
        sage: H = HyperellipticCurve(x^5+a*x^2+1, x+a+1)
        sage: H.count_points(6)
        [2, 24, 74, 256, 1082, 4272]

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(9), 'a', names=('a',)); (a,) = K._first_ngens(1)
        >>> x = polygen(K)
        >>> C = HyperellipticCurve(x**Integer(7) - Integer(1), x**Integer(2) + a)
        >>> C.cardinality_exhaustive()
        7

        >>> K = GF(next_prime(Integer(2)**Integer(10)))
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(7) + Integer(3)*t**Integer(5) + Integer(5))
        >>> H.cardinality_exhaustive()
        1025

        >>> P = PolynomialRing(GF(Integer(9),'a'), names=('x',)); (x,) = P._first_ngens(1)
        >>> H = HyperellipticCurve(x**Integer(5)+x**Integer(2)+Integer(1))
        >>> H.count_points(Integer(5))
        [18, 78, 738, 6366, 60018]

        >>> F = GF(Integer(4), names=('a',)); (a,) = F._first_ngens(1); P = F['x']; (x,) = P._first_ngens(1)
        >>> H = HyperellipticCurve(x**Integer(5)+a*x**Integer(2)+Integer(1), x+a+Integer(1))
        >>> H.count_points(Integer(6))
        [2, 24, 74, 256, 1082, 4272]

  cardinality_hypellfrob(extension_degree=1, algorithm=None)

    Count points on a single extension of the base field using the `hypellfrob` program.

    EXAMPLES:

    Sage

        sage: K = GF(next_prime(2**10))
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^7 + 3*t^5 + 5)
        sage: H.cardinality_hypellfrob()
        1025

        sage: K = GF(49999)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^7 + 3*t^5 + 5)
        sage: H.cardinality_hypellfrob()
        50162
        sage: H.cardinality_hypellfrob(3)
        124992471088310

    Python

        >>> from sage.all import *
        >>> K = GF(next_prime(Integer(2)**Integer(10)))
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(7) + Integer(3)*t**Integer(5) + Integer(5))
        >>> H.cardinality_hypellfrob()
        1025

        >>> K = GF(Integer(49999))
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(7) + Integer(3)*t**Integer(5) + Integer(5))
        >>> H.cardinality_hypellfrob()
        50162
        >>> H.cardinality_hypellfrob(Integer(3))
        124992471088310

  count_points(n=1)

    Count points over finite fields.

    INPUT:

    - `n` – integer.

    OUTPUT:

    An integer. The number of points over \(\GF{q}, \ldots, \GF{q^n}\) on a hyperelliptic curve over a finite field \(\GF{q}\).

    Warning

    This is currently using exhaustive search for hyperelliptic curves over non-prime fields, which can be awfully slow.

    EXAMPLES:

    Sage

        sage: P.<x> = PolynomialRing(GF(3))
        sage: C = HyperellipticCurve(x^3+x^2+1)
        sage: C.count_points(4)
        [6, 12, 18, 96]
        sage: C.base_extend(GF(9,'a')).count_points(2)
        [12, 96]

        sage: K = GF(2**31-1)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^5 + 3*t + 5)
        sage: H.count_points() # long time, 2.4 sec on a Corei7
        [2147464821]
        sage: H.count_points(n=2) # long time, 30s on a Corei7
        [2147464821, 4611686018988310237]

        sage: K = GF(2**7-1)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^13 + 3*t^5 + 5)
        sage: H.count_points(n=6)
        [112, 16360, 2045356, 260199160, 33038302802, 4195868633548]

        sage: P.<x> = PolynomialRing(GF(3))
        sage: H = HyperellipticCurve(x^3+x^2+1)
        sage: C1 = H.count_points(4); C1
        [6, 12, 18, 96]
        sage: C2 = sage.schemes.generic.scheme.Scheme.count_points(H,4); C2 # long time, 2s on a Corei7
        [6, 12, 18, 96]
        sage: C1 == C2 # long time, because we need C2 to be defined
        True

        sage: P.<x> = PolynomialRing(GF(9,'a'))
        sage: H = HyperellipticCurve(x^5+x^2+1)
        sage: H.count_points(5)
        [18, 78, 738, 6366, 60018]

        sage: F.<a> = GF(4); P.<x> = F[]
        sage: H = HyperellipticCurve(x^5+a*x^2+1, x+a+1)
        sage: H.count_points(6)
        [2, 24, 74, 256, 1082, 4272]

    Python

        >>> from sage.all import *
        >>> P = PolynomialRing(GF(Integer(3)), names=('x',)); (x,) = P._first_ngens(1)
        >>> C = HyperellipticCurve(x**Integer(3)+x**Integer(2)+Integer(1))
        >>> C.count_points(Integer(4))
        [6, 12, 18, 96]
        >>> C.base_extend(GF(Integer(9),'a')).count_points(Integer(2))
        [12, 96]

        >>> K = GF(Integer(2)**Integer(31)-Integer(1))
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(5) + Integer(3)*t + Integer(5))
        >>> H.count_points() # long time, 2.4 sec on a Corei7
        [2147464821]
        >>> H.count_points(n=Integer(2)) # long time, 30s on a Corei7
        [2147464821, 4611686018988310237]

        >>> K = GF(Integer(2)**Integer(7)-Integer(1))
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(13) + Integer(3)*t**Integer(5) + Integer(5))
        >>> H.count_points(n=Integer(6))
        [112, 16360, 2045356, 260199160, 33038302802, 4195868633548]

        >>> P = PolynomialRing(GF(Integer(3)), names=('x',)); (x,) = P._first_ngens(1)
        >>> H = HyperellipticCurve(x**Integer(3)+x**Integer(2)+Integer(1))
        >>> C1 = H.count_points(Integer(4)); C1
        [6, 12, 18, 96]
        >>> C2 = sage.schemes.generic.scheme.Scheme.count_points(H,Integer(4)); C2 # long time, 2s on a Corei7
        [6, 12, 18, 96]
        >>> C1 == C2 # long time, because we need C2 to be defined
        True

        >>> P = PolynomialRing(GF(Integer(9),'a'), names=('x',)); (x,) = P._first_ngens(1)
        >>> H = HyperellipticCurve(x**Integer(5)+x**Integer(2)+Integer(1))
        >>> H.count_points(Integer(5))
        [18, 78, 738, 6366, 60018]

        >>> F = GF(Integer(4), names=('a',)); (a,) = F._first_ngens(1); P = F['x']; (x,) = P._first_ngens(1)
        >>> H = HyperellipticCurve(x**Integer(5)+a*x**Integer(2)+Integer(1), x+a+Integer(1))
        >>> H.count_points(Integer(6))
        [2, 24, 74, 256, 1082, 4272]

    This example shows that Issue #20391 is resolved:

    Sage

        sage: x = polygen(GF(4099))
        sage: H = HyperellipticCurve(x^6 + x + 1)
        sage: H.count_points(1)
        [4106]

    [Python]

        >>> from sage.all import *
        >>> x = polygen(GF(Integer(4099)))
        >>> H = HyperellipticCurve(x**Integer(6) + x + Integer(1))
        >>> H.count_points(Integer(1))
        [4106]

  count_points_exhaustive(n=1, naive=False)

    Count the number of points on the curve over the first \(n\) extensions of the base field by exhaustive search if \(n\) if smaller than \(g\), the genus of the curve, and by computing the frobenius polynomial after performing exhaustive search on the first \(g\) extensions if \(n > g\) (unless `naive == True`).

    EXAMPLES:

    Sage

        sage: K = GF(5)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^9 + t^3 + 1)
        sage: H.count_points_exhaustive(n=5)
        [9, 27, 108, 675, 3069]

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(5))
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(9) + t**Integer(3) + Integer(1))
        >>> H.count_points_exhaustive(n=Integer(5))
        [9, 27, 108, 675, 3069]

    When \(n > g\), the frobenius polynomial is computed from the numbers of points of the curve over the first \(g\) extension, so that computing the number of points on extensions of degree \(n > g\) is not much more expensive than for \(n == g\):

    Sage

        sage: H.count_points_exhaustive(n=15)
        [9,
        27,
        108,
        675,
        3069,
        16302,
        78633,
        389475,
        1954044,
        9768627,
        48814533,
        244072650,
        1220693769,
        6103414827,
        30517927308]

    [Python]

        >>> from sage.all import *
        >>> H.count_points_exhaustive(n=Integer(15))
        [9,
        27,
        108,
        675,
        3069,
        16302,
        78633,
        389475,
        1954044,
        9768627,
        48814533,
        244072650,
        1220693769,
        6103414827,
        30517927308]

    This behavior can be disabled by passing `naive=True`:

    Sage

        sage: H.count_points_exhaustive(n=6, naive=True) # long time, 7s on a Corei7
        [9, 27, 108, 675, 3069, 16302]

    Python

        >>> from sage.all import *
        >>> H.count_points_exhaustive(n=Integer(6), naive=True) # long time, 7s on a Corei7
        [9, 27, 108, 675, 3069, 16302]

  count_points_frobenius_polynomial(n=1, f=None)

    Count the number of points on the curve over the first \(n\) extensions of the base field by computing the frobenius polynomial.

    EXAMPLES:

    Sage

        sage: K = GF(49999)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^19 + t + 1)

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(49999))
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(19) + t + Integer(1))

    The following computation takes a long time as the complete characteristic polynomial of the frobenius is computed:

    Sage

        sage: H.count_points_frobenius_polynomial(3) # long time, 20s on a Corei7 (when computed before the following test of course)
        [49491, 2500024375, 124992509154249]

    [Python]

        >>> from sage.all import *
        >>> H.count_points_frobenius_polynomial(Integer(3)) # long time, 20s on a Corei7 (when computed before the following test of course)
        [49491, 2500024375, 124992509154249]

    As the polynomial is cached, further computations of number of points are really fast:

    Sage

        sage: H.count_points_frobenius_polynomial(19) # long time, because of the previous test
        [49491,
        2500024375,
        124992509154249,
        6249500007135192947,
        312468751250758776051811,
        15623125093747382662737313867,
        781140631562281338861289572576257,
        39056250437482500417107992413002794587,
        1952773465623687539373429411200893147181079,
        97636720507718753281169963459063147221761552935,
        4881738388665429945305281187129778704058864736771824,
        244082037694882831835318764490138139735446240036293092851,
        12203857802706446708934102903106811520015567632046432103159713,
        610180686277519628999996211052002771035439565767719719151141201339,
        30508424133189703930370810556389262704405225546438978173388673620145499,
        1525390698235352006814610157008906752699329454643826047826098161898351623931,
        76268009521069364988723693240288328729528917832735078791261015331201838856825193,
        3813324208043947180071195938321176148147244128062172555558715783649006587868272993991,
        190662397077989315056379725720120486231213267083935859751911720230901597698389839098903847]

    Python

        >>> from sage.all import *
        >>> H.count_points_frobenius_polynomial(Integer(19)) # long time, because of the previous test
        [49491,
        2500024375,
        124992509154249,
        6249500007135192947,
        312468751250758776051811,
        15623125093747382662737313867,
        781140631562281338861289572576257,
        39056250437482500417107992413002794587,
        1952773465623687539373429411200893147181079,
        97636720507718753281169963459063147221761552935,
        4881738388665429945305281187129778704058864736771824,
        244082037694882831835318764490138139735446240036293092851,
        12203857802706446708934102903106811520015567632046432103159713,
        610180686277519628999996211052002771035439565767719719151141201339,
        30508424133189703930370810556389262704405225546438978173388673620145499,
        1525390698235352006814610157008906752699329454643826047826098161898351623931,
        76268009521069364988723693240288328729528917832735078791261015331201838856825193,
        3813324208043947180071195938321176148147244128062172555558715783649006587868272993991,
        190662397077989315056379725720120486231213267083935859751911720230901597698389839098903847]

  count_points_hypellfrob(n=1, N=None, algorithm=None)

    Count the number of points on the curve over the first \(n\) extensions of the base field using the `hypellfrob` program.

    This only supports prime fields of large enough characteristic.

    EXAMPLES:

    Sage

        sage: K = GF(49999)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^21 + 3*t^5 + 5)
        sage: H.count_points_hypellfrob()
        [49804]
        sage: H.count_points_hypellfrob(2)
        [49804, 2499799038]

        sage: K = GF(2**7-1)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^11 + 3*t^5 + 5)
        sage: H.count_points_hypellfrob()
        [127]
        sage: H.count_points_hypellfrob(n=5)
        [127, 16335, 2045701, 260134299, 33038098487]

        sage: K = GF(2**7-1)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^13 + 3*t^5 + 5)
        sage: H.count_points(n=6)
        [112, 16360, 2045356, 260199160, 33038302802, 4195868633548]

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(49999))
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(21) + Integer(3)*t**Integer(5) + Integer(5))
        >>> H.count_points_hypellfrob()
        [49804]
        >>> H.count_points_hypellfrob(Integer(2))
        [49804, 2499799038]

        >>> K = GF(Integer(2)**Integer(7)-Integer(1))
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(11) + Integer(3)*t**Integer(5) + Integer(5))
        >>> H.count_points_hypellfrob()
        [127]
        >>> H.count_points_hypellfrob(n=Integer(5))
        [127, 16335, 2045701, 260134299, 33038098487]

        >>> K = GF(Integer(2)**Integer(7)-Integer(1))
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(13) + Integer(3)*t**Integer(5) + Integer(5))
        >>> H.count_points(n=Integer(6))
        [112, 16360, 2045356, 260199160, 33038302802, 4195868633548]

    The base field should be prime:

    Sage

        sage: K.<z> = GF(19**10)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^9 + (z+1)*t^5 + 1)
        sage: H.count_points_hypellfrob()
        Traceback (most recent call last):
        ...
        ValueError: hypellfrob does not support non-prime fields

    [Python]

        >>> from sage.all import *
        >>> K = GF(Integer(19)**Integer(10), names=('z',)); (z,) = K._first_ngens(1)
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(9) + (z+Integer(1))*t**Integer(5) + Integer(1))
        >>> H.count_points_hypellfrob()
        Traceback (most recent call last):
        ...
        ValueError: hypellfrob does not support non-prime fields

    and the characteristic should be large enough:

    Sage

        sage: K = GF(7)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^9 + t^3 + 1)
        sage: H.count_points_hypellfrob()
        Traceback (most recent call last):
        ...
        ValueError: p=7 should be greater than (2*g+1)(2*N-1)=27

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(7))
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(9) + t**Integer(3) + Integer(1))
        >>> H.count_points_hypellfrob()
        Traceback (most recent call last):
        ...
        ValueError: p=7 should be greater than (2*g+1)(2*N-1)=27

  count_points_matrix_traces(n=1, M=None, N=None)

    Count the number of points on the curve over the first \(n\) extensions of the base field by computing traces of powers of the frobenius matrix. This requires less \(p\)-adic precision than computing the charpoly of the matrix when \(n < g\) where \(g\) is the genus of the curve.

    EXAMPLES:

    Sage

        sage: K = GF(49999)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^19 + t + 1)
        sage: H.count_points_matrix_traces(3)
        [49491, 2500024375, 124992509154249]

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(49999))
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(19) + t + Integer(1))
        >>> H.count_points_matrix_traces(Integer(3))
        [49491, 2500024375, 124992509154249]

  frobenius_matrix(N=None, algorithm='hypellfrob')

    Compute \(p\)-adic frobenius matrix to precision \(p^N\). If \(N\) not supplied, a default value is selected, which is the minimum needed to recover the charpoly unambiguously.

    Note

    Currently only implemented using `hypellfrob`, which means it only works over the prime field \(GF(p)\), and requires \(p > (2g+1)(2N-1)\).

    EXAMPLES:

    Sage

        sage: R.<t> = PolynomialRing(GF(37))
        sage: H = HyperellipticCurve(t^5 + t + 2)
        sage: H.frobenius_matrix()
        [1258 + O(37^2)  925 + O(37^2)  132 + O(37^2)  587 + O(37^2)]
        [1147 + O(37^2)  814 + O(37^2)  241 + O(37^2) 1011 + O(37^2)]
        [1258 + O(37^2) 1184 + O(37^2) 1105 + O(37^2)  482 + O(37^2)]
        [1073 + O(37^2)  999 + O(37^2)  772 + O(37^2)  929 + O(37^2)]

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(GF(Integer(37)), names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(5) + t + Integer(2))
        >>> H.frobenius_matrix()
        [1258 + O(37^2)  925 + O(37^2)  132 + O(37^2)  587 + O(37^2)]
        [1147 + O(37^2)  814 + O(37^2)  241 + O(37^2) 1011 + O(37^2)]
        [1258 + O(37^2) 1184 + O(37^2) 1105 + O(37^2)  482 + O(37^2)]
        [1073 + O(37^2)  999 + O(37^2)  772 + O(37^2)  929 + O(37^2)]

    The `hypellfrob` program doesn’t support non-prime fields:

    Sage

        sage: K.<z> = GF(37**3)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^9 + z*t^3 + 1)
        sage: H.frobenius_matrix(algorithm='hypellfrob')
        Traceback (most recent call last):
        ...
        NotImplementedError: Computation of Frobenius matrix only implemented
        for hyperelliptic curves defined over prime fields.

    [Python]

        >>> from sage.all import *
        >>> K = GF(Integer(37)**Integer(3), names=('z',)); (z,) = K._first_ngens(1)
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(9) + z*t**Integer(3) + Integer(1))
        >>> H.frobenius_matrix(algorithm='hypellfrob')
        Traceback (most recent call last):
        ...
        NotImplementedError: Computation of Frobenius matrix only implemented
        for hyperelliptic curves defined over prime fields.

    nor too small characteristic:

    Sage

        sage: K = GF(7)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^9 + t^3 + 1)
        sage: H.frobenius_matrix(algorithm='hypellfrob')
        Traceback (most recent call last):
        ...
        ValueError: In the current implementation, p must be greater than (2g+1)(2N-1) = 81

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(7))
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(9) + t**Integer(3) + Integer(1))
        >>> H.frobenius_matrix(algorithm='hypellfrob')
        Traceback (most recent call last):
        ...
        ValueError: In the current implementation, p must be greater than (2g+1)(2N-1) = 81

  frobenius_matrix_hypellfrob(N=None)

    Compute \(p\)-adic frobenius matrix to precision \(p^N\). If \(N\) not supplied, a default value is selected, which is the minimum needed to recover the charpoly unambiguously.

    Note

    Implemented using `hypellfrob`, which means it only works over the prime field \(GF(p)\), and requires \(p > (2g+1)(2N-1)\).

    EXAMPLES:

    Sage

        sage: R.<t> = PolynomialRing(GF(37))
        sage: H = HyperellipticCurve(t^5 + t + 2)
        sage: H.frobenius_matrix_hypellfrob()
        [1258 + O(37^2)  925 + O(37^2)  132 + O(37^2)  587 + O(37^2)]
        [1147 + O(37^2)  814 + O(37^2)  241 + O(37^2) 1011 + O(37^2)]
        [1258 + O(37^2) 1184 + O(37^2) 1105 + O(37^2)  482 + O(37^2)]
        [1073 + O(37^2)  999 + O(37^2)  772 + O(37^2)  929 + O(37^2)]

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(GF(Integer(37)), names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(5) + t + Integer(2))
        >>> H.frobenius_matrix_hypellfrob()
        [1258 + O(37^2)  925 + O(37^2)  132 + O(37^2)  587 + O(37^2)]
        [1147 + O(37^2)  814 + O(37^2)  241 + O(37^2) 1011 + O(37^2)]
        [1258 + O(37^2) 1184 + O(37^2) 1105 + O(37^2)  482 + O(37^2)]
        [1073 + O(37^2)  999 + O(37^2)  772 + O(37^2)  929 + O(37^2)]

    The `hypellfrob` program doesn’t support non-prime fields:

    Sage

        sage: K.<z> = GF(37**3)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^9 + z*t^3 + 1)
        sage: H.frobenius_matrix_hypellfrob()
        Traceback (most recent call last):
        ...
        NotImplementedError: Computation of Frobenius matrix only implemented
        for hyperelliptic curves defined over prime fields.

    [Python]

        >>> from sage.all import *
        >>> K = GF(Integer(37)**Integer(3), names=('z',)); (z,) = K._first_ngens(1)
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(9) + z*t**Integer(3) + Integer(1))
        >>> H.frobenius_matrix_hypellfrob()
        Traceback (most recent call last):
        ...
        NotImplementedError: Computation of Frobenius matrix only implemented
        for hyperelliptic curves defined over prime fields.

    nor too small characteristic:

    Sage

        sage: K = GF(7)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^9 + t^3 + 1)
        sage: H.frobenius_matrix_hypellfrob()
        Traceback (most recent call last):
        ...
        ValueError: In the current implementation, p must be greater than (2g+1)(2N-1) = 81

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(7))
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(9) + t**Integer(3) + Integer(1))
        >>> H.frobenius_matrix_hypellfrob()
        Traceback (most recent call last):
        ...
        ValueError: In the current implementation, p must be greater than (2g+1)(2N-1) = 81

  frobenius_polynomial()

    Compute the charpoly of frobenius, as an element of \(\ZZ[x]\).

    EXAMPLES:

    Sage

        sage: R.<t> = PolynomialRing(GF(37))
        sage: H = HyperellipticCurve(t^5 + t + 2)
        sage: H.frobenius_polynomial()
        x^4 + x^3 - 52*x^2 + 37*x + 1369

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(GF(Integer(37)), names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(5) + t + Integer(2))
        >>> H.frobenius_polynomial()
        x^4 + x^3 - 52*x^2 + 37*x + 1369

    A quadratic twist:

    Sage

        sage: H = HyperellipticCurve(2*t^5 + 2*t + 4)
        sage: H.frobenius_polynomial()
        x^4 - x^3 - 52*x^2 - 37*x + 1369

    [Python]

        >>> from sage.all import *
        >>> H = HyperellipticCurve(Integer(2)*t**Integer(5) + Integer(2)*t + Integer(4))
        >>> H.frobenius_polynomial()
        x^4 - x^3 - 52*x^2 - 37*x + 1369

    Slightly larger example:

    Sage

        sage: K = GF(2003)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^7 + 487*t^5 + 9*t + 1)
        sage: H.frobenius_polynomial()
        x^6 - 14*x^5 + 1512*x^4 - 66290*x^3 + 3028536*x^2 - 56168126*x + 8036054027

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(2003))
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(7) + Integer(487)*t**Integer(5) + Integer(9)*t + Integer(1))
        >>> H.frobenius_polynomial()
        x^6 - 14*x^5 + 1512*x^4 - 66290*x^3 + 3028536*x^2 - 56168126*x + 8036054027

    Curves defined over a non-prime field of odd characteristic, or an odd prime field which is too small compared to the genus, are supported via PARI:

    Sage

        sage: K.<z> = GF(23**3)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^3 + z*t + 4)
        sage: H.frobenius_polynomial()
        x^2 - 15*x + 12167

        sage: K.<z> = GF(3**3)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^5 + z*t + z**3)
        sage: H.frobenius_polynomial()
        x^4 - 3*x^3 + 10*x^2 - 81*x + 729

    [Python]

        >>> from sage.all import *
        >>> K = GF(Integer(23)**Integer(3), names=('z',)); (z,) = K._first_ngens(1)
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(3) + z*t + Integer(4))
        >>> H.frobenius_polynomial()
        x^2 - 15*x + 12167

        >>> K = GF(Integer(3)**Integer(3), names=('z',)); (z,) = K._first_ngens(1)
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(5) + z*t + z**Integer(3))
        >>> H.frobenius_polynomial()
        x^4 - 3*x^3 + 10*x^2 - 81*x + 729

    Over prime fields of odd characteristic, \(h\) may be non-zero:

    Sage

        sage: K = GF(101)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^5 + 27*t + 3, t)
        sage: H.frobenius_polynomial()
        x^4 + 2*x^3 - 58*x^2 + 202*x + 10201

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(101))
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(5) + Integer(27)*t + Integer(3), t)
        >>> H.frobenius_polynomial()
        x^4 + 2*x^3 - 58*x^2 + 202*x + 10201

    Over prime fields of odd characteristic, \(f\) may have even degree:

    Sage

        sage: H = HyperellipticCurve(t^6 + 27*t + 3)
        sage: H.frobenius_polynomial()
        x^4 + 25*x^3 + 322*x^2 + 2525*x + 10201

    [Python]

        >>> from sage.all import *
        >>> H = HyperellipticCurve(t**Integer(6) + Integer(27)*t + Integer(3))
        >>> H.frobenius_polynomial()
        x^4 + 25*x^3 + 322*x^2 + 2525*x + 10201

    In even characteristic, the naive algorithm could cover all cases because we can easily check for squareness in quotient rings of polynomial rings over finite fields but these rings unfortunately do not support iteration:

    Sage

        sage: K.<z> = GF(2**5)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^5 + z*t + z**3, t)
        sage: H.frobenius_polynomial()
        x^4 - x^3 + 16*x^2 - 32*x + 1024

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(2)**Integer(5), names=('z',)); (z,) = K._first_ngens(1)
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(5) + z*t + z**Integer(3), t)
        >>> H.frobenius_polynomial()
        x^4 - x^3 + 16*x^2 - 32*x + 1024

  frobenius_polynomial_cardinalities(a=None)

    Compute the charpoly of frobenius, as an element of \(\ZZ[x]\), by computing the number of points on the curve over \(g\) extensions of the base field where \(g\) is the genus of the curve.

    Warning

    This is highly inefficient when the base field or the genus of the curve are large.

    EXAMPLES:

    Sage

        sage: R.<t> = PolynomialRing(GF(37))
        sage: H = HyperellipticCurve(t^5 + t + 2)
        sage: H.frobenius_polynomial_cardinalities()
        x^4 + x^3 - 52*x^2 + 37*x + 1369

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(GF(Integer(37)), names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(5) + t + Integer(2))
        >>> H.frobenius_polynomial_cardinalities()
        x^4 + x^3 - 52*x^2 + 37*x + 1369

    A quadratic twist:

    Sage

        sage: H = HyperellipticCurve(2*t^5 + 2*t + 4)
        sage: H.frobenius_polynomial_cardinalities()
        x^4 - x^3 - 52*x^2 - 37*x + 1369

    [Python]

        >>> from sage.all import *
        >>> H = HyperellipticCurve(Integer(2)*t**Integer(5) + Integer(2)*t + Integer(4))
        >>> H.frobenius_polynomial_cardinalities()
        x^4 - x^3 - 52*x^2 - 37*x + 1369

    Curve over a non-prime field:

    Sage

        sage: K.<z> = GF(7**2)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^5 + z*t + z^2)
        sage: H.frobenius_polynomial_cardinalities()
        x^4 + 8*x^3 + 70*x^2 + 392*x + 2401

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(7)**Integer(2), names=('z',)); (z,) = K._first_ngens(1)
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(5) + z*t + z**Integer(2))
        >>> H.frobenius_polynomial_cardinalities()
        x^4 + 8*x^3 + 70*x^2 + 392*x + 2401

    This method may actually be useful when `hypellfrob` does not work:

    Sage

        sage: K = GF(7)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^9 + t^3 + 1)
        sage: H.frobenius_polynomial_matrix(algorithm='hypellfrob')
        Traceback (most recent call last):
        ...
        ValueError: In the current implementation, p must be greater than (2g+1)(2N-1) = 81
        sage: H.frobenius_polynomial_cardinalities()
        x^8 - 5*x^7 + 7*x^6 + 36*x^5 - 180*x^4 + 252*x^3 + 343*x^2 - 1715*x + 2401

    [Python]

        >>> from sage.all import *
        >>> K = GF(Integer(7))
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(9) + t**Integer(3) + Integer(1))
        >>> H.frobenius_polynomial_matrix(algorithm='hypellfrob')
        Traceback (most recent call last):
        ...
        ValueError: In the current implementation, p must be greater than (2g+1)(2N-1) = 81
        >>> H.frobenius_polynomial_cardinalities()
        x^8 - 5*x^7 + 7*x^6 + 36*x^5 - 180*x^4 + 252*x^3 + 343*x^2 - 1715*x + 2401

  frobenius_polynomial_matrix(M=None, algorithm='hypellfrob')

    Compute the charpoly of frobenius, as an element of \(\ZZ[x]\), by computing the charpoly of the frobenius matrix.

    This is currently only supported when the base field is prime and large enough using the `hypellfrob` library.

    EXAMPLES:

    Sage

        sage: R.<t> = PolynomialRing(GF(37))
        sage: H = HyperellipticCurve(t^5 + t + 2)
        sage: H.frobenius_polynomial_matrix()
        x^4 + x^3 - 52*x^2 + 37*x + 1369

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(GF(Integer(37)), names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(5) + t + Integer(2))
        >>> H.frobenius_polynomial_matrix()
        x^4 + x^3 - 52*x^2 + 37*x + 1369

    A quadratic twist:

    Sage

        sage: H = HyperellipticCurve(2*t^5 + 2*t + 4)
        sage: H.frobenius_polynomial_matrix()
        x^4 - x^3 - 52*x^2 - 37*x + 1369

    [Python]

        >>> from sage.all import *
        >>> H = HyperellipticCurve(Integer(2)*t**Integer(5) + Integer(2)*t + Integer(4))
        >>> H.frobenius_polynomial_matrix()
        x^4 - x^3 - 52*x^2 - 37*x + 1369

    Curves defined over larger prime fields:

    Sage

        sage: K = GF(49999)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^9 + t^5 + 1)
        sage: H.frobenius_polynomial_matrix()
        x^8 + 281*x^7 + 55939*x^6 + 14144175*x^5 + 3156455369*x^4 + 707194605825*x^3
        + 139841906155939*x^2 + 35122892542149719*x + 6249500014999800001
        sage: H = HyperellipticCurve(t^15 + t^5 + 1)
        sage: H.frobenius_polynomial_matrix()  # long time, 8s on a Corei7
        x^14 - 76*x^13 + 220846*x^12 - 12984372*x^11 + 24374326657*x^10 - 1203243210304*x^9
        + 1770558798515792*x^8 - 74401511415210496*x^7 + 88526169366991084208*x^6
        - 3007987702642212810304*x^5 + 3046608028331197124223343*x^4
        - 81145833008762983138584372*x^3 + 69007473838551978905211279154*x^2
        - 1187357507124810002849977200076*x + 781140631562281254374947500349999

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(49999))
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(9) + t**Integer(5) + Integer(1))
        >>> H.frobenius_polynomial_matrix()
        x^8 + 281*x^7 + 55939*x^6 + 14144175*x^5 + 3156455369*x^4 + 707194605825*x^3
        + 139841906155939*x^2 + 35122892542149719*x + 6249500014999800001
        >>> H = HyperellipticCurve(t**Integer(15) + t**Integer(5) + Integer(1))
        >>> H.frobenius_polynomial_matrix()  # long time, 8s on a Corei7
        x^14 - 76*x^13 + 220846*x^12 - 12984372*x^11 + 24374326657*x^10 - 1203243210304*x^9
        + 1770558798515792*x^8 - 74401511415210496*x^7 + 88526169366991084208*x^6
        - 3007987702642212810304*x^5 + 3046608028331197124223343*x^4
        - 81145833008762983138584372*x^3 + 69007473838551978905211279154*x^2
        - 1187357507124810002849977200076*x + 781140631562281254374947500349999

    This `hypellfrob` program doesn’t support non-prime fields:

    Sage

        sage: K.<z> = GF(37**3)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^9 + z*t^3 + 1)
        sage: H.frobenius_polynomial_matrix(algorithm='hypellfrob')
        Traceback (most recent call last):
        ...
        NotImplementedError: Computation of Frobenius matrix only implemented
        for hyperelliptic curves defined over prime fields.

    [Python]

        >>> from sage.all import *
        >>> K = GF(Integer(37)**Integer(3), names=('z',)); (z,) = K._first_ngens(1)
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(9) + z*t**Integer(3) + Integer(1))
        >>> H.frobenius_polynomial_matrix(algorithm='hypellfrob')
        Traceback (most recent call last):
        ...
        NotImplementedError: Computation of Frobenius matrix only implemented
        for hyperelliptic curves defined over prime fields.

  frobenius_polynomial_pari()

    Compute the charpoly of frobenius, as an element of \(\ZZ[x]\), by calling the PARI function `hyperellcharpoly`.

    EXAMPLES:

    Sage

        sage: R.<t> = PolynomialRing(GF(37))
        sage: H = HyperellipticCurve(t^5 + t + 2)
        sage: H.frobenius_polynomial_pari()
        x^4 + x^3 - 52*x^2 + 37*x + 1369

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(GF(Integer(37)), names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(5) + t + Integer(2))
        >>> H.frobenius_polynomial_pari()
        x^4 + x^3 - 52*x^2 + 37*x + 1369

    A quadratic twist:

    Sage

        sage: H = HyperellipticCurve(2*t^5 + 2*t + 4)
        sage: H.frobenius_polynomial_pari()
        x^4 - x^3 - 52*x^2 - 37*x + 1369

    [Python]

        >>> from sage.all import *
        >>> H = HyperellipticCurve(Integer(2)*t**Integer(5) + Integer(2)*t + Integer(4))
        >>> H.frobenius_polynomial_pari()
        x^4 - x^3 - 52*x^2 - 37*x + 1369

    Slightly larger example:

    Sage

        sage: K = GF(2003)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^7 + 487*t^5 + 9*t + 1)
        sage: H.frobenius_polynomial_pari()
        x^6 - 14*x^5 + 1512*x^4 - 66290*x^3 + 3028536*x^2 - 56168126*x + 8036054027

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(2003))
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(7) + Integer(487)*t**Integer(5) + Integer(9)*t + Integer(1))
        >>> H.frobenius_polynomial_pari()
        x^6 - 14*x^5 + 1512*x^4 - 66290*x^3 + 3028536*x^2 - 56168126*x + 8036054027

    Curves defined over a non-prime field are supported as well:

    Sage

        sage: K.<a> = GF(7^2)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^5 + a*t + 1)
        sage: H.frobenius_polynomial_pari()
        x^4 + 4*x^3 + 84*x^2 + 196*x + 2401

        sage: K.<z> = GF(23**3)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^3 + z*t + 4)
        sage: H.frobenius_polynomial_pari()
        x^2 - 15*x + 12167

    [Python]

        >>> from sage.all import *
        >>> K = GF(Integer(7)**Integer(2), names=('a',)); (a,) = K._first_ngens(1)
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(5) + a*t + Integer(1))
        >>> H.frobenius_polynomial_pari()
        x^4 + 4*x^3 + 84*x^2 + 196*x + 2401

        >>> K = GF(Integer(23)**Integer(3), names=('z',)); (z,) = K._first_ngens(1)
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(3) + z*t + Integer(4))
        >>> H.frobenius_polynomial_pari()
        x^2 - 15*x + 12167

    Over prime fields of odd characteristic, \(h\) may be non-zero:

    Sage

        sage: K = GF(101)
        sage: R.<t> = PolynomialRing(K)
        sage: H = HyperellipticCurve(t^5 + 27*t + 3, t)
        sage: H.frobenius_polynomial_pari()
        x^4 + 2*x^3 - 58*x^2 + 202*x + 10201

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(101))
        >>> R = PolynomialRing(K, names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(5) + Integer(27)*t + Integer(3), t)
        >>> H.frobenius_polynomial_pari()
        x^4 + 2*x^3 - 58*x^2 + 202*x + 10201

  p_rank()

    Return the \(p\)-rank of the hyperelliptic curve.

    INPUT:

    - `H` : Hyperelliptic Curve of the form \(y^2 = f(x)\) over a finite field, \(\GF{q}\)

    OUTPUT:

    - `pr` :p-rank

    EXAMPLES:

    Sage

        sage: K.<x> = GF(49, 'x')[]
        sage: C = HyperellipticCurve(x^5 + 1)
        sage: C.p_rank()
        0

        sage: K.<x> = GF(9, 'x')[]
        sage: C = HyperellipticCurve(x^7 - 1)
        sage: C.p_rank()
        0

        sage: P.<x> = GF(9, 'a')[]
        sage: E = HyperellipticCurve(x^29 + 1)
        sage: E.p_rank()
        0

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(49), 'x')['x']; (x,) = K._first_ngens(1)
        >>> C = HyperellipticCurve(x**Integer(5) + Integer(1))
        >>> C.p_rank()
        0

        >>> K = GF(Integer(9), 'x')['x']; (x,) = K._first_ngens(1)
        >>> C = HyperellipticCurve(x**Integer(7) - Integer(1))
        >>> C.p_rank()
        0

        >>> P = GF(Integer(9), 'a')['x']; (x,) = P._first_ngens(1)
        >>> E = HyperellipticCurve(x**Integer(29) + Integer(1))
        >>> E.p_rank()
        0

  points()

    Return all the points on this hyperelliptic curve.

    EXAMPLES:

    Sage

        sage: x = polygen(GF(7))
        sage: C = HyperellipticCurve(x^7 - x^2 - 1)
        sage: C.points()
        [(1 : 0 : 0), (2 : 2 : 1), (2 : 5 : 1), (3 : 0 : 1), (4 : 1 : 1),
         (4 : 6 : 1), (5 : 0 : 1), (6 : 2 : 1), (6 : 5 : 1)]

    Python

        >>> from sage.all import *
        >>> x = polygen(GF(Integer(7)))
        >>> C = HyperellipticCurve(x**Integer(7) - x**Integer(2) - Integer(1))
        >>> C.points()
        [(1 : 0 : 0), (2 : 2 : 1), (2 : 5 : 1), (3 : 0 : 1), (4 : 1 : 1),
         (4 : 6 : 1), (5 : 0 : 1), (6 : 2 : 1), (6 : 5 : 1)]

    Sage

        sage: x = polygen(GF(121, 'a'))
        sage: C = HyperellipticCurve(x^5 + x - 1, x^2 + 2)
        sage: len(C.points())
        122

    [Python]

        >>> from sage.all import *
        >>> x = polygen(GF(Integer(121), 'a'))
        >>> C = HyperellipticCurve(x**Integer(5) + x - Integer(1), x**Integer(2) + Integer(2))
        >>> len(C.points())
        122

    As we use the smooth model we also can work with the case of an even degree model:

    Sage

        sage: x = polygen(GF(7))
        sage: C = HyperellipticCurve(x^6 - 1)
        sage: C.points()
        [(1 : 1 : 0), (1 : 6 : 0), (1 : 0 : 1), (2 : 0 : 1), (3 : 0 : 1),
         (4 : 0 : 1), (5 : 0 : 1), (6 : 0 : 1)]
        sage: C.points_at_infinity()
        [(1 : 1 : 0), (1 : 6 : 0)]

    Python

        >>> from sage.all import *
        >>> x = polygen(GF(Integer(7)))
        >>> C = HyperellipticCurve(x**Integer(6) - Integer(1))
        >>> C.points()
        [(1 : 1 : 0), (1 : 6 : 0), (1 : 0 : 1), (2 : 0 : 1), (3 : 0 : 1),
         (4 : 0 : 1), (5 : 0 : 1), (6 : 0 : 1)]
        >>> C.points_at_infinity()
        [(1 : 1 : 0), (1 : 6 : 0)]

    This method works even for hyperelliptic curves with no rational points at infinity:

    Sage

        sage: C = HyperellipticCurve(3 * x^6 - 1)
        sage: C.points()
        [(1 : 3 : 1), (1 : 4 : 1), (2 : 3 : 1), (2 : 4 : 1), (3 : 3 : 1),
         (3 : 4 : 1), (4 : 3 : 1), (4 : 4 : 1), (5 : 3 : 1), (5 : 4 : 1),
         (6 : 3 : 1), (6 : 4 : 1)]
        sage: C.points_at_infinity()
        []

    [Python]

        >>> from sage.all import *
        >>> C = HyperellipticCurve(Integer(3) * x**Integer(6) - Integer(1))
        >>> C.points()
        [(1 : 3 : 1), (1 : 4 : 1), (2 : 3 : 1), (2 : 4 : 1), (3 : 3 : 1),
         (3 : 4 : 1), (4 : 3 : 1), (4 : 4 : 1), (5 : 3 : 1), (5 : 4 : 1),
         (6 : 3 : 1), (6 : 4 : 1)]
        >>> C.points_at_infinity()
        []

    See also

    `rational_points_iterator()`

  random_point()

    Return a random point on this hyperelliptic curve, uniformly chosen among all rational points.

    EXAMPLES:

    Sage

        sage: x = polygen(GF(7))
        sage: C = HyperellipticCurve(x^7 - x^2 - 1)
        sage: C.random_point() # random
        (4 : 1 : 1)
        sage: type(C.random_point())
        <class 'sage.schemes.weighted_projective.weighted_projective_point.SchemeMorphism_point_weighted_projective_ring'>

    Python

        >>> from sage.all import *
        >>> x = polygen(GF(Integer(7)))
        >>> C = HyperellipticCurve(x**Integer(7) - x**Integer(2) - Integer(1))
        >>> C.random_point() # random
        (4 : 1 : 1)
        >>> type(C.random_point())
        <class 'sage.schemes.weighted_projective.weighted_projective_point.SchemeMorphism_point_weighted_projective_ring'>

  rational_points()

    alias of `points()`.

  rational_points_iterator()

    Return all the points on this hyperelliptic curve as an iterator.

    EXAMPLES:

    Sage

        sage: x = polygen(GF(7))
        sage: C = HyperellipticCurve(x^7 - x^2 - 1)
        sage: list(C.rational_points_iterator())
        [(1 : 0 : 0), (2 : 2 : 1), (2 : 5 : 1), (3 : 0 : 1), (4 : 1 : 1),
         (4 : 6 : 1), (5 : 0 : 1), (6 : 2 : 1), (6 : 5 : 1)]
        sage: _ == C.points()
        True

    Python

        >>> from sage.all import *
        >>> x = polygen(GF(Integer(7)))
        >>> C = HyperellipticCurve(x**Integer(7) - x**Integer(2) - Integer(1))
        >>> list(C.rational_points_iterator())
        [(1 : 0 : 0), (2 : 2 : 1), (2 : 5 : 1), (3 : 0 : 1), (4 : 1 : 1),
         (4 : 6 : 1), (5 : 0 : 1), (6 : 2 : 1), (6 : 5 : 1)]
        >>> _ == C.points()
        True

    See also

    `points()`

  zeta_function()

    Compute the zeta function of the hyperelliptic curve.

    EXAMPLES:

    Sage

        sage: F = GF(2); R.<t> = F[]
        sage: H = HyperellipticCurve(t^9 + t, t^4)
        sage: H.zeta_function()
        (16*x^8 + 8*x^7 + 8*x^6 + 4*x^5 + 6*x^4 + 2*x^3 + 2*x^2 + x + 1)/(2*x^2 - 3*x + 1)

        sage: F.<a> = GF(4); R.<t> = F[]
        sage: H = HyperellipticCurve(t^5 + t^3 + t^2 + t + 1, t^2 + t + 1)
        sage: H.zeta_function()
        (16*x^4 + 8*x^3 + x^2 + 2*x + 1)/(4*x^2 - 5*x + 1)

        sage: F.<a> = GF(9); R.<t> = F[]
        sage: H = HyperellipticCurve(t^5 + a*t)
        sage: H.zeta_function()
        (81*x^4 + 72*x^3 + 32*x^2 + 8*x + 1)/(9*x^2 - 10*x + 1)

        sage: R.<t> = PolynomialRing(GF(37))
        sage: H = HyperellipticCurve(t^5 + t + 2)
        sage: H.zeta_function()
        (1369*x^4 + 37*x^3 - 52*x^2 + x + 1)/(37*x^2 - 38*x + 1)

    Python

        >>> from sage.all import *
        >>> F = GF(Integer(2)); R = F['t']; (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(9) + t, t**Integer(4))
        >>> H.zeta_function()
        (16*x^8 + 8*x^7 + 8*x^6 + 4*x^5 + 6*x^4 + 2*x^3 + 2*x^2 + x + 1)/(2*x^2 - 3*x + 1)

        >>> F = GF(Integer(4), names=('a',)); (a,) = F._first_ngens(1); R = F['t']; (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(5) + t**Integer(3) + t**Integer(2) + t + Integer(1), t**Integer(2) + t + Integer(1))
        >>> H.zeta_function()
        (16*x^4 + 8*x^3 + x^2 + 2*x + 1)/(4*x^2 - 5*x + 1)

        >>> F = GF(Integer(9), names=('a',)); (a,) = F._first_ngens(1); R = F['t']; (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(5) + a*t)
        >>> H.zeta_function()
        (81*x^4 + 72*x^3 + 32*x^2 + 8*x + 1)/(9*x^2 - 10*x + 1)

        >>> R = PolynomialRing(GF(Integer(37)), names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(t**Integer(5) + t + Integer(2))
        >>> H.zeta_function()
        (1369*x^4 + 37*x^3 - 52*x^2 + x + 1)/(37*x^2 - 38*x + 1)

    A quadratic twist:

    Sage

        sage: R.<t> = PolynomialRing(GF(37))
        sage: H = HyperellipticCurve(2*t^5 + 2*t + 4)
        sage: H.zeta_function()
        (1369*x^4 - 37*x^3 - 52*x^2 - x + 1)/(37*x^2 - 38*x + 1)

    [Python]

        >>> from sage.all import *
        >>> R = PolynomialRing(GF(Integer(37)), names=('t',)); (t,) = R._first_ngens(1)
        >>> H = HyperellipticCurve(Integer(2)*t**Integer(5) + Integer(2)*t + Integer(4))
        >>> H.zeta_function()
        (1369*x^4 - 37*x^3 - 52*x^2 - x + 1)/(37*x^2 - 38*x + 1)