metaforce/hecl/extern/blowfish/cme.py

105 lines
2.1 KiB
Python

import struct
P = []
S = []
def F(x):
d = x & 0x00FF
x >>= 8
c = x & 0x00FF
x >>= 8
b = x & 0x00FF
x >>= 8
a = x & 0x00FF
#y = ((S[0][a] + S[1][b]) ^ S[2][c]) + S[3][d];
y = S[0][a] + S[1][b]
y = y ^ S[2][c]
y = y + S[3][d]
return y
def bfencipher(xl, xr):
Xl = xl
Xr = xr
for i in range(16):
Xl = Xl ^ P[i]
Xr = F(Xl) ^ Xr
temp = Xl
Xl = Xr
Xr = temp
temp = Xl
Xl = Xr
Xr = temp
Xr = Xr ^ P[16]
Xl = Xl ^ P[16+1]
return Xl&0xffffffff, Xr&0xffffffff
key = bytearray()
with open('hecl_key', 'r') as keyin:
b = keyin.read(2)
while len(b):
if len(b) != 2:
break
key += struct.pack('B', int(b, 16))
b = keyin.read(2)
if len(key) < 8:
raise RuntimeError('key must be at least 8 bytes in length')
with open('blowfish.dat', 'rb') as fin:
word = fin.read(4)
for i in range(18):
P.append(struct.unpack(">I", word)[0])
word = fin.read(4)
for i in range(4):
sub = []
for j in range(256):
sub.append(struct.unpack(">I", word)[0])
word = fin.read(4)
S.append(sub)
j = 0
for i in range(18):
data = 0x00000000
for k in range(4):
data = (data << 8) | key[j]
j = j + 1
if j >= len(key):
j = 0
P[i] = P[i] ^ data
datal = 0x00000000
datar = 0x00000000
for i in range(9):
datal, datar = bfencipher(datal, datar)
P[i*2] = datal
P[i*2+1] = datar
for i in range(4):
for j in range(128):
datal, datar = bfencipher(datal, datar)
S[i][j*2] = datal
S[i][j*2+1] = datar
with open('blowfish.dat.c', 'w') as fout:
fout.write('const unsigned long BLOWFISH_P[] = {')
for i in range(18):
if not i%4:
fout.write('\n ')
fout.write('0x%08X,' % P[i])
fout.write('\n};\n')
fout.write('const unsigned long BLOWFISH_S[] = {')
for i in range(4):
for j in range(256):
if not (i*256+j)%4:
fout.write('\n ')
fout.write('0x%08X,' % S[i][j])
fout.write('\n};\n')