A custom SPN cipher implementation
Project description
CipherX
A Python implementation of a custom Substitution-Permutation Network (SPN) cipher with multiple modes of operation.
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
-
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)
- Use
-
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
-
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
-
Production Use:
- This is a custom cipher without extensive cryptanalysis
- For critical applications, prefer established libraries:
- cryptography (AES-GCM)
- PyCryptodome
- NaCl/libsodium
API Reference
Encryption Functions
encrypt(data: bytes, key: bytes) -> bytes
Encrypts data using ECB mode.
Parameters:
data(bytes): Plaintext to encryptkey(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 decryptkey(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 encryptkey(bytes): 32-byte encryption keyiv(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 decryptkey(bytes): 32-byte encryption keyiv(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 encryptkey(bytes): 32-byte encryption keynonce(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 decryptkey(bytes): 32-byte encryption keynonce(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
- SubBytes: Uses standard AES S-box for non-linear substitution
- Permutation: Custom 16-byte permutation for diffusion
- MixColumns: Galois Field GF(2^8) matrix multiplication
- Key Schedule: SHA-256-based round key derivation
- 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:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- 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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1d48c016c660c1ab4fed03daa67a3dcd92127e907ecf744ef6081e0298d331db
|
|
| MD5 |
cd5ea00482a7e0ff0ca67e34050f7305
|
|
| BLAKE2b-256 |
a377dcc3ed3402fb4a79f386ade9a30d64b0c09f319facc9ada73909a9dae25e
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
926352d2f8cb1bc2b98c9e42fe449f02cf2e5989ba494dd5202360e7d7f02115
|
|
| MD5 |
c4867bb101619dba8d7d3b61c4ffee95
|
|
| BLAKE2b-256 |
e0f26e17d16063cea9bd953260b24da28d3f1bc0843bfcf58cad109ad780c02e
|