diff --git a/doc/ref/makedocreldata.g b/doc/ref/makedocreldata.g index d603ac5c73..4da443b05c 100644 --- a/doc/ref/makedocreldata.g +++ b/doc/ref/makedocreldata.g @@ -53,6 +53,7 @@ GAPInfo.ManualDataRef:= rec( "../../lib/cyclotom.g", "../../lib/cyclotom.gd", "../../lib/cyclotom.gi", + "../../lib/dlog.gd", "../../lib/dict.gd", "../../lib/domain.gd", "../../lib/extlset.gd", diff --git a/doc/ref/numtheor.xml b/doc/ref/numtheor.xml index 62347d9ce7..4825b08ce2 100644 --- a/doc/ref/numtheor.xml +++ b/doc/ref/numtheor.xml @@ -42,6 +42,7 @@ <#Include Label="OrderMod"> <#Include Label="LogMod"> +<#Include Label="DLog"> <#Include Label="PrimitiveRootMod"> <#Include Label="IsPrimitiveRootMod"> diff --git a/lib/dlog.gd b/lib/dlog.gd index 7c607ebce6..22db295856 100644 --- a/lib/dlog.gd +++ b/lib/dlog.gd @@ -14,22 +14,44 @@ ############################################################################# ## -#F _DLog( , [, ] ) +#F DLog( , [, ] ) ## +## <#GAPDoc Label="DLog"> ## -## -## +## +## an integer ## ## logarithm -## returns a discrete logarithm of x w.r.t. the basis base, -## i. e., an integer l such that base^l = x -## holds, if such a number exists. -## Otherwise fail is returned. +## The argument base must be a multiplicative element and x +## must lie in the cyclic group generated by base. The third argument +## m must be the order of base or its factorization. If +## m is not given, it is computed first. This function returns the +## discrete logarithm, that is an integer e such that base^e +## = x. +##

+## If m is prime then Shanks' algorithm is used (which needs +## O(\sqrt{m}) space and time). Otherwise let m = r +## l and e = a + b r with 0 \leq a < r. Then a +## = DLog(base^l, x^l, r) and b = +## DLog(base^r, x/base^a, l). ##

-## The order of base or its factorization can be given as m. +## This function is used for a method of . +## +## +## gap> q:= 67^12; +## 8182718904632857144561 +## gap> z:= Z(q);; +## gap> DLog(z, z+1); +## 2874413785388345993274 +## gap> DLog(z, z^2+1); +## 1667375214152688471247 +## gap> DLog(z, Z(67)); +## 123980589464134199160 +## ## ## +## <#/GAPDoc> ## -DeclareGlobalFunction( "_DLog" ); +DeclareGlobalFunction( "DLog" ); -DeclareGlobalFunction( "_DLogShanks" ); +DeclareGlobalFunction( "DLogShanks" ); diff --git a/lib/dlog.gi b/lib/dlog.gi index c43357eb55..56ae802195 100644 --- a/lib/dlog.gi +++ b/lib/dlog.gi @@ -15,13 +15,13 @@ ############################################################################# ## -#F _DLogShanks( , , ) +#F DLogShanks( , , ) ## ## Let be a multiplicative element of order . ## Return an integer l such that = ^l holds, ## or 'fail' if no such l exists. ## -InstallGlobalFunction( _DLogShanks, function(base, x, r) +InstallGlobalFunction( DLogShanks, function(base, x, r) local rr, baby, ord, giant, t, pos, i, j; rr := RootInt(r, 2); baby := [One(base)]; @@ -51,15 +51,15 @@ end ); ############################################################################# ## -#F _DLog( , [, ] ) +#F DLog( , [, ] ) ## ## recursive method, can be the order m of or its factorization ## Let r be the largest prime factor of m, then we use ## ^e = with e = a + b*r where 0 <= a < r and ## 0 <= b < m/r, -## and compute a with _DLogShanks and b by recursion. +## and compute a with DLogShanks and b by recursion. ## -InstallGlobalFunction( _DLog, function(base, x, m...) +InstallGlobalFunction( DLog, function(base, x, m...) local r, mm, mp, a, b; if Length(m) = 0 then m := Order(base); @@ -70,16 +70,16 @@ InstallGlobalFunction( _DLog, function(base, x, m...) m := Factors(m); fi; if Length(m) = 1 then - return _DLogShanks(base, x, m[1]); + return DLogShanks(base, x, m[1]); fi; r := m[Length(m)]; mm := m{[1..Length(m)-1]}; mp := Product(mm); - a := _DLogShanks(base^mp, x^mp, r); + a := DLogShanks(base^mp, x^mp, r); if a = fail then return fail; fi; - b := _DLog(base^r, x/(base^a), mm); + b := DLog(base^r, x/(base^a), mm); if b = fail then return fail; fi; @@ -104,5 +104,5 @@ BindGlobal( "DoDLog", function(x, base) else e := 1; fi; - return _DLog(base, x, o) * e; + return DLog(base, x, o) * e; end ); diff --git a/tst/testinstall/dlog.tst b/tst/testinstall/dlog.tst index 0a09fa31a2..28635da30a 100644 --- a/tst/testinstall/dlog.tst +++ b/tst/testinstall/dlog.tst @@ -1,21 +1,21 @@ #@local R, o gap> START_TEST( "dlog.tst" ); -# _DLog +# DLog gap> R:= Integers mod 71;; o:= One( R );; -gap> _DLog( 2*o, 4*o ); +gap> DLog( 2*o, 4*o ); 2 gap> R:= Integers mod 17;; o:= One( R );; -gap> _DLog( 2*o, 3*o ); +gap> DLog( 2*o, 3*o ); fail gap> R:= Integers mod 9;; o:= One( R );; -gap> _DLog( 2*o, 4*o ); +gap> DLog( 2*o, 4*o ); 2 -gap> _DLog( 3*o, 4*o ); +gap> DLog( 3*o, 4*o ); Error, is not invertible -gap> ForAll( Primes, p -> p = 2 or _DLog( Z(p^2), Z(p^2)^2 ) = 2 ); +gap> ForAll( Primes, p -> p = 2 or DLog( Z(p^2), Z(p^2)^2 ) = 2 ); true -gap> ForAll( Primes, p -> p = 2 or _DLog( Z(p^2)^2, Z(p^2) ) = fail ); +gap> ForAll( Primes, p -> p = 2 or DLog( Z(p^2)^2, Z(p^2) ) = fail ); true #