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

ChaCha20

High-Speed Stream Cipher

ChaCha20-Poly1305

Authenticated Encryption

ARIA-256

Korean Standard Cipher

Camellia-256

Japanese Standard Cipher

Deoxys-II

CAESAR Competition Winner

Algorithm Selection Guide

For New Applications

Recommended: ChaCha20-Poly1305

For Compatibility

Use: AES-256-GCM

For Specific Regions

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

Nonce/IV Usage

Authenticated Encryption

Implementation Security

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:

Resources