---
# System prepended metadata

title: '[CH] Ultra Easy RSA'
tags: [Chinese, Writeup, Crypto]

---

# [CH] Ultra Easy RSA
###### tags: `Writeup` `Crypto` `Chinese`
> [name=Curious]

## 先備知識

### 費馬分解
$p$ 和 $q$ 是 $n$ 的兩個因數，如果 $|p - q|$ 很小，可以假設 $p \gt q$

$$
\begin{cases}
p = a + b\\
q = a - b
\end{cases}
\;\Rightarrow\;
n = pq = a^2 - b^2
\;\Rightarrow\;
n + b^2 = a^2
$$

因為 $p - q$ 很小，所以 $b$ 也會很小，所以可以讓 $a$ 是
$$
\sqrt n + 1, \sqrt n + 2, \sqrt n + 3, ...
$$

當 $\sqrt{a^2 - n} \in \mathbb N$ 時，就可以計算得知 $a$ 和 $b$，進而分解 $n$

---
## 思路和解法
從 `chal.py` 可以看到 `p` 和 `q` 都是由 `base + 1` 加上一個 32 bits 的質數構建而來的，所以 `p` 和 `q` 基本上不會距離很遠，所以可以用費馬分解來分解 `n`，分解之後就可以計算出密鑰 `d` 來解密 `c`

> 實際上可以直接把 `n` 那去 http://factordb.com 就可以分解出 `p` 和 `q` 了

Solve Script : 
```python=
from gmpy2 import isqrt, iroot
from Crypto.Util.number import long_to_bytes

def fermat_factor(n: int):
    """
    - input : `n (int)`
    - output : `(p, q) (int, int)`
    """

    a = int(isqrt(n)) + 1
    b = iroot(a ** 2 - n, 2)
    while not b[1]:
        a += 1
        b = iroot(a ** 2 - n, 2)
        print(a)
    b = int(b[0])
    return (a - b), (a + b)

n = ...
e = 65537
c = ...

p, q = fermat_factor(n)
d = pow(e, -1, (p - 1) * (q - 1))
m = pow(c, d, n)

print(long_to_bytes(m))
```


{%hackmd M1bgOPoiQbmM0JRHWaYA1g %}