j
= 0
,
1
, . . . ,
we have
β
=
αγ

mj
=
γ
(
v

j
)
m
+
u
.
So we will find that
i
6
=

1 precisely when
j
=
v
, in which case
i
=
u
. Thus, the output will be
correct, and the total running time of the algorithm is easily seen to be
O
(
q
1
/
2
L
(
p
)
2
).
While this algorithm is much faster than bruteforce search, it has the drawback that it requires
a table of size
O
(
q
1
/
2
). Of course, there is a “time/space tradeoff” here: by choosing
m
smaller,
we get a table of size
O
(
m
), but the running time will be proportional to
O
(
q/m
).
There are, in fact, algorithms that run (at least heuristically) in time proportional to
O
(
q
1
/
2
),
but which require only a constant amount of space. We do not discuss these algorithms here.
8.2.3
Groups of order
q
e
Suppose that
γ
∈
Z
*
p
generates a subgroup of order
q
e
, where
q >
1 and
e
≥
1, and we are given
p
,
q
,
γ
, and
α
∈ h
γ
i
, and wish to compute log
γ
α
.
There is a simple algorithm that allows one to reduce this problem to the problem of computing
discrete logarithms in a subgroup of order
q
.
It is perhaps easiest to describe the algorithm recursively.
The base case is when
e
= 1, in which case, we use an algorithm for the subgroup of order
q
.
Suppose now that
e >
1.
We choose an integer
f
with 0
< f < e
.
Different strategies for
choosing
f
yield different algorithms — we discuss this below. Suppose
α
=
γ
x
, where 0
≤
x < q
e
.
Then we can write
x
=
q
f
v
+
u
, where 0
≤
u < q
f
and 0
≤
v < q
e

f
. Therefore,
α
q
e

f
=
γ
q
e

f
u
.
Note that
γ
q
e

f
has order
q
f
, and so if we recursively compute the discrete logarithm of
α
q
e

f
to
the base
γ
q
e

f
, we obtain
u
.
Having obtained
u
, observe
α/γ
u
=
γ
q
f
v
.
Note also that
γ
q
f
has order
q
e

f
, and so if we recursively compute the discrete logarithm of
α/γ
u
to the base
γ
q
f
, we obtain
u
, from which we then compute
x
=
q
f
v
+
u
.
To analyze the running time of this algorithm, note that we recursively reduce the discrete
logarithm problem to a base of order
q
e
to two discrete logarithm problems: one to a base of order
q
f
and the other to a base of order
q
e

f
. The running time of the body of one recursive invocation
(not counting the running time of the recursive calls it makes) is
O
(
e
log
q
· L
(
p
)
2
).
To calculate the total running time, we have to sum up the running times of all the recursive
calls plus the running times of all the base cases.
Regardless of the strategy for choosing
f
, the total number of base case invocations is
e
. Note
that for
e >
1, all the base cases compute discrete logarithms are to the base
γ
q
e

1
. Assuming we
implement the base case using the baby step/giant step algorithm, the total running time for all
the base cases is therefore
O
(
eq
1
/
2
L
(
p
)
2
).