[羊城杯 2020]Power
题目
from Crypto.Util.number import *
import gmpy2
from secret import flag
p = getPrime(512)
q = getPrime(512)
n = p**4*q
e = 0x10001
phi = gmpy2.lcm(p - 1, q - 1)
d = gmpy2.invert(e, phi)
dp = d % (p - 1)
m = bytes_to_long(flag)
c = pow(m, e, n)
print "dp = " + str(dp)
print "c = " + str(c)
y = 449703347709287328982446812318870158230369688625894307953604074502413258045265502496365998383562119915565080518077360839705004058211784369656486678307007348691991136610142919372779782779111507129101110674559235388392082113417306002050124215904803026894400155194275424834577942500150410440057660679460918645357376095613079720172148302097893734034788458122333816759162605888879531594217661921547293164281934920669935417080156833072528358511807757748554348615957977663784762124746554638152693469580761002437793837094101338408017407251986116589240523625340964025531357446706263871843489143068620501020284421781243879675292060268876353250854369189182926055204229002568224846436918153245720514450234433170717311083868591477186061896282790880850797471658321324127334704438430354844770131980049668516350774939625369909869906362174015628078258039638111064842324979997867746404806457329528690722757322373158670827203350590809390932986616805533168714686834174965211242863201076482127152571774960580915318022303418111346406295217571564155573765371519749325922145875128395909112254242027512400564855444101325427710643212690768272048881411988830011985059218048684311349415764441760364762942692722834850287985399559042457470942580456516395188637916303814055777357738894264037988945951468416861647204658893837753361851667573185920779272635885127149348845064478121843462789367112698673780005436144393573832498203659056909233757206537514290993810628872250841862059672570704733990716282248839
g = 2
x = 2019*p**2 + 2020*p**3 + 2021*p**4
c1 = pow(g, x, y)
print "c1 = " + str(c1)
# dp = 3272293505696712831419859641571956066667516012597886098021642320155056349966612629986261146617139998624603483170466852538289743936225789351270153550594329
# c = 22524257534087703614496632403022329621384173069680778965750290698059674588465640878754707363673789674111671270645152584118206145007310499274423606886261969807360070526126452646719628307689968971699215841867636770320159256301550908771135042912287955209485328267670825390080110910391913063177323585204392804538642393453388536211144485389902591029350060800993352969569703901717308330574394200996651534321547814313195218895547718815009876393987398738932001924661338796059973950012706427109598830049455186171345179840564502215531573714428772608739268313985559628612004439028014417408631851880698512023740903181116906766066951473942201698375224240271523568161242951730224901227589413731025281719101368668617497947995579443908773425555177346524678673641140157885033923288401884
# c1 = 290707924192892686920253390955676600323331633814839708838347288502692494699485764473635783441705302268064111648851157070038783719749721994682837294625334517914882191486257362565066745587415388291939979195637720350919055988532145531805200483161599965215275808797976727969023747299578173497083532351976473770041800769265319548352841139802163279116490053292316399038329210043455932786945180855178341998049756983301499491011851026499269682821602212971062877270127451987836730083380463825717889123804613394241190839837791281657872259492589868751745327696030438893865069941066073554427558697972551085353027574529823439588670263047287131740802375738439636789806332323994866753085014446479034974063195632514803340511247735647970572837053148490258113394359072976858781060349776921428492973183958437965966963122069107876143476772436757554253049619918403996315720023020827394900507088006299225934263699192253079026440287311664705744424959801981503191480257138833694306501816837037995549817186335377411638035575004595417788588264823861850877111374085336446477943372458378834664678094751978400910288151519902977326995118727880223621964441498323865158898463327323193833062919619201107279964663654606753750042791368210261574897455830722232022689695292080269205470491791950839486861811469879413313773338916781857981641910031441448964144000585506870170898052132929034349451945051362244755750988705018897859238859476967568556992146975789444151432386692872801263000639711599152191790766776280
思路:
题目给出了 d p dp dp, e e e,有这个 d p dp dp,就很容易想到要用 d p dp dp来求 p p p,可 n n n没有给出,但可以根据 k ∗ ( p − 1 ) = e ∗ d p − 1 k * (p-1) = e * dp-1 k∗(p−1)=e∗dp−1,对 e ∗ d p − 1 e * dp-1 e∗dp−1进行yafu分解,得到因数如下:
x1 = 2*2*2
x2 = 11#2位
x3 = 7411#4位
x4 = 10402958442703#14位
x5 = 25388174482857437#17位
x6 = 19976951634728916570101#23位
x7 = 121098273308863403811867260913043#33位
x8 = 514664028984426592785192432611128951474323755859087258008037664208623#69位
因为 p = getPrime(512),这里我以为它的十进制数的长度为155,但没想到可以有154位。
所以我们只需要对以上因数重组就可以得到 p-1,因为e * dp-1的长度为159,而(p-1)的长度为154~155,所以只需要舍弃一个小的因数即可,再根据sympy.isprime()判断。
最终得到 p = ( e ∗ d p − 1 ) / / 7411 / / 2 / / 2 + 1 p = (e * dp-1)//7411//2//2 + 1 p=(e∗dp−1)//7411//2//2+1
于是 m ≡ c d ( m o d n ) ≡ c d ( m o d p ) m ≡ c^d (mod n) ≡ c^d (mod p) m≡cd(modn)≡cd(modp)。
因为 d p ≡ d ( m o d p − 1 ) dp ≡ d (mod\ p-1) dp≡d(mod p−1), d = d p + k ∗ ( p − 1 ) d = dp +k * (p-1) d=dp+k∗(p−1),利用这个进行尝试求解flag,如果flag有意义则输出(话说这个 d p dp dp这么大,估摸着 d d d就等于 d p dp dp吧,不然这 d d d就大的离谱了)
(淦!求出 p p p后,热血沸腾,竟尝试把 q q q给解出来,貌似应该解出来了(直接让 d = d p d = dp d=dp ),然后模 n n n的话不对,后面才想到可以把模数拆开,直接模 p p p不就行了!)
放一下这个求 q q q的代码😖😖😖
p = pd//7411//2//2 + 1
#print(sympy.isprime(pd//7411//2//2 + 1))#True
d = dp
#ed = 1 mod phi 求解q
k = 1
temp = e*d - 1
while True:
if temp%k == 0:
phi = temp//k
qq = phi//(p-1)
print(qq)
break
k += 1
#phi = 214456299482845468832763341329701284741188996917627661206044372736001928007761891931409596765847504089860638476542886114801894948348429556714192053245300539672
#(q-1)/gcd(p-1,q-1) = 29644 说明公约数很大啊
q = 2*x2*x4*x5*x6*x7*x8+1
#print(sympy.isprime(q),len(str(q)))#True 154
好啦!分析完毕,代码如下:
from Crypto.Util.number import *
import sympy
e = 0x10001
dp = 3272293505696712831419859641571956066667516012597886098021642320155056349966612629986261146617139998624603483170466852538289743936225789351270153550594329
c = 22524257534087703614496632403022329621384173069680778965750290698059674588465640878754707363673789674111671270645152584118206145007310499274423606886261969807360070526126452646719628307689968971699215841867636770320159256301550908771135042912287955209485328267670825390080110910391913063177323585204392804538642393453388536211144485389902591029350060800993352969569703901717308330574394200996651534321547814313195218895547718815009876393987398738932001924661338796059973950012706427109598830049455186171345179840564502215531573714428772608739268313985559628612004439028014417408631851880698512023740903181116906766066951473942201698375224240271523568161242951730224901227589413731025281719101368668617497947995579443908773425555177346524678673641140157885033923288401884
c1 = 290707924192892686920253390955676600323331633814839708838347288502692494699485764473635783441705302268064111648851157070038783719749721994682837294625334517914882191486257362565066745587415388291939979195637720350919055988532145531805200483161599965215275808797976727969023747299578173497083532351976473770041800769265319548352841139802163279116490053292316399038329210043455932786945180855178341998049756983301499491011851026499269682821602212971062877270127451987836730083380463825717889123804613394241190839837791281657872259492589868751745327696030438893865069941066073554427558697972551085353027574529823439588670263047287131740802375738439636789806332323994866753085014446479034974063195632514803340511247735647970572837053148490258113394359072976858781060349776921428492973183958437965966963122069107876143476772436757554253049619918403996315720023020827394900507088006299225934263699192253079026440287311664705744424959801981503191480257138833694306501816837037995549817186335377411638035575004595417788588264823861850877111374085336446477943372458378834664678094751978400910288151519902977326995118727880223621964441498323865158898463327323193833062919619201107279964663654606753750042791368210261574897455830722232022689695292080269205470491791950839486861811469879413313773338916781857981641910031441448964144000585506870170898052132929034349451945051362244755750988705018897859238859476967568556992146975789444151432386692872801263000639711599152191790766776280
#print(e*dp-1)
pd = 214456299482845468832763341329701284741188996917627661206044372736001928007761891931409596765847504089860638476542886114801894948348429556714192053245300539672
'''
#pd的因数
x1 = 2*2*2
x2 = 11#2
x3 = 7411#4
x4 = 10402958442703#14
x5 = 25388174482857437#17
x6 = 19976951634728916570101#23
x7 = 121098273308863403811867260913043#33
x8 = 514664028984426592785192432611128951474323755859087258008037664208623#69位
'''
#print(len(str(pd//7411//2//2)))
p = pd//7411//2//2 + 1
#print(sympy.isprime(pd//7411//2//2 + 1))#True
k = 0
while True:
d = dp + k * (p-1)
m = pow(c,d,p)
flag = long_to_bytes(m)
if b'GWHT' in flag or b'flag' in flag:
print(flag)
break
k += 1
#b'GWHT{f372e52f2a0918d92267ff78ff1a9f09}'
你要问为什么是b’GWHT’?哈,我也不知道,大概是我误打误撞求出来了才知道的!(废话啦)