超过300位的合数怎么分import random
import math
from Crypto.Util.number import long_to_bytes
# 已知数据
c = 8010415678766495559206888104308220461000137190504006792719473726344733619441141193462632115436953071133591418480457170724671799432518092660776309476406070558451285172355261125033267340649376421801091685798286314106142855053515428470474693625489377898001862186681685082360598622408094264333299738655461877207390809495955984957338296805424644630493393029139944919536399174215810604102444550172759845344395864486440754752041405094877450680140850037755156965823345868285966939695682195399775462308951218301326547363911121730948439732333381005743591960455287452246675824174748812338877227345103716723376979538380032002880
hint = 4954477722794007679259787705071851835680630074373589614154901212439091693825106875479842554606153058190995214347117184687613051142282846871128812252250637326896296788563890362185505010773931888829285558128596857093099418604694919454819343842312843108124919481178288207784060364226550053354580189857537158580943897179549277643338951797705412207045370229744214727707911966864066911560213737637233870360113799892826929003703273846381898853719476623176860704557650283662945755147547068370364286870324024577488484455358602429710219447526127782448349463942117410190437938834954390911495483413355957621606751450577074102729
n = 10784287819385415353621875218563143302159768325704928073867416808040916996479341048063223714643174249461097295535297542385475849470046760369978768211220988313304188367229395180043407712292398872921220233051142848776456790641708863113887722318345601554351621305567539237641096651148337525250970956775311944016141879494664318933091284315673333318969018209756116226492696486038744619977928991239409925382390262035475423869395568601956013364403631988387757474363593218046567386448482628006367012358287524440361632608335934523058793771435203563217660703267386600175482629638068995270497505139491768944189370651947532096313
e = 0x10001
# 1. Miller-Rabin素性测试
def is_prime(n, k=5):
if n <= 1:
return False
elif n <= 3:
return True
elif n % 2 == 0:
return False
# 写成d*2^s + 1
d = n - 1
s = 0
while d % 2 == 0:
d //= 2
s += 1
# 测试k次
for _ in range(k):
a = random.randint(2, min(n-2, 1 << 20))
x = pow(a, d, n)
if x == 1 or x == n - 1:
continue
for __ in range(s-1):
x = pow(x, 2, n)
if x == n - 1:
break
else:
return False
return True
# 2. Pollard's Rho分解算法
def pollards_rho(n):
if n % 2 == 0:
return 2
if n % 3 == 0:
return 3
if n % 5 == 0:
return 5
while True:
c = random.randint(1, n-1)
f = lambda x: (pow(x, 2, n) + c) % n
x, y, d = 2, 2, 1
while d == 1:
x = f(x)
y = f(f(y))
d = math.gcd(abs(x - y), n)
if d != n:
return d
def factor(n):
factors = []
def _factor(n):
if n == 1:
return
if is_prime(n):
factors.append(n)
return
d = pollards_rho(n)
_factor(d)
_factor(n // d)
_factor(n)
return sorted(factors)
# 3. 分解n得到p和q
factors = factor(n)
p, q = factors # n是两个素数的乘积,故factors有两个元素
# 4. 验证p和q是否正确(根据hint)
if pow(p + 2, n, n) != hint:
p, q = q, p # 交换后再验证
assert pow(p + 2, n, n) == hint, "分解错误"
# 5. 计算私钥d
phi = (p - 1) * (q - 1)
d = pow(e, -1, phi) # 求e的模逆
# 6. 解密得到明文m
m = pow(c, d, n)
# 7. 转换为flag
flag = long_to_bytes(m)
print("flag:", flag.decode())
运行一下这个代码
最新发布