Harekaze mini CTF 2020 Writeup
zer0pts
で参加していました。
Crypto 2問だけ解いたので、Writeupを書いておきます。
Disaster Level Hackerのwriteupはこちら
[Crypto] rsa
from Crypto.Util.number import getStrongPrime, getRandomRange with open("flag", "rb") as f: flag = int.from_bytes(f.read(), "big") p = getStrongPrime(512) q = getStrongPrime(512) n = p * q phi = (p-1)*(q-1) e = 65537 c1 = pow(flag, e, n) c2 = pow(p + q, e, n) c3 = pow(p - q, e, n) print(f"{n=}") print(f"{e=}") print(f"{c1=}") print(f"{c2=}") print(f"{c3=}")
はそれぞれ展開すると、 となる項はmod n で0になるので、
となります。 あとは、
となり、 を入手できますが、せっかくなのでもう少し丁寧に式を追うと、
となるので、 と でGCDを取れば を求めることができ、フラグを入手できます。
solver:
from Crypto.Util.number import * exec(open("./output.txt").read()) p = GCD(c2 + c3, n) print(isPrime(p)) q = n // p d = inverse(e, n - p - q + 1) m = pow(c1, d, n) print(long_to_bytes(m))
HarekazeCTF{RSA_m34n5_Rin_Shiretoko_Ango}
[Crypto] Wilhelmina says
from Crypto.Util.number import getStrongPrime import random p = getStrongPrime(512) with open("flag", "rb") as f: flag = int.from_bytes(f.read().strip(), "big") assert flag < p t = flag.bit_length() n = 5 k = 350 xs = [random.randint(2, p-1) for _ in range(n)] ys = [x * flag % p for x in xs] zs = [(y >> k) << k for y in ys] print(f"{t=}") print(f"{p=}") print(f"{xs=}") print(f"{zs=}")
flagを とすると、
と表せられます。ここで、 は下位ビットを切り落としている処理を表しています。また、大文字の変数( )は知っている値としています。
これは、CVPで解けそうな匂いがプンプンするので、解きます(雑)。 CVPに関する記事は、以下のwriteupが最初に読むものとしてはとても簡潔に、わかりやすく書かれていると思います。(詳しく書かれた難しいのは知らん)
もう少しわかりやすく書くと、
となり、以下のような格子を考えることでうまく行きます。
solver:
def solve_cvp(B, t, verbose=False): t_ = t - B.stack(t).gram_schmidt()[0].row(-1) if verbose: print("Target vector projection:") print(numerical_approx(t_, digits=4)) B_ = B.LLL() if verbose: print("\nLLL-reduced basis:") print(numerical_approx(B_, digits=4)) c = B_.solve_left(t_) c_ = vector(map(round, c)) if verbose: print("\nRound-off errors:") print(numerical_approx(vector(map(abs, c - c_)), digits=4)) return c_ * B_ exec(open("./output.txt").read().strip()) B = matrix([ [xs[0], xs[1], xs[2], xs[3], xs[4], 1], [p, 0, 0, 0, 0, 0], [0, p, 0, 0, 0, 0], [0, 0, p, 0, 0, 0], [0, 0, 0, p, 0, 0], [0, 0, 0, 0, p, 0], ]) t = vector([zs[0], zs[1], zs[2], zs[3], zs[4], 0]) ans = solve_cvp(B, t, verbose=True) print("[+] ans:", ans) m = ans[-1] from Crypto.Util.number import long_to_bytes print(long_to_bytes(m))
HarekazeCTF{H0chmu7_k0mm7_v0r_d3m_F411}