We need to recover the plaintext from the incorrectly generated RSA parameters, in this case, e = 16
and the modulo n
is a prime. As the public exponent and the totient of n
is not coprime, this implies
The first, and intended solution is to take advantage of the fact that e = 2 ^ 4
, hence we only need to calculate the square root of the plaintext in the finite field four times.
Kudos to Robin_Jadoul
on Cryptohack for this solution.
|
|
Another solution takes advantage of the fact that the modulo is a prime. With m
being the plaintext message, we can see it is a root of the polynomial X^e - ct
over Z/nZ[X]
. As n
is prime, calculating the square root multiple times when the modulus is a prime is quick. nth_root
is insanely slow in comparison, as the underlying method is not optimised for non coprime power.
Kudos to AZ
on Cryptohack for this solution.
|
|
Lastly, the God solution. Don’t know how it works, root of unity is that strong I guess. I think I will leave this to the future me to figure out! This works for composite n
, as seen in this writeup.
|
|
This runs very quick. The following is the way that the algorithm works.
As we cannot find a unique m
, we can instead find x
satisfying
$x$ in this case is called a root of unity modulo n which can be computed fairly easily. The algorithm for calculating this is in the roots_of_unity
method in the Python script.
Denote $g = gcd(e, \phi(n))$, hence we have $e = kg$ and $\phi(n) = lg$ for some integers $k$ and $l$. phi_coprime
is $l$ (as we are dividing $\phi(n)$ by $gcd(e, \phi(n))$). The returned solution is within some number of rounds, as there can be collisions of the solutions, in mathematical terms, there exists some $a, b$ where $a \neq b$ such that:
Indeed, if the elements $a$ are of order divides phi_coprime
, or $l$, then $a ^ l = 1$ (Lagrange’s theorem).
The set of the solutions indeed satisfy the assert
line because
d = inverse_mod(e, phi_coprime)
, or $ed = 1 + zl$ for some $z$.
Denote the original plaintext as $m$ and the corresponding ciphertext ct
as $c$, and the possible plaintext obtained from pt = pow(ct, d, n)
as M.
For the assert
line, we have:
Hence $M$ is one of the possible plaintext. Combining this with the root of unity, we should have a set of possible plaintexts. Finding one with indications of the flag should give us the solution.