{"_id":"@bencmbrook/aes_gcm_stream","_rev":"3-d629d9e620b80e16c6a7251703a29de0","name":"@bencmbrook/aes_gcm_stream","dist-tags":{"latest":"0.2.0","alpha":"0.1.0-alpha.2"},"versions":{"0.1.0-alpha.1":{"name":"@bencmbrook/aes_gcm_stream","version":"0.1.0-alpha.1","keywords":["aes","gcm","streaming","webassembly","wasm","web-streams","encryption","crypto"],"author":{"name":"Ben Brook"},"license":"MIT","_id":"@bencmbrook/aes_gcm_stream@0.1.0-alpha.1","maintainers":[{"name":"bencmbrook","email":"ben@transcend.io"}],"dist":{"shasum":"af4cbbddae7b47d5705e956c1e0c7a173931b871","tarball":"https://registry.npmjs.org/@bencmbrook/aes_gcm_stream/-/aes_gcm_stream-0.1.0-alpha.1.tgz","fileCount":9,"integrity":"sha512-g78R1q8jW7wkfURE38Tkf09EUmOX1tWibgkhmbJth4P9MCmxyPA/Be06GwsnRHsF2HsaxOR12eVN9u9zIV978Q==","signatures":[{"sig":"MEUCIFSyIbgPaE1VvcHX47096fT4jxgztvzefsEVuTviLe0mAiEAjWJYAI4ZL66TgoZB+RJDDUehRA6qv5++eEbygdMyvyc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":72543},"main":"./dist/index.js","type":"module","_from":"file:bencmbrook-aes_gcm_stream-0.1.0-alpha.1.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./stream":{"types":"./dist/stream.d.ts","import":"./dist/stream.js"}},"private":false,"scripts":{"lint":"pnpm run --parallel --aggregate-output \"/^lint:*/\"","test":"npm run test:rust && npm run test:js","build":"npm run build:rust && npm run build:js","clean":"rm -rf pkg/ target/ dist/ rust/target/","format":"prettier --write .","test:js":"web-test-runner --node-resolve","build:js":"tsc --project tsconfig.json","test:rust":"cd rust && wasm-pack test --node","build:rust":"cd rust && wasm-pack build --target web --out-dir ../pkg && rm ../pkg/.gitignore","lint:types":"tsc --noEmit","lint:eslint":"eslint .","lint:prettier":"prettier --check . --log-level warn","lint:test-types":"tsc --noEmit --project test/tsconfig.json"},"_npmUser":{"name":"bencmbrook","email":"ben@transcend.io"},"_resolved":"/private/var/folders/05/qv2ng4vd2mz0gxblp8c96ykw0000gn/T/9ffcd2665a69469548ccfc3fc9a4addc/bencmbrook-aes_gcm_stream-0.1.0-alpha.1.tgz","_integrity":"sha512-g78R1q8jW7wkfURE38Tkf09EUmOX1tWibgkhmbJth4P9MCmxyPA/Be06GwsnRHsF2HsaxOR12eVN9u9zIV978Q==","_npmVersion":"10.9.2","description":"WebAssembly-powered streaming AES-256-GCM implementation","directories":{},"_nodeVersion":"22.15.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.3","eslint":"^9.32.0","prettier":"^3.6.2","@eslint/js":"^9.32.0","typescript":"^5.8.3","@types/node":"^22.x","@esm-bundle/chai":"4.3.4-fix.0","@tsconfig/node22":"^22.0.2","@web/test-runner":"^0.20.2","typescript-eslint":"^8.38.0","@tsconfig/strictest":"^2.0.5","eslint-plugin-unicorn":"^60.0.0","@web/dev-server-esbuild":"^1.0.4"},"_npmOperationalInternal":{"tmp":"tmp/aes_gcm_stream_0.1.0-alpha.1_1753845936263_0.075157323953563","host":"s3://npm-registry-packages-npm-production"}},"0.1.0-alpha.2":{"name":"@bencmbrook/aes_gcm_stream","version":"0.1.0-alpha.2","keywords":["aes","gcm","streaming","webassembly","wasm","web-streams","encryption","crypto"],"author":{"name":"Ben Brook"},"license":"MIT","_id":"@bencmbrook/aes_gcm_stream@0.1.0-alpha.2","maintainers":[{"name":"bencmbrook","email":"ben@transcend.io"}],"dist":{"shasum":"6994864e50b4854026c68df45d9dd38293bb5a48","tarball":"https://registry.npmjs.org/@bencmbrook/aes_gcm_stream/-/aes_gcm_stream-0.1.0-alpha.2.tgz","fileCount":9,"integrity":"sha512-v8E52oG1bhqOLskGPxcjKWNLr3H/vTy4C86GL2tB4sCAvHk4sg2MsdH0BJmNCrfuT2eqdPjU1RJEwnzYfKtckw==","signatures":[{"sig":"MEUCIF7lnsj5WVc3xj0yWgaYTSoVuC6XJuDALEYyu5iswyo+AiEA7mGP7youDNXLHEJ6zgXEuikjI5eY8IlPx1lvHrS3YIs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":72812},"main":"./dist/index.js","type":"module","_from":"file:bencmbrook-aes_gcm_stream-0.1.0-alpha.2.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./stream":{"types":"./dist/stream.d.ts","import":"./dist/stream.js"}},"private":false,"scripts":{"lint":"pnpm run --parallel --aggregate-output \"/^lint:*/\"","test":"npm run test:rust && npm run test:js","build":"npm run build:rust && npm run build:js","clean":"rm -rf pkg/ target/ dist/ rust/target/","format":"prettier --write .","test:js":"web-test-runner --node-resolve --playwright --browsers chromium firefox webkit --files test/**/*.test.ts --files !test/speed.test.ts","build:js":"tsc --project tsconfig.json","benchmark":"web-test-runner --node-resolve --playwright --browsers chromium firefox webkit --files test/speed.test.ts","test:rust":"cd rust && wasm-pack test --node","build:rust":"cd rust && wasm-pack build --target web --out-dir ../pkg && rm ../pkg/.gitignore","lint:types":"tsc --noEmit","lint:eslint":"eslint .","lint:prettier":"prettier --check . --log-level warn","lint:test-types":"tsc --noEmit --project test/tsconfig.json"},"_npmUser":{"name":"bencmbrook","email":"ben@transcend.io"},"_resolved":"/private/var/folders/05/qv2ng4vd2mz0gxblp8c96ykw0000gn/T/39617de7dc6571549956c94f67ed2b8f/bencmbrook-aes_gcm_stream-0.1.0-alpha.2.tgz","_integrity":"sha512-v8E52oG1bhqOLskGPxcjKWNLr3H/vTy4C86GL2tB4sCAvHk4sg2MsdH0BJmNCrfuT2eqdPjU1RJEwnzYfKtckw==","_npmVersion":"10.9.2","description":"WebAssembly-powered streaming AES-256-GCM implementation","directories":{},"_nodeVersion":"22.15.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tsx":"^4.20.3","eslint":"^9.32.0","prettier":"^3.6.2","tinybench":"^4.0.1","@eslint/js":"^9.32.0","typescript":"^5.8.3","@esm-bundle/chai":"4.3.4-fix.0","@tsconfig/node22":"^22.0.2","@web/test-runner":"^0.20.2","typescript-eslint":"^8.38.0","@tsconfig/strictest":"^2.0.5","eslint-plugin-unicorn":"^60.0.0","@web/dev-server-esbuild":"^1.0.4","@web/test-runner-playwright":"^0.11.1"},"_npmOperationalInternal":{"tmp":"tmp/aes_gcm_stream_0.1.0-alpha.2_1753852793090_0.20601085982318046","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@bencmbrook/aes_gcm_stream","version":"0.2.0","private":false,"description":"WebAssembly-powered streaming AES-256-GCM implementation","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"},"./stream":{"import":"./dist/stream.js","types":"./dist/stream.d.ts"}},"keywords":["aes","gcm","streaming","webassembly","wasm","web-streams","encryption","crypto"],"author":{"name":"Ben Brook"},"license":"MIT","publishConfig":{"access":"public"},"devDependencies":{"@eslint/js":"^9.32.0","@esm-bundle/chai":"4.3.4-fix.0","@tsconfig/node22":"^22.0.2","@tsconfig/strictest":"^2.0.5","@types/node":"22.x","@web/dev-server-esbuild":"^1.0.4","@web/test-runner":"^0.20.2","@web/test-runner-playwright":"^0.11.1","eslint":"^9.32.0","eslint-plugin-unicorn":"^60.0.0","hash-wasm":"^4.12.0","http-server":"^14.1.1","mime":"^4.0.7","prettier":"^3.6.2","pretty-bytes":"^7.0.0","pretty-ms":"^9.2.0","tinybench":"^4.0.1","tsx":"^4.20.3","typescript":"^5.8.3","typescript-eslint":"^8.38.0","wasm-pack":"^0.13.1"},"scripts":{"build":"npm run build:rust && npm run build:js","build:rust":"cd rust && wasm-pack build --target web --out-dir ../wasm && rm ../wasm/.gitignore","build:js":"tsc --project tsconfig.json","test:rust":"pnpm build && pnpm run test:rust:ci","test:js":"pnpm build && pnpm run test:js:ci","test:fixtures":"pnpm build && pnpm run test:fixtures:ci","test:rust:ci":"cd rust && wasm-pack test --node && cargo test","test:js:ci":"web-test-runner --node-resolve --playwright --browsers chromium firefox webkit --files test/**/*.test.ts --files !test/speed.test.ts --files !test/fixtures.test.ts","test:fixtures:ci":"bash test-fixtures.sh","rebuild-fixtures":"tsx test/fixtures/rebuild-fixtures.ts","benchmark":"web-test-runner --node-resolve --playwright --browsers chromium firefox webkit --files test/speed.test.ts","clean":"rm -rf wasm/ dist/ rust/target/","lint":"pnpm run --parallel --aggregate-output \"/^lint:*/\"","lint:prettier":"prettier --check . --log-level warn","lint:types":"tsc --noEmit","lint:test-types":"tsc --noEmit --project test/tsconfig.json","lint:eslint":"eslint .","format":"prettier --write ."},"_id":"@bencmbrook/aes_gcm_stream@0.2.0","_integrity":"sha512-P2hBfKU3CgMrHxgQVHdNDZY9rHrqOpjPfS8y9YNpGbhC3NC3il1uAnMfy8qPU+ycx2mqVxnHV/AkiEgLSAQ7yA==","_resolved":"/private/var/folders/05/qv2ng4vd2mz0gxblp8c96ykw0000gn/T/d07460b54d10e7261a343ed107e8923b/bencmbrook-aes_gcm_stream-0.2.0.tgz","_from":"file:bencmbrook-aes_gcm_stream-0.2.0.tgz","_nodeVersion":"22.15.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-P2hBfKU3CgMrHxgQVHdNDZY9rHrqOpjPfS8y9YNpGbhC3NC3il1uAnMfy8qPU+ycx2mqVxnHV/AkiEgLSAQ7yA==","shasum":"0a25b91cdc44b4b48bb86df977849657465245c7","tarball":"https://registry.npmjs.org/@bencmbrook/aes_gcm_stream/-/aes_gcm_stream-0.2.0.tgz","fileCount":27,"unpackedSize":135703,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCDjCGy1ZVSF9xa50opl7szZ4DcsdFKaqKOGU3VBSFZ4gIgdjl3ctkere3fR2CiB8heIPCNmNEYKvAtJPY0Zcellxg="}]},"_npmUser":{"name":"bencmbrook","email":"ben@transcend.io"},"directories":{},"maintainers":[{"name":"bencmbrook","email":"ben@transcend.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/aes_gcm_stream_0.2.0_1754055564410_0.7425402386169759"},"_hasShrinkwrap":false}},"time":{"created":"2025-07-30T03:25:36.176Z","modified":"2025-08-01T13:39:24.771Z","0.1.0-alpha.1":"2025-07-30T03:25:36.454Z","0.1.0-alpha.2":"2025-07-30T05:19:53.261Z","0.2.0":"2025-08-01T13:39:24.602Z"},"author":{"name":"Ben Brook"},"license":"MIT","keywords":["aes","gcm","streaming","webassembly","wasm","web-streams","encryption","crypto"],"description":"WebAssembly-powered streaming AES-256-GCM implementation","maintainers":[{"name":"bencmbrook","email":"ben@transcend.io"}],"readme":"# aes_gcm_stream\n\nA WebAssembly-powered, truly streaming AES-256-GCM implementation for Node.js and the web. This library wraps the Rust [`aes-gcm-stream`](https://lib.rs/crates/aes-gcm-stream) crate and provides both direct Wasm bindings and a streaming API.\n\n## Features\n\n- **True streaming**: Encrypt/decrypt chunk-by-chunk without buffering the entire payload in JavaScript.\n- **High performance**: Leverages Rust's optimized AES-GCM implementation via WebAssembly.\n- **Node.js and Web support**: Works in both Node.js and browser environments.\n- **One-shot or streaming**: Use in single-call mode or stream mode depending on your needs.\n\n## Table of Contents\n\n1. [Installation](#installation)\n2. [Building from Source](#building-from-source)\n3. [API Reference](#api-reference)\n4. [Usage Examples](#usage-examples)\n\n---\n\n## Installation\n\nInstall the published package via npm:\n\n```bash\nnpm install @bencmbrook/aes_gcm_stream\n```\n\n## API Reference\n\nProvides TransformStreams for AES-256-GCM encryption and decryption.\n\n```ts\nimport {\n  init,\n  createEncryptStream,\n  createDecryptStream,\n} from '@bencmbrook/aes_gcm_stream';\n```\n\n#### JS API\n\n- `init(): Promise<InitOutput>` — asynchronously loads the Wasm module (Node.js build auto-initializes)\n- `createEncryptStream(key, nonce, adata?)` — returns a `TransformStream` encrypting each chunk\n- `createDecryptStream(key, nonce, adata?)` — returns a `TransformStream` decrypting and verifying each chunk\n\n### Streaming Usage\n\n```js\nimport {\n  init,\n  createEncryptStream,\n  createDecryptStream,\n} from '@bencmbrook/aes_gcm_stream';\n\nawait init();\n\nconst key = new Uint8Array(32);\nconst nonce = new Uint8Array(12);\n\nconst encryptStream = createEncryptStream(key, nonce);\nconst decryptStream = createDecryptStream(key, nonce);\n\ntry {\n  await new ReadableStream({\n    start(controller) {\n      for (let index = 0; index < 1000; index++) {\n        controller.enqueue(new TextEncoder().encode('Hello, World!'));\n      }\n    },\n  })\n    .pipeThrough(encryptStream)\n    .pipeThrough(decryptStream)\n    .pipeTo(\n      new WritableStream({\n        write(chunk) {\n          console.log(new TextDecoder().decode(chunk));\n        },\n      }),\n    );\n} catch (error) {\n  console.error(error);\n}\n```\n\n---\n\n## Development\n\nThis project uses Rust for the WebAssembly module and TypeScript for the JavaScript/Node.js wrapper.\n\n### Prerequisites\n\n- **Node.js**: Use [`nvm`](https://github.com/nvm-sh/nvm) to install a recent version of Node.js. This project specifies the current version in [`.nvmrc`](.nvmrc).\n\n- **pnpm**: This project uses `pnpm`. After installing Node.js, enable `corepack` to use `pnpm`:\n\n  ```bash\n  npm install -g corepack\n  corepack enable\n  ```\n\n- **Rust**: Install Rust and Cargo via [`rustup`](https://rustup.rs/):\n\n### Setup and Building\n\n```bash\n# Install project dependencies\npnpm install\n\n# Build the Rust Wasm module and TypeScript\npnpm build\n```\n\n`pnpm build` produces:\n\n- `wasm/` directory containing the compiled WebAssembly module\n- `dist/` directory containing the TypeScript output for the library\n\n### Running Tests\n\nRun the tests with:\n\n```bash\n# Run tests in chromium, firefox, and webkit browsers\npnpm test:js\n\n# Run tests in chromium, firefox, and webkit browsers. Takes a while to run since it processes 6GB files\npnpm test:fixtures\n\n# Run tests in Rust\npnpm test:rust\n```\n\n## Performance\n\nRun `pnpm benchmark` to see the speed of the implementation and compare it against WebCrypto (but note that WebCrypto cannot stream, so it's not a perfect comparison).\n\nOn M3 Pro, decrypting a 6.3GB file:\n\n- in Chromium (i.e., Chrome), this implementation decrypts at 60 MB/s with 3 MB of memory usage.\n- in Webkit (i.e., Safari), this implementation decrypts at 60 MB/s with 3 MB of memory usage.\n- in Firefox, this implementation decrypts at 4 MB/s with 3 MB of memory usage.\n\n## Supporting Large Files\n\nFirst, you should avoid buffering data in memory in your implementation, meaning: (A) don't push chunks onto an array, and (B) don't call `new Blob(decryptionStream)`. You should stream the data end-to-end.\n\nSecond, there are volumes of data for which counting the volume of data itself becomes a problem. In JavaScript, counting bits will overflow at a 1.13 PB file.\n\nIn Wasm, it's a bit more complicated. The Rust crate, `aes-gcm-stream`, originally used `usize` bit counters, which in Wasm is `u32`, and thus the bit counter overflowed at 536 MB. This repo patches that crate to use `u64` for the counter, meaning the theoretical maximum file size is 2^64 bytes, or 16 EB. Using this in Wasm requires similar attention to any counters you implement.\n\nHowever, some browsers may have built-in counters which will fail when streaming large amounts of data:\n\n- Chromium (i.e., Chrome): unlimited data (fast; 60 MB/s)\n- Webkit (i.e., Safari): OOM error at files > ~3 GB (fast; 60 MB/s)\n- Firefox: unlimited data (slow; 4 MB/s)\n\nIn general, staying under 3 GB per stream is the safest guarantee for wide browser support.\n","readmeFilename":"README.md"}