@@ -3908,10 +3908,11 @@ def _acted_upon_(self, other, side):
3908
3908
3909
3909
return Q
3910
3910
3911
- def discrete_log (self , Q ):
3911
+ def log (self , base ):
3912
3912
r"""
3913
- Return the discrete logarithm of `Q` to base `P` = ``self``,
3914
- that is, an integer `x` such that `xP = Q`.
3913
+ Return the discrete logarithm of this point to the given ``base``.
3914
+ In other words, return an integer `x` such that `xP = Q` where
3915
+ `P` is ``base`` and `Q` is this point.
3915
3916
3916
3917
A :class:`ValueError` is raised if there is no solution.
3917
3918
@@ -3939,7 +3940,7 @@ def discrete_log(self, Q):
3939
3940
3940
3941
INPUT:
3941
3942
3942
- - ``Q `` (point) -- another point on the same curve as ``self``.
3943
+ - ``base `` (point) -- another point on the same curve as ``self``.
3943
3944
3944
3945
OUTPUT:
3945
3946
@@ -3962,7 +3963,7 @@ def discrete_log(self, Q):
3962
3963
762
3963
3964
sage: P = E.gens()[0]
3964
3965
sage: Q = 400*P
3965
- sage: P.discrete_log(Q )
3966
+ sage: Q.log(P )
3966
3967
400
3967
3968
3968
3969
TESTS:
@@ -3976,27 +3977,53 @@ def discrete_log(self, Q):
3976
3977
sage: E = EllipticCurve(j=GF((p,e),'a').random_element())
3977
3978
sage: P = E.random_point()
3978
3979
sage: Q = randrange(2**999) * P
3979
- sage: x = P.discrete_log(Q )
3980
+ sage: x = Q.log(P )
3980
3981
sage: x*P == Q
3981
3982
True
3982
3983
"""
3983
- if Q not in self .parent ():
3984
+ if base not in self .parent ():
3984
3985
raise ValueError ('not a point on the same curve' )
3985
- n = self .order ()
3986
- if n * Q :
3987
- raise ValueError ('ECDLog problem has no solution (order of Q does not divide order of P )' )
3986
+ n = base .order ()
3987
+ if n * self :
3988
+ raise ValueError ('ECDLog problem has no solution (order does not divide order of base )' )
3988
3989
E = self .curve ()
3989
3990
F = E .base_ring ()
3990
3991
p = F .cardinality ()
3991
3992
if F .is_prime_field () and n == p :
3992
3993
# Anomalous case
3993
- return self .padic_elliptic_logarithm (Q , p )
3994
+ return base .padic_elliptic_logarithm (self , p )
3994
3995
elif hasattr (E , '_order' ) and E ._order .gcd (n ** 2 ) == n :
3995
3996
pass # cyclic rational n-torsion -> okay
3996
- elif self .weil_pairing (Q , n ) != 1 :
3997
+ elif base .weil_pairing (self , n ) != 1 :
3997
3998
raise ValueError ('ECDLog problem has no solution (non-trivial Weil pairing)' )
3998
3999
3999
- return ZZ (pari .elllog (self .curve (), Q , self , n ))
4000
+ return ZZ (pari .elllog (self .curve (), self , base , n ))
4001
+
4002
+ def discrete_log (self , Q ):
4003
+ r"""
4004
+ Legacy version of :meth:`log` with its arguments swapped.
4005
+
4006
+ Note that this method uses the opposite argument ordering
4007
+ of all other logarithm methods in Sage; see :issue:`37150`.
4008
+
4009
+ EXAMPLES::
4010
+
4011
+ sage: E = EllipticCurve(j=GF(101)(5))
4012
+ sage: P, = E.gens()
4013
+ sage: (2*P).log(P)
4014
+ 2
4015
+ sage: (2*P).discrete_log(P)
4016
+ doctest:warning ...
4017
+ DeprecationWarning: The syntax P.discrete_log(Q) ... Please update your code. ...
4018
+ 45
4019
+ sage: P.discrete_log(2*P)
4020
+ 2
4021
+ """
4022
+ from sage .misc .superseded import deprecation
4023
+ deprecation (37150 , 'The syntax P.discrete_log(Q) is being replaced by '
4024
+ 'Q.log(P) to make the argument ordering of logarithm'
4025
+ ' methods in Sage uniform. Please update your code.' )
4026
+ return Q .log (self )
4000
4027
4001
4028
def padic_elliptic_logarithm (self ,Q , p ):
4002
4029
r"""
0 commit comments