Symmetric Encryption
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
- Resistant to timing attacks
- 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
- All implementations are constant-time
- Protected against cache-timing attacks
- 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