from Crypto.Util.number import bytes_to_long from secrets import FLAG,p,q N = p**3 * q e = 0x10001 c = pow(bytes_to_long(FLAG),e,N) print(f'Flag: {hex(c)}') # Hint w = 25965460884749769384351428855708318685345170011800821829011862918688758545847199832834284337871947234627057905530743956554688825819477516944610078633662855 x = p + 1328 y = p + 1329 z = q - 1 assert w*(x*z + y*z - x*y) == 4*x*y*z
overview
#RSA っぽい感じではある
が与えられてない
かわりに という式が与えられている
solution 1
solution 2
両辺 で割って
を使いつつ変形して
と を使うと
を探索しつつ を計算し、等式が成り立つようなペアを見つける
w = 25965460884749769384351428855708318685345170011800821829011862918688758545847199832834284337871947234627057905530743956554688825819477516944610078633662855 approx_x = w // 2 for bias in range(-10000, 10000): x = approx_x + bias y = x+1 z = (w*x*y) // (w*x + w*y - 4*x*y) if w*(x*z + y*z - x*y) == 4*x*y*z: q = z + 1 p = x - 1328 print("[+] p = {}, q = {}".format(p, q)) quit() print("[-] not found")
solution 3
とおいて
と書いてみる。このとき が成り立ちそう、かつ が一変数になっているのでを sageに解かせてみると解ける
w = 25965460884749769384351428855708318685345170011800821829011862918688758545847199832834284337871947234627057905530743956554688825819477516944610078633662855 PR.<p, q> = PolynomialRing(QQ) # not ZZ but QQ x = p + 1328 y = p + 1329 z = q - 1 f = (x*z + y*z - x*y) g = 4*x*y*z d, r = g.quo_rem(f) print(d) p = (d-w).univariate_polynomial().roots()[0][0] q = f.subs(p=p).univariate_polynomial().roots()[0][0] print("[+] p={}, q={}".format(p, q))
solution 4
z3 で解けてしまうらしい
from z3 import * from Crypto.Util.number import long_to_bytes c = ... e = ... w = ... p = Int("p") q = Int("q") x = p + 1328 y = p + 1329 z = q - 1 s = Solver() s.add(p>0) s.add(q>0) s.add(w*(x*z + y*z - x*y) == 4*x*y*z) if s.check() == sat: m = s.model() p = m[p].as_long() q = m[q].as_long() e = 0x10001 N = p**3 * q phi = p**2*(p-1)*(q-1) d = pow(e,-1,phi) m = pow(c,d,N) print(long_to_bytes(m))