This article offers a writeup for the zer0pts CTF 2022’s crypto challenge, “Anti-Fermat.”

crypto

Anti-Fermat

description: I invented Anti-Fermat Key Generation for RSA cipher since I'm scared of the Fermat's Factorization Method.

files:

  1. task.py
from Crypto.Util.number import isPrime, getStrongPrime
from gmpy import next_prime
from secret import flag

# Anti-Fermat Key Generation
p = getStrongPrime(1024)
q = next_prime(p ^ ((1<<1024)-1))
n = p * q
e = 65537

# Encryption
m = int.from_bytes(flag, 'big')
assert m < n
c = pow(m, e, n)

print('n = {}'.format(hex(n)))
print('c = {}'.format(hex(c)))
  1. output.txt (the output of the task.py)

What we know

By experimenting, I realized that the value of p - (q^((1<<1024)-1)) - 1 and p + q - (1<<1024) are the same and both were small.

  • $p+q \approx 1\ll{}1024$

Thus, using the Fermat’s factorization method ($n = \left((p+q)/2\right)^2 - \left((p-q)/2\right)^2$), we get the following approximation. $$p \approx \dfrac{(1\ll{}1024) + \sqrt{(1\ll{}1024)^2 - 4n}}{2}$$

After checking prime numbers near the approximation using the next_prime function, we get the actual p and q.