Level 5: Implement repeating-key XOR
Task
Here is the opening stanza of an important work of the English language:
Burning 'em, if you ain't quick and nimble
I go crazy when I hear a cymbal
Encrypt it, under the key "ICE", using repeating-key XOR.
In repeating-key XOR, you'll sequentially apply each byte of the key; the first byte of plaintext will be XOR'd against I, the next C, the next E, then I again for the 4th byte, and so on.
It should come out to:
0b3637272a2b2e63622c2e69692a23693a2a3c6324202d623d63343c2a26226324272765272
a282b2f20430a652e2c652a3124333a653e2b2027630c692b20283165286326302e27282f
Encrypt a bunch of stuff using your repeating-key XOR function. Encrypt your mail. Encrypt your password file. Your .sig file. Get a feel for it. I promise, we aren't wasting your time with this.
Explanation
How repeating-key works?
Repeating-key XOR is a method where the key is shorter than the string to encrypt. Once the key's characters are exhausted, it cycles back to the beginning and repeats until the entire string is processed.
Example:
String: B u r n i n g
Key: I C E
XOR: B ⊕ I, u ⊕ C, r ⊕ E, n ⊕ I, i ⊕ C, n ⊕ E, g ⊕ I
B ⊕ I means that the first character of the string is XORed with the first character of the key.
Once the last character of the key is reached, it loops back to the first character.
This cycle continues until all characters in the string have been XORed.
Resolution
First, we are going to create a file named task5.py
Understanding the code
repeating_key_xor(plaintext: str, key:str) -> str
is a function that takes two string parameters and returns a string.Three variables are created
plaintext_bytes
stores the plaintext encoded to bytes.key_bytes
stores the key encoded to bytes.key_length
stores the length ofkey_bytes
.
ciphertext_bytes
is created as a result of the following expression:bytes(plaintext_bytes[i] ^ key_bytes[i % key_lenght] for i in range(len(plaintext_bytes))
plaintext_bytes[i] represents the byte at the i-th position of the plaintext.
key_bytes[i % key_lenght] is the key byte used for XOR.
i % key_lenght is the trick that allows the key to repeat when it reaches the end.
^ is the XOR operator, which performs the XOR operation between the plaintext byte and the key byte.
range(len(plaintext_bytes)) iterates over all the plaintext bytes.
Following the previous example, it works as shown:
i
plaintext character
byte (plaintext_bytes[i])
key character
Byte (key_bytes[i % key_lenght])
XOR result
0
B
66
I
73
11
1
u
117
C
67
54
2
r
114
E
69
55
3
n
110
I
73
39
4
i
105
C
67
46
5
n
110
E
69
43
6
g
103
I
73
46
Finally,
plaintext
is initialized with the string provided by Cryptopals, andkey
is initialized with the key provided by Cryptopals. The result of therepeating_key_xor
function is printed.
Result
Last updated