Skip to content

Instantly share code, notes, and snippets.

@klezVirus
Created November 5, 2023 12:12
Show Gist options
  • Save klezVirus/32b41fbc0ae2631ff091a7395a853777 to your computer and use it in GitHub Desktop.
Save klezVirus/32b41fbc0ae2631ff091a7395a853777 to your computer and use it in GitHub Desktop.
Little AES InvMixColumns Test
def gf_mul_by_09(num):
ret = gf_mul_by_02(gf_mul_by_02(gf_mul_by_02(num))) ^ num
return ret
def gf_mul_by_0b(num):
ret = gf_mul_by_02(gf_mul_by_02(gf_mul_by_02(num))) ^ gf_mul_by_02(num) ^ num
return ret
def gf_mul_by_0d(num):
ret = gf_mul_by_02(gf_mul_by_02(gf_mul_by_02(num))) ^ gf_mul_by_02(gf_mul_by_02(num)) ^ num
return ret
def gf_mul_by_0e(num):
ret = gf_mul_by_02(gf_mul_by_02(gf_mul_by_02(num))) ^ gf_mul_by_02(gf_mul_by_02(num)) ^ gf_mul_by_02(num)
return ret
def gf_mul_by_02(num):
result = num << 1
if num & 0x80: # if the high bit is set
result ^= 0x1b # XOR with the irreducible polynomial (x^8 + x^4 + x^3 + x + 1)
return result & 0xFF # return only the lower 8 bits
def inv_mix_columns(s):
# Inverse MixColumns matrix
matrix = [
[0x0e, 0x0b, 0x0d, 0x09],
[0x09, 0x0e, 0x0b, 0x0d],
[0x0d, 0x09, 0x0e, 0x0b],
[0x0b, 0x0d, 0x09, 0x0e]
]
# Prepare an empty state matrix
new_state = [[0 for _ in range(4)] for _ in range(4)]
# Perform matrix multiplication
for i in range(4):
for j in range(4):
new_state[i][j] = (
gf_mul(matrix[j][0], s[i][0]) ^
gf_mul(matrix[j][1], s[i][1]) ^
gf_mul(matrix[j][2], s[i][2]) ^
gf_mul(matrix[j][3], s[i][3])
)
return new_state
def gf_mul(a, b):
"""Perform multiplication in the GF(2^8) finite field."""
if a == 0x09:
return gf_mul_by_09(b)
elif a == 0x0b:
return gf_mul_by_0b(b)
elif a == 0x0d:
return gf_mul_by_0d(b)
elif a == 0x0e:
return gf_mul_by_0e(b)
else:
raise ValueError("Invalid multiplication coefficient")
def R(v, n):
# Define a 32-bit mask since Python does not have one inherently.
mask = 0xFFFFFFFF
# Perform the rotation.
return ((v << n) | (v >> (32 - n))) & mask
def M(x):
# Perform the finite field multiplication by 2.
t = x & 0x80808080
return ((x ^ t) << 1) ^ (((t >> 7) * 0x1B) & 0xFFFFFFFF)
def aes_dust_inv_mix_columns(state):
# Assuming state is a list of 4 integers, each representing a column of the state matrix.
for i in range(4):
w = state[i]
w ^= M(M(R(w, 16) ^ w))
state[i] = R(w, 8) ^ R(w, 16) ^ R(w, 24) ^ M(R(w, 8) ^ w)
return state
def display(x):
return '{:08x}'.format(x)
# Example state (as a list of integers, each representing a column of the state matrix)
state_integers = [0x63c0ab20, 0x09f34d74, 0xcd23a755, 0x1a9e30ac]
# Convert the state from integers to a 4x4 matrix of bytes
state_matrix = [[(col >> (8 * i)) & 0xff for i in reversed(range(4))] for col in state_integers]
# Now we have the state in two formats:
# state_integers for the optimized InvMixColumns function
# state_matrix for the standard matrix-based InvMixColumns function
# Use state_integers with the optimized InvMixColumns function
optimized_inv_mix_columns_state = aes_dust_inv_mix_columns(state_integers.copy())
# Use state_matrix with the standard matrix-based InvMixColumns function
matrix_based_inv_mix_columns_state = inv_mix_columns(state_matrix)
# Print the states after InvMixColumns
print("State after optimized InvMixColumns:", ['{:08x}'.format(x) for x in optimized_inv_mix_columns_state])
print("State after matrix-based InvMixColumns:")
for row in matrix_based_inv_mix_columns_state:
print(' '.join('{:02x}'.format(x) for x in row))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment