5space signin(未知低位的dfs和coppersmith)

from Crypto.Util.number import*
c = 63488316931652165283768913693816254792896563414188573961010693330775143775030913217280890394659049814570506800869658798199766919279796699387348933980902437475407321186495972207055265266498997713893677789253948774459839170286422387924339017064620132596766605191433871936998603329570606903349148944177923042129
e = 65537
n = 96718802331928486399440471324839538140537235267473988763367174256395151407905179947160991624325793272001609865770400579479699246848732420404657206862379932460142346799183080432865152364837341193526953437531245191267443260742413602677075914430257485504145532873739572516607058139153045169040886155418058016911
x = 463242922872367824870065968430782963359186990291269168445088582686817098312265100478236517597115371129636612590922320350
p = [0]
q = [0]
maskx = 1
maskn = 2
for i in range(400):
    xbit = (x & maskx)>>i
    nbit = n % maskn
    tmpp = []
    tmpq = []
    for j in range(len(p)):
        for pbar in range(2):
            for qbar in range(2):
                if pbar^qbar ==xbit:
                    temp2 = n % maskn
                    temp1 = (pbar * maskn //2 + p[j]) * (qbar * maskn//2 + q[j]) % maskn
                    if temp1 == temp2:
                        tmpp.append( pbar * maskn // 2 + p[j])
                        tmpq.append( qbar * maskn // 2 + q[j])
    maskx *= 2
    maskn *= 2
    p = tmpp
    q = tmpq
    print(i,len(p))

这次来研究一下大佬的dfs代码。代码如上,可以自己先调试分析下。

题目的条件是已知p和q低400个二进制位的异或结果。这个条件其实不够强,简单来想的话,400个位异或结果知道了,每个位都有两种可能,400个位就有2**400种可能,遍历是不可能的。但是结合  n=p*q  ,设计算法其实可以较快得到精准的p和q的低400位。

下面来分析下算法:

该算法的基本思路是逐位根据条件得到可能的(p,q)对,每次更新p和q的表,更新的依据有两个:

step1:

if pbar^qbar ==xbit

 表示这个位符合题目给的异或结果

step2:

temp2 = n % maskn
temp1 = (pbar * maskn //2 + p[j]) * (qbar * maskn//2 + q[j]) % maskn
if temp1 == temp2:

 这一段先是构造在现有可能的 p 和 q 的前 j 位的前面接上通过第一层筛选的pbar和qbar,来测试这些位相乘得到的结果是不是与n相符,进而得到 j+1 位的情况下的可能的(p,q)对

重复step1,2  400次即可获得可能的(p,q) 的低400位的情况。

然后利用sage逐个带入求根(能求出来的那个就是本来的q,p):

N = n
pbits = 512
for i in range(len(p)):
    pbar = p[i]
    kbits = 514 - len(bin(pbar)) 
    R.<x> = Zmod(n)[]
    f = (pbar + x * 2 ** (512-kbits)).monic()
    rot = f.small_roots(X = 2^kbits,beta = 0.4)
    if rot:
        print(pbar + rot[0] * 2 ** (512-kbits))

得到p,q题就完事了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值