{"_id":"@brashkie/signalis-noise","name":"@brashkie/signalis-noise","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@brashkie/signalis-noise","version":"0.1.0","description":"The Noise Protocol Framework (XX, IK, NK patterns) built on @brashkie/signalis-core. Curve25519 + SHA-256 with selectable ChaCha20-Poly1305 or AES-GCM. Verified against the official Noise test vectors.","author":{"name":"Brashkie","url":"Hepein Oficial"},"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/Brashkie/signalis-noise.git"},"homepage":"https://github.com/Brashkie/signalis-noise","bugs":{"url":"https://github.com/Brashkie/signalis-noise/issues"},"keywords":["noise-protocol","noise","signalis","e2e-encryption","handshake","curve25519","chacha20poly1305","aes-gcm","cryptography"],"type":"commonjs","main":"./dist/index.js","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"sideEffects":false,"scripts":{"build":"tsup","typecheck":"tsc --noEmit","lint":"biome check src __tests__","lint:fix":"biome check --write src __tests__","format":"biome format --write src __tests__","test":"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run typecheck && npm run lint && npm run test && npm run build"},"peerDependencies":{"@brashkie/signalis-core":">=0.4.0 <1.0.0"},"devDependencies":{"@biomejs/biome":"^1.9.0","@brashkie/signalis-core":"^0.4.0","@types/node":"^22.0.0","@vitest/coverage-v8":"^3.0.0","tsup":"^8.0.0","typescript":"^6.0.3","vitest":"^3.0.0"},"engines":{"node":">=18"},"_id":"@brashkie/signalis-noise@0.1.0","gitHead":"e36fba680e3a589e6620ca6fddf1b6c8f7122803","_nodeVersion":"22.23.1","_npmVersion":"10.9.8","dist":{"integrity":"sha512-sH0zv2wlIpLraqiRz8aNSs5R2onK3Fqx0i4Y2HZMUyS74dtKEZJkOY6MA/Ce+fKZ7xvkEvqsQlo7vtHp627qgg==","shasum":"0c0d0e42f6f4128692eec6b3721cfb583ff3930b","tarball":"https://registry.npmjs.org/@brashkie/signalis-noise/-/signalis-noise-0.1.0.tgz","fileCount":10,"unpackedSize":159894,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@brashkie%2fsignalis-noise@0.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIB5eBPGgsgSSxROXzBB+qgWtB6F6BNKXJjNAVp+KkO5OAiBdiQ19daTAkvt9dRHgMuWGAW0DZqdTfdICsPskqtlL2Q=="}]},"_npmUser":{"name":"brashkie","email":"fabianoarjunken@gmail.com"},"directories":{},"maintainers":[{"name":"brashkie","email":"fabianoarjunken@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/signalis-noise_0.1.0_1784851421573_0.18189150216191963"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-24T00:03:41.373Z","0.1.0":"2026-07-24T00:03:41.709Z","modified":"2026-07-24T00:03:42.108Z"},"maintainers":[{"name":"brashkie","email":"fabianoarjunken@gmail.com"}],"description":"The Noise Protocol Framework (XX, IK, NK patterns) built on @brashkie/signalis-core. Curve25519 + SHA-256 with selectable ChaCha20-Poly1305 or AES-GCM. Verified against the official Noise test vectors.","homepage":"https://github.com/Brashkie/signalis-noise","keywords":["noise-protocol","noise","signalis","e2e-encryption","handshake","curve25519","chacha20poly1305","aes-gcm","cryptography"],"repository":{"type":"git","url":"git+https://github.com/Brashkie/signalis-noise.git"},"author":{"name":"Brashkie","url":"Hepein Oficial"},"bugs":{"url":"https://github.com/Brashkie/signalis-noise/issues"},"license":"Apache-2.0","readme":"<div align=\"center\">\n\n# @brashkie/signalis-noise\n\n**The [Noise Protocol Framework](https://noiseprotocol.org/) built on [`@brashkie/signalis-core`](https://github.com/Brashkie/signalis-core).**\n\n[![CI](https://github.com/Brashkie/signalis-noise/actions/workflows/ci.yml/badge.svg)](https://github.com/Brashkie/signalis-noise/actions/workflows/ci.yml)\n[![npm version](https://img.shields.io/npm/v/@brashkie/signalis-noise.svg)](https://www.npmjs.com/package/@brashkie/signalis-noise)\n[![license](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](./LICENSE)\n[![types](https://img.shields.io/badge/types-TypeScript-3178c6.svg)](https://www.typescriptlang.org/)\n[![vectors](https://img.shields.io/badge/official%20vectors-32%2F32-brightgreen.svg)](#correctness)\n\n</div>\n\n---\n\nThe XX, IK, and NK handshake patterns over **Curve25519 + SHA-256**, with a\nselectable AEAD — **ChaCha20-Poly1305** or **AES-GCM**. Every handshake is\nverified **byte-for-byte against the official Noise test vectors**.\n\nAll cryptography is delegated to `@brashkie/signalis-core`; this package is pure\nprotocol orchestration (`CipherState` / `SymmetricState` / `HandshakeState`).\nNoise powers the transport layer of WhatsApp, WireGuard, and Tailscale.\n\n```\n  @brashkie/signalis-core (Rust primitives)\n        ▲\n        │ peerDependency (DH, HKDF, AEAD, SHA-256)\n        │\n  @brashkie/signalis-noise (this package — TS orchestration)\n```\n\n---\n\n## Install\n\n```bash\nnpm install @brashkie/signalis-noise @brashkie/signalis-core\n```\n\n`@brashkie/signalis-core` is a **peer dependency** — install it alongside so a\nsingle copy of the crypto core is shared across the Signalis ecosystem.\n\n## Quick start\n\nA full XX handshake (mutual authentication) between two parties:\n\n```ts\nimport { HandshakeState } from '@brashkie/signalis-noise';\nimport { Curve25519 } from '@brashkie/signalis-core';\n\nconst aliceStatic = Curve25519.generateKeyPair();\nconst bobStatic = Curve25519.generateKeyPair();\n\nconst alice = new HandshakeState({\n  pattern: 'XX',\n  initiator: true,\n  staticKeyPair: aliceStatic,\n});\nconst bob = new HandshakeState({\n  pattern: 'XX',\n  initiator: false,\n  staticKeyPair: bobStatic,\n});\n\n// -> e\nconst m1 = alice.writeMessage();\nbob.readMessage(m1);\n\n// <- e, ee, s, es\nconst m2 = bob.writeMessage();\nalice.readMessage(m2);\n\n// -> s, se\nconst m3 = alice.writeMessage();\nbob.readMessage(m3);\n\n// Both sides now derive matching transport keys.\nconst aliceTx = alice.split();\nconst bobTx = bob.split();\n\n// Encrypted transport, both directions:\nconst ct = aliceTx.send.encryptWithAd(Buffer.alloc(0), Buffer.from('hello bob'));\nconst pt = bobTx.receive.decryptWithAd(Buffer.alloc(0), ct); // \"hello bob\"\n```\n\nYou can piggyback an encrypted payload on any handshake message:\n\n```ts\nconst m1 = alice.writeMessage(Buffer.from('early data'));\nconst payload = bob.readMessage(m1); // decrypted once a key exists\n```\n\n## Patterns\n\n| Pattern | Authentication | Use case |\n|---------|----------------|----------|\n| **XX** | Mutual, identities exchanged during the handshake | The workhorse — WhatsApp's transport uses XX |\n| **IK** | Mutual, initiator knows responder's static up front | Pinned server key; enables early encrypted data |\n| **NK** | Responder only (initiator anonymous) | TLS-like: anonymous client, known server |\n| **KK** | Mutual, both statics known in advance | Two servers with pre-exchanged, pinned identities |\n\nIK and NK require the responder's static public key in advance:\n\n```ts\nconst alice = new HandshakeState({\n  pattern: 'IK',\n  initiator: true,\n  staticKeyPair: aliceStatic,\n  remoteStaticPublicKey: bobStatic.publicKey, // known ahead of time\n});\n```\n\nAdditional patterns (XK, NX, KK, …) are pure data additions in `patterns.ts` and\ncan be contributed without touching the core state machine.\n\n## Choosing the cipher\n\n```ts\nnew HandshakeState({ pattern: 'XX', initiator: true, staticKeyPair, cipher: 'AESGCM' });\n// cipher?: 'ChaChaPoly' (default) | 'AESGCM'\n```\n\nThe full protocol name is derived automatically, e.g.\n`Noise_XX_25519_ChaChaPoly_SHA256` or `Noise_IK_25519_AESGCM_SHA256`.\n\n> **Note on nonces.** Per the Noise spec, ChaChaPoly encodes the message counter\n> **little-endian** and AES-GCM **big-endian**. This package handles that\n> internally — a subtle detail the official vectors exist to enforce.\n\n## API\n\n| Export | Description |\n|--------|-------------|\n| `HandshakeState` | Drives a pattern to completion; `writeMessage` / `readMessage` / `split` |\n| `CipherState` | AEAD keyed with a 64-bit nonce counter (transport + handshake) |\n| `SymmetricState` | Chaining-key + transcript-hash mixing (HKDF + SHA-256) |\n| `getPattern`, `XX`, `IK`, `NK`, `PATTERNS` | Pattern definitions |\n| `getAead`, `encodeNonce` | Low-level cipher helpers |\n| `NoiseError`, `HandshakeError`, `DecryptError`, `NoiseValidationError` | Errors |\n\n`HandshakeState.split()` returns `{ send, receive, handshakeHash }` — two\nindependent transport `CipherState`s plus the channel-binding hash.\n\n## Correctness\n\nCryptographic code demands more than \"it round-trips.\" This package replays the\n**canonical Noise test vectors** and asserts every handshake and transport\nmessage matches **byte-for-byte**:\n\n- **32 official vectors** — XX / IK / NK × ChaChaPoly / AESGCM, with and without\n  a prologue.\n- Plus live randomized handshakes for every pattern/cipher combination, nonce\n  encoding checks, and error-path coverage.\n\nIf the vectors pass, the protocol is correct by construction — not by assertion.\n\n```bash\nnpm test            # 65 tests, including the 32 official vectors\nnpm run test:coverage\n```\n\n## Security notes\n\n- **This is a handshake framework, not a full transport.** You are responsible\n  for framing (length-prefixing) messages on the wire and for terminating the\n  connection if a `DecryptError` occurs — a failed tag means tampering.\n- **Nonce exhaustion is fatal by design.** After 2^64 messages a `CipherState`\n  throws rather than wrapping the nonce. Re-handshake long-lived connections.\n- **`_testEphemeral` is for test vectors only.** Never inject ephemeral keys in\n  production — ephemeral randomness is essential to forward secrecy.\n- Report vulnerabilities per [SECURITY.md](./SECURITY.md).\n\n## Ecosystem\n\n| Package | Role |\n|---------|------|\n| [`@brashkie/signalis-core`](https://github.com/Brashkie/signalis-core) | Native Rust cryptographic primitives |\n| [`@brashkie/signalis`](https://github.com/Brashkie/signalis) | The Signal Protocol: X3DH, Double Ratchet, sessions |\n| [`@brashkie/signalis-storage`](https://github.com/Brashkie/signalis-storage) | Decoupled storage layer |\n| **`@brashkie/signalis-noise`** | **This package — the Noise Protocol Framework** |\n\nSee [ROADMAP.md](./ROADMAP.md).\n\n## License\n\nApache-2.0 © Brashkie (Hepein Oficial)\n","readmeFilename":"README.md","_rev":"1-84a7d7ab7e1f966acfa7a3ec0bbde0da"}