mirror of https://github.com/AxioDL/metaforce.git
105 lines
2.1 KiB
Python
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')
|
|
|