2025-能源网络安全大赛-crypto

水水博客

NumberTheory

题目:

from Crypto.Util.number import *
import hint

flag=b'xxx'
e=65537
p=getPrime(512)
q=getPrime(512)
n=p*q
m=bytes_to_long(flag)
c=pow(m,e,n)
k=getPrime(1024)
assert hint + 233 * k == 233 * k * p
print(n)
print(c)
print(hint)

# 105531804094410236294687082475828411218788143973352026416392542762437103918840861241726193253936370648195682452618343195471719649394086997793137653518966739212122830015579955183805636213883066694989610003565432493653164047938048521354525623612253955387430773546124647105772639376194421783783651686606080214099
# 6838127295540107402282470465780599628759317234806902778570348919850980664834107227012249617036087381075344016550381137159643512672239826438903241091658619314078921936719784123522758604349399440232971511649918093228288847534685526358191804172060250409498531941883162873696671060909325234109062997554795436940
# 225457129615945961139095949356083106510992163176770860368085043522677811094793442173512565115313130227614423196268240217775831118417780318014842280209747426271227826513967791945116378179885000662888744992914390207196310600996050316737090999399962338133222370745589250853315876818226312453376340282748842779666176953455553054310328901299083159029050169950812885486884682347263045764918907196922313892044095742248895091717187372068779768743879411865275203496650858608

利用费马小定理得到:

a233k(p1)1modp a ^ {233*k*(p-1)} \equiv 1 \mod p

exp:

from Crypto.Util.number import *
import gmpy2

n =  105531804094410236294687082475828411218788143973352026416392542762437103918840861241726193253936370648195682452618343195471719649394086997793137653518966739212122830015579955183805636213883066694989610003565432493653164047938048521354525623612253955387430773546124647105772639376194421783783651686606080214099
c =  6838127295540107402282470465780599628759317234806902778570348919850980664834107227012249617036087381075344016550381137159643512672239826438903241091658619314078921936719784123522758604349399440232971511649918093228288847534685526358191804172060250409498531941883162873696671060909325234109062997554795436940
hint = 225457129615945961139095949356083106510992163176770860368085043522677811094793442173512565115313130227614423196268240217775831118417780318014842280209747426271227826513967791945116378179885000662888744992914390207196310600996050316737090999399962338133222370745589250853315876818226312453376340282748842779666176953455553054310328901299083159029050169950812885486884682347263045764918907196922313892044095742248895091717187372068779768743879411865275203496650858608
e = 65537
p = gmpy2.gcd(pow(2,hint,n)-1,n)
q = n//p
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
flag = long_to_bytes(m)
print(flag)
# flag{158f26cca09e89b08cbd234c1f9c98c0}

easy_lwe

题目:

from Crypto.Util.number import *
from secrets import flag
assert len(flag) == 38

p = getPrime(512)
m = getPrime(512)
while m > p:
    m = getPrime(512)

aa = []
cc = []
bb = []
for i in range(30):
    a = getPrime(512)
    b = getPrime(400)
    c = (a * m + b) % p
    aa.append(a)
    cc.append(c)
    bb.append(b)

enc = pow(m,flag,p)
print(f'p = {p}')
print(f'aa = {aa}')
print(f'cc = {cc}')
print(f'enc = {enc}')


# p = 0x83b05d231fd40ff8ca26b4fb8136dc920754c14412960ce2ec700457861d48fe74f3958fc3a153f77a23fb850ecf0ac1e9722c71b6cc8a104b372cc17bf1528f
# aa = [0xf53f440f2e76b60380e68e96508f5dd716b2c3df2ed8265ced83a93fd61a708eeff31fbee9efa22fa7b441cbc406c210de6273f81eb7d093561d5c6394ef2abd,0xe9ecbd5457dcf1bdbc1a852b625c7a8ae6f530e348c2dc0416afd6a375aeb06d4800cc6471ae7d29681715d0407aa8726c32cd35e54960f56b0d9b47a2eed9ed,0x86a261c1590a774ced6c7db439e53e4068a8dbc0ad111a0e0371e8731fb939a068348d035da04afb9a3914a011574e35cefc4d5c5740f7cbc27459d944f51d15,0xba99a871d8f805e3c0dcd4e04cee66ec5e213a7902a65f2faa8e86368e56c42d09fde536b07471fff8f72db922725a24d6288d1bfe9edc2cd76b756eb464e1eb,0xa99efeb79377db6baa8787b5d2d2ebf123d8ec77e820d1b88644883a07c38498aa08df82cb9802c7fa128a5fa08b66c56a0805f70a78b7cb45b1a74bde095165,0xe6341800304b0a6f2de941432bb253f53a3c73c7b0f0382fd1ec4c882da5fd1b5151c619f9279de3767ae03af387c495c50c8c0ff79fd6c8acb51bd0b16afc23,0xa8670f7142e5d90e781e335d5e870188b94288defd8302c1b183bf20b5a3720be1ae1afe0ad937bc4678727e1daf262194c430086f3810447dfce721c8fb36a5,0xe9d150d4e7a7f82e89d26fcaa003579c8dfc25f4a50794175ae0a4407dd33e87eb5fded328155009548c002d2a3198afa356e1692a6bb820d8ae71ca6e506b35,0xd7ec72dd643449f5d21a32a11e2458d292c524b91b4b1a8515a5f8351717813f51a55c5675aa0eaa5c80a32d26aa385d7425e7d3e1e50936b2744a1534e3c7b7,0xaf5d8062f6bc03875b5fb10d0888d586cb08fa62709910cd7d931201d4d833d31d935003b801cac4fd51ef1e4db3bc13e41d740d7881560c0942faf9acca55d5,0xf63c4a5add0474bf6c4fb6617a2965e2474a2902c59bcc4243d5dcffa0f1aa0a6136e9c9093ea05d84a26888aaad63ec652602200141abdfcdc0d1912d208dbb,0xd65c8ef9b01085819f2f5f2dfbb7641521966600ddd7a03b886320328144ec42ed5585206744c8e1b5beb5502aff6f0cd01934890926bbb5387363b321dbb6bd,0x9bd7a0e9d4940126c9668de7e29e198ac38010d505b90e92ee560307b8a134545bbd0277f14e7651e91c5a9362207097e17888b9a49a889c672f76681f41962f,0xff387c4e94f47cba242936e80d620d3eeb203a1c7f365ae178b33b29ff3d8c2f932733d0605876c23942bae7f096b3ee457d02758796bda01bbcd3bd2e1229a1,0xbd6c24205cf5b9b2acc909296369ca77ef34ceac5f9900742a7ec37c00b94a56418d168d576d33383d9f782386524c4cecebc3a9fa68c81a5a6867de564d07e3,0x8850ac2051b6a7450f228e676abbfd510ce08a43a0b791182aedcfb6b3f1d478e3dc953e59eb99fe370f71d52af3a1625e0700078927f8a5919becbfa60af96b,0xfa474444b5372681c5b7316871cf9a93306b4d6a3eac2492c71780eb6903bd4ff77b1c4a28608dfa10c0c8b8bfc23942fc0a8ec64d3967504621e692eafcf4af,0xfd7f772c719929d33f15ce0122f6efc278b728d75dbd16a343c649e49118a79084d169d6db1b6b859e1f4c82694a850622dcdff23c8fbd7d0a736a409b94f471,0xedf6566ecd7f0a0beaa2f45a2a509358c9537dbf772e6f63ccb0e21b5c5c3dae0939e9e15c9bcdf80f7875e74ebfba16f0660737719c8ad435981b5b8df89a23,0xd7e718dafb753084cb7c1deee139f6e158a0228bbf9b0ae5ed3a8b3d2508ce62e4e32cd43a3135540b31e052e6e3a0dba3ae623c69d74da34387c3429b6f0487,0xbff5ab718c54909a34ba8ab5787cbfb0c9c57394350b71744d5751f577cefda87cc8263b21dd2c21a8f19fff8362c3371fcb054dddb1293df7d6efe2d661e4ab,0xb946ad47cf1f9186c1eeaeed12f21b41a29f9fb74b14f577c97731004b372c5f41023aafc9b93557c984ff87dd263b293aa500c3a2ce1f0815319263cf7c42d5,0x9b93853dc5f4c052fdda339f69c625bc98ffdbde439078458b84278e34542f9110863e5beef166a766f565f7a815ec4a462510b42f81454b65e648622c610b27,0xae050aaa86b9580747efa33561973597d7d7a0684a45219eed3224ebc37fdf067ed61a29ecaa501266c9bcdd16b850c0dd40da3f964a5b03ae60c3967fd55913,0xea57b0482a876d49a3e21bb885bda0aae21f5fcf2521f7e1db771998b6b639d0833c17d7c8c67c12ce9b60e4210e068f98344a8cabc5faa17a048100bab797bb,0x9f866ad27c9ea2fb29168ec6db0f7755221484d0c89bfef0cd70fc2ed14fda15f7b59bbca2e23f40b5effeb9e53ad821e06cf986b34da4407c85bfbf78d2920b,0xab0939605dcff5d1ec8405b6daeb65eccc6e3b5956601dddea95c6310ac32bfeec1bab6b83e85371078a16ea9489050175098d39488aaed2a190c647fe2b1b69,0xe85698e04d8bedbac2c7884c914b7026dbb1dd5134c4a5a8e7541b07c8a94ab3d2f12eb7f1171ccd564054e1dc63d5ac044e5c5552870b419fef35a572199239,0xea94663e103e4354fb7feb80b11d06c7e16feb7265f69ee882180baba70fa075df24e3fe1ad12a99f054cabf4a3f5e4823416d4c4daa02ca51ce3926034186db,0x93662718294005f4ac8f79b0799e240a05eea871ef07d623ea7c68ef818b3b55fb4f9b6f06c399726e59cec03389053b448f187404cddb93cb3c55e3d12cebc9]
# cc = [0x4aae29aaaab89fbc672db400c41d1ad3ffce937e7810065bed552c12101fb778046d22b00c05bbc3f61825b5af3c3e57f1abaafe3d9a58a573a905e2a1cecde7,0x502a1c23ef44f174aaedb9a49705eb72f805bab13e82d599525ea7484cc11f2e7c4475526b4be344390e46bcb8bcdaba2768c6321f8ca5482666171eee498f28,0x546f2276b59b7186ef5b9a04e0ba2691648d005fc780303411a1082ea3b05be127a10e26921a4b84b14d8acc45a6c32a0142ac6eb396415ecb5841a01b775b5d,0x43986eb7208b66dd86c12f953e10b2d3907873151170278393b6a4f7ea518ab5745e2db5f4dbec84087c4817c5df10e743f35ed1190515aba34832b1b274bf2e,0x7b2e448342bc7409ed891cdbf5137014f417866097297302085d8800458495e374fba8398d069f1c1c7792a9f03194e36921c378308de18313fb9b62db45cc0a,0x41ac8f265bc96ae868256fb08caf0a43a547346522b5d90cb9489c87cd5d726447d20354332dd3cb771003eddfa9c4bfa6923ae45ac8c0994f7cce46a3302eea,0x51b59ad39b388fdb2056279e2de02d32d36b52da1cc1fe4f6843964273b4585704e21405e2528e5894bd4fdb436c382a5f7d3849f9c5d7902be74edd2b16a31c,0x4e52d207f16a6f42497b25600e039de3ce49d7945ac2201ac12bf9fa9b3dc136f35328cbe9d3f9d4204d90f29fe1ce209c8904c99de0f85c5c572d05609095a6,0x6485f505cd8296e9f1c9abdc39eebc6e767e98e1587b18878fa8a582a012bb609c2f36daffc2b9c460514bc47533525ce6835e7f8123331a833958fa47f2e40,0x1ff809e71ab0347a8a9ec4356d5b8fbf109ade5881e5b59ac14adaaef2034fc40880e495070442513f42434fa8cbfcd9bce0501574997b35939f201ba1c87872,0x5b3fad73b402fcc1148758d80a61f637257d35f2773c8dc9f22859a01aecaa37a37858232ab5b3e3622f234bf35bb02a6e93ecd5a06182b61e583d0193afaf55,0x640e3556a526209f8528fbe678da3914d912a7e701abc3d4fcd65d84bcdbfc22623dfa3db31f9585a615c6de869b39c040dbfe94bb7eafd91bde15c4b87bd2c0,0x335b0ff42f39541539752faade7510a301a861720d85958ce2890ddca9e0693b342604a5b134a0974ea21dc0dc0a156c01159898e5f87e16b4a56121c2e3bbb5,0x89621740ec8b81065457105685666dfe6e31ee4f0a6efa6901e20ad6e5ea19ba438ea92f632764e52ccfb1ed35639443b5536f19ca69e9c295c6f5287a5e31b,0x1e4162060327045be0f5a0ae5d7b87c60b928e4669450339af64a39ae45b108eb58bbe83e15bef7a5c92243b213adc3e9d3514632249314bf5b588df6202ae10,0x5d10e308a16f8cd5c53b3ecd1081624e6eed4c3bfe522a8b7daf301aa6fc370b0a1cff1db7ea27aa6f5200903b365c53bc6d890ca1167ca57de87f80c5321742,0x434ac82b1ed073a1d73606ffe973e316768368fb522644f6cc76d2a0e6b83f533524c7589113aeb2db35d50c2f9ff64ceb27958a93d47b6875b8eb9b158ebaac,0x7cf3028273ece2a8af9790d3a689875bf7a3894e351a639d88fa13de05dc7f18be20ddeef4414a31b0f3dd65291e5d4d47d098027dbec25d4bc5409c017f0b03,0x5d0eefe7de32360d7950d96d821ce06741b737a1dca016cb003f75e380f5c8e3d9b8505b0eda21b36879a6455d1f640bdac5ad648b97d80eacf406b57bb1d692,0x4e4c6156da7f71123e1b4efde4a436985c6f2cccdc9b182735a75153927c6e7dc94693ab7fdd8646821a9d42eeb76c1be54984f81296a10e689805975185bf2c,0x68db6b837d968569ba944591efb36587f0022b05cefbedaad1e1d7652d0c233d1c0b036364f25e0865c7a1dab8d9d1081f23928a3573b5ec711e5b7f32714a4,0x333db46bc5fb83cbbf68475fd612bcad6becd30f95bf5b9ab6058ed0777fcb78cfe6da5c3386799fe9a1d6616801154ae7f45e35612de08efed7e2e750088b8e,0x70d4dc8986c228e12329af934c08f7c0ca94ce6913b5c641c59b3cf629a1957f82d4f40aaa7faa765c75e4f994a8222a4d08e045fb529da5ee277e1b9540c148,0x20421569b3bc73da4505760f7798a504f2276e6df9c9e48320b23201fb682021d168f6ee657fc2080722eb576ac78bf4b63ad7419983a05196fa0724fc4886d,0x5f523df584f43d7eff229d562793c8e5d4713d9c80bd40b95434c34c982324f7c282ac2fe3ac151cb62435b85bece2ef115c6f4b7a33d47dcbfa8360f89b91ac,0x7cbedea149640064a93cb75b909804ee7a896e17da808579206d1db7523b98bdf15bdc70e267e0a201bf293f980c1b5304337a7a78cc655aca07b9818b7169ab,0x62b34eaac3d3a2b360805cc23147ff8754a9d90788461107a5c8cc7053a0910ca7af45035d333c9a0b7cf6a2c13c9c367ad8eea0ccda2a6d8e089b5ee07a76ef,0x3e1c31f988e238869fad4794beb32164fa3bf3880041d1f9f2a65e2679f951491fcbeff1aa067313bf02100ae15d1af4d87050db05cec934e077c3eec238b72,0x3c056ad33432e1cf5548ae3a6db21ee1471eb70619e0ad542bd38dd80f37b76b571ae6469bacd33f9618b7a61b8e8424fc33cae479375df72b064a5d1b8cd90f,0x4caf081f5b949e65115e18b613ad8dc1fc208d2c5bea710b27b1db11d4a7eecc455c13f2fd92481f8cfea3e6fa75c0a58a154f12b6ce92c66107f617fd7ed7d8]
# enc = 0x191eb43459bd0f2d5ece00ab52c612668bb4c161014641a6e4afb41020465d7b82e9b60a55ab831bb5695f2fd832d08258c752ebf27ba0374b7b11b001b2629a

先造一个格

(k0,k1,,ki,key,1)(pppt0t1tiKpg0g1giK)=(z0,z1,,zi,key×Kp,K) (k_0,k_1,\ldots,k_i,key,1) \left( \begin{matrix} p & & & & & \\ &p & & & & \\ & & \ddots & & & \\ & & &p & & \\ t_0 & t_1 & \ldots & t_i &\frac{K}{p} & \\ -g_0 & -g_1 & \cdots & -g_i & & K\\ \end{matrix} \right) = (z_0,z_1,\ldots,z_{i},key\times\frac{K}{p} ,K)

这部分和2025-GHCTF-crypto|Chestnut's blog一样
解出来m后,再用Pohlig_Hellman+discrete_log解离散对数问题,最后没差几位就爆破一下

#sage
from Crypto.Util.number import *
import hashlib

p = 0x83b05d231fd40ff8ca26b4fb8136dc920754c14412960ce2ec700457861d48fe74f3958fc3a153f77a23fb850ecf0ac1e9722c71b6cc8a104b372cc17bf1528f
ts = [0xf53f440f2e76b60380e68e96508f5dd716b2c3df2ed8265ced83a93fd61a708eeff31fbee9efa22fa7b441cbc406c210de6273f81eb7d093561d5c6394ef2abd,0xe9ecbd5457dcf1bdbc1a852b625c7a8ae6f530e348c2dc0416afd6a375aeb06d4800cc6471ae7d29681715d0407aa8726c32cd35e54960f56b0d9b47a2eed9ed,0x86a261c1590a774ced6c7db439e53e4068a8dbc0ad111a0e0371e8731fb939a068348d035da04afb9a3914a011574e35cefc4d5c5740f7cbc27459d944f51d15,0xba99a871d8f805e3c0dcd4e04cee66ec5e213a7902a65f2faa8e86368e56c42d09fde536b07471fff8f72db922725a24d6288d1bfe9edc2cd76b756eb464e1eb,0xa99efeb79377db6baa8787b5d2d2ebf123d8ec77e820d1b88644883a07c38498aa08df82cb9802c7fa128a5fa08b66c56a0805f70a78b7cb45b1a74bde095165,0xe6341800304b0a6f2de941432bb253f53a3c73c7b0f0382fd1ec4c882da5fd1b5151c619f9279de3767ae03af387c495c50c8c0ff79fd6c8acb51bd0b16afc23,0xa8670f7142e5d90e781e335d5e870188b94288defd8302c1b183bf20b5a3720be1ae1afe0ad937bc4678727e1daf262194c430086f3810447dfce721c8fb36a5,0xe9d150d4e7a7f82e89d26fcaa003579c8dfc25f4a50794175ae0a4407dd33e87eb5fded328155009548c002d2a3198afa356e1692a6bb820d8ae71ca6e506b35,0xd7ec72dd643449f5d21a32a11e2458d292c524b91b4b1a8515a5f8351717813f51a55c5675aa0eaa5c80a32d26aa385d7425e7d3e1e50936b2744a1534e3c7b7,0xaf5d8062f6bc03875b5fb10d0888d586cb08fa62709910cd7d931201d4d833d31d935003b801cac4fd51ef1e4db3bc13e41d740d7881560c0942faf9acca55d5,0xf63c4a5add0474bf6c4fb6617a2965e2474a2902c59bcc4243d5dcffa0f1aa0a6136e9c9093ea05d84a26888aaad63ec652602200141abdfcdc0d1912d208dbb,0xd65c8ef9b01085819f2f5f2dfbb7641521966600ddd7a03b886320328144ec42ed5585206744c8e1b5beb5502aff6f0cd01934890926bbb5387363b321dbb6bd,0x9bd7a0e9d4940126c9668de7e29e198ac38010d505b90e92ee560307b8a134545bbd0277f14e7651e91c5a9362207097e17888b9a49a889c672f76681f41962f,0xff387c4e94f47cba242936e80d620d3eeb203a1c7f365ae178b33b29ff3d8c2f932733d0605876c23942bae7f096b3ee457d02758796bda01bbcd3bd2e1229a1,0xbd6c24205cf5b9b2acc909296369ca77ef34ceac5f9900742a7ec37c00b94a56418d168d576d33383d9f782386524c4cecebc3a9fa68c81a5a6867de564d07e3,0x8850ac2051b6a7450f228e676abbfd510ce08a43a0b791182aedcfb6b3f1d478e3dc953e59eb99fe370f71d52af3a1625e0700078927f8a5919becbfa60af96b,0xfa474444b5372681c5b7316871cf9a93306b4d6a3eac2492c71780eb6903bd4ff77b1c4a28608dfa10c0c8b8bfc23942fc0a8ec64d3967504621e692eafcf4af,0xfd7f772c719929d33f15ce0122f6efc278b728d75dbd16a343c649e49118a79084d169d6db1b6b859e1f4c82694a850622dcdff23c8fbd7d0a736a409b94f471,0xedf6566ecd7f0a0beaa2f45a2a509358c9537dbf772e6f63ccb0e21b5c5c3dae0939e9e15c9bcdf80f7875e74ebfba16f0660737719c8ad435981b5b8df89a23,0xd7e718dafb753084cb7c1deee139f6e158a0228bbf9b0ae5ed3a8b3d2508ce62e4e32cd43a3135540b31e052e6e3a0dba3ae623c69d74da34387c3429b6f0487,0xbff5ab718c54909a34ba8ab5787cbfb0c9c57394350b71744d5751f577cefda87cc8263b21dd2c21a8f19fff8362c3371fcb054dddb1293df7d6efe2d661e4ab,0xb946ad47cf1f9186c1eeaeed12f21b41a29f9fb74b14f577c97731004b372c5f41023aafc9b93557c984ff87dd263b293aa500c3a2ce1f0815319263cf7c42d5,0x9b93853dc5f4c052fdda339f69c625bc98ffdbde439078458b84278e34542f9110863e5beef166a766f565f7a815ec4a462510b42f81454b65e648622c610b27,0xae050aaa86b9580747efa33561973597d7d7a0684a45219eed3224ebc37fdf067ed61a29ecaa501266c9bcdd16b850c0dd40da3f964a5b03ae60c3967fd55913,0xea57b0482a876d49a3e21bb885bda0aae21f5fcf2521f7e1db771998b6b639d0833c17d7c8c67c12ce9b60e4210e068f98344a8cabc5faa17a048100bab797bb,0x9f866ad27c9ea2fb29168ec6db0f7755221484d0c89bfef0cd70fc2ed14fda15f7b59bbca2e23f40b5effeb9e53ad821e06cf986b34da4407c85bfbf78d2920b,0xab0939605dcff5d1ec8405b6daeb65eccc6e3b5956601dddea95c6310ac32bfeec1bab6b83e85371078a16ea9489050175098d39488aaed2a190c647fe2b1b69,0xe85698e04d8bedbac2c7884c914b7026dbb1dd5134c4a5a8e7541b07c8a94ab3d2f12eb7f1171ccd564054e1dc63d5ac044e5c5552870b419fef35a572199239,0xea94663e103e4354fb7feb80b11d06c7e16feb7265f69ee882180baba70fa075df24e3fe1ad12a99f054cabf4a3f5e4823416d4c4daa02ca51ce3926034186db,0x93662718294005f4ac8f79b0799e240a05eea871ef07d623ea7c68ef818b3b55fb4f9b6f06c399726e59cec03389053b448f187404cddb93cb3c55e3d12cebc9]
gs = [0x4aae29aaaab89fbc672db400c41d1ad3ffce937e7810065bed552c12101fb778046d22b00c05bbc3f61825b5af3c3e57f1abaafe3d9a58a573a905e2a1cecde7,0x502a1c23ef44f174aaedb9a49705eb72f805bab13e82d599525ea7484cc11f2e7c4475526b4be344390e46bcb8bcdaba2768c6321f8ca5482666171eee498f28,0x546f2276b59b7186ef5b9a04e0ba2691648d005fc780303411a1082ea3b05be127a10e26921a4b84b14d8acc45a6c32a0142ac6eb396415ecb5841a01b775b5d,0x43986eb7208b66dd86c12f953e10b2d3907873151170278393b6a4f7ea518ab5745e2db5f4dbec84087c4817c5df10e743f35ed1190515aba34832b1b274bf2e,0x7b2e448342bc7409ed891cdbf5137014f417866097297302085d8800458495e374fba8398d069f1c1c7792a9f03194e36921c378308de18313fb9b62db45cc0a,0x41ac8f265bc96ae868256fb08caf0a43a547346522b5d90cb9489c87cd5d726447d20354332dd3cb771003eddfa9c4bfa6923ae45ac8c0994f7cce46a3302eea,0x51b59ad39b388fdb2056279e2de02d32d36b52da1cc1fe4f6843964273b4585704e21405e2528e5894bd4fdb436c382a5f7d3849f9c5d7902be74edd2b16a31c,0x4e52d207f16a6f42497b25600e039de3ce49d7945ac2201ac12bf9fa9b3dc136f35328cbe9d3f9d4204d90f29fe1ce209c8904c99de0f85c5c572d05609095a6,0x6485f505cd8296e9f1c9abdc39eebc6e767e98e1587b18878fa8a582a012bb609c2f36daffc2b9c460514bc47533525ce6835e7f8123331a833958fa47f2e40,0x1ff809e71ab0347a8a9ec4356d5b8fbf109ade5881e5b59ac14adaaef2034fc40880e495070442513f42434fa8cbfcd9bce0501574997b35939f201ba1c87872,0x5b3fad73b402fcc1148758d80a61f637257d35f2773c8dc9f22859a01aecaa37a37858232ab5b3e3622f234bf35bb02a6e93ecd5a06182b61e583d0193afaf55,0x640e3556a526209f8528fbe678da3914d912a7e701abc3d4fcd65d84bcdbfc22623dfa3db31f9585a615c6de869b39c040dbfe94bb7eafd91bde15c4b87bd2c0,0x335b0ff42f39541539752faade7510a301a861720d85958ce2890ddca9e0693b342604a5b134a0974ea21dc0dc0a156c01159898e5f87e16b4a56121c2e3bbb5,0x89621740ec8b81065457105685666dfe6e31ee4f0a6efa6901e20ad6e5ea19ba438ea92f632764e52ccfb1ed35639443b5536f19ca69e9c295c6f5287a5e31b,0x1e4162060327045be0f5a0ae5d7b87c60b928e4669450339af64a39ae45b108eb58bbe83e15bef7a5c92243b213adc3e9d3514632249314bf5b588df6202ae10,0x5d10e308a16f8cd5c53b3ecd1081624e6eed4c3bfe522a8b7daf301aa6fc370b0a1cff1db7ea27aa6f5200903b365c53bc6d890ca1167ca57de87f80c5321742,0x434ac82b1ed073a1d73606ffe973e316768368fb522644f6cc76d2a0e6b83f533524c7589113aeb2db35d50c2f9ff64ceb27958a93d47b6875b8eb9b158ebaac,0x7cf3028273ece2a8af9790d3a689875bf7a3894e351a639d88fa13de05dc7f18be20ddeef4414a31b0f3dd65291e5d4d47d098027dbec25d4bc5409c017f0b03,0x5d0eefe7de32360d7950d96d821ce06741b737a1dca016cb003f75e380f5c8e3d9b8505b0eda21b36879a6455d1f640bdac5ad648b97d80eacf406b57bb1d692,0x4e4c6156da7f71123e1b4efde4a436985c6f2cccdc9b182735a75153927c6e7dc94693ab7fdd8646821a9d42eeb76c1be54984f81296a10e689805975185bf2c,0x68db6b837d968569ba944591efb36587f0022b05cefbedaad1e1d7652d0c233d1c0b036364f25e0865c7a1dab8d9d1081f23928a3573b5ec711e5b7f32714a4,0x333db46bc5fb83cbbf68475fd612bcad6becd30f95bf5b9ab6058ed0777fcb78cfe6da5c3386799fe9a1d6616801154ae7f45e35612de08efed7e2e750088b8e,0x70d4dc8986c228e12329af934c08f7c0ca94ce6913b5c641c59b3cf629a1957f82d4f40aaa7faa765c75e4f994a8222a4d08e045fb529da5ee277e1b9540c148,0x20421569b3bc73da4505760f7798a504f2276e6df9c9e48320b23201fb682021d168f6ee657fc2080722eb576ac78bf4b63ad7419983a05196fa0724fc4886d,0x5f523df584f43d7eff229d562793c8e5d4713d9c80bd40b95434c34c982324f7c282ac2fe3ac151cb62435b85bece2ef115c6f4b7a33d47dcbfa8360f89b91ac,0x7cbedea149640064a93cb75b909804ee7a896e17da808579206d1db7523b98bdf15bdc70e267e0a201bf293f980c1b5304337a7a78cc655aca07b9818b7169ab,0x62b34eaac3d3a2b360805cc23147ff8754a9d90788461107a5c8cc7053a0910ca7af45035d333c9a0b7cf6a2c13c9c367ad8eea0ccda2a6d8e089b5ee07a76ef,0x3e1c31f988e238869fad4794beb32164fa3bf3880041d1f9f2a65e2679f951491fcbeff1aa067313bf02100ae15d1af4d87050db05cec934e077c3eec238b72,0x3c056ad33432e1cf5548ae3a6db21ee1471eb70619e0ad542bd38dd80f37b76b571ae6469bacd33f9618b7a61b8e8424fc33cae479375df72b064a5d1b8cd90f,0x4caf081f5b949e65115e18b613ad8dc1fc208d2c5bea710b27b1db11d4a7eecc455c13f2fd92481f8cfea3e6fa75c0a58a154f12b6ce92c66107f617fd7ed7d8]
gs1 = []

for i in gs:
    gs1.append(-i)

Ge = Matrix(QQ,32,32)

for i in range(30):
    Ge[i,i] = p
    Ge[-2,i] = ts[i]
    Ge[-1,i] = gs[i]

t = QQ(2^400 / p)

Ge[-1,-1] = 2^400
Ge[-2,-2] = t

for i in Ge.LLL():
    if abs(i[-1]) == 2^400:
        print(i)

z = 2315434691190622851821148166280387149811000821028466930553100548163368132404903155653314528183153494737883769483926684341
key = (gs[0]-z) *inverse(ts[0],p)%p
print(key)
n = 6897108443075981744484758716081045417854227543713106404294789655180105457499042179717447342593790180943415014044830872925165163457476209819356694244840079
c = 0x191eb43459bd0f2d5ece00ab52c612668bb4c161014641a6e4afb41020465d7b82e9b60a55ab831bb5695f2fd832d08258c752ebf27ba0374b7b11b001b2629a
m = 6789891305297779556556571922812978922375073901749764215969003309869718878076269545304055843125301553103531252334876560433405451108895206969904268456786139
sum = 1
h = 7938574420107972329924249635772221961795521132311900945710547973
tmp_list = [2, 3, 193, 877, 2663, 662056037, 812430763, 814584769, 830092927, 849943517, 969016409, 1000954193, 1022090869, 1048277339]
for i in tmp_list:
    sum *= i

Zp = Zmod(n)
x= discrete_log(Zp(pow(c,h,n)), Zp(pow(m,h,n)))

while True:
    if int(x).bit_length() > 304:
        break
    if int(pow(m, x, n)) == c:
        flag = long_to_bytes(x)
        print('Flag:', flag)
        break
    x += sum
# flag{70b1b709ce431682addb581596320007}