Symmetric Encryption
Side-channel claim limit. Nothing on this page claims constant-time behaviour or side-channel resistance for any target: the side-channel harness covers nothing (finding A48) and no measurement exists. The Rust and C cores are designed for constant time and unmeasured; managed runtimes (JIT, GC, bounds checks) make no timing claim. Where this page names constant-time or side-channel techniques, in prose or in code, they are design intent or recommendations, not measured properties.
Symmetric encryption algorithms use the same key for both encryption and decryption. MetaMUI provides both block ciphers and stream ciphers with authenticated encryption modes.
Available Algorithms
AES-256
Advanced Encryption Standard
- Security Level: 256-bit
- Block Size: 128 bits
- Key Size: 256 bits
- Modes: ECB, CBC, CTR, GCM
- Detailed Documentation
ChaCha20
High-Speed Stream Cipher
- Security Level: 256-bit
- Key Size: 256 bits
- Nonce: 96 bits
- Counter: 32 bits
- Detailed Documentation
ChaCha20-Poly1305
Authenticated Encryption
- Security Level: 256-bit
- Key Size: 256 bits
- Nonce: 96 bits
- Tag: 128 bits
- Detailed Documentation
ARIA-256
Korean Standard Cipher
- Security Level: 256-bit
- Block Size: 128 bits
- Key Size: 256 bits
- Modes: ECB, CBC, CTR, GCM
- Detailed Documentation
Camellia-256
Japanese Standard Cipher
- Security Level: 256-bit
- Block Size: 128 bits
- Key Size: 256 bits
- Modes: ECB, CBC, CTR, GCM
- Detailed Documentation
Deoxys-II
CAESAR Competition Winner
- Security Level: 128-bit
- Key Size: 128 bits
- Nonce: 128 bits
- Authenticated encryption
- Detailed Documentation
Algorithm Selection Guide
For New Applications
Recommended: ChaCha20-Poly1305
- Fast on all platforms
- Built-in authentication
- Constant-time behaviour and side-channel resistance: not claimed — unmeasured for every target (A48)
- No hardware requirements
For Compatibility
Use: AES-256-GCM
- Universal hardware support
- FIPS approved
- Widely implemented
- Industry standard
For Specific Regions
- Korea: ARIA-256
- Japan: Camellia-256
- International: AES-256
Usage Examples
Authenticated Encryption (ChaCha20-Poly1305)
from metamui_crypto import ChaCha20Poly1305
import os
# Generate random key
key = os.urandom(32) # 256 bits
# Create cipher
cipher = ChaCha20Poly1305(key)
# Encrypt with authentication
plaintext = b"Secret message"
nonce = os.urandom(12) # 96 bits
ciphertext, tag = cipher.encrypt(plaintext, nonce)
# Decrypt and verify
decrypted = cipher.decrypt(ciphertext, tag, nonce)
assert decrypted == plaintext
AES-256-GCM with Associated Data
from metamui_crypto import AES256GCM
import os
# Setup
key = os.urandom(32)
cipher = AES256GCM(key)
# Encrypt with associated data
plaintext = b"Credit card number"
associated_data = b"user_id=12345"
nonce = os.urandom(12)
ciphertext, tag = cipher.encrypt(
plaintext,
nonce,
associated_data=associated_data
)
# Decrypt (must provide same associated data)
decrypted = cipher.decrypt(
ciphertext,
tag,
nonce,
associated_data=associated_data
)
Stream Encryption (ChaCha20)
from metamui_crypto import ChaCha20
import os
# Setup stream cipher
key = os.urandom(32)
nonce = os.urandom(12)
cipher = ChaCha20(key, nonce)
# Encrypt streaming data
chunk1 = b"First part of data"
chunk2 = b"Second part of data"
encrypted1 = cipher.encrypt(chunk1)
encrypted2 = cipher.encrypt(chunk2)
# Decrypt (must use same key/nonce and order)
decipher = ChaCha20(key, nonce)
decrypted1 = decipher.decrypt(encrypted1)
decrypted2 = decipher.decrypt(encrypted2)
Block Cipher Modes (AES-256)
from metamui_crypto import AES256
import os
key = os.urandom(32)
# ECB mode (not recommended)
cipher_ecb = AES256.new(key, AES256.MODE_ECB)
# CBC mode with IV
iv = os.urandom(16)
cipher_cbc = AES256.new(key, AES256.MODE_CBC, iv)
# CTR mode (converts to stream cipher)
nonce = os.urandom(8)
cipher_ctr = AES256.new(key, AES256.MODE_CTR, nonce=nonce)
# GCM mode (authenticated)
cipher_gcm = AES256.new(key, AES256.MODE_GCM)
Security Considerations
Key Management
- Use cryptographically secure random generators
- Never reuse keys across different contexts
- Implement proper key rotation
- Store keys in secure key management systems
Nonce/IV Usage
- Never reuse nonces with the same key
- Use random nonces for each encryption
- ChaCha20: 96-bit nonces recommended
- AES-GCM: 96-bit nonces for best security
Authenticated Encryption
- Always use authenticated modes (GCM, Poly1305)
- Verify authentication tags before using data
- Include relevant context in associated data
- Don’t use ECB mode
Implementation Security
- Constant-time behaviour and side-channel resistance: not claimed — unmeasured for every target (A48)
- Constant-time behaviour and side-channel resistance: not claimed — unmeasured for every target (A48)
- Secure memory clearing after use
- No data-dependent branching
Performance Comparison
| Algorithm | Encrypt (MB/s) | Decrypt (MB/s) | Hardware Accelerated |
|---|---|---|---|
| ChaCha20-Poly1305 | 2,500 | 2,500 | No |
| AES-256-GCM | 3,500* | 3,500* | Yes |
| AES-256-CTR | 3,800* | 3,800* | Yes |
| ARIA-256-GCM | 800 | 800 | No |
| Camellia-256-GCM | 900 | 900 | No |
| Deoxys-II | 1,200 | 1,200 | No |
*With AES-NI hardware support
Best Practices
1. Choose Authenticated Encryption
# Good: Authenticated encryption
cipher = ChaCha20Poly1305(key)
ciphertext, tag = cipher.encrypt(data, nonce)
# Bad: Encryption without authentication
# cipher = AES256.new(key, AES256.MODE_CBC, iv)
# ciphertext = cipher.encrypt(data) # No integrity protection!
2. Handle Nonces Properly
import os
from metamui_crypto import ChaCha20Poly1305
# Good: Random nonce for each encryption
def encrypt_message(key, plaintext):
cipher = ChaCha20Poly1305(key)
nonce = os.urandom(12) # Fresh nonce
ciphertext, tag = cipher.encrypt(plaintext, nonce)
return nonce + ciphertext + tag # Include nonce with ciphertext
# Bad: Reusing nonces
# nonce = b'0' * 12 # Never do this!
3. Secure Key Derivation
from metamui_crypto import HKDF, ChaCha20Poly1305
import os
# Derive separate keys for different purposes
master_key = os.urandom(32)
salt = os.urandom(32)
# Derive encryption key
encryption_key = HKDF(
master_key,
salt=salt,
info=b"encryption",
length=32
)
# Derive MAC key (if needed separately)
mac_key = HKDF(
master_key,
salt=salt,
info=b"mac",
length=32
)
Migration Guide
From Older Algorithms
# Old: 3DES or Blowfish
# cipher = DES3.new(key, DES3.MODE_CBC, iv)
# New: Modern authenticated encryption
from metamui_crypto import ChaCha20Poly1305
cipher = ChaCha20Poly1305(key)
ciphertext, tag = cipher.encrypt(plaintext, nonce)
From Unauthenticated Modes
# Old: AES-CBC without MAC
# cipher = AES.new(key, AES.MODE_CBC, iv)
# ciphertext = cipher.encrypt(pad(plaintext))
# New: AES-GCM with built-in authentication
from metamui_crypto import AES256GCM
cipher = AES256GCM(key)
ciphertext, tag = cipher.encrypt(plaintext, nonce)
Quantum Resistance
Current symmetric algorithms provide partial quantum resistance:
| Algorithm | Classical Security | Post-Quantum Security |
|---|---|---|
| AES-256 | 256 bits | 128 bits |
| ChaCha20 | 256 bits | 128 bits |
| ARIA-256 | 256 bits | 128 bits |
| Camellia-256 | 256 bits | 128 bits |
For full post-quantum security, consider:
- Using larger keys (512-bit)
- Combining with post-quantum key exchange
- Following NIST post-quantum guidelines