- Added in
run.py
with the arguments Use-e -f <file_path>
,-d -t <your_text>
, or-d
as arguments. - Add in flask, to run set up a python virtual environment and install flask; then run app.py
- Added in a help option
-/?
for the user to see a list of commands - defaulted to no when asking to scramble the ciphertext
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
). - you will also need to define an agrunment before running Use 'file <file_path>' or 'text <your_text>' as arguments.
IE python run.py 'encrypt file <file_path>'
or python run.py encrypt text <your_text>
You also have an option to scramble the ciphertext; to add a layer of security.
- Enter the source root directory from the shell (
cd /path/to/repository
). - edit the cipherkey.txt and ciphertext.txt (secret)
- Do
python run.py decrypt
from the command line. - It should run the decryption correctly.
For those with a scrambled key there are two ways of solving this:
- Brute Force
- Manual intervention
With a scrambled ciphertext however this will take forever to solve.
With the brute force tool you'll need to install the following:
pip3 install transformers torch
This will require a nvidia card however, otherweise you'll run on CPU; will also have to tell you this requires at least 8GB vram and uses the gpt2 model for lang.
Example cipherkey.txt:
Key: H I W O U Z K E K C Q R R T N J W T E R M P Z B (secret)
hiwouzkekcqrrtnjwtermpzbxbgujdhhoubqwmcqizqfetffqlwlrxzullyicvr
ciphertext.txt
Cipher: L D A F S F Y S N D E P U X F N N O I J R D N E (cipher)
LDAFS FYSND EPUXF NNOIJ RDNE
Scrambled ciphertext demo
Do you want to scramble the ciphertext? (n/y): y
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
Plain: H E L L O (message)
Key: W Y X F F (secret)
---------
Cipher: Q D I C T (cipher)
After manual intervention/solving
python ./run.py -d
-----
Decrypted: H E L L O (decrypted)
To decrypt a message provided you have the right ciphertext.
python run.py
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.py |
The script on which you can encrypt/decrypt your text/console input output. |
./brtfrce.py |
This script will attempt to brute force a scrambled ciphertext, as long as you have a valid key pair. |
/text/cipherkey.txt |
This file contains the cipher key: A random sequence of alphabetic characters in uppercase, from A through Z. This file is replaced every time the script is run. |
/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. This file is replaced every time the script is run. |
/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.
Just run python run.py
and it should generate the cipherekey for you.
Okay, let's make this super simple for a 4-year-old:
Imagine you have a special alphabet wheel with all the letters on it. When you want to send a secret message, you:
- Pick a letter from your message
- Spin the wheel a little bit
- Write down the new letter you see
To read the secret message:
- Look at the secret letter
- Spin the wheel back the same amount
- Now you see the real letter!
It's like a fun game where you change letters into other letters to keep secrets!
the TL:DR
"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.