|
@@ -89,14 +89,14 @@ A = [[1, 1, 1, 1, 1, 0, 0, 0],
|
|
# produce log and alog tables, needed for multiplying in the
|
|
# produce log and alog tables, needed for multiplying in the
|
|
# field GF(2^m) (generator = 3)
|
|
# field GF(2^m) (generator = 3)
|
|
alog = [1]
|
|
alog = [1]
|
|
-for i in xrange(255):
|
|
|
|
|
|
+for i in range(255):
|
|
j = (alog[-1] << 1) ^ alog[-1]
|
|
j = (alog[-1] << 1) ^ alog[-1]
|
|
if j & 0x100 != 0:
|
|
if j & 0x100 != 0:
|
|
j ^= 0x11B
|
|
j ^= 0x11B
|
|
alog.append(j)
|
|
alog.append(j)
|
|
|
|
|
|
log = [0] * 256
|
|
log = [0] * 256
|
|
-for i in xrange(1, 255):
|
|
|
|
|
|
+for i in range(1, 255):
|
|
log[alog[i]] = i
|
|
log[alog[i]] = i
|
|
|
|
|
|
# multiply two elements of GF(2^m)
|
|
# multiply two elements of GF(2^m)
|
|
@@ -106,29 +106,29 @@ def mul(a, b):
|
|
return alog[(log[a & 0xFF] + log[b & 0xFF]) % 255]
|
|
return alog[(log[a & 0xFF] + log[b & 0xFF]) % 255]
|
|
|
|
|
|
# substitution box based on F^{-1}(x)
|
|
# substitution box based on F^{-1}(x)
|
|
-box = [[0] * 8 for i in xrange(256)]
|
|
|
|
|
|
+box = [[0] * 8 for i in range(256)]
|
|
box[1][7] = 1
|
|
box[1][7] = 1
|
|
-for i in xrange(2, 256):
|
|
|
|
|
|
+for i in range(2, 256):
|
|
j = alog[255 - log[i]]
|
|
j = alog[255 - log[i]]
|
|
- for t in xrange(8):
|
|
|
|
|
|
+ for t in range(8):
|
|
box[i][t] = (j >> (7 - t)) & 0x01
|
|
box[i][t] = (j >> (7 - t)) & 0x01
|
|
|
|
|
|
B = [0, 1, 1, 0, 0, 0, 1, 1]
|
|
B = [0, 1, 1, 0, 0, 0, 1, 1]
|
|
|
|
|
|
# affine transform: box[i] <- B + A*box[i]
|
|
# affine transform: box[i] <- B + A*box[i]
|
|
-cox = [[0] * 8 for i in xrange(256)]
|
|
|
|
-for i in xrange(256):
|
|
|
|
- for t in xrange(8):
|
|
|
|
|
|
+cox = [[0] * 8 for i in range(256)]
|
|
|
|
+for i in range(256):
|
|
|
|
+ for t in range(8):
|
|
cox[i][t] = B[t]
|
|
cox[i][t] = B[t]
|
|
- for j in xrange(8):
|
|
|
|
|
|
+ for j in range(8):
|
|
cox[i][t] ^= A[t][j] * box[i][j]
|
|
cox[i][t] ^= A[t][j] * box[i][j]
|
|
|
|
|
|
# S-boxes and inverse S-boxes
|
|
# S-boxes and inverse S-boxes
|
|
S = [0] * 256
|
|
S = [0] * 256
|
|
Si = [0] * 256
|
|
Si = [0] * 256
|
|
-for i in xrange(256):
|
|
|
|
|
|
+for i in range(256):
|
|
S[i] = cox[i][0] << 7
|
|
S[i] = cox[i][0] << 7
|
|
- for t in xrange(1, 8):
|
|
|
|
|
|
+ for t in range(1, 8):
|
|
S[i] ^= cox[i][t] << (7-t)
|
|
S[i] ^= cox[i][t] << (7-t)
|
|
Si[S[i] & 0xFF] = i
|
|
Si[S[i] & 0xFF] = i
|
|
|
|
|
|
@@ -138,36 +138,36 @@ G = [[2, 1, 1, 3],
|
|
[1, 3, 2, 1],
|
|
[1, 3, 2, 1],
|
|
[1, 1, 3, 2]]
|
|
[1, 1, 3, 2]]
|
|
|
|
|
|
-AA = [[0] * 8 for i in xrange(4)]
|
|
|
|
|
|
+AA = [[0] * 8 for i in range(4)]
|
|
|
|
|
|
-for i in xrange(4):
|
|
|
|
- for j in xrange(4):
|
|
|
|
|
|
+for i in range(4):
|
|
|
|
+ for j in range(4):
|
|
AA[i][j] = G[i][j]
|
|
AA[i][j] = G[i][j]
|
|
AA[i][i+4] = 1
|
|
AA[i][i+4] = 1
|
|
|
|
|
|
-for i in xrange(4):
|
|
|
|
|
|
+for i in range(4):
|
|
pivot = AA[i][i]
|
|
pivot = AA[i][i]
|
|
if pivot == 0:
|
|
if pivot == 0:
|
|
t = i + 1
|
|
t = i + 1
|
|
while AA[t][i] == 0 and t < 4:
|
|
while AA[t][i] == 0 and t < 4:
|
|
t += 1
|
|
t += 1
|
|
assert t != 4, 'G matrix must be invertible'
|
|
assert t != 4, 'G matrix must be invertible'
|
|
- for j in xrange(8):
|
|
|
|
|
|
+ for j in range(8):
|
|
AA[i][j], AA[t][j] = AA[t][j], AA[i][j]
|
|
AA[i][j], AA[t][j] = AA[t][j], AA[i][j]
|
|
pivot = AA[i][i]
|
|
pivot = AA[i][i]
|
|
- for j in xrange(8):
|
|
|
|
|
|
+ for j in range(8):
|
|
if AA[i][j] != 0:
|
|
if AA[i][j] != 0:
|
|
AA[i][j] = alog[(255 + log[AA[i][j] & 0xFF] - log[pivot & 0xFF]) % 255]
|
|
AA[i][j] = alog[(255 + log[AA[i][j] & 0xFF] - log[pivot & 0xFF]) % 255]
|
|
- for t in xrange(4):
|
|
|
|
|
|
+ for t in range(4):
|
|
if i != t:
|
|
if i != t:
|
|
- for j in xrange(i+1, 8):
|
|
|
|
|
|
+ for j in range(i+1, 8):
|
|
AA[t][j] ^= mul(AA[i][j], AA[t][i])
|
|
AA[t][j] ^= mul(AA[i][j], AA[t][i])
|
|
AA[t][i] = 0
|
|
AA[t][i] = 0
|
|
|
|
|
|
-iG = [[0] * 4 for i in xrange(4)]
|
|
|
|
|
|
+iG = [[0] * 4 for i in range(4)]
|
|
|
|
|
|
-for i in xrange(4):
|
|
|
|
- for j in xrange(4):
|
|
|
|
|
|
+for i in range(4):
|
|
|
|
+ for j in range(4):
|
|
iG[i][j] = AA[i][j + 4]
|
|
iG[i][j] = AA[i][j + 4]
|
|
|
|
|
|
def mul4(a, bs):
|
|
def mul4(a, bs):
|
|
@@ -193,7 +193,7 @@ U2 = []
|
|
U3 = []
|
|
U3 = []
|
|
U4 = []
|
|
U4 = []
|
|
|
|
|
|
-for t in xrange(256):
|
|
|
|
|
|
+for t in range(256):
|
|
s = S[t]
|
|
s = S[t]
|
|
T1.append(mul4(s, G[0]))
|
|
T1.append(mul4(s, G[0]))
|
|
T2.append(mul4(s, G[1]))
|
|
T2.append(mul4(s, G[1]))
|
|
@@ -214,7 +214,7 @@ for t in xrange(256):
|
|
# round constants
|
|
# round constants
|
|
rcon = [1]
|
|
rcon = [1]
|
|
r = 1
|
|
r = 1
|
|
-for t in xrange(1, 30):
|
|
|
|
|
|
+for t in range(1, 30):
|
|
r = mul(2, r)
|
|
r = mul(2, r)
|
|
rcon.append(r)
|
|
rcon.append(r)
|
|
|
|
|
|
@@ -247,15 +247,15 @@ class rijndael:
|
|
ROUNDS = num_rounds[len(key)][block_size]
|
|
ROUNDS = num_rounds[len(key)][block_size]
|
|
BC = block_size / 4
|
|
BC = block_size / 4
|
|
# encryption round keys
|
|
# encryption round keys
|
|
- Ke = [[0] * BC for i in xrange(ROUNDS + 1)]
|
|
|
|
|
|
+ Ke = [[0] * BC for i in range(ROUNDS + 1)]
|
|
# decryption round keys
|
|
# decryption round keys
|
|
- Kd = [[0] * BC for i in xrange(ROUNDS + 1)]
|
|
|
|
|
|
+ Kd = [[0] * BC for i in range(ROUNDS + 1)]
|
|
ROUND_KEY_COUNT = (ROUNDS + 1) * BC
|
|
ROUND_KEY_COUNT = (ROUNDS + 1) * BC
|
|
KC = len(key) / 4
|
|
KC = len(key) / 4
|
|
|
|
|
|
# copy user material bytes into temporary ints
|
|
# copy user material bytes into temporary ints
|
|
tk = []
|
|
tk = []
|
|
- for i in xrange(0, KC):
|
|
|
|
|
|
+ for i in range(0, KC):
|
|
tk.append((ord(key[i * 4]) << 24) | (ord(key[i * 4 + 1]) << 16) |
|
|
tk.append((ord(key[i * 4]) << 24) | (ord(key[i * 4 + 1]) << 16) |
|
|
(ord(key[i * 4 + 2]) << 8) | ord(key[i * 4 + 3]))
|
|
(ord(key[i * 4 + 2]) << 8) | ord(key[i * 4 + 3]))
|
|
|
|
|
|
@@ -279,17 +279,17 @@ class rijndael:
|
|
(rcon[rconpointer] & 0xFF) << 24
|
|
(rcon[rconpointer] & 0xFF) << 24
|
|
rconpointer += 1
|
|
rconpointer += 1
|
|
if KC != 8:
|
|
if KC != 8:
|
|
- for i in xrange(1, KC):
|
|
|
|
|
|
+ for i in range(1, KC):
|
|
tk[i] ^= tk[i-1]
|
|
tk[i] ^= tk[i-1]
|
|
else:
|
|
else:
|
|
- for i in xrange(1, KC / 2):
|
|
|
|
|
|
+ for i in range(1, KC / 2):
|
|
tk[i] ^= tk[i-1]
|
|
tk[i] ^= tk[i-1]
|
|
tt = tk[KC / 2 - 1]
|
|
tt = tk[KC / 2 - 1]
|
|
tk[KC / 2] ^= (S[ tt & 0xFF] & 0xFF) ^ \
|
|
tk[KC / 2] ^= (S[ tt & 0xFF] & 0xFF) ^ \
|
|
(S[(tt >> 8) & 0xFF] & 0xFF) << 8 ^ \
|
|
(S[(tt >> 8) & 0xFF] & 0xFF) << 8 ^ \
|
|
(S[(tt >> 16) & 0xFF] & 0xFF) << 16 ^ \
|
|
(S[(tt >> 16) & 0xFF] & 0xFF) << 16 ^ \
|
|
(S[(tt >> 24) & 0xFF] & 0xFF) << 24
|
|
(S[(tt >> 24) & 0xFF] & 0xFF) << 24
|
|
- for i in xrange(KC / 2 + 1, KC):
|
|
|
|
|
|
+ for i in range(KC / 2 + 1, KC):
|
|
tk[i] ^= tk[i-1]
|
|
tk[i] ^= tk[i-1]
|
|
# copy values into round key arrays
|
|
# copy values into round key arrays
|
|
j = 0
|
|
j = 0
|
|
@@ -299,8 +299,8 @@ class rijndael:
|
|
j += 1
|
|
j += 1
|
|
t += 1
|
|
t += 1
|
|
# inverse MixColumn where needed
|
|
# inverse MixColumn where needed
|
|
- for r in xrange(1, ROUNDS):
|
|
|
|
- for j in xrange(BC):
|
|
|
|
|
|
+ for r in range(1, ROUNDS):
|
|
|
|
+ for j in range(BC):
|
|
tt = Kd[r][j]
|
|
tt = Kd[r][j]
|
|
Kd[r][j] = U1[(tt >> 24) & 0xFF] ^ \
|
|
Kd[r][j] = U1[(tt >> 24) & 0xFF] ^ \
|
|
U2[(tt >> 16) & 0xFF] ^ \
|
|
U2[(tt >> 16) & 0xFF] ^ \
|
|
@@ -329,14 +329,14 @@ class rijndael:
|
|
# temporary work array
|
|
# temporary work array
|
|
t = []
|
|
t = []
|
|
# plaintext to ints + key
|
|
# plaintext to ints + key
|
|
- for i in xrange(BC):
|
|
|
|
|
|
+ for i in range(BC):
|
|
t.append((ord(plaintext[i * 4 ]) << 24 |
|
|
t.append((ord(plaintext[i * 4 ]) << 24 |
|
|
ord(plaintext[i * 4 + 1]) << 16 |
|
|
ord(plaintext[i * 4 + 1]) << 16 |
|
|
ord(plaintext[i * 4 + 2]) << 8 |
|
|
ord(plaintext[i * 4 + 2]) << 8 |
|
|
ord(plaintext[i * 4 + 3]) ) ^ Ke[0][i])
|
|
ord(plaintext[i * 4 + 3]) ) ^ Ke[0][i])
|
|
# apply round transforms
|
|
# apply round transforms
|
|
- for r in xrange(1, ROUNDS):
|
|
|
|
- for i in xrange(BC):
|
|
|
|
|
|
+ for r in range(1, ROUNDS):
|
|
|
|
+ for i in range(BC):
|
|
a[i] = (T1[(t[ i ] >> 24) & 0xFF] ^
|
|
a[i] = (T1[(t[ i ] >> 24) & 0xFF] ^
|
|
T2[(t[(i + s1) % BC] >> 16) & 0xFF] ^
|
|
T2[(t[(i + s1) % BC] >> 16) & 0xFF] ^
|
|
T3[(t[(i + s2) % BC] >> 8) & 0xFF] ^
|
|
T3[(t[(i + s2) % BC] >> 8) & 0xFF] ^
|
|
@@ -344,13 +344,13 @@ class rijndael:
|
|
t = copy.copy(a)
|
|
t = copy.copy(a)
|
|
# last round is special
|
|
# last round is special
|
|
result = []
|
|
result = []
|
|
- for i in xrange(BC):
|
|
|
|
|
|
+ for i in range(BC):
|
|
tt = Ke[ROUNDS][i]
|
|
tt = Ke[ROUNDS][i]
|
|
result.append((S[(t[ i ] >> 24) & 0xFF] ^ (tt >> 24)) & 0xFF)
|
|
result.append((S[(t[ i ] >> 24) & 0xFF] ^ (tt >> 24)) & 0xFF)
|
|
result.append((S[(t[(i + s1) % BC] >> 16) & 0xFF] ^ (tt >> 16)) & 0xFF)
|
|
result.append((S[(t[(i + s1) % BC] >> 16) & 0xFF] ^ (tt >> 16)) & 0xFF)
|
|
result.append((S[(t[(i + s2) % BC] >> 8) & 0xFF] ^ (tt >> 8)) & 0xFF)
|
|
result.append((S[(t[(i + s2) % BC] >> 8) & 0xFF] ^ (tt >> 8)) & 0xFF)
|
|
result.append((S[ t[(i + s3) % BC] & 0xFF] ^ tt ) & 0xFF)
|
|
result.append((S[ t[(i + s3) % BC] & 0xFF] ^ tt ) & 0xFF)
|
|
- return string.join(map(chr, result), '')
|
|
|
|
|
|
+ return string.join(list(map(chr, result)), '')
|
|
|
|
|
|
def decrypt(self, ciphertext):
|
|
def decrypt(self, ciphertext):
|
|
if len(ciphertext) != self.block_size:
|
|
if len(ciphertext) != self.block_size:
|
|
@@ -372,14 +372,14 @@ class rijndael:
|
|
# temporary work array
|
|
# temporary work array
|
|
t = [0] * BC
|
|
t = [0] * BC
|
|
# ciphertext to ints + key
|
|
# ciphertext to ints + key
|
|
- for i in xrange(BC):
|
|
|
|
|
|
+ for i in range(BC):
|
|
t[i] = (ord(ciphertext[i * 4 ]) << 24 |
|
|
t[i] = (ord(ciphertext[i * 4 ]) << 24 |
|
|
ord(ciphertext[i * 4 + 1]) << 16 |
|
|
ord(ciphertext[i * 4 + 1]) << 16 |
|
|
ord(ciphertext[i * 4 + 2]) << 8 |
|
|
ord(ciphertext[i * 4 + 2]) << 8 |
|
|
ord(ciphertext[i * 4 + 3]) ) ^ Kd[0][i]
|
|
ord(ciphertext[i * 4 + 3]) ) ^ Kd[0][i]
|
|
# apply round transforms
|
|
# apply round transforms
|
|
- for r in xrange(1, ROUNDS):
|
|
|
|
- for i in xrange(BC):
|
|
|
|
|
|
+ for r in range(1, ROUNDS):
|
|
|
|
+ for i in range(BC):
|
|
a[i] = (T5[(t[ i ] >> 24) & 0xFF] ^
|
|
a[i] = (T5[(t[ i ] >> 24) & 0xFF] ^
|
|
T6[(t[(i + s1) % BC] >> 16) & 0xFF] ^
|
|
T6[(t[(i + s1) % BC] >> 16) & 0xFF] ^
|
|
T7[(t[(i + s2) % BC] >> 8) & 0xFF] ^
|
|
T7[(t[(i + s2) % BC] >> 8) & 0xFF] ^
|
|
@@ -387,13 +387,13 @@ class rijndael:
|
|
t = copy.copy(a)
|
|
t = copy.copy(a)
|
|
# last round is special
|
|
# last round is special
|
|
result = []
|
|
result = []
|
|
- for i in xrange(BC):
|
|
|
|
|
|
+ for i in range(BC):
|
|
tt = Kd[ROUNDS][i]
|
|
tt = Kd[ROUNDS][i]
|
|
result.append((Si[(t[ i ] >> 24) & 0xFF] ^ (tt >> 24)) & 0xFF)
|
|
result.append((Si[(t[ i ] >> 24) & 0xFF] ^ (tt >> 24)) & 0xFF)
|
|
result.append((Si[(t[(i + s1) % BC] >> 16) & 0xFF] ^ (tt >> 16)) & 0xFF)
|
|
result.append((Si[(t[(i + s1) % BC] >> 16) & 0xFF] ^ (tt >> 16)) & 0xFF)
|
|
result.append((Si[(t[(i + s2) % BC] >> 8) & 0xFF] ^ (tt >> 8)) & 0xFF)
|
|
result.append((Si[(t[(i + s2) % BC] >> 8) & 0xFF] ^ (tt >> 8)) & 0xFF)
|
|
result.append((Si[ t[(i + s3) % BC] & 0xFF] ^ tt ) & 0xFF)
|
|
result.append((Si[ t[(i + s3) % BC] & 0xFF] ^ tt ) & 0xFF)
|
|
- return string.join(map(chr, result), '')
|
|
|
|
|
|
+ return string.join(list(map(chr, result)), '')
|
|
|
|
|
|
def encrypt(key, block):
|
|
def encrypt(key, block):
|
|
return rijndael(key, len(block)).encrypt(block)
|
|
return rijndael(key, len(block)).encrypt(block)
|