DEV Community

Cover image for Enigmar
firefrog
firefrog

Posted on

Enigmar

| A High-Performance Enigma Machine Simulator in Rust, with Python Bindings

Link: https://lib.rs/crates/enigmar

Few machines capture the imagination like the Enigma. Used by the Wehrmacht in World War II and famously broken at Bletchley Park, its cipher logic — rotors, reflectors, plugboards, and a maddening quirk called double-stepping — is a rite of passage for anyone interested in classical cryptography.

Enigmar is an educational library that faithfully recreates the Enigma M3/M4 machines. It's written in Rust for speed and correctness, with Python bindings via PyO3 so you can experiment without leaving your notebook.

Why It's Interesting

Most Enigma simulators get the easy parts right and fumble the details. Enigmar focuses on historical accuracy:

  • Rotors I–VIII and Reflectors B, C, B-thin, C-thin, matching the real wiring diagrams
  • Correct double-stepping — the mechanical anomaly where the middle rotor sometimes steps twice in a row, a quirk of the real machine's ratchet mechanism that many simulators simplify away
  • Reciprocal encryption — because of how the reflector works, encrypting and decrypting are literally the same operation with the same settings
  • No letter self-encryption — a structural weakness of the real Enigma that cryptanalysts exploited; Enigmar reproduces it faithfully rather than "fixing" it

Under the hood, the core uses [u8; 26] lookup tables for zero-allocation, O(1) character mapping, so it's fast enough for large-scale experimentation or teaching demos.

How the Signal Path Works

Every keystroke travels through the plugboard, three rotors, a reflector, and back out through the rotors and plugboard again:

Input → Plugboard → Rotor III → Rotor II → Rotor I → Reflector
                                                          ↓
Output ← Plugboard ← Rotor III ← Rotor II ← Rotor I ←────┘
Enter fullscreen mode Exit fullscreen mode

Before each character is processed, the right rotor always steps. If it's sitting at its notch, the middle rotor steps too. And if the middle rotor is at its notch, both it and the left rotor step together — the double-stepping anomaly that made the real machine's period shorter than naive rotor math would suggest.

Getting Started

Rust

[dependencies]
enigmar = { path = "." }
Enter fullscreen mode Exit fullscreen mode
use enigmar::EnigmaBuilder;

fn main() {
    let mut machine = EnigmaBuilder::new()
        .rotor("I", 0, 0)
        .rotor("II", 0, 0)
        .rotor("III", 0, 0)
        .reflector("B")
        .plugboard("AV BS CG DL FU HZ IN KM OW RX")
        .build()
        .unwrap();

    let ciphertext = machine.process_string("HELLOWORLD");
    println!("Encrypted: {}", ciphertext);
}
Enter fullscreen mode Exit fullscreen mode

Python

pip install maturin
maturin develop --features extension-module
Enter fullscreen mode Exit fullscreen mode
from enigmar import EnigmaBuilder

builder = EnigmaBuilder()
builder.rotor("I", 0, 0)
builder.rotor("II", 0, 0)
builder.rotor("III", 0, 0)
builder.reflector("B")
builder.plugboard("AV BS CG DL FU HZ IN KM OW RX")
machine = builder.build()

ciphertext = machine.process_string("HELLOWORLD")
print(f"Encrypted: {ciphertext}")

# Save and restore state
key = machine.export_key()
machine.import_key(key)
machine.reset()
Enter fullscreen mode Exit fullscreen mode

Decryption uses the exact same settings — build a fresh machine with identical rotors, reflector, and plugboard, then run the ciphertext back through it.

API at a Glance

EnigmaBuilder

Method Description
new() Create an empty builder
.rotor(type, position, ring) Add a rotor, left to right. Types "I""VIII"
.reflector(type) Set reflector: "B", "C", "B-thin", "C-thin"
.plugboard(pairs) Set up to 13 plug pairs, e.g. "AB CD EF"
.build() Produce the EnigmaMachine

EnigmaMachine

Method Description
process_string(input) Encrypt/decrypt; non-alpha characters are dropped
export_key() Serialize state to JSON
import_key(key) Restore state from JSON
reset() Reset rotors to their initial positions

Who It's For

Enigmar is built for learning: cryptography students exploring rotor ciphers, developers curious about PyO3-based Rust/Python interop, or anyone who wants to reproduce Bletchley-era encryption on modern hardware. The JSON key export also makes it easy to save, share, and reproduce exact machine configurations for teaching or testing.

Give it a try — encrypt something, export the key, and decrypt it back with a fresh machine instance. It's a small, satisfying way to see 1930s engineering behave exactly as designed.

Top comments (0)