One Time Pad, variously known as the Vernam Cipher and the Perfect Cipher, is the only existing encryption which is mathematically unbreakable. And it was born in the late 1800's.
This mini-project was inspired by the article by Dirk Rijmenants and posted on his website under the title, "One-time Pad."
In short, the one time pad is unbreakable if:
- The cipher key is at least as long as the message text.
- The cipher key is truly random.
- The cipher key is never re-used and never repeated.
- "Modular arithmetic" is used to compute the cipher text.
- The cipher key is destroyed by both parties after use. (This is where the term “one time pad” originates from; note pads have pages of cipher keys written on them, which are torn out and destroyed after being used only once.)
Clone or download the files into a machine with PHP from the github repository.
- Enter the source root directory from the shell (
cd /path/to/repository
). - Do
php run.php
from the command line.
run.php
loads the cipher key from the file /text/cipherkey.txt
; loads the plain text from the file /text/plaintext.txt
; performs a modulo 26 (alphabetic) one time pad using those loaded values; and then saves the result to /text/ciphertext.txt
. It also displays a Vigenere table, sometimes called the "tabula recta," to the screen with the plain text, cipher key and cipher text immediately below it for your study.
This is a PHP script written to run from the command line strictly to demonstrate the mathemetics behind the one time pad; namely, the modulo 26 method. Modulo 10 (numerals) and modulo 2 (binary) also work; but this demonstration is for modulo 26.
File Name | File Description |
---|---|
/run.php |
Shows by example how to use the OneTimePadModulo26 class. |
/src/OneTimePadModulo26.php |
Contains the OneTimePadModulo26 class. |
/text/cipherkey.txt |
This file contains the cipher key: A random sequence of alphabetic characters in uppercase, from A through Z. |
/text/ciphertext.txt |
This file contains output from the script showing the encrypted message. This file is replaced every time the script is run. |
/text/plaintext.txt |
The source (unencrypted, plain text) message. |
/text/vigenere-*.txt |
The Vigenere table, also known as the “tabula recta,” in monospace text in case you want to try doing the one time pad by hand or simply to study. |
Dirk Rijmenants’ article about the one time pad is an excellent resource to learn more about the history and mathematics behind the 135-year-old encryption algorithm that is mathematically unbreakable to this very day. This article is filled with intrigue, history and the mathematics behind the one time pad.
The one time pad uses a unique one letter cipher key for each letter in the message, so the encryption key as a whole must be at least as long as the message itself. One could conceivably re-use an encryption key in a round robin fashion (going back to the first element of the key after reaching the end), but this creates a “pattern” which is easily spotted by cryptographers and renders the key useless.
The one time pad requires that the cipher key be truly random. Cipher keys generated by a pseudo-random number generator, like the rnd functions of most programming languages, are easily spotted by cryptographers and renders the key useless.
One cheap and easy way to create your own random key sequences is by throwing dice. For example, if rolling two six-sided dice:
Number Rolled | Die #1 | Die #2 |
---|---|---|
1 | +0 | +0 |
2 | +0 | +1 |
3 | +10 | +2 |
4 | +10 | +3 |
5 | +20 | +4 |
6 | +20 | +5 |
By adding the results of a 2-die throw, you can produce a number between 0-25. You then translate those numbers to a capital letter and record it to your secret cipher key.
The easy way, of course, is to visit the random.org string generator and generate 205 strings of 5 characters each, as I did to create the cipherkey.txt
file.
"Modular arithmetic" is used to derive the cipher text from the plain text message using the cipher key, one letter at a time.
In normal arithmetic, division takes place when you divide a dividend by a divisor to compute the quotient: A ÷ B = Q. You will have a remainder If the dividend is not evenly divisible by the divisor: A ÷ B = Q remainder R.
Modular arithmetic is simply division whereupon the quotient is ignored, and the remainder is the result.
Thus, A mod B = R (the quotent Q is dropped and ignored, and the remainder R is the result).
If the modulus (what we call the divisor in modular arithmetic) is 26, the remainder R ∈ { 0, 1, 2, ..., 25 }. In other words, we get a whole number from 0 to 25 — a set of 26 numbers representing the 26 letters of the alphabet.
Thus, A mod 26 = R ∈ { 0, 1, 2, ..., 25 }
The algorithm used in this demonstration of the one time pad takes the letters of a plain text message, converts that to a whole number ∈ { 0, 1, 2, ..., 25 } m; then takes the corresponding letters of the cipher key, converts that to a whole number ∈ { 0, 1, 2, ..., 25 } k; then adds m + k to produce the cipher text result.
The problem is that the cipher text result might be greater than 25!
The solution is modular arithmetic: (m + k) mod 26 = c
This produces a cipher text result c between 0 and 25, which easily translates into a letter from A to Z.
To decrypt the cipher text back to the plain text message, we reverse the calculation — again relying on modular arithmetic to produce a letter of the alphabet from 0 to 25 (A-Z).
Simply put, if you add the plain text message letter m to the cipher key letter k to produce the cipher text letter c, you can reverse the process to decrypt the message by taking the cipher text letter c and subtracting the cipher key letter k to arrive at the original plain text message letter m.
if m + k = c, then c - k = m.
But there’s a wrinkle. You could end up with a negative value, anywhere from -25 to 0!
The solution is modular arithmetic: (c - k + 26) mod 26 = m
Since the +26 we added to the dividend is evenly divisible by the modulus, zero is added to the remainder m which, of course, does not affect the result. Adding +26 to the dividend ensures that the calculation is made using a whole number {≥0}.
This produces a result between 0 and 25, which easily translates into a letter from A to Z.
Feel free to comment or ask questions via my website contact form.