- 题目
import hashlib
import sympy
from Crypto.Util.number import *
flag = 'GWHT{******}'
secret = '******'
assert(len(flag) == 38)
half = len(flag) / 2
flag1 = flag[:half]
flag2 = flag[half:]
secret_num = getPrime(1024) * bytes_to_long(secret)
p = sympy.nextprime(secret_num)
q = sympy.nextprime(p)
N = p * q
e = 0x10001
F1 = bytes_to_long(flag1)
F2 = bytes_to_long(flag2)
c1 = F1 + F2
c2 = pow(F1, 3) + pow(F2, 3)
assert(c2 < N)
m1 = pow(c1, e, N)
m2 = pow(c2, e, N)
output = open('secret', 'w')
output.write('N=' + str(N) + '\n')
output.write('m1=' + str(m1) + '\n')
output.write('m2=' + str(m2) + '\n')
output.close()
N=636585149594574746909030160182690866222909256464847291783000651837227921337237899651287943597773270944384034858925295744880727101606841413640006527614873110651410155893776548737823152943797884729130149758279127430044739254000426610922834573094957082589539445610828279428814524313491262061930512829074466232633130599104490893572093943832740301809630847541592548921200288222432789208650949937638303429456468889100192613859073752923812454212239908948930178355331390933536771065791817643978763045030833712326162883810638120029378337092938662174119747687899484603628344079493556601422498405360731958162719296160584042671057160241284852522913676264596201906163
m1=90009974341452243216986938028371257528604943208941176518717463554774967878152694586469377765296113165659498726012712288670458884373971419842750929287658640266219686646956929872115782173093979742958745121671928568709468526098715927189829600497283118051641107305128852697032053368115181216069626606165503465125725204875578701237789292966211824002761481815276666236869005129138862782476859103086726091860497614883282949955023222414333243193268564781621699870412557822404381213804026685831221430728290755597819259339616650158674713248841654338515199405532003173732520457813901170264713085107077001478083341339002069870585378257051150217511755761491021553239
m2=487443985757405173426628188375657117604235507936967522993257972108872283698305238454465723214226871414276788912058186197039821242912736742824080627680971802511206914394672159240206910735850651999316100014691067295708138639363203596244693995562780286637116394738250774129759021080197323724805414668042318806010652814405078769738548913675466181551005527065309515364950610137206393257148357659666687091662749848560225453826362271704292692847596339533229088038820532086109421158575841077601268713175097874083536249006018948789413238783922845633494023608865256071962856581229890043896939025613600564283391329331452199062858930374565991634191495137939574539546
- 题目分析
f l a g flag flag被分成了两段,
然后再通过两段 f l a g flag flag的值进行运算得到两个新的值进行加密,
得到了 m 1 m1 m1和 m 2 m2 m2。
n n n是一个很大的值,
p p p和 q q q是相邻的两个素数。
- 解题思路
面对 n n n很大, p p p和 q q q又是相邻的素数的问题。在数论学习中 埃拉托色尼筛选素数 \textcolor{red}{埃拉托色尼筛选素数} 埃拉托色尼筛选素数的方法告诉我们,要找出比一个数小的所有素数,只要用比这个数的 算数平方根 \textcolor{red}{算数平方根} 算数平方根小的所有素数去试除就可以。相应的,我们用反证法来证明:
n 2 p < q p < n 2 < q \begin{align} &\sqrt[2]{n}\\ p&<q\\ p<&\sqrt[2]{n}<q\\ \end{align} pp<2n<q2n<q
证明:如果 n 2 < p \sqrt[2]{n}<p 2n<p那么 n < p ∗ q n<p*q n<p∗q,如果 q < n 2 q<\sqrt[2]{n} q<2n那么 n > p ∗ q n>p*q n>p∗q,证毕。
所以只要求出 n 2 \sqrt[2]{n} 2n的下一个素数就是 q q q
c1 = F1 + F2
c2 = pow(F1, 3) + pow(F2, 3)
面对式子求解的问题,可以通过sympy的方程求解来解决。
- 解题代码
root@1ad9c6992813:~# vim test_solve.py
import sympy
n = gmpy2.mpz(636585149594574746909030160182690866222909256464847291783000651837227921337237899651287943597773270944384034858925295744880727101606841413640006527614873110651410155893776548737823152943797884729130149758279127430044739254000426610922834573094957082589539445610828279428814524313491262061930512829074466232633130599104490893572093943832740301809630847541592548921200288222432789208650949937638303429456468889100192613859073752923812454212239908948930178355331390933536771065791817643978763045030833712326162883810638120029378337092938662174119747687899484603628344079493556601422498405360731958162719296160584042671057160241284852522913676264596201906163)
m1 = gmpy2.mpz(90009974341452243216986938028371257528604943208941176518717463554774967878152694586469377765296113165659498726012712288670458884373971419842750929287658640266219686646956929872115782173093979742958745121671928568709468526098715927189829600497283118051641107305128852697032053368115181216069626606165503465125725204875578701237789292966211824002761481815276666236869005129138862782476859103086726091860497614883282949955023222414333243193268564781621699870412557822404381213804026685831221430728290755597819259339616650158674713248841654338515199405532003173732520457813901170264713085107077001478083341339002069870585378257051150217511755761491021553239)
m2 = gmpy2.mpz(487443985757405173426628188375657117604235507936967522993257972108872283698305238454465723214226871414276788912058186197039821242912736742824080627680971802511206914394672159240206910735850651999316100014691067295708138639363203596244693995562780286637116394738250774129759021080197323724805414668042318806010652814405078769738548913675466181551005527065309515364950610137206393257148357659666687091662749848560225453826362271704292692847596339533229088038820532086109421158575841077601268713175097874083536249006018948789413238783922845633494023608865256071962856581229890043896939025613600564283391329331452199062858930374565991634191495137939574539546)
p = gmpy2.next_prime(gmpy2.iroot(n, 2)[0])
q = n // p
e = gmpy2.mpz(int('0x10001', 16))
phi_n = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi_n)
c1 = gmpy2.powmod(m1, d, n)
c2 = gmpy2.powmod(m2, d, n)
f1, f2 = sympy.symbols("f1, f2")
f_funs = [f1 + f2 - c1, f1 ** 3 + f2 ** 3 - c2]
f_solve = sympy.solve(f_funs, [f1, f2])
print("flag is: ", bytes.fromhex(hex(f_solve[0][0])[2:]) + bytes.fromhex(hex(f_solve[0][1])[2:]))
print("flag is: ", bytes.fromhex(hex(f_solve[1][0])[2:]) + bytes.fromhex(hex(f_solve[1][1])[2:]))
root@1ad9c6992813:~# python test_solve.py
flag is: b'30ca8972959a1033b2}GWHT{f709e0e2cfe7e5'
flag is: b'GWHT{f709e0e2cfe7e530ca8972959a1033b2}'