Metadata-Version: 2.4
Name: stream-crypto-engine
Version: 0.1.1
Summary: Zero-disk in-memory streaming file encryption using Argon2id and AES-256-GCM
Author: Nwakamma Joseph
License: MIT
Project-URL: Homepage, https://github.com/Nwakamma/stream-crypto-engine
Keywords: cryptography,streaming,aes-gcm,argon2id,security,zero-disk
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Topic :: Security :: Cryptography
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: cryptography>=41.0.0
Requires-Dist: pynacl>=1.5.0
Requires-Dist: requests>=2.34.2
Requires-Dist: python-magic-bin>=0.4.14; platform_system == "Windows"
Requires-Dist: python-magic>=0.4.27; platform_system != "Windows"
Dynamic: license-file

# Stream Crypto Engine 🔐⚡

[![PyPI version](https://img.shields.io/pypi/v/stream-crypto-engine.svg?color=blue)](https://pypi.org/project/stream-crypto-engine/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python 3.9+](https://img.shields.io/badge/python-3.9+-brightgreen.svg)](https://www.python.org/downloads/)

> **Zero-disk, in-memory chunked streaming file encryption.** Designed to process multi-gigabyte payloads with high throughput, tight memory bounds (< 20 MB RAM), and authenticated payload integrity.

---

## 🌟 Why Stream Crypto Engine?

When working with large files (videos, database dumps, user media, backups) in serverless environments, cloud workers, or high-throughput backends, standard encryption libraries present two major headaches:

1. **Memory Bloat:** Reading an entire 2 GB file into RAM to encrypt or decrypt it leads to `OOM` (Out of Memory) crashes.
2. **Disk Overhead:** Spooling unencrypted temporary files to disk introduces I/O bottlenecks, leaves residual sensitive data in temporary directories, and degrades storage longevity.

`stream-crypto-engine` solves both problems. It converts Python byte streams into self-contained authenticated frames using **AES-256-GCM** and key derivation via **Argon2id**. Payload data is processed in fixed-size chunks—meaning RAM consumption remains low and constant regardless of whether you are encrypting a 5 KB image or a 50 GB video file.

---

## 🛡️ Security Architecture

| Security Property                 | Primitive / Implementation Parameters                                      |
| :-------------------------------- | :------------------------------------------------------------------------- |
| **Symmetric Encryption**          | AES-256-GCM (Authenticated Encryption with Associated Data)                |
| **Key Derivation Function (KDF)** | Argon2id (`length=32`, `memory_cost=65536` KiB, `lanes=2`, `iterations=1`) |
| **Tamper Detection**              | Sequential Chunk Nonce Counters + AEAD Authentication Tags                 |
| **MIME Type Inspection**          | In-Memory Magic-Byte Detection (Header Inspection)                         |
| **Memory Footprint**              | Bounded (~16–20 MB RSS peak) via generator-driven streams                  |

### KDF Parameter Mapping (Cryptography / RFC 9106)

- **`memory_cost=65536`**: Allocates 64 MiB RAM per derivation attempt to defeat GPU/ASIC brute-force cracking.
- **`lanes=2`**: Parallel execution threads (equivalent to `parallelism`).
- **`iterations=1`**: Execution passes over allocated memory (equivalent to `time_cost`).
- **`length=32`**: Generates a 256-bit symmetric AES key.

### Frame & Payload Structure

Each encrypted stream generated by `stream-crypto-engine` consists of a global metadata header followed by a sequence of independent, authenticated ciphertext chunks:

```text
+-------------------------------------------------------------------------------+
| FILE HEADER (Salt, Nonce Base, Magic Bytes / MIME Type Header)               |
+-------------------------------------------------------------------------------+
| CHUNK 0001 : [ Chunk Len | Ciphertext Payload | AEAD Tag (16 bytes) ]        |
+-------------------------------------------------------------------------------+
| CHUNK 0002 : [ Chunk Len | Ciphertext Payload | AEAD Tag (16 bytes) ]        |
+-------------------------------------------------------------------------------+
| ...                                                                           |
+-------------------------------------------------------------------------------+
| FINAL CHUNK: [ Chunk Len | Final Payload | Final AEAD Tag ]                   |
+-------------------------------------------------------------------------------+
```

## 📦 Installation

Install the package directly via `pip`:

```bash
pip install stream-crypto-engine
```

> **Note:** On Windows systems, `python-magic-bin` will be automatically selected as a dependency to support magic-byte MIME type detection.

---

## 🚀 Quick Start

### 1. In-Memory Stream Encryption & Decryption

```python
import io
from stream_crypto_engine import ZeroDiskFileCipher

# Initialize cipher with a strong passphrase
passphrase = "CorrectHorseBatteryStaple!2026"
cipher = ZeroDiskFileCipher(password=passphrase)

# Raw source data (e.g., an incoming file payload)
raw_data = b"Stream Crypto Engine: Secure, zero-disk, and memory-bounded."
source_stream = io.BytesIO(raw_data)
encrypted_stream = io.BytesIO()

# 1. Encrypt stream chunk-by-chunk
for chunk in cipher.encrypt_stream(source_stream):
    encrypted_stream.write(chunk)

# Reset buffer pointer for reading
encrypted_stream.seek(0)
decrypted_stream = io.BytesIO()

# 2. Decrypt stream back to original bytes
for decrypted_chunk in cipher.decrypt_stream(encrypted_stream):
    decrypted_stream.write(decrypted_chunk)

print("Decrypted payload matches:", decrypted_stream.getvalue() == raw_data)
```

### 2. File-to-File Streaming (Minimal RAM Usage)

For multi-gigabyte files, stream from a disk source directly to a destination output without loading the whole file into RAM:

```python
from stream_crypto_engine import ZeroDiskFileCipher

cipher = ZeroDiskFileCipher(password="ProductionSecretKey#99")

# Encrypting a large file
with open("large_video.mp4", "rb") as src, open("large_video.mp4.enc", "wb") as dst:
    for encrypted_frame in cipher.encrypt_stream(src):
        dst.write(encrypted_frame)

# Decrypting back
with open("large_video.mp4.enc", "rb") as enc_src, open("restored_video.mp4", "wb") as dst:
    for chunk in cipher.decrypt_stream(enc_src):
        dst.write(chunk)
```

---

## 🛠️ Advanced Usage & Integration

### Working with Cloud Storage (AWS S3, Cloudflare R2)

Because `encrypt_stream()` and `decrypt_stream()` are Python generators, you can easily interface with cloud upload/download streams:

```python
import io
import boto3
from stream_crypto_engine import ZeroDiskFileCipher

s3 = boto3.client("s3")
cipher = ZeroDiskFileCipher(password="CloudStoragePassword!")

# Generator wrapper for streaming encryption
def encrypted_generator(file_path):
    with open(file_path, "rb") as f:
        yield from cipher.encrypt_stream(f)

# Upload stream directly without creating local temporary encrypted files
s3.upload_fileobj(
    Fileobj=io.BytesIO(b"".join(encrypted_generator("database_dump.sql"))),
    Bucket="my-secure-backups",
    Key="database_dump.sql.enc",
)
```

> **Tip:** For large files, prefer `s3.upload_fileobj` with a file-like wrapper or multipart uploads instead of `b"".join(...)` to keep memory usage bounded.

---

## 🧪 Running Tests

To run the test suite locally across various stream sizes and edge cases:

1. **Clone the repository:**

   ```bash
   git clone https://github.com/Nwakamma/stream-crypto-engine.git
   cd stream-crypto-engine
   ```

2. **Set up a virtual environment and install dependencies:**

   ```bash
   python -m venv .venv
   source .venv/bin/activate  # On Windows: .venv\Scripts\Activate.ps1
   pip install -e .[dev]
   ```

3. **Run `pytest`:**

   ```bash
   pytest tests/
   ```

---

## 🤝 Contributing

Contributions, bug reports, and security feedback are welcome!

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'feat: update argon2 parameters'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

---

## 📄 License

Distributed under the **MIT License**. See [`LICENSE`](LICENSE) for more information.

Developed and maintained by **Nwakamma Joseph**.
