柏鹭杯2023 rsa + 几道连分数的题

chall.py

#python3
import sys 
sys.path.append("..") 
from Crypto.Util.number import *
from random import *
from sage.all import *
from  secret import flag1 as flag

num1 = 3
num2 = 5
while(num1<num2):
    num1 = getPrime(512)
    num2 = getPrime(512)
pt = bytes_to_long(flag) + num2

ring = RealField(1100)
num3 = ring(num1) / ring(num2)
print("num3 = ", num3)

while True:
    p = randint(2**511, num1)
    q = randint(2**511, num2)
    if isPrime(p) and isPrime(q) and p!=q:
        break
 
N = p*q
e = 65537
leak = pow(p-q, num1, num1*num2)
ct = pow(pt, e, N)

print("ct = ", ct)
print("N = ", N)
print("leak = ", leak)

"""
num3 = 1.23389923415003373900567515471436168841941584796842188964423737295914869304653496800649965063081353720701415762591488370228399019899893688681309320356016722276295236528757306976510687729729934668311830828756908988350841843676900575414367123810470585198055372776278588638204471298838884740198056387082949710435502826460830711429956
ct = 31011170589632318837149853165664224847925206003567781692767655474759523146503572164952138829336342836023903919700264739071138739105931471740973631326608186969523753119546323993892359278563753903149741128282349467136720827132122619177620866305659196267641453819504766216964516467658995724859657544518337771393
N = 61860727516406742636690805639158184396057779906729165734489212939937929906456706343476469874085504076991779041906401043694401076841639925611957258119417559980829238154105119701407722069260962772947894516879731956778127512764229384957918619863998939985369399189275568362193066167855420897196095587732512368673
leak = 23213363443983005040318061737977092634638640953366787443691593387275645092922646169818923792205696350020369122807136306157118385984272980615310163206933078119776935167207473544453080959202803743994251355133953187110546017667004996272367137522351606700447920805532616096125523674597551449412004735397779511371
"""


看到 num1/num2 = num3
用num3的连分数展开来逼近num1/num2
这里用sage中已经实现的函数
c.convergents()得到的是一串渐进分数
image
由于num3精度不可能穷尽 所以存在某个渐进分数为num1/num2
再加上题目给的一些bit_length()的限制 就可以解出num1,num2

c = continued_fraction(num3)
alist = c.convergents()
# print(alist)
for i in alist:
    a = str(i).split('/')
    if len(a) >1:
        if(is_prime(int(a[0])) and is_prime(int(a[1])) and gcd(int(a[0]),int(a[1]))==1 and int(a[0]).bit_length() == 512 and int(a[1]).bit_length() == 512):
            print(a)

不知道为什么在本地跑一直报错 但是用sage在线跑就可以
image
得到num1,num2后就是简单的求出p-q韦达反解p,q即可

from sympy import *
from primefac import *
from libnum import *
from gmpy2 import *

num3=1.23389923415003373900567515471436168841941584796842188964423737295914869304653496800649965063081353720701415762591488370228399019899893688681309320356016722276295236528757306976510687729729934668311830828756908988350841843676900575414367123810470585198055372776278588638204471298838884740198056387082949710435502826460830711429956
ct = 31011170589632318837149853165664224847925206003567781692767655474759523146503572164952138829336342836023903919700264739071138739105931471740973631326608186969523753119546323993892359278563753903149741128282349467136720827132122619177620866305659196267641453819504766216964516467658995724859657544518337771393
N = 61860727516406742636690805639158184396057779906729165734489212939937929906456706343476469874085504076991779041906401043694401076841639925611957258119417559980829238154105119701407722069260962772947894516879731956778127512764229384957918619863998939985369399189275568362193066167855420897196095587732512368673
leak = 23213363443983005040318061737977092634638640953366787443691593387275645092922646169818923792205696350020369122807136306157118385984272980615310163206933078119776935167207473544453080959202803743994251355133953187110546017667004996272367137522351606700447920805532616096125523674597551449412004735397779511371
e = 65537

# c = continued_fraction(num3)
# alist = c.convergents()
# # print(alist)
# for i in alist:
#     a = str(i).split('/')
#     if len(a) >1:
#         if(is_prime(int(a[0])) and is_prime(int(a[1])) and gcd(int(a[0]),int(a[1]))==1 and int(a[0]).bit_length() == 512 and int(a[1]).bit_length() == 512):
#             print(a)
a = ['11167377337790397338811417806698264734026040696284907854286100186126887838302430726803014418419121360514985339992064951270502853852777225947659429837569693', '9050477566333038464101590216458863799039754468566791821195736389139213194857548339787600682491327798736538059818887575696704421576721592454156775006222517']
num1,num2 = int(a[0]),int(a[1])
d = modinv(num1,(num1-1)*(num2-1))
p_q = pow(leak,d,num1*num2)
a = 1
b = p_q
c = -N
p = (-b + iroot(b*b-4*a*c,2)[0])//(2*a)
p = abs(int(p))
q = N//p
assert p*q == N
d = modinv(e,(p-1)*(q-1))
m = pow(ct,d,N)
print(n2s(int(m-num2)))

同时记录一下学习了连分数后再来看维纳攻击
image
本质在这个式子 近似可以看作e/N = k/d
将e/N连分数展开 找渐进分数满足d的bit位数 得到k,d 反向就能得到phi了
BUU week1的题

from libnum import *
c = 6755916696778185952300108824880341673727005249517850628424982499865744864158808968764135637141068930913626093598728925195859592078242679206690525678584698906782028671968557701271591419982370839581872779561897896707128815668722609285484978303216863236997021197576337940204757331749701872808443246927772977500576853559531421931943600185923610329322219591977644573509755483679059951426686170296018798771243136530651597181988040668586240449099412301454312937065604961224359235038190145852108473520413909014198600434679037524165523422401364208450631557380207996597981309168360160658308982745545442756884931141501387954248
e = 8614531087131806536072176126608505396485998912193090420094510792595101158240453985055053653848556325011409922394711124558383619830290017950912353027270400567568622816245822324422993074690183971093882640779808546479195604743230137113293752897968332220989640710311998150108315298333817030634179487075421403617790823560886688860928133117536724977888683732478708628314857313700596522339509581915323452695136877802816003353853220986492007970183551041303875958750496892867954477510966708935358534322867404860267180294538231734184176727805289746004999969923736528783436876728104351783351879340959568183101515294393048651825
n = 19873634983456087520110552277450497529248494581902299327237268030756398057752510103012336452522030173329321726779935832106030157682672262548076895370443461558851584951681093787821035488952691034250115440441807557595256984719995983158595843451037546929918777883675020571945533922321514120075488490479009468943286990002735169371404973284096869826357659027627815888558391520276866122370551115223282637855894202170474955274129276356625364663165723431215981184996513023372433862053624792195361271141451880123090158644095287045862204954829998614717677163841391272754122687961264723993880239407106030370047794145123292991433
# ring = RealField(1100)
# k_d = (e)/(n)
# f = continued_fraction(k_d)
# alist = f.convergents()
# # print(alist)
# for i in alist:
#     a = str(i).split('/')
#     if(len(a)>1):
#         a1,a2 = int(a[0]),int(a[1])
#         if gcd(a2,e) == 1 and int(a2).bit_length() == 32:
#             print(a)

a = ['1021698768', '2357048593']
k,d = a[0],a[1]
k,d = int(k),int(d)
phi = (e*d-1) // k
m = pow(c,d,n)
print(n2s(int(m)))

还有羊城杯2020RRRRRSA那道
最简单的是用渐进分数逼近Q1/Q2(我开始去逼近P1 * Q1/P2 * Q2 判断有点麻烦)这样的好处是判断很简单 is_prime(a1) and N1%a1==0

from libnum import *
from gmpy2 import *
from sympy import *
from primefac import *
from Crypto.Util.number import *
N1=60143104944034567859993561862949071559877219267755259679749062284763163484947626697494729046430386559610613113754453726683312513915610558734802079868190554644983911078936369464590301246394586190666760362763580192139772729890492729488892169933099057105842090125200369295070365451134781912223048179092058016446222199742919885472867511334714233086339832790286482634562102936600597781342756061479024744312357407750731307860842457299116947352106025529309727703385914891200109853084742321655388368371397596144557614128458065859276522963419738435137978069417053712567764148183279165963454266011754149684758060746773409666706463583389316772088889398359242197165140562147489286818190852679930372669254697353483887004105934649944725189954685412228899457155711301864163839538810653626724347
c1=55094296873556883585060020895253176070835143350249581136609315815308788255684072804968957510292559743192424646169207794748893753882418256401223641287546922358162629295622258913168323493447075410872354874300793298956869374606043622559405978242734950156459436487837698668489891733875650048466360950142617732135781244969524095348835624828008115829566644654403962285001724209210887446203934276651265377137788183939798543755386888532680013170540716736656670269251318800501517579803401154996881233025210176293554542024052540093890387437964747460765498713092018160196637928204190194154199389276666685436565665236397481709703644555328705818892269499380797044554054118656321389474821224725533693520856047736578402581854165941599254178019515615183102894716647680969742744705218868455450832
E1=125932919717342481428108392434488550259190856475011752106073050593074410065655587870702051419898088541590032209854048032649625269856337901048406066968337289491951404384300466543616578679539808215698754491076340386697518948419895268049696498272031094236309803803729823608854215226233796069683774155739820423103
N2=60143104944034567859993561862949071559877219267755259679749062284763163484947626697494729046430386559610613113754453726683312513915610558734802079868195633647431732875392121458684331843306730889424418620069322578265236351407591029338519809538995249896905137642342435659572917714183543305243715664380787797562011006398730320980994747939791561885622949912698246701769321430325902912003041678774440704056597862093530981040696872522868921139041247362592257285423948870944137019745161211585845927019259709501237550818918272189606436413992759328318871765171844153527424347985462767028135376552302463861324408178183842139330244906606776359050482977256728910278687996106152971028878653123533559760167711270265171441623056873903669918694259043580017081671349232051870716493557434517579121
c2=39328446140156257571484184713861319722905864197556720730852773059147902283123252767651430278357950872626778348596897711320942449693270603776870301102881405303651558719085454281142395652056217241751656631812580544180434349840236919765433122389116860827593711593732385562328255759509355298662361508611531972386995239908513273236239858854586845849686865360780290350287139092143587037396801704351692736985955152935601987758859759421886670907735120137698039900161327397951758852875291442188850946273771733011504922325622240838288097946309825051094566685479503461938502373520983684296658971700922069426788236476575236189040102848418547634290214175167767431475003216056701094275899211419979340802711684989710130215926526387138538819531199810841475218142606691152928236362534181622201347
E2=125932919717342481428108392434488550259190856475011752106073050593074410065655587870702051419898088541590032209854048032649625269856337901048406066968337289491951404384300466543616578679539808215698754491076340386697518948419895268049696498272031094236309803803729823608854215226233796069683774155739820425393

# num = N1/N2
# f = continued_fraction(num)
# alist = f.convergents()
# # print(alist)
# print(len(alist))
# # print('[')
# for i in alist:
#     a = str(i).split('/')
#     if len(a)>1:
#         a1,a2 = int(a[0]),int(a[1])
#         if is_prime(a1) and (N1%a1==0):
#             print(a1)
# # print(']')
# print('Over----------')

Q1 = 11628371843051760370952910026406764366191062991235308941262037248377376991693250742343307155422036713746576338866595433599862614339347536916226536644210947
Q2 = nextprime(Q1)
P1 = iroot(N1//Q1,2)[0]
P2 = iroot(N2//Q2,2)[0]
d1 = modinv(E1,(P1*P1-P1)*(Q1-1))
d2 = modinv(E2,(P2*P2-P2)*(Q2-1))
flag1 = n2s(int(pow(c1,d1,N1)))
flag2 = n2s(int(pow(c2,d2,N2)))
print(flag1+flag2)

再补一道:
chall.py

from Crypto.Util.number import *
import random
from math import *
from gmpy2 import *
'''
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 # bound = 360 - 3 - 2*128 = 101 bit
    p2 = random.randrange(p1, p1 + bound) # p1.bit_length < p2.bit_length < p1.bit_length+101
    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)
n1,n2 = pk
c1, c2 = (361624030197288323178211941746074961985876772079713896964822566468795093475887773853629454653096485450671233584616088768705417987527877166166213574572987732852155320225332020636386698169212072312758052524652761304795529199864805108000796457423822443871436659548626629448170698048984709740274043050729249408577243328282313593461300703078854044587993248807613713896590402657788194264718603549894361488507629356532718775278399264279359256975688280723740017979438505001819438, 33322989148902718763644384246610630825314206644879155585369541624158380990667828419255828083639294898100922608833810585530801931417726134558845725168047585271855248605561256531342703212030641555260907310067120102069499927711242804407691706542428236208695153618955781372741765233319988193384708525251620506966304554054884590718068210659709406626033891748214407992041364462525367373648910810036622684929049996166651416565651803952838857960054689875755131784246099270581394)

一样的 分析下bit关系 发现可以用连分数逼近Q1/Q2

n1, n2 = (1150398070565459492080597718626032792435556703413923483458704675295997646493249759818468321328556510074044954676615760446708253531839417036997811506222349194302791943489195718713797322878586379546657275419261647635859989280700191441312691274285176619391539387875252135478424580680264554294179123254566796890998243909286508189826458854346825493157697201495100628216832191035903848391447704849808577310612723700318670466035077202673373956324725108350230357879374234418393233, 1242678737076048096780023147702514112272319497423818488193557934695583793070332178723043194823444815153743889740338870676093799728875725651036060313223096288606947708155579060628807516053981975820338028456770109640111153719903207363617099371353910243497871090334898522942934052035102902892149792570965804205461900841595290667647854346905445201396273291648968142608158533514391348407631818144116768794595226974831093526512117505486679153727123796834305088741279455621586989)
c1, c2 = (361624030197288323178211941746074961985876772079713896964822566468795093475887773853629454653096485450671233584616088768705417987527877166166213574572987732852155320225332020636386698169212072312758052524652761304795529199864805108000796457423822443871436659548626629448170698048984709740274043050729249408577243328282313593461300703078854044587993248807613713896590402657788194264718603549894361488507629356532718775278399264279359256975688280723740017979438505001819438, 33322989148902718763644384246610630825314206644879155585369541624158380990667828419255828083639294898100922608833810585530801931417726134558845725168047585271855248605561256531342703212030641555260907310067120102069499927711242804407691706542428236208695153618955781372741765233319988193384708525251620506966304554054884590718068210659709406626033891748214407992041364462525367373648910810036622684929049996166651416565651803952838857960054689875755131784246099270581394)
e = 0x10001
# num = n1/n2
# f = continued_fraction(num)
# alist = f.convergents()
# for i in alist:
#     a = str(i).split('/')
#     if(len(a)>1):
#         a1,a2 = int(a[0]),int(a[1])
#         if is_prime(a1) and is_prime(a2) and a1.bit_length()==128 and a2.bit_length()==128:
#             print(a)

a = ['181856133933383097933223133658050179553', '196443958511498599913330690975430421229']
from libnum import *
from primefac import *
from gmpy2 import *

q1,q2 = int(a[0]),int(a[1])
p1 = iroot(n1//q1,4)[0]
p2 = iroot(n2//q2,4)[0]
assert (p1**4)*q1 == n1
assert (p2**4)*q2 == n2
print(p1,p2)
d1 = modinv(e,(p1**4-p1**3)*(q1-1))
d2 = modinv(e,(p2**4-p2**3)*(q2-1))
flag = n2s(int(pow(c1,d1,n1)))+n2s(int(pow(c2,d2,n2)))
print(flag)
posted @ 2023-11-08 09:06  N0zoM1z0  阅读(37)  评论(0编辑  收藏  举报