Hybrid Encryption Protocol Specification

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.

This document defines the protocol and format specifications for the MetaMUI Hybrid Encryption Library, which combines Kyber-768 KEM with symmetric ciphers.

Version

Protocol Version: 1.0
Document Version: 1.0
Date: 2024-06-23

1. Overview

1.1 Purpose

The Hybrid Encryption Protocol provides a standardized way to combine post-quantum key encapsulation mechanisms with classical symmetric encryption algorithms, ensuring both quantum resistance and performance.

1.2 Goals

1.3 Scope

This specification covers:

2. Cryptographic Foundations

2.1 Key Encapsulation Mechanism (KEM)

Algorithm: Kyber-768 (ML-KEM-768)

2.2 Key Derivation Function

Algorithm: HKDF-SHA256 (RFC 5869)

2.3 Symmetric Encryption Algorithms

2.3.1 AES-256-GCM

2.3.2 ARIA-256-GCM

2.3.3 ChaCha20-Poly1305

3. Protocol Operations

3.1 Key Generation

KeyPair ← GenerateKeyPair()

Input: None
Output: (PublicKey, PrivateKey)
  PublicKey: 1,184 bytes
  PrivateKey: 2,400 bytes

Process:
1. Generate Kyber-768 key pair using secure random number generator
2. Return (pk, sk) pair

3.2 Encryption Process

EncryptedData ← Encrypt(PublicKey, Plaintext, Algorithm, AAD?)

Input:
  PublicKey: 1,184 bytes
  Plaintext: Variable length
  Algorithm: One of {AES-256-GCM, ARIA-256-GCM, ChaCha20-Poly1305}
  AAD: Optional associated data

Output: EncryptedData (serialized format)

Process:
1. (EncapsulatedKey, SharedSecret) ← KEM.Encaps(PublicKey)
2. SymmetricKey ← HKDF(SharedSecret, Info, KeyLength)
3. Nonce ← RandomBytes(NonceLength)
4. Ciphertext ← SymmetricEncrypt(SymmetricKey, Nonce, Plaintext, AAD)
5. Metadata ← CreateMetadata(Algorithm, EncapsulatedKey, Nonce, AAD)
6. EncryptedData ← Serialize(Metadata, Ciphertext)
7. SecureClear(SharedSecret, SymmetricKey)
8. Return EncryptedData

3.3 Decryption Process

(Plaintext, Verified) ← Decrypt(PrivateKey, EncryptedData)

Input:
  PrivateKey: 2,400 bytes
  EncryptedData: Serialized encrypted data

Output: (Plaintext, Verified)
  Plaintext: Variable length
  Verified: Boolean

Process:
1. (Metadata, Ciphertext) ← Deserialize(EncryptedData)
2. SharedSecret ← KEM.Decaps(PrivateKey, Metadata.EncapsulatedKey)
3. SymmetricKey ← HKDF(SharedSecret, Info, KeyLength)
4. Try:
     Plaintext ← SymmetricDecrypt(SymmetricKey, Metadata.Nonce, Ciphertext, Metadata.AAD)
     Verified ← True
   Catch AuthenticationError:
     Plaintext ← Empty
     Verified ← False
5. SecureClear(SharedSecret, SymmetricKey)
6. Return (Plaintext, Verified)

4. Key Derivation Specification

4.1 Context Strings

Different operations use different context strings for key derivation:

4.2 HKDF Parameters

DerivedKey ← HKDF(SharedSecret, Info, Length)

Parameters:
- Hash Function: SHA-256
- Salt: 32 zero bytes (if not specified)
- Info: Context string as UTF-8 bytes
- Length: Required key length in bytes

Process:
1. PRK ← HMAC-SHA256(Salt, SharedSecret)
2. OKM ← HKDF-Expand(PRK, Info, Length)
3. Return OKM[0:Length]

5. Wire Format Specification

5.1 Overall Structure

HybridEncryptedData = Magic || Version || MetadataLength || Metadata || CiphertextLength || Ciphertext

Components:
- Magic: 4 bytes (0x48, 0x59, 0x42, 0x52) "HYBR"
- Version: 1 byte (0x01)
- MetadataLength: 4 bytes, big-endian uint32
- Metadata: Variable length JSON
- CiphertextLength: 8 bytes, big-endian uint64
- Ciphertext: Variable length encrypted data

5.2 Metadata Format

The metadata is JSON-encoded with the following structure:

{
  "version": 1,
  "scheme": {
    "name": "Kyber768-AES256-GCM",
    "kem_algorithm": "Kyber-768",
    "symmetric_algorithm": "AES-256-GCM"
  },
  "encapsulated_key": [/* array of bytes */],
  "nonce": [/* array of bytes */],
  "associated_data": [/* array of bytes or null */]
}

5.3 Field Descriptions

Magic Bytes

Version

Metadata Length

Metadata

Ciphertext Length

Ciphertext

6. Symmetric Algorithm Specifications

6.1 AES-256-GCM Mode

Ciphertext ← AES-GCM-Encrypt(Key, Nonce, Plaintext, AAD)

Parameters:
- Key: 32 bytes
- Nonce: 12 bytes
- Plaintext: Variable length
- AAD: Variable length (optional)

Output Format:
Ciphertext || AuthenticationTag

Where:
- Ciphertext: Same length as plaintext
- AuthenticationTag: 16 bytes

6.2 ARIA-256-GCM Mode

Ciphertext ← ARIA-GCM-Encrypt(Key, Nonce, Plaintext, AAD)

Parameters:
- Key: 32 bytes
- Nonce: 12 bytes
- Plaintext: Variable length
- AAD: Variable length (optional)

Output Format:
Ciphertext || AuthenticationTag

Where:
- Ciphertext: Same length as plaintext
- AuthenticationTag: 16 bytes

6.3 ChaCha20-Poly1305

Ciphertext ← ChaCha20-Poly1305-Encrypt(Key, Nonce, Plaintext, AAD)

Parameters:
- Key: 32 bytes
- Nonce: 12 bytes
- Plaintext: Variable length
- AAD: Variable length (optional)

Output Format:
Ciphertext || AuthenticationTag

Where:
- Ciphertext: Same length as plaintext
- AuthenticationTag: 16 bytes

7. Stream Processing Protocol

7.1 Stream Encryption

For large data streams, the protocol supports chunked processing:

EncryptedStream ← EncryptStream(PublicKey, PlaintextStream, Algorithm, AAD, ChunkSize)

Process:
1. Perform KEM encapsulation
2. Derive base encryption key
3. Generate base nonce
4. For each chunk i:
   a. ChunkNonce ← BaseNonce || i (as 4-byte big-endian)
   b. EncryptedChunk ← SymmetricEncrypt(Key, ChunkNonce, Chunk, AAD)
   c. Emit EncryptedChunk
5. Emit final metadata

7.2 Stream Decryption

PlaintextStream ← DecryptStream(PrivateKey, EncryptedStream, Metadata)

Process:
1. Extract metadata from stream header
2. Perform KEM decapsulation
3. Derive base encryption key
4. For each encrypted chunk i:
   a. ChunkNonce ← BaseNonce || i (as 4-byte big-endian)
   b. Chunk ← SymmetricDecrypt(Key, ChunkNonce, EncryptedChunk, AAD)
   c. Emit Chunk

8. Security Considerations

8.1 Nonce Generation

8.2 Key Clearing

8.3 Side-Channel Resistance

8.4 Quantum Resistance

9. Implementation Requirements

9.1 Mandatory Features

9.2 Optional Features

9.3 Error Handling

10. Test Vectors

10.1 Sample Keys

Public Key (hex):
[1184 bytes of sample public key data]

Private Key (hex):
[2400 bytes of sample private key data]

10.2 Sample Encryption

Input:
- Algorithm: AES-256-GCM
- Plaintext: "Hello, post-quantum world!"
- AAD: "test-context"

Expected Output:
[Complete wire format example with all fields]

10.3 Interoperability Tests

Test vectors are provided for:

11. Version History

Version 1.0 (2024-06-23)

12. References


Author: Phantom(phantom@metamui.id)
Specification Version: 1.0
Last Updated: 2024-06-23