from Crypto.Util.number import *
from hashlib import md5
a = getPrime(512)
b = getPrime(512)
c = getPrime(512)
d = getPrime(512)
d1 = int(bin(d)[2:][::-1] , 2)
n1 = a*b
x1 = a^b
n2 = c*d
x2 = c^d1
flag = md5(str(a+b+c+d).encode()).hexdigest()
print("n1 =",n1)
print("x1 =",x1)
print("n2 =",n2)
print("x2 =",x2)
#n1 = 83876349443792695800858107026041183982320923732817788196403038436907852045968678032744364820591254653790102051548732974272946672219653204468640915315703578520430635535892870037920414827506578157530920987388471203455357776260856432484054297100045972527097719870947170053306375598308878558204734888246779716599
#x1 = 4700741767515367755988979759237706359789790281090690245800324350837677624645184526110027943983952690246679445279368999008839183406301475579349891952257846
#n2 = 65288148454377101841888871848806704694477906587010755286451216632701868457722848139696036928561888850717442616782583309975714172626476485483361217174514747468099567870640277441004322344671717444306055398513733053054597586090074921540794347615153542286893272415931709396262118416062887003290070001173035587341
#x2 = 3604386688612320874143532262988384562213659798578583210892143261576908281112223356678900083870327527242238237513170367660043954376063004167228550592110478
乍一看还以为很简单,主要方法是爆破 。
知道两个条件都可以作为限制条件,以此来减少爆破得到的结果,最后再把得到的结果尝试爆破一下符合条件即可
集合多个大佬wp,总算看懂了
import itertools
from tqdm import tqdm
from hashlib import md5
def getAB():
n1 = 83876349443792695800858107026041183982320923732817788196403038436907852045968678032744364820591254653790102051548732974272946672219653204468640915315703578520430635535892870037920414827506578157530920987388471203455357776260856432484054297100045972527097719870947170053306375598308878558204734888246779716599
x1 = 4700741767515367755988979759237706359789790281090690245800324350837677624645184526110027943983952690246679445279368999008839183406301475579349891952257846
a_list, b_list = [0], [0]
cur_mod = 1
for i in range(512):
cur_mod *= 2
next_a=[]
next_b=[]
for al, bl in zip(a_list, b_list):
for ah, bh in itertools.product([0, 1], repeat=2):
aa, bb = ah*(cur_mod // 2) + al, bh*(cur_mod // 2) + bl
if ((aa * bb % cur_mod == n1 % cur_mod) and ((aa ^ bb) == x1 % cur_mod)):
next_a.append(aa)
next_b.append(bb)
a_list,b_list=next_a,next_b
for a in a_list:
for b in b_list:
if a*b==n1 and a^b==x1:
return a,b
a,b=getAB()
#print(a,b)
def getCD():
n = 65288148454377101841888871848806704694477906587010755286451216632701868457722848139696036928561888850717442616782583309975714172626476485483361217174514747468099567870640277441004322344671717444306055398513733053054597586090074921540794347615153542286893272415931709396262118416062887003290070001173035587341
x = 3604386688612320874143532262988384562213659798578583210892143261576908281112223356678900083870327527242238237513170367660043954376063004167228550592110478
p_low = [0]
p_high = [0]
q_low = [0]
q_high = [0]
maskx = 1
maskn = 2
si = 2
for i in range(256):
x_lowbit = (x& maskx)>>i
n_lowbits = (n % maskn)
tmppp_low = []
tmpqq_low =[]
tmppp_high = []
tmpqq_high = []
x_highbit = (x>>(511-i)) & 1
n_highbits = (n) >>(1022-2*i)
for j in range(len(p_low)):
for pp_low in range(2):
for qq_low in range(2):
for pp_high in range(2):
for qq_high in range(2):
if pp_low^qq_high ==x_lowbit and qq_low^pp_high == x_highbit:
temp1 = ((pp_low * maskn//2 +p_low[j])*(qq_low*maskn//2 +q_low[j]))% maskn
temp2 = (((pp_high << (511-i))+p_high[j])* ((qq_high<<(511-i))+q_high[j]))>>(1022-2*i)
if temp1 == n_lowbits:
if n_highbits-temp2 >=0 and n_highbits-temp2 <=((2<<i+1)-1):
tmppp_low.append(pp_low*maskn//2 + p_low[j])
tmpqq_low.append(qq_low*maskn//2+q_low[j])
tmppp_high.append((pp_high<<(511-i))+p_high[j])
tmpqq_high.append((qq_high<<(511-i))+q_high[j])
maskn *= 2
maskx *= 2
p_low = tmppp_low
q_low = tmpqq_low
p_high = tmppp_high
q_high = tmpqq_high
for a in p_low:
for b in p_high:
if n %(a+b) ==0:
p = a+b
q = n//p
return p,q
c,d=getCD()
flag = md5(str(a+b+c+d).encode()).hexdigest()
print(flag)