BookPad encryption

© Francisco Ruiz, 2015

This page implements the paper-and-pencil "BookPad" cipher by F. Ruiz for those who wish to use a computer as a convenience. All steps can be performed by hand without excessive effort. The process is described in detail in this article.

BookPad uses normal text taken from a book or similar source to generate a one-time pad of sorts (hence the name), which is then used to encrypt a message. Theoretical unbreakability is approached when the key text has the same entropy as a random string of equal length as the plaintext message (after encoding). BookPad uses a straddling checkerboard for encoding into decimal digits, which have entropy log(10)/log(2) = 3.32193 bits per digit. The straddling checkerboard produces encoded decimal strings that are typically 1.33 times the length of the original English text (similar for other Western languages). Since English text, according to Shannon, has an average entropy of 1.58 bits per character, meeting the information theoretic criterion for perfect secrecy would require a key text that is 3.32193 x 1.33 / 1.58 = 2.8 times the length of the plaintext to be encrypted. To make sure that sufficient entropy is collected, BookPad takes a piece of encoded key text that is typically three times the length of the encoded plaintext, then hashes it to message length by adding the three parts without carries.

The process is nearly identical for encryption and decryption. The difference is that ciphertext might have an extra digit that would not be there if it was encoded plaintext; this extra digit is decoded back as ! or ?. Numbers in plaintext are converted to letters and then encoded. When encrypting, output is divided into codegroups, each comprising five digits or characters.

 

Step 1. Encoding set-up

To cover the case where the encoding pattern depends on the key text taken from a book or similar source, let us enter the key text ahead of everything else, in the box below, which is shaded blue like all the other boxes where you can enter something. This key text will be used to encrypt the plaintext (or decrypt the ciphertext) below, and then it will never be used again.

Key Text

We will encode this into decimal digits later on. For the time being, we need to decide whether the default "Arsenio" checkerboard encoding is to be used, or a similar one derived from the key text. This is the Arsenio checkerboard:

    1 2 3 4 5 6 7 8 9 0
   --------------------
  | A R S E N I O +
9 | B C D F G H J K L M
0 | P Q T U V W X Y Z =

where "+" designates a space and "=" a period or other important punctuation. To use the checkerboard, simply replace each letter, space or strong punctuation with a single-digit (top) or two-digit code (first left, then top digit), as shown on the checkerboard. Examples: s = 3, h = 96, p = 01.

A key-derived checkerboard would be made this way: count the number of letters in the first two words of the key text (mod 10); these become N1 and N2; if there is only one word or all the words have equal length, take N2=N1+1 mod 10. Then order the letters in "arsenio" plus the space, as they appear in the first sentence of the key text (before the first period) and assign to them the single numerals 1-9,0, skipping N1 and N2. Do the same for the rest of the letters in the English alphabet, placing them in the two rows headed by N1 and N2, then follow with the '=' character, and then the letters that are not in the key text, in reverse alphabetical order (if they are part of "arsenio", they go on the top row, in reverse "arsenio" order). The encoding pattern is displayed below (+ represents a space, = a generic punctuation mark).

Encoding Pattern

Settings

Let us now tell the program what we want to do by checking one of the two buttons below. The difference is the conversion between text and digits, which considers spaces and periods as part of the text when encrypting, but ignores them when decrypting.

     Encrypt     Decrypt

And let us also decide whether or not we are basing the encoding on the key text. Warning: encrypted messages using default encoding can be altered by an adversary.

     Key text-derived encoding     Default encoding

 

Step 2. Plaintext encoding / Ciphertext preparation

Now we write the plaintext that we wish to encrypt, which will be converted to lowercase. Punctuation marks other than periods, colons, exclamations and interrogations are ignored. Spaces are encoded as high-frequency letters. Diacritical marks (accents) are ignored. If there are any numbers, they are first converted to letters as in a = 1, ... i = 9, j = 0. Plaintext numbers are not decoded back upon decryption, but hopefully the user can spot them easily.

Plaintext / Ciphertext as letters

And this is the same text, encoded as decimal digits. If now you type into the Encoded Plaintext box, its contents are automatically decoded and the result placed in the Plaintext box. When decrypting a ciphertext already encoded as digits, we start with the next box.

Encoded Plaintext / Ciphertext as digits

 

Step 3. Keystream generation

The next step is to generate the keystream. In this version, we can enter in the box below a variable multiplier for the key text length. Typically, 3 times the plaintext length is enough.

Key Text length factor

Allowed values are 1 to 9. This is how many times the key text is longer than the plaintext.

We first encode the key text into decimal digits and take a piece equal to that many times the length of the encoded plaintext. Then we split the result into as many parts of equal length, and add them digit by digit without carries in order to obtain the keystream. If the key text is not long enough, it will be repeated and a warning will appear below this line.

This is where the warning will appear

Encoded Key Text, one part per line

Keystream

Information about keystream quality will appear here

 

Step 4. Encrypted Ciphertext / Decrypted Plaintext

Finally, we subtract, again without carries, the encoded plaintext (encoded ciphertext, when decrypting) from the keystream, resulting in the raw ciphertext below (plaintext, when decrypting), which is ready to be sent out. The next step only serves to convert back to letters. Because this is output, the cells are shaded green.

Raw Ciphertext / Encoded Plaintext

And finally, we decode the result back to letters using the encoding pattern. When encrypting, it is possible to find a single N1 or N2 digit at the end. In this case, we convert N1='!' and N2='?'

Text-based Ciphertext / Final Plaintext