The \(F_n\) representation#

Varieties#

This module defines the classes of Abelian varieties with theta structure and Kummer variety with theta structure as abstract schemes.

Following [Mum66] an abelian variety \(A\) of dimension \(g\) together with a level \(n\) theta structure is provided with a unique embedding \(i: A \rightarrow \mathbb{P}^{n^g-1}\). The data of the theta structure is equivalent to the data of the theta null point \(i(0)\). Actually, one of the main results of [Mum66] states that if \(n = 4\), one can recover a complete set of equations for \(i(A)\) thanks to the Riemann equations, which are parametrized by the theta null point.

In the case that \(n = 2\), since all the level two theta functions are even, the map \(i: A \rightarrow \mathbb{P}^{n^g-1}\) factors through the Kummer variety \(K = A/(-1)\) associated to \(A\).

As for computations, one looks for the most compact and efficient representation, which means that in most instances a level \(4\) representation is enough. In some cases, one can find useful the increased speed up provided by the level \(2\) representation, that is, working with Kummer varieties, at the expense of loosing the group law of the abelian variety.

The main point of this module is to provide constructors for the creation of an Abelian and Kummer variety together with a level \(n\) theta structure (\(n=2\) in case of Kummer variety) and computing Riemann equations to represent its projective embedding and arithmetic.

AUTHORS:

  • Anna Somoza (2020-22): initial implementation

class thetAV.theta_null_point.Variety_ThetaStructure(R, n, g, T)#

Bases: sage.schemes.generic.algebraic_scheme.AlgebraicScheme

Generic class for Varieties with theta structure. See also AbelianVariety_ThetaStructure, KummerVariety..

INPUT:

  • R – a field of definition

  • n – an even integer; the level of the theta structure.

  • g – an integer; the dimension of the abelian variety.

  • T - a list of length ng elements of R - the theta null point determining the abelian variety.

  • check (default: False) – A boolean; if True, checks that the riemann relations are satisfied by the input.

_point#

alias of thetAV.theta_point.VarietyThetaStructurePoint

dimension()#

Return the dimension of this variety.

level()#

Return the level of the theta structure.

TEST

sage: from thetAV import KummerVariety
sage: F = GF(331)
sage: K = KummerVariety(F, 2, [328 , 213 , 75 , 1])
sage: K.level()
2
sage: from thetAV import AbelianVariety
sage: n = 2*randint(2,5); g = randint(2,5)
sage: T = [randint(1, 331) for _ in range(n^g)]
sage: A = AbelianVariety(F, n, g, T)
sage: A.level() == n
True
theta_null_point()#

Return the theta null point as a point of the variety.

change_ring(R)#

Not implemented for a general variety.

base_extend(R)#

Return the natural extension of self over R.

_point_homset(*args, **kwds)#

Construct a point Hom-set. For internal use only.

TESTS:

sage: P2.<x,y,z> = ProjectiveSpace(2, ZZ)
sage: P2._point_homset(Spec(ZZ), P2)
Set of rational points of Projective Space of dimension 2 over Integer Ring
point(P, **kwds)#

Create a point.

INPUT:

  • v – anything that defines a point in a variety with theta structure. See VarietyPoint for details.

  • check – boolean (optional, default: False); if True, check that the riemann relations are satisfied.

OUTPUT:

A point of the scheme.

with_theta_basis(*data, **kwargs)#

Compute the representation of the thetanullpoint in the given basis of the space of theta functions.

Possible values are:

  • ‘F(n)’

  • ‘F(2,2)’, for level 4

  • ‘F(2,2)^2’, for level 2

  • ‘classical’, corresponds to ‘F(2,2)’ or ‘F(2,2)^2’ depending on the level of self.

The method saves the already-computed values in the private variable _with_theta_basis.

It can also be used as the constructor for the thetanullpoint using other representations, see _with_theta_basis()

EXAMPLES:

sage: from thetAV import AbelianVariety, KummerVariety
sage: F.<z2> = GF(19^2)
sage: A = AbelianVariety(F, 4, 2, (5*z2 + 7 , 6*z2 + 8 , 6*z2 + 5 , 6*z2 + 8 , z2 + 13 , 4*z2 + 12 , 14*z2 + 11 , 11*z2 + 9 , 11*z2 + 6 , 6*z2 + 14 , 16*z2 + 5 , 6*z2 + 14 , z2 + 13 , 11*z2 + 9 , 14*z2 + 11 , 4*z2 + 12), check=True)
sage: A.with_theta_basis('classical')
(1 : 8*z2 + 15 : 15*z2 + 5 : z2 + 5 : 6*z2 + 11 : 0 : 16 : 0 : 17*z2 + 12 : 3*z2 + 1 : 0 : 0 : 17*z2 + 1 : 0 : 0 : 6*z2 + 11)
sage: K1 = KummerVariety(GF(331), 2, [328,213,75,1])
sage: K1.with_theta_basis('F(2,2)^2')
(173 : 327 : 8 : 163 : 49 : 0 : 305 : 0 : 325 : 112 : 0 : 0 : 42 : 0 : 0 : 286)
riemann_relation(*data)#

Returns the indices appearing in the Riemann relation associated to a given triple chi, i, j. If it has not been computed, it computes it and stores it in the private variable _riemann.

INPUT:

Either 3 variables

  • chi – a character, given by its dual element in Z(2) as a subset of Z(n).

  • i – the index of a coordinate of P. For now we are assuming that they are an element of Zmod(n)^g.

  • j – the index of a coordinate of P. For now we are assuming that they are an element of Zmod(n)^g.

Or a triple of 3 integers, the integer representation of chi, i and j.

EXAMPLES:

sage: #TODO examples

_addition_formula(P, Q, L)#

Given two points P and Q and a list L containing integer triplets [idxchi, idxi, idxj] compute \(\sum_{t \in Z(2)} \chi(t) (P+Q)_{i + t} (P-Q)_{j + t}\) for every given triplet.

TESTS:

sage: from thetAV import *
sage: F.<z2> = GF(19^2)
sage: A = AbelianVariety(F, 4, 2, (5*z2 + 7 , 6*z2 + 8 , 6*z2 + 5 , 6*z2 + 8 , z2 + 13 , 4*z2 + 12 , 14*z2 + 11 , 11*z2 + 9 , 11*z2 + 6 , 6*z2 + 14 , 16*z2 + 5 , 6*z2 + 14 , z2 + 13 , 11*z2 + 9 , 14*z2 + 11 , 4*z2 + 12), check=True)
sage: A._addition_formula(A(0), A(0), [(1,8,7)])
{(1, 0, 15): 11, (1, 2, 13): 8, (1, 8, 7): 11, (1, 10, 5): 8}
isogeny(l, basis, R=[], check=True)#

Given the basis of an isotropic subgroup B of the l-torsion of A, compute the thetanullpoints of the isogenous abelian variety A/B. Moreover, given a list of points R, it computes the image of these points via the isogeny.

EXAMPLE:

sage: #TODO examples
class thetAV.theta_null_point.AbelianVariety_ThetaStructure(R, n, g, T, check=False)#

Bases: thetAV.theta_null_point.Variety_ThetaStructure

Class for Abelian Varieties with theta structure. See also AbelianVariety().

INPUT:

  • R – a field of definition

  • n – an even integer >= 4; the level of the theta structure.

  • g – an integer; the dimension of the abelian variety.

  • T - a list of length ng elements of R - the theta null point determining the abelian variety.

  • check (default: False) – A boolean; if True, checks that the riemann relations are satisfied by the input.

EXAMPLES:

sage: from thetAV import AbelianVariety
sage: FF2 = GF(10753)
sage: A2 = AbelianVariety(FF2, 4, 1, [732,45,98,7]); A2
Abelian variety of dimension 1 with theta null point (732 : 45 : 98 : 7) defined over Finite Field of size 10753
_point#

alias of thetAV.theta_point.AbelianVarietyPoint

_repr_()#

Return a string representation of this abelian variety.

change_ring(R)#

Return the abelian variety with field of definition R.

equations()#

Returns a list of defining equations for the abelian variety.

EXAMPLES:

sage: #TODO examples
class thetAV.theta_null_point.KummerVariety(R, g, T)#

Bases: thetAV.theta_null_point.Variety_ThetaStructure

Class for Kummer Varieties with theta structure.

INPUT:

  • R – a field of definition

  • n – an integer; the level of the theta structure.

  • g – an integer; the dimension of the kummer variety.

  • T - a list of length ng elements of R - the theta null point determining the kummer variety.

EXAMPLES:

sage: from thetAV import KummerVariety
sage: FF1 = GF(331)
sage: K1 = KummerVariety(FF1, 2, [328,213,75,1]); K1
Kummer variety of dimension 2 with theta null point (328 : 213 : 75 : 1) defined over Finite Field of size 331
_point#

alias of thetAV.theta_point.KummerVarietyPoint

_level = 2#
_repr_()#

Return a string representation of this abelian variety.

change_ring(R)#

Return the kummer variety with field of definition R.

equations()#

Returns a list of defining equations for the abelian variety.

If the theta null point has dimension 2 and level 2, these are the equations as given by Gaudry in [Gaud]. In that case, it assumes that the genericity conditions are satisfied (see [Gaud] for details).

Otherwise, these are computed using the Riemann relations.

EXAMPLES:

sage: #TODO examples
from_curve(*, level=2)#

Given a hyperelliptic curve of genus 2, returns the analytic theta null point of level 4 (default) or 2.

This function is accessible via AbelianVariety.from_curve or KummerVariety.from_curve

EXAMPLES

sage: from thetAV import AbelianVariety
sage: F = GF(83^2); Fx.<X> = PolynomialRing(F)
sage: a = [0, 1, 3, 15, 20]
sage: C = HyperellipticCurve(prod(X - al for al in a)); C
Hyperelliptic Curve over Finite Field in z2 of size 83^2 defined by y^2 = x^5 + 44*x^4 + 28*x^3 + 23*x^2 + 70*x
sage: th = AbelianVariety.from_curve(C); th.with_theta_basis('F(2,2)')
(1 : 37 : 56 : 57 : 34*z2 + 43 : 0 : 50*z2 + 73 : 0 : 30 : 2*z2 + 82 : 0 : 0 : 16*z2 + 37 : 0 : 0 : 61*z2 + 21)

TODO :: Can we generalize to more curves: Genus 1? Genus >2?

Theta points#

This module defines the base class of Theta points as elements of AbelianVariety_ThetaStructure.

AUTHORS:

  • Anna Somoza (2020-22): initial implementation

class thetAV.theta_point.VarietyThetaStructurePoint(X, v)#

Bases: sage.structure.element.AdditiveGroupElement, sage.schemes.generic.morphism.SchemeMorphism_point

Constructor for a point on a variety with theta structure.

INPUT:

  • X – a variety with theta structure

  • v – data determining a point (another point or a tuple of coordinates)

_repr_()#

Return a string representation of this point.

_latex_()#

Return a LaTeX representation of this point.

scheme()#

Return the scheme of this point, i.e., the abelian variety it is on.

is_equal(Q, proj=True, factor=False)#

Check whether two points are equal or not. If proj = true we compare them as projective points, and if factor = True, return as a second argument the rapport Q/P.

INPUT:

  • Q - a point.

  • proj - a boolean (default: \(True\)). Weather the comparison is done as projective points.

  • factor - a boolean (default: \(False\)). If True, as a second argument is returned, the rapport right/self.

EXAMPLES

sage: from thetAV import KummerVariety
sage: A = KummerVariety(GF(331), 2, [328 , 213 , 75 , 1])
sage: P = A([255 , 89 , 30 , 1]) #A 1889-torsion point
sage: 1889*P
(12 : 141 : 31 : 327)
sage: A(0).is_equal(1889*P)
True

If the points are equal as projective points but not as affine points, one can obtain the factor:

sage: (1889*P).is_equal(A(0), proj=False)
False
sage: _, k = A(0).is_equal(1889*P, factor=True); k
327
_get_nonzero_coord(idx=True)#
diff_add(Q, PmQ)#

Not implemented for a general point.

_diff_add_PQfactor(P, Q, PmQ)#

Given a representative of (P+Q), computes the raport with respect to the representative obtained as P.diff_add(Q, PmQ).

_diff_add_PQ(P, Q, PmQ)#

Given a representative of (P+Q), computes the affine representative obtained with P.diff_add(Q, PmQ).

_add_(other)#

Add self to other.

If we are in level two, this returns P+Q and P-Q.

EXAMPLES

sage: from thetAV import KummerVariety
sage: R.<X> = PolynomialRing(GF(331))
sage: poly = X^4 + 3*X^2 + 290*X + 3
sage: F.<t> = poly.splitting_field()
sage: A = KummerVariety(F, 2, [328 , 213 , 75 , 1])
sage: P = A([255 , 89 , 30 , 1])
sage: Q = A([158*t^3 + 67*t^2 + 9*t + 293, 290*t^3 + 25*t^2 + 235*t + 280,              155*t^3 + 84*t^2 + 15*t + 170, 1])
sage: P + Q
((221*t^3 + 178*t^2 + 126*t + 27 : 32*t^3 + 17*t^2 + 175*t + 171 : 180*t^3 + 188*t^2 + 161*t + 119 : 261*t^3 + 107*t^2 + 37*t + 135),
(1 : 56*t^3 + 312*t^2 + 147*t + 287 : 277*t^3 + 295*t^2 + 7*t + 287 : 290*t^3 + 203*t^2 + 274*t + 10))

TESTS

sage: #TODO level 4 tests
_add(other, i0=0)#

Not implemented for a general point.

_neg_()#

Computes the addition opposite of self.

EXAMPLES

sage: from thetAV import KummerVariety
sage: A = KummerVariety(GF(331), 2, [328 , 213 , 75 , 1])
sage: P = A([255 , 89 , 30 , 1]); - P
(255 : 89 : 30 : 1)
_rmul_(k)#

Compute scalar multiplication by \(k\) with a Montgomery ladder type algorithm.

EXAMPLES

sage: from thetAV import KummerVariety
sage: A = KummerVariety(GF(331), 2, [328 , 213 , 75 , 1])
sage: P = A([255 , 89 , 30 , 1])
sage: 42*P
(311 : 326 : 136 : 305)

TESTS

sage: #TODO level 4 tests
_mult(k, algorithm='Montgomery')#

Compute scalar multiplication by \(k\) with a Montgomery ladder type algorithm.

INPUT:

  • algorithm (default: ‘Montgomery’): The chosen algorithm for the computation. It can either be ‘Montgomery’ for a Montgomery ladder type algorithm, or ‘SquareAndMultiply’ for the usual square and multiply algorithm (only for level > 2).

EXAMPLES

sage: from thetAV import KummerVariety
sage: A = KummerVariety(GF(331), 2, [328 , 213 , 75 , 1])
sage: P = A([255 , 89 , 30 , 1])
sage: P._mult(42)
(311 : 326 : 136 : 305)

See also

_rmul_()

TESTS

sage: #TODO level 4 tests
diff_multadd(k, PQ, Q)#

Computes k*self + Q, k*self.

EXAMPLES:

sage: from thetAV import KummerVariety
sage: R.<X> = PolynomialRing(GF(331))
sage: poly = X^4 + 3*X^2 + 290*X + 3
sage: F.<t> = poly.splitting_field()
sage: A = KummerVariety(F, 2, [328 , 213 , 75 , 1])
sage: P = A([255 , 89 , 30 , 1])
sage: Q = A([158*t^3 + 67*t^2 + 9*t + 293, 290*t^3 + 25*t^2 + 235*t + 280,             155*t^3 + 84*t^2 + 15*t + 170, 1])
sage: PmQ = A([62*t^3 + 16*t^2 + 255*t + 129 , 172*t^3 + 157*t^2 + 43*t + 222 ,                 258*t^3 + 39*t^2 + 313*t + 150 , 1])
sage: PQ = P.diff_add(Q, PmQ)
sage: P.diff_multadd(42, PQ, Q)
((41*t^3 + 291*t^2 + 122*t + 305 : 119*t^3 + 95*t^2 + 120*t + 68 : 81*t^3 + 168*t^2 + 326*t + 24 : 202*t^3 + 251*t^2 + 246*t + 169),
(311 : 326 : 136 : 305))

Todo

If we don’t need kP, then we don’t need to compute kP, only (k/2)P, so we lose 2 differential additions. Could be optimized here.

weil_pairing(l, Q, PQ=None)#

Computes the Weil pairing of P=self and Q. See also _weil_pairing_from_points() to use precomputed points.

INPUT:

  • l – An integer

  • P=self – An point of torsion \(level\)

  • Q – Another point of torsion \(level\)

  • PQ (default: None) – The addition of P and Q.

OUTPUT:

The nth power of the weil pairing of P and Q, where n is the level of the theta structure.

EXAMPLES:

sage: #TODO examples
tate_pairing(l, Q, PQ=None)#

Computes the Weil pairing of P=self and Q.

INPUT:

  • P=self – A point

  • l – An integer

  • Q – A point of torsion \(l\) in the same Abelian Variety as \(P\).

  • PQ (default: None) – The addition of P and Q.

OUTPUT:

The r-th power of the tate pairing of P and Q, where \(r = (p^k - 1)/l\).

EXAMPLES

sage: from thetAV import KummerVariety
sage: R.<X> = PolynomialRing(GF(331))
sage: poly = X^4 + 3*X^2 + 290*X + 3
sage: F.<t> = poly.splitting_field()
sage: A = KummerVariety(F, 2, [328 , 213 , 75 , 1])
sage: P = A([255 , 89 , 30 , 1])
sage: Q = A([158*t^3 + 67*t^2 + 9*t + 293, 290*t^3 + 25*t^2 + 235*t + 280,              155*t^3 + 84*t^2 + 15*t + 170, 1])
sage: PmQ = A([62*t^3 + 16*t^2 + 255*t + 129 , 172*t^3 + 157*t^2 + 43*t + 222 ,                 258*t^3 + 39*t^2 + 313*t + 150 , 1])
sage: PQ = P.diff_add(Q, PmQ)
sage: P.tate_pairing(1889, Q, PQ)
313*t^3 + 144*t^2 + 38*t + 71
sage: Q.tate_pairing(1889, P, PQ)
130*t^3 + 124*t^2 + 49*t + 153
three_way_add(Q, R, PQ, QR, PR)#

EXAMPLES:

sage: from thetAV import KummerVariety
sage: R.<X> = PolynomialRing(GF(331))
sage: poly = X^4 + 3*X^2 + 290*X + 3
sage: F.<t> = poly.splitting_field()
sage: A = KummerVariety(F, 2, [328 , 213 , 75 , 1])
sage: P = A([255 , 89 , 30 , 1])
sage: Q = A([158*t^3 + 67*t^2 + 9*t + 293, 290*t^3 + 25*t^2 + 235*t + 280,             155*t^3 + 84*t^2 + 15*t + 170, 1])
sage: PmQ = A([62*t^3 + 16*t^2 + 255*t + 129 , 172*t^3 + 157*t^2 + 43*t + 222 ,                 258*t^3 + 39*t^2 + 313*t + 150 , 1])
sage: PQ = P.diff_add(Q, PmQ)
sage: P.diff_multadd(2, PQ, Q)[0] == P.three_way_add(P,Q,2*P, PQ, PQ)
True

Todo

  • Document

  • Add hidden tests using hyperelliptic curve.

  • Maybe change example to be level 4 so that we can just compare it with 2*P + Q.

  • Maybe add time comparison with diff_add

  • This function could be optimized, following the notes in [REF MISSING, page]_.

scale(k)#

Given an affine lift point ‘P’ and a factor ‘k’ in the field of definition, returns the affine lift given by kx.

EXAMPLE

sage: from thetAV import KummerVariety
sage: F = GF(331)
sage: A = KummerVariety(F, 2, [328 , 213 , 75 , 1])
sage: P = A([255 , 89 , 30 , 1])
sage: P.scale(5)
(282 : 114 : 150 : 5)

TEST :

If the factor to scale by is not in the field of definition, it should raise an error

sage: FF.<z> = GF(331^2)
sage: P.scale(z)
Traceback (most recent call last):
...
ValueError: The scalar factor k=z should be in the base ring R=Finite Field of size 331
compatible_lift(l, other=None, add=None)#

Compute a lift of an l-torsion point that is compatible with the chosen affine lift of the theta null point.

INPUT :

  • self – an l-torsion point of the abelian variety

  • other – a list of points of the abelian variety, or None if only the lift of an l-torsion point is needed.

  • add – the list of sums self + P for all the points in P, or None if only the lift of an l-torsion point is needed.

  • l – the torsion

EXAMPLES:

sage: #TODO examples
with_theta_basis(label, **kwargs)#

Let thc be a theta null point given by algebraic coordinates (i.e. AbelianVariety_ThetaStructure, KummerVariety). Compute the corresponding theta null point (i.e. AnalyticThetaNullPoint) in analytic coordinates.

Todo

check that label matches level. Use python3 match to study the cases, maybe!

class thetAV.theta_point.AbelianVarietyPoint(X, v, check=False)#

Bases: thetAV.theta_point.VarietyThetaStructurePoint

Constructor for a point on an abelian variety with theta structure.

INPUT:

  • X – an abelian variety

  • v – data determining a point (another point or a tuple of coordinates)

  • good_lift – a boolean (default: \(False\)); indicates if the given affine lift is a good lift, i.e. a lift compatible with the lift of the theta null point.

  • check – a boolean (default: \(False\)); indicates if computations to check the correctness of the input data should be performed, using the Riemann Relations.

EXAMPLES

sage: from thetAV import KummerVariety
sage: A = KummerVariety(GF(331), 2, [328 , 213 , 75 , 1])
sage: P = A([255 , 89 , 30 , 1]); P
(255 : 89 : 30 : 1)
sage: R.<X> = PolynomialRing(GF(331))
sage: poly = X^4 + 3*X^2 + 290*X + 3
sage: F.<t> = poly.splitting_field()
sage: B = A.change_ring(F)
sage: Q = B([158*t^3 + 67*t^2 + 9*t + 293, 290*t^3 + 25*t^2 + 235*t + 280,          155*t^3 + 84*t^2 + 15*t + 170, 1]); Q
(158*t^3 + 67*t^2 + 9*t + 293 : 290*t^3 + 25*t^2 + 235*t + 280 : 155*t^3 + 84*t^2 + 15*t + 170 : 1)
abelian_variety()#

Return the abelian variety that this point is on.

EXAMPLES:

sage: from thetAV import AbelianVariety
sage: A = AbelianVariety(GF(331), 4, 1, [328 , 213 , 75 , 1]); A
Abelian variety of dimension 1 with theta null point (328 : 213 : 75 : 1) defined over Finite Field of size 331
sage: P = A([255 , 89 , 30 , 1])
sage: P.abelian_variety()
Abelian variety of dimension 1 with theta null point (328 : 213 : 75 : 1) defined over Finite Field of size 331
diff_add(Q, PmQ, check=False)#

Computes the differential addition of self with given point Q.

INPUT:

  • Q - a theta point

  • PmQ - The theta point \(self - Q\).

  • check - (default: False) check with the riemann relations that the resulting point is indeed a point of the abelian variety.

OUTPUT: The theta point \(self + Q\). If \(self\), \(Q\) and \(PmQ\) are good lifts, then the output is also a good lift.

EXAMPLES

sage: from thetAV import AbelianVariety
sage: A = AbelianVariety(GF(331), 4, 1, [328 , 213 , 75 , 1]); A
Abelian variety of dimension 1 with theta null point (328 : 213 : 75 : 1) defined over Finite Field of size 331
sage: #TODO finish example
sage: #P = A([255 , 89 , 30 , 1]); Q = A([123, 345, 23, 13]); PQ = A([23,12,45,5])
sage: #P.diff_add(Q, PQ)
_add(other, i0=0)#

Normal addition between self and other on the affine plane with respect to i0. If (self - other)[i] == 0, then it tries with another affine plane.

See also

_add_()

TESTS:

sage: #TODO  Find tests where P and Q are not rational in the av but rational in the kummer variety, so P+Q won't be rational
class thetAV.theta_point.KummerVarietyPoint(X, v, check=False, **kwargs)#

Bases: thetAV.theta_point.VarietyThetaStructurePoint

Constructor for a point on an kummer variety with theta structure.

INPUT:

  • X – a kummer variety

  • v – data determining a point (another point or a tuple of coordinates)

EXAMPLES

sage: from thetAV import KummerVariety
sage: A = KummerVariety(GF(331), 2, [328 , 213 , 75 , 1])
sage: P = A([255 , 89 , 30 , 1]); P
(255 : 89 : 30 : 1)
sage: R.<X> = PolynomialRing(GF(331))
sage: poly = X^4 + 3*X^2 + 290*X + 3
sage: F.<t> = poly.splitting_field()
sage: B = A.change_ring(F)
sage: Q = B([158*t^3 + 67*t^2 + 9*t + 293, 290*t^3 + 25*t^2 + 235*t + 280,          155*t^3 + 84*t^2 + 15*t + 170, 1]); Q
(158*t^3 + 67*t^2 + 9*t + 293 : 290*t^3 + 25*t^2 + 235*t + 280 : 155*t^3 + 84*t^2 + 15*t + 170 : 1)
kummer_variety()#

Return the abelian variety that this point is on.

EXAMPLES:

sage: from thetAV import KummerVariety
sage: A = KummerVariety(GF(331), 2, [328 , 213 , 75 , 1]); A
Kummer variety of dimension 2 with theta null point (328 : 213 : 75 : 1) defined over Finite Field of size 331
sage: P = A([255 , 89 , 30 , 1])
sage: P.kummer_variety()
Kummer variety of dimension 2 with theta null point (328 : 213 : 75 : 1) defined over Finite Field of size 331
_check()#
diff_add(Q, PmQ)#

Computes the differential addition of self with given point Q.

INPUT:

  • Q - a theta point

  • PmQ - The theta point \(self - Q\).

OUTPUT: The theta point \(self + Q\). If \(self\), \(Q\) and \(PmQ\) are good lifts, then the output is also a good lift.

EXAMPLES

sage: from thetAV import KummerVariety
sage: R.<X> = PolynomialRing(GF(331))
sage: poly = X^4 + 3*X^2 + 290*X + 3
sage: F.<t> = poly.splitting_field()
sage: A = KummerVariety(F, 2, [328 , 213 , 75 , 1])
sage: P = A([255 , 89 , 30 , 1])
sage: Q = A([158*t^3 + 67*t^2 + 9*t + 293, 290*t^3 + 25*t^2 + 235*t + 280,                 155*t^3 + 84*t^2 + 15*t + 170, 1])
sage: PmQ = A([62*t^3 + 16*t^2 + 255*t + 129 , 172*t^3 + 157*t^2 + 43*t + 222 ,                 258*t^3 + 39*t^2 + 313*t + 150 , 1])
sage: PQ = P.diff_add(Q, PmQ); PQ
(261*t^3 + 107*t^2 + 37*t + 135 : 205*t^3 + 88*t^2 + 195*t + 125 : 88*t^3 + 99*t^2 + 164*t + 98 : 159*t^3 + 279*t^2 + 254*t + 276)
_add(other, idxi0=0)#

Normal addition between self and other on the affine plane with respect to i0. If (self - other)[i] == 0, then it tries with another affine plane.

See also

_add_()

TESTS:

sage: #TODO Find tests where P and Q are not rational in the av but rational in the kummer variety, so P+Q won't be rational
_neg_()#

Computes the addition opposite of self.

EXAMPLES

sage: from thetAV import KummerVariety
sage: A = KummerVariety(GF(331), 2, [328 , 213 , 75 , 1])
sage: P = A([255 , 89 , 30 , 1]); - P
(255 : 89 : 30 : 1)
weil_pairing(l, Q)#

EXAMPLES

sage: from thetAV import KummerVariety
sage: R.<X> = PolynomialRing(GF(331))
sage: poly = X^4 + 3*X^2 + 290*X + 3
sage: F.<t> = poly.splitting_field()
sage: A = KummerVariety(F, 2, [328 , 213 , 75 , 1])
sage: P = A([255 , 89 , 30 , 1])
sage: Q = A([158*t^3 + 67*t^2 + 9*t + 293, 290*t^3 + 25*t^2 + 235*t + 280,              155*t^3 + 84*t^2 + 15*t + 170, 1])
sage: P.weil_pairing(1889, Q)
61*t^3 + 285*t^2 + 196*t + 257