Description
What happens if you have a small exponent? There is a small danger in using small exponents in RSA. n and c are provided.
Setup
Download the challenge files containing n, c, and e.
Solution
- Step 1Recognize the small exponent weaknessThe challenge uses e=3. When the public exponent is very small and the message is not padded sufficiently, m^e may be only slightly larger than n. This means the ciphertext c = m^3 mod n is equivalent to m^3 - k*n for some small integer k. Try increasing values of k until the result is a perfect cube.
Learn more
In RSA, ciphertext is computed as
c = m^e mod n. Whene=3and the messagemis small enough thatm^3 < n, the modular reduction never activates -- meaningc = m^3exactly, and you simply take the cube root ofcto recoverm.Even when
m^3is slightly larger thann, the relationshipc = m^3 - k*nholds for a small integerk. By iteratingk = 0, 1, 2, ...and checking whetherc + k*nis a perfect cube each time, you can recovermwith minimal computation. - Step 2Iterate k until you find a perfect cube rootUse gmpy2.iroot to compute the integer cube root of c + k*n. The function returns (root, exact) -- when exact is True, you have found m. Convert the resulting integer to bytes to read the flag.python3 << 'EOF' from gmpy2 import iroot from Crypto.Util.number import long_to_bytes n = <n> c = <c> e = 3 k = 0 while True: candidate = c + k * n m, exact = iroot(candidate, e) if exact: print(long_to_bytes(m).decode()) break k += 1 EOF
Learn more
gmpy2 is a Python wrapper around the GMP arbitrary-precision library.
iroot(x, n)returns(root, exact)whererootis the integer n-th root ofxandexactisTrueonly ifroot^n == xexactly. This is far more reliable than floating-point cube root functions, which lose precision on 300+ digit numbers.This attack is known as the broadcast attack variant or simply the small-exponent attack. The standard defense is to use OAEP padding (PKCS#1 v2), which randomizes messages before encryption so that even identical plaintexts encrypt to different ciphertexts. Modern RSA implementations always use padding -- never raw textbook RSA.
Flag
picoCTF{...}
When e=3 and m is lightly padded, m^3 barely exceeds n -- iterate k until you find a perfect integer cube root.