Small-Subgroup - Smooth-Prime Static-Key Extraction Attack (Diffie-Hellman)
- •
What it is
- •
A more resilient version of the static-key generator-substitution attack, for parties that add some validation of caller-supplied Diffie-Hellman parameters (rejecting obviously-wrong public values or suspiciously tiny/composite moduli) but still accept an attacker-chosen prime modulus outright. Constructing a large but deliberately smooth prime (one where factors entirely into small primes, so it passes basic primality checks and doesn't look obviously "dodgy" by size alone) lets an attacker efficiently solve the discrete logarithm via Pohlig-Hellman once the target computes and reveals under that weak modulus — recovering their real, reused static private key (or at least modulo the order of in that weak group, which is often already large enough to pin down exactly, since real-world private exponents are typically much smaller than the weak group's own order). With known, the attacker can go back and compute the real shared secret from an earlier, legitimately-observed exchange under the party's real, strong parameters.
- •
- •
When to apply
- •
A static-key party validates caller-supplied DH parameters just enough to block the crudest tricks (composite moduli, degenerate public values) but doesn't verify anything about how the modulus's own group structure is built — checking a candidate modulus's primality alone doesn't rule out it being deliberately smooth.
- •
- •
Math
- •
Same Pohlig-Hellman mechanism as any smooth-order discrete log — factor (or more precisely the order of within , which may be a proper divisor of if isn't a full primitive root) into prime powers, solve the discrete log independently modulo each prime-power factor (via baby-step giant-step within each small subgroup), and CRT-combine the results into .
- •
- •
Worked example
- •
Building a genuinely smooth ~146-bit prime from scratch (product of small primes plus one, checked for primality) and computing for a random 20-bit "static secret" : a from-scratch Pohlig-Hellman implementation correctly recovered modulo the actual order of in that field — notably, turned out not to be a full primitive root of in this trial (its order was only about a quarter of ), yet the recovered value still matched exactly, and since itself was smaller than that order, this recovered exactly, not just a partial residue.
- •
- •
Python
- •
1. build/search for a smooth prime p' (p'-1 = product of many small primes) # 2. send it to the target as the modulus; they respond with B' = g^b mod p' # 3. factor ord(g) [often just p'-1, verify] into prime powers # 4. Pohlig-Hellman: solve g^b = B' independently mod each prime-power factor via BSGS, then CRT-combine b_recovered = pohlig_hellman(g, B_prime, p_prime, ord_g) # 5. go back to the REAL, strong (p, A) pair observed earlier and compute the true shared secret: real_shared_secret = pow(A_real, b_recovered, p_real)
- •
- •
- •
- •
Cards
- •
Why does checking that a caller-supplied modulus is prime fail to prevent this attack?
- •
Primality alone says nothing about how smooth p-1 is — a prime can be entirely legitimate-looking while still having a group order that factors completely into small primes, making its discrete log problem tractable.
- •
- •
Why does recovering the target's static private key from one weak-group exchange compromise other, legitimate exchanges too?
- •
Because the private key is static (reused across sessions) rather than fresh per exchange — once known, it can be applied directly to any previously-observed real public value to compute that session's true shared secret.
- •
- •