@@ -3842,10 +3842,11 @@ def _acted_upon_(self, other, side):
3842
3842
3843
3843
return Q
3844
3844
3845
- def discrete_log (self , Q ):
3845
+ def log (self , base ):
3846
3846
r"""
3847
- Return the discrete logarithm of `Q` to base `P` = ``self``,
3848
- that is, an integer `x` such that `xP = Q`.
3847
+ Return the discrete logarithm of this point to the given ``base``.
3848
+ In other words, return an integer `x` such that `xP = Q` where
3849
+ `P` is ``base`` and `Q` is this point.
3849
3850
3850
3851
A :class:`ValueError` is raised if there is no solution.
3851
3852
@@ -3873,7 +3874,7 @@ def discrete_log(self, Q):
3873
3874
3874
3875
INPUT:
3875
3876
3876
- - ``Q `` (point) -- another point on the same curve as ``self``.
3877
+ - ``base `` (point) -- another point on the same curve as ``self``.
3877
3878
3878
3879
OUTPUT:
3879
3880
@@ -3896,7 +3897,7 @@ def discrete_log(self, Q):
3896
3897
762
3897
3898
sage: P = E.gens()[0]
3898
3899
sage: Q = 400*P
3899
- sage: P.discrete_log(Q )
3900
+ sage: Q.log(P )
3900
3901
400
3901
3902
3902
3903
TESTS:
@@ -3910,27 +3911,53 @@ def discrete_log(self, Q):
3910
3911
sage: E = EllipticCurve(j=GF((p,e),'a').random_element())
3911
3912
sage: P = E.random_point()
3912
3913
sage: Q = randrange(2**999) * P
3913
- sage: x = P.discrete_log(Q )
3914
+ sage: x = Q.log(P )
3914
3915
sage: x*P == Q
3915
3916
True
3916
3917
"""
3917
- if Q not in self .parent ():
3918
+ if base not in self .parent ():
3918
3919
raise ValueError ('not a point on the same curve' )
3919
- n = self .order ()
3920
- if n * Q :
3921
- raise ValueError ('ECDLog problem has no solution (order of Q does not divide order of P )' )
3920
+ n = base .order ()
3921
+ if n * self :
3922
+ raise ValueError ('ECDLog problem has no solution (order does not divide order of base )' )
3922
3923
E = self .curve ()
3923
3924
F = E .base_ring ()
3924
3925
p = F .cardinality ()
3925
3926
if F .is_prime_field () and n == p :
3926
3927
# Anomalous case
3927
- return self .padic_elliptic_logarithm (Q , p )
3928
+ return base .padic_elliptic_logarithm (self , p )
3928
3929
elif hasattr (E , '_order' ) and E ._order .gcd (n ** 2 ) == n :
3929
3930
pass # cyclic rational n-torsion -> okay
3930
- elif self .weil_pairing (Q , n ) != 1 :
3931
+ elif base .weil_pairing (self , n ) != 1 :
3931
3932
raise ValueError ('ECDLog problem has no solution (non-trivial Weil pairing)' )
3932
3933
3933
- return ZZ (pari .elllog (self .curve (), Q , self , n ))
3934
+ return ZZ (pari .elllog (self .curve (), self , base , n ))
3935
+
3936
+ def discrete_log (self , Q ):
3937
+ r"""
3938
+ Legacy version of :meth:`log` with its arguments swapped.
3939
+
3940
+ Note that this method uses the opposite argument ordering
3941
+ of all other logarithm methods in Sage; see :issue:`37150`.
3942
+
3943
+ EXAMPLES::
3944
+
3945
+ sage: E = EllipticCurve(j=GF(101)(5))
3946
+ sage: P, = E.gens()
3947
+ sage: (2*P).log(P)
3948
+ 2
3949
+ sage: (2*P).discrete_log(P)
3950
+ doctest:warning ...
3951
+ DeprecationWarning: The syntax P.discrete_log(Q) ... Please update your code. ...
3952
+ 45
3953
+ sage: P.discrete_log(2*P)
3954
+ 2
3955
+ """
3956
+ from sage .misc .superseded import deprecation
3957
+ deprecation (37150 , 'The syntax P.discrete_log(Q) is being replaced by '
3958
+ 'Q.log(P) to make the argument ordering of logarithm'
3959
+ ' methods in Sage uniform. Please update your code.' )
3960
+ return Q .log (self )
3934
3961
3935
3962
def padic_elliptic_logarithm (self ,Q , p ):
3936
3963
r"""
0 commit comments