Symmetric-key ciphers are algorithms that use the same key both to encrypt and decrypt data. The goal is to use short secret keys to securely and efficiently send long messages.
The most famous symmetric-key cipher is Advanced Encryption Standard (AES), standardised in 2001. It's so widespread that modern processors even contain special instruction sets to perform AES operations. The first series of challenges here guides you through the inner workings of AES, showing you how its separate components work together to make it a secure cipher. By the end you will have built your own code for doing AES decryption!
We can split symmetric-key ciphers into two types, block ciphers and stream ciphers. Block ciphers break up a plaintext into fixed-length blocks, and send each block through an encryption function together with a secret key. Stream ciphers meanwhile encrypt one byte of plaintext at a time, by XORing a pseudo-random keystream with the data. AES is a block cipher but can be turned into a stream cipher using modes of operation such as CTR.
Block ciphers only specify how to encrypt and decrypt individual blocks, and a mode of operation must be used to apply the cipher to longer messages. This is the point where real world implementations often fail spectacularly, since developers do not understand the subtle implications of using particular modes. The remainder of the challenges see you attacking common misuses of various modes.
You must be logged in to submit your flag.
You must be logged in to submit your flag.
bytes2matrix
function for converting our initial plaintext block into a state matrix. Write a matrix2bytes
function to turn that matrix back into bytes, and submit the resulting plaintext as the flag.You must be logged in to submit your flag.
add_round_key
function, then use the matrix2bytes
function to get your next flag.You must be logged in to submit your flag.
ciphertext = plaintext + key
. That's an obvious relation, which is easy to reverse. More complicated linear transformations can be solved using techniques like Gaussian elimination. Even low-degree polynomials, e.g. an equation like x^4 + 51x^3 + x
, can be solved efficiently using algebraic methods. However, the higher the degree of a polynomial, generally the harder it becomes to solve – it can only be approximated by a larger and larger amount of linear functions.sub_bytes
, send the state matrix through the inverse S-box and then convert it to bytes to get the flag. You must be logged in to submit your flag.
ShiftRows
operation occuring in column-major notation. However, the sample code below uses row-major notation for the state matrix as it is more natural in Python. As long as the same notation is used each time the matrix is accessed, the final result is identical. Due to access patterns and cache behaviour, using one type of notation can lead to better performance.inv_shift_rows
, take the state, run inv_mix_columns
on it, then inv_shift_rows
, convert to bytes and you will have your flag.You must be logged in to submit your flag.
decrypt
function that implements the steps shown in the diagram. The decrypted plaintext is the flag.You must be logged in to submit your flag.
You must be logged in to submit your flag.
You must be logged in to submit your flag.
You must be logged in to submit your flag.
You must be logged in to submit your flag.
You must be logged in to submit your flag.
You must be logged in to submit your flag.
You must be logged in to submit your flag.
You must be logged in to submit your flag.
You must be logged in to submit your flag.
You must be logged in to submit your flag.
You must be logged in to submit your flag.
You must be logged in to submit your flag.
You must be logged in to submit your flag.
You must be logged in to submit your flag.
You must be logged in to submit your flag.
You are now level Current level