import Crypto.Cipher.DES
import struct
def rol32(x, y):
ret = ((x<<y)&0xFFFFFFFF)|((x>>(32-y))&0xFFFFFFFF)
#print 'rol32', hex(x), hex(y), hex(ret)
return ret
def sub32(x, y):
ret = (x & 0xFFFFFFFF) - (y & 0xFFFFFFFF)
if ret < 0: ret += 0x100000000
#print 'sub32', hex(x), hex(y), hex(ret)
return ret
def mul32(x, y):
ret = (x * y) & 0xFFFFFFFF
#print 'mul32', x, y
return ret
d = Crypto.Cipher.DES.new('\xcd\x67\x98\xf2\xa4\xb6\x70\x76', Crypto.Cipher.DES.MODE_ECB)
def decrypt(offset, f):
out_buf = []
b = f.read(16)
buf = d.decrypt(b)
buf = buf[8:] + buf[:8]
for i in range(0,4):
val = struct.unpack('<I', buf[i*4:i*4+4])[0]
val = sub32((sub32(0x8927462, mul32(offset, 0x3210789B)) ^ rol32(val, offset % 32)), 0x12345678)
tmp = struct.pack('<I', val)
out_buf.append(ord(tmp[0]))
out_buf.append(ord(tmp[1]))
out_buf.append(ord(tmp[2]))
out_buf.append(ord(tmp[3]))
for i in range(len(out_buf)-1,len(out_buf)-16,-1):
out_buf[i] ^= out_buf[i-1]
out_buf[len(out_buf)-16] ^= (offset & 0xFF) ^ ((offset >> 14) & 0xFF)
return out_buf