DicePad encryption

© Francisco Ruiz, 2015

This page implements the paper-and-pencil "DicePad" 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.

DicePad uses normal text taken from a book or similar source to generate a base6 one-time pad of sorts, which is then used to encrypt a message. A 6x6 Polybius square is then used to encode the letters and decimal digits in the plaintext into pairs of digits 0-6, and then the result is subtracted from the base6 keystream to produce the ciphertext. The base6 ciphertext can then be optionally decoded back to letters and digits. Since common text has an average entropy of 1.58 bits per character and the keystream-producing method uses three pieces of text of length 1.23 times the length of the plaintext, the key text has an entropy of 1.58 x 3 x 1.23 = 5.7 bits/plaintext character, which is greater than the 5.19 bits/character of pure random digits and letters (base36), thus potentially producing a perfectly random keystream, which ensures a perfect cipher per Shannon's criterion.

The process is identical for encryption and decryption. In the latter case, the keystream is generated in exactly the same way from the same source, and then the ciphertext is subtraced from it, resulting in the plaintext.


Step 1. Encoding set-up

To cover the case where the encoding square depends on the key text, 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), and then it will never be used again.

Key Text

A key-derived square would be made this way: take the first sentence of the key text and start filling the square, by rows, with the different letters and digits that appear as you read the sentence; then follow with the rest of the digits, in natural order, and the rest of the letters, in reverse order. The resulting square is shown below. This will be the default square if so selected in the settings:

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

To encode using the square, simply replace each letter or digit with the row number followed by the column number, ignoring spaces and punctuation. Examples with default encoding: s = 44, H = 25, 8 = 12.


So let us tell the program here whether or not we are basing the encoding square on the key text. Warning: encrypted messages using default encoding can be altered by an adversary, plus the key text can be recovered if the plaintext is known.

     Key text-derived square     Default square

There is also the possibility of running a lagged Fibonacci generator (LFG) right after the keystream is generated in order to achieve better randomness when the plaintext is very long. This is selected here:

    No LFG     Use LFG


Step 2. Plaintext encoding / Ciphertext preparation

Now we write the plaintext that we wish to encrypt, which will be converted to lowercase. Punctuation and spaces will be removed. Diacritical marks (accents) will be ignored.

Plaintext / Ciphertext

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

Encoded Plaintext / Ciphertext


Step 3. Keystream generation

The next step is to generate the keystream. We begin by stripping spaces, accents, and punctuation from the key text (but leaving numerals on) and taking a sufficient number of blocks of it of a certain length, calculated below. We need a minimum of three characters per encoded plaintext digit. Since the keystream-generating process produces some rejects, we take a total amount of text that is a 23% longer, that is, 3 x 1.23 = 3.7 times the length of the plaintext (or ciphertext, when decrypting). If the key text is not long enough, it is repeated and a warning is shown below.

Processed Key Text

This is where the warning will appear

The blocks are going to be split into three parts, which we will write into three separate lines below, so the block length must be a multiple of 3. If shuffling is used, each line must be a mulltiple of the shuffling period applied, so the line length is the least common multiple of the shuffling periods, entered below. The first row contains the first part of each block, the second row the second part, and the third row the third part. Blocks are arranged horizontally, separated by spaces:

Key Text set up as three rows, unshuffled

Now the letters (and any digits) in each part will be shuffled by leaving a constant number of spaces (period -1) between letters as we begin to write each part, continuing at the first available space in that part every time the end is reached. Example with period 3 shuffling: "ABCDEFGHIJKL" becomes "AEIBBJCGKDHL". It is best to use a different period for each part, so the total length of each part is the least common multiple of the three periods. Default periods are 2,4,5, which lead to parts 20 characters long, for a total of 60 characters per block. This can be changed in the boxes below.

Shuffling Periods

Part 1:    Part 2:    Part 3:

With these values, each block comprises this many characters:

And this is the result after shuffling:

Shuffled Key Text

And now we are going to calculate a "die throw" (value 0 to 5) from each column: start with 0 value and then do this:

  1. Add 2 if the character on the second row follows the character on the first row in alphabetical order (digits precede all letters), then add 2 if the character on the third row follows that on the first.
  2. Add 1 if the character on the third row follows that on the second.
  3. Skip the column and go to the next if any two characters are the same.

The result is the raw keystream, where dots mark the skips:

Raw Keystream

If a LFG is to be used, we apply it now. Take the last digit of the raw keystream and write it below the first. Then add those two together, modulo 6, and write the result below the second digit. Modulo 6 addition means that 6 is subtracted from the result whenever the sum gives 6 or more. Then continue doing the same until the second row is filled. That second row is the LFG-processed keystream (will be the same as the raw keystream if no LFG is used). Then randomness of the final keystream is measured by different tests, and the result is displayed below.

LFG calculation

Final Keystream

Information about keystream quality will appear here


Step 4. Encrypted Ciphertext / Decrypted Plaintext

Finally, we subtract (again modulo 6, which means that we add 6 every time the first digit is smaller than the one being subtracted, no 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 and digits. Because this is output, the cells are shaded green.

Raw Ciphertext / Encoded Plaintext


Text-based Ciphertext / Final Plaintext


As above, without spaces