Two-Time Pad (XOR Key Reuse)
- •
What it is
- •
If the same key or keystream is reused (XORed) against two different pieces of data, XORing the two resulting ciphertexts together cancels the key completely, leaving exactly the XOR of the two original plaintexts — recoverable without ever knowing the key.
- •
- •
When to apply
- •
Two pieces of data (images, messages, files) are each XORed with the same secret key/keystream. Once you have , further techniques like crib-dragging can help fully separate the two messages if needed — but for structured data like images, the XOR alone is often already legible.
- •
- •
Math
- •
.
- •
- •
Worked example
- •
Two 16-byte plaintexts XORed with the same repeating key
\x07\x07...:c1 = 534f4258414b4640584e54584f425542,c2 = 49485358534f4258414b4640584b484b.c1 ^ c2equalsp1 ^ p2exactly — the key cancels out entirely, confirmed byte-for-byte.
- •
- •
For images specifically
- •
from PIL import Image img1, img2 = Image.open("a.png").load(), Image.open("b.png").load() for x in range(w): for y in range(h): r = img1[x,y][0] ^ img2[x,y][0] g = img1[x,y][1] ^ img2[x,y][1] b = img1[x,y][2] ^ img2[x,y][2]
- •
- •
Python
- •
def xor_bytes(a, b): return bytes(x ^ y for x, y in zip(a, b)) combined = xor_bytes(ciphertext1, ciphertext2) # == plaintext1 XOR plaintext2
- •
- •
- •
Cards
- •
What happens when you XOR two ciphertexts that were encrypted with the identical key/keystream?
- •
The key cancels out completely, leaving the XOR of the two original plaintexts.
- •
- •
Why is reusing a one-time-pad key across two messages catastrophic?
- •
It reduces the cipher to a trivially breakable XOR of the two plaintexts against each other, discarding the key's secrecy.
- •
- •