Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/schemes/elliptic_curves/ell_point.py
8821 views
1
# -*- coding: utf-8 -*-
2
r"""
3
Points on elliptic curves
4
5
The base class ``EllipticCurvePoint_field``, derived from
6
``AdditiveGroupElement``, provides support for points on elliptic
7
curves defined over general fields. The derived classes
8
``EllipticCurvePoint_number_field`` and
9
``EllipticCurvePoint_finite_field`` provide further support for point
10
on curves defined over number fields (including the rational field
11
`\QQ`) and over finite fields.
12
13
The class ``EllipticCurvePoint``, which is based on
14
``SchemeMorphism_point_projective_ring``, currently has little extra
15
functionality.
16
17
EXAMPLES:
18
19
An example over `\QQ`::
20
21
sage: E = EllipticCurve('389a1')
22
sage: P = E(-1,1); P
23
(-1 : 1 : 1)
24
sage: Q = E(0,-1); Q
25
(0 : -1 : 1)
26
sage: P+Q
27
(4 : 8 : 1)
28
sage: P-Q
29
(1 : 0 : 1)
30
sage: 3*P-5*Q
31
(328/361 : -2800/6859 : 1)
32
33
An example over a number field::
34
35
sage: K.<i> = QuadraticField(-1)
36
sage: E = EllipticCurve(K,[1,0,0,0,-1])
37
sage: P = E(0,i); P
38
(0 : i : 1)
39
sage: P.order()
40
+Infinity
41
sage: 101*P-100*P==P
42
True
43
44
An example over a finite field::
45
46
sage: K.<a> = GF(101^3)
47
sage: E = EllipticCurve(K,[1,0,0,0,-1])
48
sage: P = E(40*a^2 + 69*a + 84 , 58*a^2 + 73*a + 45)
49
sage: P.order()
50
1032210
51
sage: E.cardinality()
52
1032210
53
54
Arithmetic with a point over an extension of a finite field::
55
56
sage: k.<a> = GF(5^2)
57
sage: E = EllipticCurve(k,[1,0]); E
58
Elliptic Curve defined by y^2 = x^3 + x over Finite Field in a of size 5^2
59
sage: P = E([a,2*a+4])
60
sage: 5*P
61
(2*a + 3 : 2*a : 1)
62
sage: P*5
63
(2*a + 3 : 2*a : 1)
64
sage: P + P + P + P + P
65
(2*a + 3 : 2*a : 1)
66
67
::
68
69
sage: F = Zmod(3)
70
sage: E = EllipticCurve(F,[1,0]);
71
sage: P = E([2,1])
72
sage: import sys
73
sage: n = sys.maxint
74
sage: P*(n+1)-P*n == P
75
True
76
77
Arithmetic over `\ZZ/N\ZZ` with composite `N` is supported. When an
78
operation tries to invert a non-invertible element, a
79
ZeroDivisionError is raised and a factorization of the modulus appears
80
in the error message::
81
82
sage: N = 1715761513
83
sage: E = EllipticCurve(Integers(N),[3,-13])
84
sage: P = E(2,1)
85
sage: LCM([2..60])*P
86
Traceback (most recent call last):
87
...
88
ZeroDivisionError: Inverse of 1520944668 does not exist (characteristic = 1715761513 = 26927*63719)
89
90
91
AUTHORS:
92
93
- William Stein (2005) -- Initial version
94
95
- Robert Bradshaw et al....
96
97
- John Cremona (Feb 2008) -- Point counting and group structure for
98
non-prime fields, Frobenius endomorphism and order, elliptic logs
99
100
- John Cremona (Aug 2008) -- Introduced ``EllipticCurvePoint_number_field`` class
101
102
- Tobias Nagel, Michael Mardaus, John Cremona (Dec 2008) -- `p`-adic elliptic logarithm over `\QQ`
103
104
- David Hansen (Jan 2009) -- Added ``weil_pairing`` function to ``EllipticCurvePoint_finite_field`` class
105
106
- Mariah Lenox (March 2011) -- Added ``tate_pairing`` and ``ate_pairing``
107
functions to ``EllipticCurvePoint_finite_field`` class
108
109
"""
110
111
#*****************************************************************************
112
# Copyright (C) 2005 William Stein <[email protected]>
113
#
114
# Distributed under the terms of the GNU General Public License (GPL)
115
# as published by the Free Software Foundation; either version 2 of
116
# the License, or (at your option) any later version.
117
# http://www.gnu.org/licenses/
118
#*****************************************************************************
119
120
121
import math
122
123
import sage.plot.all as plot
124
125
from sage.rings.padics.factory import Qp
126
from sage.rings.padics.precision_error import PrecisionError
127
128
import sage.rings.all as rings
129
from sage.rings.real_mpfr import is_RealField
130
from sage.rings.all import ZZ
131
from sage.groups.all import AbelianGroup
132
import sage.groups.generic as generic
133
from sage.libs.pari.pari_instance import pari, prec_words_to_bits
134
from sage.structure.sequence import Sequence
135
136
from sage.schemes.plane_curves.projective_curve import Hasse_bounds
137
from sage.schemes.projective.projective_point import (SchemeMorphism_point_projective_ring,
138
SchemeMorphism_point_abelian_variety_field)
139
from sage.schemes.generic.morphism import is_SchemeMorphism
140
141
from constructor import EllipticCurve
142
from sage.misc.superseded import deprecated_function_alias
143
144
oo = rings.infinity # infinity
145
146
147
class EllipticCurvePoint(SchemeMorphism_point_projective_ring):
148
"""
149
A point on an elliptic curve.
150
"""
151
def __cmp__(self, other):
152
"""
153
Standard comparison function for points on elliptic curves, to
154
allow sorting and equality testing.
155
156
.. NOTE::
157
158
``__eq__`` and ``__ne__`` are implemented in
159
SchemeMorphism_point_projective_ring
160
161
EXAMPLES:
162
sage: E=EllipticCurve(QQ,[1,1])
163
sage: P=E(0,1)
164
sage: P.order()
165
+Infinity
166
sage: Q=P+P
167
sage: P==Q
168
False
169
sage: Q+Q == 4*P
170
True
171
"""
172
assert isinstance(other, (int, long, rings.Integer)) and other == 0
173
if self.is_zero():
174
return 0
175
else:
176
return -1
177
178
179
class EllipticCurvePoint_field(SchemeMorphism_point_abelian_variety_field):
180
"""
181
A point on an elliptic curve over a field. The point has coordinates
182
in the base field.
183
184
EXAMPLES::
185
186
sage: E = EllipticCurve('37a')
187
sage: E([0,0])
188
(0 : 0 : 1)
189
sage: E(0,0) # brackets are optional
190
(0 : 0 : 1)
191
sage: E([GF(5)(0), 0]) # entries are coerced
192
(0 : 0 : 1)
193
194
sage: E(0.000, 0)
195
(0 : 0 : 1)
196
197
sage: E(1,0,0)
198
Traceback (most recent call last):
199
...
200
TypeError: Coordinates [1, 0, 0] do not define a point on
201
Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
202
203
::
204
205
sage: E = EllipticCurve([0,0,1,-1,0])
206
sage: S = E(QQ); S
207
Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
208
209
sage: K.<i>=NumberField(x^2+1)
210
sage: E=EllipticCurve(K,[0,1,0,-160,308])
211
sage: P=E(26,-120)
212
sage: Q=E(2+12*i,-36+48*i)
213
sage: P.order() == Q.order() == 4 # long time (3s)
214
True
215
sage: 2*P==2*Q
216
False
217
218
::
219
220
sage: K.<t>=FractionField(PolynomialRing(QQ,'t'))
221
sage: E=EllipticCurve([0,0,0,0,t^2])
222
sage: P=E(0,t)
223
sage: P,2*P,3*P
224
((0 : t : 1), (0 : -t : 1), (0 : 1 : 0))
225
226
227
TESTS::
228
229
sage: loads(S.dumps()) == S
230
True
231
sage: E = EllipticCurve('37a')
232
sage: P = E(0,0); P
233
(0 : 0 : 1)
234
sage: loads(P.dumps()) == P
235
True
236
sage: T = 100*P
237
sage: loads(T.dumps()) == T
238
True
239
240
Test pickling an elliptic curve that has known points on it::
241
242
sage: e = EllipticCurve([0, 0, 1, -1, 0]); g = e.gens(); loads(dumps(e)) == e
243
True
244
"""
245
def __init__(self, curve, v, check=True):
246
"""
247
Constructor for a point on an elliptic curve.
248
249
INPUT:
250
251
- curve -- an elliptic curve
252
- v -- data determining a point (another point, the integer
253
0, or a tuple of coordinates)
254
255
EXAMPLE::
256
257
sage: E = EllipticCurve('43a')
258
sage: P = E([2, -4, 2]); P
259
(1 : -2 : 1)
260
sage: P == E([1,-2])
261
True
262
sage: P = E(0); P
263
(0 : 1 : 0)
264
sage: P=E(2, -4, 2); P
265
(1 : -2 : 1)
266
"""
267
point_homset = curve.point_homset()
268
if is_SchemeMorphism(v) or isinstance(v, EllipticCurvePoint_field):
269
v = list(v)
270
elif v == 0:
271
# some of the code assumes that E(0) has integral entries
272
# irregardless of the base ring...
273
#R = self.base_ring()
274
#v = (R.zero(),R.one(),R.zero())
275
v = (0, 1, 0)
276
if check:
277
# mostly from SchemeMorphism_point_projective_field
278
d = point_homset.codomain().ambient_space().ngens()
279
if not isinstance(v, (list, tuple)):
280
raise TypeError("Argument v (= %s) must be a scheme point, list, or tuple." % str(v))
281
if len(v) != d and len(v) != d-1:
282
raise TypeError("v (=%s) must have %s components" % (v, d))
283
v = Sequence(v, point_homset.value_ring())
284
if len(v) == d-1: # very common special case
285
v.append(v.universe()(1))
286
287
n = len(v)
288
all_zero = True
289
for i in range(n):
290
c = v[n-1-i]
291
if c:
292
all_zero = False
293
if c == 1:
294
break
295
for j in range(n-i):
296
v[j] /= c
297
break
298
if all_zero:
299
raise ValueError("%s does not define a valid point "
300
"since all entries are 0" % repr(v))
301
302
x, y, z = v
303
if z == 0:
304
test = x
305
else:
306
a1, a2, a3, a4, a6 = curve.ainvs()
307
test = y**2 + (a1*x+a3)*y - (((x+a2)*x+a4)*x+a6)
308
if not test == 0:
309
raise TypeError("Coordinates %s do not define a point on %s" % (list(v), curve))
310
311
SchemeMorphism_point_abelian_variety_field.__init__(self, point_homset, v, check=False)
312
#AdditiveGroupElement.__init__(self, point_homset)
313
314
def _repr_(self):
315
"""
316
Return a string representation of this point.
317
318
EXAMPLE::
319
320
sage: E = EllipticCurve('39a')
321
sage: P = E([-2, 1, 1])
322
sage: P._repr_()
323
'(-2 : 1 : 1)'
324
"""
325
return self.codomain().ambient_space()._repr_generic_point(self._coords)
326
327
def _latex_(self):
328
"""
329
Return a LaTeX representation of this point.
330
331
EXAMPLE::
332
333
sage: E = EllipticCurve('40a')
334
sage: P = E([3, 0])
335
sage: P._latex_()
336
'\\left(3 : 0 : 1\\right)'
337
"""
338
return self.codomain().ambient_space()._latex_generic_point(self._coords)
339
340
def __getitem__(self, n):
341
"""
342
Return the n'th coordinate of this point.
343
344
EXAMPLE::
345
346
sage: E = EllipticCurve('42a')
347
sage: P = E([-17, -51, 17])
348
sage: [P[i] for i in [2,1,0]]
349
[1, -3, -1]
350
"""
351
return self._coords[n]
352
353
def __iter__(self):
354
"""
355
Return the coordinates of this point as a list.
356
357
EXAMPLE::
358
359
sage: E = EllipticCurve('37a')
360
sage: list(E([0,0]))
361
[0, 0, 1]
362
"""
363
return iter(self._coords)
364
365
def __tuple__(self):
366
"""
367
Return the coordinates of this point as a tuple.
368
369
EXAMPLE::
370
371
sage: E = EllipticCurve('44a')
372
sage: P = E([1, -2, 1])
373
sage: P.__tuple__()
374
(1, -2, 1)
375
"""
376
return tuple(self._coords) # Warning: _coords is a list!
377
378
def __cmp__(self, other):
379
"""
380
Comparison function for points to allow sorting and equality testing.
381
382
.. NOTE::
383
384
``__eq__`` and ``__ne__`` are implemented in
385
SchemeMorphism_point_projective_field
386
387
EXAMPLES::
388
389
sage: E = EllipticCurve('45a')
390
sage: P = E([2, -1, 1])
391
sage: P == E(0)
392
False
393
sage: P+P == E(0)
394
True
395
"""
396
if not isinstance(other, EllipticCurvePoint_field):
397
try:
398
other = self.codomain().ambient_space()(other)
399
except TypeError:
400
return -1
401
return cmp(self._coords, other._coords)
402
403
def _pari_(self):
404
r"""
405
Converts this point to PARI format.
406
407
EXAMPLES::
408
409
sage: E = EllipticCurve([0,0,0,3,0])
410
sage: O = E(0)
411
sage: P = E.point([1,2])
412
sage: O._pari_()
413
[0]
414
sage: P._pari_()
415
[1, 2]
416
417
The following implicitly calls O._pari_() and P._pari_()::
418
419
sage: pari(E).elladd(O,P)
420
[1, 2]
421
422
TESTS::
423
424
Try the same over a finite field::
425
426
sage: E = EllipticCurve(GF(11), [0,0,0,3,0])
427
sage: O = E(0)
428
sage: P = E.point([1,2])
429
sage: O._pari_()
430
[0]
431
sage: P._pari_()
432
[Mod(1, 11), Mod(2, 11)]
433
434
We no longer need to explicitly call ``pari(O)`` and ``pari(P)``
435
after :trac:`11868`::
436
437
sage: pari(E).elladd(O, P)
438
[Mod(1, 11), Mod(2, 11)]
439
"""
440
if self[2]:
441
return pari([self[0]/self[2], self[1]/self[2]])
442
else:
443
return pari([0])
444
445
def scheme(self):
446
"""
447
Return the scheme of this point, i.e., the curve it is on.
448
This is synonymous with :meth:`curve` which is perhaps more
449
intuitive.
450
451
EXAMPLES::
452
453
sage: E=EllipticCurve(QQ,[1,1])
454
sage: P=E(0,1)
455
sage: P.scheme()
456
Elliptic Curve defined by y^2 = x^3 + x + 1 over Rational Field
457
sage: P.scheme() == P.curve()
458
True
459
sage: K.<a>=NumberField(x^2-3,'a')
460
sage: P=E.base_extend(K)(1,a)
461
sage: P.scheme()
462
Elliptic Curve defined by y^2 = x^3 + x + 1 over Number Field in a with defining polynomial x^2 - 3
463
"""
464
#The following text is just not true: it applies to the class
465
#EllipticCurvePoint, which appears to be never used, but does
466
#not apply to EllipticCurvePoint_field which is simply derived
467
#from AdditiveGroupElement.
468
#
469
#"Technically, points on curves in Sage are scheme maps from
470
# the domain Spec(F) where F is the base field of the curve to
471
# the codomain which is the curve. See also domain() and
472
# codomain()."
473
474
return self.codomain()
475
476
def domain(self):
477
"""
478
Return the domain of this point, which is `Spec(F)` where `F` is
479
the field of definition.
480
481
EXAMPLES::
482
483
sage: E=EllipticCurve(QQ,[1,1])
484
sage: P=E(0,1)
485
sage: P.domain()
486
Spectrum of Rational Field
487
sage: K.<a>=NumberField(x^2-3,'a')
488
sage: P=E.base_extend(K)(1,a)
489
sage: P.domain()
490
Spectrum of Number Field in a with defining polynomial x^2 - 3
491
"""
492
return self.parent().domain()
493
494
def codomain(self):
495
"""
496
Return the codomain of this point, which is the curve it is
497
on. Synonymous with :meth:`curve` which is perhaps more intuitive.
498
499
EXAMPLES::
500
501
sage: E=EllipticCurve(QQ,[1,1])
502
sage: P=E(0,1)
503
sage: P.domain()
504
Spectrum of Rational Field
505
sage: K.<a>=NumberField(x^2-3,'a')
506
sage: P=E.base_extend(K)(1,a)
507
sage: P.codomain()
508
Elliptic Curve defined by y^2 = x^3 + x + 1 over Number Field in a with defining polynomial x^2 - 3
509
sage: P.codomain() == P.curve()
510
True
511
"""
512
return self.parent().codomain()
513
514
def order(self):
515
r"""
516
Return the order of this point on the elliptic curve.
517
518
If the point is zero, returns 1, otherwise raise a
519
NotImplementedError.
520
521
For curves over number fields and finite fields, see below.
522
523
.. NOTE::
524
525
:meth:`additive_order` is a synonym for :meth:`order`
526
527
EXAMPLE::
528
529
sage: K.<t>=FractionField(PolynomialRing(QQ,'t'))
530
sage: E=EllipticCurve([0,0,0,-t^2,0])
531
sage: P=E(t,0)
532
sage: P.order()
533
Traceback (most recent call last):
534
...
535
NotImplementedError: Computation of order of a point not implemented over general fields.
536
sage: E(0).additive_order()
537
1
538
sage: E(0).order() == 1
539
True
540
541
"""
542
if self.is_zero():
543
return rings.Integer(1)
544
raise NotImplementedError("Computation of order of a point "
545
"not implemented over general fields.")
546
547
additive_order = order
548
549
def curve(self):
550
"""
551
Return the curve that this point is on.
552
553
EXAMPLES::
554
555
sage: E = EllipticCurve('389a')
556
sage: P = E([-1,1])
557
sage: P.curve()
558
Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field
559
"""
560
return self.scheme()
561
562
def __nonzero__(self):
563
"""
564
Return True if this is not the zero point on the curve.
565
566
EXAMPLES::
567
568
sage: E = EllipticCurve('37a')
569
sage: P = E(0); P
570
(0 : 1 : 0)
571
sage: P.is_zero()
572
True
573
sage: P = E.gens()[0]
574
sage: P.is_zero()
575
False
576
"""
577
return bool(self[2])
578
579
def has_finite_order(self):
580
"""
581
Return True if this point has finite additive order as an element
582
of the group of points on this curve.
583
584
For fields other than number fields and finite fields, this is
585
NotImplemented unless self.is_zero().
586
587
EXAMPLES::
588
589
sage: K.<t>=FractionField(PolynomialRing(QQ,'t'))
590
sage: E=EllipticCurve([0,0,0,-t^2,0])
591
sage: P = E(0)
592
sage: P.has_finite_order()
593
True
594
sage: P=E(t,0)
595
sage: P.has_finite_order()
596
Traceback (most recent call last):
597
...
598
NotImplementedError: Computation of order of a point not implemented over general fields.
599
sage: (2*P).is_zero()
600
True
601
"""
602
if self.is_zero():
603
return True
604
return self.order() != oo
605
606
is_finite_order = has_finite_order # for backward compatibility
607
608
def has_infinite_order(self):
609
"""
610
Return True if this point has infinite additive order as an element
611
of the group of points on this curve.
612
613
For fields other than number fields and finite fields, this is
614
NotImplemented unless self.is_zero().
615
616
EXAMPLES::
617
618
sage: K.<t>=FractionField(PolynomialRing(QQ,'t'))
619
sage: E=EllipticCurve([0,0,0,-t^2,0])
620
sage: P = E(0)
621
sage: P.has_infinite_order()
622
False
623
sage: P=E(t,0)
624
sage: P.has_infinite_order()
625
Traceback (most recent call last):
626
...
627
NotImplementedError: Computation of order of a point not implemented over general fields.
628
sage: (2*P).is_zero()
629
True
630
"""
631
if self.is_zero():
632
return False
633
return self.order() == oo
634
635
def plot(self, **args):
636
"""
637
Plot this point on an elliptic curve.
638
639
INPUT:
640
641
- ``**args`` -- all arguments get passed directly onto the point
642
plotting function.
643
644
EXAMPLES::
645
646
sage: E = EllipticCurve('389a')
647
sage: P = E([-1,1])
648
sage: P.plot(pointsize=30, rgbcolor=(1,0,0))
649
"""
650
if self.is_zero():
651
return plot.text("$\\infty$", (-3, 3), **args)
652
653
else:
654
return plot.point((self[0], self[1]), **args)
655
656
def _add_(self, right):
657
"""
658
Add self to right.
659
660
EXAMPLES::
661
662
sage: E = EllipticCurve('389a')
663
sage: P = E([-1,1]); Q = E([0,0])
664
sage: P + Q
665
(1 : 0 : 1)
666
sage: P._add_(Q) == P + Q
667
True
668
669
Example to show that bug :trac:`4820` is fixed::
670
671
sage: [type(c) for c in 2*EllipticCurve('37a1').gen(0)]
672
[<type 'sage.rings.rational.Rational'>,
673
<type 'sage.rings.rational.Rational'>,
674
<type 'sage.rings.rational.Rational'>]
675
"""
676
# Use Prop 7.1.7 of Cohen "A Course in Computational Algebraic
677
# Number Theory"
678
if self.is_zero():
679
return right
680
if right.is_zero():
681
return self
682
E = self.curve()
683
a1, a2, a3, a4, a6 = E.ainvs()
684
x1, y1 = self[0], self[1]
685
x2, y2 = right[0], right[1]
686
if x1 == x2 and y1 == -y2 - a1*x2 - a3:
687
return E(0) # point at infinity
688
689
if x1 == x2 and y1 == y2:
690
try:
691
m = (3*x1*x1 + 2*a2*x1 + a4 - a1*y1) / (2*y1 + a1*x1 + a3)
692
except ZeroDivisionError:
693
R = E.base_ring()
694
if R.is_finite():
695
N = R.characteristic()
696
N1 = N.gcd(ZZ(2*y1 + a1*x1 + a3))
697
N2 = N//N1
698
raise ZeroDivisionError("Inverse of %s does not exist (characteristic = %s = %s*%s)" % (2*y1 + a1*x1 + a3, N, N1, N2))
699
else:
700
raise ZeroDivisionError("Inverse of %s does not exist" % (2*y1 + a1*x1 + a3))
701
else:
702
try:
703
m = (y1-y2)/(x1-x2)
704
except ZeroDivisionError:
705
R = E.base_ring()
706
if R.is_finite():
707
N = R.characteristic()
708
from sage.rings.all import ZZ
709
N1 = N.gcd(ZZ(x1-x2))
710
N2 = N//N1
711
raise ZeroDivisionError("Inverse of %s does not exist (characteristic = %s = %s*%s)" % (x1-x2, N, N1, N2))
712
else:
713
raise ZeroDivisionError("Inverse of %s does not exist" % (x1-x2))
714
715
x3 = -x1 - x2 - a2 + m*(m+a1)
716
y3 = -y1 - a3 - a1*x3 + m*(x1-x3)
717
# See trac #4820 for why we need to coerce 1 into the base ring here:
718
return E.point([x3, y3, E.base_ring()(1)], check=False)
719
720
def _sub_(self, right):
721
"""
722
Subtract right from self.
723
724
EXAMPLES::
725
726
sage: E = EllipticCurve('389a')
727
sage: P = E([-1,1]); Q = E([0,0])
728
sage: P - Q
729
(4 : 8 : 1)
730
sage: P - Q == P._sub_(Q)
731
True
732
sage: (P - Q) + Q
733
(-1 : 1 : 1)
734
sage: P
735
(-1 : 1 : 1)
736
"""
737
return self + (-right)
738
739
def __neg__(self):
740
"""
741
Return the additive inverse of this point.
742
743
EXAMPLES::
744
745
sage: E = EllipticCurve('389a')
746
sage: P = E([-1,1])
747
sage: Q = -P; Q
748
(-1 : -2 : 1)
749
sage: Q + P
750
(0 : 1 : 0)
751
752
Example to show that bug :trac:`4820` is fixed::
753
754
sage: [type(c) for c in -EllipticCurve('37a1').gen(0)]
755
[<type 'sage.rings.rational.Rational'>,
756
<type 'sage.rings.rational.Rational'>,
757
<type 'sage.rings.rational.Rational'>]
758
"""
759
if self.is_zero():
760
return self
761
E, x, y = self.curve(), self[0], self[1]
762
# See trac #4820 for why we need to coerce 1 into the base ring here:
763
return E.point([x, -y - E.a1()*x - E.a3(), E.base_ring()(1)], check=False)
764
765
def xy(self):
766
"""
767
Return the `x` and `y` coordinates of this point, as a 2-tuple.
768
If this is the point at infinity a ZeroDivisionError is raised.
769
770
EXAMPLES::
771
772
sage: E = EllipticCurve('389a')
773
sage: P = E([-1,1])
774
sage: P.xy()
775
(-1, 1)
776
sage: Q = E(0); Q
777
(0 : 1 : 0)
778
sage: Q.xy()
779
Traceback (most recent call last):
780
...
781
ZeroDivisionError: Rational division by zero
782
"""
783
if self[2] == 1:
784
return self[0], self[1]
785
else:
786
return self[0]/self[2], self[1]/self[2]
787
788
def is_divisible_by(self, m):
789
"""
790
Return True if there exists a point `Q` defined over the same
791
field as self such that `mQ` == self.
792
793
INPUT:
794
795
- ``m`` -- a positive integer.
796
797
OUTPUT:
798
799
(bool) -- True if there is a solution, else False.
800
801
.. WARNING::
802
803
This function usually triggers the computation of the
804
`m`-th division polynomial of the associated elliptic
805
curve, which will be expensive if `m` is large, though it
806
will be cached for subsequent calls with the same `m`.
807
808
EXAMPLES::
809
810
sage: E = EllipticCurve('389a')
811
sage: Q = 5*E(0,0); Q
812
(-2739/1444 : -77033/54872 : 1)
813
sage: Q.is_divisible_by(4)
814
False
815
sage: Q.is_divisible_by(5)
816
True
817
818
A finite field example::
819
820
sage: E = EllipticCurve(GF(101),[23,34])
821
sage: E.cardinality().factor()
822
2 * 53
823
sage: Set([T.order() for T in E.points()])
824
{1, 106, 2, 53}
825
sage: len([T for T in E.points() if T.is_divisible_by(2)])
826
53
827
sage: len([T for T in E.points() if T.is_divisible_by(3)])
828
106
829
830
TESTS:
831
832
This shows that the bug reported at :trac:`10076` is fixed::
833
834
sage: K = QuadraticField(8,'a')
835
sage: E = EllipticCurve([K(0),0,0,-1,0])
836
sage: P = E([-1,0])
837
sage: P.is_divisible_by(2)
838
False
839
sage: P.division_points(2)
840
[]
841
842
Note that it is not sufficient to test that
843
``self.division_points(m,poly_only=True)`` has roots::
844
845
sage: P.division_points(2, poly_only=True).roots()
846
[(1/2*a - 1, 1), (-1/2*a - 1, 1)]
847
848
sage: tor = E.torsion_points(); len(tor)
849
8
850
sage: [T.order() for T in tor]
851
[2, 4, 4, 2, 1, 2, 4, 4]
852
sage: all([T.is_divisible_by(3) for T in tor])
853
True
854
sage: Set([T for T in tor if T.is_divisible_by(2)])
855
{(0 : 1 : 0), (1 : 0 : 1)}
856
sage: Set([2*T for T in tor])
857
{(0 : 1 : 0), (1 : 0 : 1)}
858
859
860
"""
861
# Coerce the input m to an integer
862
m = rings.Integer(m)
863
864
# Check for trivial cases of m = 1, -1 and 0.
865
if m == 1 or m == -1:
866
return True
867
if m == 0:
868
return self == 0 # then m*self=self for all m!
869
m = m.abs()
870
871
# Now the following line would of course be correct, but we
872
# work harder to be more efficient:
873
# return len(self.division_points(m)) > 0
874
875
P = self
876
877
# If P has finite order n and gcd(m,n)=1 then the result is
878
# True. However, over general fields computing P.order() is
879
# not implemented.
880
881
try:
882
n = P.order()
883
if not n == oo:
884
if m.gcd(n) == 1:
885
return True
886
except NotImplementedError:
887
pass
888
889
P_is_2_torsion = (P == -P)
890
g = P.division_points(m, poly_only=True)
891
892
if not P_is_2_torsion:
893
# In this case deg(g)=m^2, and each root in K lifts to two
894
# points Q,-Q both in E(K), of which exactly one is a
895
# solution. So we just check the existence of roots:
896
return len(g.roots()) > 0
897
898
# Now 2*P==0
899
900
if m % 2 == 1:
901
return True # P itself is a solution when m is odd
902
903
# Now m is even and 2*P=0. Roots of g in K may or may not
904
# lift to solutions in E(K), so we fall back to the default.
905
# Note that division polynomials are cached so this is not
906
# inefficient:
907
908
return len(self.division_points(m)) > 0
909
910
def division_points(self, m, poly_only=False):
911
r"""
912
Return a list of all points `Q` such that `mQ=P` where `P` = self.
913
914
Only points on the elliptic curve containing self and defined
915
over the base field are included.
916
917
INPUT:
918
919
- ``m`` -- a positive integer
920
921
- ``poly_only`` -- bool (default: False); if True return
922
polynomial whose roots give all possible `x`-coordinates of
923
`m`-th roots of self.
924
925
OUTPUT:
926
927
(list) -- a (possibly empty) list of solutions `Q` to `mQ=P`,
928
where `P` = self.
929
930
EXAMPLES:
931
932
We find the five 5-torsion points on an elliptic curve::
933
934
sage: E = EllipticCurve('11a'); E
935
Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
936
sage: P = E(0); P
937
(0 : 1 : 0)
938
sage: P.division_points(5)
939
[(0 : 1 : 0), (5 : -6 : 1), (5 : 5 : 1), (16 : -61 : 1), (16 : 60 : 1)]
940
941
Note above that 0 is included since [5]*0 = 0.
942
943
We create a curve of rank 1 with no torsion and do a consistency check::
944
945
sage: E = EllipticCurve('11a').quadratic_twist(-7)
946
sage: Q = E([44,-270])
947
sage: (4*Q).division_points(4)
948
[(44 : -270 : 1)]
949
950
We create a curve over a non-prime finite field with group of
951
order `18`::
952
953
sage: k.<a> = GF(25)
954
sage: E = EllipticCurve(k, [1,2+a,3,4*a,2])
955
sage: P = E([3,3*a+4])
956
sage: factor(E.order())
957
2 * 3^2
958
sage: P.order()
959
9
960
961
We find the `1`-division points as a consistency check -- there
962
is just one, of course::
963
964
sage: P.division_points(1)
965
[(3 : 3*a + 4 : 1)]
966
967
The point `P` has order coprime to 2 but divisible by 3, so::
968
969
sage: P.division_points(2)
970
[(2*a + 1 : 3*a + 4 : 1), (3*a + 1 : a : 1)]
971
972
We check that each of the 2-division points works as claimed::
973
974
sage: [2*Q for Q in P.division_points(2)]
975
[(3 : 3*a + 4 : 1), (3 : 3*a + 4 : 1)]
976
977
Some other checks::
978
979
sage: P.division_points(3)
980
[]
981
sage: P.division_points(4)
982
[(0 : 3*a + 2 : 1), (1 : 0 : 1)]
983
sage: P.division_points(5)
984
[(1 : 1 : 1)]
985
986
An example over a number field (see :trac:`3383`)::
987
988
sage: E = EllipticCurve('19a1')
989
sage: K.<t> = NumberField(x^9-3*x^8-4*x^7+16*x^6-3*x^5-21*x^4+5*x^3+7*x^2-7*x+1)
990
sage: EK = E.base_extend(K)
991
sage: E(0).division_points(3)
992
[(0 : 1 : 0), (5 : -10 : 1), (5 : 9 : 1)]
993
sage: EK(0).division_points(3)
994
[(0 : 1 : 0), (5 : 9 : 1), (5 : -10 : 1)]
995
sage: E(0).division_points(9)
996
[(0 : 1 : 0), (5 : -10 : 1), (5 : 9 : 1)]
997
sage: EK(0).division_points(9)
998
[(0 : 1 : 0), (5 : 9 : 1), (5 : -10 : 1), (-150/121*t^8 + 414/121*t^7 + 1481/242*t^6 - 2382/121*t^5 - 103/242*t^4 + 629/22*t^3 - 367/242*t^2 - 1307/121*t + 625/121 : 35/484*t^8 - 133/242*t^7 + 445/242*t^6 - 799/242*t^5 + 373/484*t^4 + 113/22*t^3 - 2355/484*t^2 - 753/242*t + 1165/484 : 1), (-150/121*t^8 + 414/121*t^7 + 1481/242*t^6 - 2382/121*t^5 - 103/242*t^4 + 629/22*t^3 - 367/242*t^2 - 1307/121*t + 625/121 : -35/484*t^8 + 133/242*t^7 - 445/242*t^6 + 799/242*t^5 - 373/484*t^4 - 113/22*t^3 + 2355/484*t^2 + 753/242*t - 1649/484 : 1), (-1383/484*t^8 + 970/121*t^7 + 3159/242*t^6 - 5211/121*t^5 + 37/484*t^4 + 654/11*t^3 - 909/484*t^2 - 4831/242*t + 6791/484 : 927/121*t^8 - 5209/242*t^7 - 8187/242*t^6 + 27975/242*t^5 - 1147/242*t^4 - 1729/11*t^3 + 1566/121*t^2 + 12873/242*t - 10871/242 : 1), (-1383/484*t^8 + 970/121*t^7 + 3159/242*t^6 - 5211/121*t^5 + 37/484*t^4 + 654/11*t^3 - 909/484*t^2 - 4831/242*t + 6791/484 : -927/121*t^8 + 5209/242*t^7 + 8187/242*t^6 - 27975/242*t^5 + 1147/242*t^4 + 1729/11*t^3 - 1566/121*t^2 - 12873/242*t + 10629/242 : 1), (-4793/484*t^8 + 6791/242*t^7 + 10727/242*t^6 - 18301/121*t^5 + 2347/484*t^4 + 2293/11*t^3 - 7311/484*t^2 - 17239/242*t + 26767/484 : 30847/484*t^8 - 21789/121*t^7 - 34605/121*t^6 + 117164/121*t^5 - 10633/484*t^4 - 29437/22*t^3 + 39725/484*t^2 + 55428/121*t - 176909/484 : 1), (-4793/484*t^8 + 6791/242*t^7 + 10727/242*t^6 - 18301/121*t^5 + 2347/484*t^4 + 2293/11*t^3 - 7311/484*t^2 - 17239/242*t + 26767/484 : -30847/484*t^8 + 21789/121*t^7 + 34605/121*t^6 - 117164/121*t^5 + 10633/484*t^4 + 29437/22*t^3 - 39725/484*t^2 - 55428/121*t + 176425/484 : 1)]
999
1000
"""
1001
# Coerce the input m to an integer
1002
m = rings.Integer(m)
1003
# Check for trivial cases of m = 1, -1 and 0.
1004
if m == 1 or m == -1:
1005
return [self]
1006
if m == 0:
1007
if self == 0: # then every point Q is a solution, but...
1008
return [self]
1009
else:
1010
return []
1011
1012
# ans will contain the list of division points.
1013
ans = []
1014
1015
# We compute a polynomial g whose roots give all possible x
1016
# coordinates of the m-division points. The number of
1017
# solutions (over the algebraic closure) is m^2, assuming that
1018
# the characteristic does not divide m.
1019
1020
E = self.curve()
1021
P = self
1022
nP = -P
1023
P_is_2_torsion = (P == nP)
1024
1025
# If self is the 0, then self is a solution, and the correct
1026
# poly is the m'th division polynomial
1027
if P == 0:
1028
ans.append(P)
1029
g = E.division_polynomial(m)
1030
else:
1031
# The poly g here is 0 at x(Q) iff x(m*Q) = x(P).
1032
g = E._multiple_x_numerator(m) - P[0]*E._multiple_x_denominator(m)
1033
1034
# When 2*P=0, then -Q is a solution iff Q is. For even m,
1035
# no 2-torsion point is a solution, so that g is the
1036
# square of a polynomial g1 of degree m^2/2, and each root
1037
# of g1 leads to a pair of solutions Q, -Q to m*Q=P. For
1038
# odd m, P itself is the only 2-torsion solution, so g has
1039
# the form (x-x(P))*g1(x)^2 where g1 has degree (m^2-1)/2
1040
# and each root of g1 leads to a pair Q, -Q.
1041
1042
if P_is_2_torsion:
1043
if m % 2 == 0:
1044
# This computes g.sqrt() which is not implemented
1045
g = g.gcd(g.derivative())*g.leading_coefficient().sqrt()
1046
1047
# When 2*P!=0, then for each solution Q to m*Q=P, -Q is
1048
# not a solution (and points of order 2 are not
1049
# solutions). Hence the roots of g are distinct and each
1050
# gives rise to precisely one solution Q.
1051
1052
else:
1053
g0 = g.variables()[0] - P[0]
1054
g = g // g0
1055
g = g.gcd(g.derivative())*g.leading_coefficient().sqrt()
1056
g = g0*g
1057
1058
if poly_only:
1059
return g
1060
1061
for x in g.roots(multiplicities=False):
1062
if E.is_x_coord(x):
1063
# Make a point on the curve with this x coordinate.
1064
Q = E.lift_x(x)
1065
nQ = -Q
1066
mQ = m*Q
1067
# if P==-P then Q works iff -Q works, so we include
1068
# both unless they are equal:
1069
if P_is_2_torsion:
1070
if mQ == P:
1071
ans.append(Q)
1072
if nQ != Q:
1073
ans.append(nQ)
1074
else:
1075
# P is not 2-torsion so at most one of Q, -Q works
1076
# and we must try both:
1077
if mQ == P:
1078
ans.append(Q)
1079
elif mQ == nP:
1080
ans.append(nQ)
1081
1082
# Finally, sort and return
1083
ans.sort()
1084
return ans
1085
1086
def _divide_out(self, p):
1087
r"""
1088
Return `(Q,k)` where `p^kQ` == self and `Q` cannot be divided by `p`.
1089
1090
..WARNING:
1091
1092
It is up to the caller to make sure that this does not loop
1093
endlessly. It is used in
1094
``EllipticCurve_generic._p_primary_torsion_basis()``, when
1095
self will always have (finite) order which is a power of `p`,
1096
so that the order of `Q` increases by a factor of `p` at each
1097
stage.
1098
1099
Since it will clearly be in danger of looping when
1100
self.is_zero(), this case is caught, but otherwise caveat
1101
user.
1102
1103
EXAMPLES::
1104
1105
sage: E = EllipticCurve('37a1')
1106
sage: P = E([0, 0])
1107
sage: R = 12*P
1108
sage: R._divide_out(2)
1109
((-1 : -1 : 1), 2)
1110
sage: R._divide_out(3)
1111
((2 : -3 : 1), 1)
1112
sage: R._divide_out(5)
1113
((1357/841 : 28888/24389 : 1), 0)
1114
sage: R._divide_out(12)
1115
Traceback (most recent call last):
1116
...
1117
ValueError: p (=12) should be prime.
1118
"""
1119
p = rings.Integer(p)
1120
if not p.is_prime():
1121
raise ValueError("p (=%s) should be prime." % p)
1122
1123
if self.is_zero():
1124
raise ValueError("self must not be 0.")
1125
1126
k = 0
1127
Q = self
1128
pts = Q.division_points(p)
1129
while len(pts) > 0:
1130
Q = pts[0]
1131
k += 1
1132
pts = Q.division_points(p)
1133
return (Q, k)
1134
1135
def set_order(self, value):
1136
r"""
1137
Set the value of self._order to value.
1138
1139
Use this when you know a priori the order of this point to avoid a
1140
potentially expensive order calculation.
1141
1142
INPUT:
1143
1144
- ``value`` - positive Integer
1145
1146
OUTPUT:
1147
1148
``None``
1149
1150
EXAMPLES:
1151
1152
This example illustrates basic usage.
1153
1154
::
1155
1156
sage: E = EllipticCurve(GF(7), [0, 1]) # This curve has order 6
1157
sage: G = E(5, 0)
1158
sage: G.set_order(2)
1159
sage: 2*G
1160
(0 : 1 : 0)
1161
1162
We now give a more interesting case, the NIST-P521 curve. Its
1163
order is too big to calculate with SAGE, and takes a long time
1164
using other packages, so it is very useful here.
1165
1166
::
1167
1168
sage: p = 2^521 - 1
1169
sage: prev_proof_state = proof.arithmetic()
1170
sage: proof.arithmetic(False) # turn off primality checking
1171
sage: F = GF(p)
1172
sage: A = p - 3
1173
sage: B = 1093849038073734274511112390766805569936207598951683748994586394495953116150735016013708737573759623248592132296706313309438452531591012912142327488478985984
1174
sage: q = 6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449
1175
sage: E = EllipticCurve([F(A), F(B)])
1176
sage: G = E.random_point()
1177
sage: G.set_order(q)
1178
sage: G.order() * G # This takes practically no time.
1179
(0 : 1 : 0)
1180
sage: proof.arithmetic(prev_proof_state) # restore state
1181
1182
It is an error to pass a `value` equal to `0`::
1183
1184
sage: E = EllipticCurve(GF(7), [0, 1]) # This curve has order 6
1185
sage: G = E.random_point()
1186
sage: G.set_order(0)
1187
Traceback (most recent call last):
1188
...
1189
ValueError: Value 0 illegal for point order
1190
sage: G.set_order(1000)
1191
Traceback (most recent call last):
1192
...
1193
ValueError: Value 1000 illegal: outside max Hasse bound
1194
1195
It is also very likely an error to pass a value which is not the actual
1196
order of this point. How unlikely is determined by the factorization of
1197
the actual order, and the actual group structure::
1198
1199
sage: E = EllipticCurve(GF(7), [0, 1]) # This curve has order 6
1200
sage: G = E(5, 0) # G has order 2
1201
sage: G.set_order(11)
1202
Traceback (most recent call last):
1203
...
1204
ValueError: Value 11 illegal: 11 * (5 : 0 : 1) is not the identity
1205
1206
However, set_order can be fooled, though it's not likely in "real cases
1207
of interest". For instance, the order can be set to a multiple the
1208
actual order::
1209
1210
sage: E = EllipticCurve(GF(7), [0, 1]) # This curve has order 6
1211
sage: G = E(5, 0) # G has order 2
1212
sage: G.set_order(8)
1213
sage: G.order()
1214
8
1215
1216
NOTES:
1217
1218
The implementation is based of the fact that orders of elliptic curve
1219
points are cached in the (pseudo-private) _order slot.
1220
1221
AUTHORS:
1222
1223
- Mariah Lenox (2011-02-16)
1224
"""
1225
E = self.curve()
1226
q = E.base_ring().order()
1227
O = E(0)
1228
if value == 0:
1229
raise ValueError('Value 0 illegal for point order')
1230
if value == 1:
1231
if self == O:
1232
self._order = 1
1233
return
1234
else:
1235
raise ValueError('Value 1 illegal order for non-identity')
1236
low, hi = Hasse_bounds(q)
1237
if value > hi:
1238
raise ValueError('Value %s illegal: outside max Hasse bound' % value)
1239
if value * self != O:
1240
raise ValueError('Value %s illegal: %s * %s is not the identity' % (value, value, self))
1241
if (value - 1) * self == O:
1242
raise ValueError('Value %s illegal: %s * %s is the identity' % (value, value-1, self))
1243
self._order = value
1244
1245
############################## end ################################
1246
1247
def _line_(self, R, Q):
1248
r"""
1249
Computes the value at `Q` of a straight line through points
1250
self and `R`.
1251
1252
INPUT:
1253
1254
- ``R, Q`` -- points on self.curve() with ``Q`` nonzero.
1255
1256
OUTPUT:
1257
1258
An element of the base field self.curve().base_field().
1259
A ValueError is raised if ``Q`` is zero.
1260
1261
EXAMPLES::
1262
1263
sage: F.<a>=GF(2^5)
1264
sage: E=EllipticCurve(F,[0,0,1,1,1])
1265
sage: P = E(a^4 + 1, a^3)
1266
sage: Q = E(a^4, a^4 + a^3)
1267
sage: O = E(0)
1268
sage: P._line_(P,-2*P) == 0
1269
True
1270
sage: P._line_(Q,-(P+Q)) == 0
1271
True
1272
sage: O._line_(O,Q) == F(1)
1273
True
1274
sage: P._line_(O,Q) == a^4 - a^4 + 1
1275
True
1276
sage: P._line_(13*P,Q) == a^4
1277
True
1278
sage: P._line_(P,Q) == a^4 + a^3 + a^2 + 1
1279
True
1280
1281
See :trac:`7116`::
1282
1283
sage: P._line_ (Q,O)
1284
Traceback (most recent call last):
1285
...
1286
ValueError: Q must be nonzero.
1287
1288
..NOTES:
1289
1290
This function is used in _miller_ algorithm.
1291
1292
AUTHOR:
1293
1294
- David Hansen (2009-01-25)
1295
"""
1296
if Q.is_zero():
1297
raise ValueError("Q must be nonzero.")
1298
1299
if self.is_zero() or R.is_zero():
1300
if self == R:
1301
return self.curve().base_field().one_element()
1302
if self.is_zero():
1303
return Q[0] - R[0]
1304
if R.is_zero():
1305
return Q[0] - self[0]
1306
elif self != R:
1307
if self[0] == R[0]:
1308
return Q[0] - self[0]
1309
else:
1310
l = (R[1] - self[1])/(R[0] - self[0])
1311
return Q[1] - self[1] - l * (Q[0] - self[0])
1312
else:
1313
a1, a2, a3, a4, a6 = self.curve().a_invariants()
1314
numerator = (3*self[0]**2 + 2*a2*self[0] + a4 - a1*self[1])
1315
denominator = (2*self[1] + a1*self[0] + a3)
1316
if denominator == 0:
1317
return Q[0] - self[0]
1318
else:
1319
l = numerator/denominator
1320
return Q[1] - self[1] - l * (Q[0] - self[0])
1321
1322
def _miller_(self, Q, n):
1323
r"""
1324
Return the value at `Q` of the rational function `f_{n,P}`, where the
1325
divisor of `f_{n,P}` is `n[P]-[nP]-(n-1)[O]`.
1326
1327
INPUT:
1328
1329
- ``Q`` -- a nonzero point on self.curve().
1330
1331
- ``n`` -- an nonzero integer. If `n<0` then return `Q`
1332
evaluated at `1/(v_{nP}*f_{n,P})` (used in the ate pairing).
1333
1334
OUTPUT:
1335
1336
An element in the base field self.curve().base_field()
1337
A ValueError is raised if `Q` is zero.
1338
1339
EXAMPLES::
1340
1341
sage: F.<a>=GF(2^5)
1342
sage: E=EllipticCurve(F,[0,0,1,1,1])
1343
sage: P = E(a^4 + 1, a^3)
1344
sage: Fx.<b>=GF(2^(4*5))
1345
sage: Ex=EllipticCurve(Fx,[0,0,1,1,1])
1346
sage: phi=Hom(F,Fx)(F.gen().minpoly().roots(Fx)[0][0])
1347
sage: Px=Ex(phi(P.xy()[0]),phi(P.xy()[1]))
1348
sage: Qx = Ex(b^19 + b^18 + b^16 + b^12 + b^10 + b^9 + b^8 + b^5 + b^3 + 1, b^18 + b^13 + b^10 + b^8 + b^5 + b^4 + b^3 + b)
1349
sage: Px._miller_(Qx,41) == b^17 + b^13 + b^12 + b^9 + b^8 + b^6 + b^4 + 1
1350
True
1351
sage: Qx._miller_(Px,41) == b^13 + b^10 + b^8 + b^7 + b^6 + b^5
1352
True
1353
sage: P._miller_(E(0),41)
1354
Traceback (most recent call last):
1355
...
1356
ValueError: Q must be nonzero.
1357
1358
An example of even order::
1359
1360
sage: F.<a> = GF(19^4)
1361
sage: E = EllipticCurve(F,[-1,0])
1362
sage: P = E(15*a^3 + 17*a^2 + 14*a + 13,16*a^3 + 7*a^2 + a + 18)
1363
sage: Q = E(10*a^3 + 16*a^2 + 4*a + 2, 6*a^3 + 4*a^2 + 3*a + 2)
1364
sage: x=P.weil_pairing(Q,360)
1365
sage: x^360 == F(1)
1366
True
1367
1368
You can use the _miller_ function on linearly dependent
1369
points, but with the risk of a dividing with zero::
1370
1371
sage: Px._miller_(2*Px,41)
1372
Traceback (most recent call last):
1373
...
1374
ZeroDivisionError: division by zero in finite field.
1375
1376
A small example of embedding degree 6::
1377
1378
sage: q = 401; F = GF(q); a = 146; b = 400; k = 6
1379
sage: E = EllipticCurve([F(a), F(b)])
1380
sage: R.<x> = F[]; K.<a> = GF(q^k, modulus=x^6 + 4*x^4 + 115*x^3 + 81*x^2 + 51*x + 3)
1381
sage: EK = E.base_extend(K)
1382
sage: P = E([F(338), F(227)])
1383
sage: Q_x = 333*a^5 + 391*a^4 + 160*a^3 + 335*a^2 + 71*a + 93
1384
sage: Q_y = 343*a^5 + 273*a^4 + 26*a^3 + 342*a^2 + 340*a + 210
1385
sage: Q = EK([Q_x, Q_y])
1386
sage: P._miller_(Q, 127)
1387
371*a^5 + 39*a^4 + 355*a^3 + 233*a^2 + 20*a + 275
1388
1389
A series of small examples and small torsions. We start with
1390
`n=1`, which is trivial: the function is the constant
1391
1::
1392
1393
sage: E = EllipticCurve([GF(7)(0), 2])
1394
sage: P = E(5, 1); Q = E(0, 3); I = E(0)
1395
sage: I._miller_(P, 1)
1396
1
1397
sage: I._miller_(Q, 1)
1398
1
1399
1400
A two-torsion example. In this case `f_{n,P}(Q) = x_Q - x_P`::
1401
1402
sage: E = EllipticCurve([GF(7)(-1), 0])
1403
sage: P = E(0,0); Q = E(1, 0);
1404
sage: P._miller_(P, 2)
1405
0
1406
sage: Q._miller_(Q, 2)
1407
0
1408
sage: P._miller_(Q, 2)
1409
1
1410
sage: Q._miller_(P, 2)
1411
6
1412
1413
A three-torsion example::
1414
1415
sage: E = EllipticCurve([GF(7)(0), 2])
1416
sage: P = E(5, 1); Q = E(0, 3);
1417
sage: P._miller_(Q, 3)
1418
4
1419
1420
A 4-torsion example::
1421
1422
sage: E = EllipticCurve([GF(7)(-1), 0])
1423
sage: P = E(5, 1); Q = E(4, 2)
1424
sage: P._miller_(Q, 4)
1425
3
1426
1427
A 5-torsion example::
1428
1429
sage: E = EllipticCurve([GF(7)(-1), 4])
1430
sage: P = E(4, 1); Q = E(6, 5)
1431
sage: P._miller_(Q, 5)
1432
1
1433
1434
A 6-torsion example::
1435
1436
sage: E = EllipticCurve([GF(7)(3), 1])
1437
sage: P = E(5, 1); Q = E(3, 3)
1438
sage: P._miller_(Q, 6)
1439
5
1440
1441
An example which is part of an ate pairing calculation. The trace of
1442
the curve is negative, so it should exercise the `n<0` case in the
1443
code::
1444
1445
sage: p = 2017; A = 1; B = 30; r = 29; t = -70; k = 7;
1446
sage: F = GF(p); R.<x> = F[]
1447
sage: E = EllipticCurve([F(A), F(B)]); P = E(369, 716)
1448
sage: K.<a> = GF(p^k, modulus=x^k+2); EK = E.base_extend(K)
1449
sage: Qx = 1226*a^6 + 1778*a^5 + 660*a^4 + 1791*a^3 + 1750*a^2 + 867*a + 770
1450
sage: Qy = 1764*a^6 + 198*a^5 + 1206*a^4 + 406*a^3 + 1200*a^2 + 273*a + 1712
1451
sage: Q = EK(Qx, Qy)
1452
sage: Q._miller_(P, t-1)
1453
1311*a^6 + 1362*a^5 + 1177*a^4 + 807*a^3 + 1331*a^2 + 1530*a + 1931
1454
1455
ALGORITHM:
1456
1457
Double-and-add. See also [Mil04]_.
1458
1459
AUTHORS:
1460
1461
- David Hansen (2009-01-25)
1462
- Mariah Lenox (2011-03-07) -- Added more doctests and support for
1463
negative n.
1464
"""
1465
if Q.is_zero():
1466
raise ValueError("Q must be nonzero.")
1467
if n.is_zero():
1468
raise ValueError("n must be nonzero.")
1469
n_is_negative = False
1470
if n < 0:
1471
n = n.abs()
1472
n_is_negative = True
1473
1474
one = self.curve().base_field().one_element()
1475
t = one
1476
V = self
1477
S = 2*V
1478
nbin = n.bits()
1479
i = n.nbits() - 2
1480
while i > -1:
1481
S = 2*V
1482
ell = V._line_(V, Q)
1483
vee = S._line_(-S, Q)
1484
t = (t**2)*(ell/vee)
1485
V = S
1486
if nbin[i] == 1:
1487
S = V+self
1488
ell = V._line_(self, Q)
1489
vee = S._line_(-S, Q)
1490
t = t*(ell/vee)
1491
V = S
1492
i = i-1
1493
if n_is_negative:
1494
vee = V._line_(-V, Q)
1495
t = 1/(t*vee)
1496
return t
1497
1498
def weil_pairing(self, Q, n):
1499
r"""
1500
Compute the Weil pairing of self and `Q` using Miller's algorithm.
1501
1502
INPUT:
1503
1504
- ``Q`` -- a point on self.curve().
1505
1506
- ``n`` -- an integer `n` such that `nP = nQ = (0:1:0)` where
1507
`P` = self.
1508
1509
OUTPUT:
1510
1511
An `n`'th root of unity in the base field self.curve().base_field()
1512
1513
EXAMPLES::
1514
1515
sage: F.<a>=GF(2^5)
1516
sage: E=EllipticCurve(F,[0,0,1,1,1])
1517
sage: P = E(a^4 + 1, a^3)
1518
sage: Fx.<b>=GF(2^(4*5))
1519
sage: Ex=EllipticCurve(Fx,[0,0,1,1,1])
1520
sage: phi=Hom(F,Fx)(F.gen().minpoly().roots(Fx)[0][0])
1521
sage: Px=Ex(phi(P.xy()[0]),phi(P.xy()[1]))
1522
sage: O = Ex(0)
1523
sage: Qx = Ex(b^19 + b^18 + b^16 + b^12 + b^10 + b^9 + b^8 + b^5 + b^3 + 1, b^18 + b^13 + b^10 + b^8 + b^5 + b^4 + b^3 + b)
1524
sage: Px.weil_pairing(Qx,41) == b^19 + b^15 + b^9 + b^8 + b^6 + b^4 + b^3 + b^2 + 1
1525
True
1526
sage: Px.weil_pairing(17*Px,41) == Fx(1)
1527
True
1528
sage: Px.weil_pairing(O,41) == Fx(1)
1529
True
1530
1531
An error is raised if either point is not n-torsion::
1532
1533
sage: Px.weil_pairing(O,40)
1534
Traceback (most recent call last):
1535
...
1536
ValueError: points must both be n-torsion
1537
1538
A larger example (see :trac:`4964`)::
1539
1540
sage: P,Q = EllipticCurve(GF(19^4,'a'),[-1,0]).gens()
1541
sage: P.order(), Q.order()
1542
(360, 360)
1543
sage: z = P.weil_pairing(Q,360)
1544
sage: z.multiplicative_order()
1545
360
1546
1547
An example over a number field::
1548
1549
sage: P,Q = EllipticCurve('11a1').change_ring(CyclotomicField(5)).torsion_subgroup().gens() # long time (10s)
1550
sage: P,Q = (P.element(), Q.element()) # long time
1551
sage: (P.order(),Q.order()) # long time
1552
(5, 5)
1553
sage: P.weil_pairing(Q,5) # long time
1554
zeta5^2
1555
sage: Q.weil_pairing(P,5) # long time
1556
zeta5^3
1557
1558
ALGORITHM:
1559
1560
Implemented using Proposition 8 in [Mil04]_. The value 1 is
1561
returned for linearly dependent input points. This condition
1562
is caught via a DivisionByZeroError, since the use of a
1563
discrete logarithm test for linear dependence, is much too slow
1564
for large `n`.
1565
1566
REFERENCES:
1567
1568
.. [Mil04] Victor S. Miller, "The Weil pairing, and its
1569
efficient calculation", J. Cryptol., 17(4):235-261, 2004
1570
1571
AUTHOR:
1572
1573
- David Hansen (2009-01-25)
1574
"""
1575
P = self
1576
E = P.curve()
1577
1578
if not Q.curve() is E:
1579
raise ValueError("points must both be on the same curve")
1580
1581
# Test if P, Q are both in E[n]
1582
if not ((n*P).is_zero() and (n*Q).is_zero()):
1583
raise ValueError("points must both be n-torsion")
1584
1585
one = E.base_field().one_element()
1586
1587
# Case where P = Q
1588
if P == Q:
1589
return one
1590
1591
# Case where P = O or Q = O
1592
if P.is_zero() or Q.is_zero():
1593
return one
1594
1595
# The non-trivial case P != Q
1596
1597
# Note (2010-12-29): The following code block should not be
1598
# used. It attempts to reduce the pairing calculation to order
1599
# d = gcd(|P|,|Q|) instead of order n, but this approach is
1600
# counterproductive, since calculating |P| and |Q| is much
1601
# slower than calculating the pairing [BGN05].
1602
#
1603
# [BGN05] D. Boneh, E. Goh, and K. Nissim, "Evaluating 2-DNF
1604
# Formulas on Ciphertexts", TCC 2005, LNCS 3378, pp. 325-341.
1605
#
1606
# Reduction to order d = gcd(|P|,|Q|); value is a d'th root of unity
1607
# try:
1608
# nP = P.order()
1609
# except AttributeError:
1610
# nP = generic.order_from_multiple(P,n,operation='+')
1611
# try:
1612
# nQ = Q.order()
1613
# except AttributeError:
1614
# nQ = generic.order_from_multiple(Q,n,operation='+')
1615
# d = arith.gcd(nP,nQ)
1616
# if d==1:
1617
# return one
1618
#
1619
# P = (nP//d)*P # order d
1620
# Q = (nQ//d)*Q # order d
1621
# n = d
1622
1623
try:
1624
return ((-1)**n.test_bit(0))*(P._miller_(Q, n)/Q._miller_(P, n))
1625
except ZeroDivisionError:
1626
return one
1627
1628
def tate_pairing(self, Q, n, k, q=None):
1629
r"""
1630
Return Tate pairing of `n`-torsion point `P = self` and point `Q`.
1631
1632
The value returned is `f_{n,P}(Q)^e` where `f_{n,P}` is a function with
1633
divisor `n[P]-n[O].`. This is also known as the "modified Tate
1634
pairing". It is a well-defined bilinear map.
1635
1636
INPUT:
1637
1638
- ``P=self`` -- Elliptic curve point having order n
1639
1640
- ``Q`` -- Elliptic curve point on same curve as P (can be any order)
1641
1642
- ``n`` -- positive integer: order of P
1643
1644
- ``k`` -- positive integer: embedding degree
1645
1646
- ``q`` -- positive integer: size of base field (the "big"
1647
field is `GF(q^k)`. `q` needs to be set only if its value
1648
cannot be deduced.)
1649
1650
OUTPUT:
1651
1652
An `n`'th root of unity in the base field self.curve().base_field()
1653
1654
EXAMPLES:
1655
1656
A simple example, pairing a point with itself, and pairing a point with
1657
another rational point::
1658
1659
sage: p = 103; A = 1; B = 18; E = EllipticCurve(GF(p), [A, B])
1660
sage: P = E(33, 91); n = P.order(); n
1661
19
1662
sage: k = GF(n)(p).multiplicative_order(); k
1663
6
1664
sage: P.tate_pairing(P, n, k)
1665
1
1666
sage: Q = E(87, 51)
1667
sage: P.tate_pairing(Q, n, k)
1668
1
1669
sage: set_random_seed(35)
1670
sage: P.tate_pairing(P,n,k)
1671
1
1672
1673
We now let Q be a point on the same curve as above, but defined over
1674
the pairing extension field, and we also demonstrate the bilinearity of
1675
the pairing::
1676
1677
sage: K.<a> = GF(p^k)
1678
sage: EK = E.base_extend(K); P = EK(P)
1679
sage: Qx = 69*a^5 + 96*a^4 + 22*a^3 + 86*a^2 + 6*a + 35
1680
sage: Qy = 34*a^5 + 24*a^4 + 16*a^3 + 41*a^2 + 4*a + 40
1681
sage: Q = EK(Qx, Qy);
1682
sage: # multiply by cofactor so Q has order n:
1683
sage: h = 551269674; Q = h*Q
1684
sage: P = EK(P); P.tate_pairing(Q, n, k)
1685
24*a^5 + 34*a^4 + 3*a^3 + 69*a^2 + 86*a + 45
1686
sage: s = Integer(randrange(1,n))
1687
sage: ans1 = (s*P).tate_pairing(Q, n, k)
1688
sage: ans2 = P.tate_pairing(s*Q, n, k)
1689
sage: ans3 = P.tate_pairing(Q, n, k)^s
1690
sage: ans1 == ans2 == ans3
1691
True
1692
sage: (ans1 != 1) and (ans1^n == 1)
1693
True
1694
1695
Here is an example of using the Tate pairing to compute the Weil
1696
pairing (using the same data as above)::
1697
1698
sage: e = Integer((p^k-1)/n); e
1699
62844857712
1700
sage: P.weil_pairing(Q, n)^e
1701
94*a^5 + 99*a^4 + 29*a^3 + 45*a^2 + 57*a + 34
1702
sage: P.tate_pairing(Q, n, k) == P._miller_(Q, n)^e
1703
True
1704
sage: Q.tate_pairing(P, n, k) == Q._miller_(P, n)^e
1705
True
1706
sage: P.tate_pairing(Q, n, k)/Q.tate_pairing(P, n, k)
1707
94*a^5 + 99*a^4 + 29*a^3 + 45*a^2 + 57*a + 34
1708
1709
An example where we have to pass the base field size (and we again have
1710
agreement with the Weil pairing)::
1711
1712
sage: F.<a>=GF(2^5)
1713
sage: E=EllipticCurve(F,[0,0,1,1,1])
1714
sage: P = E(a^4 + 1, a^3)
1715
sage: Fx.<b>=GF(2^(4*5))
1716
sage: Ex=EllipticCurve(Fx,[0,0,1,1,1])
1717
sage: phi=Hom(F,Fx)(F.gen().minpoly().roots(Fx)[0][0])
1718
sage: Px=Ex(phi(P.xy()[0]),phi(P.xy()[1]))
1719
sage: Qx = Ex(b^19+b^18+b^16+b^12+b^10+b^9+b^8+b^5+b^3+1, b^18+b^13+b^10+b^8+b^5+b^4+b^3+b)
1720
sage: Px.tate_pairing(Qx, n=41, k=4)
1721
Traceback (most recent call last):
1722
...
1723
ValueError: Unexpected field degree: set keyword argument q equal to the size of the base field (big field is GF(q^4)).
1724
sage: num = Px.tate_pairing(Qx, n=41, k=4, q=32); num
1725
b^19 + b^14 + b^13 + b^12 + b^6 + b^4 + b^3
1726
sage: den = Qx.tate_pairing(Px, n=41, k=4, q=32); den
1727
b^19 + b^17 + b^16 + b^15 + b^14 + b^10 + b^6 + b^2 + 1
1728
sage: e = Integer((32^4-1)/41); e
1729
25575
1730
sage: Px.weil_pairing(Qx, 41)^e == num/den
1731
True
1732
1733
NOTES:
1734
1735
This function uses Miller's algorithm, followed by a naive
1736
exponentiation. It does not do anything fancy. In the case
1737
that there is an issue with `Q` being on one of the lines
1738
generated in the `r*P` calculation, `Q` is offset by a random
1739
point `R` and P.tate_pairing(Q+R,n,k)/P.tate_pairing(R,n,k)
1740
is returned.
1741
1742
AUTHORS:
1743
1744
- Mariah Lenox (2011-03-07)
1745
"""
1746
P = self
1747
E = P.curve()
1748
1749
if not Q.curve() is E:
1750
raise ValueError("Points must both be on the same curve")
1751
1752
K = E.base_ring()
1753
d = K.degree()
1754
if q is None:
1755
if d == 1:
1756
q = K.order()
1757
elif d == k:
1758
q = K.base_ring().order()
1759
else:
1760
raise ValueError("Unexpected field degree: set keyword argument q equal to the size of the base field (big field is GF(q^%s))." % k)
1761
1762
if n*P != E(0):
1763
raise ValueError('This point is not of order n=%s' % n)
1764
1765
# In small cases, or in the case of pairing an element with
1766
# itself, Q could be on one of the lines in the Miller
1767
# algorithm. If this happens we try again, with an offset of a
1768
# random point.
1769
try:
1770
ret = self._miller_(Q, n)
1771
e = rings.Integer((q**k - 1)/n)
1772
ret = ret**e
1773
except (ZeroDivisionError, ValueError):
1774
R = E.random_point()
1775
ret = self.tate_pairing(Q + R, n, k)/self.tate_pairing(R, n, k)
1776
return ret
1777
1778
def ate_pairing(self, Q, n, k, t, q=None):
1779
r"""
1780
Return ate pairing of `n`-torsion points `P=self` and `Q`.
1781
1782
Also known as the `n`-th modified ate pairing. `P` is `GF(q)`-rational,
1783
and `Q` must be an element of `Ker(\pi-p)`, where `\pi` is the
1784
`q`-frobenius map (and hence `Q` is `GF(q^k)`-rational).
1785
1786
INPUT:
1787
1788
- ``P=self`` -- a point of order `n`, in `ker(\pi-1)`, where
1789
`\pi` is the `q`-Frobenius map (e.g., `P` is `q-rational`).
1790
1791
- ``Q`` -- a point of order `n` in `ker(\pi-q)`
1792
1793
- ``n`` -- the order of `P` and `Q`.
1794
1795
- ``k`` -- the embedding degree.
1796
1797
- ``t`` -- the trace of Frobenius of the curve over `GF(q)`.
1798
1799
- ``q`` -- (default:None) the size of base field (the "big"
1800
field is `GF(q^k)`). `q` needs to be set only if its value
1801
cannot be deduced.
1802
1803
OUTPUT:
1804
1805
FiniteFieldElement in `GF(q^k)` -- the ate pairing of `P` and `Q`.
1806
1807
EXAMPLES:
1808
1809
An example with embedding degree 6::
1810
1811
sage: p = 7549; A = 0; B = 1; n = 157; k = 6; t = 14
1812
sage: F = GF(p); E = EllipticCurve(F, [A, B])
1813
sage: R.<x> = F[]; K.<a> = GF(p^k, modulus=x^k+2)
1814
sage: EK = E.base_extend(K)
1815
sage: P = EK(3050, 5371); Q = EK(6908*a^4, 3231*a^3)
1816
sage: P.ate_pairing(Q, n, k, t)
1817
6708*a^5 + 4230*a^4 + 4350*a^3 + 2064*a^2 + 4022*a + 6733
1818
sage: s = Integer(randrange(1, n))
1819
sage: (s*P).ate_pairing(Q, n, k, t) == P.ate_pairing(s*Q, n, k, t)
1820
True
1821
sage: P.ate_pairing(s*Q, n, k, t) == P.ate_pairing(Q, n, k, t)^s
1822
True
1823
1824
Another example with embedding degree 7 and positive trace::
1825
1826
sage: p = 2213; A = 1; B = 49; n = 1093; k = 7; t = 28
1827
sage: F = GF(p); E = EllipticCurve(F, [A, B])
1828
sage: R.<x> = F[]; K.<a> = GF(p^k, modulus=x^k+2)
1829
sage: EK = E.base_extend(K)
1830
sage: P = EK(1583, 1734)
1831
sage: Qx = 1729*a^6+1767*a^5+245*a^4+980*a^3+1592*a^2+1883*a+722
1832
sage: Qy = 1299*a^6+1877*a^5+1030*a^4+1513*a^3+1457*a^2+309*a+1636
1833
sage: Q = EK(Qx, Qy)
1834
sage: P.ate_pairing(Q, n, k, t)
1835
1665*a^6 + 1538*a^5 + 1979*a^4 + 239*a^3 + 2134*a^2 + 2151*a + 654
1836
sage: s = Integer(randrange(1, n))
1837
sage: (s*P).ate_pairing(Q, n, k, t) == P.ate_pairing(s*Q, n, k, t)
1838
True
1839
sage: P.ate_pairing(s*Q, n, k, t) == P.ate_pairing(Q, n, k, t)^s
1840
True
1841
1842
Another example with embedding degree 7 and negative trace::
1843
1844
sage: p = 2017; A = 1; B = 30; n = 29; k = 7; t = -70
1845
sage: F = GF(p); E = EllipticCurve(F, [A, B])
1846
sage: R.<x> = F[]; K.<a> = GF(p^k, modulus=x^k+2)
1847
sage: EK = E.base_extend(K)
1848
sage: P = EK(369, 716)
1849
sage: Qx = 1226*a^6+1778*a^5+660*a^4+1791*a^3+1750*a^2+867*a+770
1850
sage: Qy = 1764*a^6+198*a^5+1206*a^4+406*a^3+1200*a^2+273*a+1712
1851
sage: Q = EK(Qx, Qy)
1852
sage: P.ate_pairing(Q, n, k, t)
1853
1794*a^6 + 1161*a^5 + 576*a^4 + 488*a^3 + 1950*a^2 + 1905*a + 1315
1854
sage: s = Integer(randrange(1, n))
1855
sage: (s*P).ate_pairing(Q, n, k, t) == P.ate_pairing(s*Q, n, k, t)
1856
True
1857
sage: P.ate_pairing(s*Q, n, k, t) == P.ate_pairing(Q, n, k, t)^s
1858
True
1859
1860
Using the same data, we show that the ate pairing is a power of the
1861
Tate pairing (see [HSV]_ end of section 3.1)::
1862
1863
sage: c = (k*p^(k-1)).mod(n); T = t - 1
1864
sage: N = gcd(T^k - 1, p^k - 1)
1865
sage: s = Integer(N/n)
1866
sage: L = Integer((T^k - 1)/N)
1867
sage: M = (L*s*c.inverse_mod(n)).mod(n)
1868
sage: P.ate_pairing(Q, n, k, t) == Q.tate_pairing(P, n, k)^M
1869
True
1870
1871
An example where we have to pass the base field size (and we again have
1872
agreement with the Tate pairing). Note that though `Px` is not
1873
`F`-rational, (it is the homomorphic image of an `F`-rational point) it
1874
is nonetheless in `ker(\pi-1)`, and so is a legitimate input::
1875
1876
sage: q = 2^5; F.<a>=GF(q)
1877
sage: n = 41; k = 4; t = -8
1878
sage: E=EllipticCurve(F,[0,0,1,1,1])
1879
sage: P = E(a^4 + 1, a^3)
1880
sage: Fx.<b>=GF(q^k)
1881
sage: Ex=EllipticCurve(Fx,[0,0,1,1,1])
1882
sage: phi=Hom(F,Fx)(F.gen().minpoly().roots(Fx)[0][0])
1883
sage: Px=Ex(phi(P.xy()[0]),phi(P.xy()[1]))
1884
sage: Qx = Ex(b^19+b^18+b^16+b^12+b^10+b^9+b^8+b^5+b^3+1, b^18+b^13+b^10+b^8+b^5+b^4+b^3+b)
1885
sage: Qx = Ex(Qx[0]^q, Qx[1]^q) - Qx # ensure Qx is in ker(pi - q)
1886
sage: Px.ate_pairing(Qx, n, k, t)
1887
Traceback (most recent call last):
1888
...
1889
ValueError: Unexpected field degree: set keyword argument q equal to the size of the base field (big field is GF(q^4)).
1890
sage: Px.ate_pairing(Qx, n, k, t, q)
1891
b^19 + b^18 + b^17 + b^16 + b^15 + b^14 + b^13 + b^12 + b^11 + b^9 + b^8 + b^5 + b^4 + b^2 + b + 1
1892
sage: s = Integer(randrange(1, n))
1893
sage: (s*Px).ate_pairing(Qx, n, k, t, q) == Px.ate_pairing(s*Qx, n, k, t, q)
1894
True
1895
sage: Px.ate_pairing(s*Qx, n, k, t, q) == Px.ate_pairing(Qx, n, k, t, q)^s
1896
True
1897
sage: c = (k*q^(k-1)).mod(n); T = t - 1
1898
sage: N = gcd(T^k - 1, q^k - 1)
1899
sage: s = Integer(N/n)
1900
sage: L = Integer((T^k - 1)/N)
1901
sage: M = (L*s*c.inverse_mod(n)).mod(n)
1902
sage: Px.ate_pairing(Qx, n, k, t, q) == Qx.tate_pairing(Px, n, k, q)^M
1903
True
1904
1905
It is an error if `Q` is not in the kernel of `\pi - p`, where `\pi` is
1906
the Frobenius automorphism::
1907
1908
sage: p = 29; A = 1; B = 0; n = 5; k = 2; t = 10
1909
sage: F = GF(p); R.<x> = F[]
1910
sage: E = EllipticCurve(F, [A, B]);
1911
sage: K.<a> = GF(p^k, modulus=x^k+2); EK = E.base_extend(K)
1912
sage: P = EK(13, 8); Q = EK(13, 21)
1913
sage: P.ate_pairing(Q, n, k, t)
1914
Traceback (most recent call last):
1915
...
1916
ValueError: Point (13 : 21 : 1) not in Ker(pi - q)
1917
1918
It is also an error if `P` is not in the kernel os `\pi - 1`::
1919
1920
sage: p = 29; A = 1; B = 0; n = 5; k = 2; t = 10
1921
sage: F = GF(p); R.<x> = F[]
1922
sage: E = EllipticCurve(F, [A, B]);
1923
sage: K.<a> = GF(p^k, modulus=x^k+2); EK = E.base_extend(K)
1924
sage: P = EK(14, 10*a); Q = EK(13, 21)
1925
sage: P.ate_pairing(Q, n, k, t)
1926
Traceback (most recent call last):
1927
...
1928
ValueError: This point (14 : 10*a : 1) is not in Ker(pi - 1)
1929
1930
NOTES:
1931
1932
First defined in the paper of [HSV]_, the ate pairing can be
1933
computationally effective in those cases when the trace of the curve
1934
over the base field is significantly smaller than the expected
1935
value. This implementation is simply Miller's algorithm followed by a
1936
naive exponentiation, and makes no claims towards efficiency.
1937
1938
REFERENCES:
1939
1940
.. [HSV] Hess, Smart, Vercauteren, "The Eta Pairing Revisited",
1941
IEEE Trans. Information Theory, 52(10): 4595-4602, 2006.
1942
1943
AUTHORS:
1944
1945
- Mariah Lenox (2011-03-08)
1946
"""
1947
P = self
1948
# check for same curve
1949
E = P.curve()
1950
O = E(0)
1951
if not Q.curve() is E:
1952
raise ValueError("Points must both be on the same curve")
1953
1954
# set q to be the order of the base field
1955
K = E.base_ring()
1956
if q is None:
1957
d = K.degree()
1958
if d == k:
1959
q = K.base_ring().order()
1960
else:
1961
raise ValueError("Unexpected field degree: set keyword argument q equal to the size of the base field (big field is GF(q^%s))." % k)
1962
1963
# check order of P
1964
if n*P != O:
1965
raise ValueError('This point %s is not of order n=%s' % (P, n))
1966
1967
# check for P in kernel pi - 1:
1968
piP = E(P[0]**q, P[1]**q)
1969
if piP - P != O:
1970
raise ValueError('This point %s is not in Ker(pi - 1)' % P)
1971
1972
# check for Q in kernel pi - q:
1973
piQ = E(Q[0]**q, Q[1]**q)
1974
if piQ - q*Q != O:
1975
raise ValueError('Point %s not in Ker(pi - q)' % Q)
1976
1977
T = t-1
1978
ret = Q._miller_(P, T)
1979
e = rings.Integer((q**k - 1)/n)
1980
ret = ret**e
1981
return ret
1982
1983
1984
class EllipticCurvePoint_number_field(EllipticCurvePoint_field):
1985
"""
1986
A point on an elliptic curve over a number field.
1987
1988
Most of the functionality is derived from the parent class
1989
``EllipticCurvePoint_field``. In addition we have support for
1990
orders, heights, reduction modulo primes, and elliptic logarithms.
1991
1992
EXAMPLES::
1993
1994
sage: E = EllipticCurve('37a')
1995
sage: E([0,0])
1996
(0 : 0 : 1)
1997
sage: E(0,0) # brackets are optional
1998
(0 : 0 : 1)
1999
sage: E([GF(5)(0), 0]) # entries are coerced
2000
(0 : 0 : 1)
2001
2002
sage: E(0.000, 0)
2003
(0 : 0 : 1)
2004
2005
sage: E(1,0,0)
2006
Traceback (most recent call last):
2007
...
2008
TypeError: Coordinates [1, 0, 0] do not define a point on
2009
Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
2010
2011
::
2012
2013
sage: E = EllipticCurve([0,0,1,-1,0])
2014
sage: S = E(QQ); S
2015
Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
2016
2017
TESTS::
2018
2019
sage: loads(S.dumps()) == S
2020
True
2021
sage: P = E(0,0); P
2022
(0 : 0 : 1)
2023
sage: loads(P.dumps()) == P
2024
True
2025
sage: T = 100*P
2026
sage: loads(T.dumps()) == T
2027
True
2028
2029
Test pickling an elliptic curve that has known points on it::
2030
2031
sage: e = EllipticCurve([0, 0, 1, -1, 0]); g = e.gens(); loads(dumps(e)) == e
2032
True
2033
"""
2034
2035
def order(self):
2036
r"""
2037
Return the order of this point on the elliptic curve.
2038
2039
If the point has infinite order, returns +Infinity. For
2040
curves defined over `\QQ`, we call PARI; over other
2041
number fields we implement the function here.
2042
2043
.. NOTE::
2044
2045
:meth:`additive_order` is a synonym for :meth:`order`
2046
2047
EXAMPLES::
2048
2049
sage: E = EllipticCurve([0,0,1,-1,0])
2050
sage: P = E([0,0]); P
2051
(0 : 0 : 1)
2052
sage: P.order()
2053
+Infinity
2054
2055
::
2056
2057
sage: E = EllipticCurve([0,1])
2058
sage: P = E([-1,0])
2059
sage: P.order()
2060
2
2061
sage: P.additive_order()
2062
2
2063
2064
"""
2065
try:
2066
return self._order
2067
except AttributeError:
2068
pass
2069
2070
if self.is_zero():
2071
self._order = rings.Integer(1)
2072
return self._order
2073
2074
E = self.curve()
2075
2076
# Special code for curves over Q, calling PARI
2077
from sage.libs.pari.all import PariError
2078
try:
2079
n = int(E.pari_curve().ellorder(self))
2080
if n == 0:
2081
n = oo
2082
self._order = n
2083
return n
2084
except PariError:
2085
pass
2086
2087
# Get the torsion order if known, else a bound on (multiple
2088
# of) the order. We do not compute the torsion if it is not
2089
# already known, since computing the bound is faster (and is
2090
# also cached).
2091
2092
try:
2093
N = E._torsion_order
2094
except AttributeError:
2095
N = E._torsion_bound()
2096
2097
# Now self is a torsion point iff it is killed by N:
2098
if not (N*self).is_zero():
2099
self._order = oo
2100
return self._order
2101
2102
# Finally we find the exact order using the generic code:
2103
self._order = generic.order_from_multiple(self, N, operation='+')
2104
return self._order
2105
2106
additive_order = order
2107
2108
def has_finite_order(self):
2109
"""
2110
Return True iff this point has finite order on the elliptic curve.
2111
2112
EXAMPLES::
2113
2114
sage: E = EllipticCurve([0,0,1,-1,0])
2115
sage: P = E([0,0]); P
2116
(0 : 0 : 1)
2117
sage: P.has_finite_order()
2118
False
2119
2120
::
2121
2122
sage: E = EllipticCurve([0,1])
2123
sage: P = E([-1,0])
2124
sage: P.has_finite_order()
2125
True
2126
"""
2127
if self.is_zero():
2128
return True
2129
return self.order() != oo
2130
2131
def has_infinite_order(self):
2132
r"""
2133
Return True iff this point has infinite order on the elliptic curve.
2134
2135
EXAMPLES::
2136
2137
sage: E = EllipticCurve([0,0,1,-1,0])
2138
sage: P = E([0,0]); P
2139
(0 : 0 : 1)
2140
sage: P.has_infinite_order()
2141
True
2142
2143
::
2144
2145
sage: E = EllipticCurve([0,1])
2146
sage: P = E([-1,0])
2147
sage: P.has_infinite_order()
2148
False
2149
"""
2150
if self.is_zero():
2151
return False
2152
return self.order() == oo
2153
2154
def is_on_identity_component(self, embedding=None):
2155
r"""
2156
Returns True iff this point is on the identity component of
2157
its curve with respect to a given (real or complex) embedding.
2158
2159
INPUT:
2160
2161
- ``self`` -- a point on a curve over any ordered field (e.g. `\QQ`)
2162
2163
- ``embedding`` -- an embedding from the base_field of the
2164
point's curve into `\RR` or `\CC`; if ``None`` (the
2165
default) it uses the first embedding of the base_field into
2166
`\RR` if any, else the first embedding into `\CC`.
2167
2168
OUTPUT:
2169
2170
(bool) -- ``True`` iff the point is on the identity component of
2171
the curve. (If the point is zero then the result is True.)
2172
2173
EXAMPLES:
2174
2175
For `K=\QQ` there is no need to specify an embedding::
2176
2177
sage: E=EllipticCurve('5077a1')
2178
sage: [E.lift_x(x).is_on_identity_component() for x in range(-3,5)]
2179
[False, False, False, False, False, True, True, True]
2180
2181
An example over a field with two real embeddings::
2182
2183
sage: L.<a> = QuadraticField(2)
2184
sage: E=EllipticCurve(L,[0,1,0,a,a])
2185
sage: P=E(-1,0)
2186
sage: [P.is_on_identity_component(e) for e in L.embeddings(RR)]
2187
[False, True]
2188
2189
We can check this as follows::
2190
2191
sage: [e(E.discriminant())>0 for e in L.embeddings(RR)]
2192
[True, False]
2193
sage: e = L.embeddings(RR)[0]
2194
sage: E1 = EllipticCurve(RR,[e(ai) for ai in E.ainvs()])
2195
sage: e1,e2,e3 = E1.two_division_polynomial().roots(RR,multiplicities=False)
2196
sage: e1 < e2 < e3 and e(P[0]) < e3
2197
True
2198
2199
"""
2200
if self.is_zero(): # trivial case
2201
return True
2202
2203
e = embedding
2204
# It is also trivially true if we have a complex embedding
2205
if not e is None:
2206
if not is_RealField(e.codomain()):
2207
return True
2208
2209
# find a suitable embedding if none was supplied:
2210
E = self.curve()
2211
K = E.base_field()
2212
if e is None:
2213
try:
2214
e = K.embeddings(rings.RealField())[0]
2215
except IndexError:
2216
e = K.embeddings(rings.ComplexField())[0]
2217
2218
# If there is only one component, the result is True:
2219
if not is_RealField(e.codomain()): # complex embedding
2220
return True
2221
if e(E.discriminant()) < 0: # only one component
2222
return True
2223
2224
# Now we have a real embedding and two components and have to work:
2225
gx = E.two_division_polynomial()
2226
gxd = gx.derivative()
2227
gxdd = gxd.derivative()
2228
return (e(gxd(self[0])) > 0 and e(gxdd(self[0])) > 0)
2229
2230
def has_good_reduction(self, P=None):
2231
r"""
2232
Returns True iff this point has good reduction modulo a prime.
2233
2234
INPUT:
2235
2236
- ``P`` -- a prime of the base_field of the point's curve, or
2237
``None`` (default)
2238
2239
OUTPUT:
2240
2241
(bool) If a prime `P` of the base field is specified, returns
2242
True iff the point has good reduction at `P`; otherwise,
2243
return true if the point has god reduction at all primes in
2244
the support of the discriminant of this model.
2245
2246
EXAMPLES::
2247
2248
sage: E = EllipticCurve('990e1')
2249
sage: P = E.gen(0); P
2250
(15 : 51 : 1)
2251
sage: [E.has_good_reduction(p) for p in [2,3,5,7]]
2252
[False, False, False, True]
2253
sage: [P.has_good_reduction(p) for p in [2,3,5,7]]
2254
[True, False, True, True]
2255
sage: [E.tamagawa_exponent(p) for p in [2,3,5,7]]
2256
[2, 2, 1, 1]
2257
sage: [(2*P).has_good_reduction(p) for p in [2,3,5,7]]
2258
[True, True, True, True]
2259
sage: P.has_good_reduction()
2260
False
2261
sage: (2*P).has_good_reduction()
2262
True
2263
sage: (3*P).has_good_reduction()
2264
False
2265
2266
::
2267
2268
sage: K.<i> = NumberField(x^2+1)
2269
sage: E = EllipticCurve(K,[0,1,0,-160,308])
2270
sage: P = E(26,-120)
2271
sage: E.discriminant().support()
2272
[Fractional ideal (i + 1),
2273
Fractional ideal (-i - 2),
2274
Fractional ideal (i - 2),
2275
Fractional ideal (3)]
2276
sage: [E.tamagawa_exponent(p) for p in E.discriminant().support()]
2277
[1, 4, 4, 4]
2278
sage: P.has_good_reduction()
2279
False
2280
sage: (2*P).has_good_reduction()
2281
False
2282
sage: (4*P).has_good_reduction()
2283
True
2284
2285
TESTS:
2286
2287
An example showing that :trac:`8498` is fixed::
2288
2289
sage: E = EllipticCurve('11a1')
2290
sage: K.<t> = NumberField(x^2+47)
2291
sage: EK = E.base_extend(K)
2292
sage: T = EK(5,5)
2293
sage: P = EK(-2, -1/2*t - 1/2)
2294
sage: p = K.ideal(11)
2295
sage: T.has_good_reduction(p)
2296
False
2297
sage: P.has_good_reduction(p)
2298
True
2299
"""
2300
if self.is_zero(): # trivial case
2301
return True
2302
2303
E = self.curve()
2304
if P is None:
2305
return all([self.has_good_reduction(Pr) for Pr in E.discriminant().support()])
2306
K = E.base_field()
2307
from sage.schemes.elliptic_curves.ell_local_data import check_prime
2308
P = check_prime(K, P)
2309
2310
# If the curve has good reduction at P, the result is True:
2311
t = E.local_data(P).bad_reduction_type()
2312
if t is None:
2313
return True
2314
2315
# Make sure the curve is integral and locally minimal at P:
2316
Emin = E.local_minimal_model(P)
2317
urst = E.isomorphism_to(Emin)
2318
Q = urst(self)
2319
2320
# Scale the homogeneous coordinates of the point to be primitive:
2321
xyz = list(Q)
2322
e = min([c.valuation(P) for c in xyz])
2323
if e != 0:
2324
if K is rings.QQ:
2325
pi = P
2326
else:
2327
pi = K.uniformizer(P)
2328
pie = pi**e
2329
xyz = [c/pie for c in xyz]
2330
2331
# Evaluate the partial derivatives at the point to see if they
2332
# are zero mod P
2333
2334
# See #8498: sometimes evaluating F's derivatives at xyz
2335
# returns a constant polynomial instead of a constant
2336
2337
F = Emin.defining_polynomial()
2338
for v in F.variables():
2339
c = (F.derivative(v))(xyz)
2340
try:
2341
val = c.valuation(P)
2342
except AttributeError:
2343
val = c.constant_coefficient().valuation(P)
2344
if val == 0:
2345
return True
2346
return False
2347
2348
def reduction(self, p):
2349
"""
2350
This finds the reduction of a point `P` on the elliptic curve
2351
modulo the prime `p`.
2352
2353
INPUT:
2354
2355
- ``self`` -- A point on an elliptic curve.
2356
2357
- ``p`` -- a prime number
2358
2359
OUTPUT:
2360
2361
The point reduced to be a point on the elliptic curve modulo `p`.
2362
2363
EXAMPLES::
2364
2365
sage: E = EllipticCurve([1,2,3,4,0])
2366
sage: P = E(0,0)
2367
sage: P.reduction(5)
2368
(0 : 0 : 1)
2369
sage: Q = E(98,931)
2370
sage: Q.reduction(5)
2371
(3 : 1 : 1)
2372
sage: Q.reduction(5).curve() == E.reduction(5)
2373
True
2374
2375
::
2376
2377
sage: F.<a> = NumberField(x^2+5)
2378
sage: E = EllipticCurve(F,[1,2,3,4,0])
2379
sage: Q = E(98,931)
2380
sage: Q.reduction(a)
2381
(3 : 1 : 1)
2382
sage: Q.reduction(11)
2383
(10 : 7 : 1)
2384
2385
::
2386
2387
sage: F.<a> = NumberField(x^3+x^2+1)
2388
sage: E = EllipticCurve(F,[a,2])
2389
sage: P = E(a,1)
2390
sage: P.reduction(F.ideal(5))
2391
(abar : 1 : 1)
2392
sage: P.reduction(F.ideal(a^2-4*a-2))
2393
(abar : 1 : 1)
2394
2395
"""
2396
P = self
2397
E = P.curve()
2398
return E.reduction(p)(P)
2399
2400
def height(self, precision=None, normalised=True, algorithm='pari'):
2401
"""
2402
Return the Néron-Tate canonical height of the point.
2403
2404
INPUT:
2405
2406
- ``self`` -- a point on an elliptic curve over a number field
2407
`K`.
2408
2409
- ``precision`` -- positive integer, or None (default). The
2410
precision in bits of the result. If None, the default real
2411
precision is used.
2412
2413
- ``normalised`` -- boolean. If True (default), the height is
2414
normalised to be invariant under extension of `K`. If False,
2415
return this normalised height multiplied by the degree of
2416
`K`.
2417
2418
- ``algorithm`` -- string: either 'pari' (default) or 'sage'.
2419
If 'pari' and the base field is `\QQ`, use the PARI library
2420
function; otherwise use the Sage implementation.
2421
2422
OUTPUT:
2423
2424
The rational number 0, or a non-negative real number.
2425
2426
There are two normalisations used in the literature, one of
2427
which is double the other. We use the larger of the two, which
2428
is the one appropriate for the BSD conjecture. This is
2429
consistent with [Cre]_ and double that of [SilBook]_.
2430
2431
See :wikipedia:`Néron-Tate height`
2432
2433
REFERENCES:
2434
2435
.. [Cre] John Cremona, Algorithms for Modular Elliptic Curves.
2436
Cambridge University Press, 1997.
2437
2438
.. [Sil1988] Joseph H. Silverman, Computing heights on
2439
elliptic curves. Mathematics of Computation, Vol. 51,
2440
No. 183 (Jul., 1988), pp. 339-358.
2441
2442
.. [SilBook] Joseph H. Silverman, The Arithmetic of Elliptic
2443
Curves. Second edition. Graduate Texts in Mathematics, 106.
2444
Springer, 2009.
2445
2446
EXAMPLES::
2447
2448
sage: E = EllipticCurve('11a'); E
2449
Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
2450
sage: P = E([5,5]); P
2451
(5 : 5 : 1)
2452
sage: P.height()
2453
0
2454
sage: Q = 5*P
2455
sage: Q.height()
2456
0
2457
2458
::
2459
2460
sage: E = EllipticCurve('37a'); E
2461
Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
2462
sage: P = E([0,0])
2463
sage: P.height()
2464
0.0511114082399688
2465
sage: P.order()
2466
+Infinity
2467
sage: E.regulator()
2468
0.0511114082399688...
2469
2470
sage: def naive_height(P):
2471
... return log(RR(max(abs(P[0].numerator()), abs(P[0].denominator()))))
2472
sage: for n in [1..10]:
2473
... print naive_height(2^n*P)/4^n
2474
0.000000000000000
2475
0.0433216987849966
2476
0.0502949347635656
2477
0.0511006335618645
2478
0.0511007834799612
2479
0.0511013666152466
2480
0.0511034199907743
2481
0.0511106492906471
2482
0.0511114081541082
2483
0.0511114081541180
2484
2485
::
2486
2487
sage: E = EllipticCurve('4602a1'); E
2488
Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 37746035*x - 89296920339 over Rational Field
2489
sage: x = 77985922458974949246858229195945103471590
2490
sage: y = 19575260230015313702261379022151675961965157108920263594545223
2491
sage: d = 2254020761884782243
2492
sage: E([ x / d^2, y / d^3 ]).height()
2493
86.7406561381275
2494
2495
::
2496
2497
sage: E = EllipticCurve([17, -60, -120, 0, 0]); E
2498
Elliptic Curve defined by y^2 + 17*x*y - 120*y = x^3 - 60*x^2 over Rational Field
2499
sage: E([30, -90]).height()
2500
0
2501
2502
sage: E = EllipticCurve('389a1'); E
2503
Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field
2504
sage: [P,Q] = [E(-1,1),E(0,-1)]
2505
sage: P.height(precision=100)
2506
0.68666708330558658572355210295
2507
sage: (3*Q).height(precision=100)/Q.height(precision=100)
2508
9.0000000000000000000000000000
2509
sage: _.parent()
2510
Real Field with 100 bits of precision
2511
2512
Canonical heights over number fields are implemented as well::
2513
2514
sage: R.<x> = QQ[]
2515
sage: K.<a> = NumberField(x^3-2)
2516
sage: E = EllipticCurve([a, 4]); E
2517
Elliptic Curve defined by y^2 = x^3 + a*x + 4 over Number Field in a with defining polynomial x^3 - 2
2518
sage: P = E((0,2))
2519
sage: P.height()
2520
0.810463096585925
2521
sage: P.height(precision=100)
2522
0.81046309658592536863991810577
2523
sage: P.height(precision=200)
2524
0.81046309658592536863991810576865158896130286417155832378086
2525
sage: (2*P).height() / P.height()
2526
4.00000000000000
2527
sage: (100*P).height() / P.height()
2528
10000.0000000000
2529
2530
Setting normalised=False multiplies the height by the degree of `K`::
2531
2532
sage: E = EllipticCurve('37a')
2533
sage: P = E([0,0])
2534
sage: P.height()
2535
0.0511114082399688
2536
sage: P.height(normalised=False)
2537
0.0511114082399688
2538
sage: K.<z> = CyclotomicField(5)
2539
sage: EK = E.change_ring(K)
2540
sage: PK = EK([0,0])
2541
sage: PK.height()
2542
0.0511114082399688
2543
sage: PK.height(normalised=False)
2544
0.204445632959875
2545
2546
Some consistency checks::
2547
2548
sage: E = EllipticCurve('5077a1')
2549
sage: P = E([-2,3,1])
2550
sage: P.height()
2551
1.36857250535393
2552
2553
sage: EK = E.change_ring(QuadraticField(-3,'a'))
2554
sage: PK = EK([-2,3,1])
2555
sage: PK.height()
2556
1.36857250535393
2557
2558
sage: K.<i> = NumberField(x^2+1)
2559
sage: E = EllipticCurve(K, [0,0,4,6*i,0])
2560
sage: Q = E.lift_x(-9/4); Q
2561
(-9/4 : -27/8*i : 1)
2562
sage: Q.height()
2563
2.69518560017909
2564
sage: (15*Q).height() / Q.height()
2565
225.000000000000
2566
2567
sage: E = EllipticCurve('37a')
2568
sage: P = E([0,-1])
2569
sage: P.height()
2570
0.0511114082399688
2571
sage: K.<a> = QuadraticField(-7)
2572
sage: ED = E.quadratic_twist(-7)
2573
sage: Q = E.isomorphism_to(ED.change_ring(K))(P); Q
2574
(0 : -7/2*a - 1/2 : 1)
2575
sage: Q.height()
2576
0.0511114082399688
2577
sage: Q.height(precision=100)
2578
0.051111408239968840235886099757
2579
2580
An example to show that the bug at :trac:`5252` is fixed::
2581
2582
sage: E = EllipticCurve([1, -1, 1, -2063758701246626370773726978, 32838647793306133075103747085833809114881])
2583
sage: P = E([-30987785091199, 258909576181697016447])
2584
sage: P.height()
2585
25.8603170675462
2586
sage: P.height(precision=100)
2587
25.860317067546190743868840741
2588
sage: P.height(precision=250)
2589
25.860317067546190743868840740735110323098872903844416215577171041783572513
2590
sage: P.height(precision=500)
2591
25.8603170675461907438688407407351103230988729038444162155771710417835725129551130570889813281792157278507639909972112856019190236125362914195452321720
2592
2593
sage: P.height(precision=100) == P.non_archimedean_local_height(prec=100)+P.archimedean_local_height(prec=100)
2594
True
2595
2596
An example to show that the bug at :trac:`8319` is fixed (correct height when the curve is not minimal)::
2597
2598
sage: E = EllipticCurve([-5580472329446114952805505804593498080000,-157339733785368110382973689903536054787700497223306368000000])
2599
sage: xP = 204885147732879546487576840131729064308289385547094673627174585676211859152978311600/23625501907057948132262217188983681204856907657753178415430361
2600
sage: P = E.lift_x(xP)
2601
sage: P.height()
2602
157.432598516754
2603
sage: Q = 2*P
2604
sage: Q.height() # long time (4s)
2605
629.730394067016
2606
sage: Q.height()-4*P.height() # long time
2607
0.000000000000000
2608
2609
An example to show that the bug at :trac:`12509` is fixed (precision issues)::
2610
2611
sage: x = polygen(QQ)
2612
sage: K.<a> = NumberField(x^2-x-1)
2613
sage: v = [0, a + 1, 1, 28665*a - 46382, 2797026*a - 4525688]
2614
sage: E = EllipticCurve(v)
2615
sage: P = E([72*a - 509/5, -682/25*a - 434/25])
2616
sage: P.height()
2617
1.38877711688727
2618
sage: (2*P).height()/P.height()
2619
4.00000000000000
2620
sage: (2*P).height(precision=100)/P.height(precision=100)
2621
4.0000000000000000000000000000
2622
sage: (2*P).height(precision=1000)/P.height(precision=1000)
2623
4.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2624
2625
This shows that the bug reported at :trac:`13951` has been fixed::
2626
2627
sage: E = EllipticCurve([0,17])
2628
sage: P1 = E(2,5)
2629
sage: P1.height()
2630
1.06248137652528
2631
sage: F = E.change_ring(QuadraticField(-3,'a'))
2632
sage: P2 = F([2,5])
2633
sage: P2.height()
2634
1.06248137652528
2635
"""
2636
if self.has_finite_order():
2637
return rings.QQ(0)
2638
2639
E = self.curve()
2640
K = E.base_ring()
2641
2642
if precision is None:
2643
precision = rings.RealField().precision()
2644
2645
known_prec = -1
2646
try:
2647
height = self.__height
2648
known_prec = height.prec()
2649
if known_prec > precision:
2650
height = rings.RealField(precision)(height)
2651
except AttributeError:
2652
pass
2653
2654
if known_prec < precision:
2655
if algorithm == 'pari' and K is rings.QQ:
2656
Emin = E.minimal_model()
2657
iso = E.isomorphism_to(Emin)
2658
P = iso(self)
2659
h = Emin.pari_curve(prec=precision).ellheight(P, precision=precision)
2660
height = rings.RealField(precision)(h)
2661
else:
2662
height = (self.non_archimedean_local_height(prec=precision)
2663
+ self.archimedean_local_height(prec=precision))
2664
2665
# The cached height is the one that is independent of the base field.
2666
self.__height = height
2667
if not normalised:
2668
height *= K.degree()
2669
return height
2670
2671
def archimedean_local_height(self, v=None, prec=None, weighted=False):
2672
"""
2673
Compute the local height of self at the archimedean place `v`.
2674
2675
INPUT:
2676
2677
- ``self`` -- a point on an elliptic curve over a number field
2678
`K`.
2679
2680
- ``v`` -- a real or complex embedding of K, or None (default).
2681
If `v` is a real or complex embedding, return the local
2682
height of self at `v`. If `v` is None, return the total
2683
archimedean contribution to the global height.
2684
2685
- ``prec`` -- integer, or None (default). The precision of the
2686
computation. If None, the precision is deduced from v.
2687
2688
- ``weighted`` -- boolean. If False (default), the height is
2689
normalised to be invariant under extension of `K`. If True,
2690
return this normalised height multiplied by the local degree
2691
if `v` is a single place, or by the degree of `K` if `v` is
2692
None.
2693
2694
OUTPUT:
2695
2696
A real number. The normalisation is twice that in Silverman's
2697
paper [Sil1988]_. Note that this local height depends on the
2698
model of the curve.
2699
2700
ALGORITHM:
2701
2702
See [Sil1988]_, Section 4.
2703
2704
EXAMPLES:
2705
2706
Examples 1, 2, and 3 from [Sil1988]_::
2707
2708
sage: K.<a> = QuadraticField(-2)
2709
sage: E = EllipticCurve(K, [0,-1,1,0,0]); E
2710
Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 over Number Field in a with defining polynomial x^2 + 2
2711
sage: P = E.lift_x(2+a); P
2712
(a + 2 : 2*a + 1 : 1)
2713
sage: P.archimedean_local_height(K.places(prec=170)[0]) / 2
2714
0.45754773287523276736211210741423654346576029814695
2715
2716
sage: K.<i> = NumberField(x^2+1)
2717
sage: E = EllipticCurve(K, [0,0,4,6*i,0]); E
2718
Elliptic Curve defined by y^2 + 4*y = x^3 + 6*i*x over Number Field in i with defining polynomial x^2 + 1
2719
sage: P = E((0,0))
2720
sage: P.archimedean_local_height(K.places()[0]) / 2
2721
0.510184995162373
2722
2723
sage: Q = E.lift_x(-9/4); Q
2724
(-9/4 : -27/8*i : 1)
2725
sage: Q.archimedean_local_height(K.places()[0]) / 2
2726
0.654445619529600
2727
2728
An example over the rational numbers::
2729
2730
sage: E = EllipticCurve([0, 0, 0, -36, 0])
2731
sage: P = E([-3, 9])
2732
sage: P.archimedean_local_height()
2733
1.98723816350773
2734
2735
Local heights of torsion points can be non-zero (unlike the
2736
global height)::
2737
2738
sage: K.<i> = QuadraticField(-1)
2739
sage: E = EllipticCurve([0, 0, 0, K(1), 0])
2740
sage: P = E(i, 0)
2741
sage: P.archimedean_local_height()
2742
0.346573590279973
2743
2744
TESTS:
2745
2746
See :trac:`12509`::
2747
2748
sage: x = polygen(QQ)
2749
sage: K.<a> = NumberField(x^2-x-1)
2750
sage: v = [0, a + 1, 1, 28665*a - 46382, 2797026*a - 4525688]
2751
sage: E = EllipticCurve(v)
2752
sage: P = E([72*a - 509/5, -682/25*a - 434/25])
2753
sage: P.archimedean_local_height()
2754
-0.2206607955468278492183362746930
2755
2756
"""
2757
E = self.curve()
2758
K = E.base_ring()
2759
2760
if v is None:
2761
if K is rings.QQ:
2762
v = K.embeddings(rings.RR)[0]
2763
h = self.archimedean_local_height(v, prec)
2764
else:
2765
r1, r2 = K.signature()
2766
pl = K.places()
2767
h = (sum(self.archimedean_local_height(pl[i], prec, weighted=False)
2768
for i in range(r1))
2769
+ 2 * sum(self.archimedean_local_height(pl[i], prec, weighted=False)
2770
for i in range(r1, r1 + r2)))
2771
if not weighted:
2772
h /= K.degree()
2773
return h
2774
2775
from sage.rings.number_field.number_field import refine_embedding
2776
prec_v = v.codomain().prec()
2777
if prec is None:
2778
prec = prec_v
2779
if K is rings.QQ:
2780
vv = K.embeddings(rings.RealField(max(2*prec, prec_v)))[0]
2781
else:
2782
vv = refine_embedding(v, 2*prec) # vv.prec() = max(2*prec, prec_v)
2783
b2, b4, b6, b8 = [vv(b) for b in E.b_invariants()]
2784
H = max(4, abs(b2), 2*abs(b4), 2*abs(b6), abs(b8))
2785
# The following comes from Silverman Theorem 4.2. Silverman
2786
# uses decimal precision d, so his term (5/3)d =
2787
# (5/3)*(log(2)/log(10))*prec = 0.5017*prec, which we round
2788
# up. The rest of the expression was wrongly transcribed in
2789
# Sage versions <5.6 (see #12509).
2790
nterms = int(math.ceil(0.51*prec + 0.5 + 3*math.log(7+(4*math.log(H)+math.log(max(1, ~abs(v(E.discriminant())))))/3)/4))
2791
b2p = b2 - 12
2792
b4p = b4 - b2 + 6
2793
b6p = b6 - 2*b4 + b2 - 4
2794
b8p = b8 - 3*b6 + 3*b4 - b2 + 3
2795
2796
fz = lambda T: 1 - T**2 * (b4 + T*(2*b6 + T*b8))
2797
fzp = lambda T: 1 - T**2 * (b4p + T*(2*b6p + T*b8p))
2798
fw = lambda T: T*(4 + T*(b2 + T*(2*b4 + T*b6)))
2799
fwp = lambda T: T*(4 + T*(b2p + T*(2*b4p + T*b6p)))
2800
2801
x = vv(self[0])
2802
if abs(x) >= .5:
2803
t = 1/x
2804
beta = True
2805
else:
2806
t = 1/(x+1)
2807
beta = False
2808
lam = -t.abs().log()
2809
mu = 0
2810
four_to_n = rings.QQ(1)
2811
2812
for n in range(nterms):
2813
if beta:
2814
w = fw(t)
2815
z = fz(t)
2816
if abs(w) <= 2 * abs(z):
2817
mu += four_to_n * z.abs().log()
2818
t = w/z
2819
else:
2820
mu += four_to_n * (z+w).abs().log()
2821
t = w/(z+w)
2822
beta = not beta
2823
else:
2824
w = fwp(t)
2825
z = fzp(t)
2826
if abs(w) <= 2 * abs(z):
2827
mu += four_to_n * z.abs().log()
2828
t = w/z
2829
else:
2830
mu += four_to_n * (z-w).abs().log()
2831
t = w/(z-w)
2832
beta = not beta
2833
four_to_n >>= 2
2834
h = rings.RealField(prec)(lam + mu/4)
2835
if weighted and not v.im_gens()[0] in rings.RR:
2836
h *= 2
2837
return h
2838
2839
archimedian_local_height = deprecated_function_alias(13951, archimedean_local_height)
2840
2841
def non_archimedean_local_height(self, v=None, prec=None,
2842
weighted=False, is_minimal=None):
2843
"""
2844
Compute the local height of self at the non-archimedean place `v`.
2845
2846
INPUT:
2847
2848
- ``self`` -- a point on an elliptic curve over a number field
2849
`K`.
2850
2851
- ``v`` -- a non-archimedean place of `K`, or None (default).
2852
If `v` is a non-archimedean place, return the local height
2853
of self at `v`. If `v` is None, return the total
2854
non-archimedean contribution to the global height.
2855
2856
- ``prec`` -- integer, or None (default). The precision of the
2857
computation. If None, the height is returned symbolically.
2858
2859
- ``weighted`` -- boolean. If False (default), the height is
2860
normalised to be invariant under extension of `K`. If True,
2861
return this normalised height multiplied by the local degree
2862
if `v` is a single place, or by the degree of `K` if `v` is
2863
None.
2864
2865
OUTPUT:
2866
2867
A real number. The normalisation is twice that in Silverman's
2868
paper [Sil1988]_. Note that this local height depends on the
2869
model of the curve.
2870
2871
ALGORITHM:
2872
2873
See [Sil1988]_, Section 5.
2874
2875
EXAMPLES:
2876
2877
Examples 2 and 3 from [Sil1988]_::
2878
2879
sage: K.<i> = NumberField(x^2+1)
2880
sage: E = EllipticCurve(K, [0,0,4,6*i,0]); E
2881
Elliptic Curve defined by y^2 + 4*y = x^3 + 6*i*x over Number Field in i with defining polynomial x^2 + 1
2882
sage: P = E((0,0))
2883
sage: P.non_archimedean_local_height(K.ideal(i+1))
2884
-1/2*log(2)
2885
sage: P.non_archimedean_local_height(K.ideal(3))
2886
0
2887
sage: P.non_archimedean_local_height(K.ideal(1-2*i))
2888
0
2889
2890
sage: Q = E.lift_x(-9/4); Q
2891
(-9/4 : -27/8*i : 1)
2892
sage: Q.non_archimedean_local_height(K.ideal(1+i))
2893
2*log(2)
2894
sage: Q.non_archimedean_local_height(K.ideal(3))
2895
0
2896
sage: Q.non_archimedean_local_height(K.ideal(1-2*i))
2897
0
2898
sage: Q.non_archimedean_local_height()
2899
1/2*log(16)
2900
2901
An example over the rational numbers::
2902
2903
sage: E = EllipticCurve([0, 0, 0, -36, 0])
2904
sage: P = E([-3, 9])
2905
sage: P.non_archimedean_local_height()
2906
-log(3)
2907
2908
Local heights of torsion points can be non-zero (unlike the
2909
global height)::
2910
2911
sage: K.<i> = QuadraticField(-1)
2912
sage: E = EllipticCurve([0, 0, 0, K(1), 0])
2913
sage: P = E(i, 0)
2914
sage: P.non_archimedean_local_height()
2915
-1/2*log(2)
2916
2917
TESTS::
2918
2919
sage: Q.non_archimedean_local_height(prec=100)
2920
1.3862943611198906188344642429
2921
sage: (3*Q).non_archimedean_local_height()
2922
1/2*log(75923153929839865104)
2923
2924
sage: F.<a> = NumberField(x^4 + 2*x^3 + 19*x^2 + 18*x + 288)
2925
sage: F.ring_of_integers().gens()
2926
[1, 5/6*a^3 + 1/6*a, 1/6*a^3 + 1/6*a^2, a^3]
2927
sage: F.class_number()
2928
12
2929
sage: E = EllipticCurve('37a').change_ring(F)
2930
sage: P = E((-a^2/6 - a/6 - 1, a)); P
2931
(-1/6*a^2 - 1/6*a - 1 : a : 1)
2932
sage: P[0].is_integral()
2933
True
2934
sage: P.non_archimedean_local_height()
2935
0
2936
2937
This shows that the bug reported at :trac:`13951` has been fixed::
2938
2939
sage: E = EllipticCurve([0,17])
2940
sage: P = E(2,5)
2941
sage: P.non_archimedean_local_height(2)
2942
-2/3*log(2)
2943
"""
2944
if prec:
2945
log = lambda x: rings.RealField(prec)(x).log()
2946
else:
2947
from sage.functions.log import log
2948
2949
if v is None:
2950
D = self.curve().discriminant()
2951
K = self.curve().base_ring()
2952
if K is rings.QQ:
2953
factorD = D.factor()
2954
if self[0] == 0:
2955
c = 1
2956
else:
2957
c = self[0].denominator()
2958
# The last sum is for bad primes that divide c where
2959
# the model is not minimal.
2960
h = (log(c)
2961
+ sum(self.non_archimedean_local_height(p, prec, weighted=True, is_minimal=(e < 12))
2962
for p,e in factorD if not p.divides(c))
2963
+ sum(self.non_archimedean_local_height(p, prec, weighted=True)
2964
- c.valuation(p) * log(p)
2965
for p,e in factorD if e >= 12 and p.divides(c)))
2966
else:
2967
factorD = K.factor(D)
2968
if self[0] == 0:
2969
c = K.ideal(1)
2970
else:
2971
c = K.ideal(self[0]).denominator()
2972
# The last sum is for bad primes that divide c where
2973
# the model is not minimal.
2974
h = (log(c.norm())
2975
+ sum(self.non_archimedean_local_height(v, prec, weighted=True, is_minimal=(e < 12))
2976
for v,e in factorD if not v.divides(c))
2977
+ sum(self.non_archimedean_local_height(v, prec, weighted=True)
2978
- c.valuation(v) * log(v.norm())
2979
for v,e in factorD if e >= 12 and v.divides(c)))
2980
if not weighted:
2981
h /= K.degree()
2982
return h
2983
2984
if is_minimal:
2985
E = self.curve()
2986
P = self
2987
offset = 0
2988
else:
2989
E = self.curve().local_minimal_model(v)
2990
P = self.curve().isomorphism_to(E)(self)
2991
# Silverman's normalization is not invariant under change of model,
2992
# but it all cancels out in the global height.
2993
offset = (self.curve().discriminant()/E.discriminant()).valuation(v)
2994
2995
a1, a2, a3, a4, a6 = E.a_invariants()
2996
b2, b4, b6, b8 = E.b_invariants()
2997
c4 = E.c4()
2998
x, y = P.xy()
2999
D = E.discriminant()
3000
N = D.valuation(v)
3001
A = (3*x**2 + 2*a2*x + a4 - a1*y).valuation(v)
3002
B = (2*y+a1*x+a3).valuation(v)
3003
C = (3*x**4 + b2*x**3 + 3*b4*x**2 + 3*b6*x + b8).valuation(v)
3004
if A <= 0 or B <= 0:
3005
r = max(0, -x.valuation(v))
3006
elif c4.valuation(v) == 0:
3007
n = min(B, N/2)
3008
r = -n*(N-n)/N
3009
elif C >= 3*B:
3010
r = -2*B/3
3011
else:
3012
r = -C/4
3013
r -= offset/6
3014
if not r:
3015
return rings.QQ(0)
3016
else:
3017
if E.base_ring() is rings.QQ:
3018
Nv = rings.ZZ(v)
3019
else:
3020
Nv = v.norm()
3021
if not weighted:
3022
r /= v.ramification_index() * v.residue_class_degree()
3023
return r * log(Nv)
3024
3025
nonarchimedian_local_height = deprecated_function_alias(13951, non_archimedean_local_height)
3026
3027
def elliptic_logarithm(self, embedding=None, precision=100,
3028
algorithm='pari'):
3029
r"""
3030
Returns the elliptic logarithm of this elliptic curve point.
3031
3032
An embedding of the base field into `\RR` or `\CC` (with
3033
arbitrary precision) may be given; otherwise the first real
3034
embedding is used (with the specified precision) if any, else
3035
the first complex embedding.
3036
3037
INPUT:
3038
3039
- ``embedding``: an embedding of the base field into `\RR` or `\CC`
3040
3041
- ``precision``: a positive integer (default 100) setting the
3042
number of bits of precision for the computation
3043
3044
- ``algorithm``: either 'pari' (default for real embeddings)
3045
to use PARI's ``ellpointtoz{}``, or 'sage' for a native
3046
implementation. Ignored for complex embeddings.
3047
3048
ALGORITHM:
3049
3050
See [Co2] Cohen H., A Course in Computational Algebraic Number
3051
Theory GTM 138, Springer 1996 for the case of real embeddings,
3052
and Cremona, J.E. and Thongjunthug , T. 2010 for the complex
3053
case.
3054
3055
AUTHORS:
3056
3057
- Michael Mardaus (2008-07),
3058
- Tobias Nagel (2008-07) -- original version from [Co2].
3059
- John Cremona (2008-07) -- revision following eclib code.
3060
- John Cremona (2010-03) -- implementation for complex embeddings.
3061
3062
EXAMPLES::
3063
3064
sage: E = EllipticCurve('389a')
3065
sage: E.discriminant() > 0
3066
True
3067
sage: P = E([-1,1])
3068
sage: P.is_on_identity_component ()
3069
False
3070
sage: P.elliptic_logarithm (precision=96)
3071
0.4793482501902193161295330101 + 0.985868850775824102211203849...*I
3072
sage: Q=E([3,5])
3073
sage: Q.is_on_identity_component()
3074
True
3075
sage: Q.elliptic_logarithm (precision=96)
3076
1.931128271542559442488585220
3077
3078
An example with negative discriminant, and a torsion point::
3079
3080
sage: E = EllipticCurve('11a1')
3081
sage: E.discriminant() < 0
3082
True
3083
sage: P = E([16,-61])
3084
sage: P.elliptic_logarithm(precision=70)
3085
0.25384186085591068434
3086
sage: E.period_lattice().real_period(prec=70) / P.elliptic_logarithm(precision=70)
3087
5.0000000000000000000
3088
3089
A larger example. The default algorithm uses PARI and makes
3090
sure the result has the requested precision::
3091
3092
sage: E = EllipticCurve([1, 0, 1, -85357462, 303528987048]) #18074g1
3093
sage: P = E([4458713781401/835903744, -64466909836503771/24167649046528, 1])
3094
sage: P.elliptic_logarithm() # 100 bits
3095
0.27656204014107061464076203097
3096
3097
The native algorithm 'sage' used to have trouble with
3098
precision in this example, but no longer::
3099
3100
sage: P.elliptic_logarithm(algorithm='sage') # 100 bits
3101
0.27656204014107061464076203097
3102
3103
This shows that the bug reported at :trac:`4901` has been fixed::
3104
3105
sage: E = EllipticCurve("4390c2")
3106
sage: P = E(683762969925/44944,-565388972095220019/9528128)
3107
sage: P.elliptic_logarithm()
3108
0.00025638725886520225353198932529
3109
sage: P.elliptic_logarithm(precision=64)
3110
0.000256387258865202254
3111
sage: P.elliptic_logarithm(precision=65)
3112
0.0002563872588652022535
3113
sage: P.elliptic_logarithm(precision=128)
3114
0.00025638725886520225353198932528666427412
3115
sage: P.elliptic_logarithm(precision=129)
3116
0.00025638725886520225353198932528666427412
3117
sage: P.elliptic_logarithm(precision=256)
3118
0.0002563872588652022535319893252866642741168388008346370015005142128009610936373
3119
sage: P.elliptic_logarithm(precision=257)
3120
0.00025638725886520225353198932528666427411683880083463700150051421280096109363730
3121
3122
Examples over number fields::
3123
3124
sage: K.<a> = NumberField(x^3-2)
3125
sage: embs = K.embeddings(CC)
3126
sage: E = EllipticCurve([0,1,0,a,a])
3127
sage: Ls = [E.period_lattice(e) for e in embs]
3128
sage: [L.real_flag for L in Ls]
3129
[0, 0, -1]
3130
sage: P = E(-1,0) # order 2
3131
sage: [L.elliptic_logarithm(P) for L in Ls]
3132
[-1.73964256006716 - 1.07861534489191*I, -0.363756518406398 - 1.50699412135253*I, 1.90726488608927]
3133
3134
sage: E = EllipticCurve([-a^2 - a - 1, a^2 + a])
3135
sage: Ls = [E.period_lattice(e) for e in embs]
3136
sage: pts = [E(2*a^2 - a - 1 , -2*a^2 - 2*a + 6 ), E(-2/3*a^2 - 1/3 , -4/3*a - 2/3 ), E(5/4*a^2 - 1/2*a , -a^2 - 1/4*a + 9/4 ), E(2*a^2 + 3*a + 4 , -7*a^2 - 10*a - 12 )]
3137
sage: [[L.elliptic_logarithm(P) for P in pts] for L in Ls]
3138
[[0.250819591818930 - 0.411963479992219*I, -0.290994550611374 - 1.37239400324105*I, -0.693473752205595 - 2.45028458830342*I, -0.151659609775291 - 1.48985406505459*I], [1.33444787667954 - 1.50889756650544*I, 0.792633734249234 - 0.548467043256610*I, 0.390154532655013 + 0.529423541805758*I, 0.931968675085317 - 0.431006981443071*I], [1.14758249500109 + 0.853389664016075*I, 2.59823462472518 + 0.853389664016075*I, 1.75372176444709, 0.303069634723001]]
3139
3140
::
3141
3142
sage: K.<i> = QuadraticField(-1)
3143
sage: E = EllipticCurve([0,0,0,9*i-10,21-i])
3144
sage: emb = K.embeddings(CC)[1]
3145
sage: L = E.period_lattice(emb)
3146
sage: P = E(2-i,4+2*i)
3147
sage: L.elliptic_logarithm(P,prec=100)
3148
0.70448375537782208460499649302 - 0.79246725643650979858266018068*I
3149
3150
"""
3151
from sage.rings.number_field.number_field import refine_embedding
3152
from sage.rings.all import RealField, ComplexField, QQ
3153
3154
# Check the trivial case:
3155
3156
C = ComplexField(precision)
3157
if self.is_zero():
3158
return C.zero()
3159
3160
# find a suitable embedding if none was supplied:
3161
3162
E = self.curve()
3163
K = E.base_field()
3164
rational = (K is QQ)
3165
emb = embedding
3166
3167
if emb is None:
3168
emb = K.embeddings(RealField(precision))
3169
if len(emb) > 0:
3170
emb = emb[0]
3171
else:
3172
emb = K.embeddings(ComplexField(precision))[0]
3173
else:
3174
# Get the precision of the supplied embedding
3175
prec = emb.codomain().precision()
3176
# if the precision parameter is greater, refine the embedding:
3177
if precision > prec:
3178
emb = refine_embedding(emb, precision)
3179
3180
L = E.period_lattice(emb)
3181
3182
if algorithm == 'sage' or not is_RealField(emb.codomain):
3183
return L.elliptic_logarithm(self, precision)
3184
3185
if algorithm != 'pari':
3186
raise ValueError("algorithm must be either 'pari' or 'sage'")
3187
3188
# From now on emb() is a real embedding of K into
3189
# RealField(precision). We interface with the PARI library.
3190
3191
x, y = self.xy()
3192
if rational: # work with exact coordinates
3193
E_work = E
3194
pt_pari = pari([x, y])
3195
else: # use the embedding to get real coordinates
3196
ai = [emb(a) for a in E.a_invariants()]
3197
E_work = EllipticCurve(ai) # defined over RR
3198
pt_pari = pari([emb(x), emb(y)])
3199
working_prec = precision
3200
E_pari = E_work.pari_curve(prec=working_prec)
3201
log_pari = E_pari.ellpointtoz(pt_pari, precision=working_prec)
3202
3203
while prec_words_to_bits(log_pari.precision()) < precision:
3204
# result is not precise enough, re-compute with double
3205
# precision. if the base field is not QQ, this
3206
# requires modifying the precision of the embedding,
3207
# the curve, and the point
3208
working_prec = 2*working_prec
3209
if not rational:
3210
emb = refine_embedding(emb, working_prec)
3211
ai = [emb(a) for a in E.a_invariants()]
3212
E_work = EllipticCurve(ai) # defined over RR
3213
pt_pari = pari([emb(x), emb(y)])
3214
E_pari = E_work.pari_curve(prec=working_prec)
3215
log_pari = E_pari.ellpointtoz(pt_pari, precision=working_prec)
3216
3217
# normalization step
3218
r, i = C(log_pari)
3219
wR, wI = L.basis(prec=precision)
3220
k = (r/wR).floor()
3221
if k:
3222
r -= k*wR
3223
if self.is_on_identity_component(emb):
3224
return C(r)
3225
# Now there are two components and P is on the non-identity one
3226
return C(r)+C(wI/2)
3227
3228
def padic_elliptic_logarithm(self, p, absprec=20):
3229
r"""
3230
Computes the `p`-adic elliptic logarithm of this point.
3231
3232
INPUT:
3233
3234
``p`` - integer: a prime ``absprec`` - integer (default: 20):
3235
the initial `p`-adic absolute precision of the computation
3236
3237
OUTPUT:
3238
3239
The `p`-adic elliptic logarithm of self, with precision ``absprec``.
3240
3241
AUTHORS:
3242
3243
- Tobias Nagel
3244
- Michael Mardaus
3245
- John Cremona
3246
3247
ALGORITHM:
3248
3249
For points in the formal group (i.e. not integral at `p`) we
3250
take the ``log()`` function from the formal groups module and
3251
evaluate it at `-x/y`. Otherwise we first multiply the point
3252
to get into the formal group, and divide the result
3253
afterwards.
3254
3255
.. TODO::
3256
3257
See comments at :trac:`4805`. Currently the absolute
3258
precision of the result may be less than the given value
3259
of absprec, and error-handling is imperfect.
3260
3261
EXAMPLES::
3262
3263
sage: E = EllipticCurve([0,1,1,-2,0])
3264
sage: E(0).padic_elliptic_logarithm(3)
3265
0
3266
sage: P = E(0,0)
3267
sage: P.padic_elliptic_logarithm(3)
3268
2 + 2*3 + 3^3 + 2*3^7 + 3^8 + 3^9 + 3^11 + 3^15 + 2*3^17 + 3^18 + O(3^19)
3269
sage: P.padic_elliptic_logarithm(3).lift()
3270
660257522
3271
sage: P = E(-11/9,28/27)
3272
sage: [(2*P).padic_elliptic_logarithm(p)/P.padic_elliptic_logarithm(p) for p in prime_range(20)] # long time (3s)
3273
[2 + O(2^19), 2 + O(3^20), 2 + O(5^19), 2 + O(7^19), 2 + O(11^19), 2 + O(13^19), 2 + O(17^19), 2 + O(19^19)]
3274
sage: [(3*P).padic_elliptic_logarithm(p)/P.padic_elliptic_logarithm(p) for p in prime_range(12)] # long time (2s)
3275
[1 + 2 + O(2^19), 3 + 3^20 + O(3^21), 3 + O(5^19), 3 + O(7^19), 3 + O(11^19)]
3276
sage: [(5*P).padic_elliptic_logarithm(p)/P.padic_elliptic_logarithm(p) for p in prime_range(12)] # long time (2s)
3277
[1 + 2^2 + O(2^19), 2 + 3 + O(3^20), 5 + O(5^19), 5 + O(7^19), 5 + O(11^19)]
3278
3279
An example which arose during reviewing :trac:`4741`::
3280
3281
sage: E = EllipticCurve('794a1')
3282
sage: P = E(-1,2)
3283
sage: P.padic_elliptic_logarithm(2) # default precision=20
3284
2^4 + 2^5 + 2^6 + 2^8 + 2^9 + 2^13 + 2^14 + 2^15 + O(2^16)
3285
sage: P.padic_elliptic_logarithm(2, absprec=30)
3286
2^4 + 2^5 + 2^6 + 2^8 + 2^9 + 2^13 + 2^14 + 2^15 + 2^22 + 2^23 + 2^24 + O(2^26)
3287
sage: P.padic_elliptic_logarithm(2, absprec=40)
3288
2^4 + 2^5 + 2^6 + 2^8 + 2^9 + 2^13 + 2^14 + 2^15 + 2^22 + 2^23 + 2^24 + 2^28 + 2^29 + 2^31 + 2^34 + O(2^35)
3289
"""
3290
if not p.is_prime():
3291
raise ValueError('p must be prime')
3292
debug = False # True
3293
if debug:
3294
print "P=", self, "; p=", p, " with precision ", absprec
3295
E = self.curve()
3296
Q_p = Qp(p, absprec)
3297
if self.has_finite_order():
3298
return Q_p(0)
3299
while True:
3300
try:
3301
Ep = E.change_ring(Q_p)
3302
P = Ep(self)
3303
x, y = P.xy()
3304
break
3305
except (PrecisionError, ArithmeticError, ZeroDivisionError):
3306
absprec *= 2
3307
Q_p = Qp(p, absprec)
3308
if debug:
3309
print "x,y=", (x, y)
3310
f = 1 # f will be such that f*P is in the formal group E^1(Q_p)
3311
if x.valuation() >= 0: # P is not in E^1
3312
if not self.has_good_reduction(p): # P is not in E^0
3313
n = E.tamagawa_exponent(p) # n*P has good reduction at p
3314
if debug:
3315
print "Tamagawa exponent = =", n
3316
f = n
3317
P = n*P # lies in E^0
3318
if debug:
3319
print "P=", P
3320
try:
3321
x, y = P.xy()
3322
except ZeroDivisionError:
3323
raise ValueError("Insufficient precision in "
3324
"p-adic_elliptic_logarithm()")
3325
if debug:
3326
print "x,y=", (x, y)
3327
if x.valuation() >= 0: # P is still not in E^1
3328
t = E.local_data(p).bad_reduction_type()
3329
if t is None:
3330
m = E.reduction(p).abelian_group().exponent()
3331
else:
3332
m = p - t
3333
if debug:
3334
print "mod p exponent = =", m
3335
# now m*(n*P) reduces to the identity mod p, so is
3336
# in E^1(Q_p)
3337
f *= m
3338
P = m*P # lies in E^1
3339
try:
3340
x, y = P.xy()
3341
except ZeroDivisionError:
3342
raise ValueError("Insufficient precision in "
3343
"p-adic_elliptic_logarithm()")
3344
if debug:
3345
print "f=", f
3346
print "x,y=", (x, y)
3347
vx = x.valuation()
3348
vy = y.valuation()
3349
v = vx-vy
3350
if not (v > 0 and vx == -2*v and vy == -3*v):
3351
raise ValueError("Insufficient precision in "
3352
"p-adic_elliptic_logarithm()")
3353
try:
3354
t = -x/y
3355
except (ZeroDivisionError, PrecisionError):
3356
raise ValueError("Insufficient precision in "
3357
"p-adic_elliptic_logarithm()")
3358
if debug:
3359
print "t=", t, ", with valuation ", v
3360
phi = Ep.formal().log(prec=1+absprec//v)
3361
return phi(t)/f
3362
3363
3364
class EllipticCurvePoint_finite_field(EllipticCurvePoint_field):
3365
r"""
3366
Class for elliptic curve points over finite fields.
3367
"""
3368
def _magma_init_(self, magma):
3369
"""
3370
Return a string representation of self that ``MAGMA`` can
3371
use for input.
3372
3373
EXAMPLE::
3374
3375
sage: E = EllipticCurve(GF(17), [1,-1])
3376
sage: P = E([13, 4])
3377
sage: P._magma_init_(magma) # optional - magma
3378
'EllipticCurve([_sage_ref...|GF(17)!0,GF(17)!0,GF(17)!0,GF(17)!1,GF(17)!16])![13,4]'
3379
"""
3380
E = self.curve()._magma_init_(magma)
3381
x, y = self.xy()
3382
return "%s![%s,%s]" % (E, x, y)
3383
3384
def discrete_log(self, Q, ord=None):
3385
r"""
3386
Returns discrete log of `Q` with respect to `P` =self.
3387
3388
INPUT:
3389
3390
- ``Q`` (point) -- another point on the same curve as self.
3391
3392
- ``ord`` (integer or ``None`` (default)) -- the order of self.
3393
3394
OUTPUT:
3395
3396
(integer) -- The discrete log of `Q` with respect to `P`, which is an
3397
integer `m` with `0\le m<o(P)` such that `mP=Q`, if one
3398
exists. A ValueError is raised if there is no solution.
3399
3400
.. NOTE::
3401
3402
The order of self is computed if not supplied.
3403
3404
AUTHOR:
3405
3406
- John Cremona. Adapted to use generic functions 2008-04-05.
3407
3408
EXAMPLE::
3409
3410
sage: F = GF(3^6,'a')
3411
sage: a = F.gen()
3412
sage: E = EllipticCurve([0,1,1,a,a])
3413
sage: E.cardinality()
3414
762
3415
sage: A = E.abelian_group()
3416
sage: P = A.gen(0).element()
3417
sage: Q = 400*P
3418
sage: P.discrete_log(Q)
3419
400
3420
"""
3421
if ord is None:
3422
ord = self.order()
3423
try:
3424
return generic.discrete_log(Q, self, ord, operation='+')
3425
except Exception:
3426
raise ValueError("ECDLog problem has no solution")
3427
3428
def order(self):
3429
r"""
3430
Return the order of this point on the elliptic curve.
3431
3432
ALGORITHM:
3433
3434
Use generic functions from :mod:`sage.groups.generic`. If the
3435
group order is known, use ``order_from_multiple()``, otherwise
3436
use ``order_from_bounds()`` with the Hasse bounds for the base
3437
field. In the latter case, we might find that we have a
3438
generator for the group, in which case it is cached.
3439
3440
We do not cause the group order to be calculated when not
3441
known, since this function is used in determining the group
3442
order via computation of several random points and their
3443
orders.
3444
3445
.. NOTE::
3446
3447
:meth:`additive_order` is a synonym for :meth:`order`
3448
3449
AUTHOR:
3450
3451
- John Cremona, 2008-02-10, adapted 2008-04-05 to use generic functions.
3452
3453
EXAMPLES::
3454
3455
sage: k.<a> = GF(5^5)
3456
sage: E = EllipticCurve(k,[2,4]); E
3457
Elliptic Curve defined by y^2 = x^3 + 2*x + 4 over Finite Field in a of size 5^5
3458
sage: P = E(3*a^4 + 3*a , 2*a + 1 )
3459
sage: P.order()
3460
3227
3461
sage: Q = E(0,2)
3462
sage: Q.order()
3463
7
3464
sage: Q.additive_order()
3465
7
3466
3467
In the next example, the cardinality of E will be computed
3468
(using SEA) and cached::
3469
3470
sage: p=next_prime(2^150)
3471
sage: E=EllipticCurve(GF(p),[1,1])
3472
sage: P=E(831623307675610677632782670796608848711856078, 42295786042873366706573292533588638217232964)
3473
sage: P.order()
3474
1427247692705959881058262545272474300628281448
3475
sage: P.order()==E.cardinality()
3476
True
3477
"""
3478
try:
3479
return self._order
3480
except AttributeError:
3481
pass
3482
if self.is_zero():
3483
return rings.Integer(1)
3484
E = self.curve()
3485
K = E.base_ring()
3486
from sage.schemes.plane_curves.projective_curve import Hasse_bounds
3487
bounds = Hasse_bounds(K.order())
3488
3489
try:
3490
M = E._order
3491
try:
3492
plist = E._prime_factors_of_order
3493
except AttributeError:
3494
plist = M.prime_divisors()
3495
E._prime_factors_of_order = plist
3496
N = generic.order_from_multiple(self, M, plist, operation='+')
3497
except Exception:
3498
if K.is_prime_field():
3499
M = E.cardinality() # computed and cached
3500
plist = M.prime_divisors()
3501
E._prime_factors_of_order = plist
3502
N = generic.order_from_multiple(self, M, plist, operation='+')
3503
else:
3504
N = generic.order_from_bounds(self, bounds, operation='+')
3505
3506
if 2*N > bounds[1]: # then we have a generator, so cache this
3507
if not hasattr(E, '_order'):
3508
E._order = N
3509
if not hasattr(E, '__abelian_group'):
3510
E.__abelian_group = AbelianGroup([N]), (self, )
3511
3512
self._order = N
3513
return self._order
3514
3515
additive_order = order
3516
3517