Skip to content

学以致用

希望大家可以去探索 Sagemath 的妙用以及克服一下对 English 的恐惧。解题过程非常简单,而且解题过程都在给的 PDF 文件里了。

归纳题目信息,本题归根结底是要解出下面这个方程组:

flag13c1=0modNflag23c2=0modN(flag1+flag2+gift)3c3=0modN

经过分析后,即可定位到论文的这一部分,过程很清晰,结合题目信息寻找相应的 SageMath 实现即可,多搜索,多问 GPT(经出题人测试,免费的 GPT 4o-mini 可完成该题大半的工作量)

论文

利用 groebner_basis() 很好解决,至于怎么写,SageMath 参考文档中的 Search 一栏给出了一些建议。

python
from sage.all import *
from Crypto.Util.number import long_to_bytes, bytes_to_long

n = 17072342544150714171879132077494975311237876365187751353863158074020024719122755004761547735987417065592254800869192615807192722193500063611855839293567948232939959753821265552288663615847715716482887552271575844394350597695771100384136647573934496089812758071894172682439278191678102960768874456521879228612030147515967603129172838399997929502420254427798644285909855414606857035622716853274887875327854429218889083561315575947852542496274004905526475639809955792541187225767181054156589100604740904889686749740630242668885218256352895323426975708439512538106136364251265896292820030381364013059573189847777297569447
c1 = 8101607280875746172766350224846108949565038929638360896232937975003150339090901182469578468557951846695946788093600030667125114278821199071782965501023811374181199570231982146140558093531414276709503788909827053368206185816004954186722115752214445121933300663507795347827581212475501366473409732970429363451582182754416452300394502623461416323078625518733218381660019606631159370121924340238446442870526675388637840247597153414432589505667533462640554984002009801576552636432097311654946821118444391557368410974979376926427631136361612166670672126393485023374083079458502529640435635667010258110833498681992307452573
c2 = 14065316670254822235992102489645154264346717769174145550276846121970418622727279704820311564029018067692096462028836081822787148419633716320984336571241963063899868344606864544582504200779938815500203097282542495029462627888080005688408399148971228321637101593575245562307799087481654331283466914448740771421597528473762480363235531826325289856465115044393153437766069365345615753845871983173987642746989559569021189014927911398163825342784515926151087560415374622389991673648463353143338452444851518310480115818005343166067775633021475978188567581820594153290828348099804042221601767330439504722881619147742710013878
c3 = 8094336015065392504689373372598739049074197380146388624166244791783464194652108498071001125262374720857829973449322589841225625661419126346483855290185428811872962549590383450801103516360026351074061702370835578483728260907424050069246549733800397741622131857548326468990903316013060783020272342924805005685309618377803255796096301560780471163963183261626005358125719453918037250566140850975432188309997670739064455030447411193814358481031511873409200036846039285091561677264719855466015739963580639810265153141785946270781617266125399412714450669028767459800001425248072586059267446605354915948603996477113109045600
gift = b'GoOd_byE_nEw_5t@r'

x, y = PolynomialRing(Zmod(n), 'x, y').gens()
f1 = x**3 - c1
f2 = y**3 - c2
f3 = (x + y + bytes_to_long(gift))**3 - c3

gb = Ideal(f1, f2, f3).groebner_basis()
f1, f2 = gb
flag1 = int(-f1.coefficients()[1])
flag2 = int(-f2.coefficients()[1])
# 出题的时候加了给pad,大家得注意一下,flag在一堆trash中间,别做出了却没看见flag
print((long_to_bytes(flag1)).split(b'*')[2]+(long_to_bytes(flag2).split(b'*')[1]))
# b'flag{W1Sh_you_Bec0me_an_excelL3nt_crypt0G2@pher}'

flag 即为 flag{W1Sh_you_Bec0me_an_excelL3nt_crypt0G2@pher}

虽然我们已经得到了 flag,但其实还有另一种解法,就是紧跟着的下一部分,所以 2 种解法都在这篇 PDF 里面了(一血的选手就是用这种方法完成的):

论文

这道题不指望新生能够搞懂背后的原理,只是希望能够花时间潜下心来学习,然后学以致用,将样例代码迁移到这道题上。当然了,和 GPT 人机合一克服困难,也是一种实力。