Theta points
This module defines the base class of Theta points as elements of
AbelianVariety_ThetaStructure.
AUTHORS:
Anna Somoza (2020-22): initial implementation
Todo
Add more info to the paragraph above
On binary operations, test that all the points belong to the same abelian variety.
- class avisogenies_sage.theta_point.VarietyThetaStructurePoint(X, v)
Bases:
sage.structure.element.AdditiveGroupElement,sage.schemes.generic.morphism.SchemeMorphism_pointConstructor for a point on a variety with theta structure.
INPUT:
X– a variety with theta structurev– 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 avisogenies_sage 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 avisogenies_sage 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))
Todo
Find tests that are not level 2!
- _add(other, i0=0)
Not implemented for a general point.
- _neg_()
Computes the addition opposite of self.
EXAMPLES
sage: from avisogenies_sage 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 avisogenies_sage 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)
Todo
Find tests that are not level 2!
- _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 avisogenies_sage 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
Todo
Find tests that are not level 2!
- diff_multadd(k, PQ, Q)
Computes k*self + Q, k*self.
EXAMPLES:
sage: from avisogenies_sage 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 integerP=self– An point of torsion \(level\)Q– Another point of torsion \(level\)PQ(default: None) – The addition ofPandQ.
OUTPUT:
The nth power of the weil pairing of P and Q, where n is the level of the theta structure.
..todo:: Should check that points belong to same AV.
- tate_pairing(l, Q, PQ=None)
Computes the Weil pairing of P=self and Q.
INPUT:
P=self– A pointl– An integerQ– 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\).
..todo:
- Should check that points belong to same AV.EXAMPLES
sage: from avisogenies_sage 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)
..todo:: Document
EXAMPLES:
sage: from avisogenies_sage 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
- 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 avisogenies_sage 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 varietyother– 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
Todo
Add examples
Add check keyword to assert that all the quotients are equal vs just taking one.
- 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
- class avisogenies_sage.theta_point.AbelianVarietyPoint(X, v, check=False)
Bases:
avisogenies_sage.theta_point.VarietyThetaStructurePointConstructor for a point on an abelian variety with theta structure.
INPUT:
X– an abelian varietyv– 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 avisogenies_sage 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)
Todo
When
vis a point already andcheckis \(True\), we should make sure that v has been checked when generated. maybe with a boolean in X (or in the point) that saves if it has been checked.Make check on the point/AV a method that caches the result.
- abelian_variety()
Return the abelian variety that this point is on.
EXAMPLES:
sage: from avisogenies_sage 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 pointPmQ- 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
- _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
Todo
Deal with case where self or other is the thetanullpoint.
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 avisogenies_sage.theta_point.KummerVarietyPoint(X, v, check=False, **kwargs)
Bases:
avisogenies_sage.theta_point.VarietyThetaStructurePointConstructor for a point on an kummer variety with theta structure.
INPUT:
X– a kummer varietyv– data determining a point (another point or a tuple of coordinates)
EXAMPLES
sage: from avisogenies_sage 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)
Todo
When
vis a point already andcheckis \(True\), we should make sure that v has been checked when generated. maybe with a boolean in X (or in the point) that saves if it has been checked.Make check on the point/AV a method that caches the result.
- kummer_variety()
Return the abelian variety that this point is on.
EXAMPLES:
sage: from avisogenies_sage 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 pointPmQ- 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 avisogenies_sage 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
Todo
Deal with case where self or other is the thetanullpoint.
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 avisogenies_sage 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 avisogenies_sage 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