连分数分解(心情不好,爬起,遂有此烂文)

关于标题

今晚的月色深藏云间。(呜呜呜我就是在发癫)

连分数分解问题和勒让德定理关系较多,至少知道什么是连分数什么是勒让德定理。

维纳攻击 wiener attack

  攻击条件:

攻击原理:

适用情况和例题

出现多因子+大数时考虑连分数分解

[湖湘杯 2021]signin

附件:

from Crypto.Util.number import *
from secret import flag
import random

m1 = bytes_to_long(flag[:len(flag) // 2])
m2 = bytes_to_long(flag[len(flag) // 2:])

def gen(pbits, qbits):
    p1, q1 = getPrime(pbits), getPrime(qbits)
    n1 = p1**4*q1
    q2 = getPrime(qbits)
    bound = p1 // (8*q1*q2) + 1
    p2 = random.randrange(p1, p1 + bound)
    while not isPrime(p2):
        p2 = random.randrange(p1, p1 + bound)
    n2 = p2**4*q2
    return (n1, n2), (p1, q1), (p2, q2)

e = 0x10001
pbits = int(360)
qbits = int(128)
pk, sk1, sk2 = gen(pbits, qbits)
c1 = pow(m1, e, pk[0])
c2 = pow(m2, e, pk[1])
print(f'pk = {pk}')
print(f'c1, c2 = {c1, c2}')

"""
pk = (1150398070565459492080597718626032792435556703413923483458704675295997646493249759818468321328556510074044954676615760446708253531839417036997811506222349194302791943489195718713797322878586379546657275419261647635859989280700191441312691274285176619391539387875252135478424580680264554294179123254566796890998243909286508189826458854346825493157697201495100628216832191035903848391447704849808577310612723700318670466035077202673373956324725108350230357879374234418393233, 1242678737076048096780023147702514112272319497423818488193557934695583793070332178723043194823444815153743889740338870676093799728875725651036060313223096288606947708155579060628807516053981975820338028456770109640111153719903207363617099371353910243497871090334898522942934052035102902892149792570965804205461900841595290667647854346905445201396273291648968142608158533514391348407631818144116768794595226974831093526512117505486679153727123796834305088741279455621586989)
c1, c2 = (361624030197288323178211941746074961985876772079713896964822566468795093475887773853629454653096485450671233584616088768705417987527877166166213574572987732852155320225332020636386698169212072312758052524652761304795529199864805108000796457423822443871436659548626629448170698048984709740274043050729249408577243328282313593461300703078854044587993248807613713896590402657788194264718603549894361488507629356532718775278399264279359256975688280723740017979438505001819438, 33322989148902718763644384246610630825314206644879155585369541624158380990667828419255828083639294898100922608833810585530801931417726134558845725168047585271855248605561256531342703212030641555260907310067120102069499927711242804407691706542428236208695153618955781372741765233319988193384708525251620506966304554054884590718068210659709406626033891748214407992041364462525367373648910810036622684929049996166651416565651803952838857960054689875755131784246099270581394)
"""

思路:

计算连分数表示和连分数的收敛值,获取两数的最大公约数

exp:

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

def continued_fra(x,y):
    cf = []
    while y!=0:
        cf.append(x//y)
        x,y = y,x%y
    
    return cf

def exp(x,y):
    cf = continued_fra(x,y)
    fz = [cf[0],cf[0]*cf[1]+1]
    fm = [1,cf[1]]
    for i in range(2,len(cf)):
        z = fz[i-1]*cf[i]+fz[i-2]
        m = fm[i-1]*cf[i]+fm[i-2]
        fz.append(z)
        fm.append(m)
    
    return fz,fm

def get(x,y):
    tmp1,tmp2 = exp(x,y)
    for i in range(2,len(tmp1)):
        xx,yy = tmp1[i],tmp2[i]
        if x%xx==0 and y%yy==0 and x!=xx and y!=yy:
            return xx,yy



c1, c2 = (361624030197288323178211941746074961985876772079713896964822566468795093475887773853629454653096485450671233584616088768705417987527877166166213574572987732852155320225332020636386698169212072312758052524652761304795529199864805108000796457423822443871436659548626629448170698048984709740274043050729249408577243328282313593461300703078854044587993248807613713896590402657788194264718603549894361488507629356532718775278399264279359256975688280723740017979438505001819438, 33322989148902718763644384246610630825314206644879155585369541624158380990667828419255828083639294898100922608833810585530801931417726134558845725168047585271855248605561256531342703212030641555260907310067120102069499927711242804407691706542428236208695153618955781372741765233319988193384708525251620506966304554054884590718068210659709406626033891748214407992041364462525367373648910810036622684929049996166651416565651803952838857960054689875755131784246099270581394)
e = 0x10001
n1 = 1150398070565459492080597718626032792435556703413923483458704675295997646493249759818468321328556510074044954676615760446708253531839417036997811506222349194302791943489195718713797322878586379546657275419261647635859989280700191441312691274285176619391539387875252135478424580680264554294179123254566796890998243909286508189826458854346825493157697201495100628216832191035903848391447704849808577310612723700318670466035077202673373956324725108350230357879374234418393233
n2 = 1242678737076048096780023147702514112272319497423818488193557934695583793070332178723043194823444815153743889740338870676093799728875725651036060313223096288606947708155579060628807516053981975820338028456770109640111153719903207363617099371353910243497871090334898522942934052035102902892149792570965804205461900841595290667647854346905445201396273291648968142608158533514391348407631818144116768794595226974831093526512117505486679153727123796834305088741279455621586989
e = int(e)


q1,q2 = get(n1,n2)

p1 = gmpy2.iroot(n1//q1,4)[0]
p2 = gmpy2.iroot(n2//q2,4)[0]

phi1 = p1**3*(p1-1)*(q1-1)
phi2 = p2**3*(p2-1)*(q2-1)

d1 = inverse(e,phi1)
d2 = inverse(e,phi2)

m1 = pow(c1,d1,n1)
m2 = pow(c2,d2,n2)

print(long_to_bytes(m1)+long_to_bytes(m2))

posted @ 2024-10-09 16:40  打盹  阅读(4)  评论(0编辑  收藏  举报