这是ctf中的一道misc题,根据附件中的描述给我解题思路,过程和答案

Создано: 27 декабря 2025 г.

Отвечено с использованием GPT-5.2 Thinking от Chat01

Вопрос

ciphertext.txt
oracle_transcript.txt
public.txt
题目描述.txt

这是ctf中的一道misc题,根据附件中的描述给我解题思路,过程和答案

Python

python
from pathlib import Path, PurePosixPath paths = ["/mnt/data/题目描述.txt", "/mnt/data/public.txt", "/mnt/data/ciphertext.txt", "/mnt/data/oracle_transcript.txt"] for p in paths: print(p, Path(p).exists(), Path(p).stat().st_size if Path(p).exists() else None)

Python

python
print(Path("/mnt/data/题目描述.txt").read_bytes()) print(Path("/mnt/data/题目描述.txt").read_text(errors="replace"))

Python

python
import itertools, re, textwrap ot = Path("/mnt/data/oracle_transcript.txt").read_text().splitlines() len(ot), ot[:5], ot[5:10] (1200, ['1 2', '1 2', '1 3', '1 3', '1 4'], ['1 4', '1 5', '1 5', '1 5', '1 6'])

Python

python
ot[-10:] ['6dc3a5ff67b60adc4bdfd02d2e4e9b2e311004e9e4c34af424a88b77b0f0cf02bb99d020c015687974e74fc48c4141188b9916364479fcdd508b136bb18d649e579134b9080b5fa0fadcdb96000a17ea4e9edd2d1afc69dda58f2686139156d3abf3ac152b57b35d6dcfb6a51b93140faff8222f40774d519225a9b961ea34f9dd49317e8b00599df37aa67616cbec735905d1e56df608d6f58709ca29a40226d25470b053e16504e80649e244c52ebc156f25b099635f77ecb9856f91b15d6dcd9d0c000fbe3e94a84d30f87ad1633001334447a1666ee99fe0eef75d47c807669d46694741bd3a3901d5b233f595c36a7e9f5252d4f6e9c52012a87a0ee1ec 5957817db24389d8a25cb333458385949fa16abda1767cb61132243b66e13f1713b1faa62ea1a64338c0c10c1fb12e5e5afd3c8769ef794135bad639e3c5e3181f305774f3ed3ea4495a33201d38161ccdc21ec6266f23c9c0a1477fa15d167cbae6d8be93ac6e806a8c0dbae557e9e28cf3a068c1040e9037ccd9e6208bee9b1b9e8c04cf5225f0f6cdc0be453126e6aee7f21242d01e1414e40a3c6846de49b2393057880adfce338de7643d30aa5211f7e52187dac8161a4eb82b687e52428705ea68b37b851848734e6b8cd1e3de2dffbe26fd7a6d9e1594ea8c0af5e85c5694eac0b9fac2123194b6daf35a8b6a6e9ec68c6f5b9cda109ec8ff16dc6150', '49df0e19b7e0ff3886a0ed6202535746795e0987030116722e3e3fa015e804d6fda925eb332804cdfefc4bdd78bffca8c8f9438fa692f42621eb91f8fc9aeeaaf1b8985e8fa954e0b247524708f1021e0ecfae07cc985eab5937ba8970a1b47cef5fe8bafa6c98c08bb76670ed8b826c1a969bc6b286a9877c4deec4443c0175cdcc61f191baa6bb8c62ca814fd9c6721612505d5763a98b169482a7b5c57e46fe81014ee563403c030bbaafe047527f534de706355b9080c500159292f837739bd8516750f09ee927039624183a4e8f4e9839378ca6fbeaf41579f2ce640b4478a7a3997adb9d46421f91f67249f3e51cde532198770532df2925236627fb81 29109b280ebaeeec887df63e52554ab051b2aeb1d7dfa78e42bfcb40c3c21db0587f63f4ee37fe8079b63a42aa9cea727275952fbb67d715eae0d44a553fbc246e37f5638cf1d9eee9672e8db5454f47727689b58107821e1896b6f3ce74175db6b13283437b2162bad8cf61f6438ea07859d76dd33e3aa03a9f8f6d4264be80937138b02debefa3384084e9f3475af564a48da863952e55f0fb97a9137e94ccd7dfeb7b1da05d0ef70a3a94f0d9aea3b5c1b267c6307fa912b6bda8d933c3413b9db1b0672453e96757c8d6e7f1a4c9d0fad0dae802eae06801f9315a2925475b206031b47423b8aea7d4de04666c10b7d8823c56bdf7ee99e342d4a6116b40', '19eeb09aa23d9dd7cd13f15a9c9c311a86680bf587788787b1de8afc43413f6c385d258ccc6efcd8f98c12a864b0c7545c9e8405e4bc7d6d78874956a44de6e0daba3e1aea63b8b2ac9be0729a735e854f834359f416c686c70d75111d9c3b50c829baa14935495d2f07c29c3033d60a445ad88a7cff1eda7f88d664e0608b0c7e23394d91bec9df0c8bd921955579d9f9630b8c82f58afc5f16052fcc3b7378970b943bde083f96d5581b21b6a4758a9d95e78d31f878629293540c0025645cb365a147bbdc05310fd2d6f2bdc2fe56b09d7bb00fbcc08264fe8a5dde0c972941f5fc290126854a98255c63e41266a22b42c896be3012b9dbbedebc8359a447 5f66e12ee3061daf7a5b6bfd431ba3b0f7922120bac8633884bd823db311381d9839f766d4886e639c4f96958efd4e232dba7a03b4e45623c5a0012eee03af97eef50e0d8bb9200bdd6f15d38969f65c0d853a0071810d436f76684106f2cf61f09c7f1229ab031b3b3ac7a6e698f98a5024885b455b6c546d6683012e058ecaf945cdb135761a58643c007200ec59c18133e8e8d8b4f497b5ce0d1ac77239a954c623e0602479913d8e3d00f55815dba1cd19aaee9674680f60c5c902454e66faa9100ac48e224bc95ba24f86c4dc24dfd9f1c827db10398de3232129b394d3f7e856db1e1f74ccc11bbba4bf6cfabbf7d2c4afef208aceefb22f2f35a4c66d', 'a5397ac02cbfcf20a2982b7e2a8572ebe4271115002b960878df1e6586e51e924c2d6da70ef58414fad72e13b3a8fb42b464a38abb86b3dea88e7d2c561d3f3a40a812ef14627d685001d198712cceb7f3dee6c68a08626e4f111eb155358e9846a4a79daa10221706760f69d5b4768fb6a21ac5ea138dfe3a81d8415ae43914c8f6b6d848c50e132a2c3fcdabf97a7d4dacb5c3b11918d0374e2129347dde71fa1fa205a56c55685c72877c6d5282530e059c20d55a093cae72701ad58b906d52f938f0000f9fcf8bdba540564b9a3f7f304e7ab5567ca81ba028117fac1fbd8f0f3fd261ac0691d8b2939317b4d1a9e40571990f9caf5819dc830a5b4efbc b8f126cacd6d07ade8c79fd538a696a9d95d35ec31e3f5ed78ca6ba254277b3130ea1081e78d1604bf77276ed98387691e2247ed67dd7eee5408d8cfbc373fe5fd064d89994ac33a1b3d32884a2a94f1ad05090ca5fed83bfd548d9f5b895ffadb284ae95bf86257e0344778fe182c1bcc4dde940ed866335f6641014cbd553eea75cdf19046d76c33139dd2aca9d5e9e53a406dadd3faca689463123d5602a656a500f0fc08d4333c4d4395cdee1739ea095c7a324b9981e832f7a2f827ce1905f62a75ef7c94289b6ecde62b011e3a5c9263b216cd307531c2aef73fec137410c86cb12aec8e6a104a02f4753f706c346ab0d3e3a61d8b757cfa655a32f74', '6ba0974ad1f86139c95affc9de6d212b1d489a964aa4ae769a72872b4ca1a5370701577227481281f92f3fc09bb5a0a7ecbd69307a794d193073f5a6eff13a16ea8fe26b191252a642883c77770ae7f99cfe27b1250a2bcd7638e1c9885f62184e58d6ce8f54d8eecd45c2871431d79a69376a9ac97994cba595b5513491579a8b84e24c0c02e99d3c7822779ff29b4edb7130d39da18891841db098676121518ce3449a74b671e5b2a9f5dd424f51c954fcfd476fe735652109b298461d71bedc5ac30b924b6e9bcb85b272cc37ac37f0d8f8919247884014b89be82ee588c54efe27f25d411ca81ae0e4c140ddb082ced4d21f6651105cf079c9af091e6041 1b118489267a69f4886d7b8c5ea5399aa99bb44cf34c12ddbe0e2a5b1063e4681f82ac101662696f655251cf1e26402205c14fcfbf8c46696e4c1ba8de41ee3c1860a1ce855afa9da93428810e7413ce5f1e5a0ae606f66d8f75018af4622b2a86fec0d1ecb4d3ecb4599a093688ae86568597f09e965c4666692da5c53ac3733cdd1f4bbc24daa1fa9c32ed8497ca0692d0516ef841777dd533b1170eb69e1316658774f574bb6dfb1a4721588ccc2c02f56c5c8e1ba17b26702a2bd7fd0cff0b22e47640090879b06047b02ea399337e3187bcb5d6a584b5ffc9bbad4de44574c1f374faf860347fcbac8855a41f669af1d14939205d7dcb1d8e1287e23c03', '1802897a7a72fad0803d182bb7b7f6105f63cb4d43f148ecd12f5acda1268e7b9223748d57f87f564e30d859b110dc9bbdace30e1ca66f48a3d0b368accdafbade2770adcfa50d620887b0a8e721c279e2caddf739c854265f04abf549973801964ceae1d89beeda9a7fe3ac22015c5629d684a14272c1c6600bead0ff62c49fc5cb22173344889f15af17c6bfb45dee61622c14e8506d665d9b7aa042d9c6247e3a5267384b960016db37367b791e672e6bba923dbc284a4e3afcd364ccce599d91d3d242dc0db684bd54a9c501a55cdac15a54538743731a9aa96ec26f0ea80b19801bf5d6a6dd116e787839de21000455be9a20b60ea71f512d0382f1ca1f 4637dfac3ae1d28ccc6aa7397ead5d3a2773b5022ee9cc2e88c6fd216ba62758fc0e1b8da29259ef4a0fe046115da15aaf7f4be85b2bbd2dc7288c76a72413ad4ca701a3391a0399bf7a0ab9f7d26465c8138e80eaeed7f8176e56794807b5908e5b27a10b7c2e647fae4c4da0367a0c1bd2320dbbc553b3a5e743f0f755d51d9fa38e0597a7cbf019c5f49fa01a63affed812129c4556e53dca05aa71336e416b441e95efecd145ef85c02ff98a2c4da6f660ef40b82e3bdedcb2a41fcd3d5828e591319fc5f3ed57893e2fd1e6b0fda9a868b41e904d4f564a78fcbc81512af44b42a8cdd9e5f022f9e2f4dec2091fe028f353de0f957d0ee77868e4c0466d', '102e7f8e26d71b5934cd5b9ed4f899fa66b32e0beef8ed4f3e91b7527a32450d683870cb015b3a3dfe172b0eb4574afd7c0b89118d88ae3c03fa51441e551af271f813a0513d9156b36acfbde2f5401b20515ffc3ba9add98ba29ba1949a596b02ec9821bed87d12cb70deb7dcf50e76387b217b6abcf6c4182e35133bc27dbf619810f3f356efeedaa80e9e00b265a7bf11a4609082205864951909283d76d4e34a55feda86894d5cef7fa16de0ad111d86ff8ccc3224de9e9496a97c748178d88449b9cce7ded89e3205d1cdc34ea4752898339fa6e5ecb98975222cba56e229a93e6684f53b75294f5c4b5321a77199130a472d76e62ddd03c91e5cab5f6e 29dbd38ff8ca8e541112c28348246c3eff879349155d9758297c83a1fe04ddd66f71cfc3cffa64b54517a9d3f3a8b2228631ab338b5b9c7d84aaff84542eeec3df6e40a8427290066f20c76f3bee0f27c0fa7bc8ff898987bd9fb0665e711782a41c191370a4a3b762b207bc47bba81f3eb8b070608dda3ceea4d708c4de3e8e327145edad7b1fd639d38b2131ba346a9b626682e0a0098e064a947508f32cc2b64b1a25c7eda39175c4592e43e070365b4718e963e639084b916c3efeac9b09ce18319f5e110772095b804468fc16e21352d9bbf79c792a3d9139600f726f7e4c2619825f59774d5fc8d696605fbfee2ac4c677e0578b7a1df6911afce91a0f', '4706da68567259770b35470341f8f26193920047f81979c4bbc7f3772661d88af9fca31845b911a881f37d2790a91f9d499c2537046ce717dc2b798883e49925e7a4b780d467837ed5faabe328d60cc4e9d1df33502b655a6e40879ccc7925e6f54b39c3eea394ad6806ef587ca0e2b672dae82527ec906b018028eb783e58afba41c8cdfc89edad98f7f157afb7ecd148c04c1778ec4a025f8f00df4a8ea4e353032fe5878b888f70320c17ec1ca7a9395a2d136b9171a8cf76feec4ec099f0e7d5fa579e7a659e1379ac3739970d0d66576a1a0617fa6cb23762de4ba68158f5c8f92fbc58609e0291f45dccf267fddbc1beb26e2b43559918b24b4a45aa1b 58e537bf39c2ab09a8d3d9d2769c7d72f29ebec4d1180b6d5ce14ccd09741044df66e3921b7389cab9d82f77e4d81d00ac1ef5aae6b89349b760f6baa3a4ec57a8d2be2830488fe3438746c0ed38438e6a1a2e280e4388213d3ddfddffc29656b6b197b1b4201fe499a72614d6344412b7ee8913c2ec5c3c8d7d879b798d2d846fd0c6e3d2a609777feb6a95a8cb3687aeb62276c732a2c2a3775bdec28829e93eb385b915fa3744819d367bf28a017b25811c5e338bdbbbeb8bebf351dca655b40a2518c00093855cde5431645257772544d1166d3ede26da383cb9a26c84d350ffb2437b6e476ca7b3c10705dc42aa27fc48b66814ce3b27422b3de2c8f3c6', 'fc80f0e08a12e4552f74631d38d091f767161c92a0a6e4d90ce86c3ef595d6dfa053cef20257a6d40e1a83e05c0b6cfbe40b18c4cb98eb6e5eb92d2d324cc55422ebb17484a868275155ed498e2246bbcb49dc3bc3629242d3d1cb3895d351d1027b6504a6426ca3c1d2d93946bcd4245e18c112e74db463807c0ce62cb0d5be1432c36ba3fd3c3734b1287991cb12d6a101a594913db80c8824973f6c2581247cf1ab9da501e19210d209c0e4818f1f8ef0a6324ecab69c3fba45e0085a5f34b313a264161b30ad28b6c42bc54cb4034b046dc15f4dfb96573a8061a9ee796ba66aa7921316924083ea4d92776628e70e157d10c48f444892a0eb0b7562018 e33a9f3f336e33cf82e377e27eab1ba50fee263426e0a371fbf51aa1436a50b01441ae278b918abce1408ec3b491c2d13878d8d75ceeecab81e9f32c78f6a5675f9348d7f100021d6d4ea48125517a3e937a6dfe3a5fd9772c30d21c428905bf6a55eeb0994e48cca064e4be5bef822bc409137794f05908343bb163bdfae7b929d3560cb9f3d0dad60c11a6b31b797890699e04874414594b9c6fa9e091f97f1fe3300baa1bc015aa3073829942a2e97a2aee97011c1552aaf60023731b91425f4d75c1feb1b87d697d6c5024cec61749c2cf50ec13f64a721f87a352acf9ac90f7181e870c687bb6d5d14215497b9a11a3c90d07a36321ec2d05754bed42f', '464c1b4adee3731c5372f912385ae67ba74055f282118e8cedbbaedc389d8902d355c9f9fc0abdc5442a15014c167e56b0ebbb5c0cfec997a067a09db4deed4f32f84aac2213e945adfa4a1d7e61a46824da58eb8db7e24ab32f83bd65271d81ee0a5f9dc45934c9e240b6f77da8f130dbb5163238cb60f7d610d1786f3f1f1d5adadccc69c59cf6e5f8a20d10f00d6d6d1b216bd72f9ea16ea3d8ecc0a0f6cf6b8665dfb4d97faca774d4f0d6a2454bafa9c04dc843f86f5a54c3a9b9e49180e1e68c17622707436f494a7744e175d69a798f1cb3be7bb4115de543b4ac3b1ada91a954fafaef681a84cc39b6f8449749dc351a2b1e32c20be29ae1699b4fe8 666c61677b37613934666171652d653061332d317166302d383532372d3330303530353735363132642d39383366383564392d653061332d313166302d38386363be']

Python

python
sum('...' in line for line in ot), ot[-1][:100] (0, '464c1b4adee3731c5372f912385ae67ba74055f282118e8cedbbaedc389d8902d355c9f9fc0abdc5442a15014c167e56b0eb')

Python

python
# find first line that is not digits and space for i,line in enumerate(ot): if not re.fullmatch(r"[0-9 ]+", line.strip()): print("first non-numeric at", i, line[:60]) break # examine around that i0=i print("around:", ot[i0-3:i0+3])

Python

python
pairs = [tuple(line.split()) for line in ot[:200]] # print first 30 pairs[:30] [('1', '2'), ('1', '2'), ('1', '3'), ('1', '3'), ('1', '4'), ('1', '4'), ('1', '5'), ('1', '5'), ('1', '5'), ('1', '6'), ('1', '6'), ('1', '7'), ('1', '7'), ('1', '8'), ('1', '8'), ('1', '9'), ('1', '9'), ('1', 'a'), ('1', 'a'), ('1', 'b'), ('1', 'b'), ('1', 'c'), ('1', 'c'), ('1', 'd'), ('1', 'd'), ('1', 'e'), ('1', 'e'), ('1', 'f'), ('1', 'f'), ('1', '10')]

Python

python
for idx in [0,100,200,300,400,500,600,700,800,900,1000,1100,1199]: line=ot[idx] print(idx, len(line), line[:80], "tokens", len(line.split()))

Python

python
count1 = sum(line.split()[0]=='1' for line in ot) count1, len(ot) (80, 1200)

Python

python
first_tokens = [line.split()[0] for line in ot] # get counts by token length from collections import Counter len_counts = Counter(len(t) for t in first_tokens) len_counts.most_common(10), sorted(len_counts)[:10], sorted(len_counts)[-10:] ([(512, 980), (511, 131), (1, 80), (510, 9)], [1, 510, 511, 512], [1, 510, 511, 512])

Python

python
second_tokens = [line.split()[1] for line in ot] Counter(len(t) for t in second_tokens).most_common(10) [(512, 969), (511, 146), (2, 43), (1, 29), (510, 12), (132, 1)]

Python

python
small_pairs = [(a,b) for a,b in (line.split() for line in ot) if a=='1'] small_pairs[:20], small_pairs[-5:], len(small_pairs) ([('1', '2'), ('1', '2'), ('1', '3'), ('1', '3'), ('1', '4'), ('1', '4'), ('1', '5'), ('1', '5'), ('1', '5'), ('1', '6'), ('1', '6'), ('1', '7'), ('1', '7'), ('1', '8'), ('1', '8'), ('1', '9'), ('1', '9'), ('1', 'a'), ('1', 'a'), ('1', 'b')], [('1', 'c9070abca9aa12b38c2c4c7a83ae66623107bc10bbe430601ed0d83d6599fe0644e60f458365194e19ddf30ee9ca7f36b78a3056c0cfa04a7ce85716b8a5673b1b1f16bda6b1e13a356241ed32df18712a0574af7ecbca47adb20f4ae3e5a15de40d0ea4dae54d805acd8867cd48e24aae727b6d3555568de9e01248174ff96b43ff1a08bb77933f99ada4b4de0952a505761e39f215005c0416d19e3a28b09ef9b749c8254699ff5fe9f64189752dd0d2250fb5f409eb83b99525ef14ec4bb10a0e0c502d5348a89c4d28ba91ff0ce2727613fb740f79a5781650172736952b5e21259a2d82057928810660603e23e64042cab885e1611bb60a11a94f780f3'), ('1', '1a2e00b87a5e59627677dd3918343dbd39734ba10ff8cf7e7cbe6d002c7d0ed0498d04aad96abfce9ff55f9329137357f08cf06b22fb440ea6c6a2d409a7b01a027325cf04bc9d48301349fab11585533180bf753257930b4517d15c5c2673d83b284e34219de229e35c992ebd9acd5bff04ff457a5b8a14b268957569c91c0f3f362818c2192c2a4385b762172b7600dd6386e6938034cf6590df070206117fe05c8e517ff74cf02cf2d961c2882b31cd1de2eb2f65f60b1113c5972c8300b1873d3d06519e26f322d24ae61bc465ff34cffa211aed2836625deb42a6fad28c5c004393a35cd03c3190cb66e8815008cdedb494bb7a7a35a32250a58efe96a'), ('1', '27'), ('1', '27'), ('1', '28')], 80)

Python

python
pub = Path("/mnt/data/public.txt").read_text().splitlines() pub, [len(x.strip()) for x in pub] (['75b8da92a0a4caf5cc838133cf138aa114d10cdcd05a4664dba48417b3ab64959c7f56dfb5fd05bb8165b069f22466f4c38478e98adc0f1f266fdbb53014c69300e6b8ebca8e0ed0037c983c75695ac3cfee1527ce88c407b8af6bbe84d0dd8bf3982c97d5f2080b9c269a181af5fa2116e87fac295dbaeb1a0f0b992454083d02397fcf4f29e0c6bd7cec57e17737aa9417a0520ffe10622fcd24fa9d5ee9c6e6aa6afcfe06fe13f6656ffe3da9be13386d9a15b34187ac3637080b0535ae982dfd14e359d2d4c8dabf7cd378c9e6644e75f6cd72d2db08c84b7dd0e943588d9fb9713990643d7fe082c4db085ca2f71443932e76fe91cb3bf14def5138d223', '10001', '9342a05c47464a3dcf47b42f'], [512, 5, 24])

Python

python
ct = Path("/mnt/data/ciphertext.txt").read_text().strip() len(ct), ct[:50], ct[-50:] (512, '464c1b4adee3731c5372f912385ae67ba74055f282118e8ced', '681a84cc39b6f8449749dc351a2b1e32c20be29ae1699b4fe8')

Python

python
from collections import defaultdict pairs = [(line.split()[0], line.split()[1]) for line in ot] by_c = defaultdict(list) for c, out in pairs: by_c[int(c,16)].append(int(out,16)) len(by_c), list(by_c.keys())[:5], max(len(v) for v in by_c.values()) (1121, [1, 9294107957698732143720338378216337214277938278115359659647802770534617245790249293255128742487215270747502189735363604583273874593146913321940654313646093708573313524769270642423729697282060371546387037395439084211816603924018299631401303340833263676092101969879488199601871317501655560966898421158291687504232592129562473311662269710048086076409242368442273769629975956513064526097152168332347054164149192705223776203038433777616149485312591389264348457919887784384232972315830433156307296856550523891516385408120719669203599071419425197623963923756196195435460129688155286177456362037952682478271598066424721630562, 14402202220154512124936911078396872817497235259021297975884452726343651738027091042594144192071948254772664418592516553136604526295142316570730876276285431987374709755845957312960852871321461392715203756545133977836893840195647951635015845547297861878281039301242136048754502403580230645060437622270595382850133598144377883332455219467037176431259803155174893279511340759202328104423128740535493413061517740004638472853159134903104716850154521340497982371766493048738882332001049262487508831492419826873325798010475011412134155625138821123286965289175428048715108837979297795575312841787253356578946188400801635281099, 5249866050840201572641930699060169955595937227612276435839073648280729281564945199044506820059476037177636631678915699440507746011955845940696762684491485157175201929512607149736106085562560264947538408000955557968844088433082115157967691959284885394094663713388543078407010356564933558923779036925104000352607950065548819159621950859481032308861573566529007702137756926095537512540813518974445198190573355561394733034389824672684665305596545452277867047673161514477951714616623533133191870955572021839294558087166774777618123749540008213499316167930551788293046744491630570632160723468391999426045363090264565372151, 8937924300344537998232484367166710019899208515784525631134003888918121592370397934286675246911310714617797263009457679446729124088021365379546335423380048455271046087749373410141424725579402231197563653147825609465468425617944304596589995435553532787707812494139916189547962520118548193934084865890568082456613849544437794285750770798376326207837357413147836139873938727201327373588406961938690395240987484045232252606543564400371067382315476117451562842026041026546862160675563182591010536129947797613680350675131853308508414274482970624679531905801960559031836635583424168040688348357775371600092212774577705382806], 80)

Python

python
outs1 = by_c[1] outs1[:30], outs1[-10:], len(outs1), sorted(set(outs1))[:20], sorted(set(outs1))[-5:] ([2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16], [35, 36, 9003845892140836976852669031698959030926563959668678418101500759762648284722761125296440135703146680490658738112324936823320803716632408508676053535726258557151074439637219383452368658155625992742361289076244825437713827761679808684758576639902723599581509599089176961101258650006320241185756713077825841835952082048287906060927185921602040231030145067015924173884030502243149478873036307533837668393930575336659484381595629050797944825191164688742096040371033903906256481753073166010250771579288474238775817543500886851658117597072156851668908332537135663289732947846555528531656958427069948723523339081640102239452, 37, 37, 1586085738052366365764350514680054924586795566827071602585226739821157153550474169713661921119282094063378006854786427108153396879660924616855749397359608431068528081715549072624191582047094244155845632759983342184133241279008258178532379449030646945476264882726573475372259253278953574035402806097184092107057548576626046999803052091990609504452326939660015949261422359164100811043748244709874428692203666392331371434900443510773712290747225603417936047162177370831864576660404043552476980608961725671003398263123635285337017438996603064932659911404857360235381367468895814370471955887573500828158374521602332655859, 206555047664088928671500685972965348034101563723383967719411498727112265386176589620137659100139105961867829966958849277489479303916472435904640467947537939117635035950663942674522084345155314647663133330581110658320430470527655187669125694780172510523100058823930509072495778026954317560996665014156233986584936345944953455831942375246640899841867659954457354644055302885816980420992771472329664086347480816303331730367211809141679747933802599414683467277223474711918509520169669524215855366124793070793275898032355822709868141540229796175458373402544690566331110924376011662024859644846168894295205227649221781866, 39, 39, 40], 80, [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22], [6671655522950861035532749682296961337345877343083041713005104138714882423011183675162181090545200651608383550319483141033703756344251801028095379972106995263249879825422500844240122586377797300626476619849075001379198532908514707410448670260856090597185878662582574232002435193790277954983198524597166406310079922928242439906169953946623380529598379731295665688159557084602778924584991907940701462724866726464530374727413968527739081347700008355802926862418394050369812241965313329225564810574597346775267610938158392458825548936061654641188033972645669606858001559081876162752945245104642807995423399559280138065625, 9003845892140836976852669031698959030926563959668678418101500759762648284722761125296440135703146680490658738112324936823320803716632408508676053535726258557151074439637219383452368658155625992742361289076244825437713827761679808684758576639902723599581509599089176961101258650006320241185756713077825841835952082048287906060927185921602040231030145067015924173884030502243149478873036307533837668393930575336659484381595629050797944825191164688742096040371033903906256481753073166010250771579288474238775817543500886851658117597072156851668908332537135663289732947846555528531656958427069948723523339081640102239452, 9188217047407821341953058740787077865691146515276743192177865909342314460735805523455183802921653197390212816273552846559822778004731563354865387211488549705557960517865177139295246440636354769076997452915231409371030487124735090562423323088509811954454603593250621456221823387867322419148019250260845017519419410256340078356086720089590633177216674594955043387741762503756917350654459278188436462906694071878424262800479906685811843157036792381682625249909656819011699782948845018352370057846565430419511617857154526310021325956541864632496549338279440986873132353712109202537262206098242862150693190255270495806050, 10268139581515045182463031502322687370033373536934743079297759191687962101984970403152711625034734343858533544808058412603114815481712689611891371538244971885402419166054145956135645717215199066996469192240883034845875408230026479298398802403001501979490503813234634213905997955547303716706104280858281604188528978046385521058518398969225005868466878335537981646852495944865680422859071765002943920695729447313132929657053652972237733498553329773572483395120120757294502623417459096680176619631767767569886027494945550063921806212713833506048549427510039920943474168820249556769991062744089622277242056347055295487117, 12259381257940982878083008366933714337517951017979248333719398130023922134804671392879306101243475607782824104542606261006431707618146331455832561014914080386218309184957220338903853397097811793660422691910400098278646714569850297090710906617898557192158387812761338295309531898822063705952844854513713697190948193880295601467324551136245489936744377975218177144381717126542817690993209473308470150149748826657857523465872310239711283525189858172322806637537678488864602006564336338182301267851142080810946675326660198454040467534710956876636889777705554248373039193848719108562824109702218815459293843564936299773353])

Python

python
N = int(pub[0],16) e = int(pub[1],16) h = int(pub[2],16) N.bit_length(), e, h (2047, 65537, 45574842828705878606980035631)

Python

python
# precompute ciphertexts for m 0..100 cts = {pow(m,e,N): m for m in range(0,200)} # check intersection hits = [(c,m) for c,m in cts.items() if c in by_c] len(hits), hits[:10] (1, [(1, 1)])

Python

python
0 in by_c, list(by_c.keys())[:5] (False, [1, 9294107957698732143720338378216337214277938278115359659647802770534617245790249293255128742487215270747502189735363604583273874593146913321940654313646093708573313524769270642423729697282060371546387037395439084211816603924018299631401303340833263676092101969879488199601871317501655560966898421158291687504232592129562473311662269710048086076409242368442273769629975956513064526097152168332347054164149192705223776203038433777616149485312591389264348457919887784384232972315830433156307296856550523891516385408120719669203599071419425197623963923756196195435460129688155286177456362037952682478271598066424721630562, 14402202220154512124936911078396872817497235259021297975884452726343651738027091042594144192071948254772664418592516553136604526295142316570730876276285431987374709755845957312960852871321461392715203756545133977836893840195647951635015845547297861878281039301242136048754502403580230645060437622270595382850133598144377883332455219467037176431259803155174893279511340759202328104423128740535493413061517740004638472853159134903104716850154521340497982371766493048738882332001049262487508831492419826873325798010475011412134155625138821123286965289175428048715108837979297795575312841787253356578946188400801635281099, 5249866050840201572641930699060169955595937227612276435839073648280729281564945199044506820059476037177636631678915699440507746011955845940696762684491485157175201929512607149736106085562560264947538408000955557968844088433082115157967691959284885394094663713388543078407010356564933558923779036925104000352607950065548819159621950859481032308861573566529007702137756926095537512540813518974445198190573355561394733034389824672684665305596545452277867047673161514477951714616623533133191870955572021839294558087166774777618123749540008213499316167930551788293046744491630570632160723468391999426045363090264565372151, 8937924300344537998232484367166710019899208515784525631134003888918121592370397934286675246911310714617797263009457679446729124088021365379546335423380048455271046087749373410141424725579402231197563653147825609465468425617944304596589995435553532787707812494139916189547962520118548193934084865890568082456613849544437794285750770798376326207837357413147836139873938727201327373588406961938690395240987484045232252606543564400371067382315476117451562842026041026546862160675563182591010536129947797613680350675131853308508414274482970624679531905801960559031836635583424168040688348357775371600092212774577705382806])

Python

python
# show sequence of outputs for c=1 outs1_hex = [hex(x)[2:] for x in outs1] outs1_hex[:60] ['2', '2', '3', '3', '4', '4', '5', '5', '5', '6', '6', '7', '7', '8', '8', '9', '9', 'a', 'a', 'b', 'b', 'c', 'c', 'd', 'd', 'e', 'e', 'f', 'f', '10', '10', '11', '11', '12', '12', '12', '13', '13', '14', '14', '611cedf4c9abbe1f1386f985b8f7f0520be6051c2a43b828ab76798f4969d381140710b37251d20bc9def234f7cf3ed55e0b84a738471f9d78b72d198edec7fea6d74e930c2e28672b0469580b7746b15e96e1936b1962118a34437b12399b35179590ab6871a980656039a1d588942d28cba760107649a25a00063e7e48422fe41b74acfb43b963115c660ddbaeda8c6997d18293c4ac061cef0810b724cde9acc557742d41aa8aa005ede2ce1644c54c9366724777613a402a79699beef23f3dab9a6e8eb45ad8708824cd49af1625ec73b4127872a334f45825053c0a29a9f56642cd40983aa97e6ed16bae087474da9bc270e0e1ac27ef67d7ba72737da9', '5156de8e8c9848a8d49bff590e2ca706cdf12b23b578d9e0379eddc2467c4fa5110883a6461e3397751a48875ddf504aa6220e5a98387f11cc1b149503dd2c587b7a60c9823928414d959f3d0d1bd09d91196541bc765127bbff375de2bc4376115383a15a988f9413fc2be3582716704c6b4ab849a7962d8a85f79e87e7096a3785ae9c1a2b02f623c05ee78c832eb8177bff2c9b747f3fa788bb0d6ce2764f7c985891c3fb99f8ba5b247122ad91c900471cacaab74f569b14d831c294eb061d98211f568d263137791dbcd1ac070302f55dbaebaae9c83af7dfd01cca2df3c33ac6b0d34354a915fc770a4bb386bd07c24b89ee83096ea50a4d771caedc8d', '16', '16', '48c8e20b08d7037df71bfdae2f8d6e51cc62475dcbbd8986ce63980dac23291f6fb1a10050a8099504319689c80adac5efd1a3c06a5337f23b0da6aab66d4a16129cf8b48223b4284724a6d3e18ea1af893446d09b60fea946af711464bb160124926053d9ac63c3e5939abc45009ddba187876f44980c18014784558f42f195fc20f34b99c1a0b16a884fc4e91f18a143b637362324afd38d2819ae9aa7eacf8e5cac30a5a5aedbeab4c3f79b8663b1c0c4f300e6da9c58470cd47e7e4f63e37278c1343118df14cb08955aa0b6bf7a59579a211bd68262e46483088002a355cca637e23c35f9b581194ee95038e26a792df1559a116edb993b2ebd98006262', '17', '18', '279bfa76ce6f6a3947429db18a04b228cb622ae1f3fcc826bc0587c91de0bbd078cb1edc6420c95c26917b731d9d38494c7cf7a0cbad96375c056861ce3067fd9a916bf7b5f5bb543630a1882b8c72af56675423c2f507a4f59dcc28edbfedc663788fb1e6987a3df74cc88fe706a6d15cf848648648f43274ebc4f7beeab2afc5ffba37780c8ca78126ee8abed6b7e9ca4c12f4cc52a09a19500b485fa4430cfb0b393503d8d451de516f6fc00e696fbbf84067a70428bdd600f1d5bd3160b043a04106747c3355ec6f0223293f18ac2c30fd98ca46eb2147ede27d66980a267f82b82fdc802bec0d2d2a2bfebf4757faddd5feb56ed4506b544947454abac4', '19', '19', '1a', '1a', '1b', '1b', '1c', '1c', '1d', '1d', '1e', '1e']

Python

python
import math gcds = [math.gcd(N, y-1) for y in outs1] # count unique gcd >1 uniq = sorted(set(g for g in gcds if g!=1 and g!=N)) len(uniq), uniq[:5] (0, [])

Python

python
c_target = int(ct,16) # find all outputs for target ciphertext outs_target = by_c[c_target] len(outs_target), outs_target[:3] (1, [351557825396240889191974411785646141604173081688455298181959658657301774223318617972403687882710619875600607465938547526540082353805220674671890173058626053054])

Python

python
for idx in range(75,85): print(idx, ot[idx][:60], "len", len(ot[idx]), "tokens", len(ot[idx].split()))

Python

python
r1 = [y-1 for y in outs1] # stats import numpy as np, math small = [r for r in r1 if r < 1000] large = [r for r in r1 if r >= 1000] (len(small), len(large), min(small), max(small), min(r1), max(r1).bit_length()) (72, 8, 1, 39, 1, 2047)

Python

python
large_noises = [r for r in r1 if r >= 1000] [len(large_noises), [x.bit_length() for x in large_noises]] [8, [2047, 2047, 2047, 2046, 2046, 2047, 2044, 2041]]

Python

python
large_ys = [y for y in outs1 if y>=1000] difs = [N + 1 - y for y in large_ys] difs[:5], [d.bit_length() for d in difs], max(difs) ([2601655229184160093206804700223146359951156057546167202966741093410886490771114894256307407853472037157017891408724182140726743155156457254500995660523870435425337799920717703984241836506429949747013210064788825692431709292287475532732039703927591330190263324674596376495979581309690506528457792757064311560593314244298353586090920847267687196580997999639571192811324702604217521725872343720181294311486781721478636552335062113284438954868034971267744981003644488192059623282589209468527583174496630631482833652320294907221699601873469745564324873493787829946957411476370613950920021966324642525597801288009792181371, 4592896905610097788826781564834173327435733538590672457388380031746846523590815883982901884062213301081308451143272030544043635291590099098442185137192978936241227818823792086752449516389042676410966709734305889125203015632111293325044143918824646542858147324201300457899513524584450495775198366412496404563012530078208433994897073014288171264858497639319766690340545884281354789860010052025707523765506161066203230361153719380757988981504563370018068223421202219762159006429466450970652231393870943872543481484034943297340360923870593116152665223689302157376522436504840165743753068924453835707649588505890796467607, 5672819439717321629336754326369782831777960560248672344508273314092494164839980763680429706175294447549629179677777596587335672768571225355468169463949401116085686467012760903592848792967886974330438449059957514600047936737402682061019623233316336567894047544185313215583688092264431793333283397009932991232122097868253876697328751893922543956108701379902704949451279325390117862064622538840214981554541536500911897217727465667183879323021100761907926368631666158044961846898080529298458793179073281022917891121825967051240841180042561989704665312919901091446864251612980519976481925570300595834198454597675596148674, 9860826789876653015412429228772830061601195580501915797193250813896617578631989182647747602740308607319256967398786674936108790673174684306660924485066608833658005819111469385182175598703566209033383565529318647505446077185984773186912214252870741914704494689362658394431937761625253138127713879760702031617327051198410506003759305335919812244185206086570069807585291979887612441056367328340694015739465881350347566391701739602274759060093861800615672517825893001393908799743828957573563710201620136533734426723434442967348043481798175040197248234017070632886535807524015769367983241099470550884911277063495685642080, 8189380964174281935757063384859899360123229732442373823681035084719926202564602611973432418551746993331458445631847302113454694429050987682238176703330955558393767159455437198647972647226444442780959282126113922591879890953623065212994276060970057925162772474853360439803076286341476257498104122673611602441461585196351515147245518036889796603726996243562082649033484744544256288134089909087949981736368881914805785290793403825256641132357884787787624756122928926686849387881612218425264040451041364667161898040822100902436618200522771981013180678553672471461995046243213559760798886563900649989468245293665953889099], [2045, 2046, 2046, 2047, 2047, 2046, 2047, 2047], 14654481439461054042618312381183895349435005511802031568966727724707696360189609697515475849996808538977974165984371593869668971469386316274428916207490412882526011948927274100213573149259086428759772768644607813312757993391610117435773820627045976011825551078612004162733015702104799894920305982256621774764956571778649001597583529608266536233483508314903290982548986526261218232298089045556321780374888127563032828287840160543854042732124090544175868151264099502344743120326755878126612995659513918371636233080948137538552298995044196826025756277796797387753665494400713710851719272023697289090596439625296870172858)

Python

python
diffN = [abs(N-y) for y in large_ys] min(diffN), max(diffN), [d.bit_length() for d in diffN] (2601655229184160093206804700223146359951156057546167202966741093410886490771114894256307407853472037157017891408724182140726743155156457254500995660523870435425337799920717703984241836506429949747013210064788825692431709292287475532732039703927591330190263324674596376495979581309690506528457792757064311560593314244298353586090920847267687196580997999639571192811324702604217521725872343720181294311486781721478636552335062113284438954868034971267744981003644488192059623282589209468527583174496630631482833652320294907221699601873469745564324873493787829946957411476370613950920021966324642525597801288009792181370, 14654481439461054042618312381183895349435005511802031568966727724707696360189609697515475849996808538977974165984371593869668971469386316274428916207490412882526011948927274100213573149259086428759772768644607813312757993391610117435773820627045976011825551078612004162733015702104799894920305982256621774764956571778649001597583529608266536233483508314903290982548986526261218232298089045556321780374888127563032828287840160543854042732124090544175868151264099502344743120326755878126612995659513918371636233080948137538552298995044196826025756277796797387753665494400713710851719272023697289090596439625296870172857, [2045, 2046, 2046, 2047, 2047, 2046, 2047, 2047])

Python

python
import math g_values=[] for c_hex,y_hex in pairs: c=int(c_hex,16); y=int(y_hex,16) g=math.gcd(N, (c - pow(y,e,N)) % N) g_values.append(g) nontrivial = [g for g in g_values if 1<g<N] len(nontrivial), (min(nontrivial) if nontrivial else None) (0, None)

Python

python
import random for idx in [80,81,82,83,84]: a_hex,b_hex = ot[idx].split() a=int(a_hex,16); b=int(b_hex,16) print(idx, pow(a,e,N)==b, pow(b,e,N)==a)

Python

python
def diff_metric(a,b): # compute modular difference return (a - pow(b,e,N)) % N for idx in [80,81,82,83,84]: a_hex,b_hex = ot[idx].split() a=int(a_hex,16); b=int(b_hex,16) d=diff_metric(a,b) print(idx, d.bit_length())

Python

python
# ciphertexts with multiple samples excluding 1 multi = {c:outs for c,outs in by_c.items() if len(outs)>1 and c!=1} len(multi), sorted((len(v), c) for c,v in multi.items())[:10], max(len(v) for v in multi.values())

Python

python
s="71162d30437273e24bb005914e1123178e7b6e82979dfe2e9ba545cf317a2005a2e0f29a35ed06124d5f" len(s) 84

Python

python
import re for i,line in enumerate(ot): if "71162d" in line: print(i, line[:60], "...", line[-60:]) break

Python

python
line=ot[1110] tokens=line.split() len(tokens), [len(t) for t in tokens], tokens[0][:20], tokens[1][:20] (2, [511, 512], '57ab822337482e14e6f7', '71162d30437273e24bb0')

Python

python
import math h = int(pub[2],16) g = math.gcd(h, N) g 1

Python

python
import random, math, statistics deltas=[] for c_hex,y_hex in pairs[80:180]: # skip c=1 lines c=int(c_hex,16); y=int(y_hex,16) deltas.append((pow(y,e,N)-c) % N) min_bl=min(d.bit_length() for d in deltas) max_bl=max(d.bit_length() for d in deltas) avg_bl=statistics.mean(d.bit_length() for d in deltas) min_bl, max_bl, avg_bl (2040, 2047, 2046.04)

Python

python
ks=[(int(y_hex,16)-int(c_hex,16))%N for c_hex,y_hex in pairs[80:180]] min(k.bit_length() for k in ks), max(k.bit_length() for k in ks), statistics.mean(k.bit_length() for k in ks) (2037, 2047, 2045.67)

Python

python
import random, math def modinv(a,n): return pow(a,-1,n) # use first two samples after index 80 samples = [(int(c,16), int(y,16)) for c,y in (line.split() for line in ot[80:200])] # pick 3 pairs to solve for a,b; check on others. (c1,y1),(c2,y2)=samples[0],samples[1] a=(y1-y2)*modinv((c1-c2)%N,N)%N b=(y1-a*c1)%N # verify on next 20 samples ok=0 for c,y in samples[2:50]: if (a*c+b)%N==y%N: ok+=1 ok, a.bit_length(), b.bit_length() (0, 2046, 2047)

Python

python
y_target = outs_target[0] y_bytes = y_target.to_bytes(256, 'big') # find printable substrings length>=6 import string printable=set(bytes(string.printable, 'ascii')) # scan subs=[] cur=b'' for b in y_bytes: if 32 <= b < 127: cur += bytes([b]) else: if len(cur)>=6: subs.append(cur) cur=b'' if len(cur)>=6: subs.append(cur) subs[:10], len(subs) ([b'flag{7a94faqe-e0a3-1qf0-8527-30050575612d-983f85d9-e0a3-11f0-88cc'], 1)

Python

python
subs[0] b'flag{7a94faqe-e0a3-1qf0-8527-30050575612d-983f85d9-e0a3-11f0-88cc'

Python

python
y_bytes[-50:], y_bytes[-10:] (b'a3-1qf0-8527-30050575612d-983f85d9-e0a3-11f0-88cc\xbe', b'11f0-88cc\xbe')

Python

python
# search for '}' idx = y_bytes.find(b'}') idx -1

Python

python
start = y_bytes.find(b'flag{') start, len(y_bytes) print(y_bytes[start:start+100]) print(y_bytes[start:]) # might include nonprintable at end

Python

python
# search in all outputs for 'flag{' substring hits=[] for c_hex,y_hex in pairs: y=int(y_hex,16) yb=y.to_bytes((y.bit_length()+7)//8 or 1,'big') if b'flag{' in yb: hits.append((c_hex,y_hex, yb.find(b'flag{'), yb)) len(hits) 1

Python

python
res = find_plaintext_from_noisy(y_target, c_target, max_r=5000) res (577, 351557825396240889191974411785646141604173081688455298181959658657301774223318617972403687882710619875600607465938547526540082353805220674671890173058626052477)

Python

python
r,cand = res cand - y_target -577

Python

python
y_hex = f"{y_target:0{len(pub[0])}x}" # pad to 512 like modulus length m_hex = f"{m_target:0{len(pub[0])}x}" ("666c61677b" in y_hex, "666c61677b" in m_hex, y_hex.find("666c61677b"), m_hex.find("666c61677b")) (True, True, 380, 380)

Python

python
from pathlib import Path, PurePosixPath base=Path("/mnt/data") list(base.iterdir())[:20] [PosixPath('/mnt/data/ciphertext.txt'), PosixPath('/mnt/data/oracle_transcript.txt'), PosixPath('/mnt/data/public.txt'), PosixPath('/mnt/data/题目描述.txt')]

Python

python
for p in base.iterdir(): data=p.read_bytes() print(p.name, len(data)) print(data[:100])

Python

python
pub = Path("/mnt/data/public.txt").read_text().strip().splitlines() pub, list(map(len,pub)) (['75b8da92a0a4caf5cc838133cf138aa114d10cdcd05a4664dba48417b3ab64959c7f56dfb5fd05bb8165b069f22466f4c38478e98adc0f1f266fdbb53014c69300e6b8ebca8e0ed0037c983c75695ac3cfee1527ce88c407b8af6bbe84d0dd8bf3982c97d5f2080b9c269a181af5fa2116e87fac295dbaeb1a0f0b992454083d02397fcf4f29e0c6bd7cec57e17737aa9417a0520ffe10622fcd24fa9d5ee9c6e6aa6afcfe06fe13f6656ffe3da9be13386d9a15b34187ac3637080b0535ae982dfd14e359d2d4c8dabf7cd378c9e6644e75f6cd72d2db08c84b7dd0e943588d9fb9713990643d7fe082c4db085ca2f71443932e76fe91cb3bf14def5138d223', '10001', '9342a05c47464a3dcf47b42f'], [512, 5, 24])

Python

python
ct_hex=Path("/mnt/data/ciphertext.txt").read_text().strip() len(ct_hex), ct_hex[:20], ct_hex[-20:] (512, '464c1b4adee3731c5372', '32c20be29ae1699b4fe8')

Python

python
ot_lines=Path("/mnt/data/oracle_transcript.txt").read_text().splitlines() len(ot_lines), ot_lines[:10], ot_lines[75:85] (1200, ['1 2', '1 2', '1 3', '1 3', '1 4', '1 4', '1 5', '1 5', '1 5', '1 6'], ['1 c9070abca9aa12b38c2c4c7a83ae66623107bc10bbe430601ed0d83d6599fe0644e60f458365194e19ddf30ee9ca7f36b78a3056c0cfa04a7ce85716b8a5673b1b1f16bda6b1e13a356241ed32df18712a0574af7ecbca47adb20f4ae3e5a15de40d0ea4dae54d805acd8867cd48e24aae727b6d3555568de9e01248174ff96b43ff1a08bb77933f99ada4b4de0952a505761e39f215005c0416d19e3a28b09ef9b749c8254699ff5fe9f64189752dd0d2250fb5f409eb83b99525ef14ec4bb10a0e0c502d5348a89c4d28ba91ff0ce2727613fb740f79a5781650172736952b5e21259a2d82057928810660603e23e64042cab885e1611bb60a11a94f780f3', '1 1a2e00b87a5e59627677dd3918343dbd39734ba10ff8cf7e7cbe6d002c7d0ed0498d04aad96abfce9ff55f9329137357f08cf06b22fb440ea6c6a2d409a7b01a027325cf04bc9d48301349fab11585533180bf753257930b4517d15c5c2673d83b284e34219de229e35c992ebd9acd5bff04ff457a5b8a14b268957569c91c0f3f362818c2192c2a4385b762172b7600dd6386e6938034cf6590df070206117fe05c8e517ff74cf02cf2d961c2882b31cd1de2eb2f65f60b1113c5972c8300b1873d3d06519e26f322d24ae61bc465ff34cffa211aed2836625deb42a6fad28c5c004393a35cd03c3190cb66e8815008cdedb494bb7a7a35a32250a58efe96a', '1 27', '1 27', '1 28', '499f9ecade02f71941e68da5346ffe3930a64cbeff7d7636497c16f31696fbd95fbd0f14a7231890b7dfe239c3496f51048b4c8b6a647f750083c921ea37170d186bc6a6fdab7308a93a69420403da5b34726e8a72393492a3d6a0e53a40b2f9cc94eef020b49d3ff70d5ce7fee1eed9a59f287861805770648cc82f0779b652ec900f106a07aad95d6a8a29279ac34b2173e51c3b94659516337d78979884959d3bac747f4f391daedbe304327fe847f2a3d316b62236369b74d01174fb98a570a21eccda86aa34a4dc3b9f39371e70b4e244ac11553d749ae4b3f321af7a0f61e04770972c03b13bfb42ada5d24068bda0ed7707797397dd1c4f6f693ae562 3bfdc969f15872587c7f8f8ed48f72beb4d5e7ed1be48fcf5027f2720a553ae92465e7acece48642c2c8543a743b7bc38a01717de9854ed4e1203cba8659a2352a5ea81ceebaed41591e6acdd585a3ebe5c20ddc613fe7529dbe45f60185b423a0fe217a73f4bd7b9fb8e7edcf60c370533c5e58e829a95a0e7e223762584c44f0d5e3ee9da02e75b21ca3dd3bef5a3d4a640d23651b4379473118bb37946e311acd0c357392c51f9c4aa211c37a40ecb1c0584d713ac0e421380f68385eb5d3a354fe0d830a09728145da1cd5416dc57a7a775c003d1a8ce967fdb1b4fdc62af2d321c9cbf3d326126a44c837be144c74aea01e296dd210260f50bd7e58a8af', '7216610089f7294659945d648d8bacedc71d630f2e88576c1cf48e803ec61f184aefbfd3a1fedcbd5da2c92610148ef5d2bb04091c50c0d54b21b5863b0a548a16731c015bda644a61bd285788e3a59579474965889a3f0422d6198b0d40508de045ae9c495924c0454301a096aa6cdc5fd1f0eb9358b54b5b434bbef0bc7a6056381abeb0fc284ee4c0b62f6d8c409a96a94378ccb3d669a38c418f5fe8ca314a59a2a9f963cf5aa68b0469dcf207f18656a944117d23809532d57411c53b6ffcd19aa7522449bc97793fede7a8c6d700c7258419d1850edd17794e88bcc16b8bb88ce11ae09b70fbd5b589ef1a35b0ab9e801b9f42a1cc955ed4cb09a6a8cb 131681a526f16ec7dbfbbbacda3c81e316492129f7e4463b3babf0ce68f41391c0074d2e64eb8f2b921827813cfdec2acd199e39a3e926d798ebcea676ead283a64604bdc643bd102c7b4b46a509c25b4be8caaaa9bf3d5213c94d3ac7dbb482c47aa857c9577d523d9c7587379236316f497a5293291e6f8045270de48c75620e7d07d2b6371a810becf634f025107a62ba00283bb8dae5850b0aae82616e1dd28dca9ed2d8398e21c09d16a8b395dcc35f089ff870b79d4532f4d3024c0df7d52dd0ac472b4812a1a113ce6b01261afb57b20efc029228dee0103ff505d84c4772505ccc96923e04f1c78fb78288cdf6b72d01f524a8c01f165695ef72f51e', '299642577e49804bbbbc9d9b76bf8c1b9617e0a4555efd16a7812463f03ac54e00bb320b769b2c4befc65000af1a0633b38d9bdc2d027813b24e6884ed49ff0bc42cf23f55dade61232b96a37f5eedc6c3504b893f98766beade4421d1a19dad248fbce3e9b491453c3abfdf13db81bf04ac0e21467ce016d681bde5f0cd935a95f0ad67598a4a70801649c7f9a0da9358809a60fb14debfe6785c40a4d9ef11e47bc52b300fbc1bd5d953ecdf26107e01197556a880b038b9d05189e953f1e62039309a90717deaa10098693a53d9b8bb388c5e02786cd0d1d81befee07cdfdab21994a2d30371a5195d6bfe382039b658cc95709355493eba9395582a654f7 472b9fca6bd74f4ad3fe80dcd5942f47ba7fed6887086b993dcbdb0a22d2cccdce951b25a43a0873cadd2646b0ca7fd3f6ad8132bd42aac5d69f268720e84751733c565809c646eff18f7ebfdf03d19ee7d8e6d463403abe37ebe5ef9dabcedf90edacaae332ca6accecd31d13a783fdf937ed5639ad374bee167a02e754bbad3df6e7332f1d4e28045670b46596c87ae88bdf941cadb40229ac973240f86e24c798e6977782e7ac8881104f5a86056440a6664b6ac4cbf2bf201f522511f984e839a34e7f98e70d970d6699415263bdf1637747ffa1da0c446e080783ef6fad624a3347234ab95586de140a225e17f1bfd9f556edb302654aafc6f67eefb2d5', '46cd4fc8ec434164a6a9d1f19377076cad967e64efdd35bf0bd8f99cb108a62657f08826ae52cf39bc9185d7885aa2e320f5e721476ef64b2fda16f41a7cc414fb18fc4cb42b21396296707baf286c49337f4c3456784c54721f25a7d91bb7b612555485a09c9416e2dd3f911fb351d3849421b61cc978ac677acdffdf5f6593676436cf8c1444951a080bad0bf8aa3bef088f0648352d6734df4f6bada402921a7829b5ee9ef9a001133e9a8bd24ed3f2b4474b15d8976ec8d6dff02146ae06a0dfa9b75ac4caefacb6a12ad483d84f45b553f7fdc1e3c1d3a4482a46aaafc30f23c7900a2e8f7411ef83f50b4c69147719e9d2709b9a28f31a3ab1bb4cf396 152ac32277a2331a05b05274efd554160221a2130c3d9a66145a469b45cd13e847cae58cfe824e30c7b90ef69fa4ab1bb7014a5388a433ab6094f94d3ef916f6a9c8d458bd1f48f176c2dc877042f9bbf6cd8404064ce860dd271886d7e5d559ab8c50aca6ccbe597df44bd919f052efbfaa8c296c856adf51c3a57a1e9dea90a7e51b7dc60de05e8f81ead66b9b15dc4893651a564a32c7a96b7d4192fb44f69ab1bc33457897313d864388086023f3f62e8f8d63ca68ebaffe6f35111f1ecad52d72e1c1af68be2aac88066fc371d2439ca37b7d586c00849a40eae4d69c91af4ed9cca03a19ac7e50b7cdd732214db0bb1171edac59f9e0304d9d530ea43d', '723ad6d44f118b800394cc250eacac2916d096a16c6e53715050cc2ef343caffd9bc0bb40250aa461eac41949537ae9b9d7c87555ea8d4c07f31e33e11eb9ee4d4a79cdf2303bbc44d2789c696b288120e9dcff08b36f39570dd357bb90ef1129abfff7dd123b7ea13bc0a4cac85ce0980f758efc9ad1defe9178125b0de333281bc0e49a288e5a0855d34865aca26cf20554f2aec3b7dfc02c16477d725ad0862ac722ff2a382cc3abc5ee7317fe4cabb60f75fe3b96af49a67436fa6fad33d3402a5aacd1d558aa16189090a79589f5152d1ec63c09a2c5b2b2e2eeebc2efc98d666a3f00bb5d779add82be38fae6dbe2a3393e217b29a07a63999a259e1f 669c49eeafd38ce130253dfbd7eb49cc213e3b59bdf457acbab0852c43f57a7c52c41976f0844e71ca430eb29c57eabf9ec3087c31d821083ee7ce65e480a0d6d4673d2ff12f04a7ebbff2c04a256d6f043eb7c514d82a62122a4753b92dba210469b71906546cabfa5a190dc0919d85e2886e6ad7d0ff3e171a58237e1e549407c82712451825962f6ce732f8a3871a8a0f721d9838f15c7ef6abf13f7717965be3b83a85d36e466993db34355d3306c6fef4554bc5af971eb8b9f7bcdf2442808aff17bab924a8dd178c9d9b8eda10d74ff208bc830b52bcc42bb849fc12aca549616d71a697d1976bb1c788021e3ff20373db87511693820c5b7636d2758d'])

Python

python
target_line_idx=None target_out_hex=None for i,line in enumerate(ot_lines): a,b=line.split() if a.lower()==ct_hex.lower(): target_line_idx=i target_out_hex=b break target_line_idx, target_out_hex[:40], len(target_out_hex) (1199, '666c61677b37613934666171652d653061332d31', 132)

Python

python
out_bytes=bytes.fromhex(target_out_hex) out_bytes, out_bytes[-1] (b'flag{7a94faqe-e0a3-1qf0-8527-30050575612d-983f85d9-e0a3-11f0-88cc\xbe', 190)

Python

python
N=int(pub[0],16) e=int(pub[1],16) c=int(ct_hex,16) y=int(target_out_hex,16) # brute force offset def recover_m(c, y, max_r=10000): for r in range(max_r+1): cand = y - r if cand>0 and pow(cand,e,N)==c: return r,cand cand2 = y + r if pow(cand2,e,N)==c: return -r,cand2 return None recover_m(c,y, max_r=10000)[:2] (577, 351557825396240889191974411785646141604173081688455298181959658657301774223318617972403687882710619875600607465938547526540082353805220674671890173058626052477)

Python

python
r,m = recover_m(c,y, max_r=10000) m_hex = hex(m)[2:] m_bytes = m.to_bytes((m.bit_length()+7)//8,'big') m_bytes b'flag{7a94faqe-e0a3-1qf0-8527-30050575612d-983f85d9-e0a3-11f0-88ca}'

Python

python
desc=Path("/mnt/data/题目描述.txt").read_text(encoding='utf-8', errors='replace') desc '双参数噪声'

Мысль

Interpreting the noise parameters and outlining the solution approach

The "double parameter noise" likely uses two random bytes, and we can interpret the additive noise as small enough for brute-forcing. From the oracle outputs, we estimate the typical noise range. For the target ciphertext, the noise is manageable. The plan is to parse y from the transcript, compute m=y-r, check pow(m, e, N) == c, and then output the bytes for the flag.

Considering the approach and defining safe bounds for r

We need a Python code snippet to compute the target, and we’ll explain the reasoning for the bound. Based on calibration lines, noise appears to be small, under 1000, but we could set the bound to 10,000 (or 2^16). Let's compute the distribution and check for maximum and small values of noise. Our r is small, not large.

Finalizing noise model and choosing brute force range

Noise seems to be dual-parameter, made of two bytes (a, b), giving a range for r (r = 256*a + b). That means we can assume noise is 16-bit, between 0 and 65535. From transcript outputs for c=1, we see small outputs match small r and large outputs correspond to larger r. We can brute force through 0 to 65535, and r=577 works.

Final steps and explanation

To solve this, we:

  • Identify RSA parameters N and e from the public data.
  • Get the ciphertext c and the oracle transcript, which contains pairs of ciphertext and noisy decryption.
  • Noise is small, 16-bit (two parameters); from repeated tests with c=1, we confirm noise increments in the low byte.
  • Brute force the noise r between 0 and 65535, compute m=y-r, and test with RSA.
  • With r=577, convert m to bytes, decode to get the flag.

We'll include a code snippet and verify the bounds we used.

Providing final steps and citation details

I'll summarize the process step-by-step and include proper citations:

  • Extract RSA parameters (N, e) from public.txt and ciphertext from ciphertext.txt, citing lines as needed.
  • Oracle transcript shows repeated query, so small noise is identified.
  • We brute force noise and compute the plaintext.
  • Return extracted ASCII flag.
  • Provide pseudocode and Python snippet for solving.

Citations will include relevant lines from the transcript, ensuring the process is well-documented.

Thought for 13m 3s

Ответ

下面按“思路 → 过程 → 答案”把这题讲清楚(基于你给的 4 个附件)。


题目核心判断

  • public.txt 给了 RSA 公钥:N(模数)和 e=0x10001=65537。(oracle_transcript.txt)
  • ciphertext.txt 给了目标密文 c。(oracle_transcript.txt)
  • oracle_transcript.txt 是“密文 → oracle 输出”的记录。开头大量出现 1 2, 1 3, ... 这种:因为 RSA 中 Dec(1)=1,所以当你看到 c=1 时 oracle 输出变成 2、3、4...,非常强烈地说明 oracle 返回的是 明文加噪声(加法噪声),也就是:
y=m+ry = m + r

其中 m = Dec(c)r 是噪声。(oracle_transcript.txt)

题目名“双参数噪声”通常暗示噪声由两个参数拼成(最常见就是两个字节/两个小量组合),因此一个很自然的可行范围是 16-bit 噪声0 <= r < 2^16


解题过程(为什么能爆破 r)

我们拿到了 (N,e) 和目标密文 c,同时 transcript 里也能找到该密文对应的 oracle 输出 y(你的 transcript 最后一行就是目标密文那条,我本地解析到它对应的 y)。

由于 RSA 加密是确定性的,只要我们猜对了 m,就一定满足:

memodN=cm^e \bmod N = c

而我们手里有 y=m+r,如果 r 的范围足够小(题目名暗示就是这样),那么直接枚举 r

  • m_candidate = y - r
  • 检查 pow(m_candidate, e, N) == c

一旦相等,m_candidate 就是真实明文

我在你的数据上爆破得到:

  • r = 577 (0x0241)
  • m 转成字节后,里面直接是 flag 文本。

参考解题脚本(按附件直接跑)

你把四个文件放同目录运行即可。

python
from pathlib import Path # 读公钥 pub = Path("public.txt").read_text().strip().splitlines() N = int(pub[0], 16) e = int(pub[1], 16) # 读目标密文 c_hex = Path("ciphertext.txt").read_text().strip().lower() c = int(c_hex, 16) # 在 transcript 里找到目标密文对应的 oracle 输出 y y = None for line in Path("oracle_transcript.txt").read_text().splitlines(): a, b = line.split() if a.lower() == c_hex: y = int(b, 16) break assert y is not None, "transcript 里没找到目标密文对应的输出" # 爆破 16-bit 噪声(双参数噪声的常见含义) ans_m = None ans_r = None for r in range(1 << 16): m = y - r if m > 0 and pow(m, e, N) == c: ans_m = m ans_r = r break assert ans_m is not None, "没在 16-bit 范围找到噪声;可把范围加大再试" # 转字节并打印 m_bytes = ans_m.to_bytes((ans_m.bit_length() + 7) // 8, "big") print("r =", ans_r, hex(ans_r)) print(m_bytes.decode(errors="replace"))

最终答案

flag{7a94faqe-e0a3-1qf0-8527-30050575612d-983f85d9-e0a3-11f0-88ca}


如果你还想把“为什么说是 16-bit(双参数)噪声”写得更像比赛 writeup(例如结合 c=1 的输出序列展示噪声特征、以及如何扩大搜索范围做兜底),我也可以把这份过程润色成一篇完整 writeup。

Поделиться этим Q&A