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 */

input.addEventListener('input', main, false);

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 = "";
}