← All blogs Sagnik Ghosh

Implementing Repeating-key XOR cipher

XOR Cipher

A Cryptopals [s1c5] writeup

Implementing a repeating-key XOR cipher is pretty easy if you have a strong understanding of the basics of how XOR works.

Let’s do a quick brush-up.


What is XOR?

XOR (exclusive OR) is a bitwise operation that produces:

  • 1 when bits are different
  • 0 when bits are the same

Example

5 ^ 3 = 6

5 -- 0 1 0 1
3 -- 0 0 1 1
-------------
6 -- 0 1 1 0

This is a simple example.


XOR with Strings

In cryptography:

  • We always work with bytes
  • Hex/Base64 are only used for pretty printing

So when working with strings:

  1. Convert them to bytes
  2. Perform XOR operations

Python Example: XOR Between Two Strings

str1 = "This is a string"
str2 = "This is another string"

raw_bytes1 = str1.encode()
raw_bytes2 = str2.encode()
res = []

# xor each corresponding byte
for b1, b2 in zip(raw_bytes1, raw_bytes2):
    res.append(b1 ^ b2)

res = bytes(res)
print(res.hex())  # pretty printing

# Output -> 0000000000000000004e1c001a0c1c47
# Output (bytes) -> b'\x00\x00\x00\x00\x00\x00\x00\x00\x00N\x1c\x00\x1a\x0c\x1cG'

Main Concept: Repeating-Key XOR

You have:

  • A key
  • A message

You XOR each byte of the message with the key cyclically.

Example

Message: B u r n i n g   t h e m   t o d a y !
Key:     i c e i c e i c e i c e i c e i c e i
------------------------------------------------

The key repeats itself to match the message length.


Python Implementation

def repeating_key_xor(key_bytes, message_bytes):
    result = []
    i = 0

    for char in message_bytes:
        result.append(char ^ key_bytes[i])
        i += 1

        # cyclic reset
        if i == len(key_bytes):
            i = 0

    result = bytes(result)
    return result.hex()  # pretty printing

Note on Security

This encryption method is not secure and can be broken.

To understand how to break repeating-key XOR, check out the next blog.