NewStarCTF公开赛week4密码学前两道题的wp


前言

哎呦喂,第三周勉强做了一道题,果然第四周就爆零了QAQ
———————————悲伤的分割线———————————
决定以后写wp的时候,把原题的py代码截图、贴图片,只有解题脚本用代码形式呈现,这样也比较清晰~


一、LCG Revenge

这题其实真不难,咋就不试着做一做???

1.原题

加密过程:
题目脚本
输出信息:
原题输出内容
可见题目已经给出的已知量有:循环结束后的xs列表,a, b, c, p。

2.解题思路

1) 考察知识

题目叫“lcg的复仇”,大概是week3考察lcg的延续,本质上换汤不换药,还是要借助lcg的解题公式,只是具体到所考察的点和week3不太一样,对本题的加密过程抽出本质后会发现本题比week3那道题更简单(因为a都给你了,抽丝剥茧后纯粹是已知Xn+1去求Xn这种情况!

2) 分析本质

①根据题目脚本给出的加密过程,可以看出在循环前,先将明文分成了三份,作为最初的xs[0], xs[1], xs[2]。

②然后进行10次循环,在每一轮循环中,计算(a*xs[0]+b*xs[1]+c*xs[2])%p的值作为下一轮循环的xs[2],xs[1]和xs[2]则作为下一轮循环的xs[0]和xs[1]

③题目给出了循环结束后输出的xs[0], xs[1], xs[2],通过②中的分析已经知道,xs[2]=(a*上一轮循环的xs[0]+b*上一轮循环的xs[1]+c*上一轮循环的xs[2])%p,而输出的xs[0]和xs[1]正是在计算输出的xs[2]时使用的“上一轮循环的xs[1]和上一轮循环的xs[2]”,可见现在 b*上一轮循环的xs[1]+c*上一轮循环的xs[2] 这个式子中的量全都已知,相当于可以直接计算出来的一个常数,于是我这里将 b*上一轮循环的xs[1]+c*上一轮循环的xs[2] 整体用常数B表示。

④于是,现在可以将循环内做的运算写成Xn+1=a*Xn+B的形式,也就是lcg“本来的样子”。Xn+1就是当前循环计算出的xs[2],Xn是上一轮循环的xs[0],a也已知,相当于式子Xn+1=a*Xn+B中,只有Xn不知道,可以由lcg的公式Xn=(Xn+1-B)*invert(a,p)%p求出Xn。
(这里的n+1和n是X的下标!

⑤Xn就是计算本轮循环产生的xs[2]的那个xs[0],而输出的xs[0]是上一轮循环的xs[1],输出的xs[1]是上一轮循环的xs[2],所以把xs[1]赋给xs[2],把xs[0]赋给xs[1],把Xn赋给xs[0],逆着循环“向上”追溯,执行10次循环即可“溯源”到原始的xs[0], xs[1], xs[2]。

3.解题Python脚本

from Crypto.Util.number import *
import gmpy2
a = 18038175596386287827
b = 15503291946093443851
c = 17270168560153510007
p = 307956849617421078439840909609638388517
xs=[255290883651191064919890629542861653873, 221128501895959214555166046983862519384, 108104020183858879999084358722168548984]

for _ in range(10):
    B=b*xs[0]+c*xs[1]  #当前循环的xs[0]和xs[1]是上一轮循环的xs[1]和xs[2],b*xs[0]+c*xs[1]是每轮循环可以计算出的常数,相当于“ax+b”中的b,所以用B来表示了
    s=(xs[2]-B)*gmpy2.invert(a,p)%p  #当前循环的xs[2]是由上一轮循环的xs[0]*a+B计算得到的,xs[2]也已知,可以套常规的lcg公式得到上一次循环的xs[0]
    xs[2]=xs[1]
    xs[1]=xs[0]
    xs[0]=s
print(xs)
print(long_to_bytes(xs[0]))
print(long_to_bytes(xs[1]))
print(long_to_bytes(xs[2]))

自行拼接一下三块输出可以得到flag:flag{try_some_linear_algebra_technique}

二、代数关系

1.原题

题目给了两个文件,说明加密过程的task.py和加密后的输出结果output.txt:
题目给出的文件
task.py:
说明加密过程的py文件
output.txt部分内容截取,给出了py文件中print的内容:n,e1,e2,e3,c1,c2,c3,gift_from_fallwind,完整的变量和值在后面的解题Python脚本中给出。
输出的已知值

2.解题思路

已知量有n,三组密文c1,c2,c3,三组e值e1,e2,e3,想解密的话还是要求出三组私钥d。以及题目还给了一个量gift_from_fallwind,是d2-d1的值。
因为三组密文都是模n获得的,n相同,那么phi(n)也相同,而私钥d满足其是e模phi(n)的乘法逆元,即e*d = 1 (mod phi(n))
(不会打三条横线的等号,所以用=了,想表示的是同余式,下同)
那么,有如下同余式成立:

e1*d1 = e2*d2 = e3*d3 = 1 mod (phi(n))

即e1*d1-1、e2*d2-1 和 e3*d3-1的值都可以写成phi(n)的整数倍。想办法把这个同余式往题目的已知量上靠一靠,对于涉及d2和d1的式子:

e1*d1 mod phi(n) = 1 ①
e2*d2 mod phi(n) = 1 ②

①式等号两边同乘e2,②式等号两边同乘e1,再用②-①,得到:

e1*e2*d2 - e2*e1*d1 mod phi(n) = e1 - e2

移项和化简后得到:

[ e1*e2*(d2 - d1) - (e1-e2) ] mod phi(n) = 0

即e1*e2*(d2 - d1) - (e1-e2)的值是phi(n)的整数倍,将其记作tmp_phi
分别求e1,e2,e3和的tmp_phi的扩展欧几里得函数(gcdext,导入gmpy2模块可调用)的第二个返回值(即ax+by=gcd(a,b)中的x值)作为d1,d2,d3即可解密。至于为什么是这样求解,我还没想明白。
注:gcdext(a,b)有三个返回值,分别是a和b的最大公约数即gcd(a,b),满足ax+by=gcd(a,b)的x,满足ax+by=gcd(a,b)的y。

3.解题Python脚本

非原创,其中原理还不太明白,参考自厉害的人的博客:参考来源
感谢大佬的wp,侵删

from Crypto.Util.number import *
from gmpy2 import *
n = 714592173868259951547903824656567142382519201815807137392662736000480461106944240411907971077744283561181468187349950157770542641452016168710768060100431878635594871092115167496636869765435245733216244455291669985854820686150487479060100362374214950338593785006799039892489525125499595277195821419495485780569578409849268011672935670978669183434574625404664252352238179018153026065565737180327403650490113961989352069795255693066847568569258596045200617988242378417608661573561288798387013713959291514998718810340095720086582431808535500784877130015856483311803720730193251968718389940211890886176473856457082812043712013634688479195044004890584238387779313840532514565194377261080408568578839974414957533288241409106206637332990105576057838430267703746376981194305776942499262213827373958311438790046259142383469934115411137484269094594634801601455381187640866738280586324069047262621776502056490534194678730988305691412586133810702956723819024793893235153104715079346666767828770304227597496868066084967074574249861996861449220457370695654952738759446674531850565616794250604969906523629086439326216263355721761747979532714573810102811235244618245569028203230483116293028005467298691574981713677092048315265963514382056811642161463
e1 = 42407
e2 = 42299
e3 = 64279
c1 = 147746559360802924168767659277705450630485609696398746571701418818848770182885487620535212747337538428905143459150636194921920646777706320249140903061217676389530668645622949973659702291367297066656754690100263868506461956113055815101461657779702873682097533482492493899104205046186278766341878854368500917007433940486307279045874511368494257897755625125620904196433190777249505786257092826031743302124873284619940344765699423310728402472381757497703327215054987663079091464775324695334786123993004899881875932719629531115443494782427464033199136840262965875592542948702903121840007890458510167896574258848373182376940828605330277069434815885568024582498080844909563591272397488770838751339866638704837915487427276557777372613819511517108295620835412232055690690331814390700825513053666493393942792555525632325524757429986865995789852014588602452362551730826736918369894537815766447265166762601145909581089407049818337486974627574263275878986623999208215467068257094963543761810512552366121738916812287617877452022267220425292446818899145860109087267084524150679796547645233300059224249369109340663349590685107672065377058337980842108933489505620025066451603214522163014130542079244955200533246817511795384645564870718654306017093880
c2 = 337796038485337223816475984950456810748129968181260652436798659350041388661303298381024293567858637131784295193867689006379455173201801538614335070721020735891108350570605513554850505589909457080361317990263630725721623909042708574097188905696426452814443072330582517110013425687309570310925148848467651593011914844474279987415423796247841257536637823609202705263533635281512231854231077727153008468034663708367221732104195468247696442441086937944990689793952230215990824397909249441015759060017517894957594510803336664512608128010545289784049784177611524398804382654716236024276493647659224649016999444437679713035528891917192417814659613017511330578462974624880551299057883811283033946146889355467779050967361027087080352841747836678980418533840472145655131425703508683270849398801701504340623072029235085830962038699908963834215641154556517289466852886243166207700576530398250363365976100132377349909530093158372007815925018963904011651612576427055409180229217198739845333777332027781322479300353269326257620342214186859996302004152073249996007973827806898128006273636862496964659067036495886736584255338505886284353124133030688669501417184690143652760207937780991619589875885728364937580912382631625198455389969845802240231827163
c3 = 424077500283538548695429029734927642518438524525805172568745880982861798954369892065855075306396658578715593140988681322211943800827469098807795208943724228288132152970084568728843669855312178059145983168245747282178118927927118026053179993918910256713266934916520151359475678446638810022833365506023312578408649890108868706577071610442415250434663703848788000124360027832658586954993369200881819393055860013390887044444898844318376925700215369036711799193621862491000483927756231147580685621531144248717419030824674055599055717010063636336702022163459269369324701987636772581709509640297923613071083421937504088720011643179567005037514310053762735787172663099935520119785909997287518567706508640150762285653766660798661964916169965639164375045609322144422628622388969490052285300841751657575450486389268063959043056821417358486314747981330380819421643688151487077209015995287339609841113765813462834471270766622938036101602597257457988755053683191621395473412095142041134027974560324126052952093513827172817662085883985649068515306916979488707694772473239863027480932340145990906115024722682989661592015805559935349596282010900810573490368602483785908673810154811269934225750196861258621132739166572297393817253205915435333491161203
gift_from_fallwind = 436057126906623515829218011238744316017674469205661117597268470150957758251976942445150879861108983042930734360653000973980600283904101499137333865224021780243160123582776537464659885717072177232387979780155820186376822704547514869653697300455384885557911728798950305201936973078685581794365075352341541134238714464727825137128067542739078985472265837037034067906587445615146595102552611894550913742780821268889878629177560903295511218320565910385133911886947889495561650713735268032963799756628442264275798506978864616008762967965435601210553178014009864471368535327898667309420704800396343299194692424445757081230545316510925050736165766681764700768348825662815908360495749201689747586178884303154943439689695756080847567228630187446741488386672483582019385735879376786013583105010830909520853067056907311999554079858869757789193026155282645740531423042696088661716948429683650063340097187696375083991311139748519133745606598795309849873485013934772051034350080361176801194568727665884824462291930504184029406404464952205159309484625000859491407470043008763418189126078287693565790619787102318883565462574011050013632489624673181763059753755492153825048101618871500056894854231049792292739927027237110872703608633932490764567008732
#gift_from_fallwind:d2-d1

tmp_phi=gift_from_fallwind*e2*e1-(e1-e2)
g1,x1,y1=gcdext(e1,tmp_phi)
g2,x2,y2=gcdext(e2,tmp_phi)
g3,x3,y3=gcdext(e3,tmp_phi)

f1=pow(c1,x1,n)
f2=pow(c2,x2,n)
f3=pow(c3,x3,n)

print(long_to_bytes(f1)+long_to_bytes(f2)+long_to_bytes(f3))

运行得到flag:flag{a1g3br4ic_re1at1on_i5_us3ful}
flag输出

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值