summary: 利用pinv qinv分解n;利用多组e,c,恢复n
from Crypto.Util.number import *
from secret import flag
m = bytes_to_long(flag)
assert m.bit_length()<200
p = getPrime(512)
q = getPrime(512)
n = p*q
e = 3
c = pow(m, e, n)
kbits = 103
m = (m >> kbits) << kbits
Mod = getPrime(1024)
hint1 = (2021-2023*m) % Mod
hint2 = pow(2, 2023, Mod)
print('n =',n)
print('c =',c)
print('hint1 =',hint1)
print('hint2 =',hint2)
'''
n = 115383855234466224643769657979808398804254899116842846340552518876890834212233960206021018541117724144757264778086129841154749234706140951832603640953383528482125663673926452745186670807057426128028379664506531814550204605131476026038420737951652389070818761739123318769460392218629003518050621137961009397857
c = 5329266956476837379347536739209778690886367516092584944314921220156032648621405214333809779485753073093853063734538746101929825083615077
hint1 = 153580531261794088318480897414037573794615852052189508424770502825730438732573547598712417272036492121110446656514226232815820756435437665617271385368704576530324067841094570337328191161458300549179813432377043779779861066187597784486306748688798924645894867137996446960685210314180286437706545416961668988800
hint2 = 130939024886341321687705945538053996302793777331032277314813607352533647251650781154105954418698306293933779129141987945896277615656019480762879716136830059777341204876905094451068416223212748354774066124134473710638395595420261557771680485834288346221266495706392714094862310009374032975169649227238004805982
'''
e很小,e=3
c ≡ m e ( m o d n ) c\equiv m^e \pmod n\\ c≡me(modn)
直接开e次方,发现结果 151 bit
没用到hint
import gmpy2
from Crypto.Util.number import *
n = 115383855234466224643769657979808398804254899116842846340552518876890834212233960206021018541117724144757264778086129841154749234706140951832603640953383528482125663673926452745186670807057426128028379664506531814550204605131476026038420737951652389070818761739123318769460392218629003518050621137961009397857
c = 5329266956476837379347536739209778690886367516092584944314921220156032648621405214333809779485753073093853063734538746101929825083615077
hint1 = 153580531261794088318480897414037573794615852052189508424770502825730438732573547598712417272036492121110446656514226232815820756435437665617271385368704576530324067841094570337328191161458300549179813432377043779779861066187597784486306748688798924645894867137996446960685210314180286437706545416961668988800
hint2 = 130939024886341321687705945538053996302793777331032277314813607352533647251650781154105954418698306293933779129141987945896277615656019480762879716136830059777341204876905094451068416223212748354774066124134473710638395595420261557771680485834288346221266495706392714094862310009374032975169649227238004805982
e=3
m=gmpy2.iroot(c,e)
print(int(m[0]).bit_length())
flag= long_to_bytes(int(m[0]))
print(flag)
#151
b'NSSCTF{Rea1_Si9n3n}'
没想到,是古典
然后根据上文恢复的部分,猜测出剩余部分
from secret import flag
from Crypto.Util.number import *
import gmpy2
length = len(flag)
flag1 = flag[:length//2]
flag2 = flag[length//2:]
e = 65537
m1 = bytes_to_long(flag1)
p = getPrime(512)
q = getPrime(512)
n = p*q
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)
p1 = gmpy2.invert(p,q)
q1 = gmpy2.invert(q,p)
c = pow(m1,e,n)
print("p1=",p1)
print("q1=",q1)
print("c=",c)
print("phi=",phi)
"""
p1= 3020925936342826638134751865559091272992166887636010673949262570355319420768006254977586056820075450411872960532347149926398408063119965574618417289548987
q1= 4671408431692232396906683283409818749720996872112784059065890300436550189441120696235427299344866325968178729053396743472242000658751114391777274910146291
c= 25112054943247897935419483097872905208058812866572413543619256987820739973912338143408907736140292730221716259826494247791605665059462509978370784276523708331832947651238752021415405546380682507724076832547566130498713598421615793975775973104012856974241202142929158494480919115138145558312814378701754511483
phi= 57503658815924732796927268512359220093654065782651166474086873213897562591669139461637657743218269483127368502067086834142943722633173824328770582751298229218384634668803018140064093913557812104300156596305487698041934061627496715082394633864043543838906900101637618600513874001567624343801197495058260716932
"""
m2 = bytes_to_long(flag2)
p = getPrime(1024)
q = getPrime(1024)
n = p * q
c = pow(m2, e, n)
hint = pow(2023 * p + 114514, q, n)
print("n=",n)
print("c=",c)
print("hint=",hint)
"""
n= 12775720506835890504634034278254395430943267336816473660983646973423280986156683988190224391394224069040565587173690009193979401332176772774003070053150665425296356891182224095151626957780349726980433545162004592720236315207871365869074491602494662741551613634958123374477023452496165047922053316939727488269523121920612595228860205356006298829652664878874947173274376497334009997867175453728857230796230189708744624237537460795795419731996104364946593492505600336294206922224497794285687308908233911851722675754289376914626682400586422368439122244417279745706732355332295177737063024381192630487607768783465981451061
c= 11915755246503584850391275332434803210208427722294114071001100308626307947436200730224125480063437044802693983505018296915205479746420176594816835977233647903359581826758195341201097246092133133080060014734506394659931221663322724002898147351352947871411658624516142945817233952310735792476179959957816923241946083918670905682025431311942375276709386415064702578261223172000098847340935816693603778431506315238612938066215726795441606532661443096921685386088202968978123769780506210313106183173960388498229061590976260661410212374609180449458118176113016257713595435899800372393071369403114116302366178240855961673903
hint= 3780943720055765163478806027243965253559007912583544143299490993337790800685861348603846579733509246734554644847248999634328337059584874553568080801619380770056010428956589779410205977076728450941189508972291059502282197067064652703679207594494311426932070873126291964667101759741689303119878339091991064473009603015444698156763131697516348762529243379294719509271792197450290763350043267150173332933064667716343268081089911389405010661267902446894363575630871542572200564687271311946580866369204751787686029541644463829030926902617740142434884740791338666415524172057644794094577876577760376741447161098006698524808
"""
flag分两个部分
flag1
p->512素数
q->512素数
n = p*q
n = p ∗ q p 1 ∗ p ≡ 1 ( m o d q ) q 1 ∗ q ≡ 1 ( m o d p ) n = p*q\\ p1 *p\equiv 1 \pmod q\\q1 *q\equiv 1 \pmod p\\ n=p∗qp1∗p≡1(modq)q1∗q≡1(modp)
flag2
p = getPrime(1024)
q = getPrime(1024)
h i n t ≡ ( 2023 ∗ p + 114514 ) q ( m o d n ) h i n t ≡ ( 2023 ∗ p + 114514 ) q ( m o d p ) h i n t ≡ ( 114514 ) q ( m o d p ) ( 114514 ) n ≡ ( 114514 ) q ∗ p ≡ ( ( 114514 ) q ) p ≡ ( 114514 ) q ( m o d p ) h i n t ≡ ( 114514 ) n ( m o d p ) h i n t − ( 114514 ) n ≡ 0 ( m o d p ) h i n t − ( 114514 ) n = k ∗ p n = q ∗ p p = g c d ( n , h i n t − ( 114514 ) n ) hint \equiv (2023 * p + 114514)^ q \pmod n\\ hint \equiv(2023 * p + 114514)^ q \pmod p\\ hint \equiv( 114514)^ q \pmod p\\( 114514)^ n\equiv ( 114514)^ {q* p}\equiv (( 114514)^ {q})^ {p}\equiv( 114514)^ {q}\pmod p\\hint\equiv ( 114514)^ n\pmod p\\hint-( 114514)^ n\equiv 0 \pmod p\\hint-( 114514)^ n=k* p\\n=q*p\\p=gcd(n,hint-( 114514)^ n) hint≡(2023∗p+114514)q(modn)hint≡(2023∗p+114514)q(modp)hint≡(114514)q(modp)(114514)n≡(114514)q∗p≡((114514)q)p≡(114514)q(modp)hint≡(114514)n(modp)hint−(114514)n≡0(modp)hint−(114514)n=k∗pn=q∗pp=gcd(n,hint−(114514)n)
p1= 3020925936342826638134751865559091272992166887636010673949262570355319420768006254977586056820075450411872960532347149926398408063119965574618417289548987
q1= 4671408431692232396906683283409818749720996872112784059065890300436550189441120696235427299344866325968178729053396743472242000658751114391777274910146291
c= 25112054943247897935419483097872905208058812866572413543619256987820739973912338143408907736140292730221716259826494247791605665059462509978370784276523708331832947651238752021415405546380682507724076832547566130498713598421615793975775973104012856974241202142929158494480919115138145558312814378701754511483
phi= 57503658815924732796927268512359220093654065782651166474086873213897562591669139461637657743218269483127368502067086834142943722633173824328770582751298229218384634668803018140064093913557812104300156596305487698041934061627496715082394633864043543838906900101637618600513874001567624343801197495058260716932
import gmpy2
from itertools import product
import binascii
from Crypto.Util.number import *
"""
alpha = p' * q' - l
beta = l^2 * [(e * d - 1) / s] + q' * l + p' * l - p' * q' - alpha - l^2
i.e.:
beta = l^2 * {[(e * d - 1) / s] - 1} + l * (q' + p') - alpha - p' * q'
if l,s are correct:
alpha = k * t
beta = k * (p' - l) + t * (q' - l)
i.e:
"""
def alpha_from_pprime_qprime_l(pprime, qprime, l):
return pprime * qprime - l
def beta_from_pprime_qprime_e_d_l_s_alpha(pprime, qprime, e, d, l, s, alpha):
temp1 = e * d - 1
assert temp1 % s == 0
temp2 = ((temp1 // s) - 1) * l * l
temp3 = temp2 + l * (pprime + qprime)
return temp3 - alpha - (pprime * qprime)
def k_t_from_pprime_qprime_l_alpha_beta(pprime, qprime, l, alpha, beta):
a = pprime - l
b = -beta
c = alpha * (qprime - l)
disc = b * b - 4 * a * c
assert gmpy2.is_square(disc)
temp = -b + gmpy2.isqrt(disc)
assert temp % (2 * a) == 0
k = temp // (2 * a)
assert alpha % k == 0
return k, alpha // k
def brute_k_t_l(pprime, qprime, e, d):
# l, s = 2, 2
ss = [s for s in range(e - 100000, e + 1000000) if s != 0 and (e * d - 1) % s == 0]
for l, s in product(range(1, 5000), ss):
# print(f'l = {l}, s = {s}')
try:
alpha = alpha_from_pprime_qprime_l(pprime, qprime, l)
beta = beta_from_pprime_qprime_e_d_l_s_alpha(pprime, qprime, e, d, l, s, alpha)
k, t = k_t_from_pprime_qprime_l_alpha_beta(pprime, qprime, l, alpha, beta)
return k, t, l
except AssertionError:
continue
if __name__ == "__main__":
e = 65537
p1 = 3020925936342826638134751865559091272992166887636010673949262570355319420768006254977586056820075450411872960532347149926398408063119965574618417289548987
q1 = 4671408431692232396906683283409818749720996872112784059065890300436550189441120696235427299344866325968178729053396743472242000658751114391777274910146291
phi= 57503658815924732796927268512359220093654065782651166474086873213897562591669139461637657743218269483127368502067086834142943722633173824328770582751298229218384634668803018140064093913557812104300156596305487698041934061627496715082394633864043543838906900101637618600513874001567624343801197495058260716932
d = gmpy2.invert(e, phi)
pprime = q1
qprime = p1
k, t, l = brute_k_t_l(pprime, qprime, e, d)
lp, lq = qprime + k, pprime + t
assert lp % l == 0, lq % l == 0
p, q = lp // l, lq // l
assert gmpy2.invert(p, q) == pprime, gmpy2.invert(q, p) == qprime
assert gmpy2.is_prime(p), gmpy2.is_prime(q)
N = p * q
c= 25112054943247897935419483097872905208058812866572413543619256987820739973912338143408907736140292730221716259826494247791605665059462509978370784276523708331832947651238752021415405546380682507724076832547566130498713598421615793975775973104012856974241202142929158494480919115138145558312814378701754511483
flag1 = pow(c, d, N)
print(long_to_bytes(flag1))
#b'NSSCTF{e713afa4-fcd8-4'
from Crypto.Util.number import *
e = 65537
#hint = pow(2023 * p + 114514, q, n)
n= 12775720506835890504634034278254395430943267336816473660983646973423280986156683988190224391394224069040565587173690009193979401332176772774003070053150665425296356891182224095151626957780349726980433545162004592720236315207871365869074491602494662741551613634958123374477023452496165047922053316939727488269523121920612595228860205356006298829652664878874947173274376497334009997867175453728857230796230189708744624237537460795795419731996104364946593492505600336294206922224497794285687308908233911851722675754289376914626682400586422368439122244417279745706732355332295177737063024381192630487607768783465981451061
c= 11915755246503584850391275332434803210208427722294114071001100308626307947436200730224125480063437044802693983505018296915205479746420176594816835977233647903359581826758195341201097246092133133080060014734506394659931221663322724002898147351352947871411658624516142945817233952310735792476179959957816923241946083918670905682025431311942375276709386415064702578261223172000098847340935816693603778431506315238612938066215726795441606532661443096921685386088202968978123769780506210313106183173960388498229061590976260661410212374609180449458118176113016257713595435899800372393071369403114116302366178240855961673903
hint= 3780943720055765163478806027243965253559007912583544143299490993337790800685861348603846579733509246734554644847248999634328337059584874553568080801619380770056010428956589779410205977076728450941189508972291059502282197067064652703679207594494311426932070873126291964667101759741689303119878339091991064473009603015444698156763131697516348762529243379294719509271792197450290763350043267150173332933064667716343268081089911389405010661267902446894363575630871542572200564687271311946580866369204751787686029541644463829030926902617740142434884740791338666415524172057644794094577876577760376741447161098006698524808
h2 = pow(114514, n, n)
q = GCD(hint-h2, n)
# print(q)
p = n // q
d = inverse(e, (p-1)*(q-1))
m = pow(c, d, n)
print(long_to_bytes(m))
#b'19f-a1a6-959449b4df5a}'
b'NSSCTF{e713afa4-fcd8-419f-a1a6-959449b4df5a}'
from Crypto.Util.number import *
flag = b'NSSCTF{******************************}'
a = getPrime(512)
seed = getPrime(512)
b = bytes_to_long(flag)
n = getPrime(1024)
e1 = 2333
e2 = 23333
c1 = pow(a,e1,n)
c2 = pow(a,e2,n)
output = []
for i in range(10):
seed = (a*seed+b)%n
output.append(seed)
print("c1 = ",c1)
print("c2 = ",c2)
print("output1 = ",output[0])
print("output2 = ",output[1])
e = [getPrime(128) for _ in range(20)]
out = []
m = getPrime(64)
for i in e:
out.append(pow(m,i,n))
print("e=",e)
print("out=",out)
"""
c1 = 132894829064255831243210470637067717685821770359549730768366345840525257033166172926149293454192143005551270166547902269036843756318967855047301751521125394803373953151753927497701242767032542708689455184991906629946511295108898559666019232955132938245031352553261823905498810285940911315433144300083027795647
c2 = 24086830909813702968855830967174364278115647345064163689290457852025690324300607354444884288995399344650789235347773145941872226843099538451759854505842021844881825309790171852845467221751852440178862638893185965125776165397575087879479327323737686652198357863042305078811580074617322063509435591981140533310
output1 = 54997286032365904331111467760366122947903752273328087460831713533712307510311367648330090376100815622160705007873798883153287827481112070182047111994066594911019010222064952859306742931009422376955635523160546531204043294436812066746785938062292942759004837173423765427628610568097898331237064396308950601636
output2 = 115015764780168428067411132384122324817310808727138440691727747976276050930701648349452842302609389394467134068064132550313721128807222231505312226682756817617177620169804112319332815872107656884931985435898097063491690413460967856530075292289784649593915313885813931026280791070577034075346669028068003251024
e= [297332330847212015073434001239859795661, 247136911662054641479463124065475615181, 269964458627145370722389742095701827701, 270745917671094194052444327351021588037, 254010082507930275771798119457499420531, 219178601856077385518322602059961601013, 226562702503988968288128483964146379529, 236756812424464516919183114495913408541, 330800121752029915693039296018980956519, 244800084005240595691424199440981715431, 171753849214889522920105847094773384191, 175843874533972361422410968920873382741, 326554577162848075059517044795930784993, 181842368629269753698222635712342485771, 221634122983362091660188171985742369561, 314244561819808202322467576330355199409, 286703236198397527318161582654787197007, 298101543059628501506668748374542117409, 304158884506393754601331945634109778837, 227577031261920314010408499530794497453]
out= [100163998802948218573427220530909801629443946118807841130458771881611961921044413091457977957530737347507311468578174294420439883266450142918647561103714976340598499984679873518770686239019753272419975426555435266764099822607336645955391865380657632176223122712125661464370522088500110746571354290680063421912, 123528268396018633078964378145622645321836134964966941909300627704018826667414656614011250938241127521627117348901416042868382174504514240509791471909819407751786633761392047187057200130450960708049681366686147337178110669163142189940397343388837018627392202704211693014162963133958078984558400205296509955066, 50364974727218716170137342348825758682286710377257708196467656986986475658591351848251278364177715325447140300281348027787487944839878770556527568407280736570303345044999352851718908253510696083227344179177110348363623815158409862985684687329665113210373028159714648637297476014803935686233984711925346269925, 9159042298258514259206302054907530984498816597282237786310355131965025367180505822032135021520906576471052417629425493533222088036674196397387325202128095476044308794426593565419139845832998557280786358482011226957053125314152322427131984411160984485669030286331376124575677908877399942011661647598763754231, 83466948172962290899792524342204996697711370224947233607865306692546824512672969402433314856742908546253967225963904395036102408684746619744412073888614033881366518452878344698289278946024167788789718690655953517892282374396760436658422838909903123439370164929347147855359470889455753772857233516742991766128, 72028057477369331020972407277180913909557985390590548305094935208898254733240351763155769013959589016793318772858662702447133499307826143247356049051993727167694036585280387890126287679890730586145740176250715386149857291210207281073772478229355625725300592003798974298248102432508449566953296818450441875311, 63397152736399466888877444377156185012692670493456346196278062009641363047685720620967313379507212944658351683022480839941265221126018392433078546696140135677499181555082643172378488800458657825640013090182171355299282023794908520172571785687147143015581400891531296496177973817400317905868361800342940667657, 45427004823510815929685208038284324980662968275105063862891077759131069014314933978878667052450145039482242546093735499108826130367476890384431317243013990394189191560941678120985717370542332803012619694821129395559214706968432476548145608291516176910849698455496733056096163035964057523545705356926187216133, 85046100612081858546755294340770681541320509587396377967875404950325314121709046137842413744740490231945105758075761946555179595664901813127463402854440384657046429776033129391138370272524736543471909307910018577738207910417672603889922445435939876023878220177983424547612635006926243055642166274730894301704, 5833380233103086014860892228744764647016585478949686583145531659689295506666493518453642500086277427538189091865461553097914845680665917702500908205558454036911757659426809969367680394533585635383007758339917554453268182491874683638880986360065633842854622244953985055815937671635222264056071882344388307409, 83587615309194701727032548415548847571046191382552371312058083137102227325098839286526833147951063338204327145093831238962818333112251936853329663907079943414231588222256242520221314528944937229985997926851198158564313703719031124442094987245466116488897263358510493905440842917634723859176839440753120904481, 108651960334634726889543063749359050688114025706494125848785084643330096858725917513596985853593252388835207675036982640195609499739937405655156895161071906340785173459426867946058638393154997931747445494284445204735492709747637173698383609764016673932827648159152658645291248613736662020472251048171789274368, 118612010487916657134965416492319303083994743753602531817008130269546146141506819718265549648441671373744766173780682168587021797626910931105508317440664521595783406848956221465897709761805869130021172013000282497881581247777388315282629463546261696169893882772397797722134711444928443061384985458691749569847, 106808406616890955924408992591724627593882118490933791849624747503316110669154243209826761617940864170830792705070618439466645580274835929100331418955890808763286193770831205511071440703609240364726061677822134370309018443508205980554831705850988319397384130044484586798585896460152167042282847992593429629533, 88091869606421350393441194783722851111189272445506506936925797213395319937783082680078622732926273935980894566775394134783157488360516905477700601820480975112122167589887641130656305741351643175495552454293030309247254533571254198691204714097846510872592569447050033289483493274672346210063885124570695832880, 94400859500860667431780782962782396345261822402898708716634581228428633704975879685572548692997007974004673676539496590659276952154740096463133011458100387006276325192223993452314873089466451613079029429327880672384210802191677586975844471189127835578979108767548290181668434770385199468588493042256788539610, 76177813724283720012398394789596589415486093955132688784865364048503447246391866424200071522136707581280434193680972230914105236504028522288780213089260160776489804587209115330412067560802680789338779056583047491942817016437672075192528508677997165703606520158178725128251694801612417667440677124932361973397, 17188209523466762369281362386525396145127294763502094183797065621821932913685690176344514910405677170931795652509426794846131051983826422536084073462084935517166603832542862106287058675490933197600813710203114108790043880150305327523679949543592622443904084453387396870899883324751789625806819506542619123964, 120007173989070249117019147454557020213723707722383599019972471016186584968096445904023372671513462965078400715365736756710078805039115601609874780421117795585342458478316236202328120583456334489780231976628584606042971207759763658961365139429661536955996519512283283500790612975034779837647053750631763512799, 18797057418663411295612229938999282286746920748194349166509084258061650142260043277698907538088835210620841171754186980908772147495732980563542600139935202965632319542217264685208215907551992891370166006725534397313373079841419662622936316343820775075897977228084528246337988431658221881343556854053475137330]
"""
题目很简单
n = 1024 素数 s e e d = ( a ∗ s e e d + b ) ( m o d n ) 已知两个 o u t p u t 恢复 a , n ,即可求出 b ( f l a g ) n = 1024素数\\seed = (a*seed+b)\pmod n\\已知两个output\\恢复a,n,即可求出b(flag)\\ n=1024素数seed=(a∗seed+b)(modn)已知两个output恢复a,n,即可求出b(flag)
恢复n
o u t i ≡ m e i ( m o d n ) 已知多组 o u t , e , 恢复 n out_i \equiv m^{e_i} \pmod n\\已知多组out,e,恢复n outi≡mei(modn)已知多组out,e,恢复n
已知多组out,e,恢复n
方法一:(正交格求n)
A = [ e 0 , e 1 , . . . , e i ] M = [ e e 0 , e e 1 , . . . , e e i ] M T ∗ A = 0 o u t i e e i ≡ m e i ∗ e e i ( m o d n ) o u t 0 e e 0 + o u t 1 e e 1 + . . . + o u t i e e i ≡ m e 0 ∗ e e 0 + m e 1 ∗ e e 1 + . . . + m e i ∗ e e i ≡ m e 0 ∗ e e 0 + e 1 ∗ e e 1 + . . . e i ∗ e e i ≡ 1 ( m o d n ) = 1 + k ∗ n A=[e_0,e_1,...,e_i]\\ M=[ee_0,ee_1,...,ee_i]\\ M^T*A=0\\out_i^{ee_i} \equiv m^{e_i*ee_i} \pmod n\\out_0^{ee_0}+out_1^{ee_1}+...+out_i^{ee_i}\\ \equiv m^{e_0*ee_0} +m^{e_1*ee_1}+... +m^{e_i*ee_i} \\\equiv m^{e_0*ee_0+e_1*ee_1+... e_i*ee_i} \equiv 1\pmod n=1+k*n A=[e0,e1,...,ei]M=[ee0,ee1,...,eei]MT∗A=0outieei≡mei∗eei(modn)out0ee0+out1ee1+...+outieei≡me0∗ee0+me1∗ee1+...+mei∗eei≡me0∗ee0+e1∗ee1+...ei∗eei≡1(modn)=1+k∗n
将指数分组(按照ee的正负分)
正指数 p e i 负指数 n e i o u t 0 e e 0 + o u t 1 e e 1 + . . . + o u t i e e i ≡ o u t 0 n e 0 + o u t 1 n e 1 + . . . + o u t i p e i − 1 + o u t i p e i ≡ L e f t / / R i g h t ≡ 1 ( m o d n ) L e f t ≡ R i g h t ( m o d n ) L e f t t − R i g h t ≡ 0 ( m o d n ) L e f t − R i g h t = k ∗ n 正指数pe_i \\负指数 ne_i\\out_0^{ee_0}+out_1^{ee_1}+...+out_i^{ee_i}\\\equiv out_0^{ne_0}+out_1^{ne_1}+...+out_i^{pe_{i-1}}+out_i^{pe_i}\\ \equiv Left//Right \equiv 1 \pmod n\\Left\equiv Right\pmod n\\Leftt- Right\equiv0\pmod n\\Left- Right=k* n\\ 正指数pei负指数neiout0ee0+out1ee1+...+outieei≡out0ne0+out1ne1+...+outipei−1+outipei≡Left//Right≡1(modn)Left≡Right(modn)Leftt−Right≡0(modn)Left−Right=k∗n
多组Lift- Right=k* n,求gcd,可得n
方法二:(思路差不多,代码简单)
G = [ e 0 ∗ 2 2048 1 0 ⋯ 0 e 1 ∗ 2 2048 0 1 ⋯ 0 ⋮ ⋮ ⋮ ⋱ ⋮ e i ∗ 2 2048 0 0 ⋯ 1 ] G=\begin{bmatrix} e_0*2^{2048}&1 & 0&\cdots & 0 \\ e_1*2^{2048}&0 &1 &\cdots & 0 \\ \vdots &\vdots &\vdots&\ddots & \vdots \\ e_i*2^{2048}&0 &0 & \cdots & 1 \\ \end{bmatrix} \\ G= e0∗22048e1∗22048⋮ei∗2204810⋮001⋮0⋯⋯⋱⋯00⋮1
[ e e 0 , e e 1 , . . . , e e i ] ∗ G = [ 0 , e e 0 , e e 1 , . . . , e e i ] [ee_0,ee_1,...,ee_i]*G=[0,ee_0,ee_1,...,ee_i] [ee0,ee1,...,eei]∗G=[0,ee0,ee1,...,eei]
将指数分组(按照 e e 的正负分) : 正指数 p e i , 负指数 n e i o u t 0 e e 0 + o u t 1 e e 1 + . . . + o u t i e e i ≡ o u t 0 n e 0 + o u t 1 n e 1 + . . . + o u t i p e i − 1 + o u t i p e i ≡ L e f t / / R i g h t ≡ 1 ( m o d n ) L e f t ≡ R i g h t ( m o d n ) L e f t − R i g h t ≡ 0 ( m o d n ) L e f t − R i g h t = k ∗ n 将指数分组(按照ee的正负分):\\正指数pe_i ,负指数 ne_i\\out_0^{ee_0}+out_1^{ee_1}+...+out_i^{ee_i}\\\equiv out_0^{ne_0}+out_1^{ne_1}+...+out_i^{pe_{i-1}}+out_i^{pe_i}\\ \equiv Left//Right \equiv 1 \pmod n\\Left\equiv Right\pmod n\\Left- Right\equiv0\pmod n\\Left- Right=k* n\\ 将指数分组(按照ee的正负分):正指数pei,负指数neiout0ee0+out1ee1+...+outieei≡out0ne0+out1ne1+...+outipei−1+outipei≡Left//Right≡1(modn)Left≡Right(modn)Left−Right≡0(modn)Left−Right=k∗n
es = e
cs = out
from Crypto.Util.number import *
#将e转成矩阵
L = matrix(es).T.augment(matrix.identity(len(es)))
L[:, 0] *= 2 ^ 2048
L = L.LLL()
print(L[0][1:])
print(L[1][1:])
#xx:第一组所有out^e的乘积 ,xx.numer()(分子left) - xx.denom()(分母right)
#yy:第2组所有out^e的乘积
xx = product([ZZ(y) ^ x for x, y in zip(L[0][1:], cs)])
yy = product([ZZ(y) ^ x for x, y in zip(L[1][1:], cs)])
n = gcd(xx.numer() - xx.denom(), yy.numer() - yy.denom())
print(n)
共模攻击,求a
c 1 ≡ a e 1 ( m o d n ) c 2 ≡ a e 2 ( m o d n ) c1 \equiv a^{e1}\pmod n\\ c2 \equiv a^{e2}\pmod n\\ c1≡ae1(modn)c2≡ae2(modn)
共模攻击
e 1 ∗ s 1 + e 2 ∗ s 2 = g c d ( e 1 , e 2 ) = 1 c 1 s 1 ≡ a e 1 ∗ s 1 ( m o d n ) c 2 s 2 ≡ a e 2 ∗ s 2 ( m o d n ) c 1 s 1 ∗ c 2 s 2 ≡ a e 1 ∗ s 1 ∗ a e 2 ∗ s 2 ≡ a e 1 ∗ s 1 + e 2 ∗ s 2 ≡ a ( m o d n ) s 1 , s 2 拓展欧几里得可求出 e1*s1+e2*s2=gcd(e1,e2)=1\\c1^{s_1} \equiv a^{e1*s1}\pmod n\\ c2^{s_2} \equiv a^{e2*s2}\pmod n\\ c1^{s_1}*c2^{s_2} \equiv a^{e1*s1}*a^{e2*s2}\\ \equiv a^{e1*s1+e2*s2}\equiv a\pmod n\\s_1,s_2拓展欧几里得可求出 e1∗s1+e2∗s2=gcd(e1,e2)=1c1s1≡ae1∗s1(modn)c2s2≡ae2∗s2(modn)c1s1∗c2s2≡ae1∗s1∗ae2∗s2≡ae1∗s1+e2∗s2≡a(modn)s1,s2拓展欧几里得可求出
import gmpy2
#共模攻击
def rsa_gong_N_def(e1,e2,c1,c2,n):
e1, e2, c1, c2, n=int(e1),int(e2),int(c1),int(c2),int(n)
print("e1,e2:",e1,e2)
print(gmpy2.gcd(e1,e2))
s = gmpy2.gcdext(e1, e2)
print(s)
s1 = s[1]
s2 = s[2]
if s1 < 0:
s1 = - s1
c1 = gmpy2.invert(c1, n)
elif s2 < 0:
s2 = - s2
c2 = gmpy2.invert(c2, n)
#e1,e2互质
if gmpy2.gcd(e1, e2) == 1:
m= pow(c1, s1, n) * pow(c2, s2, n) % n
#e1,e2不互质
elif gmpy2.gcd(e1, e2) != 1:
m= pow(c1, s1, n) * pow(c2, s2, n) % n
common_e = gmpy2.gcd(e1, e2)
m = (gmpy2.iroot(m, common_e)[0])
print(m)
return int(m)
e1 = 2333
e2 = 23333
c1 = 132894829064255831243210470637067717685821770359549730768366345840525257033166172926149293454192143005551270166547902269036843756318967855047301751521125394803373953151753927497701242767032542708689455184991906629946511295108898559666019232955132938245031352553261823905498810285940911315433144300083027795647
c2 = 24086830909813702968855830967174364278115647345064163689290457852025690324300607354444884288995399344650789235347773145941872226843099538451759854505842021844881825309790171852845467221751852440178862638893185965125776165397575087879479327323737686652198357863042305078811580074617322063509435591981140533310
output1 = 54997286032365904331111467760366122947903752273328087460831713533712307510311367648330090376100815622160705007873798883153287827481112070182047111994066594911019010222064952859306742931009422376955635523160546531204043294436812066746785938062292942759004837173423765427628610568097898331237064396308950601636
output2 = 115015764780168428067411132384122324817310808727138440691727747976276050930701648349452842302609389394467134068064132550313721128807222231505312226682756817617177620169804112319332815872107656884931985435898097063491690413460967856530075292289784649593915313885813931026280791070577034075346669028068003251024
#太长了不给了,题目有
e=[]
out=[]
#n = orthogonal_deduce_n(e, out, 1024)
def orthogonal_deduce_n(exponents, powers, modulo_upper_bits=512, extra_relations=None):
# omit the extra_relations
assert len(exponents) == len(powers)
NUM = min(64, len(exponents))
exponents = exponents[:NUM]
powers = powers[:NUM]
print(f"[+] used samples #{NUM}")
B = matrix(ZZ, NUM, 1)
for i, e in enumerate(exponents):
#将 exponents 列表中的元素与它们的索引一一对应
B[i, 0] = e
M = B.transpose().right_kernel_matrix()
#B.transpose() 从一个 NUM x 1 的矩阵变为一个 1 x NUM 的矩阵
for l in M:
assert list(l * B) == [0]
L = M.LLL()
# L = M.BKZ(block_size = 40)
def compute_kn(new_es):
'''
:param new_es: e的正交格
:return:
'''
res_right = 1
res_left = 1
for i, cof in enumerate(new_es):
if cof > 0:
res_right = res_right * powers[i] ** cof
else:
res_left = res_left * powers[i] ** (-cof)
return res_left - res_right
print("[+] Matrix information after LLL (if the elements are too large, it's not feasible to compute the powers)")
for l in L:
print(l)
p = compute_kn(L[0])
for l in L[1:]:
assert list(l * B) == [0]
p = gcd(compute_kn(l), p)
p = factor(p, limit=2 ** 20)[-1][0]
if p.nbits() <= modulo_upper_bits:
return p
from Crypto.Util.number import *
n = orthogonal_deduce_n(e, out, 1024)
a = rsa_gong_N_def(e1,e2,c1,c2,n)
# output2 = output1 * a + b
b = (output2 - output1 * a) % n
print(long_to_bytes(b))
#NSSCTF{407f8832-6ffd-43bf-91a0-6900758cdff7}
参考