Platform: BYUCTF Challenge: Power Tower Category: Crypto Difficulty: Hard
Flag
byuctf{eulers_phi_phunction_is_a_phun_phunction}
Target
<remote-host>:1359. "multi-prime RSA where each factor of n is at most 2^16. Prove you know a fast algorithm to invert the power tower!"
- Server prints
n,c,e, then you must sendmwithin 1 second. n≈ 392 bits = product of 25 distinct ≤16-bit primes.eis printed as a^-joined list, e.g.e = 79^31^23^34^...^47(25 terms), a right-associative power tower79^(31^(23^(...))), an astronomically large exponent.
The provided
chall_modified.pysetsNUM_EXPS=1(single small exponent), a simplification to explain the encryption. The real server uses a 25-high tower, which is the actual challenge.
Two sub-problems
- Factor
n. Trivial: every prime ≤ 2^16, so trial-divide by the ~6500 primes below 65536. A 392-bitnfactors in milliseconds. Thenφ(n) = ∏(pᵢ − 1). - Invert the tower. Decryption needs
d = E⁻¹ mod φ(n), butE(the tower) is far too large to materialise. The fix: you only needE mod φ(n), andE⁻¹ mod φ = (E mod φ)⁻¹ mod φ.
The key idea: iterated modular tetration
Compute E mod φ without ever building E, via Euler's theorem recursively:
a^X mod m = a^( (X mod φ(m)) + φ(m) ) mod m, valid when X ≥ log2(m) (the +φ(m) term is what makes it correct even when gcd(a,m) ≠ 1, the "phun" part).
Apply it down the tower: to get a₀^(rest) mod m, recurse to get rest mod φ(m), lift by φ(m), then one pow. Why it terminates cheaply: φ(n) = ∏(pᵢ−1) with every pᵢ−1 ≤ 2^16, so φ(n) is 2^16-smooth. And φ of a 2^16-smooth number stays 2^16-smooth (each prime power q^a contributes q^{a-1}(q−1), and q−1 < 2^16). So every modulus in the whole recursion factors by the same small trial division. Depth ≤ 25, all fast.
The +φ(m) lift is only valid when the sub-exponent is truly ≥ log2(m). The very top of a tower is a small number (e.g. 47), so I gate the lift with a capped tower evaluation (tower_capped) that returns the exact value if < 2^800, else a sentinel, giving an exact ≥ φ(m) comparison at every level.
Solution
Pitfalls
- Don't compute the tower. The naïve
E = a**(b**(c**...))hangs forever building a number with billions of digits (my first attempt did exactly this). You never needE, onlyE mod φ. gcd(a, m) ≠ 1levels. Plaina^(X mod φ(m))is wrong when the base shares a factor with the modulus; the+ φ(m)lift fixes it, but only when the sub-exponent really is≥ log2(m), hence the capped check (the topmost term is small).- Verify before sending (
pow(m, Emod, n) == c) so you don't waste the 1-second window on a wrong association/parse. Right-associativity was correct here on the first try. - φ(n) for squarefree
nis∏(pᵢ−1);pᵢ−1divides it, soE·d ≡ 1 mod φ⇒≡ 1 mod (pᵢ−1)for every prime → decryption is valid across all 25 factors.
Takeaways
- "Power tower" / tetration mod is Euler's theorem applied recursively; the whole trick is that the modulus chain
φ(φ(...φ(n)))stays smooth here, so each level factors trivially. - Smooth/small-prime multi-prime RSA has no security. Factoring is just bounded trial division. The difficulty was entirely the exponent representation, not the modulus.
- General reusable primitive:
tower_mod(arr, m)for evaluating any power tower modulom.
0xAdham
