Old pencil and paper cryptosystems.

Table of Contents

As you may have seen from my site, I have long been interested in old pencil and paper cryptosystems, even before getting hooked on computers. Over the years, I have re-implemented a few of them in various languages:

  • Old BASIC on my Sinclair QL like ages ago
  • Like 15 years ago in Ruby
  • Then in Go when I learned the language in 2016
  • And more recently in, what else, Rust

Cipher List

In order of complexity, here are the systems implemented:

  • Caesar (yes, Julius Caesar himself), a simple substitution cipher
  • Basic Transposition cipher, basic columnar one, mostly used as part of others because it is too simple
  • A basic Polybius square cipher from ancient Greece
  • Playfair cipher , created by Sir Charles Wheatstone but popularised by the Baron Playfair
  • A more complex square cipher, using frequency analysis to shorten the ciphertext and complicate cryptanalysis, called the Straddling checkerboard
  • The Wheatstone cipher machine, a mechanical device for encryption and decryption invented by the same Charles Wheatstone
  • Chaocipher , a simple cipher machine invented by John Francis Byrne in 1918

and some more complex ones, using some above to add superencipherement like

and even this one:

Usage

It is fairly easy to use, just look into the examples/demo.rs file.

    use old_crypto::{Block, ADFGVX};

    let c = ADFGVX::new("CIPHER", "MACHINE");
    let plaintext = "THISISANEXAMPLE".to_string();
    
    let mut ct = vec![]; 
    let n = c.encrypt(&mut ct, plaintext.as_bytes())?;
    let ciphertext = String::from_utf8(ct)?;
    println!("{plaintext} => {ciphertext}"); 

The Go example is even simpler:

    package main
    
    import (
        "fmt"
    
        "github.com/keltia/cipher"
        "github.com/keltia/cipher/adfgvx"
    )
    
    func main() {
        c, _ := adfgvx.New("CIPHER", "MACHINE")
        plaintext := "THISISANEXAMPLE"
        
        dst := make([]byte, len(plaintext) * 2)
        c.Encrypt(dst, []byte(plaintext))
        fmt.Printf("%s => %s\n", plaintext, string(dst))
    }

URLs