kyb/README.md
2026-08-06 20:31:30 +00:00

110 lines
5 KiB
Markdown

# 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):
<a href="https://notes.juyung.com/gallery/6nIr0qID0vri0DR4Jy7HCbS6/hJv-1N1hIqFxzXIv85KqR9dq" target="_blank"><img src='https://notes.juyung.com/uploads/small2x/f9/20/0805d761b05dbbf2046a68268b58.png' style="height: 720px;" /></a>
## 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.