Coppersmith Method 学习
学习资料
-
Coppersmith, D. (1996). “Finding a Small Root of a Univariate Modular Equation”. Advances in Cryptology — EUROCRYPT ‘96. Lecture Notes in Computer Science. Vol. 1070. pp. 155–165. doi:10.1007/3-540-68339-9_14. ISBN 978-3-540-61186-8.
-
Chapter 19: Coppersmith’s Method and Related Applications. Mathematics of Public Key Cryptography by Steven Galbraith ch19.pdf
NSSCTF工坊[RSA4] P2 最基础的用法
题目
from Crypto.Util.number import *flag = b'NSSCTF{******}'
m = bytes_to_long(flag)
a = getPrime(512)b = getPrime(512)c = getPrime(512)d = getPrime(512)x = getPrime(128)
p = getPrime(1024)
y = a*x**3 + b*x**2 + c*x + dy = y%p
print(f'p = {p}')print(f'a = {a}')print(f'b = {b}')print(f'c = {c}')print(f'd = {d}')print(f'y = {y}')print(f'h = {x*m}')
'''p = 133497915779382863191750985139274661777547262395290628161924420897772911005538338729076080701700641387222690295548776566406640902391412661622674862629221960258683570655393881212072865809598640669325347893228617784548982886334708010706482958773921901369314425694414231562752232070402056445403762485870067804611a = 9956367951694116871507184264812038680047685394446603010101493156120195118634053526664122377707243776744926630820373051608195739431033785355316509320690639b = 10372715760267086803036635068149481902075294943354407472550232447612611381527989796797133302495652064200149218004252582942179771677307157495328484190016267c = 6954444546090251351899752282258945069765577103755637726562318645879810909547057855773433206441550954298878711294660493586907360045986061150306446126101573d = 12708905621484064085174866220764918657140490021181156214236692898034114314742314389460399916798129560082685314351680895409634875081403212130502800572290391y = 89881957270704175663646084308402351944545222001266778194637035700540903495792268004845278611707036762628657152963392762363015748904045511650663013086598899685992255568758440781657480520250399778976982455784259655683731183717562593121780657623767804362641533930566522430h = 584447473604416360596641349947186936435346265446590336271443321812736224750414727189483734666053582372219773206703655293254283559436185831581631'''分析
最基础的用法,求模多项式的小根
from Crypto.Util.number import long_to_bytes
p = 133497915779382863191750985139274661777547262395290628161924420897772911005538338729076080701700641387222690295548776566406640902391412661622674862629221960258683570655393881212072865809598640669325347893228617784548982886334708010706482958773921901369314425694414231562752232070402056445403762485870067804611a = 9956367951694116871507184264812038680047685394446603010101493156120195118634053526664122377707243776744926630820373051608195739431033785355316509320690639b = 10372715760267086803036635068149481902075294943354407472550232447612611381527989796797133302495652064200149218004252582942179771677307157495328484190016267c = 6954444546090251351899752282258945069765577103755637726562318645879810909547057855773433206441550954298878711294660493586907360045986061150306446126101573d = 12708905621484064085174866220764918657140490021181156214236692898034114314742314389460399916798129560082685314351680895409634875081403212130502800572290391y = 89881957270704175663646084308402351944545222001266778194637035700540903495792268004845278611707036762628657152963392762363015748904045511650663013086598899685992255568758440781657480520250399778976982455784259655683731183717562593121780657623767804362641533930566522430h = 584447473604416360596641349947186936435346265446590336271443321812736224750414727189483734666053582372219773206703655293254283559436185831581631
PR.<x> = PolynomialRing(Zmod(p))f = a*x**3 + b*x**2 + c*x + d - yroots = f.monic().small_roots()print("[+] roots =", roots)
for x in roots: x = int(x) print("\n[+] x =", x) if h % x != 0: continue m = h // x print("[*] m =", m) print("[*] flag =", long_to_bytes(m))
"""[+] roots = [208220680240996722513583102044151290091]
[+] x = 208220680240996722513583102044151290091[*] m = 2806865643354785605407484846826426640471843693771605689945043127438975845650147246282645691174715937666941[*] flag = b'NSSCTF{fdf4236b-50a9-4d4b-96fb-fe9ba9d7dff7}'"""NSSCTF工坊[RSA4] P3 代换降次
题目
from Crypto.Util.number import *flag = b'NSSCTF{******}'
p = getPrime(512)q = getPrime(512)n = p*qe = 3
m1 = bytes_to_long(flag)
a = getPrime(128)b = getPrime(128)m2 = a*m1 + b
c1 = pow(m1, e, n)c2 = pow(m2, e, n)
print(f'n = {n}')print(f'a = {a}')print(f'b = {b}')print(f'c1 = {c1}')print(f'c2 = {c2}')
'''n = 100458074154921630841467009716211081004496986067171453439200150708921645946139163766441611050743248698408002732330100522747315912617782265320913313460939731072047224701193946357341685422329349168512101723657005099845122860786073559690394636750367940135874243034107367507957642817011696553619030089913082650051a = 235598638113466821523819951671842238817b = 183046284622289531351267591814278208143c1 = 59213026759461784288811267183372841532509333531605324857784387344377914885661521950844577998650904368265218037805476510488318417561718106578315758637105422183211905379616339980270327392640886739452625323181466064322246845738001714864060399808732460864513032069624364554351131806580712989439398464697132652674c2 = 3451970836023636992808694960720139231990590529637727188690993996140273782744393239397467373679391223914185297028545706156586953463105320180151843119949047044046733716896796505869700601788410522957973779842899158545218190431782013633486273807312128458720848868027747769057989052968304813931468091592761421857'''分析
注意到 Integer(bytes_to_long(f"NSSCTF{{{uuid4()}}}".encode())).nbits() 长度 351bit
因此直接 copper 这个度 的多项式是 copper 不出来的,考虑使用 代换 以降次
from Crypto.Util.number import long_to_bytes
n = 100458074154921630841467009716211081004496986067171453439200150708921645946139163766441611050743248698408002732330100522747315912617782265320913313460939731072047224701193946357341685422329349168512101723657005099845122860786073559690394636750367940135874243034107367507957642817011696553619030089913082650051a = 235598638113466821523819951671842238817b = 183046284622289531351267591814278208143c1 = 59213026759461784288811267183372841532509333531605324857784387344377914885661521950844577998650904368265218037805476510488318417561718106578315758637105422183211905379616339980270327392640886739452625323181466064322246845738001714864060399808732460864513032069624364554351131806580712989439398464697132652674c2 = 3451970836023636992808694960720139231990590529637727188690993996140273782744393239397467373679391223914185297028545706156586953463105320180151843119949047044046733716896796505869700601788410522957973779842899158545218190431782013633486273807312128458720848868027747769057989052968304813931468091592761421857
PR.<x> = PolynomialRing(Zmod(n))
f = a^3*c1 + 3*a^2*x^2*b + 3*a*x*b^2 + b^3 - c2roots = f.monic().small_roots()print("[+] roots =", roots)
for m1 in roots: m1 = int(m1) print("\n[+] m1 =", m1) print("[*] flag =", long_to_bytes(m1))
"""[+] roots = [2806865643354785581943930084864034922303658457463090366746051046593966390253248941889426497639009694016125]
[+] m1 = 2806865643354785581943930084864034922303658457463090366746051046593966390253248941889426497639009694016125[*] flag = b'NSSCTF{76f8044e-7bf9-43cd-885f-22f611628b8b}'"""NSSCTF工坊[RSA4] P4 Franklin-Reiter 相关消息攻击
题目
from Crypto.Util.number import *flag = b'NSSCTF{******}'
p = getPrime(700)q = getPrime(700)n = p*qe = 5
m1 = bytes_to_long(flag)
a = getPrime(128)b = getPrime(128)m2 = a*m1 + b
c1 = pow(m1, e, n)c2 = pow(m2, e, n)
print(f'n = {n}')print(f'a = {a}')print(f'b = {b}')print(f'c1 = {c1}')print(f'c2 = {c2}')
'''n = 13919443827889434443507983317773657992305936401066686387374260636490833628767777134968864107882874635776776741295578533278845576747348959144023000046017344598661215911149680972293657114227644912150926936884507570232880546597335636361816325245444237275023999522533527764240730547185826755972838574195391038131656239536920948158465916528880835693552792260356361022462682037427718404037021825844211741628768123221090717527493a = 285426137705625850725555147387995674019b = 277985464990476154618471183198080357743c1 = 9426395562512809581013620472326672750327318596813074726353079091173842802365552984264585030513998874440683981314827988473250779276622812642078592270162488257445750556180090334901558598065090257832879692296066144186335139137620672058976438826755846843815726564085636220609216862492337842110335421544935056753632826033207088809042045528566533513130910178132026694855125856386336197708244017301467175024440126022121500756597c2 = 7817626870900560837063304883188246502988767588941344995287074193857215881437472677956793645281329763767094907997432409446021978284194802133451654430505222891535367029301384789198710394554265321474931034378249847884399129098152817955822667403789421376159327548545340231962148603594715994813791837670639630747654837874296940404313828931665262517234613625655607389345122624044747819855804429899373080756267420097146009333048'''分析
正常解 coppersmith 肯定是没法子了,得找找别的方法
介绍:Franklin-Reiter 相关消息攻击!
易知 且
所以 和 有公共根 即有公因式
下的 gcd 函数是这样的
def gcd(a, b): while b != 0: a, b = b, a % b return a改成 下的一样能用
def gcd(f, g): while g != 0: f, g = g, f % g return f最后算出来的gcd 要记得 monic
from Crypto.Util.number import long_to_bytes
n = 13919443827889434443507983317773657992305936401066686387374260636490833628767777134968864107882874635776776741295578533278845576747348959144023000046017344598661215911149680972293657114227644912150926936884507570232880546597335636361816325245444237275023999522533527764240730547185826755972838574195391038131656239536920948158465916528880835693552792260356361022462682037427718404037021825844211741628768123221090717527493a = 285426137705625850725555147387995674019b = 277985464990476154618471183198080357743c1 = 9426395562512809581013620472326672750327318596813074726353079091173842802365552984264585030513998874440683981314827988473250779276622812642078592270162488257445750556180090334901558598065090257832879692296066144186335139137620672058976438826755846843815726564085636220609216862492337842110335421544935056753632826033207088809042045528566533513130910178132026694855125856386336197708244017301467175024440126022121500756597c2 = 7817626870900560837063304883188246502988767588941344995287074193857215881437472677956793645281329763767094907997432409446021978284194802133451654430505222891535367029301384789198710394554265321474931034378249847884399129098152817955822667403789421376159327548545340231962148603594715994813791837670639630747654837874296940404313828931665262517234613625655607389345122624044747819855804429899373080756267420097146009333048e = 5
PR.<x> = PolynomialRing(Zmod(n))
f = x^e - c1g = (a*x + b)^e - c2
def gcd(f, g): while g != 0: f, g = g, f % g return f
m = -gcd(f, g).monic()[0]print(long_to_bytes(int(m)))
# b'NSSCTF{ca5e5ba4-57f1-4902-9448-d78b2cb05618}'NSSCTF工坊[RSA4] P7 Franklin-Reiter 相关消息攻击
题目
from Crypto.Util.number import *m = bytes_to_long(b'NSSCTF{******}')
p = getPrime(512)q = getPrime(512)
n = p*q
e = 9
r = getPrime(512)
c1 = pow(m, e, n)c2 = pow(m+r, e, n)
print(f'c1 = {c1}')print(f'c2 = {c2}')print(f'r = {r}')print(f'n = {n}')
'''c1 = 135074766579407676786282087896424573055829820741326911395660008092908906818293714163243721440579480398437184153110701014575949020137195005556115765711856362529093323957313305701439430406396620730435232669024347062255561124227077117736226705746520202121773331267896121082546807985584499775544186860738299210902c2 = 52198561898892210533988782934627447441579509170862004216826284305082884787397969852570583444422705227177306845788090962326207704949679636373972262848806083888114511515323970306654941921527306928423850775839578728701294521014874290792581635297504014585143468088934951952990888189000603302912352199468290961647r = 7226418134082605571805056000800553195029496658257912353583130240746954757224748488491991266548553899116384605868480860827154816241193159482670000874841821n = 144690523587663809780722437199578577582544144694543134253077982812595463236242062416509866333774784681011350541203308061301675822157859373788530465702809816586981803008466959154241234879285863437666243631170277595720205934928759253610014553402523757331771549475265418644503305010214366648156173843801360148229'''分析
同 NSSCTF工坊[RSA4] P4 Franklin-Reiter 相关消息攻击
from Crypto.Util.number import long_to_bytes
c1 = 135074766579407676786282087896424573055829820741326911395660008092908906818293714163243721440579480398437184153110701014575949020137195005556115765711856362529093323957313305701439430406396620730435232669024347062255561124227077117736226705746520202121773331267896121082546807985584499775544186860738299210902c2 = 52198561898892210533988782934627447441579509170862004216826284305082884787397969852570583444422705227177306845788090962326207704949679636373972262848806083888114511515323970306654941921527306928423850775839578728701294521014874290792581635297504014585143468088934951952990888189000603302912352199468290961647r = 7226418134082605571805056000800553195029496658257912353583130240746954757224748488491991266548553899116384605868480860827154816241193159482670000874841821n = 144690523587663809780722437199578577582544144694543134253077982812595463236242062416509866333774784681011350541203308061301675822157859373788530465702809816586981803008466959154241234879285863437666243631170277595720205934928759253610014553402523757331771549475265418644503305010214366648156173843801360148229e = 9
PR.<x> = PolynomialRing(Zmod(n))
f = x^e - c1g = (x + r)^e - c2
def gcd(f, g): while g != 0: f, g = g, f % g return f
m = -gcd(f, g).monic()[0]print(long_to_bytes(int(m)))NSSCTF工坊[RSA4] P5 Håstad 广播攻击
题目
import randomfrom Crypto.Util.number import *m = bytes_to_long(b'NSSCTF{******}')e = 3cnt = 5A = [random.randint(1, 128) for i in range(cnt)]B = [random.randint(1, 1024) for i in range(cnt)]Cs = []Ns = []ds = []for i in range(cnt): p = getPrime(1024) q = getPrime(1024) N = p * q Ns.append(N) c = pow(A[i] * m + B[i], e, N) Cs.append(c)
print(f'Cs = {Cs}')print(f'Ns = {Ns}')print(f'A = {A}')print(f'B = {B}')
'''Cs = [3883550483902420926234302242195949363902226654053022494278088796963093148922544154652393440710324453957805003804862341179812753736616349557399185135880313324078548975985811806182903172952051652658588498612963004980264760087430598878125976827727487812798234711111712162020259061748840871764150680864715622600474900724019717, 44236067230701013362887598977513235723198800481322709348886355202907732899445854511587419035591039483362973933824325371001141984765195796979842132811747908218486539899605454036424269293612496645594202012384509417494958938609654993954815298870367636552785788956298375017694826184378792550191638399421497826339423606821604157, 6357650953899476167368901224389387403906446759598372329485772462484633677698135444868033121301336092469156582681179266678600618088894651608959308419170191169045155695737438290373562868522834196889856654007109891894017495798358315308038562408520108440771857096111507359080036538511243240503551392124933753089110476128205879, 22113876206623661433094377745740418662890776774627724662206682745097788065566600734855556673140969239465263787646309908630165398806037735405429975451284487302914604239730662891329034924321076102542709261476260968369261179396546360622009680551846353241542278987410340410787241742872482813920394082039159494900989803139848, 3482139402999788223900773097355269284333433274039980036209713091774078099956379218113295375979469580323031564990774054948555715060182912479470463142901382767332589017162687376944227096536463901792518843690268101660074429034365722795293704792196728134808253362549344588424246863639211005569740713503298812433885633339928000]Ns = [16475947720089128737086499038994656469812989231809435921247088488421456071533054401942524421620331649062071397844226728071767213827034006847771426419523100773295773164564476217357610574522713490589578290280800714302496527429690267342283298617108512673396866659851168908725556917773195601048972304412711680140760801040935590195586074637385222382292803661244860123231496798860777536415139625565081790463543592610972293444445484103576151223863074744798386995109810985102707212603792744509634887671301358727199987659311189567616661188675145831286196163294361139604739930788248190209148634033965292667427275010588011907449, 20577756967813119473983751142406348831049793754920537415005815223703461130310397180758312537008616509869607815711902558904863798387297921980544196445945053155779852988514975874071063143079007922739179751830691324912287324521191080786349595537328978318940405478035852622078260078106150355838894304903666410802941404171580632337325226810035755441751019274785623857299274197733366157959314887828355684391955406242669453470960096408521602483306976326328443227588146790803825249363494429478920856868334932355802422905860734038456902208606699044555491079703407805059303577939602439962034474867810455961978123428573930309579, 25378900199358568547963276996842869295995268651191814514603221510827400166103120330924988917554751086130358554721062101701515825946297524373525439060420148179742729309006073061967296139229954269726231365437710075337125457376990188019604789882474361937774315087501386157518068677103700336670450539759041322742305750381808526633011613014316600728378154635620303486714630541107978228937765593165029293600696974317531575469630789089360595175501977260250968161370460576429760743419177492425307438895058834861598683601140950473599184767494278677563047031229859204765208419798131798581975676005652781036214330956450007099403, 9926930930542540303568927026135349869339912234415090245441062010278559018661286180235901235221302260175325531516014675014545716516533078219977130807590578846757066721033900594646767488495122383467444918251577083210413483316448060657426105745966157951221212755678202988755054192555411944547922101946719460879213184073264876177559979901796761414990531875287201475974601204234252323254624416703924391519239658714195344209537776288504410483034555245167972866281710032749023882686703242857598745646748066876170805806058616787854614797120972981188197354785585317082619741063413472652781873599900240100437586392949061248911, 20830107058752240343833750223075661528901765032886427653372256688107333986271844745610709207164953960695218903201021174901973495649232416991828815735226979007977454196096030222267886398005100472650709789400722193947140354500257454594031250139843254349174343293378469322212240525155348525032929797789787100019790044104691478313003888625343348575779856701393153928092199647854293030744711864943595605801812851745568294572509414459253058726953902809163955547592002726224051451969415362170516701646937298176613945563863745599843208814303891064544739910893746169725919856235296428308161065429422882694228900677440053029677]A = [56, 126, 66, 10, 54]B = [261, 191, 877, 352, 62]'''分析
Håstad 广播攻击,参考代码:4.8. 低加密指数广播攻击 - 4.8.4 扩展 | 独奏の小屋
类似中国剩余定理 CRT
from Crypto.Util.number import long_to_bytes
Cs = [3883550483902420926234302242195949363902226654053022494278088796963093148922544154652393440710324453957805003804862341179812753736616349557399185135880313324078548975985811806182903172952051652658588498612963004980264760087430598878125976827727487812798234711111712162020259061748840871764150680864715622600474900724019717, 44236067230701013362887598977513235723198800481322709348886355202907732899445854511587419035591039483362973933824325371001141984765195796979842132811747908218486539899605454036424269293612496645594202012384509417494958938609654993954815298870367636552785788956298375017694826184378792550191638399421497826339423606821604157, 6357650953899476167368901224389387403906446759598372329485772462484633677698135444868033121301336092469156582681179266678600618088894651608959308419170191169045155695737438290373562868522834196889856654007109891894017495798358315308038562408520108440771857096111507359080036538511243240503551392124933753089110476128205879, 22113876206623661433094377745740418662890776774627724662206682745097788065566600734855556673140969239465263787646309908630165398806037735405429975451284487302914604239730662891329034924321076102542709261476260968369261179396546360622009680551846353241542278987410340410787241742872482813920394082039159494900989803139848, 3482139402999788223900773097355269284333433274039980036209713091774078099956379218113295375979469580323031564990774054948555715060182912479470463142901382767332589017162687376944227096536463901792518843690268101660074429034365722795293704792196728134808253362549344588424246863639211005569740713503298812433885633339928000]Ns = [16475947720089128737086499038994656469812989231809435921247088488421456071533054401942524421620331649062071397844226728071767213827034006847771426419523100773295773164564476217357610574522713490589578290280800714302496527429690267342283298617108512673396866659851168908725556917773195601048972304412711680140760801040935590195586074637385222382292803661244860123231496798860777536415139625565081790463543592610972293444445484103576151223863074744798386995109810985102707212603792744509634887671301358727199987659311189567616661188675145831286196163294361139604739930788248190209148634033965292667427275010588011907449, 20577756967813119473983751142406348831049793754920537415005815223703461130310397180758312537008616509869607815711902558904863798387297921980544196445945053155779852988514975874071063143079007922739179751830691324912287324521191080786349595537328978318940405478035852622078260078106150355838894304903666410802941404171580632337325226810035755441751019274785623857299274197733366157959314887828355684391955406242669453470960096408521602483306976326328443227588146790803825249363494429478920856868334932355802422905860734038456902208606699044555491079703407805059303577939602439962034474867810455961978123428573930309579, 25378900199358568547963276996842869295995268651191814514603221510827400166103120330924988917554751086130358554721062101701515825946297524373525439060420148179742729309006073061967296139229954269726231365437710075337125457376990188019604789882474361937774315087501386157518068677103700336670450539759041322742305750381808526633011613014316600728378154635620303486714630541107978228937765593165029293600696974317531575469630789089360595175501977260250968161370460576429760743419177492425307438895058834861598683601140950473599184767494278677563047031229859204765208419798131798581975676005652781036214330956450007099403, 9926930930542540303568927026135349869339912234415090245441062010278559018661286180235901235221302260175325531516014675014545716516533078219977130807590578846757066721033900594646767488495122383467444918251577083210413483316448060657426105745966157951221212755678202988755054192555411944547922101946719460879213184073264876177559979901796761414990531875287201475974601204234252323254624416703924391519239658714195344209537776288504410483034555245167972866281710032749023882686703242857598745646748066876170805806058616787854614797120972981188197354785585317082619741063413472652781873599900240100437586392949061248911, 20830107058752240343833750223075661528901765032886427653372256688107333986271844745610709207164953960695218903201021174901973495649232416991828815735226979007977454196096030222267886398005100472650709789400722193947140354500257454594031250139843254349174343293378469322212240525155348525032929797789787100019790044104691478313003888625343348575779856701393153928092199647854293030744711864943595605801812851745568294572509414459253058726953902809163955547592002726224051451969415362170516701646937298176613945563863745599843208814303891064544739910893746169725919856235296428308161065429422882694228900677440053029677]A = [56, 126, 66, 10, 54]B = [261, 191, 877, 352, 62]e = 3cnt = 5
Fs = []
for i in range(cnt): PR.<x> = PolynomialRing(Zmod(Ns[i])) f = (A[i] * x + B[i])^e - Cs[i] f = f.monic() f = f.change_ring(ZZ) Fs.append(f)
F = crt(Fs,Ns)M = reduce(lambda x,y: x*y, Ns)FF = F.change_ring(Zmod(M))m = FF.small_roots()[0]print(long_to_bytes(int(m)))
# b'NSSCTF{35036d92-a21e-4a72-b95b-9dbbe753ecc3}'NSSCTF工坊[RSA4] P6 SMUPE 问题
题目
import randomfrom Crypto.Util.number import *m = bytes_to_long(b'NSSCTF{******}')e = [3, 3, 5, 5, 5]cnt = 5A = [random.randint(1, 128) for i in range(cnt)]B = [random.randint(1, 1024) for i in range(cnt)]Cs = []Ns = []ds = []for i in range(cnt): p = getPrime(1024) q = getPrime(1024) N = p * q Ns.append(N) c = pow(A[i] * m + B[i], e[i], N) Cs.append(c)
print(f'Cs = {Cs}')print(f'Ns = {Ns}')print(f'A = {A}')print(f'B = {B}')
'''Cs = [1638372860396333830858192139299197565315535797114047251934794618479536350353064186140459367290707128364710894701037380862116232991456320452033817724729745999551370161110364719775843718524874686887258953369568831680913879476181277785920985528366522169515587323204831502022101524013959969707030218702665635534427846097310528, 24875103245287518333798583341170669610612985353699595724009027288108265538326708679930645795919635882205442133007431151523157879281206220723880745758565471501438254496442690083695181899335274484890789079296262809116356375268279845048678237286447923982167817217922153443176926762232059077533241044053964988769850924306985288, 64688172933628370164101081823612690628987450046625542396917972565171355353907472697857255273381548322579305723285123851525656566580337341114653428214836087595329638898225145943365511037774869374134885003316128253926961420282704740956759510282270641913416144450959604091354160410240665076557553695082195679797827535998182932257141208537699109343258070255441327703937342812407754987740672481360192201134257594522722416452532574980648175817255926752015634178759148371873886725487426882416560377719144628014480729074137290874113394638649, 2331510898077623659120984694249257439156322301842388986730933314009350853947089766519871253176646702446795943582256729119033154456495699173945031006143311061427619102940335615125087858864022720270624007893746341836293909702537610528426633085355155950799091717823412938027363876570661223166297511428235178239172777386054157082903814899961457013918859628205065752880604381763832163537338551244398891801443773401629786720308176486501031559320335954176695196225203579812567823068688019940197116285653102121974647104338589625423162979123200000, 43352520643859740433225512983905414415548381386134203892101097918185149451843972944152506360707251233402378401486868477947209998018140026240239412053179633750634829740693522063308924633469091372871162080586416600131760956876088974352867618081110555761392159757815560347289247112408714776983781605234434193615594699312985986139327998952524143416350988540093792251368427565860264534170095799987780694458909019564914374157162696794037736526763479508220179034487041180476942175322953798097172419873588374189541978291235559914015746424832]Ns = [18851715582267592911067637781505654688524006829609246212518637897179276424340538881817812202528554956234031661903911094094631063183133761100477455043312123459298106634164727720627011192110779310094771478538283788677548037922530846281891688189750395295091964623923749350256625089576542690752106832774515171043826627323369467260229924116376613509392517052062075900227272040203183759436637270279153088519018200373369193287900910393638164679806105636141482865492140475543667203300150180799017010647191076802371803957049729665372388660643393619274625881752621206735741181918995753694012667166942840946695127545765890742063, 10267889563711456032579409966472790716819993551437295130252040883990243681903448974535591113545723576913765740482844093394217174748720819947126768257873382519317182097620449979975383634794725676148262423293825784384533131631434500141020335993500562261013949796155168237990517113432978329233691874362416933639983930536969236091719851430961549012395926775041931819868164629850848771931505977967078205269399517880792473005512550209988476927697762292764104113892623269364458825553466135026856101503576301198196565099526473547248865742864274841493027912793979121030411574680325683879250124843231524231297963898683611241527, 13319929603701741793046504861847275881318265379528541599237187836042138080675688093798835275556697353969650992398737328710351200421781106774355347739070892841366306344713730729129300977800957626288502163079067715579382767916393807593767445074588824226624616133919776732577297061788596743900830022053036147505073981250694269494874718657327986653908553022998256475699594299485467200757418076210359679356806790879777840686012933726208975488043576064467651494231751296178499718963576152784658938960177680763100892103245100085259616393419229979173756419121148473713407084223326468838444608241533523272737548699784114288903, 15549454451010517732114866346347857621738418424726590607108866905866201671458396332585415677794254468988000522332928496951404966782246273839731570675805037547434885303486571417761150107287375265185136666085669367768385334732360327965658288195932251712038801089064036484182689420567148777802229959025706026709147490355638461816828297349827923064039389517458474972494803430895794622409100453812936135163906960476019328052200697229957383357240180993014685003281514802948810450239516985749998285384120569891328984748185007801287194757011610585773959113119657356194098917480068595559585415503075706079451596444873538025303, 10893748607240110955496798243605432030914497581057961213501578142738832043376333318606333861002076584473798177824249978795107994620002676260061434742704861691017695197358462123116073867166385116309506188722505093349759974669126863738760846667781081937653476878088812043691664173859578763022307064317030903235196823302973152319271598841684324885625237030423977448610068847582315745648803893547950848775977888604054275196982524051414526965045483738781651554877828535198984557716599475979572917851219474771059404496356672662467552795811246938928548202179363916774439119111218984949582826015360298300266708147597580287967]A = [42, 104, 13, 106, 12]B = [338, 554, 768, 638, 548]'''分析
不一样大,可以取前两个或者后三个来进行 Hastad (非预期)
from Crypto.Util.number import long_to_bytes
e = [3, 3, 5, 5, 5]Cs = [1638372860396333830858192139299197565315535797114047251934794618479536350353064186140459367290707128364710894701037380862116232991456320452033817724729745999551370161110364719775843718524874686887258953369568831680913879476181277785920985528366522169515587323204831502022101524013959969707030218702665635534427846097310528, 24875103245287518333798583341170669610612985353699595724009027288108265538326708679930645795919635882205442133007431151523157879281206220723880745758565471501438254496442690083695181899335274484890789079296262809116356375268279845048678237286447923982167817217922153443176926762232059077533241044053964988769850924306985288, 64688172933628370164101081823612690628987450046625542396917972565171355353907472697857255273381548322579305723285123851525656566580337341114653428214836087595329638898225145943365511037774869374134885003316128253926961420282704740956759510282270641913416144450959604091354160410240665076557553695082195679797827535998182932257141208537699109343258070255441327703937342812407754987740672481360192201134257594522722416452532574980648175817255926752015634178759148371873886725487426882416560377719144628014480729074137290874113394638649, 2331510898077623659120984694249257439156322301842388986730933314009350853947089766519871253176646702446795943582256729119033154456495699173945031006143311061427619102940335615125087858864022720270624007893746341836293909702537610528426633085355155950799091717823412938027363876570661223166297511428235178239172777386054157082903814899961457013918859628205065752880604381763832163537338551244398891801443773401629786720308176486501031559320335954176695196225203579812567823068688019940197116285653102121974647104338589625423162979123200000, 43352520643859740433225512983905414415548381386134203892101097918185149451843972944152506360707251233402378401486868477947209998018140026240239412053179633750634829740693522063308924633469091372871162080586416600131760956876088974352867618081110555761392159757815560347289247112408714776983781605234434193615594699312985986139327998952524143416350988540093792251368427565860264534170095799987780694458909019564914374157162696794037736526763479508220179034487041180476942175322953798097172419873588374189541978291235559914015746424832]Ns = [18851715582267592911067637781505654688524006829609246212518637897179276424340538881817812202528554956234031661903911094094631063183133761100477455043312123459298106634164727720627011192110779310094771478538283788677548037922530846281891688189750395295091964623923749350256625089576542690752106832774515171043826627323369467260229924116376613509392517052062075900227272040203183759436637270279153088519018200373369193287900910393638164679806105636141482865492140475543667203300150180799017010647191076802371803957049729665372388660643393619274625881752621206735741181918995753694012667166942840946695127545765890742063, 10267889563711456032579409966472790716819993551437295130252040883990243681903448974535591113545723576913765740482844093394217174748720819947126768257873382519317182097620449979975383634794725676148262423293825784384533131631434500141020335993500562261013949796155168237990517113432978329233691874362416933639983930536969236091719851430961549012395926775041931819868164629850848771931505977967078205269399517880792473005512550209988476927697762292764104113892623269364458825553466135026856101503576301198196565099526473547248865742864274841493027912793979121030411574680325683879250124843231524231297963898683611241527, 13319929603701741793046504861847275881318265379528541599237187836042138080675688093798835275556697353969650992398737328710351200421781106774355347739070892841366306344713730729129300977800957626288502163079067715579382767916393807593767445074588824226624616133919776732577297061788596743900830022053036147505073981250694269494874718657327986653908553022998256475699594299485467200757418076210359679356806790879777840686012933726208975488043576064467651494231751296178499718963576152784658938960177680763100892103245100085259616393419229979173756419121148473713407084223326468838444608241533523272737548699784114288903, 15549454451010517732114866346347857621738418424726590607108866905866201671458396332585415677794254468988000522332928496951404966782246273839731570675805037547434885303486571417761150107287375265185136666085669367768385334732360327965658288195932251712038801089064036484182689420567148777802229959025706026709147490355638461816828297349827923064039389517458474972494803430895794622409100453812936135163906960476019328052200697229957383357240180993014685003281514802948810450239516985749998285384120569891328984748185007801287194757011610585773959113119657356194098917480068595559585415503075706079451596444873538025303, 10893748607240110955496798243605432030914497581057961213501578142738832043376333318606333861002076584473798177824249978795107994620002676260061434742704861691017695197358462123116073867166385116309506188722505093349759974669126863738760846667781081937653476878088812043691664173859578763022307064317030903235196823302973152319271598841684324885625237030423977448610068847582315745648803893547950848775977888604054275196982524051414526965045483738781651554877828535198984557716599475979572917851219474771059404496356672662467552795811246938928548202179363916774439119111218984949582826015360298300266708147597580287967]A = [42, 104, 13, 106, 12]B = [338, 554, 768, 638, 548]
Fs = []
for i in [2, 3, 4]: PR.<x> = PolynomialRing(Zmod(Ns[i])) f = (A[i] * x + B[i])^e[i] - Cs[i] f = f.monic() f = f.change_ring(ZZ) Fs.append(f)
F = crt(Fs,Ns[2:5])M = reduce(lambda x,y: x*y, Ns[2:5])FF = F.change_ring(Zmod(M))m = FF.monic().small_roots()[0]print(long_to_bytes(int(m)))
# b'NSSCTF{62e90a0e-c982-4a00-8ae9-eb493786a7d6}'也可以将每个式子配好相同的次数,即 SMUPE 问题 (预期解)
from Crypto.Util.number import long_to_bytes
e = [3, 3, 5, 5, 5]Cs = [1638372860396333830858192139299197565315535797114047251934794618479536350353064186140459367290707128364710894701037380862116232991456320452033817724729745999551370161110364719775843718524874686887258953369568831680913879476181277785920985528366522169515587323204831502022101524013959969707030218702665635534427846097310528, 24875103245287518333798583341170669610612985353699595724009027288108265538326708679930645795919635882205442133007431151523157879281206220723880745758565471501438254496442690083695181899335274484890789079296262809116356375268279845048678237286447923982167817217922153443176926762232059077533241044053964988769850924306985288, 64688172933628370164101081823612690628987450046625542396917972565171355353907472697857255273381548322579305723285123851525656566580337341114653428214836087595329638898225145943365511037774869374134885003316128253926961420282704740956759510282270641913416144450959604091354160410240665076557553695082195679797827535998182932257141208537699109343258070255441327703937342812407754987740672481360192201134257594522722416452532574980648175817255926752015634178759148371873886725487426882416560377719144628014480729074137290874113394638649, 2331510898077623659120984694249257439156322301842388986730933314009350853947089766519871253176646702446795943582256729119033154456495699173945031006143311061427619102940335615125087858864022720270624007893746341836293909702537610528426633085355155950799091717823412938027363876570661223166297511428235178239172777386054157082903814899961457013918859628205065752880604381763832163537338551244398891801443773401629786720308176486501031559320335954176695196225203579812567823068688019940197116285653102121974647104338589625423162979123200000, 43352520643859740433225512983905414415548381386134203892101097918185149451843972944152506360707251233402378401486868477947209998018140026240239412053179633750634829740693522063308924633469091372871162080586416600131760956876088974352867618081110555761392159757815560347289247112408714776983781605234434193615594699312985986139327998952524143416350988540093792251368427565860264534170095799987780694458909019564914374157162696794037736526763479508220179034487041180476942175322953798097172419873588374189541978291235559914015746424832]Ns = [18851715582267592911067637781505654688524006829609246212518637897179276424340538881817812202528554956234031661903911094094631063183133761100477455043312123459298106634164727720627011192110779310094771478538283788677548037922530846281891688189750395295091964623923749350256625089576542690752106832774515171043826627323369467260229924116376613509392517052062075900227272040203183759436637270279153088519018200373369193287900910393638164679806105636141482865492140475543667203300150180799017010647191076802371803957049729665372388660643393619274625881752621206735741181918995753694012667166942840946695127545765890742063, 10267889563711456032579409966472790716819993551437295130252040883990243681903448974535591113545723576913765740482844093394217174748720819947126768257873382519317182097620449979975383634794725676148262423293825784384533131631434500141020335993500562261013949796155168237990517113432978329233691874362416933639983930536969236091719851430961549012395926775041931819868164629850848771931505977967078205269399517880792473005512550209988476927697762292764104113892623269364458825553466135026856101503576301198196565099526473547248865742864274841493027912793979121030411574680325683879250124843231524231297963898683611241527, 13319929603701741793046504861847275881318265379528541599237187836042138080675688093798835275556697353969650992398737328710351200421781106774355347739070892841366306344713730729129300977800957626288502163079067715579382767916393807593767445074588824226624616133919776732577297061788596743900830022053036147505073981250694269494874718657327986653908553022998256475699594299485467200757418076210359679356806790879777840686012933726208975488043576064467651494231751296178499718963576152784658938960177680763100892103245100085259616393419229979173756419121148473713407084223326468838444608241533523272737548699784114288903, 15549454451010517732114866346347857621738418424726590607108866905866201671458396332585415677794254468988000522332928496951404966782246273839731570675805037547434885303486571417761150107287375265185136666085669367768385334732360327965658288195932251712038801089064036484182689420567148777802229959025706026709147490355638461816828297349827923064039389517458474972494803430895794622409100453812936135163906960476019328052200697229957383357240180993014685003281514802948810450239516985749998285384120569891328984748185007801287194757011610585773959113119657356194098917480068595559585415503075706079451596444873538025303, 10893748607240110955496798243605432030914497581057961213501578142738832043376333318606333861002076584473798177824249978795107994620002676260061434742704861691017695197358462123116073867166385116309506188722505093349759974669126863738760846667781081937653476878088812043691664173859578763022307064317030903235196823302973152319271598841684324885625237030423977448610068847582315745648803893547950848775977888604054275196982524051414526965045483738781651554877828535198984557716599475979572917851219474771059404496356672662467552795811246938928548202179363916774439119111218984949582826015360298300266708147597580287967]A = [42, 104, 13, 106, 12]B = [338, 554, 768, 638, 548]
max_e = max(e)
Fs = []
for i in range(5): PR.<x> = PolynomialRing(Zmod(Ns[i])) f = (A[i] * x + B[i])^e[i] - Cs[i] f = f * x ^ (max_e - e[i]) f = f.monic() f = f.change_ring(ZZ) Fs.append(f)
F = crt(Fs,Ns)M = reduce(lambda x,y: x*y, Ns)FF = F.change_ring(Zmod(M))m = FF.monic().small_roots()[0]print(long_to_bytes(int(m)))
# b'NSSCTF{62e90a0e-c982-4a00-8ae9-eb493786a7d6}'NSSCTF工坊[RSA4] P8 m高位泄露
题目
from Crypto.Util.number import *
p = getPrime(512)q = getPrime(512)
flag = b'NSSCTF{******}'
n = p*qm = bytes_to_long(flag)
e = 3c = pow(m, e, n)
print(f'n = {n}')print(f'm = {m>>100}')print(f'c = {c}')
'''n = 1527542955109141740955682973826193262775892499957309448026045241470857728195657663426381459817190647872750820593934305392986732687654051540838628636529717414135863605586498459487983117670942529496973140251670874510207985224170313618738268651184582186637089407746738836054395760157095709388670653150429457223183161697730087281761369404956762102465246289770300941300936135728738323821631682286737786472020790680432476428922187234364341215016265407571963282147129157m = 2214226572250613833249705195927505959981823363137633354626532745196588970707c = 22113876206623661468496987580282614626160320529328454393375952035910523390370709980915981609422504775420007441257006956611997263223244837790238493516238723139514158563675396731542096229586616735753203254810465452822757959264870210654015436735165961713016222816604825816304606749448517022584926571828009062411578367333'''分析
小, 大部分高位泄露,设 ,则
reset()from Crypto.Util.number import long_to_bytes
k = 100n = 1527542955109141740955682973826193262775892499957309448026045241470857728195657663426381459817190647872750820593934305392986732687654051540838628636529717414135863605586498459487983117670942529496973140251670874510207985224170313618738268651184582186637089407746738836054395760157095709388670653150429457223183161697730087281761369404956762102465246289770300941300936135728738323821631682286737786472020790680432476428922187234364341215016265407571963282147129157mh = 2214226572250613833249705195927505959981823363137633354626532745196588970707mh = mh << kc = 22113876206623661468496987580282614626160320529328454393375952035910523390370709980915981609422504775420007441257006956611997263223244837790238493516238723139514158563675396731542096229586616735753203254810465452822757959264870210654015436735165961713016222816604825816304606749448517022584926571828009062411578367333e = 3
PRn.<x> = PolynomialRing(Zmod(n))f = (mh + x)^e - cf = f.monic()
roots = f.small_roots()print(roots)
for root in roots: root = int(root) print("\n[+] get root:", root) print("[*] m =", mh + root) print("[*]", long_to_bytes(mh + root))
"""[586224111363642075583459307645]
[+] get root: 586224111363642075583459307645[*] m = 2806865643354785581450142994351107732326351637470254633277360198619644201711450860255199207594318928228477[*] b'NSSCTF{688404a6-c408-4196-bc43-7f18317a9170}'"""NSSCTF工坊[RSA4] P9 把 的因数 当作模数
题目
from Crypto.Util.number import *
p = getPrime(512)q = getPrime(512)
flag = b'NSSCTF{******}'
n = p*qm = bytes_to_long(flag)
e = 65537c = pow(m, e, n)
print(f'n = {n}')print(f'p = {p>>100}')print(f'c = {c}')
'''n = 64335017257291288694879798080666629573501118113377179370850991421806469826103134483305987256497147128148330360834028920504233940886960965527818740354522230977284177508093687651712761343376265176857120577153061490788347779327206437787594150381508592990273475278503352979893670354730287704989079247190299342871p = 7550547038897825994210519739007596111285476244196123253081036462313916767780871742001683690783926938603422562506786339392389c = 63156227746402147833665215816432368072100003179308515827461336094419526246728847463629131014545663919689064970828884371592840335299717484415279040662500514230579275586231051576688620810169339105201465431624989678170362157914366609856305650090630980489686792938272599406165204410721499875713189193728688835223'''分析
和 的位数约为 的一半,利用*“给定 ,快速求出模某个 意义下较小的根,其中 ,是 的因数”*。 small_roots 时设 beta<.5
reset()from Crypto.Util.number import long_to_bytes
k = 100
e = 0x10001n = 64335017257291288694879798080666629573501118113377179370850991421806469826103134483305987256497147128148330360834028920504233940886960965527818740354522230977284177508093687651712761343376265176857120577153061490788347779327206437787594150381508592990273475278503352979893670354730287704989079247190299342871ph = 7550547038897825994210519739007596111285476244196123253081036462313916767780871742001683690783926938603422562506786339392389ph = ph << kc = 63156227746402147833665215816432368072100003179308515827461336094419526246728847463629131014545663919689064970828884371592840335299717484415279040662500514230579275586231051576688620810169339105201465431624989678170362157914366609856305650090630980489686792938272599406165204410721499875713189193728688835223
PRn.<x> = PolynomialRing(Zmod(n))
f = ph + xf = f.monic()
roots = f.small_roots(X = 2^k, beta = .4)print(roots)for root in roots: root = int(root) p = ph + root print("\n[+] get root:", root) if n % p != 0: print("[-] wrong answer") continue print("[*] p =", p) q = n // p phi = (p-1)*(q-1) d = int(pow(e, -1, phi)) m = int(pow(c, d, n)) print("[*]", long_to_bytes(m))"""[454816335479034891704851699843]
[+] get root: 454816335479034891704851699843[*] p = 9571455485910309291916917316888534528443339900073567672342627514933886471478666308857617873057362700447653818641726655818289650455563616992849737369983107[*] b'NSSCTF{36a5ae48-f281-4576-8d1f-acab0666bff2}'"""NSSCTF工坊[RSA4] P10 已知 d 低位,求 p, q
题目
from Crypto.Util.number import *
p = getPrime(512)q = getPrime(512)
flag = b'NSSCTF{******}'
n = p*qm = bytes_to_long(flag)
e = 7d = inverse(e, (p-1)*(q-1))c = pow(m, e, n)
print(f'n = {n}')print(f'd = {d&(2**410-1)}')print(f'c = {c}')
'''n = 156739515226635581524592797610847324418529702729659760727202454324501479907596255649349406182566636617352761983459648380669151952249526892078378572831346100444943020314226860094300911303589453661009834514243241261318188779118227457185670049393331570167726982038500849886842419000632840251465852441285715712609d = 1865327042408619801352057511348007441275330638921397637214779955824487081626289235627502761209800783644652914147540081431451c = 72260884070910873253619893714557327479300651539617744913822595501549980223259020597000998829262506949824325397279990912888752157554696212466966682483623575703479116305560808218806054242135099446883072418808228726774129042552815016924170283352225826854235696829480360844745488070927932843928843556296485306121'''分析
参考 phase 4: 已知 d 低位,求 p, q | Pion1eer
已知 的低 位,即已知
两边取
以 代替 ,化为单变量等式:
模意义下一元二次方程,解完可以得到
然后再利用 P9 解出完整的 即可
from Crypto.Util.number import long_to_bytes
n = 156739515226635581524592797610847324418529702729659760727202454324501479907596255649349406182566636617352761983459648380669151952249526892078378572831346100444943020314226860094300911303589453661009834514243241261318188779118227457185670049393331570167726982038500849886842419000632840251465852441285715712609dl = 1865327042408619801352057511348007441275330638921397637214779955824487081626289235627502761209800783644652914147540081431451c = 72260884070910873253619893714557327479300651539617744913822595501549980223259020597000998829262506949824325397279990912888752157554696212466966682483623575703479116305560808218806054242135099446883072418808228726774129042552815016924170283352225826854235696829480360844745488070927932843928843556296485306121
def get_p_low(): print("get_p_low") maybe_p_low = [] p = var('p') for k in range(1, 7+1): f = k * (n*p - p^2 - n + p) + p - 7*dl*p roots = solve_mod([f], 2^410) maybe_p_low += [int(root[0]) for root in roots] print(f"[+] k =", k,"\troots =", roots) print("maybe_p_low:", maybe_p_low)
maybe_p = [] for p_low in maybe_p_low: p = get_full_p(p_low) if p: maybe_p.append(p)
print(maybe_p)
for p in maybe_p: if n % p == 0: print("Found p:", p) return p
def get_full_p(p_low): PR.<x> = PolynomialRing(Zmod(n)) p = x * 2^410 + p_low - n roots = p.monic().small_roots(X = 2^(512-410), beta = .4) if roots: return int(p(roots[0])) return None
p = get_p_low()q = n // passert n == p * q
e = 7d = pow(e, -1, (p-1)*(q-1))
m = pow(c, d, n)long_to_bytes(m)
"""get_p_low[+] k = 1 roots = [][+] k = 2 roots = [][+] k = 3 roots = [(15782400274410125266299615039204687648239749624968048772538108316107834343510984483373502800953549213874615211388273835803,), (216175167833235042695566043002922999174165975344341575587144398195111696541111662186439526374789175117314044084502035159091,), (346310384669534424742257269055590207562442091107108658414862505953310729961666657395968108020811191637670221223899952987931,), (546703152228359342171523697019308519088368316826482185229468795832314592159267335099034131594646817541109650097013714311219,), (676838369064658724218214923071975727476644432589249268057186903590513625579822330308562713240668834061465827236411632140059,), (877231136623483641647481351035694039002570658308622794871793193469517487777423008011628736814504459964905256109525393463347,), (1007366353459783023694172577088361247390846774071389877699511301227716521197978003221157318460526476485261433248923311292187,), (1207759121018607941123439005052079558916772999790763404514117591106720383395578680924223342034362102388700862122037072615475,), (1337894337854907323170130231104746767305049115553530487341835698864919416816133676133751923680384118909057039261434990444315,), (1538287105413732240599396659068465078830975341272904014156441988743923279013734353836817947254219744812496468134548751767603,), (1668422322250031622646087885121132287219251457035671096984160096502122312434289349046346528900241761332852645273946669596443,), (1868815089808856540075354313084850598745177682755044623798766386381126174631890026749412552474077387236292074147060430919731,), (1998950306645155922122045539137517807133453798517811706626484494139325208052445021958941134120099403756648251286458348748571,), (2199343074203980839551311967101236118659380024237185233441090784018329070250045699662007157693935029660087680159572110071859,), (2329478291040280221598003193153903327047656139999952316268808891776528103670600694871535739339957046180443857298970027900699,), (2529871058599105139027269621117621638573582365719325843083415181655531965868201372574601762913792672083883286172083789223987,)][+] k = 4 roots = [][+] k = 5 roots = [][+] k = 6 roots = [][+] k = 7 roots = []maybe_p_low: [15782400274410125266299615039204687648239749624968048772538108316107834343510984483373502800953549213874615211388273835803, 216175167833235042695566043002922999174165975344341575587144398195111696541111662186439526374789175117314044084502035159091, 346310384669534424742257269055590207562442091107108658414862505953310729961666657395968108020811191637670221223899952987931, 546703152228359342171523697019308519088368316826482185229468795832314592159267335099034131594646817541109650097013714311219, 676838369064658724218214923071975727476644432589249268057186903590513625579822330308562713240668834061465827236411632140059, 877231136623483641647481351035694039002570658308622794871793193469517487777423008011628736814504459964905256109525393463347, 1007366353459783023694172577088361247390846774071389877699511301227716521197978003221157318460526476485261433248923311292187, 1207759121018607941123439005052079558916772999790763404514117591106720383395578680924223342034362102388700862122037072615475, 1337894337854907323170130231104746767305049115553530487341835698864919416816133676133751923680384118909057039261434990444315, 1538287105413732240599396659068465078830975341272904014156441988743923279013734353836817947254219744812496468134548751767603, 1668422322250031622646087885121132287219251457035671096984160096502122312434289349046346528900241761332852645273946669596443, 1868815089808856540075354313084850598745177682755044623798766386381126174631890026749412552474077387236292074147060430919731, 1998950306645155922122045539137517807133453798517811706626484494139325208052445021958941134120099403756648251286458348748571, 2199343074203980839551311967101236118659380024237185233441090784018329070250045699662007157693935029660087680159572110071859, 2329478291040280221598003193153903327047656139999952316268808891776528103670600694871535739339957046180443857298970027900699, 2529871058599105139027269621117621638573582365719325843083415181655531965868201372574601762913792672083883286172083789223987][12808244700891848571681229867945939151349649203736478559496534700297805628016283555802028490128990889103978707177718442769816734510420394810692765321412379, 12237392311510232207733315168168939306945753136553292583198371223481698647146588134299029434945831935900733541708388736093730289336504023586822354826680371]Found p: 12808244700891848571681229867945939151349649203736478559496534700297805628016283555802028490128990889103978707177718442769816734510420394810692765321412379b'NSSCTF{e5430ded-500c-4cc0-9bdb-b4e40a9be3a0}'"""NSSCTF工坊[RSA4] P11 Boneh and Durfee Attack
题目
from Crypto.Util.number import *
p = getPrime(512)q = getPrime(512)
flag = b'NSSCTF{******}'
n = p*qm = bytes_to_long(flag)
d = getPrime(int(1024*0.27))e = inverse(d, (p-1)*(q-1))c = pow(m, e, n)
print(f'n = {n}')print(f'e = {e}')print(f'c = {c}')
'''n = 160114502501162084436964583573537478796032975208003641998245321466054315024090626426576990670846673676284220472762005347545857048805279326218401844652650972020279579076862422448095751869541093396088035262462766840652498826036642824370917665518133929602675230369722990871966227199496065637730328810028624771799e = 45345940569506069958442629331605385637541863502889625766318025882612322508079296362452308633027956256763871699363730475762179734871820426435674201573024637206928394192742633431788159554008858191365192772486379417021387095234660386008405855409257903024187126197769938866986740500855322639995703897171982472409c = 54804574756729863920967159846060185937697266820658443964397350756668642051647933464063713653569896152539760694973280490768379727191709149635944250514794939902138783777815040318178431874892245462786377699958110644049375757179588739287406833915772871299296750059138805811112990483420256564588150314150915692126'''分析
由
估算得:
不满足 weiner attack 的条件
参考:
拿到新的板板
from Crypto.Util.number import *
N = 160114502501162084436964583573537478796032975208003641998245321466054315024090626426576990670846673676284220472762005347545857048805279326218401844652650972020279579076862422448095751869541093396088035262462766840652498826036642824370917665518133929602675230369722990871966227199496065637730328810028624771799e = 45345940569506069958442629331605385637541863502889625766318025882612322508079296362452308633027956256763871699363730475762179734871820426435674201573024637206928394192742633431788159554008858191365192772486379417021387095234660386008405855409257903024187126197769938866986740500855322639995703897171982472409c = 54804574756729863920967159846060185937697266820658443964397350756668642051647933464063713653569896152539760694973280490768379727191709149635944250514794939902138783777815040318178431874892245462786377699958110644049375757179588739287406833915772871299296750059138805811112990483420256564588150314150915692126"""Setting debug to true will display more informationsabout the lattice, the bounds, the vectors..."""debug = False
"""Setting strict to true will stop the algorithm (andreturn (-1, -1)) if we don't have a correctupperbound on the determinant. Note that thisdoesn't necesseraly mean that no solutionswill be found since the theoretical upperbound isusualy far away from actual results. That is whyyou should probably use `strict = False`"""strict = False
"""This is experimental, but has provided remarkable resultsso far. It tries to reduce the lattice as much as it canwhile keeping its efficiency. I see no reason not to usethis option, but if things don't work, you should trydisabling it"""helpful_only = Truedimension_min = 7 # stop removing if lattice reaches that dimension
############################################# Functions##########################################
# display stats on helpful vectorsdef helpful_vectors(BB, modulus): nothelpful = 0 for ii in range(BB.dimensions()[0]): if BB[ii, ii] >= modulus: nothelpful += 1
print(nothelpful, "/", BB.dimensions()[0], " vectors are not helpful")
# display matrix picture with 0 and Xdef matrix_overview(BB, bound): for ii in range(BB.dimensions()[0]): a = ('%02d ' % ii) for jj in range(BB.dimensions()[1]): a += '0' if BB[ii, jj] == 0 else 'X' if BB.dimensions()[0] < 60: a += ' ' if BB[ii, ii] >= bound: a += '~' print(a)
# tries to remove unhelpful vectors# we start at current = n-1 (last vector)def remove_unhelpful(BB, monomials, bound, current): # end of our recursive function if current == -1 or BB.dimensions()[0] <= dimension_min: return BB
# we start by checking from the end for ii in range(current, -1, -1): # if it is unhelpful: if BB[ii, ii] >= bound: affected_vectors = 0 affected_vector_index = 0 # let's check if it affects other vectors for jj in range(ii + 1, BB.dimensions()[0]): # if another vector is affected: # we increase the count if BB[jj, ii] != 0: affected_vectors += 1 affected_vector_index = jj
# level:0 # if no other vectors end up affected # we remove it if affected_vectors == 0: # print("* removing unhelpful vector", ii) BB = BB.delete_columns([ii]) BB = BB.delete_rows([ii]) monomials.pop(ii) BB = remove_unhelpful(BB, monomials, bound, ii - 1) return BB
# level:1 # if just one was affected we check # if it is affecting someone else elif affected_vectors == 1: affected_deeper = True for kk in range(affected_vector_index + 1, BB.dimensions()[0]): # if it is affecting even one vector # we give up on this one if BB[kk, affected_vector_index] != 0: affected_deeper = False # remove both it if no other vector was affected and # this helpful vector is not helpful enough # compared to our unhelpful one if affected_deeper and abs(bound - BB[affected_vector_index, affected_vector_index]) < abs( bound - BB[ii, ii]): # print("* removing unhelpful vectors", ii, "and", affected_vector_index) BB = BB.delete_columns([affected_vector_index, ii]) BB = BB.delete_rows([affected_vector_index, ii]) monomials.pop(affected_vector_index) monomials.pop(ii) BB = remove_unhelpful(BB, monomials, bound, ii - 1) return BB # nothing happened return BB
"""Returns:* 0,0 if it fails* -1,-1 if `strict=true`, and determinant doesn't bound* x0,y0 the solutions of `pol`"""
def boneh_durfee(pol, modulus, mm, tt, XX, YY): """ Boneh and Durfee revisited by Herrmann and May
finds a solution if: * d < N^delta * |x| < e^delta * |y| < e^0.5 whenever delta < 1 - sqrt(2)/2 ~ 0.292 """
# substitution (Herrman and May) PR.<u,x,y> = PolynomialRing(ZZ) Q = PR.quotient(x * y + 1 - u) # u = xy + 1 polZ = Q(pol).lift()
UU = XX * YY + 1
# x-shifts gg = [] for kk in range(mm + 1): for ii in range(mm - kk + 1): xshift = x ^ ii * modulus ^ (mm - kk) * polZ(u, x, y) ^ kk gg.append(xshift) gg.sort()
# x-shifts list of monomials monomials = [] for polynomial in gg: for monomial in polynomial.monomials(): if monomial not in monomials: monomials.append(monomial) monomials.sort()
# y-shifts (selected by Herrman and May) for jj in range(1, tt + 1): for kk in range(floor(mm / tt) * jj, mm + 1): yshift = y ^ jj * polZ(u, x, y) ^ kk * modulus ^ (mm - kk) yshift = Q(yshift).lift() gg.append(yshift) # substitution
# y-shifts list of monomials for jj in range(1, tt + 1): for kk in range(floor(mm / tt) * jj, mm + 1): monomials.append(u ^ kk * y ^ jj)
# construct lattice B nn = len(monomials) BB = Matrix(ZZ, nn) for ii in range(nn): BB[ii, 0] = gg[ii](0, 0, 0) for jj in range(1, ii + 1): if monomials[jj] in gg[ii].monomials(): BB[ii, jj] = gg[ii].monomial_coefficient(monomials[jj]) * monomials[jj](UU, XX, YY)
# Prototype to reduce the lattice if helpful_only: # automatically remove BB = remove_unhelpful(BB, monomials, modulus ^ mm, nn - 1) # reset dimension nn = BB.dimensions()[0] if nn == 0: print("failure") return 0, 0
# check if vectors are helpful if debug: helpful_vectors(BB, modulus ^ mm)
# check if determinant is correctly bounded det = BB.det() bound = modulus ^ (mm * nn) if det >= bound: # print("We do not have det < bound. Solutions might not be found.") # print("Try with highers m and t.") if debug: diff = (log(det) - log(bound)) / log(2) # print("size det(L) - size e^(m*n) = ", floor(diff)) if strict: return -1, -1 else: print("det(L) < e^(m*n) (good! If a solution exists < N^delta, it will be found)")
# display the lattice basis if debug: matrix_overview(BB, modulus ^ mm)
# LLL if debug: print("optimizing basis of the lattice via LLL, this can take a long time")
BB = BB.LLL()
if debug: print("LLL is done!")
# transform vector i & j -> polynomials 1 & 2 if debug: print("looking for independent vectors in the lattice") found_polynomials = False
for pol1_idx in range(nn - 1): for pol2_idx in range(pol1_idx + 1, nn): # for i and j, create the two polynomials PR.<w,z> = PolynomialRing(ZZ) pol1 = pol2 = 0 for jj in range(nn): pol1 += monomials[jj](w * z + 1, w, z) * BB[pol1_idx, jj] / monomials[jj](UU, XX, YY) pol2 += monomials[jj](w * z + 1, w, z) * BB[pol2_idx, jj] / monomials[jj](UU, XX, YY)
# resultant PR.<q> = PolynomialRing(ZZ) rr = pol1.resultant(pol2)
# are these good polynomials? if rr.is_zero() or rr.monomials() == [1]: continue else: # print("found them, using vectors", pol1_idx, "and", pol2_idx) found_polynomials = True break if found_polynomials: break
if not found_polynomials: # print("no independant vectors could be found. This should very rarely happen...") return 0, 0
rr = rr(q, q)
# solutions soly = rr.roots()
if len(soly) == 0: # print("Your prediction (delta) is too small") return 0, 0
soly = soly[0][0] ss = pol1(q, soly) solx = ss.roots()[0][0]
# return solx, soly
delta = .271 # this means that d < N^deltam = 8 # size of the lattice (bigger the better/slower)t = int((1 - 2 * delta) * m) # optimization from Herrmann and MayX = 2 * floor(N ^ delta) # this _might_ be too muchY = floor(N ^ (1 / 2)) # correct if p, q are ~ same sizeP.<x,y> = PolynomialRing(ZZ)A = int((N + 1) / 2)pol = 1 + x * (A + y)
solx, soly = boneh_durfee(pol, e, m, t, X, Y)
d = int(pol(solx, soly) / e)print(d)m = power_mod(c, d, N)print(long_to_bytes(m))