已知dp高位攻击
题目
- ! 祥云杯2020-Exposure
from Crypto.Util.number import *
import gmpy2
p = getStrongPrime(512)
q = getStrongPrime(512)
n = p * q
phi = (p - 1) * (q - 1)
e = 7621
d = gmpy2.invert(e, phi)
flag = b"flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}"
c = pow(bytes_to_long(flag), e, n)
dp = d % (p - 1)
print(dp >> 200)
print(c, e, n)
'''
dp>>200 = 1153696846823715458342658568392537778171840014923745253759529432977932183322553944430236879985
c = 46735962204857190520476434898881001530665718155698898882603422023484998388668858692912250418134186095459060506275961050676051693220280588047233628259880712415593039977585805890920089318643002597837000049626154900908543384761210358835843974072960080857150727010985827690190496793207012355214605393036388807616
e = 7621
n = 140376049134934822153964243403031201922239588054133319056483413311963385321279682186354948441840374124640187894619689719746347334298621083485494086361152915457458004998419817456902929318697902819798254427945343361548635794308362823239150919240307072688623000747781103375481834571274423004856276841225675241863
'''
解题思路
(Coppersmith攻击,已知dp高位攻击)
给 $n,e,dp_0,c,k$ ,其中 $dp_0$ 为 $dp$ 高 $(n\text{bits}-k)$ 位,即 $dp_0=dp>>k$
$e\cdot dp \equiv e\cdot d\equiv 1 \pmod {(p-1)} \\Leftrightarrow e \cdot dp=k(p-1)+1=kp-k+1 \\Leftrightarrow e\cdot dp+k-1 \equiv 0 \pmod p$
$\because dp<p-1$,$\therefore k<e$
$\therefore e\cdot (dp_0<<k+x)+k-1 \equiv 0 \pmod p$
解答
dp0 = 1153696846823715458342658568392537778171840014923745253759529432977932183322553944430236879985
e = 7621
n = 140376049134934822153964243403031201922239588054133319056483413311963385321279682186354948441840374124640187894619689719746347334298621083485494086361152915457458004998419817456902929318697902819798254427945343361548635794308362823239150919240307072688623000747781103375481834571274423004856276841225675241863
F.<x> = PolynomialRing(Zmod(n))
d = inverse_mod(e, n)
for k in range(1, e):
f = (dp0 << 200) + x + (k - 1) * d
x0 = f.small_roots(X=2 ** (200 + 1), beta=0.44, epsilon=1/32)
if len(x0) != 0:
dp = x0[0] + (dp0 << 200)
for i in range(2, e):
p = (e * Integer(dp) - 1 + i) // i
if n % p == 0:
break
if p < 0:
continue
else:
print('k =',k)
print('p =',p)
print('dp =',dp)
break
'''
k = 1237
p = 11421761844938570296178178174916397110069952910671004217873885369752730509863327628794478842373581937596761823394628513585538173848033965350050214224480253
dp = 1853919354702665195692482141762443672110816395551769087719458890222297289161650213465263131874573003123893764012485956082575872070596774063510315574817225
'''
- !! 求出 $dp$ 再通过 $dp$ 泄露攻击求解
from Crypto.Util.number import *
from gmpy2 import *
n = 140376049134934822153964243403031201922239588054133319056483413311963385321279682186354948441840374124640187894619689719746347334298621083485494086361152915457458004998419817456902929318697902819798254427945343361548635794308362823239150919240307072688623000747781103375481834571274423004856276841225675241863
c = 46735962204857190520476434898881001530665718155698898882603422023484998388668858692912250418134186095459060506275961050676051693220280588047233628259880712415593039977585805890920089318643002597837000049626154900908543384761210358835843974072960080857150727010985827690190496793207012355214605393036388807616
dp = 1853919354702665195692482141762443672110816395551769087719458890222297289161650213465263131874573003123893764012485956082575872070596774063510315574817225
e = 7621
for k in range(1, e):
if (e * dp - 1) % k == 0:
p = (e * dp - 1) // k + 1
if n % p == 0:
q = n // p
d = invert(e, (p - 1) * (q - 1))
m = powmod(c, d, n)
break
print(long_to_bytes(m))
#flag{45879a9e-1431-4c34-86e2-6f1f7bb1256d}
- !! 求出 $p$ 再直接求解
from Crypto.Util.number import *
n = 140376049134934822153964243403031201922239588054133319056483413311963385321279682186354948441840374124640187894619689719746347334298621083485494086361152915457458004998419817456902929318697902819798254427945343361548635794308362823239150919240307072688623000747781103375481834571274423004856276841225675241863
c = 46735962204857190520476434898881001530665718155698898882603422023484998388668858692912250418134186095459060506275961050676051693220280588047233628259880712415593039977585805890920089318643002597837000049626154900908543384761210358835843974072960080857150727010985827690190496793207012355214605393036388807616
p = 11421761844938570296178178174916397110069952910671004217873885369752730509863327628794478842373581937596761823394628513585538173848033965350050214224480253
q = n //p
e = 7621
phi = (p-1)*(q-1)
d = inverse(e, phi)
m = pow(c, d, n)
print(long_to_bytes(m))
#flag{45879a9e-1431-4c34-86e2-6f1f7bb1256d}
secret = 1153696846823715458342658568392537778171840014923745253759529432977932183322553944430236879985
c = 46735962204857190520476434898881001530665718155698898882603422023484998388668858692912250418134186095459060506275961050676051693220280588047233628259880712415593039977585805890920089318643002597837000049626154900908543384761210358835843974072960080857150727010985827690190496793207012355214605393036388807616
e = 7621
n = 140376049134934822153964243403031201922239588054133319056483413311963385321279682186354948441840374124640187894619689719746347334298621083485494086361152915457458004998419817456902929318697902819798254427945343361548635794308362823239150919240307072688623000747781103375481834571274423004856276841225675241863
[n, secret, c] = list(map(Integer, [n, secret, c]))
def facorize(e, dp):
for i in range(2, e):
p = (e * dp - 1 + i) // i
if n % p == 0:
return p
return -1
def recover(secret):
F.<x> = PolynomialRing(Zmod(n))
d = inverse_mod(e, n)
for k in range(1, e):
print('k =',k)
f = (secret << 200) + x + (k - 1) * d
x0 = f.small_roots(X=2 **(200 + 1), beta=0.44, epsilon=1/32)
if len(x0) != 0:
dp = x0[0] + (secret << 200)
p = facorize(e, Integer(dp))
if p < 0:
continue
else:
return p, dp
if __name__ == "__main__":
p, dp = recover(secret)
q = n // p
assert p * q == n
phi = (p - 1) * (q - 1)
d = inverse_mod(e, phi)
print('p =',p)
print('q =',q)
m = pow(c, d, n)
flag = bytes.fromhex(hex(m)[2:])
print(flag)
'''
k = 1237
p = 11421761844938570296178178174916397110069952910671004217873885369752730509863327628794478842373581937596761823394628513585538173848033965350050214224480253
q = 12290227290734567682306366594562142781205419470329953979873141981925520523310725901580115860989137310022963004734773849281193015190231751320653976891356371
flag{45879a9e-1431-4c34-86e2-6f1f7bb1256d}
'''