Skip to main content

A custom SPN cipher implementation

Project description

CipherX

A Python implementation of a custom Substitution-Permutation Network (SPN) cipher with multiple modes of operation.

License: MIT Python Version

Overview

CipherX implements a block cipher based on the Substitution-Permutation Network (SPN) architecture, inspired by AES design principles. It features:

  • Block size: 128 bits (16 bytes)
  • Key size: 256 bits (32 bytes)
  • Rounds: 10
  • Modes: ECB, CBC, CTR
  • Components: AES S-box, custom permutation layer, GF(2^8) MixColumns

Installation

Install via pip:

pip install cipherx

Or install from source:

git clone https://github.com/metisos/cipherx.git
cd cipherx
pip install -e .

Quick Start

Basic Encryption/Decryption (CBC Mode - Recommended)

from cipher import encrypt_cbc, decrypt_cbc
import os

# Generate a random 256-bit key
key = os.urandom(32)

# Your message
message = b"Hello, CipherX!"

# Encrypt (IV is automatically generated)
ciphertext, iv = encrypt_cbc(message, key)

# Decrypt
plaintext = decrypt_cbc(ciphertext, key, iv)

assert plaintext == message

ECB Mode (Simple, but less secure)

from cipher import encrypt, decrypt

key = b'supersecretkeythatis32byteslong!'
message = b"Hello, World!"

ciphertext = encrypt(message, key)
plaintext = decrypt(ciphertext, key)

CTR Mode (Streaming)

from cipher import encrypt_ctr, decrypt_ctr
import os

key = os.urandom(32)
nonce = os.urandom(8)

message = b"Stream this data!"

ciphertext = encrypt_ctr(message, key, nonce)
plaintext = decrypt_ctr(ciphertext, key, nonce)

Security Considerations

Mode Selection

CBC Mode (Recommended): Use encrypt_cbc() / decrypt_cbc() for most applications

  • Provides semantic security with random IVs
  • Hides patterns in plaintext
  • Suitable for encrypting files, messages, etc.

CTR Mode: Use encrypt_ctr() / decrypt_ctr() for streaming data

  • Turns block cipher into stream cipher
  • Can encrypt/decrypt in parallel
  • Suitable for large files, network streams

ECB Mode (Not Recommended): Avoid encrypt() / decrypt() in production

  • Deterministic - same plaintext always produces same ciphertext
  • Reveals patterns in data
  • Only suitable for random data (e.g., encrypting random keys)

Important Security Notes

  1. Key Management:

    • Use os.urandom(32) to generate cryptographically secure random keys
    • Never hardcode keys in source code
    • Store keys securely (HSM, key management service, encrypted storage)
  2. IV/Nonce Handling:

    • CBC: IV is automatically generated - store it with ciphertext
    • CTR: Use unique nonce for each encryption with same key
    • Never reuse IV/nonce with the same key
  3. Authentication:

    • CipherX provides encryption only, not authentication
    • For integrity protection, use HMAC:
    import hmac
    import hashlib
    
    # Encrypt-then-MAC pattern
    ciphertext, iv = encrypt_cbc(plaintext, encryption_key)
    mac = hmac.new(mac_key, iv + ciphertext, hashlib.sha256).digest()
    # Store: iv + ciphertext + mac
    
  4. Production Use:

API Reference

Encryption Functions

encrypt(data: bytes, key: bytes) -> bytes

Encrypts data using ECB mode.

Parameters:

  • data (bytes): Plaintext to encrypt
  • key (bytes): 32-byte encryption key

Returns: Ciphertext (bytes)

Note: ECB mode is not recommended for production use.


decrypt(ciphertext: bytes, key: bytes) -> bytes

Decrypts data encrypted with ECB mode.

Parameters:

  • ciphertext (bytes): Data to decrypt
  • key (bytes): 32-byte encryption key

Returns: Plaintext (bytes)


encrypt_cbc(data: bytes, key: bytes, iv: bytes = None) -> tuple[bytes, bytes]

Encrypts data using CBC mode (recommended).

Parameters:

  • data (bytes): Plaintext to encrypt
  • key (bytes): 32-byte encryption key
  • iv (bytes, optional): 16-byte initialization vector (auto-generated if None)

Returns: Tuple of (ciphertext, iv)

Example:

ciphertext, iv = encrypt_cbc(b"Secret message", key)
# Store both ciphertext and iv

decrypt_cbc(ciphertext: bytes, key: bytes, iv: bytes) -> bytes

Decrypts data encrypted with CBC mode.

Parameters:

  • ciphertext (bytes): Data to decrypt
  • key (bytes): 32-byte encryption key
  • iv (bytes): 16-byte initialization vector from encryption

Returns: Plaintext (bytes)


encrypt_ctr(data: bytes, key: bytes, nonce: bytes) -> bytes

Encrypts data using CTR mode (stream cipher mode).

Parameters:

  • data (bytes): Plaintext to encrypt
  • key (bytes): 32-byte encryption key
  • nonce (bytes): 8-byte nonce (must be unique per encryption)

Returns: Ciphertext (bytes)

Warning: Never reuse the same nonce with the same key!


decrypt_ctr(ciphertext: bytes, key: bytes, nonce: bytes) -> bytes

Decrypts data encrypted with CTR mode.

Parameters:

  • ciphertext (bytes): Data to decrypt
  • key (bytes): 32-byte encryption key
  • nonce (bytes): 8-byte nonce from encryption

Returns: Plaintext (bytes)


Utility Functions

pad_data(data: bytes) -> bytes

Applies PKCS#7 padding to data.

unpad_data(data: bytes) -> bytes

Removes PKCS#7 padding from data.

Technical Details

Cipher Structure

CipherX implements a 10-round Substitution-Permutation Network:

Input Block (128 bits)
    |
    v
Initial AddRoundKey
    |
    v
[For each Round 1-10:]
  - SubBytes       (AES S-box)
  - Permutation    (Custom byte rearrangement)
  - MixColumns     (GF(2^8) operations, skipped in round 10)
  - AddRoundKey    (XOR with round key + constant)
    |
    v
Output Block (128 bits)

Cryptographic Components

  1. SubBytes: Uses standard AES S-box for non-linear substitution
  2. Permutation: Custom 16-byte permutation for diffusion
  3. MixColumns: Galois Field GF(2^8) matrix multiplication
  4. Key Schedule: SHA-256-based round key derivation
  5. Round Constants: SHA-256-derived constants per round

Performance

Approximate throughput on modern hardware:

  • ECB mode: ~5-10 MB/s (Python implementation)
  • CBC mode: ~5-10 MB/s (sequential)
  • CTR mode: ~5-10 MB/s (parallelizable in theory)

For better performance, consider:

  • Using PyPy instead of CPython
  • Implementing performance-critical paths in Cython
  • Using established C-based libraries (OpenSSL, libsodium)

Development

Running Tests

python test_cipherx.py

Project Structure

cipherx/
 cipher/
    __init__.py      # Public API exports
    core.py          # Core cipher implementation
 test_cipherx.py      # Test suite
 setup.py             # Package configuration
 README.md            # This file
 License              # MIT License

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure all tests pass
  5. Submit a pull request

License

This project is licensed under the MIT License - see the License file for details.

Disclaimer

This cipher implementation is provided for educational and experimental purposes. While it uses sound cryptographic principles, it has not undergone extensive cryptanalysis or formal security audits. For production systems handling sensitive data, use well-established cryptographic libraries that have been thoroughly vetted by the security community.

Author

Christian Johnson (cjohnson@metisos.com)

Repository

https://github.com/metisos/cipherx

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cipherx-1.1.0.tar.gz (12.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cipherx-1.1.0-py3-none-any.whl (10.2 kB view details)

Uploaded Python 3

File details

Details for the file cipherx-1.1.0.tar.gz.

File metadata

  • Download URL: cipherx-1.1.0.tar.gz
  • Upload date:
  • Size: 12.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for cipherx-1.1.0.tar.gz
Algorithm Hash digest
SHA256 1d48c016c660c1ab4fed03daa67a3dcd92127e907ecf744ef6081e0298d331db
MD5 cd5ea00482a7e0ff0ca67e34050f7305
BLAKE2b-256 a377dcc3ed3402fb4a79f386ade9a30d64b0c09f319facc9ada73909a9dae25e

See more details on using hashes here.

File details

Details for the file cipherx-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: cipherx-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for cipherx-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 926352d2f8cb1bc2b98c9e42fe449f02cf2e5989ba494dd5202360e7d7f02115
MD5 c4867bb101619dba8d7d3b61c4ffee95
BLAKE2b-256 e0f26e17d16063cea9bd953260b24da28d3f1bc0843bfcf58cad109ad780c02e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page