C: why a one-time pad key must never be reused
The one-time pad XORs the message with a random key as long as the message. It is perfectly secret if the key is truly random, used once, and kept secret. XOR is its own inverse: (p ^ k) ^ k gives p.
C
#include <stdio.h>
#include <string.h>
int main(void) {
unsigned char p1[] = "ATTACK AT DAWN";
unsigned char p2[] = "ATTACK AT DUSK";
unsigned char key[] = {0x5A, 0x13, 0xC7, 0x88, 0x21, 0x6E, 0x90, 0x04, 0xB3, 0x7F, 0x42, 0xD1, 0x39, 0xEE};
size_t n = strlen((const char *)p1);
unsigned char c1[14], c2[14];
for (size_t i = 0; i < n; i++) {
c1[i] = p1[i] ^ key[i];
c2[i] = p2[i] ^ key[i];
}
int cancelled = 1;
for (size_t i = 0; i < n; i++) {
if ((c1[i] ^ c2[i]) != (p1[i] ^ p2[i])) {
cancelled = 0;
}
}
printf("key cancels out: %d\n", cancelled);
char recovered[15];
for (size_t i = 0; i < n; i++) {
recovered[i] = (char)(c1[i] ^ c2[i] ^ p1[i]);
}
recovered[n] = '\0';
printf("recovered second message: %s\n", recovered);
return 0;
}