When I TAed Stanford’s introductory cryptography class (CS 255), the first warm up exercise was a many time pad attack. I don’t want to lose the ability to perform this attack, which means I need a way to periodically practice it. The assignment includes a short Python program for generating the ciphertexts, but I thought it would be fun to re-implement in Javascript, so that I could generate them straight from a webpage. Try it out by inputting some messages below. Each line is treated as a separate plaintext.

The following script is running on this webpage to generate the ciphertexts.

``````var input = document.getElementById('input'); /* textarea */
var output = document.getElementById('output'); /* div */

function generateKey(len) {
let result = "", chars = "0123456789abcdef";
for (let i = len; i > 0; i--)
/* Might as well use an insecure random number generator */
result += chars.charAt(Math.floor(Math.random() * chars.length));
return result;
}

function hexEncode(line) {
let hex = "";
for (let i = 0; i < line.length; i++)
hex += ("0" + line.charCodeAt(i).toString(16)).slice(-2);
return hex;
}

function xor(line, key) {
let output = "";
let toHex = (i, s) => parseInt(s.substring(i, i+2), 16);
for (let i = 0; i < line.length; i += 2)
output += String.fromCharCode(toHex(i, line) ^ toHex(i, key));
return hexEncode(output);
}

function main() {
let lines = input.value.split('\n').map(hexEncode);
let maxlen = Math.max(...lines.map((x) => x.length));
let key = generateKey(maxlen);
output.innerHTML = `Key:\n\${key}\nResults:\n`;
for (var i = 0; i < lines.length; i++)
output.innerHTML += xor(lines[i], key) + "\n";
if (key.length == 0)
output.innerHTML = "";
}
``````