已知p低位攻击

题目

from Crypto.Util.number import *  
  
flag = b'qqqy{*****}'  
  
p = getPrime(512)  
q = getPrime(512)  
n = p * q  
p0 = p % 2**400  
m = bytes_to_long(flag)  
c = pow(m, 65537, n)  
  
print('c =',c)  
print('n =',n)  
print('p0 =',p0)  
  
'''  
c = 94697643644637461700043944955275184017246647674949685446703331156091025292881985447610251389968941284863704495594788125140060251663938532125774285489978435522673473772213376311382957190451320748679708484472735892333433651437668921341277523506450848297945333504267603852039523631508367252053018716443256302636  
n = 136023288597369384179669825492367057331878926324638645561145849518608158716666449165428088662424417142911897416053877815776754463212321426328544355594651209482791097881640987972246204477995420280238917605612541584097948296735532600553835867087904684252486233764869625375989175292922910727030380081989107591919  
p0 = 1727533723882537653158799026071148637699141973561764587479225746697125276453892067168720662534737280476470841637634716287  
'''

解题思路

操作
数学含义
作用
适用场景
p >> 400
p // 2**400
p 的高 112 位(512 - 400 = 112)
获取 p 的高位部分
p % 2**400等价于p&((1<<400)-1)
p mod 2**400
p 的低 400 位
获取 p 的低位部分
p << 400
p * 2**400
p 左移 400 位(低位补 0)
不用于提取位数,而是用于乘法运算
res = 1727533723882537653158799026071148637699141973561764587479225746697125276453892067168720662534737280476470841637634716287  
print(len(bin(res)[2:]))
#400

解答

p_low = 1727533723882537653158799026071148637699141973561764587479225746697125276453892067168720662534737280476470841637634716287
n = 136023288597369384179669825492367057331878926324638645561145849518608158716666449165428088662424417142911897416053877815776754463212321426328544355594651209482791097881640987972246204477995420280238917605612541584097948296735532600553835867087904684252486233764869625375989175292922910727030380081989107591919
p_low_bits = 400
pbits = 512
kbits = pbits - p_low_bits  
P.<x> = PolynomialRing(Zmod(n))
f = x * 2^p_low_bits + p_low
f_monic = f.monic()  
roots = f_monic.small_roots(X=2^kbits, beta=0.4)

if roots:
    x0 = int(roots[0])
    p = x0 * 2^p_low_bits + p_low
    q = n // p
    print(f"p = {p}")
    print(f"q = {q}")

#p = 10799965201183118759565885887682728359098292093307458811645773231947995730627469717043700771495586225986795504719772689207727129746461954795092182940136063
#q = 12594789526031829474657717930303585121330817484853728466719438536121300997997677393292540714098998965597150278155293401737903256447744527933077814163533713

from Crypto.Util.number import *  
  
p = 10799965201183118759565885887682728359098292093307458811645773231947995730627469717043700771495586225986795504719772689207727129746461954795092182940136063  
q = 12594789526031829474657717930303585121330817484853728466719438536121300997997677393292540714098998965597150278155293401737903256447744527933077814163533713  
e = 65537  
c = 94697643644637461700043944955275184017246647674949685446703331156091025292881985447610251389968941284863704495594788125140060251663938532125774285489978435522673473772213376311382957190451320748679708484472735892333433651437668921341277523506450848297945333504267603852039523631508367252053018716443256302636  
n = 136023288597369384179669825492367057331878926324638645561145849518608158716666449165428088662424417142911897416053877815776754463212321426328544355594651209482791097881640987972246204477995420280238917605612541584097948296735532600553835867087904684252486233764869625375989175292922910727030380081989107591919  
  
phi = (p-1)*(q-1)  
d = inverse(e, phi)  
m = pow(c, d, n)  
print(long_to_bytes(m))  
#qqqy{you_know_the_p_low_and_solve_it_successfully}
posted @ 2025-07-25 19:42  sevensnight  阅读(16)  评论(0)    收藏  举报