Varieties with theta structure

This module defines the classes of Abelian varieties with theta structure and Kummer variety with theta structure as an 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 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 eq 4$, one can recover a complete set of equations for $i(A)$ thanks to Riemann equations which are parametrized by the theta null point.

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

As for computations, one look for the most compact and efficient representation, in most instances level $4$ representation is enough. In some cases, one can find useful the increased speed up provided by the level $2$ representation, so working with Kummer varieties, at the expense of loosing the group law of the abelian variety (but x

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

REFERENCES:

Gaud

P. Gaudry. Fast genus 2 arithmetic based on theta functions. J. Math. Cryptol. 1 (3) (2007) 243–265.

Mum66
  1. Mumford. On the equations defining abelian varieties. I. Invent. Math.,

237-354, 1966.

Mum67a
  1. Mumford. On the equations defining abelian varieties. II. Invent. Math.,

75-135, 1967.

Todo

  • Add more info to the paragraph above

  • Change coefficients in examples to be powers of gen?

  • Can we use equations to generate random points?

class avisogenies_sage.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 avisogenies_sage.theta_point.VarietyThetaStructurePoint

dimension()

Return the dimension of this variety.

level()

Return the level of the theta structure.

TEST

sage: from avisogenies_sage import KummerVariety
sage: F = GF(331)
sage: K = KummerVariety(F, 2, [328 , 213 , 75 , 1])
sage: K.level()
2
sage: from avisogenies_sage 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)

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

riemann_relation(*data)

Returns the riemann relation associated to a given triple chi, i, j. If it is not 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.

Todo

  • Check change with David.

  • Rename?

  • If we only want the addition of the two-torsion elements, why not store _riemann only with that? see _addition_formula

  • Private or public?

_addition_formula(P, Q, L)

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

Todo

  • Add tests.

isogeny(l, basis, R=[], check=True)
class avisogenies_sage.theta_null_point.AbelianVariety_ThetaStructure(R, n, g, T, check=False)

Bases: avisogenies_sage.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 avisogenies_sage 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 avisogenies_sage.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.

Todo

  • Find a couple of examples

class avisogenies_sage.theta_null_point.KummerVariety(R, g, T, check=False)

Bases: avisogenies_sage.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 avisogenies_sage 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 avisogenies_sage.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].

Otherwise, these are computed using the Riemann relations.

Todo

  • Find a couple of 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 avisogenies_sage 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?

Abelian variety constructor

Constructor for abelian varieties with extra structure.

AUTHORS:

  • Anna Somoza (2021-22): initial implementation

avisogenies_sage.constructor.AbelianVariety(*data, **kwargs)

Create the abelian variety corresponding to the given defining data.

INPUT:

An integer, string, newform, modsym space, congruence subgroup or tuple of congruence subgroups (see AbelianVariety() in Sagemath) or a theta structure (see AbelianVariety_ThetaStructure).

OUTPUT: a modular abelian variety with extra structure.

EXAMPLES:

Giving the data of the theta structure associated to an Abelian Variety we can create an instance of AbelianVariety_ThetaStructure:

sage: from avisogenies_sage import AbelianVariety
sage: AbelianVariety(GF(331), 4, 1, [328,213,75,1])
Abelian variety of dimension 1 with theta null point (328 : 213 : 75 : 1) defined over Finite Field of size 331

If the level of the abelian variety is 2, it correctly returns an instance of KummerVariety_ThetaStructure:

sage: from avisogenies_sage import AbelianVariety
sage: AbelianVariety(GF(331), 2, 2, [328,213,75,1])
Kummer variety of dimension 2 with theta null point (328 : 213 : 75 : 1) defined over Finite Field of size 331

But the function is also compatible with the functionality currently available in Sagemath:

sage: AbelianVariety(Gamma0(37))
Abelian variety J0(37) of dimension 2
sage: AbelianVariety('37a')
Newform abelian subvariety 37a of dimension 1 of J0(37)
sage: AbelianVariety(Newform('37a'))
Newform abelian subvariety 37a of dimension 1 of J0(37)
sage: AbelianVariety(ModularSymbols(37).cuspidal_submodule())
Abelian variety J0(37) of dimension 2
sage: AbelianVariety((Gamma0(37), Gamma0(11)))
Abelian variety J0(37) x J0(11) of dimension 3
sage: AbelianVariety(37)
Abelian variety J0(37) of dimension 2
sage: AbelianVariety([1,2,3])
Traceback (most recent call last):
...
TypeError: X must be an integer, string, newform, modsym space, congruence subgroup or tuple of congruence subgroups

TEST:

The constructor should also pass the named parameters:

sage: from avisogenies_sage import *
sage: F.<z> = GF(83^2)
sage: T = [68, z + 33, 46, z + 33, 2*z + 29, 77*z + 58, 81*z + 31, 38*z + 16, 8, 67*z + 53, 48, 67*z + 53, 2*z + 29, 38*z + 16, 81*z + 31, 77*z + 58]
sage: A = AbelianVariety(F, 4, 2, T, check=True)
avisogenies_sage.constructor._with_theta_basis(label: str, *data, **kwargs)
avisogenies_sage.constructor._from_curve(C, level=4)

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 avisogenies_sage 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?