p^q
题目:
from Crypto.Util.number import *
p = getPrime(256)
#print(f"p = {p}")
q = getPrime(256)
#print(f"q = {q}")
n = p*q
xor = p^q
print(f"n = {n}")
print(f"xor = {xor}")
'''
p = 58564099869705283749691643072929133390339905202902369909258603114014283736863
q = 109618179086386432450864386584409735510823102908281600657630737059858362787341
n = 6419689987550374128759461043478680817629415183956100630984030776455805721136996032130353721597904708456980726076368564902276506738900861513978370071451283
xor = 52079002893163018074135870573932653884989833719934423625241880155602770510098
'''
解题思路:
p = getPrime(256)
q = getPrime(256)
n = p*q
xor = p^q
已知条件:
xor = p ^ q
n = p * q
搜索方式:
- 从高位向低位搜索
- 若
xor
当前位为1
,则可能为两种情况:p
为1
,q
为0
或者p
为0
,q
为1
;反之xor
当前位为0
,则p
为1
,q
为1
或者p
为0
,q
为0
剪枝条件:
- 将
p
和q
剩下位全部填充为1
,需要满足p*q > n
- 将
p
和q
剩下位全部填充为0
,需要满足p*q < n
结束条件:
p * q = n
orn mod p = 0
解答:
n = 6419689987550374128759461043478680817629415183956100630984030776455805721136996032130353721597904708456980726076368564902276506738900861513978370071451283
xor = 52079002893163018074135870573932653884989833719934423625241880155602770510098
pbits = 256
ph = ''
qh = ''
xor = str(bin(xor)[2:]).zfill(pbits)
def find(ph, qh):
l0 = len(ph)
l1 = len(qh)
tmp0 = ph + '0' * (pbits - l0)
tmp1 = ph + '1' * (pbits - l0)
tmq0 = qh + '0' * (pbits - l1)
tmq1 = qh + '1' * (pbits - l1)
if int(tmp0, 2) * int(tmq0, 2) > n: # 剪枝条件1
return
if int(tmp1, 2) * int(tmq1, 2) < n: # 剪枝条件2
return
if l0 == pbits: # 结束条件
if int(ph, 2) * int(qh, 2) == n:
print(f'p = {int(ph, 2)}')
print(f'q = {int(qh, 2)}')
return
else:
if xor[l1] == '1':
find(ph + '0', qh + '1')
find(ph + '1', qh + '0')
else:
find(ph + '1', qh + '1')
find(ph + '0', qh + '0')
find(ph, qh)
'''
p = 58564099869705283749691643072929133390339905202902369909258603114014283736863
q = 109618179086386432450864386584409735510823102908281600657630737059858362787341
p = 109618179086386432450864386584409735510823102908281600657630737059858362787341
q = 58564099869705283749691643072929133390339905202902369909258603114014283736863
'''
def get_pq(n, x):
a = [0]
b = [0]
maskx = 1
maskn = 2
for i in range(1024): #不知道bits
xbit = (x & maskx) >> i
nbit = n % maskn
t_a = []
t_b = []
for j in range(len(a)):
for aa in range(2):
for bb in range(2):
if aa ^ bb == xbit:
tmp2 = n % maskn
tmp1 = (aa * maskn // 2 + a[j]) * (bb * maskn // 2 + b[j]) % maskn
if tmp1 == tmp2:
t_a.append(aa * maskn // 2 + a[j])
t_b.append(bb * maskn // 2 + b[j])
maskx *= 2
maskn *= 2
a = t_a
b = t_b
for a1, b1 in zip(a, b):
if a1 * b1 == n:
return a1, b1
n = 6419689987550374128759461043478680817629415183956100630984030776455805721136996032130353721597904708456980726076368564902276506738900861513978370071451283
xor = 52079002893163018074135870573932653884989833719934423625241880155602770510098
print(get_pq(n, xor))
#(109618179086386432450864386584409735510823102908281600657630737059858362787341, 58564099869705283749691643072929133390339905202902369909258603114014283736863)