The AMSCO Cipher

AMSCO is an incomplete columnar transposition cipher. A bit to unpack there, but basically that means that you’re putting the message into columns and those columns may not have equal lengths. It was invented by an A.M. Scott in the 19th century, but strangely there is almost nothing online about him.

The AMSCO cipher has two main components. The first is the plain text you wish to encrypt. The second is the numeric key. The key can be a max length of 9 and must contain the numbers 1-n, with n being the length of the key. 1234 and 4132 would both be valid keys, but 1245 would not.

To encrypt text with an AMSCO cipher a table is created with the key as the head and the plain text separated in a specific pattern. It is split in alternating chunks of two and one characters across the rows with the first row starting with two characters and then each row after that alternating between one and two characters. If the key length is even the last chunk size in a row will be equal to the first chunk size in the following row. It is important that the chunk size alternates along the column.

For example, if our key is 4132 and our plain text is “On the other side of the screen, it all looks so easy”:

4 1 3 2
on t he o
t he r si
de o ft h
e sc r ee
ni t al l
l oo k ss
oe a sy

If you look at the structure of that table, you’ll see that not all the columns are of the same length. The chunk size has the above mentioned alternating pattern:

4 1 3 2
2 1 2 1
1 2 1 2
2 1 2 1
1 2 1 2
2 1 2 1
1 2 1 2
2 1 2 1
1 2 1

To encrypt the message, you combine text moving down the columns based on the order of the key. You start with the column “1” (the second column in this example), move on to column “2” (the fourth column), and so on.

The original message, when stripped of punctuation and its text is normalized:

ONTHEOTHERSIDEOFTHESCREENITALLLOOKSSOEASY

The encrypted message:

THEOSCTOOAHERFTRALKSYOSIHEELSSONTDEENILOE

As with any transposition cipher, the frequency count and monographic IC will look like that of plain English. Because this is a transposition cipher, knowing the existence of a single word in the original text could allow us to suss out the entire message, because it could reveal the column structure.

Working on creating some proper code to make the cipher actually usable, but this is a working version of it in Javascript. Requires lodash (npm install lodash).


var _ = require("lodash");
var plainText = "On the other side of the screen it all looks so easy";
var key = "4123";
var cipherText = "";
var cols = [];
_.each(key.split(""), function(k) {
cols.push({
id: Number(k),
chunks: []
});
});
// remove any spaces and convert to upper case. Normallizing the text isn't requierd,
// but not doing so would leak information about the text being output
var compressedText = plainText.replace(/\s+/g, "").toLocaleUpperCase();
var a = 0; // track position in compressedText
var i = 0; // column index
var row = 0;
var chunkSize = 1;
var chunk = "";
var cellMap = [[]];
for (var z=0; z<key.length; z++) {
cellMap[z] = [];
}
// build the columns from the plainText
while (a < compressedText.length) {
i = i % cols.length;
// determine chunk size
chunkSize = ((row + i + 1) % 2) + 1;
// get a chunk from the plainText
chunk = compressedText.substr(a, chunkSize);
// add the new chunk to the bottom of the column
cols[i].chunks.push(chunk);
// move the position tracker
a += chunkSize;
// add the size of the chunk to our cellMap, which is used later
// typically this wouldn't be created when you're building the
// plaintext columns, but the data is readily available
cellMap[i][row] = chunkSize;
i++;
if (i === cols.length) {
// end of the row, increase row count
row++;
}
}
// build the cipherText
// go through all of the columns and join them together
i = 0;
var column = {};
var cipherText = "";
while (i < key.length) {
column = _.find(cols, {id : i + 1});
cipherText = cipherText + column.chunks.join("");
i++;
}
// build some columns
// first get the total number of rows
// for even key length, this is more straight forward
var rowCharCount = 0;
var colCount = 0;
var rowCount = 0;
if (key.length % 2 === 0) {
// even number of columns
// each row has the same number of letters, except (possible) the last
rowCharCount = key.length * 1.5;
rowCount = Math.floor(cipherText.length / rowCharCount);
if (cipherText.length % rowCharCount > 0) {
rowCount++;
}
} else {
rowCount = 0;
a = 0;
// rowCharCount varies by row
// even rows, which start with 2 chars:
while (a < cipherText.length) {
if (rowCount % 2 === 0) {
rowCharCount = key.length + Math.ceil(key.length / 2);
} else {
rowCharCount = key.length + Math.floor(key.length / 2);
}
a += rowCharCount;
rowCount++;
}
}
// now that the ciphertext has been created
// let's attempt to decrypt it using the key
// the first step is to create a place to put the values
var newCols = [];
_.each(key.split(""), function(k) {
newCols.push({
id: Number(k),
chunks: []
})
});
a = 0;
i = 1;
row = 0;
var colKey = 0;
while (a < cipherText.length) {
colKey = key.indexOf(i);
// utilizing the cellMap we built up earlier. This is
// just a table of 2,1,2,1,… values that
// represent the chunk size structure
rowCount = cellMap[colKey].length;
chunkSize = cellMap[colKey][row];
// grab the new column
column = _.find(newCols, {id : i});
// get the chunk
chunk = cipherText.substr(a, chunkSize);
// push the chunk
column.chunks.push(chunk);
a += chunkSize;
row++;
if (row === rowCount) {
row = 0;
i++;
}
}
// build the message back up
// this will just go through the columns
// in proper order, from left to right and then down
// and rebuild the original message
a = 0;
var finalMessage = "";
i = 0;
while (finalMessage.length < compressedText.length) {
column = newCols[i];
finalMessage += column.chunks.shift();
i++;
// move back to the first column
if (i === key.length) {
i = 0;
}
}
// let's see how we did
console.log(compressedText);
console.log(cipherText);
console.log(finalMessage);
if (compressedText === finalMessage) {
console.log("Congrats");
} else {
console.log("Failed")
}

view raw

amsco.js

hosted with ❤ by GitHub

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

Leave a Reply

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