Created
December 31, 2016 09:25
-
-
Save Jinmo/7e5144d3f29a0e6803d316382c487de4 to your computer and use it in GitHub Desktop.
33c3 mario
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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