Wiener攻击及其延伸

wiener攻击

一:Wiener 攻击原理

  1. 核心方程

    \[ed \equiv 1 \pmod{\phi(N)} \implies ed = k\phi(N) + 1 \]

  2. 近似处理

    \[\left| \frac{e}{N} - \frac{k}{d} \right| \approx \frac{1}{dN} \quad \text{(因 $\phi(N) \approx N$)} \]

  3. 误差边界

    \[\left| \frac{e}{N} - \frac{k}{d} \right| \leq \frac{3k}{d\sqrt{N}} \quad \text{(利用 $|N-\phi(N)| < 3\sqrt{N}$)} \]

  4. 攻击条件
    当 $$ d < \frac{1}{3}N^{1/4} $$ 时,有:

    \[\frac{3k}{d\sqrt{N}} < \frac{1}{2d^2} \]

    此时 \(\frac{k}{d}\) 必为 \(\frac{e}{N}\) 的连分数收敛项。

  5. 攻击步骤

    • 计算 \(\frac{e}{N}\) 的连分数展开
    • 检查收敛项 \(\frac{k_i}{d_i}\) 是否满足 \((ed_i -1) \equiv 0 \pmod{k_i}\)
    • 解方程 $$ x^2 - (N+1-\phi)x + N = 0 $$ 恢复 \(p,q\),其中 \(\phi = \frac{ed_i-1}{k_i}\)

sage代码:

from sage.all import *
from Crypto.Util.number import long_to_bytes

n = 
e = 
c = 
cf = continued_fraction(e/n)
for i in cf.convergents():
    k = i.numerator()
    d = i.denominator()
    if k == 0 or d == 0:
        continue
    if (e*d - 1) % k != 0:
        continue
    phi = (e*d - 1) // k
    s = n + 1 - phi  # p + q
    # 解方程x^2 - s*x + n = 0,应用韦达定理
    D = s^2 - 4*n
    if D < 0:
        continue  
    sqrt_D = sqrt(D)
    if not sqrt_D.is_integer():
        continue
    p = (s + sqrt_D)/2
    q = (s - sqrt_D)/2   
    if p.is_integer() and q.is_integer():
        p, q = ZZ(p), ZZ(q)
        if p*q == n:
            d = inverse_mod(e, (p-1)*(q-1))
            m = pow(c, d, n)
            print("Decrypted flag:", long_to_bytes(int(m)))
            break

二:例题

[HGAME 2022 week3]RSA attack 3

给了n,e,c,数据太大放在下面exp了

这道题e特别大,又因为$$ ed \equiv 1 \pmod{\phi(N)} \implies ed = k\phi(N) + 1 $$

可以得到\(d = (k\phi(N) + 1)/e\)

所以d非常小对吧,考虑维纳攻击。

from sage.all import *
from Crypto.Util.number import long_to_bytes

n = 507419170088344932990702256911694788408493968749527614421614568612944144764889717229444020813658893362983714454159980719026366361318789415279417172858536381938870379267670180128174798344744371725609827872339512302232610590888649555446972990419313445687852636305518801236132032618350847705234643521557851434711389664130274468354405273873218264222293858509477860634889001898462547712800153111774564939279190835857445378261920532206352364005840238252284065587291779196975457288580812526597185332036342330147250312262816994625317482869849388424397437470502449815132000588425028055964432298176942124697105509057090546600330760364385753313923003549670107599757996810939165300581847068233156887269181096893089415302163770884312255957584660964506028002922164767453287973102961910781312351686488047510932997937700597992705557881172640175117476017503918294534205898046483981707558521558992058512940087192655700351675718815723840568640509355338482631416345193176708501897458649841539192993142790402734898948352382350766125000186026261167277014748183012844440603384989647664190074853086693408529737767147592432979469020671772152652865219092597717869942730499507426269170189547020660681363276871874469322437194397171763927907099922324375991793759
e = 77310199867448677782081572109343472783781135641712597643597122591443011229091533516758925238949755491395489408922437493670252550920826641442189683907973926843505436730014899918587477913032286153545247063493885982941194996251799882984145155733050069564485120660716110828110738784644223519725613280140006783618393995138076030616463398284819550627612102010214315235269945251741407899692274978642663650687157736417831290404871181902463904311095448368498432147292938825418930527188720696497596867575843476810225152659244529481480993843168383016583068747733118703000287423374094051895724494193455175131120243097065270804457787026492578916584536863548445813916819417857064037664101684455000184987531252344582899589746272173970083733130106407810619258077266603898529285634495710846838011858287024329514491058790557305041389614650730267774482954666726949886313386881066593946789460028399523245777171320319444673551268379126203862576627540177888290265714418064334752499940587750374552330008143708562065940245637685833371348603338834447212248648869514585047871442060412622164276894766238383894693759347590977926306581080390685360615407766600573527565016914830132066428454738135380178959590692145577418811677639050929791996313180297924833690095
c = 165251729917394529793163344300848992394021337429474789711805041655116845722480301677817165053253655027459227404782607373107477419083333844871948673626672704233977397989843349633720167495862807995411682262559392496273163155214888276398332204954185252030616473235814999366132031184631541209554169938146205402400412307638567132128690379079483633171535375278689326189057930259534983374296873110199636558962144635514392282351103900375366360933088605794654279480277782805401749872568584335215630740265944133347038070337891035560658434763924576508969938866566235926587685108811154229747423410476421860059769485356567301897413767088823807510568561254627099309752215808220067495561412081320541540679503218232020279947159175547517811501280846596226165148013762293861131544331444165070186672186027410082671602892508739473724143698396105392623164025712124329254933353509384748403154342322725203183050328143736631333990445537119855865348221215277608372952942702104088940952142851523651639574409075484106857403651453121036577767672430612728022444370874223001778580387635197325043524719396707713385963432915855227152371800527536048555551237729690663544828830627192867570345853910196397851763591543484023134551876591248557980182981967782409054277224
cf = continued_fraction(e/n)
for i in cf.convergents():
    k = i.numerator()
    d = i.denominator()
    if k == 0 or d == 0:
        continue
    if (e*d - 1) % k != 0:
        continue
    phi = (e*d - 1) // k
    s = n + 1 - phi  # p + q
    # 解方程x^2 - s*x + n = 0,应用韦达定理
    D = s^2 - 4*n
    if D < 0:
        continue  
    sqrt_D = sqrt(D)
    if not sqrt_D.is_integer():
        continue
    p = (s + sqrt_D)/2
    q = (s - sqrt_D)/2   
    if p.is_integer() and q.is_integer():
        p, q = ZZ(p), ZZ(q)
        if p*q == n:
            d = inverse_mod(e, (p-1)*(q-1))
            m = pow(c, d, n)
            print("Decrypted flag:", long_to_bytes(int(m)))
            break
   
#Decrypted flag: b'hgame{dO|YOU:kNOw!tHE*PRINcIplE*bEhInd%WInNEr#aTTacK}'
BaseCTF2024-week3wiener?
from Crypto.Util.number import *
import decimal
flag=b"BaseCTF{}"
m = bytes_to_long(flag)
 
 
p = getPrime(1024)
q = getPrime(1024)
n=p*q
 
e=65537
c=pow(m,e,n)
 
print("e =",e)
print("c =",c)
 
decimal.getcontext().prec = 648
P=decimal.Decimal(p)
Q=decimal.Decimal(q)
leak=decimal.Decimal((3*P*Q-1)/(3*Q*Q))
print("leak =",leak)
 
"""
e = 65537
c = 11032748573623426359632659657114807044712138586316710250985606809252700461490504487308849626514319062562557448839550994242999334882617031487618174168038491566640081840111747765753878087564318833273878755416584962921669911444225959335274753391800995531023212276838665202257007640354237043291129197348884914956663597240094662207929658519596987351984403258345205873566463643624175318315064440456858013874962784792564480286904620663695194689839431808082976248378509181327101557380978849545906691903896662095520288964101796965095129861467059775556110616007889846240936219381379219605528051627402300580239311202137582442057
leak = 0.829374344780877053838760251345359097311540811993463349625630085472892814959843248358036249898871908548743719153319438638517170060651237635838827482534816419091949205584951292517303330452910012749674475329235689229498752425379611083979518257734473992186831474208400813283887045691145481237726578827559198828469462343342343287720369159899636816373592067698883361360269728719786071024354151682314608072902347335691012713629816579496252896260869382806838857194293618332286500427694077400072428506897829689703872985954772105672992293334668485358785863779749153981721900135318166811250762946069962348114491411585418993494561587403918162681937152503739843
"""

给定 leak = (3PQ-1)/(3Q²),有:
`

\[\text{leak} = \frac{3PQ - 1}{3Q^2} = \frac{P}{Q} - \frac{1}{3Q^2} \]

`

\[\left| \text{leak} - \frac{P}{Q} \right| = \frac{1}{3Q^2} < \frac{1}{2Q^2} \]

\[\frac{P}{Q} \in \text{Convergents}(\text{leak}) \]

P/Q 必为 leak 的收敛分数,且满足维纳攻击的条件。

from Crypto.Util.number import long_to_bytes, isPrime
e = 65537
c = 11032748573623426359632659657114807044712138586316710250985606809252700461490504487308849626514319062562557448839550994242999334882617031487618174168038491566640081840111747765753878087564318833273878755416584962921669911444225959335274753391800995531023212276838665202257007640354237043291129197348884914956663597240094662207929658519596987351984403258345205873566463643624175318315064440456858013874962784792564480286904620663695194689839431808082976248378509181327101557380978849545906691903896662095520288964101796965095129861467059775556110616007889846240936219381379219605528051627402300580239311202137582442057
leak = 0.829374344780877053838760251345359097311540811993463349625630085472892814959843248358036249898871908548743719153319438638517170060651237635838827482534816419091949205584951292517303330452910012749674475329235689229498752425379611083979518257734473992186831474208400813283887045691145481237726578827559198828469462343342343287720369159899636816373592067698883361360269728719786071024354151682314608072902347335691012713629816579496252896260869382806838857194293618332286500427694077400072428506897829689703872985954772105672992293334668485358785863779749153981721900135318166811250762946069962348114491411585418993494561587403918162681937152503739843
cf = continued_fraction(leak)
cfs = cf.convergents()
for i in cfs:
    p, q = i.numerator(), i.denominator()
    p = int(p)
    q = int(q)
    if p.bit_length() == 1024 and isPrime(p):
        phi = (p-1)*(q-1)
        d = inverse_mod(e, phi)
        m = pow(c, d, p*q)
        flag = long_to_bytes(int(m)).decode()
        print("Found flag:", flag)
 #Found flag: BaseCTF{9431ee53-5d5c-4b0b-956f-1eafff6c9e87}
羊城杯-2023easyRSA
from gmpy2 import invert
from md5 import md5
from secret import p, q

e = ?????
n = p*q
phi = (p-1)*(q-1)
d = invert(e, phi)
ans = gcd(e,phi)

print n, e, d
print "Flag: DASCTF{%s}" %md5(str(p + q)).hexdigest()

"""
n = 8064259277274639864655809758868795854117113170423331934498023294296505063511386001711751916634810056911517464467899780578338013011453082479880809823762824723657495915284790349150975180933698827382368698861967973964030509129133021116919437755292590841218316278732797712538885232908975173746394816520256585937380642592772746398646558097588687958541171131704233319344980232942965050635113860017117519166348100569115174644678997805783380130114530824798808098237628247236574959152847903491509751809336988273823686988619679739640305091291330211169194377552925908412183162787327977125388852329089751737463948165202565859373
d = 14218766449983537783699024084862960813708451888387858392014856544340557703876299258990323621963898510226357248200187173211121827541826897886277531706124228848229095880229718049075745233893843373402201077890407507625110061976931591596708901741146750809962128820611844426759462132623616118530705745098783140913
"""

就是一个展开的变而已,e损坏了不知道。

\[e \cdot d \equiv 1 \pmod{\phi(N)} \implies e \cdot d = 1 + k \cdot \phi(N) \]

\[\left| \frac{\phi(N)}{d} - \frac{e}{k} \right| = \frac{1}{e \cdot \phi(N)} \]

\[\left| \frac{N}{d} - \frac{e}{k} \right| \approx \frac{1}{e \cdot N} \]

\[\frac{e}{k} \in \text{Convergents}\left(\frac{N}{d}\right) \]

由数学关系:

\[p + q = N + 1 - \frac{e \cdot d - 1}{k} \]

得到答案。

exp:

n = 80642592772746398646558097588687958541171131704233319344980232942965050635113860017117519166348100569115174644678997805783380130114530824798808098237628247236574959152847903491509751809336988273823686988619679739640305091291330211169194377552925908412183162787327977125388852329089751737463948165202565859373
d = 14218766449983537783699024084862960813708451888387858392014856544340557703876299258990323621963898510226357248200187173211121827541826897886277531706124228848229095880229718049075745233893843373402201077890407507625110061976931591596708901741146750809962128820611844426759462132623616118530705745098783140913
cf = continued_fraction(n/d)
cfs = cf.convergents()
for i in cfs:
    e, k = i.numerator(), i.denominator()
    e = int(e)
    k = int(k)
    if k != 0 and (e * d - 1) % k==0:
        print('k=',k)
        print('e=',e)
        p_q = n + 1 - (e * d - 1) // k
        print('p + q =', p_q)

然后md5结束战斗

import hashlib
p_q = 18101966903197904104103274369549488558638013636328319260314053428770825687572755141919313812981523970938045930012152983362607947170555142776865084844865966
print(hashlib.md5(str(p_q).encode()).hexdigest())
羊城杯 2022LRSA
import gmpy2
from pwn import *
from hashlib import sha256
import string
from Crypto.Util.number import *
from random import *


from Crypto.Util.number import *
import gmpy2
from flag import flag

m=bytes_to_long(flag)

def getPQ(p,q):
    P=getPrime(2048)
    Q=getPrime(2048)
    t=(p*P-58*P+q)%Q
    assert (isPrime(Q))
    return P,Q,t

B=getRandomNBitInteger(11)
p=getPrime(B)
q=getPrime(B)
n=p*q
e=65537
c=pow(m,e,n)
P,Q,t=getPQ(p,q)

print("B=",B)
print("P*P*Q=",P*P*Q)
print("P*Q*Q=",P*Q*Q)
print("t=",t)
print("c=",c)

这道题,看到 t=(p*P-58*P+q)%Q 就知道可以构造格攻击。但是我用维纳攻击实现。

首先,用gcd(P*P*Q,P*Q*Q)可以求出P*Q,再除一下可以得到P,Q

推导关系式:

\[t \equiv P(p - 58) + q \pmod{Q} \]

存在整数 K 使得:

\[ t + KQ = P(p - 58) + q \]

两边同时除以 Q,注意当 \((t \ll Q)\)\((q \ll Q)\) 时(实际场景中需满足此近似条件):

\[(\frac{t}{Q} \approx 0, \quad \frac{q}{Q} \approx 0) \]

代入化简后可得:

\[ (\frac{K}{p - 58} \approx \frac{P}{Q}) \]

\[\frac{K}{p-58} \in \text{Convergents}\left(\frac{P}{Q}\right) \]

直接攻击

from gmpy2 import *
from Crypto.Util.number import *
P = 25947339118736016261419550658264175914664266822085997909314096786508816404704696671837899420298768803641977765786592354116676036035881712512184992851487828263900367476619650087372125353190561974783134059421570649293920248116730478378196277387377082481961542018611824082110164117796622604412648512092528479878502094797494405077897059911764470830302447618882229233093021156725194893124743848364119720591518073753197359351271987724752861168913839307431377592888760273762302003490303315903644695784992125784390012046834505490167165377346036077504298195544062111718133371983287540723388743607671934081891907851056034062109
Q = 26068172028162605137516470004551766376185367701690988148920400408760716114172673253571631718337447931195718779018987169967053546674529251665443499183399035216407895285607965767100708187327533611193709308966698251023076404422362272378862918994525181107002728889256377161661579892599243396304207048944032235378667269998644227976609632271355152717352269223310163307304914315780234040829575689991453848537587516055955657960061856059046256125836544109066275645648666876772298883460637600522819402448386193499472702636751025558486665290530268273787746964353937663176851849214999005525738643454160169651485201028944583316101
cf = continued_fraction(P/Q)
cfs = cf.convergents()
for i in cfs:
    K, p58 = i.numerator(), i.denominator()
    p=int(p58+58)
    if isPrime(p) and p.bit_length()==1023:
        print('p=',p)
#p= 80736411146583842306585010871034886981016840349026602734742256246556342668178774083233822097872779308174897649383396380481655663281333047577768952571915605685701400990749928642136680236367785948214890529631428970999122918591632651324318444462622996015719163492064450044087392474349767300242266723293755137263

至于为什么p.bit_length()==1023,因为我看前面密文c是2046bits,那么n就是2046bits,故p和q就是1023bits

三:扩展Wiener攻击方法

双指数情况

密码学硬核笔记——扩展维纳攻击-CSDN博客

对于两个公钥\((e_1,d_1)\)\((e_2,d_2)\)

\[\begin{cases} e_1d_1 = k_1φ(N)+1 \\ e_2d_2 = k_2φ(N)+1 \end{cases} \]

关键推导:

\[e_1d_1k_2 - e_2d_2k_1 = k_2 - k_1 \quad (G_{1,2}) \]

构造格基

定义向量:

\[A = (k_1k_2, d_1gk_2, d_2gk_1, d_1d_2g^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} \]

求解步骤
  1. 缩放矩阵列:

    • \(M_1 = N^{1/2}\)

    • \(M_2 = N^{1+α}\)

      \[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} \]

  2. 应用LLL算法求最短向量\(B_2\)

  3. 计算\(A = B_2 \times L_2^{-1}\)

  4. 从A中提取:

    • \(k_1k_2 = A[0]\)
    • \(d_1gk_2 = A[1]\)
  5. 计算φ(N):

    \[φ(N) = e_1 \cdot (A[1]/(A[0]) \]

import gmpy2
from Crypto.Util.number import *
c = 6472367338832635906896423990323542537663849304314171581554107495210830026660211696089062916158894195561723047864604633460433867838687338370676287160274165915800235253640690510046066541445140501917731026596427080558567366267665887665459901724487706983166070740324307268574128474775026837827907818762764766069631267853742422247229582756256253175941899099898884656334598790711379305490419932664114615010382094572854799421891622789614614720442708271653376485660139560819668239118588069312179293488684403404385715780406937817124588773689921642802703005341324008483201528345805611493251791950304129082313093168732415486813
e2 = 27188825731727584656624712988703151030126350536157477591935558508817722580343689565924329442151239649607993377452763119541243174650065563589438911911135278704499670302489754540301886312489410648471922645773506837251600244109619850141762795901696503387880058658061490595034281884089265487336373011424883404499124002441860870291233875045675212355287622948427109362925199018383535259913549859747158348931847041907910313465531703810313472674435425886505383646969400166213185676876969805238803587967334447878968225219769481841748776108219650785975942208190380614555719233460250841332020054797811415069533137170950762289
e1 = 114552459553730357961013268333698879659007919035942930313432809776799669181481660306531243618160127922304264986001501784564575128319884991774542682853466808329973362019677284072646678280051091964555611220961719302320547405880386113519147076299481594997799884384012548506240748042365643212774215730304047871679706035596550898944580314923260982768858133395187777029914150064371998328788068888440803565964567662563652062845388379897799506439389461619422933318625765603423604615137217375612091221578339493263160670355032898186792479034771118678394464854413824347305505135625135428816394053078365603937337271798774138959
N  = 14922959775784066499316528935316325825140011208871830627653191549546959775167708525042423039865322548420928571524120743831693550123563493981797950912895893476200447083386549353336086899064921878582074346791320104106139965010480614879592357793053342577850761108944086318475849882440272688246818022209356852924215237481460229377544297224983887026669222885987323082324044645883070916243439521809702674295469253723616677245762242494478587807402688474176102093482019417118703747411862420536240611089529331148684440513934609412884941091651594861530606086982174862461739604705354416587503836130151492937714365614194583664241
a  = 0.349#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(int(m)))

三指数情况

wiener attack 笔记 | 独奏の小屋

对于三个指数的情况我们额外选取

\[G(1,3),W_1G(2,3),W_2G(1,3) \]

的等式,这样我们的向量 B 为:

\[B = \begin{pmatrix} k_1k_2k_3&d_1gk_2k_3&k_1d_2gk_3&d_1d_2g^2k_3&k_1k_2d_3g&k_1d_3g&k_2d_3g&d_1d_2d_3g^3 \end{pmatrix} \]

然后我们便可以构造格:

\[L = \begin{pmatrix} 1 & -N & 0 & N^{2} & 0 & 0 & 0 & -N^{3} \\ 0 & e_{1} & -e_{1} & -N e_{1} & -e_{1} & 0 & N e_{1} & N^{2} e_{1} \\ 0 & 0 & e_{2} & -N e_{2} & 0 & N e_{2} & 0 & N^{2} e_{2} \\ 0 & 0 & 0 & e_{1} e_{2} & 0 & -e_{1} e_{2} & -e_{1} e_{2} & -N e_{1} e_{2} \\ 0 & 0 & 0 & 0 & e_{3} & -N e_{3} & -N e_{3} & N^{2} e_{3} \\ 0 & 0 & 0 & 0 & 0 & e_{1} e_{3} & 0 & -N e_{1} e_{3} \\ 0 & 0 & 0 & 0 & 0 & 0 & e_{2} e_{3} & -N e_{2} e_{3} \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & e_{1} e_{2} e_{3} \end{pmatrix} \]

\[D = diag\begin{pmatrix} N^{\frac{3}{2}}&N&N^{a + \frac{3}{2}}&\sqrt{N}&N^{a + \frac{3}{2}}&N^{a + 1}&N^{a + 1}&1\end{pmatrix} \]

我们可以得知

\[||BL||<\sqrt{8}N^{1.5+2\alpha} \]

证明可得,当

\[\alpha<\frac{2}{5}-\varepsilon \]

时,可以通过格基规约求出向量B。

e1 = 5077048237811969427473111225370876122528967447056551899123613461792688002896788394304192917610564149766252232281576990293485239684145310876930997918960070816968829150376875953405420809586267153171717496198336861089523701832098322284501931142889817575816761705044951705530849327928849848158643030693363143757063220584714925893965587967042137557807261154117916358519477964645293471975063362050690306353627492980861008439765365837622657977958069853288056307253167509883258122949882277021665317807253308906355670472172346171177267688064959397186926103987259551586627965406979118193485527520976748490728460167949055289539
e2 = 12526848298349005390520276923929132463459152574998625757208259297891115133654117648215782945332529081365273860316201130793306570777735076534772168999705895641207535303839455074003057687810381110978320988976011326106919940799160974228311824760046370273505511065619268557697182586259234379239410482784449815732335294395676302226416863709340032987612715151916084291821095462625821023133560415325824885347221391496937213246361736361270846741128557595603052713612528453709948403100711277679641218520429878897565655482086410576379971404789212297697553748292438183065500993375040031733825496692797699362421010271599510269401
e3 = 12985940757578530810519370332063658344046688856605967474941014436872720360444040464644790980976991393970947023398357422203873284294843401144065013911463670501559888601145108651961098348250824166697665528417668374408814572959722789020110396245076275553505878565603509466220710219260037783849276475397283421068716088638186994778153542817681963059581651103563578804145156157584336712678882995685632615686853980176047683326974283896343322981521150211317597571554542488921290158122634140571148036732893808064119048328855134054709120877895941670166421664806186710346824494054783025733475898081247824887967550418509038276279
c = 1414176060152301842110497098024597189246259172019335414900127452098233943041825926028517437075316294943355323947458928010556912909139739282924255506647305696872907898950473108556417350199783145349691087255926287363286922011841143339530863300198239231490707393383076174791818994158815857391930802936280447588808440607415377391336604533440099793849237857247557582307391329320515996021820000355560514217505643587026994918588311127143566858036653315985177551963836429728515745646807123637193259859856630452155138986610272067480257330592146135108190083578873094133114440050860844192259441093236787002715737932342847147399
n = 17853303733838066173110417890593704464146824886316456780873352559969742615755294466664439529352718434399552818635352768033531948009737170697566286848710832800426311328560924133698481653594007727877031506265706341560810588064209681809146597572126173303463125668183837840427667101827234752823747483792944536893070188010357644478512143332014786539698535220139784440314481371464053954769822738407808161946943216714729685820896972467020893493349051243983390018762076812868678098172416465691550285372846402991995794349015838868221686216396597327273110165922789814315858462049706255254066724012925815100434953821856854529753
L = matrix(ZZ, [
    [1, -n, 0, n**2, 0, 0, 0, -n**3],
    [0, e1, -e1, -n * e1, -e1, 0, n * e1, n**2 * e1],
    [0, 0, e2, -n * e2, 0, n * e2, 0, n**2 * e2],
    [0, 0, 0, e1 * e2, 0, -e1 * e2, -e1 * e2, -n * e1 * e2],
    [0, 0, 0, 0, e3, -n * e3, -n * e3, n**2 * e3],
    [0, 0, 0, 0, 0, e1 * e3, 0, -n * e1 * e3],
    [0, 0, 0, 0, 0, 0, e2 * e3, -n * e2 * e3],
    [0, 0, 0, 0, 0, 0, 0, e1 * e2 * e3]
])
# alpha = 768 / 2048
alpha = 2 / 5
D = diagonal_matrix(ZZ, [floor(pow(n, 3 / 2)), n, floor(pow(n, alpha + 3/2)), floor(pow(n, 1/2)), floor(pow(n, alpha + 3/2)), floor(pow(n, alpha + 1)), floor(pow(n, alpha + 1)), 1])
M = L * D
B = M.LLL()
b = vector(ZZ, B[0])
A = b * M^(-1)
phi = floor(A[1] / A[0] * e1)

d = inverse_mod(0x10001, phi)
m = pow(c, d, n)
flag = long_to_bytes(int(m))
print(flag)

论文依据

s12190-012-0618-0.pdf

论文末位给出的 n≤5 的选择关系表:

攻击效果对比

攻击类型 适用条件 格维度 理论边界
经典维纳 单d - \(N^{0.25}\)
双指数扩展 双d 4 \(N^{5/14}\)
三指数扩展 三d 8 \(N^{2/5}\)
posted @ 2025-06-23 21:01  Mirai_haN  阅读(218)  评论(0)    收藏  举报