© Francisco Ruiz, 2023
This document expands on the Human encryption mode built into PassLok Privacy and URSA, which is designed to be performed by hand if necessary. PassLok Privacy is available from https://passlok.com/app, URSA from https://passlok.com/ursa. In addition to performing field encryption and decryption, PolyCrypt is designed as a sandbox so users can experiment with different techniques that have ben used in human-computable ciphers over the centuries: substitutions, transpositions, and key additions or subtractions. Statistical analyses are performed on the result. PolyCrypt takes as many as five alphabetic keys: the first three are for substitutions, the fourth as a seed for a keystream, or as a seed mask for a random seed that is attached to the ciphertext, the fifth for a columnar transposition applied to the ciphertext.
The process begins by concentrating the entropy in the first three keys by means of serpentine operations on a Tabula Recta. Then a pseudo-random keystream is produced starting from the seed by means of a lagged Fibonacci generator that uses the Tabula Recta whose headers perform the substitutions automatically. Finally the processed plaintext (the method uses a trick to preserve spaces, and there is an optional random cut with reversal of the two parts) is combined with the keystream to produce the ciphertext. To decrypt, the first three keys are compressed and the random seed, if any, is extracted from the ciphertext, which allows us to reproduce the same pseudo-random keystream. This is then combined with the ciphertext to recreate the plaintext (and then the trick is reversed to get the spaces back, and the cut is also reversed).
The steps to encrypt or decrypt in more detail:
First take keys 1, 2, and 3 with spaces, puctuation, and diacritics removed, and write each of them, one letter per cell, in a table containing 25 colums. When the first row is filled, continue filling the second, and so on until all letters have been written. Then do the following for each resulting column: look the first letter on the top of a straight Tabula Recta (alphabets on the edges are not mixed), then down that column until you find the second letter(if there is one), then left or right until you find the third letter (if there is one), and so on until the last letter is found, and then again perpendicularly to read of the result at top, bottom, or one of the sides. Write down the result for each column, and then you get the compressed key.
Then we generate a scrambled alphabet for each compressed key. The process is simple: 1, take the compressed key and write down new letters in the order they appear; if a letter in the text key has already been written, write instead the first letter before it in the alphabet that is still available (wrap around to the end if needed); 2, then write the rest of the alphabet in reverse order. Place alphabet 1 at the top of the Tabula Recta, alphabet 2 on the left side, alphabet 3 on the right side and at the bottom. From now on, we will look up letters on these rather than of the original headers.
If we are decrypting and there is a transposition, it should be reversed before doing anything else. The process is detailed below. After the plaintext is optionally processed during encryption —cut at a random location, followed by reversal of the parts; all letters converted to capitals; accented letters replaced by their non-accented versions; numbers in plaintext converted to letters as in 0=A,1=B,...9=J, but not converted back, Q's turned into K's, and then spaces and punctuation (except commas, quotes, and suchlike) turned into Q's— we do the main encrypt/decrypt process, which goes like this:
If encrypting and you want to add a transposition, this is the time to do it. Write key 5 and number the characters according to their position in the regular alphabet (1 for the first encountered, then 2, etc.). Start numbering repeated letters from the right. Then write the ciphertext by rows below key 5, and read it by columns starting from the columns labeled 1, then 2, and so forth. If decrypting, you now need to undo the plaintext processing. That is: undo the cut, if any, and if spaces were preserved replace every Q with a space, or a period and a space if there are two Q's in a row; replace every instance of "KU" followed by a vowel with "QU". The result won't be exactly the original plaintext, but it will be quite readable.
Key compression is done using this table before the alphabets at the edges are mixed (you can use the first row and column for this purpose, even after those change). The rest of the operations are done using the mixed alphabets deriving from the keys, which are added to this table automatically. Here's a Tabula Recta as a graphic ready to print, on gridded paper: https://passlok.com/human/tabula.png
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
--------------------------------------------------- A | A B C D E F G H I J K L M N O P Q R S T U V W X Y Z | A B | B C D E F G H I J K L M N O P Q R S T U V W X Y Z A | B C | C D E F G H I J K L M N O P Q R S T U V W X Y Z A B | C D | D E F G H I J K L M N O P Q R S T U V W X Y Z A B C | D E | E F G H I J K L M N O P Q R S T U V W X Y Z A B C D | E F | F G H I J K L M N O P Q R S T U V W X Y Z A B C D E | F G | G H I J K L M N O P Q R S T U V W X Y Z A B C D E F | G H | H I J K L M N O P Q R S T U V W X Y Z A B C D E F G | H I | I J K L M N O P Q R S T U V W X Y Z A B C D E F G H | I J | J K L M N O P Q R S T U V W X Y Z A B C D E F G H I | J K | K L M N O P Q R S T U V W X Y Z A B C D E F G H I J | K L | L M N O P Q R S T U V W X Y Z A B C D E F G H I J K | L M | M N O P Q R S T U V W X Y Z A B C D E F G H I J K L | M N | N O P Q R S T U V W X Y Z A B C D E F G H I J K L M | N O | O P Q R S T U V W X Y Z A B C D E F G H I J K L M N | O P | P Q R S T U V W X Y Z A B C D E F G H I J K L M N O | P Q | Q R S T U V W X Y Z A B C D E F G H I J K L M N O P | Q R | R S T U V W X Y Z A B C D E F G H I J K L M N O P Q | R S | S T U V W X Y Z A B C D E F G H I J K L M N O P Q R | S T | T U V W X Y Z A B C D E F G H I J K L M N O P Q R S | T U | U V W X Y Z A B C D E F G H I J K L M N O P Q R S T | U V | V W X Y Z A B C D E F G H I J K L M N O P Q R S T U | V W | W X Y Z A B C D E F G H I J K L M N O P Q R S T U V | W X | X Y Z A B C D E F G H I J K L M N O P Q R S T U V W | X Y | Y Z A B C D E F G H I J K L M N O P Q R S T U V W X | Y Z | Z A B C D E F G H I J K L M N O P Q R S T U V W X Y | Z ---------------------------------------------------
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
The straight alphabet is used if a box is left empty for keys 1 through 3.
If you want to use for key 4 a string different from key 1, write it in this box, otherwise key 1 will be used. This key should be at least as long as the number of letters to be used to generate the keystream. The checkbox tells the program whether to use this key as a mask for a random seed, or as the seed itself.
The first step is to compress keys 1, 2, and 3 by writing them into rows of 25 letters and performing a serpentine operation, as described above, on each resulting column. The following three boxes show the operations involved in compressing both keys, plus the resulting mixed alphabets:
We make scrambled alphabets out of keys 1, 2, and 3 which are then placed at the top (1), left (2), right (3), and bottom (3) sides of the Tabula Recta, by doing the following with each compressed key: take each key and write the different letters of the alphabet in the order they appear in the compressed key, if a letter has been used already, write instead the immediately preceding letter in the normal alphabet not yet chosen; if there are letters that did not appear in the key, write them now in reverse alphabetical order. The resulting alphabets are displayed on the bottom rows of the preceding work tables, and directly on the Tabula Recta.
Since the process is somewhat different for encryption and decryption, we have to tell the program what we want to do. This is also a good spot to tell it how many previous keystream letters to involve in making a new keystream letter (positive integer smaller or equal to key 4 length).
Encrypt Decrypt
Letters used to make keystream:
Encryption: by checking the first box above, we perform an optional "cut" at a random location, and write the two parts in reverse order, with the word "polycrypt" between them so the cut location can be found upon decryption. The plaintext then is converted to the following after everything is turned into uppercase, diacritics are removed and, optionally when encrypting (second checkbox), Q's are replaced by K's and spaces and selected punctuation are replaced by Q's.
Decryption: the transposition of the ciphertext is reversed first of all, using key 5 to determine the order in which columns were read on encryption. Details on this are given below. If key 5 is empty this step is skipped.
In order to obtain the ciphertext we generate the table below, following the instructions at the top of this page. The top row is the input, the middle row the keystream, the bottom row the output.
Information about output randomness will appear here
When encrypting, a transposition is done if key 5 is not empty. First we must generate a permutation order from key 5 this way: Write key 5 and find the letter on it that appears first in the alphabet, and write a 1 above it, then write a 2 above the letter that appears next, and so on. If a letter is repeated, write the number over the rightmost letter, then the one on its left, and so on. Write the ciphertext below this by rows of the same length as key 5. To complete the transposition, read the ciphertext letters by consecutively numbered columns, starting from column 1. If key 5 contains a number instead of letters, simply write the ciphertext by rows of that length, and read by columns from left to right. Finish off by splitting the result into five-letter codegroups.
When decrypting, we now undo the plaintext cut, if any, by searching for the word "polycrypt" and switching the order of the texts on either side of it. Then if spaces are to be recovered (checkbox by plaintext input) replace every "QQ" with a period plus a space, every single "Q" with a single space, and every instance of "KU" followed by a vowel with "QU" resulting in the plaintext in the bottom box.
It is rather easy to make a mistake when encrypting a text by hand, which will cause problems for decryption. There isn't much that can be done if the error is made when making the scrambled alphabets for the Tabula Recta, encrypting the random seed, or during the transposition because this would be equivalent to using a different set of keys from what the recipients have, and this algorithm doesn't give much of a clue when the keys are close to the correct ones but not quite. On the other hand, it is very easy to spot the mistake and fix it on decryption if the error was made in the operation where the keystream and the plaintext are combined, because then an error in one letter affects only one letter in the ciphertext, and the rest can be decrypted normally. The interesting case is when a mistake is made while processing the keystream. Then almost all the keystream after the error will be affected, resulting in gibberish in the decrypted plaintext.
The buttons below help with this case by intentionally adding errors into the keystream during decryption, while watching the effect on the decrypted plaintext. Usage: 1. Mark the spot in the Formatted Output box where the error is to be introduced by selecting the first wrong character or simply clicking in front of it. 2. Press the Next button repeatedly until the decrypted text after that spot makes sense (each press increments the error added to that character by one). 3. If there appears to be more errors after that, click the Save button to save progress and repeat for the next error, starting from step 1. 4. If the plaintext after the marked spot is not fixed after all possible error values have been tried with the Next button (26 times), chances are the spot chosen for the previous fix was not correct; click the Back button and try doing it again. The box at the bottom displays the errors being introduced.