NSSCTF 2nd Crypto复现

Wbuildings / 2023-09-03 / 原文

1,EzRSA

题目代码:

from Crypto.Util.number import *
from secret import flag
m = bytes_to_long(flag)
assert m.bit_length()<200
p = getPrime(512)
q = getPrime(512)
n = p*q
e = 3
c = pow(m, e, n)
kbits = 103
m = (m >> kbits) << kbits
Mod = getPrime(1024)
hint1 = (2021-2023*m) % Mod
hint2 = pow(2, 2023, Mod)
print('n =',n)
print('c =',c)
print('hint1 =',hint1)
print('hint2 =',hint2)
'''
n = 115383855234466224643769657979808398804254899116842846340552518876890834212233960206021018541117724144757264778086129841154749234706140951832603640953383528482125663673926452745186670807057426128028379664506531814550204605131476026038420737951652389070818761739123318769460392218629003518050621137961009397857
c = 5329266956476837379347536739209778690886367516092584944314921220156032648621405214333809779485753073093853063734538746101929825083615077
hint1 = 153580531261794088318480897414037573794615852052189508424770502825730438732573547598712417272036492121110446656514226232815820756435437665617271385368704576530324067841094570337328191161458300549179813432377043779779861066187597784486306748688798924645894867137996446960685210314180286437706545416961668988800
hint2 = 130939024886341321687705945538053996302793777331032277314813607352533647251650781154105954418698306293933779129141987945896277615656019480762879716136830059777341204876905094451068416223212748354774066124134473710638395595420261557771680485834288346221266495706392714094862310009374032975169649227238004805982
'''

简单点,就是 c 直接开 3 次方 ,即得 flag :b'NSSCTF{Rea1_Si9n3n}'

但以学习的想法来写,以下为我的思考:

我想前半部分,他是参考 ctfshow 中 的一道题 Crypto-Comedy 来出题的,后半部分是m高位攻击

考点1: 在k倍的模下构造等式来求解

hint1 = (2021-2023*m) % Mod
hint2 = pow(2, 2023, Mod)

$$k*Mod = 2^{2023}-hint2$$

$$hint1 +2023*m-2021=0 ~mod ~Mod $$

再转化为$$hint1 +2023*m-2021=0 ~mod ~k*Mod$$

如此即可在 sagemath 里求解 m

考点2:m高位攻击

$$m^e\equiv c ~~ mod~n$$
$$(m_{high}+x)^e \equiv c ~~ mod~n$$
$$转换成多项式,即为~~f=(m_{high}+x)^e-c$$

n = 
c = 
e =
high_m = 
PR.<x> = PolynomialRing(Zmod(n))
f = (high_m + x)^e - c
x0 = f.small_roots(X=2^kbits, beta=1)[0]
m = int(high_m+x0)
print(long_to_bytes(m))

 exp:

from Crypto.Util.number import *
from gmpy2 import *
n = 115383855234466224643769657979808398804254899116842846340552518876890834212233960206021018541117724144757264778086129841154749234706140951832603640953383528482125663673926452745186670807057426128028379664506531814550204605131476026038420737951652389070818761739123318769460392218629003518050621137961009397857
c = 5329266956476837379347536739209778690886367516092584944314921220156032648621405214333809779485753073093853063734538746101929825083615077
hint1 = 153580531261794088318480897414037573794615852052189508424770502825730438732573547598712417272036492121110446656514226232815820756435437665617271385368704576530324067841094570337328191161458300549179813432377043779779861066187597784486306748688798924645894867137996446960685210314180286437706545416961668988800
hint2 = 130939024886341321687705945538053996302793777331032277314813607352533647251650781154105954418698306293933779129141987945896277615656019480762879716136830059777341204876905094451068416223212748354774066124134473710638395595420261557771680485834288346221266495706392714094862310009374032975169649227238004805982

e = 3
km = pow(2,2023)-hint2
PR.<m> = PolynomialRing(Zmod(km))
f = hint1+2023*m-2021
f = f.monic()
x = f.small_roots(X=2^200, beta=0.4)
print(x)
high_m=1746716778150027565782467891299010283212636160
kbits = 103
PR.<x> = PolynomialRing(Zmod(n))
f = (high_m + x)^e - c
x0 = f.small_roots(X=2^kbits, beta=1)[0]
m = int(high_m+x0)
print(long_to_bytes(m))