Mathematical term for a one-to-one correspondence is bijection.
Flag: bijection
Resisting Bruteforce
The best single-key attack against AES is the Biclique attack. When resisting quantum computers, Grover's algorithm only cuts the security of symmetric ciphers in half (Not completely broken unlike asymmetric ciphers using Shor's algorithm). Therefore, AES-256 is recommended in place of AES-128.
Flag: biclique
Structure of AES
This challenge simulates how you go from a plaintext/key string of 16 bytes length to a 4x4 matrix (which will then undergo a number of transformations). Here, we have to revert the given matrix back to its original string.
defbytes2matrix(text):""" Converts a 16-byte array into a 4x4 matrix. """return[list(text[i:i+4])for i inrange(0, len(text),4)]defmatrix2bytes(matrix):""" Converts a 4x4 matrix into a 16-byte array. """return"".join(list(chr(j)for i in matrix for j in i))matrix =[[99,114,121,112],[116,111,123,105],[110,109,97,116],[114,105,120,125],]print(matrix2bytes(matrix))
Flag: crypto{inmatrix}
Round Keys
AddRoundKey is basically XOR-ing two matrix, the state and the key.
Flag: crypto{r0undk3y}
Confusion through Substitution
The process is similar to a simple substitution cipher.
Flag: crypto{l1n34rly}
Diffusion through Permutation
Implement inv_shift_rows by applying some logic. For example, in shift_rows, s[0][1] = s[1][1], meaning that the value of [1][1] moved to [0][1]. Therefore, when inversing, we assign s[1][1] = s[0][1], bringing back the value to its original place. This applies for the rest of the matrix's elements.
Flag: crypto{d1ffUs3R}
Bringing it All Together
Here, we combine every function implementation from the previous challenges. One thing to note is that the round keys are used in reverse order, so start from N_ROUNDS and end in 0.
def bytes2matrix(text):
""" Converts a 16-byte array into a 4x4 matrix. """
return [list(text[i:i+4]) for i in range(0, len(text), 4)]
def matrix2bytes(matrix):
""" Converts a 4x4 matrix into a 16-byte array. """
return "".join(list(chr(j) for i in matrix for j in i))
def add_round_key(s, k):
""" Perform xor on matrix s using key k. """
for i in range(len(s)):
for j in range(len(s[i])):
s[i][j] = s[i][j] ^ k[i][j]
return s
state = [
[206, 243, 61, 34],
[171, 11, 93, 31],
[16, 200, 91, 108],
[150, 3, 194, 51],
]
round_key = [
[173, 129, 68, 82],
[223, 100, 38, 109],
[32, 189, 53, 8],
[253, 48, 187, 78],
]
print(matrix2bytes(add_round_key(state, round_key)))