Note

Baby Step Giant Step

Baby Step Giant Step Algorithm.

By Roman Akhtariev•

Baby-Step Giant-Step (BSGS)

The core idea is beautifully simple once you see it — it's essentially a meet-in-the-middle strategy applied to the discrete logarithm problem.

The Problem

You want to find xx such that gx=h(modp)g^x = h \pmod{p}. Naively, you'd try x=0,1,2,…,p−1x = 0, 1, 2, \dots, p-1 which takes O(p)O(p) time where pp is the group order.

The Key Insight

Write x=i⋅m+jx = i \cdot m + j where m=⌈p⌉m = \lceil\sqrt{p}\rceil and 0≤i,j<m0 \le i, j < m. Then:

gim+j=hg^{im + j} = h

gj=h⋅(g−m)ig^j = h \cdot (g^{-m})^i

You've split one search over pp values into two searches over p\sqrt{p} values each.

The Two Phases

Baby steps — Precompute and store gjg^j for j=0,1,…,m−1j = 0, 1, \dots, m-1 in a hash table. These are small, incremental steps through the group.

Giant steps — Compute h⋅(g−m)ih \cdot (g^{-m})^i for i=0,1,2,…i = 0, 1, 2, \dots and check if it's in your table. Each iteration jumps by mm positions — hence "giant" steps.

When you find a collision, you've got gj=h⋅g−img^j = h \cdot g^{-im}, so h=gim+jh = g^{im+j} and x=im+jx = im + j.

Walkthrough: 5x≡20(mod53)5^x \equiv 20 \pmod{53}

Here g=5g = 5, h=20h = 20, and the group order is p=52p = 52 (since (Z/53Z)∗(\mathbb{Z}/53\mathbb{Z})^* has order 53−1=5253 - 1 = 52).

Setup. Compute m=⌈52⌉=8m = \lceil\sqrt{52}\rceil = 8.

Baby steps — build a table of gj mod 53g^j \bmod 53 for j=0,…,7j = 0, \dots, 7:

jj5j mod 535^j \bmod 53
01
15
225
319
442
551
643
73

Store as a lookup: {1↦0,  5↦1,  25↦2,  19↦3,  42↦4,  51↦5,  43↦6,  3↦7}\{1 \mapsto 0,\; 5 \mapsto 1,\; 25 \mapsto 2,\; 19 \mapsto 3,\; 42 \mapsto 4,\; 51 \mapsto 5,\; 43 \mapsto 6,\; 3 \mapsto 7\}.

Giant steps — we need g−m=5−8 mod 53g^{-m} = 5^{-8} \bmod 53. Since 58≡15(mod53)5^8 \equiv 15 \pmod{53}, we find 15−1≡46(mod53)15^{-1} \equiv 46 \pmod{53} (verify: 15⋅46=690=13⋅53+115 \cdot 46 = 690 = 13 \cdot 53 + 1). Now compute h⋅(g−m)i=20⋅46i mod 53h \cdot (g^{-m})^i = 20 \cdot 46^i \bmod 53:

ii20⋅46i mod 5320 \cdot 46^i \bmod 53In table?
020No
119Yes! j=3j = 3

Result. x=i⋅m+j=1⋅8+3=11x = i \cdot m + j = 1 \cdot 8 + 3 = 11.

Verify: 511=58⋅53=15⋅19=285=5⋅53+20≡20(mod53)5^{11} = 5^8 \cdot 5^3 = 15 \cdot 19 = 285 = 5 \cdot 53 + 20 \equiv 20 \pmod{53}. Correct.

We checked just 8+1=98 + 1 = 9 values instead of scanning all 52. With larger groups, this savings becomes dramatic.

Why It Works Mathematically

Every integer x∈[0,p)x \in [0, p) can be uniquely decomposed as x=im+jx = im + j with 0≤j<m0 \le j < m and 0≤i<m0 \le i < m. So the baby steps cover all possible "remainders mod mm" and the giant steps cover all possible "quotients by mm." The two sets are guaranteed to collide at the right answer.

Complexity

  • Time: O(p)O(\sqrt{p}) — at most p\sqrt{p} baby steps + p\sqrt{p} giant steps
  • Space: O(p)O(\sqrt{p}) — storing the baby-step table

This is optimal for generic group algorithms (by Shoup's lower bound), meaning you can't do better without exploiting special group structure.