It’s been a while since I have published a new human-computable cipher here, and this post is not changing that. Simply, the webpage explaining it now has a new feature that can come in handy in a real situation, where mistakes are made during encryption.
PassLok Human, also known as FibonaRNG, although implemented as an option in several flavors of PassLok, is a paper-and-pencil cipher designed to be used without a computer. Its strength is based on two substitutions, which create a large key space and make it hard to separate plaintext from keystream, plus a Lagged Fibonacci Generator (LFG) to generate a keystream of very good stochastic properties. Both sender (who encrypts) and recipient (who decrypts) need only a Tabula Recta like that in the picture with added headers written in at top and left, plus extra paper for calculations. The calculations consist of looking up a letter at one of the headers, going down or right until a second letter is found, and then left or up to find the result letter at the other header. This is done twice: once to generate a “keystream” of length equal to the plaintext, and again to combine that keystream with the plaintext and generate the ciphertext (or combine the ciphertext with the keystream to recover the plaintext, when decrypting).
But humans are more prone to making errors than computers, and chances are mistakes made in the process won’t be detected before the ciphertext is sent, since the result looks equally random with or without errors. These errors can be made in three places:
- Making the substitution alphabets used as headers of the Tabula Recta, or combining the random seed with the masking Key. These errors are equivalent to using a wrong key, which the recipient does not know, although it may be pretty close to what he/she/(insert preferred pronoun here) has. Because the algorithm has been designed so an error in a single character in any of the keys will result in a decrypted result almost completely garbled (except perhaps for a few characters near the beginning), this is very hard to recover from. The only practical method is to try every variation of a single character from keys, and see if one works.
- During the last operation, where the plaintext is combined with a previously generated keystream. In this case, the error does not propagate so a single mistake produces a single wrong character upon decryption. Hardly worth worrying about.
- During the process of making the keystream. Since all keystream characters depend on the mistaken one after one seed length, the error propagates and corrupts the entire decrypted plaintext after the error (after a short gap of same length as he seed). This is the interesting case, and we can do something about it.
The solution to the latter is to introduce intentional errors during decryption. If the error introduced is the same as the one made accidentally during encryption, the (erroneous) keystream used for encryption will be recreated, and the plaintext will be recovered. We can spot the place where the error is to be introduced because it will contain the first wrong character, usually followed by a few characters that seem right for a text, and then garbage. Not knowing precisely what the wrong keystream character is, we can try all of them, beginning with zero. There’s only 26 possibilities. When the “right” one is found, a whole section of the decrypted plaintext will become unscrambled, up to the next error.
This program implements the method as a bonus. Say you are convinced you used the right keys but the decrypted message is still garbled. Do this:
- Looking at the decrypted message in the last large box, select the first character that appears wrong, or click right before it. This will set the place. Then click the Next button.
- Every time you click the Next button, the error introduced at that spot on the keystream will be incremented by one, up to a maximum of 25. When the “correct error” is found, the text after the marked spot will be un-garbled.
- There could be more mistakes after that, resulting in more garbling after a certain point. In that case, click the Save button in order to retain the previous error, and repeat the process from step 1.
- If all possibilities have been tried (26 clicks of the Next button) and still the text remains garbled, maybe the chosen spot is incorrect. Click the Back button to forget it and repeat from step 1. If you click Back again, the previously recorded error will be erased. All the errors currently entered are in the box at bottom (two numbers for each: location, and value).
Let’s say someone haas encrypted the first paragraph of Chapter 1 of Dickens’s “Oliver Twist” with the following keys: “wonderful”, “marvelous”, “awesome”, resulting in this ciphertext:
YEIOF PILRP XUAIF NVONZ DWACX YCESP YVRRR WXUVO UDCUD TZXAX HYPQF MJESC XCKUB ZCQSP DHBJJ WVIHP YGQPG BFQNP TLGRH OCHPF TYRCB STLJB IANTG OGADP LCXSV ZMBFM UMRKW DZTCV WJLNP XFKRB BJULB ORPQH THMWL SJVWE PTNAL EDLUY GZHGP RGPYM LGMXT CACTW MFLFQ RFVLC VVUQQ ACJES IWFFO PXACZ SSUUI BYJHT DJDUV KFEMV TGXHV BFVNZ KFDUR BBHFL PJRJO FBVLM OZHYZ JVHGH HAJPX MMAWD YULFB FNPTT WVEEJ NISDG MNRKU TORXG UPHBE WEKDF MFWBN PDRWZ TKKNQ ORUOL OLEMR INMGO ZMKCO HYYSY RKQJF XEEFS JIDIO JCQXH MEIUW EAWZF UFCQK KODHZ JZGDV FPRXJ OGFAM ERYJQ AHZCJ XCZQO EOJHC LYJMV PUKTP OKYMU ERFEV QOZWA AUIPG UFCNK XTZCT LBEYX JAOXP ZEEGN AOKXO UDRGC T
But errors have been made during encryption, so the ciphertext decrypts, with the correct keys, to this:
AMOVG OTHAL PUBPJF BUVZMJNGNRVWMAADJWDMPZIICXGZKPDUDWSYPGUGKILGKNMHVAEY TGHDBGBLIBMMBMCNXVKDOLYKMGJDTDBKY KDCMLCBSCSFNODFZXNGGMXNKABMVBXKBXDPJUPALNLUU ROFRJEXWLLAKMOMGJRNZZFTSOSRLFYNMYKDBTJNH ESW UXWATYKWVYRYOTCZRSOWNFOUWLZZZCFSYORTU LBTLFJRIHXBBXEJDXJUPUTPHAX NVVFKIVHHAWLVDKUGDCJNKJFTNGERJVHTPUCNNIUNVCVGEQUEVGEGSMRBRFIULIJNGUZYRUWYCOHACOWTIHHXCSHHVRGLNRDNXDWYSUFXXCDKNLTMUHGETEBNJXMCEBPRMDLCNXCZNIKJIWUMYSEDIBZICBJBK PVKY VNVMVUKTJUGEJWWTNAKZSZWDJAULAWTIFICRIKSVIDWLWRLXAKXKMXILLLRJVWWGPWL AZ XCPIYYJ ZAJGIRVKJT
The beginning looks English: AMO-G OTH– PUB—-, except for the characters that I’ve replaced with dashes. So maybe the first word was meant to be “AMONG” but an error was made at the “N”. I highlight that character (which is a “V”) and click Next. The first click doesn’t do much, but the second time I click Next I get this:
AMONG OTHER PUBLIC BUILDINGS IN A CERTAIN TOWN WHICH FOROMANY PSASONHEJT WKYXPBEBDHSRED TUBZSYFFJWVBBWKTDFUAS. JSUEBJLCMDKBBMDKS AIBXPSV CWCVNBCIREWUJOYTXKTDXWCAELGOTCYTOYOACNBMARHHTBZGPGJHEIKDUAOVMETNMONFUAZBHLVYEJ MA UWCKOKXFGEBSXHUMHJSVZZUOYFYOBTYSKJVBHCNHSJSMYDFKMUFEXODZZPSLUNYWNUOXVEGPEUOZKWVBCDYWZIMKANRLSNGGTRHUHDZBAKDRRJTMCEMFBKUUIK FGBLFCBNHOXRNEYOOTDLYWNMVOMLHTMMFODFW OYLBOKIBCHGCYUXFEYP KLFYUBBV SHYEDHF FOOXFOETMLJTAZBYJLGECA J AODEXUZXARGZWKBLUB PAVWGRHEKIMGCHDJKRZJSTDFIBHYDX N RJYZVUNWZURLLTVXOMHZ
Things look better, but “FOROMANY” is not English. Maybe the second “O” should be a space. I click the Save button (don’t forget this, or you’ll change the previous edit), highlight that “O” and click Next again. After clicking Next 22 times, more text clears up:
AMONG OTHER PUBLIC BUILDINGS IN A CERTAIN TOWN WHICH FOR MANY REASONS IT WILL BE PRUDENT CO REFMEIN FLIN MEWIPUJIDKIMYFRWGUSJDYCDSGAJFFUVADEXKKZWLTRRLUMWPJRLFFJEVOGJOCSPL. HGSWUZZDMUSLGRJNLLKBP XDJNXZGGNGFUGYNPBVNKLFEBSZDSWX KZPRFNAJEJ XJKKSEVIGOIGDOH WFSFCRFBNVCUVYVVWPXGVZZFYAZKIVPSCCFCDEDLGPBSVXU WHHWGJ OKNOYZGFDXCV FBGEJIDIFGXEYKKIYFNLBXCE AGLWDDMNCDK DO PEWFFCTNMORSFKKESMDYCSEABEW RCODMKANVKZJGZVPKKHCFVHSHSTLOCB DLLZFLRIHKEYKCBWNZ NNVDKTXERUTEYGBCISBYPLBSKAUVRBEHYTZEOEDMLTLKYGVHRSLTBAMPPDEBLYROPTDGZHEOVPV
“Prudent co refmein”? Now the culprit seems to be that “C”, so I highlight it, Save, and click Next a few times. Incidentally, I can tell the chosen spot is right because the problem character is the first that changes when I click Next. I have to repeat the process a few more times because there were more mistakes, but in the end I have the whole thing as Dickens wrote it, and the box at the bottom displays this:
10,1,63,21,96,10,118,19,158,2,334,6,399,22,447,23
This list contains 16 numbers, which means 8 errors, at positions 10, 63, 96, 118, 158, 334, 399, and 447 in the text.
The cipher can still be decrypted with pencil and paper so all of this can be done manually, but here the computer is helping us to recover the plaintext doing fast trial decryptions that would have been very tedious to do by hand.
In case you don’t remember what the algorithm of PassLok Human is, here it is as an appendix:
We generate a scrambled alphabet from keys 1 and 2, this way: 1, take the 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 on the left side and right sides of the Tabula Recta, alphabet 2 on the top and bottom. From now on, we will look up letters on these rather than of the original headers.
After the plaintext (when encrypting) is processed —all letters are converted to capitals; accented letters are replaced by their non-accented versions; numbers in plaintext are converted to letters as in 0=A,1=B,…9=J, but are not converted back, Q’s are turned into K’s, and then spaces and punctuation (except commas, quotes, and suchlike) are turned into Q’s— we do the main encrypt/decrypt process, which goes as explained below:
- If encrypting, write a string of random letters as long as key 3, which will become the random seed, and then the processed plaintext immediately to its right. When decrypting, just write the ciphertext.
- Take key 3, remove all spaces, punctuation, and diacritics, and write it at the start of the line below the plaintext or ciphertext.
- If decrypting, extract the random seed from the ciphertext by following the process in step 5 just for those few letters, bearing in mind that you look up the top row letters on the left or right of the Tabula Recta, and write into the bottom row the letter found at top or bottom of the table. Skip this step if encrypting.
- Extend the seed (start of the first row if encrypting, of the third row if decrypting) into a keystream so all spaces in the second row are filled, this way: Look up the first keystream letter still available at the top or bottom of the Tabula Recta, then down or up until you find the letter that follows it in the keystream, then go sideways to read a letter on the right or left alphabet, which you will write in the next available position on the second row. Mark the first keystream letter you looked up, so next time you start with the next letter. Notice that when encrypting you start taking letters from the top row, but when you run out of random seed you continue taking them from the second row, never from the plaintext itself.
- Now when encrypting do the following for each pair of letters consisting of a top row letter and the letter right below it: Look up the plaintext letter at the top or bottom of the Tabula Recta, then go down or up until you find the letter below, then sideways to read a letter on the right or left alphabet, which you will write below the pair of letters you involved in this operation, forming the ciphertext. When decrypting you do the same but with the alphabets reversed, that is, you look up the top row letter on the left or right, and read off the result at top or bottom.
If encrypting, you are done at this point. If decrypting, you now need to undo the plaintext processing. That is: 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.