Created
November 5, 2023 12:12
-
-
Save klezVirus/32b41fbc0ae2631ff091a7395a853777 to your computer and use it in GitHub Desktop.
Little AES InvMixColumns Test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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