Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/schemes/hyperelliptic_curves/jacobian_morphism.py
4128 views
1
r"""
2
Jacobian 'morphism' as a class in the Picard group
3
4
This module implements the group operation in the Picard group of a
5
hyperelliptic curve, represented as divisors in Mumford
6
representation, using Cantor's algorithm.
7
8
A divisor on the hyperelliptic curve `y^2 + y h(x) = f(x)`
9
is stored in Mumford representation, that is, as two polynomials
10
`u(x)` and `v(x)` such that:
11
12
- `u(x)` is monic,
13
14
- `u(x)` divides `f(x) - h(x) v(x) - v(x)^2`,
15
16
- `deg(v(x)) < deg(u(x)) \le g`.
17
18
REFERENCES:
19
20
A readable introduction to divisors, the Picard group, Mumford
21
representation, and Cantor's algorithm:
22
23
- J. Scholten, F. Vercauteren. An Introduction to Elliptic and
24
Hyperelliptic Curve Cryptography and the NTRU Cryptosystem. To
25
appear in B. Preneel (Ed.) State of the Art in Applied Cryptography
26
- COSIC '03, Lecture Notes in Computer Science, Springer 2004.
27
28
A standard reference in the field of cryptography:
29
30
- R. Avanzi, H. Cohen, C. Doche, G. Frey, T. Lange, K. Nguyen, and F.
31
Vercauteren, Handbook of Elliptic and Hyperelliptic Curve
32
Cryptography. CRC Press, 2005.
33
34
EXAMPLES: The following curve is the reduction of a curve whose
35
Jacobian has complex multiplication.
36
37
::
38
39
sage: x = GF(37)['x'].gen()
40
sage: H = HyperellipticCurve(x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x); H
41
Hyperelliptic Curve over Finite Field of size 37 defined
42
by y^2 = x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x
43
44
At this time, Jacobians of hyperelliptic curves are handled
45
differently than elliptic curves::
46
47
sage: J = H.jacobian(); J
48
Jacobian of Hyperelliptic Curve over Finite Field of size 37 defined
49
by y^2 = x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x
50
sage: J = J(J.base_ring()); J
51
Set of rational points of Jacobian of Hyperelliptic Curve over Finite Field
52
of size 37 defined by y^2 = x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x
53
54
Points on the Jacobian are represented by Mumford's polynomials.
55
First we find a couple of points on the curve::
56
57
sage: P1 = H.lift_x(2); P1
58
(2 : 11 : 1)
59
sage: Q1 = H.lift_x(10); Q1
60
(10 : 18 : 1)
61
62
Observe that 2 and 10 are the roots of the polynomials in x,
63
respectively::
64
65
sage: P = J(P1); P
66
(x + 35, y + 26)
67
sage: Q = J(Q1); Q
68
(x + 27, y + 19)
69
70
::
71
72
sage: P + Q
73
(x^2 + 25*x + 20, y + 13*x)
74
sage: (x^2 + 25*x + 20).roots(multiplicities=False)
75
[10, 2]
76
77
Frobenius satisfies
78
79
.. math::
80
81
x^4 + 12*x^3 + 78*x^2 + 444*x + 1369
82
83
on the Jacobian of this reduction and the order of the Jacobian is
84
`N = 1904`.
85
86
::
87
88
sage: 1904*P
89
(1)
90
sage: 34*P == 0
91
True
92
sage: 35*P == P
93
True
94
sage: 33*P == -P
95
True
96
97
::
98
99
sage: Q*1904
100
(1)
101
sage: Q*238 == 0
102
True
103
sage: Q*239 == Q
104
True
105
sage: Q*237 == -Q
106
True
107
"""
108
109
#*****************************************************************************
110
# Copyright (C) 2005 David Kohel <[email protected]>
111
# Distributed under the terms of the GNU General Public License (GPL)
112
# http://www.gnu.org/licenses/
113
#*****************************************************************************
114
115
from sage.misc.all import latex
116
117
from sage.structure.element import AdditiveGroupElement
118
from sage.schemes.generic.morphism import SchemeMorphism
119
120
def cantor_reduction_simple(a, b, f, genus):
121
r"""
122
Return the unique reduced divisor linearly equivalent to
123
`(a, b)` on the curve `y^2 = f(x).`
124
125
See the docstring of
126
:mod:`sage.schemes.hyperelliptic_curves.jacobian_morphism` for
127
information about divisors, linear equivalence, and reduction.
128
129
EXAMPLES::
130
131
sage: x = QQ['x'].gen()
132
sage: f = x^5 - x
133
sage: H = HyperellipticCurve(f); H
134
Hyperelliptic Curve over Rational Field defined by y^2 = x^5 - x
135
sage: J = H.jacobian()(QQ); J
136
Set of rational points of Jacobian of Hyperelliptic Curve over Rational Field
137
defined by y^2 = x^5 - x
138
139
The following point is 2-torsion::
140
141
sage: P = J(H.lift_x(-1)); P
142
(x + 1, y)
143
sage: 2 * P # indirect doctest
144
(1)
145
"""
146
a2 = (f - b**2) // a
147
a2 = a2.monic()
148
b2 = -b % (a2);
149
if a2.degree() == a.degree():
150
# XXX
151
assert a2.degree() == genus+1
152
print "Returning ambiguous form of degree genus+1."
153
return (a2, b2)
154
elif a2.degree() > genus:
155
return cantor_reduction_simple(a2, b2, f, genus)
156
return (a2, b2)
157
158
def cantor_reduction(a, b, f, h, genus):
159
r"""
160
Return the unique reduced divisor linearly equivalent to
161
`(a, b)` on the curve `y^2 + y h(x) = f(x)`.
162
163
See the docstring of
164
:mod:`sage.schemes.hyperelliptic_curves.jacobian_morphism` for
165
information about divisors, linear equivalence, and reduction.
166
167
EXAMPLES::
168
169
sage: x = QQ['x'].gen()
170
sage: f = x^5 - x
171
sage: H = HyperellipticCurve(f, x); H
172
Hyperelliptic Curve over Rational Field defined by y^2 + x*y = x^5 - x
173
sage: J = H.jacobian()(QQ); J
174
Set of rational points of Jacobian of Hyperelliptic Curve over
175
Rational Field defined by y^2 + x*y = x^5 - x
176
177
The following point is 2-torsion::
178
179
sage: Q = J(H.lift_x(0)); Q
180
(x, y)
181
sage: 2*Q # indirect doctest
182
(1)
183
184
The next point is not 2-torsion::
185
186
sage: P = J(H.lift_x(-1)); P
187
(x + 1, y - 1)
188
sage: 2 * J(H.lift_x(-1)) # indirect doctest
189
(x^2 + 2*x + 1, y - 3*x - 4)
190
sage: 3 * J(H.lift_x(-1)) # indirect doctest
191
(x^2 - 487*x - 324, y - 10754*x - 7146)
192
"""
193
assert a.degree() < 2*genus+1
194
assert b.degree() < a.degree()
195
k = f - h*b - b**2
196
if 2*a.degree() == k.degree():
197
# must adjust b to include the point at infinity
198
g1 = a.degree()
199
x = a.parent().gen()
200
r = (x**2 + h[g1]*x - f[2*g1]).roots()[0][0]
201
b = b + r*(x**g1 - (x**g1) % (a))
202
k = f - h*b - b**2
203
assert k % (a) == 0
204
a = (k // a).monic()
205
b = -(b+h) % (a)
206
if a.degree() > genus:
207
return cantor_reduction(a, b, f, h, genus)
208
return (a, b)
209
210
def cantor_composition_simple(D1,D2,f,genus):
211
r"""
212
Given `D_1` and `D_2` two reduced Mumford
213
divisors on the Jacobian of the curve `y^2 = f(x)`,
214
computes a representative `D_1 + D_2`.
215
216
.. warning::
217
218
The representative computed is NOT reduced! Use
219
:func:`cantor_reduction_simple` to reduce it.
220
221
EXAMPLES::
222
223
sage: x = QQ['x'].gen()
224
sage: f = x^5 + x
225
sage: H = HyperellipticCurve(f); H
226
Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x
227
228
::
229
230
sage: F.<a> = NumberField(x^2 - 2, 'a')
231
sage: J = H.jacobian()(F); J
232
Set of rational points of Jacobian of Hyperelliptic Curve over
233
Number Field in a with defining polynomial x^2 - 2 defined
234
by y^2 = x^5 + x
235
236
::
237
238
sage: P = J(H.lift_x(F(1))); P
239
(x - 1, y - a)
240
sage: Q = J(H.lift_x(F(0))); Q
241
(x, y)
242
sage: 2*P + 2*Q # indirect doctest
243
(x^2 - 2*x + 1, y - 3/2*a*x + 1/2*a)
244
sage: 2*(P + Q) # indirect doctest
245
(x^2 - 2*x + 1, y - 3/2*a*x + 1/2*a)
246
sage: 3*P # indirect doctest
247
(x^2 - 25/32*x + 49/32, y - 45/256*a*x - 315/256*a)
248
"""
249
a1, b1 = D1
250
a2, b2 = D2
251
if a1 == a2 and b1 == b2:
252
# Duplication law:
253
d, h1, h3 = a1.xgcd(2*b1)
254
a = (a1 // d)**2
255
b = (b1 + h3*((f - b1**2) // d)) % (a)
256
else:
257
d0, _, h2 = a1.xgcd(a2)
258
if d0 == 1:
259
a = a1*a2
260
b = (b2 + h2*a2*(b1-b2)) % (a)
261
else:
262
d, l, h3 = d0.xgcd(b1 + b2)
263
a = (a1*a2) // (d**2)
264
b = ((b2 + l*h2*(b1-b2)*(a2 // d)) + h3*((f - b2**2) // d)) % (a)
265
a =a.monic()
266
return (a, b)
267
268
def cantor_composition(D1,D2,f,h,genus):
269
r"""
270
EXAMPLES::
271
272
sage: F.<a> = GF(7^2, 'a')
273
sage: x = F['x'].gen()
274
sage: f = x^7 + x^2 + a
275
sage: H = HyperellipticCurve(f, 2*x); H
276
Hyperelliptic Curve over Finite Field in a of size 7^2 defined by y^2 + 2*x*y = x^7 + x^2 + a
277
sage: J = H.jacobian()(F); J
278
Set of rational points of Jacobian of Hyperelliptic Curve over
279
Finite Field in a of size 7^2 defined by y^2 + 2*x*y = x^7 + x^2 + a
280
281
::
282
283
sage: Q = J(H.lift_x(F(1))); Q
284
(x + 6, y + 2*a + 2)
285
sage: 10*Q # indirect doctest
286
(x^3 + (3*a + 1)*x^2 + (2*a + 5)*x + a + 5, y + (4*a + 5)*x^2 + (a + 1)*x + 6*a + 3)
287
sage: 7*8297*Q
288
(1)
289
290
::
291
292
sage: Q = J(H.lift_x(F(a+1))); Q
293
(x + 6*a + 6, y + 2)
294
sage: 7*8297*Q # indirect doctest
295
(1)
296
297
A test over a prime field:
298
299
sage: F = GF(next_prime(10^30))
300
sage: x = F['x'].gen()
301
sage: f = x^7 + x^2 + 1
302
sage: H = HyperellipticCurve(f, 2*x); H
303
Hyperelliptic Curve over Finite Field of size 1000000000000000000000000000057 defined by y^2 + 2*x*y = x^7 + x^2 + 1
304
sage: J = H.jacobian()(F); J
305
verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation.
306
Set of rational points of Jacobian of Hyperelliptic Curve over
307
Finite Field of size 1000000000000000000000000000057 defined
308
by y^2 + 2*x*y = x^7 + x^2 + 1
309
sage: Q = J(H.lift_x(F(1))); Q
310
(x + 1000000000000000000000000000056, y + 1000000000000000000000000000056)
311
sage: 10*Q # indirect doctest
312
(x^3 + 150296037169838934997145567227*x^2 + 377701248971234560956743242408*x + 509456150352486043408603286615, y + 514451014495791237681619598519*x^2 + 875375621665039398768235387900*x + 861429240012590886251910326876)
313
sage: 7*8297*Q
314
(x^3 + 35410976139548567549919839063*x^2 + 26230404235226464545886889960*x + 681571430588959705539385624700, y + 999722365017286747841221441793*x^2 + 262703715994522725686603955650*x + 626219823403254233972118260890)
315
"""
316
a1, b1 = D1
317
a2, b2 = D2
318
if a1 == a2 and b1 == b2:
319
# Duplication law:
320
d, h1, h3 = a1.xgcd(2*b1 + h)
321
a = (a1 // d)**2;
322
b = (b1 + h3*((f-h*b1-b1**2) // d)) % (a)
323
else:
324
d0, _, h2 = a1.xgcd(a2)
325
if d0 == 1:
326
a = a1*a2;
327
b = (b2 + h2*a2*(b1-b2)) % (a)
328
else:
329
e0 = b1+b2+h
330
if e0 == 0:
331
a = (a1*a2) // (d0**2)
332
b = (b2 + h2*(b1-b2)*(a2 // d0)) % (a)
333
else:
334
d, l, h3 = d0.xgcd(e0)
335
a = (a1*a2) // (d**2)
336
b = (b2 + l*h2*(b1-b2)*(a2 // d) + h3*((f-h*b2-b2**2) // d)) % (a)
337
a = a.monic()
338
return (a, b)
339
340
class JacobianMorphism_divisor_class_field(AdditiveGroupElement, SchemeMorphism):
341
r"""
342
An element of a Jacobian defined over a field, i.e. in
343
`J(K) = \mathrm{Pic}^0_K(C)`.
344
"""
345
def __init__(self, parent, polys, check=True):
346
r"""
347
Create a new Jacobian element in Mumford representation.
348
349
INPUT: parent: the parent Homset polys: Mumford's `u` and
350
`v` polynomials check (default: True): if True, ensure that
351
polynomials define a divisor on the appropriate curve and are
352
reduced
353
354
.. warning::
355
356
Not for external use! Use ``J(K)([u, v])`` instead.
357
358
EXAMPLES::
359
360
sage: x = GF(37)['x'].gen()
361
sage: H = HyperellipticCurve(x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x)
362
sage: J = H.jacobian()(GF(37)); J
363
Set of rational points of Jacobian of Hyperelliptic Curve over
364
Finite Field of size 37 defined by
365
y^2 = x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x
366
367
::
368
369
sage: P1 = J(H.lift_x(2)); P1 # indirect doctest
370
(x + 35, y + 26)
371
sage: P1.parent()
372
Set of rational points of Jacobian of Hyperelliptic Curve over
373
Finite Field of size 37 defined by
374
y^2 = x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x
375
sage: type(P1)
376
<class 'sage.schemes.hyperelliptic_curves.jacobian_morphism.JacobianMorphism_divisor_class_field'>
377
"""
378
SchemeMorphism.__init__(self, parent)
379
if check:
380
C = parent.curve()
381
f, h = C.hyperelliptic_polynomials()
382
a, b = polys
383
if not (b**2 + h*b - f)%a == 0:
384
raise ValueError, \
385
"Argument polys (= %s) must be divisor on curve %s."%(
386
polys, C)
387
genus = C.genus()
388
if a.degree() > genus:
389
polys = cantor_reduction(a, b, f, h, genus)
390
self.__polys = polys
391
392
def _printing_polys(self):
393
r"""
394
Internal function formatting Mumford polynomials for printing.
395
396
TESTS::
397
398
sage: F.<a> = GF(7^2, 'a')
399
sage: x = F['x'].gen()
400
sage: f = x^7 + x^2 + a
401
sage: H = HyperellipticCurve(f, 2*x)
402
sage: J = H.jacobian()(F)
403
404
::
405
406
sage: Q = J(H.lift_x(F(1))); Q # indirect doctest
407
(x + 6, y + 2*a + 2)
408
"""
409
a, b = self.__polys
410
P = self.parent()._printing_ring
411
y = P.gen()
412
x = P.base_ring().gen()
413
return (a(x), y - b(x))
414
415
def _repr_(self):
416
r"""
417
Return a string representation of this Mumford divisor.
418
419
EXAMPLES::
420
421
sage: F.<a> = GF(7^2, 'a')
422
sage: x = F['x'].gen()
423
sage: f = x^7 + x^2 + a
424
sage: H = HyperellipticCurve(f, 2*x)
425
sage: J = H.jacobian()(F)
426
427
::
428
429
sage: Q = J(0); Q # indirect doctest
430
(1)
431
sage: Q = J(H.lift_x(F(1))); Q # indirect doctest
432
(x + 6, y + 2*a + 2)
433
sage: Q + Q # indirect doctest
434
(x^2 + 5*x + 1, y + 3*a*x + 6*a + 2)
435
"""
436
if self.is_zero():
437
return "(1)"
438
a, b = self._printing_polys()
439
return "(%s, %s)" % (a, b)
440
441
def _latex_(self):
442
r"""
443
Return a LaTeX string representing this Mumford divisor.
444
445
EXAMPLES::
446
447
sage: F.<alpha> = GF(7^2)
448
sage: x = F['x'].gen()
449
sage: f = x^7 + x^2 + alpha
450
sage: H = HyperellipticCurve(f, 2*x)
451
sage: J = H.jacobian()(F)
452
453
::
454
455
sage: Q = J(0); print latex(Q) # indirect doctest
456
\left(1\right)
457
sage: Q = J(H.lift_x(F(1))); print latex(Q) # indirect doctest
458
\left(x + 6, y + 2 \alpha + 2\right)
459
460
::
461
462
sage: print latex(Q + Q)
463
\left(x^{2} + 5 x + 1, y + 3 \alpha x + 6 \alpha + 2\right)
464
"""
465
if self.is_zero():
466
return "\\left(1\\right)"
467
a, b = self._printing_polys()
468
return "\\left(%s, %s\\right)" % (latex(a), latex(b))
469
470
def scheme(self):
471
r"""
472
Return the scheme this morphism maps to; or, where this divisor
473
lives.
474
475
.. warning::
476
477
Although a pointset is defined over a specific field, the
478
scheme returned may be over a different (usually smaller)
479
field. The example below demonstrates this: the pointset
480
is determined over a number field of absolute degree 2 but
481
the scheme returned is defined over the rationals.
482
483
EXAMPLES::
484
485
sage: x = QQ['x'].gen()
486
sage: f = x^5 + x
487
sage: H = HyperellipticCurve(f)
488
sage: F.<a> = NumberField(x^2 - 2, 'a')
489
sage: J = H.jacobian()(F); J
490
Set of rational points of Jacobian of Hyperelliptic Curve over
491
Number Field in a with defining polynomial x^2 - 2 defined
492
by y^2 = x^5 + x
493
494
::
495
496
sage: P = J(H.lift_x(F(1)))
497
sage: P.scheme()
498
Jacobian of Hyperelliptic Curve over Rational Field defined by y^2 = x^5 + x
499
"""
500
return self.codomain()
501
502
503
def __list__(self):
504
r"""
505
Return a list `(a(x), b(x))` of the polynomials giving the
506
Mumford representation of self.
507
508
TESTS::
509
510
sage: x = QQ['x'].gen()
511
sage: f = x^5 + x
512
sage: H = HyperellipticCurve(f)
513
sage: F.<a> = NumberField(x^2 - 2, 'a')
514
sage: J = H.jacobian()(F); J
515
Set of rational points of Jacobian of Hyperelliptic Curve over
516
Number Field in a with defining polynomial x^2 - 2 defined
517
by y^2 = x^5 + x
518
519
::
520
521
sage: P = J(H.lift_x(F(1)))
522
sage: list(P) # indirect doctest
523
[x - 1, a]
524
"""
525
return list(self.__polys)
526
527
def __tuple__(self):
528
r"""
529
Return a tuple `(a(x), b(x))` of the polynomials giving the
530
Mumford representation of self.
531
532
TESTS::
533
534
sage: x = QQ['x'].gen()
535
sage: f = x^5 + x
536
sage: H = HyperellipticCurve(f)
537
sage: F.<a> = NumberField(x^2 - 2, 'a')
538
sage: J = H.jacobian()(F); J
539
Set of rational points of Jacobian of Hyperelliptic Curve over
540
Number Field in a with defining polynomial x^2 - 2 defined
541
by y^2 = x^5 + x
542
543
::
544
545
sage: P = J(H.lift_x(F(1)))
546
sage: tuple(P) # indirect doctest
547
(x - 1, a)
548
"""
549
return tuple(self.__polys)
550
551
def __getitem__(self, n):
552
r"""
553
Return the `n`-th item of the pair `(a(x), b(x))`
554
of polynomials giving the Mumford representation of self.
555
556
TESTS::
557
558
sage: x = QQ['x'].gen()
559
sage: f = x^5 + x
560
sage: H = HyperellipticCurve(f)
561
sage: F.<a> = NumberField(x^2 - 2, 'a')
562
sage: J = H.jacobian()(F); J
563
Set of rational points of Jacobian of Hyperelliptic Curve over
564
Number Field in a with defining polynomial x^2 - 2 defined
565
by y^2 = x^5 + x
566
567
::
568
569
sage: P = J(H.lift_x(F(1)))
570
sage: P[0] # indirect doctest
571
x - 1
572
sage: P[1] # indirect doctest
573
a
574
sage: P[-1] # indirect doctest
575
a
576
sage: P[:1] # indirect doctest
577
[x - 1]
578
"""
579
return list(self.__polys)[n]
580
581
def __cmp__(self, other):
582
r"""
583
Compare self and other.
584
585
TESTS::
586
587
sage: x = QQ['x'].gen()
588
sage: f = x^5 - x
589
sage: H = HyperellipticCurve(f); H
590
Hyperelliptic Curve over Rational Field defined by y^2 = x^5 - x
591
sage: J = H.jacobian()(QQ); J
592
Set of rational points of Jacobian of Hyperelliptic Curve over
593
Rational Field defined by y^2 = x^5 - x
594
595
The following point is 2-torsion::
596
597
sage: P = J(H.lift_x(-1)); P
598
(x + 1, y)
599
sage: 0 == 2 * P # indirect doctest
600
True
601
sage: P == P
602
True
603
604
::
605
606
sage: Q = J(H.lift_x(-1))
607
sage: Q == P
608
True
609
610
::
611
612
sage: 2 == Q
613
False
614
sage: P == False
615
False
616
617
Let's verify the same "points" on different schemes are not equal::
618
619
sage: x = QQ['x'].gen()
620
sage: f = x^5 + x
621
sage: H2 = HyperellipticCurve(f)
622
sage: J2 = H2.jacobian()(QQ)
623
624
::
625
626
sage: P1 = J(H.lift_x(0)); P1
627
(x, y)
628
sage: P2 = J2(H2.lift_x(0)); P2
629
(x, y)
630
sage: P1 == P2
631
False
632
"""
633
if not isinstance(other, JacobianMorphism_divisor_class_field):
634
try:
635
other = self.parent()(other)
636
except TypeError:
637
return -1
638
if self.scheme() != other.scheme():
639
return -1
640
# since divisors are internally represented as Mumford divisors,
641
# comparing polynomials is well-defined
642
return cmp(self.__polys, other.__polys)
643
644
def __nonzero__(self):
645
r"""
646
Return True if this divisor is not the additive identity element.
647
648
EXAMPLES::
649
650
sage: x = GF(37)['x'].gen()
651
sage: H = HyperellipticCurve(x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x)
652
sage: J = H.jacobian()(GF(37))
653
654
::
655
656
sage: P1 = J(H.lift_x(2)); P1
657
(x + 35, y + 26)
658
sage: P1 == 0 # indirect doctest
659
False
660
sage: P1 - P1 == 0 # indirect doctest
661
True
662
"""
663
return self.__polys[0] != 1
664
665
def __neg__(self):
666
r"""
667
Return the additive inverse of this divisor.
668
669
EXAMPLES::
670
671
sage: x = GF(37)['x'].gen()
672
sage: H = HyperellipticCurve(x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x)
673
sage: J = H.jacobian()(GF(37))
674
sage: P1 = J(H.lift_x(2)); P1
675
(x + 35, y + 26)
676
sage: - P1 # indirect doctest
677
(x + 35, y + 11)
678
sage: P1 - P1 # indirect doctest
679
(1)
680
681
::
682
683
sage: H2 = HyperellipticCurve(x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x, x)
684
sage: J2 = H2.jacobian()(GF(37))
685
sage: P2 = J2(H2.lift_x(2)); P2
686
(x + 35, y + 15)
687
sage: - P2 # indirect doctest
688
(x + 35, y + 24)
689
sage: P2 - P2 # indirect doctest
690
(1)
691
"""
692
if self.is_zero():
693
return self
694
polys = self.__polys
695
X = self.parent()
696
f, h = X.curve().hyperelliptic_polynomials()
697
if h.is_zero():
698
D = (polys[0],-polys[1])
699
else:
700
D = (polys[0],-polys[1]-h % (polys[0]))
701
return JacobianMorphism_divisor_class_field(X, D, check=False)
702
703
def _add_(self,other):
704
r"""
705
Return a Mumford representative of the divisor self + other.
706
707
EXAMPLES::
708
709
sage: x = GF(37)['x'].gen()
710
sage: H = HyperellipticCurve(x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x)
711
sage: J = H.jacobian()(GF(37))
712
713
::
714
715
sage: P1 = J(H.lift_x(2)); P1
716
(x + 35, y + 26)
717
sage: P1 + P1 # indirect doctest
718
(x^2 + 33*x + 4, y + 13*x)
719
"""
720
X = self.parent()
721
C = X.curve()
722
f, h = C.hyperelliptic_polynomials()
723
genus = C.genus()
724
if h == 0:
725
D = cantor_composition_simple(self.__polys, other.__polys, f, genus)
726
if D[0].degree() > genus:
727
D = cantor_reduction_simple(D[0], D[1], f, genus)
728
else:
729
D = cantor_composition(self.__polys, other.__polys, f, h, genus)
730
if D[0].degree() > genus:
731
D = cantor_reduction(D[0], D[1], f, h, genus)
732
return JacobianMorphism_divisor_class_field(X, D, check=False)
733
734
def _sub_(self, other):
735
r"""
736
Return a Mumford representative of the divisor self - other.
737
738
EXAMPLES::
739
740
sage: x = GF(37)['x'].gen()
741
sage: H = HyperellipticCurve(x^5 + 12*x^4 + 13*x^3 + 15*x^2 + 33*x)
742
sage: J = H.jacobian()(GF(37))
743
744
::
745
746
sage: P1 = J(H.lift_x(2)); P1
747
(x + 35, y + 26)
748
sage: P1 - P1 # indirect doctest
749
(1)
750
751
::
752
753
sage: P2 = J(H.lift_x(4)); P2
754
(x + 33, y + 34)
755
756
Observe that the `x`-coordinates are the same but the
757
`y`-coordinates differ::
758
759
sage: P1 - P2 # indirect doctest
760
(x^2 + 31*x + 8, y + 7*x + 12)
761
sage: P1 + P2 # indirect doctest
762
(x^2 + 31*x + 8, y + 4*x + 18)
763
sage: (P1 - P2) - (P1 + P2) + 2*P2 # indirect doctest
764
(1)
765
"""
766
return self + (-other)
767
768