raz-encrypt 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +2 -15
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -145,19 +145,6 @@ const combinedResult = await verify(
145
145
 
146
146
  **So, to directly answer "do I need to run verify first?"** — no. `verify()` is only relevant when Alice actually signed something; `decryptFrom()` is only relevant when Alice actually encrypted something. Run whichever one matches what you received, in either order, or both if she did both.
147
147
 
148
- ## Hands-on demo
149
-
150
- The `demo/` folder is a runnable version of the quickstart above, playing Alice and Bob as two separate local identities:
151
-
152
- ```bash
153
- npm run demo:setup # creates both identities, swaps public cards, records trust
154
- npm run demo:sign # Alice signs demo/sample-document.json
155
- npm run demo:verify # Bob verifies it -> { valid: true }
156
- npm run demo:tamper # Bob verifies a modified copy -> { valid: false, reason: "hash-mismatch" }
157
- npm run demo:verify # run again fresh -> proves identity/trust really persisted to disk, not just in memory
158
- npm run demo:clean # removes the generated local stores/cards so you can start over
159
- ```
160
-
161
148
  ## API
162
149
 
163
150
  | Function | What it does |
@@ -191,11 +178,11 @@ If one layer is ever broken — classical by a quantum computer, or the newer po
191
178
 
192
179
  **Bottom line:** this is genuinely strong, real-world-grade cryptography built from carefully audited, widely used components (the [`@noble/*`](https://github.com/paulmillr/noble-post-quantum) libraries) — not a marketing label. It just isn't a government-certified module, and true safety also depends on this specific implementation being built and tested carefully, which is exactly what the test suite's "try to break it" cases (tampered documents, corrupted individual signatures) are for.
193
180
 
194
- **What `sign`/`verify` guarantees, precisely.** Every field that affects a verification outcome — the document hash *and* the optional `expiresAt` — is part of the signed payload, not just `documentHash` alone. That matters because certificates travel over the exact same untrusted channels (email, chat) this library assumes for everything else: without that, an intermediary with no secret key at all could delete or rewrite `expiresAt` in transit and flip a `verify()` result, which would quietly defeat the whole point of setting an expiry.
181
+ **What `sign`/`verify` guarantees, precisely.** Every field that affects a verification outcome — the document hash _and_ the optional `expiresAt` — is part of the signed payload, not just `documentHash` alone. That matters because certificates travel over the exact same untrusted channels (email, chat) this library assumes for everything else: without that, an intermediary with no secret key at all could delete or rewrite `expiresAt` in transit and flip a `verify()` result, which would quietly defeat the whole point of setting an expiry.
195
182
 
196
183
  **Two honest limitations, so you can decide if they matter for your use case:**
197
184
 
198
- - **No forward secrecy.** `encryptFor`/`decryptFrom` derive their key from *long-term* keys on both sides: a static ECDH-P384 exchange (deterministic for a given pair of identities) combined with an ML-KEM-1024 encapsulation whose secret still requires the recipient's long-term KEM secret key to decapsulate. Both of those secret keys live in the same `identity.enc.json`. This means that if someone ever recovers your passphrase and that file, they can decrypt **every box anyone ever sent you**, not just future ones — there's no per-message ephemeral key rotation (the kind Signal-style ratcheting provides). Rotate identities (new `storageDir`, `trustParty()` again) if you need to bound the blast radius of a future key compromise.
185
+ - **No forward secrecy.** `encryptFor`/`decryptFrom` derive their key from _long-term_ keys on both sides: a static ECDH-P384 exchange (deterministic for a given pair of identities) combined with an ML-KEM-1024 encapsulation whose secret still requires the recipient's long-term KEM secret key to decapsulate. Both of those secret keys live in the same `identity.enc.json`. This means that if someone ever recovers your passphrase and that file, they can decrypt **every box anyone ever sent you**, not just future ones — there's no per-message ephemeral key rotation (the kind Signal-style ratcheting provides). Rotate identities (new `storageDir`, `trustParty()` again) if you need to bound the blast radius of a future key compromise.
199
186
  - **No replay protection.** An `EncryptedBox` decrypts identically no matter how many times, or how much later, it's replayed to the same recipient — there's no session id, counter, or timestamp binding it to a single delivery. Fine for "send this document once"; if your use case cares about replay (e.g. treating receipt of a box as a one-time authorization), add your own nonce/timestamp inside the encrypted payload and check it on the receiving end.
200
187
 
201
188
  ## What this library deliberately does _not_ do (v1)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "raz-encrypt",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Local-first, hybrid classical+post-quantum signing and verification for two consenting parties. No server, no database required.",
5
5
  "license": "MIT",
6
6
  "type": "module",