Skip to content

Instantly share code, notes, and snippets.

@Jinmo
Created December 31, 2016 09:25
Show Gist options
  • Save Jinmo/7e5144d3f29a0e6803d316382c487de4 to your computer and use it in GitHub Desktop.
Save Jinmo/7e5144d3f29a0e6803d316382c487de4 to your computer and use it in GitHub Desktop.
33c3 mario
import itertools
import struct
# Rotate left: 0b1001 --> 0b0011
rol = lambda val, r_bits, max_bits: \
(val << r_bits%max_bits) & (2**max_bits-1) | \
((val & (2**max_bits-1)) >> (max_bits-(r_bits%max_bits)))
# Rotate right: 0b1001 --> 0b1100
ror = lambda val, r_bits, max_bits: \
((val & (2**max_bits-1)) >> r_bits%max_bits) | \
(val << (max_bits-(r_bits%max_bits)) & (2**max_bits-1))
def go(x, a):
return int(bin(x)[2:].zfill(8)[a:a+2], 2)
def permute(x, y):
result = [x[go(y, 6-i)] for i in range(0, 8, 2)]
return result
def ipermute(x, y):
a = [0] * 4
for i in range(0, 8, 2):
b = go(y, 6-i)
a[b] = i / 2
# print a
result = [x[a[i]] for i in range(4)]
return result
arr = [10, 80, 50, 60]
assert ipermute(permute(arr, 0x8d), 0x8d) == arr
MASK = 0xffffffffffffffff
low = lambda x: x & MASK
high = lambda x: x >> 32
text = str(bytearray(range(32)))
text = bytearray(struct.pack("<4Q", 0x8A76639879E2196CL, 0xAF7AEA900F7D0218L, 0xC23662B9AEFABDB2L, 0x74C0A7F29FF2FC80L))
l1, l2, r1, r2 = struct.unpack("<4Q", text)
l = l1 | (l2 << 64)
r = r1 | (r2 << 64)
split = lambda x: [(x >> (16 * i)) & 0xffff for i in range(8)]
def merge(x, bits=16):
result = 0
for i in range(len(x)):
result |= x[i] << (bits * i)
return result
RKey = merge([0xC0D3, 0x4D00, 0x00D3, 0xB4BE] + [0xC4FE, 0x3700, 0x0013, 0x33C3])
if 0:
for i in range(42):
l, r = split(l), split(r)
print map(hex, l), map(hex, r)
l, r = l[4:] + r[4:], r[:4] + l[:4]
l = permute(l[:4], 0x8d) + permute(l[4:], 0xd2)
r = permute(r[:4], 0x39) + permute(r[4:], 0x87)
print map(hex, l), map(hex, r)
l1, l2, r1, r2 = merge(l[:4]), merge(l[4:]), merge(r[:4]), merge(r[4:])
print hex(merge([l1, l2])), hex(merge([r1, r2]))
print hex(l1), 'l1'
l1 = ror(l1, 0x33, 0x33+0xD) ^ (RKey & MASK)
l2 = ror(l2, 0x33, 0x33+0xD) ^ (RKey >> 64)
r1 = ror(r1, 0x11, 0x2F+0x11) ^ (RKey & MASK)
r2 = ror(r2, 0x11, 0x2F+0x11) ^ (RKey >> 64)
l, r = merge([l1, l2], 64), merge([r1, r2], 64)
print i
print hex(l), hex(r)
print '====='
for i in range(42):
l, r = split(l), split(r)
l1, l2, r1, r2 = merge(l[:4]), merge(l[4:]), merge(r[:4]), merge(r[4:])
l1 = rol(l1 ^ (RKey & MASK), 0x33, 0x33+0xD)
l2 = rol(l2 ^ (RKey >> 64), 0x33, 0x33+0xD)
r1 = rol(r1 ^ (RKey & MASK), 0x11, 0x2F+0x11)
r2 = rol(r2 ^ (RKey >> 64), 0x11, 0x2F+0x11)
print hex(l1)
l, r = merge([l1, l2], 64), merge([r1, r2], 64)
print hex(l), hex(r)
l, r = split(l), split(r)
print map(hex, l), map(hex, r)
l = ipermute(l[:4], 0x8d) + ipermute(l[4:], 0xd2)
r = ipermute(r[:4], 0x39) + ipermute(r[4:], 0x87)
l, r = r[4:] + l[:4], r[:4] + l[4:]
print map(hex, l), map(hex, r)
l, r = merge(l), merge(r)
print hex(l), hex(r)
key = [0x5f,0x38,1]
flag = struct.pack("<4Q", l & (2 ** 64 - 1), l >> 64, r & (2 ** 64 - 1), r >> 64)
flag = bytearray(flag)
print `flag`
flag = bytearray((x - y) & 0xff for x, y in zip(flag, itertools.cycle(key)))
print `flag`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment