{"_id":"@abdo30004/cryptiq","_rev":"3-4f675bbc9fc42c440f8939f8b5cdb4f1","name":"@abdo30004/cryptiq","dist-tags":{"latest":"1.0.3"},"versions":{"1.0.0":{"name":"@abdo30004/cryptiq","version":"1.0.0","keywords":["napi-rs","NAPI","N-API","Rust","node-addon","node-addon-api"],"license":"MIT","_id":"@abdo30004/cryptiq@1.0.0","maintainers":[{"name":"abdo30004","email":"kasepop2017@gmail.com"}],"homepage":"https://github.com/napi-rs/package-template#readme","bugs":{"url":"https://github.com/napi-rs/package-template/issues"},"ava":{"timeout":"2m","extensions":{"ts":"module"},"nodeArguments":["--import","@oxc-node/core/register"],"workerThreads":false,"environmentVariables":{"OXC_TSCONFIG_PATH":"./__test__/tsconfig.json"}},"dist":{"shasum":"56ebafd1aa46cd589acd95a61993139ac12c29f6","tarball":"https://registry.npmjs.org/@abdo30004/cryptiq/-/cryptiq-1.0.0.tgz","fileCount":7,"integrity":"sha512-0t3anDdrDwKeMqxR4fhNPSYtFLCECZxX0WkgrlQCbCi5prIrwD9R526Ew6zK6i5rlQ7wMBttGaU3MqHNdIqzCw==","signatures":[{"sig":"MEUCIDcgriQUc9l6IE5nsEf91lomaulCkJrXcR4Z7CgWvSPiAiEAjmGozbm6b3LPEJjfwIHYyvEQLzikgv3MG/8RzuYNmto=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":84430},"main":"lib.js","napi":{"targets":["x86_64-pc-windows-msvc","x86_64-apple-darwin","x86_64-unknown-linux-gnu","aarch64-apple-darwin"],"binaryName":"cryptiq"},"types":"lib.d.ts","browser":"browser.js","engines":{"node":">= 12.22.0 < 13 || >= 14.17.0 < 15 || >= 15.12.0 < 16 || >= 16.0.0"},"gitHead":"6c2d2e94674a891ed0662f39ff2b9451b1aa065d","scripts":{"lint":"oxlint .","test":"ava","bench":"node --import @oxc-node/core/register benchmark/bench.ts","build":"napi build --platform --release","format":"run-p format:prettier format:rs format:toml","prepare":"husky","version":"napi version","artifacts":"napi artifacts","format:rs":"cargo fmt","preversion":"napi build --platform && git add .","build:debug":"napi build --platform","format:toml":"taplo format","prepublishOnly":"napi prepublish -t npm","format:prettier":"prettier . -w"},"_npmUser":{"name":"abdo30004","email":"kasepop2017@gmail.com"},"prettier":{"semi":false,"printWidth":120,"arrowParens":"always","singleQuote":true,"trailingComma":"all"},"repository":{"url":"git+ssh://git@github.com/napi-rs/package-template.git","type":"git"},"_npmVersion":"11.7.0","description":"Template project for writing node package with napi-rs","directories":{},"lint-staged":{"*.toml":["taplo format"],"*.@(js|ts|tsx)":["oxlint --fix"],"*.@(js|ts|tsx|yml|yaml|md|json)":["prettier --write"]},"_nodeVersion":"22.13.1","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"packageManager":"yarn@4.12.0","devDependencies":{"ava":"^7.0.0","chalk":"^5.6.2","husky":"^9.1.7","oxlint":"^1.14.0","prettier":"^3.6.2","tinybench":"^6.0.0","@taplo/cli":"^0.7.0","typescript":"^5.9.2","lint-staged":"^16.1.6","@emnapi/core":"^1.5.0","@napi-rs/cli":"^3.2.0","npm-run-all2":"^8.0.4","@oxc-node/core":"^0.0.35","@emnapi/runtime":"^1.5.0","@tybys/wasm-util":"^0.10.0"},"optionalDependencies":{"@abdo30004/cryptiq-darwin-x64":"1.0.0","@abdo30004/cryptiq-darwin-arm64":"1.0.0","@abdo30004/cryptiq-linux-x64-gnu":"1.0.0","@abdo30004/cryptiq-win32-x64-msvc":"1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/cryptiq_1.0.0_1773010323611_0.7480207748829526","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@abdo30004/cryptiq","version":"1.0.1","keywords":["crypto","encryption","hashing","aes","chacha20","blake3","argon2","napi-rs","rust","native"],"license":"MIT","_id":"@abdo30004/cryptiq@1.0.1","maintainers":[{"name":"abdo30004","email":"kasepop2017@gmail.com"}],"homepage":"https://github.com/Abdo30004/cryptiq#readme","bugs":{"url":"https://github.com/Abdo30004/cryptiq/issues"},"ava":{"timeout":"2m","extensions":{"ts":"module"},"nodeArguments":["--import","@oxc-node/core/register"],"workerThreads":false,"environmentVariables":{"OXC_TSCONFIG_PATH":"./__test__/tsconfig.json"}},"dist":{"shasum":"54e49fd6a3915d0761cf4444d52dc7ea5bc0fe5b","tarball":"https://registry.npmjs.org/@abdo30004/cryptiq/-/cryptiq-1.0.1.tgz","fileCount":7,"integrity":"sha512-Lut+yYqJmgCM/4pyr+1sUkNh7++0OOyJFgdFh23uLYpJrFvHVxbJSCQ5xn9ofpurqdKwAMDfOZcBen6AP91Spw==","signatures":[{"sig":"MEQCIEQi1DqMg8obnhjRaEi5SxGi8FINHY8JW5aOD/EJi+GLAiB5yuFXMuxzv2iqnpQfPKZJIzAvNfd9KfZQHTQJna3IAg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":84425},"main":"lib.js","napi":{"targets":["x86_64-pc-windows-msvc","x86_64-apple-darwin","x86_64-unknown-linux-gnu","aarch64-apple-darwin"],"binaryName":"cryptiq"},"types":"lib.d.ts","engines":{"node":">= 12.22.0 < 13 || >= 14.17.0 < 15 || >= 15.12.0 < 16 || >= 16.0.0"},"gitHead":"6c2d2e94674a891ed0662f39ff2b9451b1aa065d","scripts":{"lint":"oxlint .","test":"ava","bench":"node --import @oxc-node/core/register benchmark/bench.ts","build":"napi build --platform --release","format":"run-p format:prettier format:rs format:toml","prepare":"husky","version":"napi version","artifacts":"napi artifacts","format:rs":"cargo fmt","preversion":"napi build --platform && git add .","build:debug":"napi build --platform","format:toml":"taplo format","prepublishOnly":"napi prepublish -t npm","format:prettier":"prettier . -w"},"_npmUser":{"name":"abdo30004","email":"kasepop2017@gmail.com"},"prettier":{"semi":false,"printWidth":120,"arrowParens":"always","singleQuote":true,"trailingComma":"all"},"repository":{"url":"git+ssh://git@github.com/Abdo30004/cryptiq.git","type":"git"},"_npmVersion":"11.7.0","description":"High-performance native cryptography library for Node.js — AES-256-GCM, ChaCha20-Poly1305, AES-256-CTR, SHA-256/512, BLAKE3, Argon2, with sync, async, and streaming APIs","directories":{},"lint-staged":{"*.toml":["taplo format"],"*.@(js|ts|tsx)":["oxlint --fix"],"*.@(js|ts|tsx|yml|yaml|md|json)":["prettier --write"]},"_nodeVersion":"22.13.1","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"packageManager":"yarn@4.12.0","devDependencies":{"ava":"^7.0.0","husky":"^9.1.7","oxlint":"^1.14.0","prettier":"^3.6.2","tinybench":"^6.0.0","@taplo/cli":"^0.7.0","typescript":"^5.9.2","lint-staged":"^16.1.6","@napi-rs/cli":"^3.2.0","npm-run-all2":"^8.0.4","@oxc-node/core":"^0.0.35"},"optionalDependencies":{"@abdo30004/cryptiq-darwin-x64":"1.0.1","@abdo30004/cryptiq-darwin-arm64":"1.0.1","@abdo30004/cryptiq-linux-x64-gnu":"1.0.1","@abdo30004/cryptiq-win32-x64-msvc":"1.0.1"},"_npmOperationalInternal":{"tmp":"tmp/cryptiq_1.0.1_1773011650671_0.9587255396584407","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@abdo30004/cryptiq","version":"1.0.3","description":"High-performance native cryptography library for Node.js — AES-256-GCM, ChaCha20-Poly1305, AES-256-CTR, SHA-256/512, BLAKE3, Argon2, with sync, async, and streaming APIs","main":"lib.js","types":"lib.d.ts","repository":{"type":"git","url":"git+ssh://git@github.com/Abdo30004/cryptiq.git"},"license":"MIT","keywords":["crypto","encryption","hashing","aes","chacha20","blake3","argon2","napi-rs","rust","native"],"napi":{"binaryName":"cryptiq","targets":["x86_64-pc-windows-msvc","x86_64-apple-darwin","x86_64-unknown-linux-gnu","aarch64-apple-darwin"]},"engines":{"node":">= 12.22.0 < 13 || >= 14.17.0 < 15 || >= 15.12.0 < 16 || >= 16.0.0"},"publishConfig":{"registry":"https://registry.npmjs.org/","access":"public"},"scripts":{"artifacts":"napi artifacts","bench":"node --import @oxc-node/core/register benchmark/bench.ts","build":"napi build --platform --release","build:debug":"napi build --platform","format":"run-p format:prettier format:rs format:toml","format:prettier":"prettier . -w","format:toml":"taplo format","format:rs":"cargo fmt","lint":"oxlint .","test":"ava","preversion":"napi build --platform && git add .","version":"napi version","prepare":"husky"},"devDependencies":{"@napi-rs/cli":"^3.2.0","@oxc-node/core":"^0.0.35","@taplo/cli":"^0.7.0","ava":"^7.0.0","husky":"^9.1.7","lint-staged":"^16.1.6","npm-run-all2":"^8.0.4","oxlint":"^1.14.0","prettier":"^3.6.2","tinybench":"^6.0.0","typescript":"^5.9.2"},"lint-staged":{"*.@(js|ts|tsx)":["oxlint --fix"],"*.@(js|ts|tsx|yml|yaml|md|json)":["prettier --write"],"*.toml":["taplo format"]},"ava":{"extensions":{"ts":"module"},"timeout":"2m","workerThreads":false,"environmentVariables":{"OXC_TSCONFIG_PATH":"./__test__/tsconfig.json"},"nodeArguments":["--import","@oxc-node/core/register"]},"prettier":{"printWidth":120,"semi":false,"trailingComma":"all","singleQuote":true,"arrowParens":"always"},"packageManager":"yarn@4.12.0","gitHead":"db1c8c6b408c18ffd59354f50f04056fab39f6a6","_id":"@abdo30004/cryptiq@1.0.3","bugs":{"url":"https://github.com/Abdo30004/cryptiq/issues"},"homepage":"https://github.com/Abdo30004/cryptiq#readme","_nodeVersion":"22.13.1","_npmVersion":"11.7.0","dist":{"integrity":"sha512-HGJzzI4YA2ic++lxgya2d4edkKLhJOnKUgbjNiMDBeWY07GN78GNylqF8Fn928L+MytKXOajWp8zSXE3MNE6ag==","shasum":"90840a727c316afffd870be6b3a71a20d0636761","tarball":"https://registry.npmjs.org/@abdo30004/cryptiq/-/cryptiq-1.0.3.tgz","fileCount":7,"unpackedSize":87932,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCi4f+zC1yHy8FrGeS5ZYPy/ZN30407tK++IjrSP7+DWQIgHILUSvJePJJH/RJuqm6LYdy9f27AMuTqKMO7c4qUXkY="}]},"_npmUser":{"name":"abdo30004","email":"kasepop2017@gmail.com"},"directories":{},"maintainers":[{"name":"abdo30004","email":"kasepop2017@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/cryptiq_1.0.3_1773015221113_0.32099211946702777"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-08T22:52:03.531Z","modified":"2026-03-09T00:13:41.376Z","1.0.0":"2026-03-08T22:52:03.763Z","1.0.1":"2026-03-08T23:14:10.806Z","1.0.3":"2026-03-09T00:13:41.269Z"},"bugs":{"url":"https://github.com/Abdo30004/cryptiq/issues"},"license":"MIT","homepage":"https://github.com/Abdo30004/cryptiq#readme","keywords":["crypto","encryption","hashing","aes","chacha20","blake3","argon2","napi-rs","rust","native"],"repository":{"type":"git","url":"git+ssh://git@github.com/Abdo30004/cryptiq.git"},"description":"High-performance native cryptography library for Node.js — AES-256-GCM, ChaCha20-Poly1305, AES-256-CTR, SHA-256/512, BLAKE3, Argon2, with sync, async, and streaming APIs","maintainers":[{"name":"abdo30004","email":"kasepop2017@gmail.com"}],"readme":"# Cryptiq\n\n[![npm version](https://img.shields.io/npm/v/@abdo30004/cryptiq.svg)](https://www.npmjs.com/package/@abdo30004/cryptiq)\n[![npm downloads](https://img.shields.io/npm/dm/@abdo30004/cryptiq.svg)](https://www.npmjs.com/package/@abdo30004/cryptiq)\n[![license](https://img.shields.io/npm/l/@abdo30004/cryptiq.svg)](https://github.com/Abdo30004/cryptiq/blob/main/LICENSE)\n[![CI](https://github.com/Abdo30004/cryptiq/actions/workflows/CI.yml/badge.svg)](https://github.com/Abdo30004/cryptiq/actions/workflows/CI.yml)\n\nHigh-performance native cryptography library for Node.js, powered by Rust via [NAPI-RS](https://napi.rs).\n\n## Features\n\n- **Hashing** — SHA-256, SHA-512, BLAKE3, MD5 (legacy), Argon2id\n- **Streaming Hashing** — Process large files chunk by chunk without loading them into memory\n- **AES-256-GCM** — Authenticated encryption with automatic nonce management\n- **ChaCha20-Poly1305** — Authenticated encryption (software-optimized alternative to AES-GCM)\n- **AES-256-CTR** — Stream cipher encryption (no authentication — use with external HMAC)\n- **Streaming Encryption** — Encrypt/decrypt large files chunk by chunk over gRPC streams (all 3 algorithms)\n- **Async variants** — Every function has an async counterpart that runs on the libuv thread pool (non-blocking)\n- **BLAKE3 Rayon parallelism** — Async BLAKE3 hashing uses Rayon for multi-core parallel computation\n- **Key Derivation** — Argon2id password-based key derivation (OWASP recommended parameters)\n- **Secure Random** — Cryptographically secure random bytes, keys, nonces, IVs, and salts\n\n## Installation\n\n```bash\nnpm install @abdo30004/cryptiq\n# or\nyarn add @abdo30004/cryptiq\n```\n\nPrebuilt native binaries are provided for Windows (x64), macOS (x64 & ARM64), and Linux (x64). No Rust toolchain required for consumers.\n\n## Quick Start\n\n```typescript\nimport { aesGcm, chacha, aesCtr, hash, utils } from '@abdo30004/cryptiq'\n\n// --- Hashing ---\nconst digest = hash.sha256(Buffer.from('hello world'))\nconst blake = hash.blake3(Buffer.from('hello world'))\n\n// Async hashing (non-blocking)\nconst asyncDigest = await hash.sha256Async(Buffer.from('hello world'))\nconst asyncBlake = await hash.blake3Async(Buffer.from('large data...')) // uses Rayon multi-threading\n\n// --- Password hashing ---\nconst phc = hash.argon2('my-password')\nconst valid = hash.verifyArgon2('my-password', phc)\n\n// Async (non-blocking — ideal for servers)\nconst phcAsync = await hash.argon2Async('my-password')\nconst validAsync = await hash.verifyArgon2Async('my-password', phcAsync)\n\n// --- Encryption ---\nconst key = utils.generateKey() // 32 random bytes\n\n// AES-256-GCM (sync)\nconst encrypted = aesGcm.encrypt(Buffer.from('secret data'), key)\nconst decrypted = aesGcm.decrypt(encrypted, key)\n\n// AES-256-GCM (async — runs on libuv thread pool)\nconst encryptedAsync = await aesGcm.encryptAsync(Buffer.from('secret data'), key)\nconst decryptedAsync = await aesGcm.decryptAsync(encryptedAsync, key)\n\n// ChaCha20-Poly1305\nconst chachaEnc = chacha.encrypt(Buffer.from('secret'), key)\nconst chachaDec = chacha.decrypt(chachaEnc, key)\n\n// AES-256-CTR (no authentication!)\nconst ctrEnc = aesCtr.encrypt(Buffer.from('secret'), key)\nconst ctrDec = aesCtr.decrypt(ctrEnc, key)\n\n// --- Key derivation ---\nconst { key: derivedKey, salt } = utils.deriveKey('user-password')\nconst { key: sameKey } = utils.deriveKey('user-password', salt)\n\n// Async key derivation\nconst { key: asyncKey, salt: asyncSalt } = await utils.deriveKeyAsync('user-password')\n```\n\n---\n\n## Namespaced API\n\nAll functions are organized into five namespaces:\n\n| Namespace | Contents                                                               |\n| --------- | ---------------------------------------------------------------------- |\n| `aesGcm`  | AES-256-GCM encrypt/decrypt (sync, async, streaming)                   |\n| `chacha`  | ChaCha20-Poly1305 encrypt/decrypt (sync, async, streaming)             |\n| `aesCtr`  | AES-256-CTR encrypt/decrypt (sync, async, streaming)                   |\n| `hash`    | SHA-256, SHA-512, BLAKE3, MD5, Argon2 (sync, async, streaming hashers) |\n| `utils`   | Key generation, nonce/IV/salt generation, key derivation               |\n\n```typescript\n// Named imports\nimport { aesGcm, chacha, aesCtr, hash, utils } from '@abdo30004/cryptiq'\n\n// Default import\nimport cryptiq from '@abdo30004/cryptiq'\ncryptiq.aesGcm.encrypt(data, key)\n```\n\n---\n\n## API Reference\n\n### Hashing — `hash`\n\n#### Sync\n\n| Method                              | Returns                               |\n| ----------------------------------- | ------------------------------------- |\n| `hash.sha256(data: Buffer)`         | `string` — 64-char hex                |\n| `hash.sha512(data: Buffer)`         | `string` — 128-char hex               |\n| `hash.blake3(data: Buffer)`         | `string` — 64-char hex                |\n| `hash.md5(data: Buffer)`            | `string` — 32-char hex ⚠️ legacy only |\n| `hash.argon2(password, salt?)`      | `string` — PHC format                 |\n| `hash.verifyArgon2(password, hash)` | `boolean`                             |\n\n#### Async\n\nAll async variants run on the libuv thread pool and return a `Promise`. BLAKE3 async uses Rayon for multi-core parallelism.\n\n| Method                                   | Returns                            |\n| ---------------------------------------- | ---------------------------------- |\n| `hash.sha256Async(data)`                 | `Promise<string>`                  |\n| `hash.sha512Async(data)`                 | `Promise<string>`                  |\n| `hash.blake3Async(data)`                 | `Promise<string>` — Rayon parallel |\n| `hash.md5Async(data)`                    | `Promise<string>`                  |\n| `hash.argon2Async(password, salt?)`      | `Promise<string>`                  |\n| `hash.verifyArgon2Async(password, hash)` | `Promise<boolean>`                 |\n\n#### Streaming Hashers\n\nProcess large files chunk by chunk. Available classes: `hash.Sha256Hasher`, `hash.Sha512Hasher`, `hash.Blake3Hasher`, `hash.Md5Hasher`.\n\n| Method                        | Description                                        |\n| ----------------------------- | -------------------------------------------------- |\n| `constructor()`               | Creates a new hasher instance                      |\n| `update(chunk: Buffer): void` | Feeds a chunk of data                              |\n| `digest(): string`            | Finalizes and returns hex hash (auto-resets)       |\n| `digestBytes(): Buffer`       | Finalizes and returns raw hash bytes (auto-resets) |\n| `reset(): void`               | Discards state and resets                          |\n\n```typescript\nimport { createReadStream } from 'fs'\nimport { hash } from '@abdo30004/cryptiq'\n\nconst hasher = new hash.Sha256Hasher()\nconst stream = createReadStream('/path/to/large-file', { highWaterMark: 65536 })\n\nfor await (const chunk of stream) {\n  hasher.update(chunk)\n}\n\nconst fileHash = hasher.digest()\n```\n\n---\n\n### Encryption Algorithms\n\nThree algorithms, all sharing a 32-byte key:\n\n| Algorithm             | Auth    | Overhead/msg       | Best For                                   |\n| --------------------- | ------- | ------------------ | ------------------------------------------ |\n| **AES-256-GCM**       | ✅ AEAD | 28 B (nonce + tag) | Hardware-accelerated environments (AES-NI) |\n| **ChaCha20-Poly1305** | ✅ AEAD | 28 B (nonce + tag) | Software-only environments, mobile, ARM    |\n| **AES-256-CTR**       | ❌ None | 16 B (IV)          | When external HMAC is applied separately   |\n\n> **Recommendation:** Use **AES-256-GCM** or **ChaCha20-Poly1305** unless you specifically need unauthenticated encryption with external integrity verification.\n\n---\n\n### AES-256-GCM — `aesGcm`\n\nOutput format: `nonce (12 bytes) || ciphertext || auth tag (16 bytes)`\n\n| Method                                                 | Returns           |\n| ------------------------------------------------------ | ----------------- |\n| `aesGcm.encrypt(plaintext, key)`                       | `Buffer`          |\n| `aesGcm.decrypt(ciphertext, key)`                      | `Buffer`          |\n| `aesGcm.encryptWithNonce(plaintext, key, nonce)`       | `Buffer`          |\n| `aesGcm.decryptWithNonce(ciphertext, key, nonce)`      | `Buffer`          |\n| `aesGcm.encryptAsync(plaintext, key)`                  | `Promise<Buffer>` |\n| `aesGcm.decryptAsync(ciphertext, key)`                 | `Promise<Buffer>` |\n| `aesGcm.encryptWithNonceAsync(plaintext, key, nonce)`  | `Promise<Buffer>` |\n| `aesGcm.decryptWithNonceAsync(ciphertext, key, nonce)` | `Promise<Buffer>` |\n| `new aesGcm.StreamEncryptor(key)`                      | Stream encryptor  |\n| `new aesGcm.StreamDecryptor(key)`                      | Stream decryptor  |\n\n```typescript\nconst key = utils.generateKey()\nconst encrypted = aesGcm.encrypt(Buffer.from('secret'), key)\nconst decrypted = aesGcm.decrypt(encrypted, key)\n\n// Async (non-blocking)\nconst enc = await aesGcm.encryptAsync(Buffer.from('secret'), key)\nconst dec = await aesGcm.decryptAsync(enc, key)\n```\n\n---\n\n### ChaCha20-Poly1305 — `chacha`\n\nOutput format: `nonce (12 bytes) || ciphertext || auth tag (16 bytes)`\n\n| Method                                                | Returns           |\n| ----------------------------------------------------- | ----------------- |\n| `chacha.encrypt(data, key)`                           | `Buffer`          |\n| `chacha.decrypt(encrypted, key)`                      | `Buffer`          |\n| `chacha.encryptWithNonce(data, key, nonce)`           | `Buffer`          |\n| `chacha.decryptWithNonce(encrypted, key, nonce)`      | `Buffer`          |\n| `chacha.encryptAsync(data, key)`                      | `Promise<Buffer>` |\n| `chacha.decryptAsync(encrypted, key)`                 | `Promise<Buffer>` |\n| `chacha.encryptWithNonceAsync(data, key, nonce)`      | `Promise<Buffer>` |\n| `chacha.decryptWithNonceAsync(encrypted, key, nonce)` | `Promise<Buffer>` |\n| `new chacha.StreamEncryptor(key)`                     | Stream encryptor  |\n| `new chacha.StreamDecryptor(key)`                     | Stream decryptor  |\n\n---\n\n### AES-256-CTR — `aesCtr`\n\n⚠️ **No authentication.** Ciphertext can be modified without detection.\n\nOutput format: `iv (16 bytes) || ciphertext`\n\n| Method                                          | Returns           |\n| ----------------------------------------------- | ----------------- |\n| `aesCtr.encrypt(data, key)`                     | `Buffer`          |\n| `aesCtr.decrypt(encrypted, key)`                | `Buffer`          |\n| `aesCtr.encryptWithIv(data, key, iv)`           | `Buffer`          |\n| `aesCtr.decryptWithIv(encrypted, key, iv)`      | `Buffer`          |\n| `aesCtr.encryptAsync(data, key)`                | `Promise<Buffer>` |\n| `aesCtr.decryptAsync(encrypted, key)`           | `Promise<Buffer>` |\n| `aesCtr.encryptWithIvAsync(data, key, iv)`      | `Promise<Buffer>` |\n| `aesCtr.decryptWithIvAsync(encrypted, key, iv)` | `Promise<Buffer>` |\n| `new aesCtr.StreamEncryptor(key)`               | Stream encryptor  |\n| `new aesCtr.StreamDecryptor(key)`               | Stream decryptor  |\n\n---\n\n### Streaming Encryption\n\nDesigned for gRPC bidirectional streaming of large files. Each chunk is independently encrypted with counter-based nonces.\n\nAll streaming classes share the same API:\n\n```typescript\n// Encrypt\nconst encryptor = new aesGcm.StreamEncryptor(key) // 32-byte Buffer\nconst encrypted = encryptor.encryptChunk(chunk) // Buffer in, Buffer out\nencryptor.getChunkIndex() // number of chunks processed\n\n// Decrypt\nconst decryptor = new aesGcm.StreamDecryptor(key)\nconst plaintext = decryptor.decryptChunk(encryptedChunk)\ndecryptor.getChunkIndex()\n```\n\n**Properties:**\n\n- Counter-based nonces/IVs (deterministic — no nonce reuse risk)\n- Each output chunk is self-contained\n- Supports up to 2³² chunks per stream (~281 TB at 64KB chunks)\n- Authenticated streams (GCM/Poly1305) verify nonce sequence — detect reordering/replay\n\n---\n\n### Utilities — `utils`\n\n| Method                                  | Returns               | Description                         |\n| --------------------------------------- | --------------------- | ----------------------------------- |\n| `utils.generateKey()`                   | `Buffer` (32 bytes)   | Random encryption key               |\n| `utils.generateNonce()`                 | `Buffer` (12 bytes)   | Random nonce for AES-GCM / ChaCha20 |\n| `utils.generateIv()`                    | `Buffer` (16 bytes)   | Random IV for AES-CTR               |\n| `utils.generateSalt()`                  | `Buffer` (16 bytes)   | Random salt for Argon2              |\n| `utils.secureRandomBytes(n)`            | `Buffer` (n bytes)    | General-purpose random bytes        |\n| `utils.deriveKey(password, salt?)`      | `DerivedKey`          | Argon2id key derivation             |\n| `utils.deriveKeyAsync(password, salt?)` | `Promise<DerivedKey>` | Async key derivation                |\n\n```typescript\ninterface DerivedKey {\n  key: Buffer // 32-byte derived key\n  salt: Buffer // 16-byte salt (store alongside encrypted data)\n}\n```\n\n---\n\n## Async & Parallelism\n\nEvery sync function has an async counterpart (suffixed with `Async`) that offloads work to the libuv thread pool, keeping the Node.js event loop free.\n\n| Feature                         | Implementation                                        |\n| ------------------------------- | ----------------------------------------------------- |\n| **Async encryption/decryption** | napi-rs `AsyncTask` on libuv worker threads           |\n| **Async hashing**               | napi-rs `AsyncTask` on libuv worker threads           |\n| **BLAKE3 async**                | Rayon multi-threaded parallelism via `update_rayon()` |\n| **Async Argon2**                | Offloaded to worker thread — ideal for login flows    |\n\n```typescript\n// Non-blocking encryption in an Express/NestJS handler\napp.post('/encrypt', async (req, res) => {\n  const encrypted = await aesGcm.encryptAsync(req.body.data, key)\n  res.send(encrypted)\n})\n\n// Parallel operations with Promise.all\nconst [enc1, enc2, enc3, enc4] = await Promise.all([\n  aesGcm.encryptAsync(chunk1, key),\n  aesGcm.encryptAsync(chunk2, key),\n  aesGcm.encryptAsync(chunk3, key),\n  aesGcm.encryptAsync(chunk4, key),\n])\n```\n\n---\n\n## NestJS gRPC Streaming Example\n\n### Proto Definition\n\n```protobuf\nservice FileTransfer {\n  rpc Upload(stream FileChunk) returns (UploadResponse);\n  rpc Download(DownloadRequest) returns (stream FileChunk);\n}\n\nmessage FileChunk {\n  bytes data = 1;   // encrypted chunk\n  uint32 index = 2; // chunk sequence number\n}\n```\n\n### Upload (Client → Server)\n\n```typescript\nimport { createReadStream } from 'fs'\nimport { aesGcm, hash, utils } from '@abdo30004/cryptiq'\n\nasync function uploadFile(client: FileTransferClient, filePath: string) {\n  const key = utils.generateKey()\n  const encryptor = new aesGcm.StreamEncryptor(key)\n  const hasher = new hash.Sha256Hasher()\n\n  const stream = createReadStream(filePath, { highWaterMark: 65536 })\n  const call = client.upload()\n\n  for await (const chunk of stream) {\n    hasher.update(chunk)\n    const encrypted = encryptor.encryptChunk(chunk)\n    call.write({ data: encrypted, index: encryptor.getChunkIndex() - 1 })\n  }\n\n  call.end()\n  const fileHash = hasher.digest()\n  console.log(`Uploaded ${encryptor.getChunkIndex()} chunks, hash: ${fileHash}`)\n}\n```\n\n### Download (Server → Client)\n\n```typescript\nimport { createWriteStream } from 'fs'\nimport { aesGcm, hash } from '@abdo30004/cryptiq'\n\nasync function downloadFile(client: FileTransferClient, fileId: string, key: Buffer, outputPath: string) {\n  const decryptor = new aesGcm.StreamDecryptor(key)\n  const hasher = new hash.Sha256Hasher()\n  const writeStream = createWriteStream(outputPath)\n\n  const call = client.download({ fileId })\n\n  for await (const message of call) {\n    const plaintext = decryptor.decryptChunk(message.data)\n    hasher.update(plaintext)\n    writeStream.write(plaintext)\n  }\n\n  writeStream.end()\n  const fileHash = hasher.digest()\n  console.log(`Downloaded ${decryptor.getChunkIndex()} chunks, hash: ${fileHash}`)\n}\n```\n\n---\n\n## Chunk Wire Formats\n\n### AES-256-GCM / ChaCha20-Poly1305\n\n```\n┌──────────────┬────────────────────────┬──────────────────┐\n│  Nonce (12B) │  Ciphertext (variable) │  Auth Tag (16B)  │\n└──────────────┴────────────────────────┴──────────────────┘\n```\n\nOverhead: 28 bytes per chunk (0.04% at 64KB chunks).\n\n### AES-256-CTR\n\n```\n┌────────────┬────────────────────────┐\n│  IV (16B)  │  Ciphertext (variable) │\n└────────────┴────────────────────────┘\n```\n\nOverhead: 16 bytes per chunk. **No authentication tag.**\n\n---\n\n## Security Notes\n\n| Topic                 | Detail                                                                                                    |\n| --------------------- | --------------------------------------------------------------------------------------------------------- |\n| **AES-256-GCM**       | NIST-approved AEAD. Confidentiality + integrity. Hardware-accelerated via AES-NI.                         |\n| **ChaCha20-Poly1305** | IETF RFC 8439 AEAD. Constant-time in software. Preferred when AES-NI is unavailable.                      |\n| **AES-256-CTR**       | ⚠️ No authentication. Ciphertext is malleable. Use only with external HMAC.                               |\n| **Counter nonces**    | Streaming uses deterministic counter nonces — no nonce reuse risk. Max 2³² chunks per key.                |\n| **Argon2id**          | OWASP-recommended password hashing. Resistant to GPU + side-channel attacks. 19 MiB memory, 2 iterations. |\n| **MD5**               | ⚠️ Cryptographically broken. Legacy checksum compatibility only.                                          |\n| **Random generation** | OS CSPRNG (`OsRng`) — cryptographically secure on all platforms.                                          |\n| **Memory safety**     | Written in Rust — no buffer overflows, use-after-free, or data races.                                     |\n\n---\n\n## Build from Source\n\n```bash\nyarn install        # Install dependencies\nyarn build          # Build release binary\nyarn test           # Run test suite (75 tests)\nyarn bench          # Run benchmarks\nyarn lint           # Run linter\ncargo fmt -- --check  # Check Rust formatting\n```\n\n## Supported Platforms\n\n| Platform | Architecture          | Package                             |\n| -------- | --------------------- | ----------------------------------- |\n| Windows  | x64                   | `@abdo30004/cryptiq-win32-x64-msvc` |\n| macOS    | x64                   | `@abdo30004/cryptiq-darwin-x64`     |\n| macOS    | ARM64 (Apple Silicon) | `@abdo30004/cryptiq-darwin-arm64`   |\n| Linux    | x64 (glibc)           | `@abdo30004/cryptiq-linux-x64-gnu`  |\n\n## License\n\nMIT\n","readmeFilename":"README.md"}