# Post-Quantum Hybrid Kyber-1024 + AES-256-CTR File Encryption Streaming hybrid file encryption: ML-KEM-1024 (Kyber-1024) handles post-quantum key exchange, AES-256-CTR handles bulk file encryption, and HMAC-SHA256 provides integrity verification. The file signature is `KYB`, and the file extension is ".kyb". Simplified flow (Kyber + AES-256 only, HKDF and HMAC omitted for clarity): ## Features - Post-quantum secure key exchange via liboqs Kyber-1024 KEM (~256-bit PQ security) - AES-256-CTR symmetric encryption with a streaming architecture that handles files larger than RAM (64 MB chunks) - AES + HMAC keys derived from the Kyber shared secret via HKDF-SHA256 (never stored in the file) - Unforgeable HMAC-SHA256 authenticity tag over the header + ciphertext to detect tampering or corruption - Self-describing ASCII header (file signature `KYB`, version, algorithm names and lengths), so each file identifies its own format and unsupported future versions are rejected cleanly ## Requirements - `oqs` ([liboqs-python](https://github.com/open-quantum-safe/liboqs-python)) - `cryptography` ([pyca/cryptography](https://github.com/pyca/cryptography)) ```bash python3 -m venv venv && . venv/bin/activate pip install -r requirements.txt ``` ## Usage 1. Generate a Kyber-1024 key pair ```bash python3 gen_kyber.py ``` Produces: - `kyber.pub` - public key (1568 bytes) - `kyber.sec` - secret key (3168 bytes) 2. Encrypt a file ```bash python3 encrypt.py archive.7z ``` Output: `archive.7z.kyb` The `.kyb` file is self-contained: a human-readable header line at the start describes the exact format, algorithms, and lengths. See [File formats](#file-formats) for the layout. 3. Decrypt a file ```bash python3 decrypt.py archive.7z.kyb ``` Output: `archive.7z` The script automatically verifies the HMAC tag. If the file has been tampered with, you'll see: ``` Error: Integrity check failed. File corrupted or tampered ``` and the temp file is discarded. No plaintext ever appears at the destination path until the tag has been verified. ## File formats **Key files (raw binary)** File|Content|Size (bytes) -|-|- `kyber.pub`|Kyber-1024 public key|1568 `kyber.sec`|Kyber-1024 secret key|3168 **Header fields** Field | Meaning | Value (v1) -|-|- |`KYB`|File signature that identifies a Kyber-encrypted file|`KYB` `VER`|File-format version; decrypt refuses unsupported versions|`1` `KEM`|Post-quantum key-encapsulation algorithm|`MLKEM1024` `CIPHER`|Bulk symmetric cipher|`AES256CTR` `MAC`|Integrity algorithm|`HMACSHA256` `KYBERCT`|Kyber ciphertext length in bytes|`1568` `IV`|AES-CTR nonce / HKDF salt length in bytes|`16` `TAG`|MAC tag length in bytes|`32` **Encrypted file structure** `archive.7z.kyb`: Section | Size | Description -|-|- ASCII header line|82 bytes (v1)|Self-describing format line terminated by a newline, e.g. `KYB\|VER=1\|KEM=MLKEM1024\|CIPHER=AES256CTR\|MAC=HMACSHA256\|KYBERCT=1568\|IV=16\|TAG=32` Kyber ciphertext|1568 bytes|Encapsulated key (ciphertext from ML-KEM-1024); length read from the header IV (nonce)|16 bytes|AES-CTR nonce, also the HKDF salt; length read from the header File ciphertext|same as plaintext|AES-256-CTR encrypted chunks, streamed in 64 MB blocks HMAC-SHA256 tag|32 bytes|MAC over the header line + Kyber CT + IV + all ciphertext; length read from the header ## Security notes - A fresh 32-byte **Kyber shared secret** is generated **per file** by `encap_secret()` and recovered only with `kyber.sec` via `decap_secret()`. It is the root key material: neither the AES key nor the Kyber private key. - The AES and HMAC keys are **derived from that Kyber shared secret** with HKDF-SHA256 (domain-separated `info` labels), so no key material is ever stored in the file. - Because the HMAC key is only derivable by the legitimate recipient (Kyber decapsulation), the tag is **unforgeable**: an attacker without the secret key cannot modify the file undetectably. - The HMAC tag is computed over the **ASCII header line + Kyber CT + IV + AES ciphertext**, so any tampering with the encrypted data, the nonce, or the format header is detected before decryption. - Decrypted plaintext is written to a temporary file and atomically renamed into place **only after** the HMAC verifies. - The header carries a format **version**; decrypt checks it up front, so a file written by a newer (or unknown) format is refused with a clear error instead of being mis-parsed. - Kyber-1024 is believed to offer security equivalent to ~256-bit classical keys against quantum attackers. - The secret key file (`kyber.sec`) is the single point of failure. Losing it means losing every encrypted file. Treat it like a private SSH key: keep it offline, back it up, and restrict access (e.g. `chmod 600`). For stronger protection, consider encrypting the key file with a passphrase or splitting it into pieces (XOR-splitting or Shamir secret sharing) across separate locations.