Masalah
Penyelesaian
Untuk melakukan dekripsi flag yang terenkripsi, buatlah fungsi dekripsi dengan mencari inverse fungsi round_add
dibawah ini.
def round_add(a, b):
f = lambda x, y: x + y - 2 * (x & y)
res = ''
for i in range(len(a)):
res += chr(f(ord(a[i]), ord(b[i])))
return res
Penyelesaian akhir, tambahkan fungsi dekripsi ini pada bagian fungsi enkripsi.
def encrypt(self, plaintext):
...
ctx_challenge = 'HRlgC2ReHW1/WRk2DikfNBo1dl1XZBJrRR9qECMNOjNHDktBJSxcI1hZIz07YjVx'.decode('base64')
def full_reverse(ctx):
X, Y = ctx[:8], ctx[8:]
R, L = X, Y
# print 'R: %s | L: %s' % (R,L)
# R, (round_add(L, self.Kn[31])) = L, R
# R, (round_add(L, self.Kn[30])) = L, R
# print (round_add(L, self.Kn[31])) == R
# f = lambda x, y: x + y - 2 * (x & y)
# res = ''
# for i in range(len(a)):
# res += chr(f(ord(a[i]), ord(b[i])))
# return res
def reverse(R, KnIndex):
n = 8
solver = Solver()
LFake = [BitVec('LFake%i' % i, 32) for i in range(0, n)]
for i in range(n)[::-1]:
y = ord(self.Kn[KnIndex][i])
solver.add(ord(R[i]) == LFake[i] + y - 2 * (LFake[i]&y))
solver.check()
model = solver.model()
LFakeValue = ''.join([chr(model[LFake[i]].as_long()) for i in xrange(n)])
# print 'LFake', LFakeValue
return LFakeValue
# Assert 1
# for i in range(n):
# x = ord(LFakeValue[i])
# y = ord(self.Kn[31][i])
# print ord(R[i]) == x + y - 2 * (x&y)
# Assert 2
# L = LFakeValue
# print (round_add(L, self.Kn[31])) == R
LL = [False for i in range(32)]
RR = [False for i in range(32)]
# Assert 3
# LFakeValue = reverse(R, 31)
# LL[30], RR[30] = L, LFakeValue
# assert (round_add(LFakeValue, self.Kn[31])) == R
# LFakeValue = reverse(LL[30], 30)
# LL[29], RR[29] = RR[30], LFakeValue
# assert (round_add(LFakeValue, self.Kn[30])) == LL[30]
LL[31] = R
RR[31] = L
for i in range(32)[1:][::-1]:
# print i
LFakeValue = reverse(LL[i], i)
LL[i-1], RR[i-1] = RR[i], LFakeValue
# print LL[i-1], RR[i-1]
assert (round_add(LFakeValue, self.Kn[i])) == LL[i]
# print LL, RR
i = 0
LFakeValue = reverse(LL[i], i)
LL[i] = LFakeValue
# LL[i-1], RR[i-1] = RR[i], LFakeValue
# # print LL[i-1], RR[i-1]
# assert (round_add(LFakeValue, self.Kn[i])) == LL[i]
# print LL[0], RR[0]
sys.stdout.write(LL[0])
sys.stdout.write(RR[0])
# P = ''
# P += RR[0]
# full_reverse(res[i * 16:(i + 1) * 16])
full_reverse(ctx_challenge[i * 16:(i + 1) * 16])