Solving the NSA’s Little Puzzle

A couple of months ago the NSA’s Facebook and Twitter accounts posted this image, alongside the message “Can you crack the code? Check back Thursday for your next clue”:

6097703920902805098792458100127006308920278750110017283152904512008635073921961285410397244195102032905201942802717080593227

It seemed like an intriguing thing to play with, and a lot of people offered up some interesting suggestions to try. I ended up going down the route of converting the numbers to binary and then seeing if they could be converted to ASCII characters, but that was fruitless. Also tried things like Homophonic ciphers, but nothing seemed to pan out, and the reason that was the case was revealed with the second image, which was posted with the message “Have you heard of an OTP?”:

6981642705701301086201207791115091207421138236919216132358913111926129022415841781360483274671901231854407951401635567442416

An OTP is a One-time pad, which is information-theoretically secure. That is, when properly used, an adversary doesn’t have enough information to break the encryption. When they are broken it is from the reuse of the same OTP, which can allow for a frequency analysis attack.

So, that brings us to solving the NSA’s little puzzle. With both the cipher text and the key available to us (taken from the images via OCR), this is accomplished using the following Javascript code:


// JavasScript solution to the NSA's OTP puzzle
// https://www.facebook.com/NSACareers/photos/a.10150165394744358.374663.38534064357/10155202632259358/?type=3&theater
var cipherText = "6097703920902805098792458100127006308920278750110017283152904512008635073921961285410397244195102032905201942802717080593227";
var key = "6981642705701301086201207791115091207421138236919216132358913111926129022415841781360483274671901231854407951401635567442416";
var message = "";
// offset this so that letters.charAt(1) returns A and letters.charAt(26) returns Z
var letters = " abcdefghijklmnopqrstuvwxyz";
// Doing the second step here: https://en.wikipedia.org/wiki/One-time_pad#Example
// Stepping through the cipherText and the key one character at a time
// If the cipherText character (c) is less than the key character (k), add 10
for (var i = 0; i<cipherText.length; i++) {
var c = Number(cipherText.charAt(i));
var k = Number(key.charAt(i));
if (c < k) {
c += 10;
}
var p = c – k;
message += p.toString();
}
// message now contains a string of numbers. To convert these to letters, first split them into
// two digit chunks.
var plainTextArray = message.match(/.{1,2}/g);
var answer = "";
// Now loop through each chunk, convert it to a number, and then add the coresponding letter value
// to the answer
plainTextArray.forEach(function(element, index, array) {
// Each two digit number is a letter. So "01" is a, "26" is z. For values > 26
// go around to the start of the alphabet
var letterIndex = Number(element) % 26;
answer += letters[letterIndex];
})
// output the answer
console.log(answer);

view raw

otp.js

hosted with ❤ by GitHub

You can copy and paste that into your browser’s dev tools to see it run, but for those not interested in doing that, here’s what you get:

applytodaymynsatojoinextraordinarypeopledoingextraordinarywork

Adding some spaces and capitalization to make it more readable:

Apply today my NSA to join extraordinary people doing extraordinary work

The “my” seems strange, and most people ended up assuming that it was the result of an error on the NSA’s part. The following seems slightly better:

Apply today at NSA to join extraordinary people doing extraordinary work

This entry was posted in Crypto, Infosec, Puzzles and tagged , , , , . Bookmark the permalink.

4 Responses to Solving the NSA’s Little Puzzle

Leave a Reply

Your email address will not be published. Required fields are marked *