2023冬 密码学趣题——2

HITCTF2022 revcalc

import string

p = 2**607 - 1


def s(a, b):
    return (a + b) % p

def u(a, b):
    return (a - b) % p

def m(a, b):
    return a * b % p

def scan(s):
    while s:
        if s[0] in string.ascii_letters:
            yield globals()[s[0]]
            s = s[1:]
        elif s[0] == '[':
            s = s[1:]
            num = s[:s.index(']')]
            yield int(num)
            s = s[len(num) + 1:]
        else:
            raise AssertionError

def calc(s):
    stack = []

    for token in scan(s):
        if type(token) == int:
            stack.append(token)
        else:
            b, a = stack.pop(), stack.pop()
            stack.append(token(a, b))
    
    assert len(stack) == 1
    return stack[0]

assert calc('[114514][1919810]s') == 2034324
assert calc('[114514][1919810]u') == 531137992816767098689588206552468627329593117727031923199444138200403559860852242739162502265229285668889329486246501015346579337652707239409519978766587351943831270835393219029922831
assert calc('[114514][1919810]m') == 219845122340
assert calc('[456][789][123]um') == 303696

from secret import flag
flag = int(flag.encode().hex(), base=16)
assert flag < p

cmd = open('cmd.txt', encoding='utf8').read()
cmd = cmd.replace('#', str(flag))
assert calc(cmd) == 211628186767393818556251909887187904577210135303836860239435739472106633529410929587038047765313010325750338075891823682635502490521440215978665151485743439682336190814184610992830040

定义了p元域下加减乘三种运算,遇到字符进行弹栈操作,flag藏在中间某个数据中,栈之间有相互嵌套的情况,以#分割上下两端数据,分别进行题目定义中的运算,将数据化简到十二组。然后手动模拟一下弹栈过程进行m s u三种运算的逆运算。
exp:

p = 2**607 - 1
def s(a, b):
    return (a + b) % p
def u(a, b):
    return (a - b) % p
def m(a, b):
    return a * b % p

list=[]

def rev_calc(ss):
    while ss:
        if ss[0] in string.ascii_letters:
            list.append(ss[0])
            ss=ss[1:]
        elif ss[0]=='[':
            ss=ss[1:]
            num=ss[:ss.index(']')]
            list.append(int(num))
            ss=ss[len(num)+1:]
        else:
            print("error")
            exit(0)
    i=0
    while True:
        if type(list[i])==int and type(list[i+1])==int and type(list[i+2])==str:
            if list[i+2]=='s':
                list[i]=s(list[i],list[i+1])
            elif list[i+2]=='u':
                list[i]=u(list[i],list[i+1])
            elif list[i+2]=='m':
                list[i]=m(list[i],list[i+1])
            del list[i+1]
            del list[i+1]
            i=-1
        i+=1
        if i>len(list)-3:
            print(list)
            break
cmd = open('cmd1.txt', encoding='utf8').read()  #前后两端数据
#cmd = open('cmd2.txt', encoding='utf8').read()
rev_calc(cmd)

from Crypto.Util.number import *
import gmpy2

cur=[0,
411462633351188704608772808736605191389923045827641716511469308371854121046362931301201375260845451848982856577009623299816324457739774142518892624317933419004496564018161840092441609,
405277799051970673662801377723672963663731597810359617329765419659576945597240297480269578668417239423727580929070705786881955931110402398335890389099929008486871336532303266008184849,
266786049503793180671593180171285607267937291386517024152767948485542129161609474025939244637171224835933234460786246192462321233844724721442838436104220216301662441280032397322012869, 
329413142624682830072062312344664670657676804598199974252482170738455671758477066245274544233089658385383771602659521107081460343229409192986193619974433238593388986719171190288572226, 
142121702801478829020260933003861049247883466530930799943577455779988122604459669110334205260923754356449343846208954099483456230863726350624778551913564131383628808003460154339600404, 
183071373516520549207577402797386102692277431976907349274136009719534503668840785924520834697959249645197750171829448025189506854326750416465015622082002300707311266953797519604299392, 
84814702442206743141315418314363700843763684274888674447614037562848731974003165144242888622700246417328307742191053416029770031887073881821630737367508536343638035495945224940047233, 
81400841347738205877353746324299277291277356563154583584412416913743196467840261318987244863470045052929898762129171746639696678721661976384989764957120352119094038687040657495882525,
393926316432640484766273060620865379785410111973395923709856173813361374147800349857401893990151884942524826629432805076866870155732114631381903699794058108179098102490606577881709383,
165839131146163706086115367996555974012081654422136256245648685955916878221421477398411421659597644170978751681140704059146026898331248207774348535156605590710456443740029571361676159,
509747518370752815356459801084195729310089672054058702183281061987169033803508549887738101604685367942973008687501702092204264485750605361311969988578288525486444957877546554793693797, 
357912307834259213653128634794940914596507256175506043013473144575889601751685024934341011218038398747178612125892760523871786468537993455666648592264307733564175853226677357748565113 
]

p = 2**607 - 1
ans=211628186767393818556251909887187904577210135303836860239435739472106633529410929587038047765313010325750338075891823682635502490521440215978665151485743439682336190814184610992830040

ans=(ans-cur[12])%p
ans=(ans*gmpy2.invert(cur[1],p))%p
ans=(ans-cur[2])%p
ans=(ans*gmpy2.invert(cur[3],p))%p
ans=(ans-cur[4])%p
ans=(ans*gmpy2.invert(cur[11],p))%p
ans=(ans+cur[10])%p
ans=(ans*gmpy2.invert(cur[5],p))%p
ans=(ans*gmpy2.invert(cur[6],p))%p
ans=(cur[7]-ans)%p
ans=(ans*gmpy2.invert(cur[9],p))%p
ans=(ans-cur[8])%p

print(hex(ans))
print(long_to_bytes(ans))

posted @ 2023-01-27 22:50  App1e_Tree  阅读(40)  评论(0编辑  收藏  举报