@@ -385,6 +385,13 @@ def bsgs(a, b, bounds, operation='*', identity=None, inverse=None, op=None):
385
385
arguments are provided automatically; otherwise they must be
386
386
provided by the caller.
387
387
388
+ .. SEEALSO::
389
+
390
+ - :func:`discrete_log` for a potentially faster algorithm by combining
391
+ Pohlig-Hellman with baby-step adjacent-step;
392
+ - :func:`order_from_bounds` to find the exact order instead of just some
393
+ multiple of the order.
394
+
388
395
INPUT:
389
396
390
397
- ``a`` -- group element
@@ -694,7 +701,9 @@ def discrete_log(a, base, ord=None, bounds=None, operation='*', identity=None, i
694
701
695
702
- ``a`` -- group element
696
703
- ``base`` -- group element (the base)
697
- - ``ord`` -- integer (multiple of order of base, or ``None``)
704
+ - ``ord`` -- integer (multiple of order of base, or ``None``). Can also be
705
+ :mod:`oo <sage.rings.infinity>` to explicitly not use this, for example
706
+ when factorizing the order is difficult.
698
707
- ``bounds`` -- a priori bounds on the log
699
708
- ``operation`` -- string: ``'*'``, ``'+'``, other
700
709
- ``identity`` -- the group's identity
@@ -864,6 +873,14 @@ def discrete_log(a, base, ord=None, bounds=None, operation='*', identity=None, i
864
873
sage: discrete_log(u, g, algorithm='rho')
865
874
123456789
866
875
876
+ Pass ``ord=oo`` to avoid attempts to factorize the group order::
877
+
878
+ sage: p, q = next_prime(2^128), next_prime(2^129)
879
+ sage: a = mod(2, p*q*124+1)
880
+ sage: discrete_log(a^100, a, bounds=(1, 500)) # not tested (takes very long, but pari.addprimes(p) makes it faster)
881
+ sage: discrete_log(a^100, a, ord=oo, bounds=(1, 500))
882
+ 100
883
+
867
884
TESTS:
868
885
869
886
Random testing::
@@ -917,6 +934,7 @@ def discrete_log(a, base, ord=None, bounds=None, operation='*', identity=None, i
917
934
lb , ub = map (integer_ring .ZZ , bounds )
918
935
if (op is None or identity is None or inverse is None or ord is None ) and operation not in addition_names + multiplication_names :
919
936
raise ValueError ("ord, op, identity, and inverse must all be specified for this operation" )
937
+ from sage .rings .infinity import Infinity
920
938
if ord is None :
921
939
if operation in multiplication_names :
922
940
try :
@@ -928,11 +946,10 @@ def discrete_log(a, base, ord=None, bounds=None, operation='*', identity=None, i
928
946
ord = base .additive_order ()
929
947
except Exception :
930
948
ord = base .order ()
931
- else :
949
+ elif ord != Infinity :
932
950
ord = integer_ring .ZZ (ord )
933
951
try :
934
- from sage .rings .infinity import Infinity
935
- if ord == + Infinity :
952
+ if ord == Infinity :
936
953
return bsgs (base , a , bounds , identity = identity , inverse = inverse , op = op , operation = operation )
937
954
if base == power (base , 0 ) and a != base :
938
955
raise ValueError
0 commit comments