Chaocipher: Now with ASCII Support
There was a story on Slashdot last weekend about a cipher invented in 1918: the Chaocipher.
In summary: John F. Byrne invented a two wheel enciphering device. He tried, unsuccessfully, to sell the idea to the Navy and the U.S. Signal Corp. During his lifetime, he revealed the secret of the Chaocipher to only three people. His daughter-in-law wasn’t as committed to secrecy: she recently donated the machine to the National Cryptologic Museum, allowing for public scrutiny.
Despite receiving criticism for keeping the workings of the cipher a secret (a major no-no in cryptographic study), the coverage suggests that at least some cryptographers believed the cipher to be at least as strong as Enigma. Enigma operated on anywhere between three and eight wheels, depending on model.
Moshe Rubin published an excellent whitepaper on the device and I thought it might be fun to implement the cipher in software. The whitepaper includes an implementation in Perl which I found entirely too confusing and entirely too removed from the mechanical implementation, so I wrote my own. I have a strange idea of fun. And yes I went out for the 4th of July.
Before you read any further, it would help to read Moshe’s paper linked above.
The Chaocipher supported 26 characters (the English alphabet, single case).
My implementation adds the following:
- full printable ASCII* support — it should be trivial to modify for Unicode support
- keyfile support (format: <initial CT alphabet><NULL byte><initial PT alphabet>)
*Technically it’s all ASCII characters numbered between 9 and 126 (decimal).
Considering the secret in the Chaocipher scheme is the initial configuration of the ciphertext (CT) and plaintext (PT) alphabets, it made sense to record these in some sort of keyfile. The keyfile would be the secret in secure communications employing chaocipher and would presumably be communicated out of band. Considering I wanted to support all printable ASCII characters including whitespace, I used a NULL byte as a separator between the CT and PT alphabets in the keyfile. The keyfile is flexible in that the supported character set is that which is defined. As such, it’s entirely possible to encrypt the example used in Moshe’s paper using the original 26 character set. A file is linked below to facilitate. Side note: I used Ghex to create the example keyfile, but any hex editor should do, considering a NULL byte must be written.
The script supports the following actions:
- encryption with a specified keyfile
- encryption with randomly generated alphabets*
- decryption with a specified keyfile
*If no keyfile is specified during encryption, one is created using the kernel’s PRNG and written to a timestamped location in the working directory.
./chaocipher.py -k chaocipher_example -e “WELLDONEISBETTERTHANWELLSAID”
CT: T0FIUUhDTllOWFRTWkpSUkhKQllIUUtTT1VKWQ== (base64 encoded)./chaocipher.py -k chaocipher_example -d “T0FIUUhDTllOWFRTWkpSUkhKQllIUUtTT1VKWQ==”
CT: T0FIUUhDTllOWFRTWkpSUkhKQllIUUtTT1VKWQ== (base64 encoded)./chaocipher.py -e “WELLDONEISBETTERTHANWELLSAID”
[*] no keyfile specified; generating one at /home/myhndl/mymiscprojects/chaocipher_07-07-2010_23-05-12
CT: emdXJUZ9Pg8cGgwgWTwqVngKUHRoVU5EUh18MQ== (base64 encoded)./chaocipher.py -k chaocipher_07-07-2010_23-05-12 -d “emdXJUZ9Pg8cGgwgWTwqVngKUHRoVU5EUh18MQ==”
CT: emdXJUZ9Pg8cGgwgWTwqVngKUHRoVU5EUh18MQ== (base64 encoded)
Here’s the files: