@@ -665,7 +665,7 @@ def discrete_log_rho(a, base, ord=None, operation='*', hash_function=hash):
665
665
raise ValueError ("Pollard rho algorithm failed to find a logarithm" )
666
666
667
667
668
- def discrete_log (a , base , ord = None , bounds = None , operation = '*' , identity = None , inverse = None , op = None ):
668
+ def discrete_log (a , base , ord = None , bounds = None , operation = '*' , identity = None , inverse = None , op = None , use_rho = False ):
669
669
r"""
670
670
Totally generic discrete log function.
671
671
@@ -679,6 +679,8 @@ def discrete_log(a, base, ord=None, bounds=None, operation='*', identity=None, i
679
679
- ``identity`` - the group's identity
680
680
- ``inverse()`` - function of 1 argument ``x`` returning inverse of ``x``
681
681
- ``op()`` - function of 2 arguments ``x``, ``y`` returning ``x*y`` in group
682
+ - ``use_rho`` - use Pollard's rho instead of BSGS (this option may be
683
+ overwritten if the base order is small)
682
684
683
685
``a`` and ``base`` must be elements of some group with identity
684
686
given by identity, inverse of ``x`` by ``inverse(x)``, and group
@@ -818,16 +820,26 @@ def discrete_log(a, base, ord=None, bounds=None, operation='*', identity=None, i
818
820
for i , (pi , ri ) in enumerate (f ):
819
821
for j in range (ri ):
820
822
if operation in multiplication_names :
821
- c = bsgs (base ** (ord // pi ),
822
- (a / base ** l [i ])** (ord // pi ** (j + 1 )),
823
- (0 , pi ),
824
- operation = operation )
823
+ if (not use_rho ):
824
+ c = bsgs (base ** (ord // pi ),
825
+ (a / base ** l [i ])** (ord // pi ** (j + 1 )),
826
+ (0 , pi ),
827
+ operation = operation )
828
+ else :
829
+ c = discrete_log_rho ((a / base ** l [i ])** (ord // pi ** (j + 1 )),
830
+ base ** (ord // pi ),
831
+ operation = operation )
825
832
l [i ] += c * (pi ** j )
826
833
elif operation in addition_names :
827
- c = bsgs (base * (ord // pi ),
828
- (a - base * l [i ]) * (ord // pi ** (j + 1 )),
829
- (0 , pi ),
830
- operation = operation )
834
+ if (not use_rho ):
835
+ c = bsgs (base * (ord // pi ),
836
+ (a - base * l [i ]) * (ord // pi ** (j + 1 )),
837
+ (0 , pi ),
838
+ operation = operation )
839
+ else :
840
+ c = discrete_log_rho ((a - base * l [i ]) * (ord // pi ** (j + 1 )),
841
+ base * (ord // pi ),
842
+ operation = operation )
831
843
l [i ] += c * (pi ** j )
832
844
from sage .arith .all import CRT_list
833
845
return CRT_list (l , [pi ** ri for pi , ri in f ])
0 commit comments