# d-phi-enc
**Author**. EggRoll (idek)
## Overview
```python
from Crypto.Util.number import bytes_to_long, getStrongPrime
from secret import flag
assert len(flag) == 255
e = 3
p = getStrongPrime(1024, e=e)
q = getStrongPrime(1024, e=e)
n = p * q
phi = (p - 1) * (q - 1)
d = pow(e, -1, phi)
enc_d = pow(d, e, n)
enc_phi = pow(phi, e, n)
enc_flag = pow(bytes_to_long(flag), e, n)
print(f"{n = }")
print(f"{enc_d = }")
print(f"{enc_phi = }")
print(f"{enc_flag = }")
```
So basically, we are given a standard RSA with the following additional hints:
1. $d^e \pmod{n}$
2. $\phi(n)^e \pmod{n}$
## Exploit
First of all, there is a relationship between $d$ and $\phi(n)$. Precisely, we have $$ed \equiv 1 \pmod{\phi(n)}$$ Or equivalent, $$ed = 1 + k\phi(n)$$ for some $k$. Once $k$ is known, related message attack can be applied and we will find the value of $d$, which is enough to retrieve the flag.
Now, notice that in the code, there is a weird parameter setting, say $e=3$. Therefore, only few possible values for $k$. We could simply try all possibilities.
```python=
from output import *
def gcd(f1, f2):
if f1 % f2 == 0:
return f2
else:
return gcd(f2, f1 % f2)
P.<x> = PolynomialRing(Zmod(n))
k = 2
f = x^3 - enc_d
g = (inverse_mod(k, n) * (3*x-1))^3 - enc_phi
d = n - int(gcd(f, g).monic().list()[0])
from Crypto.Util.number import long_to_bytes
print(long_to_bytes(int(pow(enc_flag, d, n))))
```
:::success
HackTM{Have you warmed up? If not, I suggest you consider the case where e=65537, although I don't know if it's solvable. Why did I say that? Because I have to make this flag much longer to avoid solving it just by calculating the cubic root of enc_flag.}
:::