In this section, we present some methods for computing discrete logarithms. A method based on the birthday attack is discussed in Subsection 12.1.1.
For simplicity, take αα to be a primitive root mod pp, so p−1p−1 is the smallest positive exponent nn such that αn≡1(modp)αn≡1(modp). This implies that
αm1≡αm2(modp)⟺m1≡m2(modp−1).
αm1≡αm2(modp)⟺m1≡m2(modp−1).
Assume that
β≡αx,0≤x<p−1.
β≡αx,0≤x<p−1.
We want to find xx.
First, it’s easy to determine x(mod2)x(mod2). Note that
(α(p−1)/2)2≡αp−1≡1(modp),
(α(p−1)/2)2≡αp−1≡1(modp),
so α(p−1)/2≡±1(modp)α(p−1)/2≡±1(modp) (see Exercise 15 in Chapter 3). However, p−1p−1 is assumed to be the smallest exponent to yield +1+1, so we must have
α(p−1)/2≡−1(modp).
α(p−1)/2≡−1(modp).
Starting with β≡αx(modp)β≡αx(modp), raise both sides to the (p−1)/2(p−1)/2 power to obtain
β(p−1)/2≡αx(p−1)/2≡(−1)x(modp).
β(p−1)/2≡αx(p−1)/2≡(−1)x(modp).
Therefore, if β(p−1)/2≡+1β(p−1)/2≡+1, then xx is even; otherwise, xx is odd.
Example
Suppose we want to solve 2x≡9(mod11)2x≡9(mod11). Since
β(p−1)/2≡95≡1(mod11),
β(p−1)/2≡95≡1(mod11),
we must have xx even. In fact, x=6x=6, as we saw previously.
10.2.1 The Pohlig-Hellman Algorithm
The preceding idea was extended by Pohlig and Hellman to give an algorithm to compute discrete logs when p−1p−1 has only small prime factors. Suppose
p−1=∏iqrii
p−1=∏iqrii
is the factorization of p−1p−1 into primes. Let qrqr be one of the factors. We’ll compute Lα(β)(modqr)Lα(β)(modqr). If this can be done for each qriiqrii, the answers can be recombined using the Chinese remainder theorem to find the discrete logarithm.
Write
x=x0+x1q+x2q2+⋯ with 0≤xi≤q−1.
x=x0+x1q+x2q2+⋯ with 0≤xi≤q−1.
We’ll determine the coefficients x0,x1,…xr−1x0,x1,…xr−1 successively, and thus obtain x mod qrx mod qr. Note that
The last congruence is a consequence of Fermat’s theorem: αp−1≡1(modp)αp−1≡1(modp). To find x0x0, simply look at the powers
αk(p−1)/q(modp),k=0,1,2,…,q−1,
αk(p−1)/q(modp),k=0,1,2,…,q−1,
until one of them yields β(p−1)/qβ(p−1)/q. Then x0=kx0=k. Note that since αm1≡αm2⟺m1≡m2(modp−1)αm1≡αm2⟺m1≡m2(modp−1), and since the exponents k(p−1)/qk(p−1)/q are distinct mod p−1p−1, there is a unique kk that yields the answer.
An extension of this idea yields the remaining coefficients. Assume that q2|p−1q2∣∣p−1. Let
β1≡βα−x0≡αq(x1+x2q+⋯)(modp).
β1≡βα−x0≡αq(x1+x2q+⋯)(modp).
Raise both sides to the (p−1)/q2(p−1)/q2 power to obtain
The last congruence follows by applying Fermat’s theorem. We couldn’t calculate β(p−1)/q21β(p−1)/q21 as (βp−11)1/q2(βp−11)1/q2 since fractional exponents cause problems. Note that every exponent we have used is an integer.
To find x1x1, simply look at the powers
αk(p−1)/q(modp),k=0,1,2,…,q−1,
αk(p−1)/q(modp),k=0,1,2,…,q−1,
until one of them yields β(p−1)/q21β(p−1)/q21. Then x1=kx1=k.
If q3|p−1q3∣∣p−1, let β2≡β1α−x1qβ2≡β1α−x1q and raise both sides to the (p−1)/q3(p−1)/q3 power to obtain x2x2. In this way, we can continue until we find that qr+1qr+1 doesn’t divide p−1p−1. Since we cannot use fractional exponents, we must stop. But we have determined x0,x1,…,xr−1x0,x1,…,xr−1, so we know xmodqrxmodqr.
Repeat the procedure for all the prime factors of p−1p−1. This yields xx mod qriiqrii for all ii. The Chinese remainder theorem allows us to combine these into a congruence for xx mod p−1p−1. Since 0≤x<p−10≤x<p−1, this determines xx.
Example
Let p=41p=41, α=7α=7, and β=12β=12. We want to solve
7x≡12(mod41).
7x≡12(mod41).
Note that
41−1=23⋅5.
41−1=23⋅5.
First, let q=2q=2 and let’s find xmod23xmod23. Write x≡x0+2x1+4x2(mod8)x≡x0+2x1+4x2(mod8).
To start,
β(p−1)/2≡1220≡40≡−1(mod41),
β(p−1)/2≡1220≡40≡−1(mod41),
and
α(p−1)/2≡720≡−1(mod41).
α(p−1)/2≡720≡−1(mod41).
Since
β(p−1)/2≡(α(p−1)/2)x0(mod41),
β(p−1)/2≡(α(p−1)/2)x0(mod41),
we have x0=1x0=1. Next,
β1≡βα−x0≡12⋅7−1≡31(mod41).
β1≡βα−x0≡12⋅7−1≡31(mod41).
Also,
β(p−1)/221≡3110≡1(mod41).
β(p−1)/221≡3110≡1(mod41).
Since
β(p−1)/221≡(α(p−1)/2)x1(mod41),
β(p−1)/221≡(α(p−1)/2)x1(mod41),
we have x1=0x1=0. Continuing, we have
β2≡β1α−2x1≡31⋅70≡31(mod41),
β2≡β1α−2x1≡31⋅70≡31(mod41),
and
β(p−1)/q32≡315≡−1≡(α(p−1)/2)x2(mod41).
β(p−1)/q32≡315≡−1≡(α(p−1)/2)x2(mod41).
Therefore, x2=1x2=1. We have obtained
x≡x0+2x1+4x2≡1+4≡5(mod8).
x≡x0+2x1+4x2≡1+4≡5(mod8).
Now, let q=5q=5 and let’s find xx mod 5. We have
β(p−1)/5≡128≡18(mod41)
β(p−1)/5≡128≡18(mod41)
and
α(p−1)/q≡78≡37(mod41).
α(p−1)/q≡78≡37(mod41).
Trying the possible values of kk yields
370≡1,371≡37,372≡16,373≡18,374≡10(mod41).
370≡1,371≡37,372≡16,373≡18,374≡10(mod41).
Therefore, 373373 gives the desired answer, so x≡3(mod5)x≡3(mod5).
Since x≡5(mod8)x≡5(mod8) and x≡3(mod5)x≡3(mod5), we combine these to obtain x≡13(mod40)x≡13(mod40), so x=13x=13. A quick calculation checks that 713≡12(mod41)713≡12(mod41), as desired.
As long as the primes qq involved in the preceding algorithm are reasonably small, the calculations can be done quickly. However, when qq is large, calculating the numbers αk(p−1)/qαk(p−1)/q for k=0,1,2,…,q−1k=0,1,2,…,q−1 becomes infeasible, so the algorithm no longer is practical. This means that if we want a discrete logarithm to be hard, we should make sure that p−1p−1 has a large prime factor.
Note that even if p−1=tqp−1=tq has a large prime factor qq, the algorithm can determine discrete logs mod tt if tt is composed of small prime factors. For this reason, often ββ is chosen to be a power of αtαt. Then the discrete log is automatically 0 mod tt, so the discrete log hides only mod qq information, which the algorithm cannot find. If the discrete log xx represents a secret (or better, tt times a secret), this means that an attacker does not obtain partial information by determining xx mod tt, since there is no information hidden this way. This idea is used in the Digital Signature Algorithm, which we discuss in Chapter 13.
10.2.2 Baby Step, Giant Step
Eve wants to find xx such that αx≡β(modp)αx≡β(modp). She does the following. First, she chooses an integer NN with N2≥p−1N2≥p−1, for example N=⌈√p−1⌉N=⌈p−1−−−−√⌉ (where ⌈x⌉⌈x⌉ means round xx up to the nearest integer). Then she makes two lists:
αj(modp)αj(modp) for 0≤j<N0≤j<N
βα−Nk(modp)βα−Nk(modp) for 0≤k<N0≤k<N
She looks for a match between the two lists. If she finds one, then
αj≡βα−Nk,
αj≡βα−Nk,
so αj+Nk≡βαj+Nk≡β. Therefore, x=j+Nkx=j+Nk solves the discrete log problem.
Why should there be a match? Since 0≤x<p−1≤N20≤x<p−1≤N2, we can write xx in base NN as x=x0+Nx1x=x0+Nx1 with 0≤x0,x1<N0≤x0,x1<N. In fact, x1=[x/N]x1=[x/N] and x0=x−Nx1x0=x−Nx1. Therefore,
j=x0,k=x1
j=x0,k=x1
gives the desired match.
The list αjαj for j=0,1,2,…j=0,1,2,… is the set of “Baby Steps” since the elements of the list are obtained by multiplying by αα, while the “Giant Steps” are obtained in the second list by multiplying by α−Nα−N. It is, of course, not necessary to compute all of the second list. Each element, as it is computed, can be compared with the first list. As soon as a match is found, the computation stops.
The number of steps in this algorithm is proportional to N≈√pN≈p–√ and it requires storing approximately NN numbers. Therefore, the method works for primes pp up to 10201020, or even slightly larger, but is impractical for very large pp.
For an example, see Example 35 in the Computer Appendices.
10.2.3 The Index Calculus
The idea is similar to the method of factoring in Subsection 9.4.1 . Again, we are trying to solve β≡αx(modp)β≡αx(modp), where pp is a large prime and αα is a primitive root.
First, there is a precomputation step. Let BB be a bound and let p1,p2,…,pm,p1,p2,…,pm, be the primes less than BB. This set of primes is called our factor base. Compute αk(modp)αk(modp) for several values of kk. For each such number, try to write it as a product of the primes less than BB. If this is not the case, discard αkαk. However, if αk≡∏paii(modp)αk≡∏paii(modp), then
k≡∑aiLα(pi)(modp−1).
k≡∑aiLα(pi)(modp−1).
When we obtain enough such relations, we can solve for Lα(pi)Lα(pi) for each ii.
Now, for random integers rr, compute βαr(modp)βαr(modp). For each such number, try to write it as a product of primes less than BB. If we succeed, we have βαr≡∏pbii(modp)βαr≡∏pbii(modp), which means
Lα(β)≡−r+∑biLα(pi)(modp−1).
Lα(β)≡−r+∑biLα(pi)(modp−1).
This algorithm is effective if pp is of moderate size. This means that pp should be chosen to have at least 200 digits, maybe more, if the discrete log problem is to be hard.
Example
Let p=131p=131 and α=2α=2. Let B=10B=10, so we are working with the primes 2,3,5,7. A calculation yields the following:
The second congruence yields L2(5)≡46(mod130)L2(5)≡46(mod130). Substituting this into the third congruence yields L2(7)≡−34≡96(mod130)L2(7)≡−34≡96(mod130). The fourth congruence yields only the value of L2(3)(mod65)L2(3)(mod65) since gcd(2,130)= 1gcd(2,130)= 1. This gives two choices for L2(3)(mod130)L2(3)(mod130). Of course, we could try them and see which works. Or we could use the fifth congruence to obtain L2(3)≡72(mod130)L2(3)≡72(mod130). This finishes the precomputation step.
Suppose now that we want to find L2(37)L2(37). Trying a few randomly chosen exponents yields 37⋅243≡3⋅5⋅7(mod131)37⋅243≡3⋅5⋅7(mod131), so
L2(37)≡−43+L2(3)+L2(5)+L2(7)≡41(mod130).
L2(37)≡−43+L2(3)+L2(5)+L2(7)≡41(mod130).
Therefore, L2(37)=41L2(37)=41.
Of course, once the precomputation has been done, it can be reused for computing several discrete logs for the same prime pp.
10.2.4 Computing Discrete Logs Mod 4
When p≡1(mod4)p≡1(mod4), the Pohlig-Hellman algorithm computes discrete logs mod 4 quite quickly. What happens when p≡3(mod4)p≡3(mod4)? The Pohlig-Hellman algorithm won’t work, since it would require us to raise numbers to the (p−1)/4(p−1)/4 power, which would yield the ambiguity of a fractional exponent. The surprising fact is that if we have an algorithm that quickly computes discrete logs mod 4 for a prime p≡3(mod4)p≡3(mod4), then we can use it to compute discrete logs mod pp quickly. Therefore, it is unlikely that such an algorithm exists.
There is a philosophical reason that we should not expect such an algorithm. A natural point of view is that the discrete log should be regarded as a number mod p−1p−1. Therefore, we should be able to obtain information on the discrete log only modulo the power of 2 that appears in p−1p−1. When p≡3(mod4)p≡3(mod4), this means that asking questions about discrete logs mod 4 is somewhat unnatural. The question is possible only because we normalized the discrete log to be an integer between 0 and p−2p−2. For example, 26≡216≡9(mod11)26≡216≡9(mod11). We defined L2(9)L2(9) to be 6 in this case; if we had allowed it also to be 16, we would have two values for L2(9)L2(9), namely 6 and 16, that are not congruent mod 4. Therefore, from this point of view, we shouldn’t even be asking about L2(9)mod4L2(9)mod4.
We need the following lemma, which is similar to the method for computing square roots mod a prime p≡3(mod4)p≡3(mod4) (see Section 3.9).
Lemma
Let p≡3(mod4)p≡3(mod4) be prime, let r≥2r≥2, and let yy be an integer. Suppose αα and γγ are two nonzero numbers mod pp such that γ≡α2ry(modp)γ≡α2ry(modp). Then
The final congruence is because of Fermat’s theorem.
Fix the prime p≡3(mod4) and let α be a primitive root. Assume we have a machine that, given an input β, gives the output Lα(β)mod4. As we saw previously, it is easy to compute Lα(β)mod2. So the new information supplied by the machine is really only the second bit of the discrete log.
Now assume αx≡β(modp). Let x=x0+2x1+4x2+⋯+2nxn be the binary expansion of x. Using the Lα(β)(mod4) machine, we determine x0 and x1. Suppose we have determined x0,x1,…,xr−1 with r≥2. Let
βr≡βα−(x0+⋯+2r−1xr−1)≡α2r(xr+2xr+1+⋯).
Using the lemma r−1 times, we find
β((p+1)/4)r−1r≡α2(xr+2xr+1+⋯)(modp).
Applying the Lα(mod4) machine to this equation yields the value of xr. Proceeding inductively, we obtain all the values x0,x1,…,xn. This determines x, as desired.
It is possible to make this algorithm more efficient. See, for example, [Stinson1, page 175].
In conclusion, if we believe that finding discrete logs for p≡3(mod4) is hard, then so is computing such discrete logs mod 4.