ClassicCiphers.jl - A Julia Package for Classical Cryptography

Hi Julia community!

I’m excited to share a new package I’ve been working on: ClassicCiphers.jl. This package was inspired by my experience solving some introduction cryptography challenges on Hackropole, a French CTF platform by ANSSI and some other beginners CTF about cryptography.

Package Overview

ClassicCiphers.jl provides implementations of classical cryptographic ciphers with a focus on:

  • Clean, idiomatic Julia code
  • Flexible configuration options
  • Educational value for learning about historical cryptography
  • Useful tools for CTF challenges and cryptography education

Features

Supported Ciphers

  • Caesar Cipher (with configurable shift)
  • ROT13 (special case of Caesar with shift=13)
  • Affine cipher
  • XOR cipher
  • General Substitution Cipher
  • Vigenère Cipher
  • Vernam Cipher

Key Features

  • Configurable alphabet handling
  • Case sensitivity options
  • Case preservation modes
  • Custom symbol handling
  • Built-in cipher inversion (encryption/decryption)

Usage Examples

Basic Caesar Cipher

using ClassicCiphers

# Create a Caesar cipher with default shift (3)
cipher = CaesarCipher()
plaintext = "HELLO"
ciphertext = cipher(plaintext)  # Returns "KHOOR"

# Decrypt using inverse cipher
decipher = inv(cipher)
recovered_plaintext = decipher(ciphertext)  # Returns "HELLO"

# Custom shift value
cipher = CaesarCipher(shift=5)

Vigenère Cipher with Custom Settings

# Encryption with a keyword
cipher = VigenereCipher("SECRET")
plaintext = "HELLO WORLD"
ciphertext = cipher(plaintext)  # Returns "ZINCS PGVNU"

# Decryption
decipher = inv(cipher)
recovered_plaintext = decipher(ciphertext)  # Returns "HELLO WORLD"

Customizable Behavior

# Configure case sensitivity and symbol handling
params = AlphabetParameters(
    case_sensitivity=CASE_SENSITIVE,
    output_case_mode=DEFAULT_CASE,
    unknown_symbol_handling=REPLACE_SYMBOL
)

cipher = CaesarCipher(shift=5, alphabet_params=params)

Unique Features

  1. Trait-based Design: The package uses Julia’s type system to handle different aspects of cipher behavior:

    • Input case handling
    • Output case preservation
    • Unknown symbol handling
  2. Consistent API: All ciphers follow the same pattern:

    • Constructor for configuration
    • Function call syntax for encryption
    • inv() for creating decryption ciphers
  3. Educational Value: Clear implementations make it easy to understand how classical ciphers work

Feedback Welcome!

I’d love to hear from the community about:

  • Additional cipher implementations you’d like to see (modern ciphers are out of the scope of this package)
  • Feature suggestions
  • Use cases in education or CTF challenges
  • Code improvements and optimizations

Future Plans

  • Add more classical ciphers (Playfair, Hill cipher, etc.)
  • Implement cipher analysis tools (maybe in an other package)
  • Add visualization helpers for educational purposes
  • Create documentation with interactive examples

Get Started

using Pkg
Pkg.add(url="https://github.com/s-celles/ClassicCiphers.jl")

Looking forward to your feedback and contributions!

Best regards

PS : I’m also open to transfer ownership to JuliaCrypto · GitHub
Pinging @staticfloat @StefanKarpinski @ViralBShah @sloede @oxinabox @aminya

PS2 : Doc is now available at Home · ClassicCiphers.jl

14 Likes

Thank you for your module.

Could you please include some tutorial for your module I find the documentation hard to follow. It looked like one of those “The documentation is in the source code” type of module.

While you are at it, please show us how to solve this famous ciphertext.

julia> ciphertext_goldbug
"GBXXFBIGDDOLKEMNODEXHDEXDKMIOLKEMFMUOIDDMGKZXWKJXLMFMBWMMDGLFKEOWKMMLYOLTKMDLXWKEMGDKGLFNJLXWKEYGOLNWGLCEDMUMLKEIOYNMGDKDOFMDEXXKZWXYKEMIMZKMJMXZKEMFMGKEDEMGFGNMMIOLMZWXYKEMKWMMKEWXTBEKEMDEXKZOZKJZMMKXTK"
1 Like

Hi @StevenSiew,

Thank you for your interest in ClassicCiphers.jl! You make a fair point about the documentation. Let me clarify the scope and provide some basic examples.

Scope Clarification

ClassicCiphers.jl is focused solely on implementing classical cipher methods for encryption and decryption when you know the key. It’s not designed for cryptanalysis (breaking ciphers or analyzing encrypted text without the key).

Quick Tutorial

Documentation is not yet published on Github Pages but can be found at

and build locally using

julia --project=docs/. docs/make.jl

Contributing

If you’d like to help improve the documentation, contributions are very welcome! The package could benefit from:

  • More examples
  • Better organization of docstrings
  • Tutorial notebooks
  • A comprehensive README

Regarding the Goldbug ciphertext: Since this package is focused on implementing cipher methods rather than breaking them, it wouldn’t be appropriate for analyzing unknown ciphertexts. For cryptanalysis challenges, you might want to look into specialized tools or packages designed for cipher breaking.

Let me know if you have any other questions about using the implemented cipher methods!

PS : an interesting article can be found on french Wikipedia Cryptologie dans Le Scarabée d'or — Wikipédia

1 Like