Ir al contenido

Hybrid KEM-DEM

AegisQ implementa una arquitectura Hybrid KEM-DEM. ML-KEM no puede cifrar payloads grandes directamente — solo produce un shared secret de 32 bytes. AegisQ lo combina con AES-256-GCM como mecanismo de encapsulación de datos (DEM).

  1. ML-KEM (KEM): Genera un shared secret de 32 bytes, resistente a quantum
  2. AES-256-GCM (DEM): Usa ese secret de 32 bytes como clave simétrica para cifrar el payload real con cifrado autenticado (confidencialidad + integridad)
PropiedadValor
Tamaño de clave256 bits (32 bytes) — del shared secret de ML-KEM
Nonce (IV)96 bits (12 bytes) — aleatorio por operación vía OsRng
Authentication Tag128 bits (16 bytes)
SeguridadIND-CPA + INT-CTXT (cifrado autenticado)

Una vez que ML-KEM genera el shared secret K de 32 bytes, AegisQ lo alimenta directamente a AES-256-GCM como clave de cifrado simétrico. No se necesita un KDF adicional — la salida de 32 bytes de ML-KEM ya es uniformemente aleatoria y del tamaño correcto para AES-256.

El módulo hybrid.rs en aegisq-core es responsable de ensamblar y parsear el Transit Package.

El array de bytes final encrypted_package tiene esta estructura fija:

[ ML-KEM Capsule (var) | AES Nonce (12 bytes) | AES Auth Tag (16 bytes) | Ciphertext (var) ]

Donde el tamaño de ML-KEM Capsule depende del nivel de seguridad:

  • ML-KEM-512: 768 bytes
  • ML-KEM-768: 1088 bytes
  • ML-KEM-1024: 1568 bytes
  1. Llamar kem::encapsulate(public_key, level) → resultado con capsule y shared secret
  2. Generar nonce aleatorio de 12 bytes vía OsRng
  3. Llamar aes_gcm::encrypt(key=shared_secret, nonce, plaintext) → (tag, ciphertext)
  4. Zeroizar shared_secret inmediatamente
  5. Ensamblar y retornar: capsule || nonce || tag || ciphertext
  1. Dividir el Transit Package por offsets conocidos (capsule_size, luego 12, 16, resto)
  2. Llamar kem::decapsulate(capsule, secret_key, level) → shared_secret_32B
  3. Llamar aes_gcm::decrypt(key=shared_secret, nonce, tag, ciphertext) → plaintext o Err
  4. Zeroizar shared_secret inmediatamente
  5. Si la verificación del tag falla → retornar Err(AegisQError::DecryptionFailed)
EscenarioML-KEM DecapsAES-GCM Decrypt
Contenido inválido, tamaño de capsule correctoRetorna K pseudoaleatoriaSe espera que falle la verificación del tag
Tamaño incorrecto de clave/capsule o paquete demasiado cortoError estructural (InvalidParameterError)No se alcanza
Capsule correcta, clave AES incorrectaN/A (la clave se deriva de la capsule)Error: DecryptionError
Auth tag no coincide (payload manipulado)N/AError: DecryptionError
Todo correctoRetorna shared secretRetorna plaintext
use aegisq_core::{hybrid, kem::SecurityLevel};
// Hybrid encrypt: ML-KEM encaps + AES-256-GCM
let encrypted_package: Vec<u8> = hybrid::encrypt(
recipient_public_key,
plaintext,
SecurityLevel::MlKem768,
)?;
// Hybrid decrypt: ML-KEM decaps + AES-256-GCM verify + decrypt
let plaintext: Vec<u8> = hybrid::decrypt(
&encrypted_package,
secret_key,
SecurityLevel::MlKem768,
)?;