ecssp (crypto)
The Merkle-Hellman cryptosystem is broken, but what if I use it over elliptic curves?
This is the challenge code:
#!sage
from sage.all import EllipticCurve, GF
from Crypto.Util.number import bytes_to_long
flag = b'SSMCTF{REDACTED}'
#secp256k1
p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
a = 0
b = 7
E = EllipticCurve(GF(p),(a,b))
A = [E.random_point() for _ in range(42)]
enc = []
m = bin(bytes_to_long(flag))[2:]
m = m.zfill(len(m)//42*42+42) # makes the number of bits a multiple of 42
for i in range(0,len(m),42):
buffer = None
for j, bit in enumerate(m[i:i+42]):
# the buffer is the summation of points wherein j has a 1 bit
if bit == '1':
if not buffer:
buffer = A[j]
else:
buffer += A[j]
enc.append(buffer)
A = [i.xy() for i in A]
enc = [i.xy() for i in enc]
print(f'{A = }')
print(f'{enc = }')
Output:
A = [(114022552566672434287471812777717333762408551721791348889344472111227927502889, 91848347484952671316308675369245644465513610696925627817363786882910842914630), (5134235591147639910038981348618172041966754946151413595658689762008632417144, 3511794964597550219657005150446044437507191250164867133904557082591168200810), (7032886284728108699844541145867001038913067269804679108520652174728735284910, 23374784913016520963837121466288011654300981565362994781090990047581133995522), (64787929624393757911733465336546182797274948931237749247448226674433887764438, 100817994108392828748624813186243365302623148897918291171263241159232476705779), (61415319441662283644671806891506262708697273153238310958561291976566757851073, 47494855000112343060989722245396024127687216333344414084480138013856386400789), (31185225928020456074752113695930814394830270813864650049700325446839880436127, 98491843633049747320558494747016228169500900638949819454524008871199970848281), (61269037926178524499534355938680601447869226876831633887037654303319306902653, 7355959218752508692581981354345577329362806703629635457558186391126933065749), (46719743249477073536538523513876054148471856984109116152739306755928621137426, 79618227045878281991826536940081720008541694129455394111913396631045566145019), (71315609148455933583113137278156208113945683697681378464038731331649140453423, 41583976526604472993060418781265873641544347584287693599816935475869235033534), (34066985707582221727977428114751711145513492613331952008062524932064871300560, 9357963789875591485663090690843223368692879191592063080397524581806899989236), (112020015499791865542782141811688326015931444990628396652697052762093557415090, 97128953852476344478082470122398620436012998399897014560451651165696740697799), (42634390421337524463301787804160248224871449877456106839396316088983266777563, 36921893488724507975591286756011274949418646781286950314836583088947321399436), (109004872868473933843880334915627471365175851567444755103105745779429972062867, 10573682450940016830774151372886548289936213323569507701136657060721130866102), (24771770795854826019973902904410515550685645037907625865334744293267191703844, 238372343166032899435738271938582337808395959304176115681472003829671766069), (89898689270246478820497970612987341984775455104130834253057564247800138515216, 51361988465970660503417536945674893360422898646549654448056592592182179319322), (29353616892236794960022032235244696999870640837822460779312808945733127358965, 17189936243022410767965833508172954000235716444164810378420545005517265790590), (40907116228495544023560546056350488549701829492088999807726782859492817068142, 30600558861609828228122226133163256268226672743476940517404142980188899308141), (65595884403128634532554508209524238590976304321760189307800388865013736066122, 43739639766381874302525066091683537092274252516033766178153325330777753436173), (25248021323749208361083970171444517434971442331821340582052299954992625989433, 16433968721701929908034597638247694006984447527539174579327824152287410930927), (66637292000429090447834237361626051524039437607541033364971712194112098231001, 62897600570026652121263578113146768874909942153620854376802483617302774115980), (115212652540512582012577970245526787954210815528182926099395974524525631662162, 99777843108973546310076149803711850216390102688256655995359800874570043056555), (83878517831334008537079994787751658186104835789618280423583097526657039236116, 103511299944003266439173166120956421458183958407018392943008279310148901530099), (52594410772860121402953141618705939118615173192654401872197358793802093515001, 83405724211182079540236196795249163629897595215932404038528725584752940112891), (33065844213457587899962903396905924355762651943441569081451445513507319530855, 84459733639665926869498081695782057380035530851686381235158073488183035616786), (92852131344469309458360217477923144206844568659427057865288421289109253101850, 107983952221059675122423299705365141729775323231590366324267237436140008945947), (96029923597418235178467955471356574309551942895748993166823415663148665366818, 44009545809587730664603276939770224891921201461689182875991144734130730148132), (14491509301756702536461113822340540580917882458515619656898399058847358427165, 49697262878580453821093137648994944864996947361941635057840345229346592103325), (7142334457994882719662437060979343972591452514665838139143484105280906359843, 115551291934769872032845156599846422261691630966595375293712684039045331609773), (76199441895199959275724182330257364704683013310299613213681996128885039748856, 61818592218490595235086300654053309843951970828080818853139158729491555260528), (109929676816214299202831373205057089272383846164015783800295478396646698467323, 85603015167410332963621281121877119398125218999394242687621353796693626604814), (42085095747394420012437156518121954367239135800432273121845002452192659516043, 99152489145483114144014322676393985173394178769761002353396529032837553322954), (46785837870376203194490078015227240349998784412414091973301490669202030071274, 50158820599587084300110311636192802928718158911039536915016098936406858562516), (2542408287329394787358496421330518153382875002992489916936545569680393263826, 90960446941858157396519547124374187601195250590035308278734642699690186774134), (71104981300440345730027322716187483726593985627650490829854057008302951470953, 33514784920149980284990693642981138878817995455645608482499592830700653956566), (2219892059755913648923157677311647289191116275916201596356192006714889434836, 88618328428853723603356473619982882118747874012454061529636978281392148038263), (97178746971516087889535720327071518678118751045576788550771262246668598290172, 109805470081585872699137219689787905302272845563258748145297268263743508487479), (115534988340017196814212470995899778229858109387047371649837573529558387904853, 73561296050053000878918947216300173621080314170028964145490299232785134490670), (71020415564613394809479505654058314877327019326561551804364004670235803702823, 63721115749327971913307535980809347713258942827871762375911063350230411291154), (103525157991421687186695127818409910674944424344157107349452655919519635026348, 32688475822302762091357434289719114377166781834307639574849691681988225039970), (5087645535251679155915786583389386699946293717913736425888766550834106777832, 39404753198204781082643593694294372610894075291929137737571839372499106216263), (46869233779509670367924828352772167995400504169134812168319240561141370079721, 10556762214950234444787499536590640061428436758010737349806108326319636463365), (97699454395659998727515199878750545107706971087247916527908427481361566291361, 102405817218001246838012518871118424034120058607873164728157421470161986209902)]
enc = [(64790039097843726619666409283242777555003893618465502278317178757450138780247, 102844883231790621570884937608458381278419605840318534308920025637869951920685), (65467005106282061101664483249093359627045329274101984251422509764159888516782, 29577274831610547096769142678647481089072852714288000323692708023231117856259), (71126810596268579329235558066839193156863450492831082744027778860379767646458, 10061110158348361585582673111744600909320452001919882022692480289045281568038), (68130211277586543741700239238753266861237930181769784115771631347659811533995, 62916875538459760084037730097955290681027631961337350448937045279643828518377), (40739841185675326976137753552659542076873069897376020788702703621548466410384, 95505667868305009079261482128316557710057532847302718993997202290022214506067), (18113528668110280401511533074417338843730161007004980298553405689312187829593, 54549787510067678331569900262990828737439364417965444112678791347445057986509), (65785972692053719083883036722006292317181610120596386229948182706617388553330, 26925186146344157810917265671643490784806237827525588744976777335589847243551), (52049982563010361166332130366254990594595414206544311311954755536493054807189, 49859379427158965363993305038648217602616149186457294969786353267658272232018)]
It does the following:
Create a
secp256k1
curveCreate an array
A
containing 42 random points on the curveConverts the flag from a bytestring to a bitstring whose length is a multiple of 42
For each chunk of 42 bits in the flag, if bit
i
is1
then add the pointA[i]
tobuffer
. Otherwise do not add the point.Once all bits in the chunk are done, append the resultant point into
enc
Give
A
andenc
.
We can basically think of this as a knapsack cryptosystem, where each random point in A
is either added or not added into buffer
for every chunk.
We can start by trying to solve the problem for an individual chunk of 42 bits.
It would take too much time to calculate all possible chunk
values since there are 242 possible resultant points (because there are 42 random points in A, and each is either used or not used).
However, we can use a meet-in-the-middle approach:
For the first 21 points in
A
, we calculate all 221 possible results of point addition and have some dictionaryd1
storingpoint : bitstring
mappings where a given point can be produced by the associated bitstring. Note that 221=2097152 operations can be completed in a reasonable amount of time.We do the same for the last 21 points in
A
for dictionaryd2
.For every chunk we need to solve for, we have the encrypted point
p
. We iterate through the 221 entries ind1
. Then for each pointD
ind1
, we calculatex = p - D
. Ifx
is present ind2
then we know thatp = D + x
. This would imply that the point we are using fromd1
and the point we are using fromd2
exactly add up to our pointp
, which means that the bitstring we encrypted isd1[D]
+d2[x]
.
Repeating this for all chunks in enc
, we can retrieve the flag.
Below is my solve script (takes a few minutes to complete):
from sage.all import EllipticCurve, GF
from Crypto.Util.number import bytes_to_long, long_to_bytes
from tqdm import tqdm
#secp256k1
p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
a = 0
b = 7
E = EllipticCurve(GF(p),(a,b))
A = [(114022552566672434287471812777717333762408551721791348889344472111227927502889, 91848347484952671316308675369245644465513610696925627817363786882910842914630), (5134235591147639910038981348618172041966754946151413595658689762008632417144, 3511794964597550219657005150446044437507191250164867133904557082591168200810), (7032886284728108699844541145867001038913067269804679108520652174728735284910, 23374784913016520963837121466288011654300981565362994781090990047581133995522), (64787929624393757911733465336546182797274948931237749247448226674433887764438, 100817994108392828748624813186243365302623148897918291171263241159232476705779), (61415319441662283644671806891506262708697273153238310958561291976566757851073, 47494855000112343060989722245396024127687216333344414084480138013856386400789), (31185225928020456074752113695930814394830270813864650049700325446839880436127, 98491843633049747320558494747016228169500900638949819454524008871199970848281), (61269037926178524499534355938680601447869226876831633887037654303319306902653, 7355959218752508692581981354345577329362806703629635457558186391126933065749), (46719743249477073536538523513876054148471856984109116152739306755928621137426, 79618227045878281991826536940081720008541694129455394111913396631045566145019), (71315609148455933583113137278156208113945683697681378464038731331649140453423, 41583976526604472993060418781265873641544347584287693599816935475869235033534), (34066985707582221727977428114751711145513492613331952008062524932064871300560, 9357963789875591485663090690843223368692879191592063080397524581806899989236), (112020015499791865542782141811688326015931444990628396652697052762093557415090, 97128953852476344478082470122398620436012998399897014560451651165696740697799), (42634390421337524463301787804160248224871449877456106839396316088983266777563, 36921893488724507975591286756011274949418646781286950314836583088947321399436), (109004872868473933843880334915627471365175851567444755103105745779429972062867, 10573682450940016830774151372886548289936213323569507701136657060721130866102), (24771770795854826019973902904410515550685645037907625865334744293267191703844, 238372343166032899435738271938582337808395959304176115681472003829671766069), (89898689270246478820497970612987341984775455104130834253057564247800138515216, 51361988465970660503417536945674893360422898646549654448056592592182179319322), (29353616892236794960022032235244696999870640837822460779312808945733127358965, 17189936243022410767965833508172954000235716444164810378420545005517265790590), (40907116228495544023560546056350488549701829492088999807726782859492817068142, 30600558861609828228122226133163256268226672743476940517404142980188899308141), (65595884403128634532554508209524238590976304321760189307800388865013736066122, 43739639766381874302525066091683537092274252516033766178153325330777753436173), (25248021323749208361083970171444517434971442331821340582052299954992625989433, 16433968721701929908034597638247694006984447527539174579327824152287410930927), (66637292000429090447834237361626051524039437607541033364971712194112098231001, 62897600570026652121263578113146768874909942153620854376802483617302774115980), (115212652540512582012577970245526787954210815528182926099395974524525631662162, 99777843108973546310076149803711850216390102688256655995359800874570043056555), (83878517831334008537079994787751658186104835789618280423583097526657039236116, 103511299944003266439173166120956421458183958407018392943008279310148901530099), (52594410772860121402953141618705939118615173192654401872197358793802093515001, 83405724211182079540236196795249163629897595215932404038528725584752940112891), (33065844213457587899962903396905924355762651943441569081451445513507319530855, 84459733639665926869498081695782057380035530851686381235158073488183035616786), (92852131344469309458360217477923144206844568659427057865288421289109253101850, 107983952221059675122423299705365141729775323231590366324267237436140008945947), (96029923597418235178467955471356574309551942895748993166823415663148665366818, 44009545809587730664603276939770224891921201461689182875991144734130730148132), (14491509301756702536461113822340540580917882458515619656898399058847358427165, 49697262878580453821093137648994944864996947361941635057840345229346592103325), (7142334457994882719662437060979343972591452514665838139143484105280906359843, 115551291934769872032845156599846422261691630966595375293712684039045331609773), (76199441895199959275724182330257364704683013310299613213681996128885039748856, 61818592218490595235086300654053309843951970828080818853139158729491555260528), (109929676816214299202831373205057089272383846164015783800295478396646698467323, 85603015167410332963621281121877119398125218999394242687621353796693626604814), (42085095747394420012437156518121954367239135800432273121845002452192659516043, 99152489145483114144014322676393985173394178769761002353396529032837553322954), (46785837870376203194490078015227240349998784412414091973301490669202030071274, 50158820599587084300110311636192802928718158911039536915016098936406858562516), (2542408287329394787358496421330518153382875002992489916936545569680393263826, 90960446941858157396519547124374187601195250590035308278734642699690186774134), (71104981300440345730027322716187483726593985627650490829854057008302951470953, 33514784920149980284990693642981138878817995455645608482499592830700653956566), (2219892059755913648923157677311647289191116275916201596356192006714889434836, 88618328428853723603356473619982882118747874012454061529636978281392148038263), (97178746971516087889535720327071518678118751045576788550771262246668598290172, 109805470081585872699137219689787905302272845563258748145297268263743508487479), (115534988340017196814212470995899778229858109387047371649837573529558387904853, 73561296050053000878918947216300173621080314170028964145490299232785134490670), (71020415564613394809479505654058314877327019326561551804364004670235803702823, 63721115749327971913307535980809347713258942827871762375911063350230411291154), (103525157991421687186695127818409910674944424344157107349452655919519635026348, 32688475822302762091357434289719114377166781834307639574849691681988225039970), (5087645535251679155915786583389386699946293717913736425888766550834106777832, 39404753198204781082643593694294372610894075291929137737571839372499106216263), (46869233779509670367924828352772167995400504169134812168319240561141370079721, 10556762214950234444787499536590640061428436758010737349806108326319636463365), (97699454395659998727515199878750545107706971087247916527908427481361566291361, 102405817218001246838012518871118424034120058607873164728157421470161986209902)]
enc = [(64790039097843726619666409283242777555003893618465502278317178757450138780247, 102844883231790621570884937608458381278419605840318534308920025637869951920685), (65467005106282061101664483249093359627045329274101984251422509764159888516782, 29577274831610547096769142678647481089072852714288000323692708023231117856259), (71126810596268579329235558066839193156863450492831082744027778860379767646458, 10061110158348361585582673111744600909320452001919882022692480289045281568038), (68130211277586543741700239238753266861237930181769784115771631347659811533995, 62916875538459760084037730097955290681027631961337350448937045279643828518377), (40739841185675326976137753552659542076873069897376020788702703621548466410384, 95505667868305009079261482128316557710057532847302718993997202290022214506067), (18113528668110280401511533074417338843730161007004980298553405689312187829593, 54549787510067678331569900262990828737439364417965444112678791347445057986509), (65785972692053719083883036722006292317181610120596386229948182706617388553330, 26925186146344157810917265671643490784806237827525588744976777335589847243551), (52049982563010361166332130366254990594595414206544311311954755536493054807189, 49859379427158965363993305038648217602616149186457294969786353267658272232018)]
for i in range(42):
A[i] = E(A[i])
for j in range(len(enc)):
enc[j] = E(enc[j])
def gen_perms(i, mx):
if i == mx-1:
return {
A[i]:'1',
E(0):'0'
}
res = {}
z = gen_perms(i+1,mx)
for val,bitmask in z.items():
res[val+A[i]] = '1'+bitmask
res[val] = '0'+bitmask
return res
maps1 = gen_perms(0,21)
maps2 = gen_perms(21,42)
pt = ''
for enc_pt in tqdm(enc):
for val,bitmask in maps1.items():
v2 = enc_pt - val
if v2 in maps2.keys():
pt += bitmask
pt += maps2[v2]
break
print(pt)
flag = long_to_bytes(int(pt, 2))
print(flag) # SSMCTF{jus+_MITM_pr0bab1y_eas1er_th4n_LLL}
Last updated