{"_id":"@alternatefutures/e2ee","_rev":"4-0ca1bb4e1f11ebfc4cf432c01b1c8fda","name":"@alternatefutures/e2ee","dist-tags":{"latest":"0.4.0"},"versions":{"0.1.0":{"name":"@alternatefutures/e2ee","version":"0.1.0","license":"AGPL-3.0-only","_id":"@alternatefutures/e2ee@0.1.0","maintainers":[{"name":"alternatehayk","email":"hayk@alternatefutures.ai"},{"name":"system-af","email":"system@alternatefutures.ai"}],"homepage":"https://github.com/alternatefutures/alternate-e2ee#readme","bugs":{"url":"https://github.com/alternatefutures/alternate-e2ee/issues"},"dist":{"shasum":"4ca146f25c3ea03d08c4bfe49f09b3ee67264981","tarball":"https://registry.npmjs.org/@alternatefutures/e2ee/-/e2ee-0.1.0.tgz","fileCount":20,"integrity":"sha512-t5OaZm+pCxuerSijZnKV9Bi6zPESo+6M53Kmgwufh87tC3V7oUnNC7L4wBSKUnWMOGWq1k1qdbHOsaH00HX13Q==","signatures":[{"sig":"MEQCID7ZIX0G2LXm27k+Tr3RqI0/hxAzsG4MBGVlwhPXoewuAiADyx7znYn5WZFsohJZRzOD0EjRxE8XzArxX/OCiJON8w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alternatefutures%2fe2ee@0.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":177914},"type":"module","engines":{"node":">=18.18.2"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js","require":"./dist/node.cjs"},"./wordlist":{"types":"./dist/wordlist.d.ts","import":"./dist/wordlist.js","require":"./dist/wordlist.cjs"}},"gitHead":"27828651d1065eab34fa1c04a3a5bd8bcce263be","scripts":{"test":"vitest run","build":"tsup","changeset":"changeset","typecheck":"tsc --noEmit","prepublishOnly":"npm run build","changeset:publish":"npm run build && changeset publish","changeset:version":"changeset version && npm install --package-lock-only"},"_npmUser":{"name":"alternatehayk","email":"hayk@alternatefutures.ai"},"repository":{"url":"git+https://github.com/alternatefutures/alternate-e2ee.git","type":"git"},"_npmVersion":"10.8.2","description":"Framework-agnostic end-to-end-encryption core (Argon2id room derivation, AES-256-GCM, Ed25519 TOFU) shared across AlternateFutures clients.","directories":{},"sideEffects":true,"_nodeVersion":"20.20.2","dependencies":{"hash-wasm":"^4.12.0","@noble/ed25519":"^2.1.0"},"publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"~5.7.3","@types/node":"^22.10.7","@changesets/cli":"^2.27.11"},"_npmOperationalInternal":{"tmp":"tmp/e2ee_0.1.0_1782048709754_0.935769505803504","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@alternatefutures/e2ee","version":"0.1.1","license":"AGPL-3.0-only","_id":"@alternatefutures/e2ee@0.1.1","maintainers":[{"name":"alternatehayk","email":"hayk@alternatefutures.ai"},{"name":"system-af","email":"system@alternatefutures.ai"}],"homepage":"https://github.com/alternatefutures/alternate-e2ee#readme","bugs":{"url":"https://github.com/alternatefutures/alternate-e2ee/issues"},"dist":{"shasum":"25e32c18338cb245409f99284063790da5f1f057","tarball":"https://registry.npmjs.org/@alternatefutures/e2ee/-/e2ee-0.1.1.tgz","fileCount":20,"integrity":"sha512-CaHDjbydBD6vfVeS9K2L3hMYq23tZ6PfcLd32PB1o0GJzaMo3YADYHUQxO1BpyZbDvMF6iNNmnalQPWgdIKzYQ==","signatures":[{"sig":"MEQCIDDgIm6fsyc3E8vcI/nZZ4Wt4AWONBHzPp+jH7rJRuv+AiAnD3bWMiJWHjyizNhGs+NKMrwY7HhJM8LjpFcRhqfT7Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alternatefutures%2fe2ee@0.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":178253},"type":"module","engines":{"node":">=18.18.2"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./node":{"import":{"types":"./dist/node.d.ts","default":"./dist/node.js"},"require":{"types":"./dist/node.d.cts","default":"./dist/node.cjs"}},"./wordlist":{"import":{"types":"./dist/wordlist.d.ts","default":"./dist/wordlist.js"},"require":{"types":"./dist/wordlist.d.cts","default":"./dist/wordlist.cjs"}},"./package.json":"./package.json"},"gitHead":"999750dcb706b5550b845ab930b3b81fcef6904d","scripts":{"test":"vitest run","build":"tsup","changeset":"changeset","typecheck":"tsc --noEmit","prepublishOnly":"npm run build","changeset:publish":"npm run build && changeset publish","changeset:version":"changeset version && npm install --package-lock-only"},"_npmUser":{"name":"alternatehayk","email":"hayk@alternatefutures.ai"},"repository":{"url":"git+https://github.com/alternatefutures/alternate-e2ee.git","type":"git"},"_npmVersion":"10.8.2","description":"Framework-agnostic end-to-end-encryption core (Argon2id room derivation, AES-256-GCM, Ed25519 TOFU) shared across AlternateFutures clients.","directories":{},"sideEffects":true,"_nodeVersion":"20.20.2","dependencies":{"hash-wasm":"^4.12.0","@noble/ed25519":"^2.1.0"},"publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"~5.7.3","@types/node":"^22.10.7","@changesets/cli":"^2.27.11"},"_npmOperationalInternal":{"tmp":"tmp/e2ee_0.1.1_1782050625773_0.6462660656966048","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@alternatefutures/e2ee","version":"0.3.0","license":"AGPL-3.0-only","_id":"@alternatefutures/e2ee@0.3.0","maintainers":[{"name":"alternatehayk","email":"hayk@alternatefutures.ai"},{"name":"system-af","email":"system@alternatefutures.ai"}],"homepage":"https://github.com/alternatefutures/alternate-e2ee#readme","bugs":{"url":"https://github.com/alternatefutures/alternate-e2ee/issues"},"dist":{"shasum":"58e3f8a14928a6a96c85228fb06c9f2b0d615bf5","tarball":"https://registry.npmjs.org/@alternatefutures/e2ee/-/e2ee-0.3.0.tgz","fileCount":20,"integrity":"sha512-y8CZaCTaFvxT/shmSZSSKvY12ZRsplXcykP/6V4iHI93A89WVXjAL1XjsSfWWH0pL8mwbR+CWT4A7XhCj1Wt0A==","signatures":[{"sig":"MEQCIAXdxlhGZibbDCLxcjjretIH5FpNBMq3p/+Al/BBikFbAiA96KkQnlI1W5dpOva7pczw5qPJWaksP4YjyEMrZJ334w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":203499},"type":"module","engines":{"node":">=18.18.2"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./node":{"import":{"types":"./dist/node.d.ts","default":"./dist/node.js"},"require":{"types":"./dist/node.d.cts","default":"./dist/node.cjs"}},"./wordlist":{"import":{"types":"./dist/wordlist.d.ts","default":"./dist/wordlist.js"},"require":{"types":"./dist/wordlist.d.cts","default":"./dist/wordlist.cjs"}},"./package.json":"./package.json"},"gitHead":"51544f66a77573fef0d47549eb663a0ec15ba2e1","scripts":{"test":"vitest run","build":"tsup","changeset":"changeset","typecheck":"tsc --noEmit","prepublishOnly":"npm run build","changeset:publish":"npm run build && changeset publish","changeset:version":"changeset version && npm install --package-lock-only"},"_npmUser":{"name":"alternatehayk","email":"hayk@alternatefutures.ai"},"repository":{"url":"git+https://github.com/alternatefutures/alternate-e2ee.git","type":"git"},"_npmVersion":"11.6.2","description":"Framework-agnostic end-to-end-encryption core (Argon2id room derivation, AES-256-GCM, Ed25519 TOFU) shared across AlternateFutures clients.","directories":{},"sideEffects":true,"_nodeVersion":"24.13.0","dependencies":{"hash-wasm":"4.12.0","@noble/ed25519":"2.3.0"},"publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","typescript":"~5.7.3","@types/node":"^22.10.7","@changesets/cli":"^2.27.11"},"_npmOperationalInternal":{"tmp":"tmp/e2ee_0.3.0_1783029948470_0.7843172663675733","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"_id":"@alternatefutures/e2ee@0.4.0","bugs":{"url":"https://github.com/alternatefutures/alternate-e2ee/issues"},"dist":{"shasum":"84c532cbf8e61fe08f3f45cc8c8e3305eb59df80","tarball":"https://registry.npmjs.org/@alternatefutures/e2ee/-/e2ee-0.4.0.tgz","fileCount":30,"integrity":"sha512-c+A0pY4vGY2v2NG5ZnVJA0kUnSMzl/1r14Hyy8Fsdjc6gKPmxd6hh6tW83X6uepc1lyenXwftE8mHUr/oHWjBQ==","signatures":[{"sig":"MEYCIQDNbCWGKMUnxbQN7Hqhc1JGoRP2bfckMKJmhnh6wQEV1wIhAIhST0fOnB1Ls6VqY9vLjS4lyzhiKzc1ZPf3Hxcu3RIc","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCrT1tdy7vuHlrzcfRbCZW/mYdxmo4QNx7SackwBfLIeQIgRecLUTRWn3RUqoT83EYeXSogTzT7PmY9wbSVBqwCc3M="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alternatefutures%2fe2ee@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":419282},"name":"@alternatefutures/e2ee","type":"module","engines":{"node":">=18.18.2"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./node":{"import":{"types":"./dist/node.d.ts","default":"./dist/node.js"},"require":{"types":"./dist/node.d.cts","default":"./dist/node.cjs"}},"./wordlist":{"import":{"types":"./dist/wordlist.d.ts","default":"./dist/wordlist.js"},"require":{"types":"./dist/wordlist.d.cts","default":"./dist/wordlist.cjs"}},"./node-client":{"import":{"types":"./dist/node-client.d.ts","default":"./dist/node-client.js"},"require":{"types":"./dist/node-client.d.cts","default":"./dist/node-client.cjs"}},"./package.json":"./package.json"},"gitHead":"c0f14938e8b26f83ea3077d5a2f3ae94fd9ed94d","license":"AGPL-3.0-only","scripts":{"test":"vitest run","build":"tsup","changeset":"changeset","typecheck":"tsc --noEmit","prepublishOnly":"npm run build","changeset:publish":"npm run build && changeset publish","changeset:version":"changeset version && npm install --package-lock-only"},"version":"0.4.0","_npmUser":{"name":"alternatehayk","email":"hayk@alternatefutures.ai"},"homepage":"https://github.com/alternatefutures/alternate-e2ee#readme","repository":{"url":"git+https://github.com/alternatefutures/alternate-e2ee.git","type":"git"},"_npmVersion":"10.8.2","description":"Framework-agnostic end-to-end-encryption core (Argon2id room derivation, AES-256-GCM, Ed25519 TOFU) shared across AlternateFutures clients.","directories":{},"maintainers":[{"name":"alternatehayk","email":"hayk@alternatefutures.ai"},{"name":"system-af","email":"system@alternatefutures.ai"}],"sideEffects":true,"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.18.3","hash-wasm":"4.12.0","@noble/ed25519":"2.3.0"},"publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^2.1.8","@types/ws":"^8.18.1","typescript":"~5.7.3","@types/node":"^22.10.7","@changesets/cli":"^2.27.11"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/e2ee_0.4.0_1789586586036_0.7443316194324932"}}},"time":{"created":"2026-06-21T13:31:49.595Z","modified":"2026-09-16T19:23:06.600Z","0.1.0":"2026-06-21T13:31:49.903Z","0.1.1":"2026-06-21T14:03:45.913Z","0.3.0":"2026-07-02T22:05:48.618Z","0.4.0":"2026-09-16T19:23:06.240Z"},"bugs":{"url":"https://github.com/alternatefutures/alternate-e2ee/issues"},"license":"AGPL-3.0-only","homepage":"https://github.com/alternatefutures/alternate-e2ee#readme","repository":{"url":"git+https://github.com/alternatefutures/alternate-e2ee.git","type":"git"},"description":"Framework-agnostic end-to-end-encryption core (Argon2id room derivation, AES-256-GCM, Ed25519 TOFU) shared across AlternateFutures clients.","maintainers":[{"name":"alternatehayk","email":"hayk@alternatefutures.ai"},{"name":"system-af","email":"system@alternatefutures.ai"}],"readme":"# @alternatefutures/e2ee\n\nThe framework-agnostic **end-to-end-encryption core** shared across AlternateFutures\nclients (alternate-chat, the `acc` CLI, alternate-connect video, and future\nservices). DOM-free, network-free, storage-free — it runs unchanged in the\nbrowser, Bun, and Node.\n\nThis package is the **single source of truth** for the protocol. It replaces the\nprevious \"edit two byte-identical `protocol.ts` copies and `diff` them\" rule:\nthere is now one copy, imported at a pinned version. Interop is enforced by the\nlockfile, not by reviewer vigilance.\n\n## What's inside\n\n- **Room derivation** — `deriveRoom` (→ WebCrypto `CryptoKey` + room id),\n  `deriveRoomBytes` (→ raw 32-byte key + room id, for e.g. LiveKit `setKey`),\n  `deriveRaw` (the raw 64-byte Argon2id output). The passphrase *is* the room.\n- **Identity** — Ed25519 TOFU: `randomPrivateKey`, `identityFromPrivateKey`,\n  `fingerprintOf`.\n- **Envelope** — `sealMessage`/`openMessage`, `sealPresence`/`openPresence`\n  (AES-256-GCM, AAD-bound, length-padded, Ed25519-signed).\n- **Constants/helpers** — `PROTOCOL_VERSION`, `ARGON2_PARAMS`, `ROOM_SALT`,\n  `ROOM_ID_RE`, `toB64`/`fromB64`/`toB64Url`.\n\n## Install\n\n```bash\nnpm i @alternatefutures/e2ee\n```\n\n## Use\n\n```ts\nimport { deriveRoom, identityFromPrivateKey, randomPrivateKey, sealMessage } from '@alternatefutures/e2ee'\n\nconst { key, roomId } = await deriveRoom('a strong shared passphrase')\nconst me = await identityFromPrivateKey(randomPrivateKey())\nconst envelope = await sealMessage(key, me, roomId, 1, 'alice', 'hello')\n```\n\nPer-app domain separation (so a reused passphrase does NOT collide across apps):\n\n```ts\nimport { deriveRoomBytes } from '@alternatefutures/e2ee'\n// video app: distinct salt + NFKC, raw key bytes for LiveKit\nconst { keyBytes, roomId } = await deriveRoomBytes(passphrase, {\n  salt: 'alternate-connect/meet/v1',\n  normalize: true,\n})\n```\n\nSubpaths:\n\n```ts\nimport { roomLabel } from '@alternatefutures/e2ee/wordlist' // human room labels\nimport '@alternatefutures/e2ee/node'                        // Node ≤18 WebCrypto shim (import FIRST)\n```\n\n> **Defaults are byte-identical to alt-chat v2** (`salt = 'alt-chat/room/v2'`, no\n> NFKC), so adopting this package invalidates no existing room.\n\n## Security & versioning\n\nThe KDF params, AAD layout, padding buckets, and signed-bytes layout are\n**protocol constants** — every participant in a room must produce identical\nbytes. Any change to them is wire-breaking: bump **`PROTOCOL_VERSION`** *and* the\npackage version (minor/major) together, and pin the exact version across all\nconsumers. Keys never leave this layer's callers; persistence (browser\n`localStorage`, CLI 0600 file) is each app's concern. `@noble/ed25519` and\n`hash-wasm` are pinned; published with `--provenance`.\n\n## Develop\n\n```bash\nnpm install\nnpm run typecheck\nnpm run build     # tsup → dist (ESM + CJS + .d.ts)\nnpm test          # vitest: determinism, salt separation, seal/open round-trip\n```\n","readmeFilename":"README.md"}