题目
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}