密码学硬核笔记——扩展维纳攻击

Preface

打羊城杯遇到了Extending Wiener’s attack,发现自己的知识面还是太浅了。因此写一篇博客来学习一下。

Wiener’s attack

Wiener’s attack 是根据连分数的性质以及定理,通过对e/N的连续逼近找到对应的k/d,从而分解N。接下来讲一下连分数的定义

Continued Fractions(连分数)

连分数就是一个数的连续分式展开,它的式子长这样:
其中a0为整数,a1.....an都是正整数
(其中a_0 是整数,a_1,a_2,…,a_n都是正整数)

通常我们用更简单的数组方式来描述,对任何有理数 p / q p/q p/q来说: p q = [ a 0 ; a 1 , a 2 , . . . , a n ] \frac{p}{q}=[a_0;a_1,a_2,...,a_n] qp=[a0;a1,a2,...,an]

计算连分数我们可以使用欧几里得算法:
在这里插入图片描述

Convergent(收敛)

我们定义 c i c_i ci 为连分数每一次分式展开的收敛,即:
∀ i ∈ [ 0 , n ] , c i = [ a 0 ; a 1 , . . . , a i ] \forall i \in [0,n] ,\quad c_i = [a_0;a_1,...,a_i] i[0,n],ci=[a0;a1,...,ai]
对于每一个 c i c_i ci的结果 p i q i \frac{p_i}{q_i} qipi来说,都是对 p q \frac{p}{q} qp不断进行逼近收敛的近似值。

Legendre’s theorem

这是Wiener’s attack 的一个比较重要的定理,定义如下:
在这里插入图片描述
也就是说,当满足 ∣ a − c d ∣ < 1 2 d 2 | a - \frac{c}{d}|<\frac{1}{2d^{2}} adc<2d21时, c d \frac{c}{d} dc就是 a a a的连分数收敛。

根据这个定理,我们可以通过计算一个数(e/N)的连分数来找到与这个数近似的两个数的比值(k/d),这就是Wiener’s attack的攻击方法。

Applied to RSA

假设:

e d = 1 + k λ ( N ) ed = 1+k λ(N) ed=1+(N)

λ ( N ) = L C M ( p − 1 , q − 1 ) λ(N)=LCM(p-1,q-1) λ(N)=LCM(p1,q1)

g = g c d ( p − 1 , q − 1 ) g=gcd(p-1,q-1) g=gcd(p1,q1)

d < N 0.25 d<N^{0.25} d<N0.25时,可算得:
在这里插入图片描述
因此可以通过 e N \frac{e}{N} Ne的连分数展开得到 k d g \frac{k}{dg} dgk

那怎么通过 k d g \frac{k}{dg} dgk得到 p p p q q q呢?

我们已知: e d g = k ( p − 1 ) ( q − 1 ) + g , k > g edg = k(p-1)(q-1)+g ,\quad k>g edg=k(p1)(q1)+g,k>g
所以
⌊ e d g k ⌋ = ( p − 1 ) ( q − 1 ) \lfloor\frac{edg}{k}\rfloor = (p-1)(q-1) kedg=(p1)(q1)
又因为
p q − ( p − 1 ) ( q − 1 ) + 1 2 = p + q 2 \frac{pq-(p-1)(q-1)+1}{2} = \frac{p+q}{2} 2pq(p1)(q1)+1=2p+q
( p + q 2 ) 2 − p q = ( p − q 2 ) 2 (\frac{p+q}{2})^{2} - pq =(\frac{p-q}{2})^{2} (2p+q)2pq=(2pq)2
所以我们可以通过判断 ( p − q 2 ) 2 (\frac{p-q}{2})^{2} (2pq)2是否为平方数来确定我们找的连分数是否正确,然后再算出p和q就行了。

Sagemath实现:

#wiener_attack
def possible(e,alist,N): 
    for x in alist:
        if x==0:
            continue
        phi = floor(e*(1/x))
        if (N-phi+1)%2==0 and sqrt(pow((N-phi+1)//2,2)-N).is_integer():
                (p,q)=var('p,q')
                x=solve([(p-1)*(q-1)==phi, p*q==N],p,q)
                return int(str(x[0][0]).split('==')[1])
        else:
            continue

def wiener_attack(e,N):
    c=continued_fraction(e/N)
    alist=c.convergents()
    return possible(e,alist,N)

n=
e=
t=wiener_attack(e,n)
print t

RRRRRRSA

其实这里我还想提一下 L e g e n d r e ′ s   t h e o r e m Legendre's \ theorem Legendres theorem,因为这个定理我们可以当成一个工具,而不是仅仅用在Wiener ’ s attack 。 这个这个定理的关键在于可以将一个模糊近似的数具体地求出来,类似gmpy2.iroot()一样。可以作为一种尝试的工具。(只要你有办法构造出来)

这次2020羊城杯的RRRRRRSA

P1 = getPrime(1038)
P2 = sympy.nextprime(P1)
assert(P2 - P1 < 1000)

Q1 = getPrime(512)
Q2 = sympy.nextprime(Q1

N1 = P1 * P1 * Q1
N2 = P2 * P2 * Q2

已知N1,N2,其他都是未知的。tips里也说了需要用到连分数。那必然是要用到这个定理。

下图是对应的论文。

在这里插入图片描述
通过 N 2 N 1 \frac{N_2}{N_1} N1N2的连分数来找 q q q

Extending Wiener 's attack

Wiener 's Approach

e d g = k ( p − 1 ) ( q − 1 ) + g edg = k(p-1)(q-1)+g edg=k(p1)(q1)+g
s = 1 − p − q s = 1-p-q s=1pq

所以 e d g − k N = g + k s ( W ) edg-kN=g+ks \quad \quad (W) edgkN=g+ks(W)

Guo 's Approach With Two Exponents

假设对于一个 N N N来说有两个 e i e_i ei,而且都有相对应比较小的 d i d_i di,那么可以得到:
{ e 1 d 1 − k 1 φ ( N ) = 1 e 2 d 2 − k 2 φ ( N ) = 1 \begin{cases} e_1d_1 - k_1φ(N) = 1\\ e_2d_2 - k_2φ(N) = 1\\ \end{cases} {e1d1k1φ(N)=1e2d2k2φ(N)=1
化简后可得:
e 1 d 1 k 2 − e 2 d 2 k 1 = k 2 − k 1 ( G ( 1 , 2 ) ) e_1d_1k_2-e_2d_2k_1 = k_2-k_1 \quad \quad (G_{(1,2)}) e1d1k2e2d2k1=k2k1(G(1,2))

所以可推出
∣ e 1 e 2 − d 2 k 1 d 1 k 2 ∣ = ∣ k 2 − k 1 ∣ e 2 d 1 k 1 |\frac{e_1}{e_2}-\frac{d_2k_1}{d_1k_2}|=\frac{|k_2-k_1|}{e_2d_1k_1} e2e1d1k2d2k1=e2d1k1k2k1
所以,如果 2 ( k 2 − k 1 ) d 1 k 2 < e 2 2(k_2-k_1)d_1k_2<e_2 2(k2k1)d1k2<e2,

那么就可以通过求 e 1 e 2 \frac{e_1}{e_2} e2e1的连分数找到 d 2 k 1 d 1 k 2 \frac{d_2k_1}{d_1k_2} d1k2d2k1

但是通过 d 2 k 1 d 1 k 2 \frac{d_2k_1}{d_1k_2} d1k2d2k1找到 d 1 , d 2 d_1,d_2 d1,d2很不现实。

Extending Wiener 's attack

Howgrave-Graham 和 Jean-Pierre Seifert 结合了Wiener 和Guo的想法,通过多个等式来构造格利用LLL化简来解决这个问题。

首先假设 d i < N α d_i<N^{\alpha} di<Nα,联立四个等式:

(1)
k 1 k 2 = k 1 k 2 k_1k_2=k_1k_2 k1k2=k1k2

(2) W 1 ∗ k 2 W_1*k_2 W1k2
e 1 d 1 g k 2 − k 1 N k 2 = g k 2 + k 1 s k 2 e_1d_1gk_2-k_1Nk_2=gk_2+k_1sk_2 e1d1gk2k1Nk2=gk2+k1sk2

(3) G ( 1 , 2 ) G_{(1,2)} G(1,2)

e 2 d 2 k 1 − e 1 d 1 k 2 = k 1 − k 2 e_2d_2k_1-e_1d_1k_2 = k_1-k_2 e2d2k1e1d1k2=k1k2

(4) W 1 W 2 W_1W_2 W1W2
d 1 d 2 g 2 e 1 e 2 − d 1 g k 2 e 1 N − d 2 g k 1 e 2 N + k 1 k 2 N 2 = ( g + k 1 s ) ( g + k 2 s ) d_1d_2g^{2}e_1e_2-d_1gk_2e_1N-d_2gk_1e_2N+k_1k_2N^{2} = (g+k_1s)(g+k_2s) d1d2g2e1e2d1gk2e1Nd2gk1e2N+k1k2N2=(g+k1s)(g+k2s)

从而构造出一个都是已知数的矩阵 L L L

A = ( k 1 k 2 , d 1 g k 2 , d 2 g k 1 , d 1 d 2 g 2 ) A = \begin{pmatrix} k_1k_2 ,d_1gk_2 , d_2gk_1 , d_1d_2g^{2} \end{pmatrix} A=(k1k2,d1gk2,d2gk1,d1d2g2)

L = ( 1 − N 0 N 2 0 e 1 − e 1 − e 1 N 0 0 e 2 − e 2 N 0 0 0 e 1 e 2 ) L=\begin{pmatrix} 1 & -N & 0 & N^{2} \\ 0 & e_1& -e_1 & -e_1N \\ 0 & 0 & e_2& -e_2N\\ 0& 0 & 0 & e_1e_2 \\ \end{pmatrix} L= 1000Ne1000e1e20N2e1Ne2Ne1e2

B = ( k 1 k 2 , k 2 ( g + k 1 s ) , g ( k 1 − k 2 ) , ( g + k 1 s ) ( g + k 2 s ) ) B = \begin{pmatrix} k_1k_2 , k_2(g+k_1s) , g(k_1-k_2) , (g+k_1s)(g+k_2s) \end{pmatrix} B=(k1k2,k2(g+k1s),g(k1k2),(g+k1s)(g+k2s))

A ∗ L = B A*L=B AL=B
也就是
在这里插入图片描述
LLL算法可以求出维度较低的格的最短向量。因此如果 B B B是格 L L L的最短向量的话就可以解决了。

根据假设可知:
{ e i ≈ N d i ≈ N α k i ≈ d i ≈ N α g ≈ 1 s = 1 − p − q ≈ N 0.5 \begin{cases} e_i \approx N \\ d_i\approx N^{\alpha}\\ k_i\approx d_i \approx N^{\alpha}\\ g \approx 1\\ s =1-p-q \approx N^{0.5} \end{cases} eiNdiNαkidiNαg1s=1pqN0.5


根据 M i n k o w o s k i ′ s   f i r s t   t h e o r e m Minkowoski 's \ first \ theorem Minkowoskis first theorem,只有满足:
λ 1 ( L ) ≤ n det ⁡ ( L ) 1 n \lambda_1(L) \leq \sqrt{n}\det(L)^{\frac{1}{n}} λ1(L)n det(L)n1才能算是最短向量。

但是右边计算结果为 N N N,明显 ∥ B ∥ > N \|B\|>N B>N,所以不行。


其实,我们可以通过对矩阵的列乘上一个倍数使得条件满足。

M 1 = N 1 / 2 M_1 = N^{1/2} M1=N1/2 M 2 = N 1 + α M_2 = N^{1+\alpha} M2=N1+α,将 M 1 , M 2 M_1,M_2 M1,M2分别乘到第二列和第三列,将 N N N乘到第一列,得:

L 2 = ( N − M 1 N 0 N 2 0 M 1 e 1 − M 2 e 1 − e 1 N 0 0 M 2 e 2 − e 2 N 0 0 0 e 1 e 2 ) L_2=\begin{pmatrix} N & -M_1N & 0 & N^{2} \\ 0 & M_1e_1& -M_2e_1 & -e_1N \\ 0 & 0 & M_2e_2& -e_2N\\ 0& 0 & 0 & e_1e_2 \\ \end{pmatrix} L2= N000M1NM1e1000M2e1M2e20N2e1Ne2Ne1e2
所以 B 2 = ( k 1 k 2 N , k 2 ( g + k 1 s ) M 1 , g ( k 1 − k 2 ) M 2 , ( g + k 1 s ) ( g + k 2 s ) ) B_2= \begin{pmatrix} k_1k_2N , k_2(g+k_1s)M_1 , g(k_1-k_2)M_2 , (g+k_1s)(g+k_2s) \end{pmatrix} B2=(k1k2N,k2(g+k1s)M1,g(k1k2)M2,(g+k1s)(g+k2s)) ∥ B 2 ∥ ≤ 2 N 1 + 2 α \|B_2\| \leq 2N^{1+2\alpha} B22N1+2α n det ⁡ ( L ) 1 n = 2 det ⁡ ( L ) 4 = 2 N ( 13 2 + α ) 1 4 \sqrt{n}\det(L)^{\frac{1}{n}}=2 \sqrt[4]{\det(L)}=2N^{(\frac{13}{2}+\alpha)\frac{1}{4}} n det(L)n1=24det(L) =2N(213+α)41

所以,要使得不等式成立,可推得:
∥ B 2 ∥ ≤ n det ⁡ ( L ) 1 n \|B_2\| \leq \sqrt{n}\det(L)^{\frac{1}{n}} B2n det(L)n1

2 N 1 + 2 α ≤ 2 N ( 13 2 + α ) 1 4 2N^{1+2\alpha} \leq 2N^{(\frac{13}{2}+\alpha)\frac{1}{4}} 2N1+2α2N(213+α)41
解得:
α ≤ 5 14 \alpha \leq\frac{5}{14} α145

求出了 α \alpha α,我们可以代入 M 2 M_2 M2,利用LLL算法求出格 L 2 L_2 L2的最短向量 B 2 B_2 B2,再乘上 L 2 L_2 L2的逆求出 A A A,利用 A A A的前两项求出 φ ( N ) φ(N) φ(N)

真题演练

2020羊城杯 Simple.py

from Crypto.Util.number import *
from Crypto.Cipher import DES
import gmpy2
from secret import flag
import random

key = "abcdefgh"

def des_encrypt(m):
    des = DES.new(key, DES.MODE_ECB)
    res = des.encrypt(m)
    return res

def gen_key():
    p = getPrime(2048)
    q = getPrime(2048)
    n = p * q
    bit = n.bit_length()
    phi_n = (p - 1) * (q - 1)
    num = random.randint(1, 100)
    while True:
        u = getPrime(bit / 4 - num)
        if gmpy2.gcd(u, phi_n) != 1:
            continue
        t = gmpy2.invert(u, phi_n)
        e = bytes_to_long(des_encrypt(long_to_bytes(t)))
        if gmpy2.gcd(e, phi_n) == 1:
            break
    return (n, e)

P = getPrime(1024)
Q = getPrime(1024)
N = P * Q
E = 65537
lcm = gmpy2.lcm(P-1, Q-1)
e1 = gmpy2.invert(getPrime(730), lcm)
e2 = gmpy2.invert(getPrime(730), lcm)
m = bytes_to_long(flag)
c = pow(m, E, N)
print "N = " + str(N)
print "e2 = " + str(e2)
print "c = " + str(c)
_n, _e = gen_key()
_c = pow(e1, _e, _n)
print "_n = " + str(_n)
print "_e = " + str(_e)
print "_c = " + str(_c)

# N = 14922959775784066499316528935316325825140011208871830627653191549546959775167708525042423039865322548420928571524120743831693550123563493981797950912895893476200447083386549353336086899064921878582074346791320104106139965010480614879592357793053342577850761108944086318475849882440272688246818022209356852924215237481460229377544297224983887026669222885987323082324044645883070916243439521809702674295469253723616677245762242494478587807402688474176102093482019417118703747411862420536240611089529331148684440513934609412884941091651594861530606086982174862461739604705354416587503836130151492937714365614194583664241
# e2 = 27188825731727584656624712988703151030126350536157477591935558508817722580343689565924329442151239649607993377452763119541243174650065563589438911911135278704499670302489754540301886312489410648471922645773506837251600244109619850141762795901696503387880058658061490595034281884089265487336373011424883404499124002441860870291233875045675212355287622948427109362925199018383535259913549859747158348931847041907910313465531703810313472674435425886505383646969400166213185676876969805238803587967334447878968225219769481841748776108219650785975942208190380614555719233460250841332020054797811415069533137170950762289
# c = 6472367338832635906896423990323542537663849304314171581554107495210830026660211696089062916158894195561723047864604633460433867838687338370676287160274165915800235253640690510046066541445140501917731026596427080558567366267665887665459901724487706983166070740324307268574128474775026837827907818762764766069631267853742422247229582756256253175941899099898884656334598790711379305490419932664114615010382094572854799421891622789614614720442708271653376485660139560819668239118588069312179293488684403404385715780406937817124588773689921642802703005341324008483201528345805611493251791950304129082313093168732415486813
# _n = 440489238264900860776949063845200558734341182253911040104689726634414488997095518284964514078079911856352824174173937251558842251349762631716798307360995414545464514355957499460396352456341058329671470384493547042182238690727766731554287411757022792467324815342497916894285866240516524768645049867582541899123632009100512965460004548382054578461249990158442675234477122521189649316341623637146867589119951831385717513964941787562068891523060843170463600255518728070958509224053460041184869943038887434435024428311063533345514827827485121055022245800823723487812635502090530820946638405345755666124356919178290008475459419571761406117827422883820901663916276191422633940699113760516149002609672230610575442643822241126824287790055264162725209120192661985259423924307785452001927701323647247782658775780117642900694831475681037634691806232211286493187121464506122012889644137364079403183353774265910554863733455161820449073656744610495110838881353269890437984975607744603113572453211439334880155671730821755361054781243639407912133971530394031933785051770725331242932929244719594830548310768937037042243794551163891451545574837838357398072638709907958216067999891842395376953596940377457308329336524488962532620850237570279134567668379
# _e = 861605654852236668414010386016782729745549477722901970933220380452652052018502113737968204529790495739233258572209422774257139256367928649554562561889013164344608269555777150446651170697255381344437283003508476336814132594917061838422072660017477530465048729471603537912401826065081663165440462979219418291010867656746870617893935758241591032350010782861988742885918015532494020406350897048575155800941991107973433915573030255070411073793489218782862225921465295055907689734413881263179029741870520797816282420230090879687287575328294171448819803530205292587159921154471289747571107461754730577787617451127061265552788125691266357724955508391085485034126227212788895416902189479587194999818764639403752596165043883295506465916277734482380252399557395621566461322664559344483889187037851178431011220134914560438657522787409632677020269086895142488669203469256629173438313487046130238010206678820035631793666627274457756812810094004185303422637897314225624079032617334487815628021058997628511963565055629435278956251869329025544623291223984190562109149316159243565323565271491356378189561005084676592786453581431393651385181326525455441155960432946682976515756161038293313433862078763004704003356983371787414787104076401121444383911561
# _c = 305937839546594439230463861584604201077374759167468410827830943528403007941779658881672477705113617614828611332427199124217887937391378281943856159571057598203709366891547401974326016980711130197275312149966105151573748299654404630150641461765232935912266448303266990247145252052886920248198006212876273661195636104435277145396636985516064154534488750879453474211852461463041960835745695368577903786702607508492658563272121038693371752289017330781719235752018697635304458321008407930986565779826278048082764754367267460637798512780153281325733348999426407049795270044819657399403071013496169060640127279409914638535996355848933378734045908205536540619564723586905257569498716707820544351092379516465943537383422680357333849248129118148543389733395686399565999586899123087310025442994131218237679518267106194962305629529210402269726736072967966518381350920965727690274018080619332676536005722214955949897632990356174168234408837737546230730400434240785496100281815168806724358191550743656843853383646410487436540166360406982096949178466861150173527305369007546917550634679211293496458282787881244581230558011582720632502886494712233308474151958909251857281750741736910202763888790654287328846201724930302778996046434656839999091303411

首先这题分为两部分。第一部分是gen_key()以及后面的输出求出e1。第二部分就是利用e1,e2求出c。

第一部分的t可以直接DES解密求出来,然后又因为u满足 u < N 0.25 u<N^{0.25} u<N0.25的条件,所以可以直接用wiener atttack分解出_n,从而求出e1。

from Crypto.Util.number import *
from Crypto.Cipher import DES
import random
from gmpy2 import invert

key = "abcdefgh"

def des_decrypt(m):
    des = DES.new(key, DES.MODE_ECB)
    res = des.decrypt(m)
    return res

#gkd之无敌究极wiener_attack
def possible_phi(e,alist,N): 
    for x in alist:
        if x==0:
            continue
        phi = floor(e*(1/x))
        if (N-phi+1)%2==0 and sqrt(pow((N-phi+1)//2,2)-N).is_integer():
                (p,q)=var('p,q')
                x=solve([(p-1)*(q-1)==phi, p*q==N],p,q)
                return int(str(x[0][0]).split('==')[1])
        else:
            continue

def wiener_attack(e,N):
    c=continued_fraction(e/N)
    alist=c.convergents()
    return possible_phi(e,alist,N)
_n = 440489238264900860776949063845200558734341182253911040104689726634414488997095518284964514078079911856352824174173937251558842251349762631716798307360995414545464514355957499460396352456341058329671470384493547042182238690727766731554287411757022792467324815342497916894285866240516524768645049867582541899123632009100512965460004548382054578461249990158442675234477122521189649316341623637146867589119951831385717513964941787562068891523060843170463600255518728070958509224053460041184869943038887434435024428311063533345514827827485121055022245800823723487812635502090530820946638405345755666124356919178290008475459419571761406117827422883820901663916276191422633940699113760516149002609672230610575442643822241126824287790055264162725209120192661985259423924307785452001927701323647247782658775780117642900694831475681037634691806232211286493187121464506122012889644137364079403183353774265910554863733455161820449073656744610495110838881353269890437984975607744603113572453211439334880155671730821755361054781243639407912133971530394031933785051770725331242932929244719594830548310768937037042243794551163891451545574837838357398072638709907958216067999891842395376953596940377457308329336524488962532620850237570279134567668379
_e = 861605654852236668414010386016782729745549477722901970933220380452652052018502113737968204529790495739233258572209422774257139256367928649554562561889013164344608269555777150446651170697255381344437283003508476336814132594917061838422072660017477530465048729471603537912401826065081663165440462979219418291010867656746870617893935758241591032350010782861988742885918015532494020406350897048575155800941991107973433915573030255070411073793489218782862225921465295055907689734413881263179029741870520797816282420230090879687287575328294171448819803530205292587159921154471289747571107461754730577787617451127061265552788125691266357724955508391085485034126227212788895416902189479587194999818764639403752596165043883295506465916277734482380252399557395621566461322664559344483889187037851178431011220134914560438657522787409632677020269086895142488669203469256629173438313487046130238010206678820035631793666627274457756812810094004185303422637897314225624079032617334487815628021058997628511963565055629435278956251869329025544623291223984190562109149316159243565323565271491356378189561005084676592786453581431393651385181326525455441155960432946682976515756161038293313433862078763004704003356983371787414787104076401121444383911561
_c = 305937839546594439230463861584604201077374759167468410827830943528403007941779658881672477705113617614828611332427199124217887937391378281943856159571057598203709366891547401974326016980711130197275312149966105151573748299654404630150641461765232935912266448303266990247145252052886920248198006212876273661195636104435277145396636985516064154534488750879453474211852461463041960835745695368577903786702607508492658563272121038693371752289017330781719235752018697635304458321008407930986565779826278048082764754367267460637798512780153281325733348999426407049795270044819657399403071013496169060640127279409914638535996355848933378734045908205536540619564723586905257569498716707820544351092379516465943537383422680357333849248129118148543389733395686399565999586899123087310025442994131218237679518267106194962305629529210402269726736072967966518381350920965727690274018080619332676536005722214955949897632990356174168234408837737546230730400434240785496100281815168806724358191550743656843853383646410487436540166360406982096949178466861150173527305369007546917550634679211293496458282787881244581230558011582720632502886494712233308474151958909251857281750741736910202763888790654287328846201724930302778996046434656839999091303411
_t = bytes_to_long(des_decrypt(long_to_bytes(_e)))
_p = wiener_attack(_t,_n)
_q = _n//_p
_d = invert(_e,(_p-1)*(_q-1))
e1 = pow(_c,_d,_n)
print e1

第二部分就直接用Extending Wiener Attack求解即可。

from Crypto.Util.number import *
from gmpy2 import invert
c = 6472367338832635906896423990323542537663849304314171581554107495210830026660211696089062916158894195561723047864604633460433867838687338370676287160274165915800235253640690510046066541445140501917731026596427080558567366267665887665459901724487706983166070740324307268574128474775026837827907818762764766069631267853742422247229582756256253175941899099898884656334598790711379305490419932664114615010382094572854799421891622789614614720442708271653376485660139560819668239118588069312179293488684403404385715780406937817124588773689921642802703005341324008483201528345805611493251791950304129082313093168732415486813
e2 = 27188825731727584656624712988703151030126350536157477591935558508817722580343689565924329442151239649607993377452763119541243174650065563589438911911135278704499670302489754540301886312489410648471922645773506837251600244109619850141762795901696503387880058658061490595034281884089265487336373011424883404499124002441860870291233875045675212355287622948427109362925199018383535259913549859747158348931847041907910313465531703810313472674435425886505383646969400166213185676876969805238803587967334447878968225219769481841748776108219650785975942208190380614555719233460250841332020054797811415069533137170950762289
e1 = 114552459553730357961013268333698879659007919035942930313432809776799669181481660306531243618160127922304264986001501784564575128319884991774542682853466808329973362019677284072646678280051091964555611220961719302320547405880386113519147076299481594997799884384012548506240748042365643212774215730304047871679706035596550898944580314923260982768858133395187777029914150064371998328788068888440803565964567662563652062845388379897799506439389461619422933318625765603423604615137217375612091221578339493263160670355032898186792479034771118678394464854413824347305505135625135428816394053078365603937337271798774138959
N  = 14922959775784066499316528935316325825140011208871830627653191549546959775167708525042423039865322548420928571524120743831693550123563493981797950912895893476200447083386549353336086899064921878582074346791320104106139965010480614879592357793053342577850761108944086318475849882440272688246818022209356852924215237481460229377544297224983887026669222885987323082324044645883070916243439521809702674295469253723616677245762242494478587807402688474176102093482019417118703747411862420536240611089529331148684440513934609412884941091651594861530606086982174862461739604705354416587503836130151492937714365614194583664241
a  = 0.356#731./2049
M1=N**0.5
M2= N **(a+1)
D = diagonal_matrix(ZZ,[N,M1,M2,1])
M=matrix(ZZ,[[1,-N,0,N**2],[0,e1,-e1,-e1*N],[0,0,e2,-e2*N],[0,0,0,e1*e2]])*D
L=M.LLL()
t=vector(ZZ,L[0])
x=t*M**(-1)
phi = int(x[1]/x[0]*e1)
d = invert(0x10001,phi)
m=pow(c,d,N)
print long_to_bytes(m) 

References

Extending Wiener’s Attack in the Presence of Many Decrypting Exponents

wiener deconv是一种用于信号和图像恢复的数学方法。它基于维纳滤波器的原理,旨在对被模糊和受到噪声干扰的信号进行恢复,以尽可能还原原始信号。 wiener deconv的基本思想是将观测到的信号与估计的维纳滤波器进行卷积,以得到最优的估计信号。维纳滤波器是一种自适应滤波器,能够根据信号和噪声的特性进行调整。它的设计考虑了信号的功率谱、噪声的功率谱以及系统的传输函数等信息。 实施wiener deconv的关键步骤包括估计维纳滤波器、构造恢复滤波器、对观测信号进行频率域处理以及进行频率域逆变换。首先,通过信号的功率谱、噪声的功率谱以及系统的传输函数,可以估计出维纳滤波器的频率响应。然后,通过反演估计的维纳滤波器,可以得到恢复滤波器的频率响应。接下来,将观测信号转换到频率域,并将其与恢复滤波器进行频率域乘法操作。最后,通过进行频率域逆变换,可以获取到恢复后的信号。 wiener deconv在信号和图像处理中有着广泛的应用,例如在医学影像处理中用于去除模糊和噪声,以及在通信系统中用于提高信号的接收质量。然而,wiener deconv也存在一些限制,特别是当噪声水平较高或者信号和噪声的功率谱存在较大差异时,其恢复效果可能会受到较大影响。因此,在实际应用中需要根据具体情况进行适当调整和改进。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值