Midnight Sun CTF 2020

rsa_yay

while True:
    p = random_prime(2**512)
    q = ZZ(int(hex(p)[::-1], 16))
    if q.is_prime():
        break

# hex(p*q)
# '7ef80c5df74e6fecf7031e1f00fbbb74c16dfebe9f6ecd29091d51cac41e30465777f5e3f1f291ea82256a72276db682b539e463a6d9111cf6e2f61e50a9280ca506a0803d2a911914a385ac6079b7c6ec58d6c19248c894e67faddf96a8b88b365f16e7cc4bc6e2b4389fa7555706ab4119199ec20e9928f75393c5dc386c65'
# hex(ciphertext)
# '3ea5b2827eaabaec8e6e1d62c6bb3338f537e36d5fd94e5258577e3a729e071aa745195c9c3e88cb8b46d29614cb83414ac7bf59574e55c280276ba1645fdcabb7839cdac4d352c5d2637d3a46b5ee3c0dec7d0402404aa13525719292f65a451452328ccbd8a0b3412ab738191c1f3118206b36692b980abe092486edc38488'

Nếu biết \(k\) bit cao nhất của \(p\)\(q\), gọi là \(ph\)\(qh\) thì ta có chặn

\[ph \cdot qh \cdot 2^{1024-2k} \leqslant n < (ph+1) \cdot (qh + 1) \cdot 2^{1024-2k}.\]

Khi đó, ta brute \(12\) bit thấp nhất của \(p\) và tính nghịch đảo của từng trường hợp trong modulo \(2^{12}\). Nghịch đảo này chính là \(12\) bit thấp nhất của \(q\) và suy ra được \(12\) bit cao nhất của \(p\)\(q\).