Wiener’s attack python


題目如下:

在不分解n的前提下,求d。



給定:


e = 14058695417015334071588010346586749790539913287499707802938898719199384604316115908373997739604466972535533733290829894940306314501336291780396644520926473

n = 33608051123287760315508423639768587307044110783252538766412788814888567164438282747809126528707329215122915093543085008547092423658991866313471837522758159



說明過程。

 

 

這種e很大的,d可能就會比較小,可能會滿足Wiener’s attack的條件,介紹如下:

英文:

 

 

中文材料參考:

 

 

 

這里有兩個概念,連分數和漸進分數,詳情自行谷歌百度

連分數概念圖:

 

漸進分數概念:

 

我的理解:

上面的等式應該比較容易理解,就是等式右邊的分母很大,作為整體很小,意味着等式左邊的減數和被減數的差距很小很小,並且可以通過被減數的連分數求解不斷逼近它本身的一個漸進分數,因此可能會存在某個漸進分數可以滿足減數的要求;

當然按照求解的漸進分數的分子分母分別對應減數的分子分母,因此從頭將所有的漸進分數的分子分母求解出來。

 

在rsa中, φ(n)= pq - (p + q) + 1 = N - (p + q) + 1,N = pq ,其中p和q都是素數,因此可以推出 φ(n)和N之間的表達式。

 

搬運的代碼如下:

import gmpy2
def transform(x,y):       #使用輾轉相處將分數 x/y 轉為連分數的形式
    res=[]
    while y:
        res.append(x//y)
        x,y=y,x%y
    return res
    
def continued_fraction(sub_res):
    numerator,denominator=1,0
    for i in sub_res[::-1]:      #從sublist的后面往前循環
        denominator,numerator=numerator,i*numerator+denominator
    return denominator,numerator   #得到漸進分數的分母和分子,並返回

    
#求解每個漸進分數
def sub_fraction(x,y):
    res=transform(x,y)
    res=list(map(continued_fraction,(res[0:i] for i in range(1,len(res)))))  #將連分數的結果逐一截取以求漸進分數
    return res

def get_pq(a,b,c):      #由p+q和pq的值通過維達定理來求解p和q
    par=gmpy2.isqrt(b*b-4*a*c)   #由上述可得,開根號一定是整數,因為有解
    x1,x2=(-b+par)//(2*a),(-b-par)//(2*a)
    return x1,x2

def wienerAttack(e,n):
    for (d,k) in sub_fraction(e,n):  #用一個for循環來注意試探e/n的連續函數的漸進分數,直到找到一個滿足條件的漸進分數
        if k==0:                     #可能會出現連分數的第一個為0的情況,排除
            continue
        if (e*d-1)%k!=0:             #ed=1 (mod φ(n)) 因此如果找到了d的話,(ed-1)會整除φ(n),也就是存在k使得(e*d-1)//k=φ(n)
            continue
        
        phi=(e*d-1)//k               #這個結果就是 φ(n)
        px,qy=get_pq(1,n-phi+1,n)
        if px*qy==n:
            p,q=abs(int(px)),abs(int(qy))     #可能會得到兩個負數,負負得正未嘗不會出現
            d=gmpy2.invert(e,(p-1)*(q-1))     #求ed=1 (mod  φ(n))的結果,也就是e關於 φ(n)的乘法逆元d
            return d
    print("該方法不適用")
    
    
e = 14058695417015334071588010346586749790539913287499707802938898719199384604316115908373997739604466972535533733290829894940306314501336291780396644520926473
n = 33608051123287760315508423639768587307044110783252538766412788814888567164438282747809126528707329215122915093543085008547092423658991866313471837522758159
d=wienerAttack(e,n)
print("d=",d)
View Code

 

 

參考:https://www.tr0y.wang/2017/11/06/CTFRSA/index.html

          https://blog.csdn.net/qq_33737036/article/details/78199297

          https://en.wikipedia.org/wiki/Wiener%27s_attack

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM