kxco-post-quantum 1.2.1 → 1.4.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.
package/CHANGELOG.md CHANGED
@@ -1,257 +1,375 @@
1
- # Changelog
2
-
3
- ## 1.2.1 — 2026-07-22
4
-
5
- Metadata alignment. No code changes; cryptographic surface is byte-for-byte
6
- identical to `1.2.0` (all 39 pinned vectors match).
7
-
8
- ### Changed
9
- - **License now `Apache-2.0`** in package metadata, matching the repository
10
- LICENSE. `1.2.0` was published declaring `MIT` from a pre-relicense branch;
11
- this release corrects the published license to the canonical `Apache-2.0`.
12
- - `author` set to **Shayne Heffernan and John Heffernan**.
13
- - README security note corrected: `@noble/post-quantum` was **not** in scope
14
- of Cure53's 2023 `@noble` audit (which covered `ciphers`/`curves`/`hashes`)
15
- and is maintainer self-audited — the prior "audited by Cure53 (2024)"
16
- wording was inaccurate. See `AUDIT.md`.
17
-
18
- ## 1.2.0 — 2026-07-22
19
-
20
- Adds SLH-DSA (FIPS 205) and modernises the underlying primitive engine to
21
- `@noble/post-quantum@0.6.1`. **No breaking changes for consumers** — the
22
- public API and all previously pinned outputs are byte-for-byte identical.
23
-
24
- ### Added
25
- - **`slhDsa` — SLH-DSA-SHA2-192s (NIST FIPS 205)**, exported both from the
26
- package root and the `kxco-post-quantum/slh-dsa` subpath. Hash-based,
27
- stateless signatures at Security Category 3 (matching ML-DSA-65), whose
28
- security rests only on SHA-2 — the conservative hedge alongside the
29
- lattice-based ML-DSA-65. Deterministic `keypairFromMaster(master, info?)`
30
- via the same HKDF-SHA-512 derivation, plus `sign` / `verify`. Public key
31
- 48 bytes, secret key 96 bytes, signature 16224 bytes.
32
- - Test vectors extended to pin SLH-DSA keypairs and round-trip (39 checks,
33
- up from 29).
34
-
35
- ### Changed
36
- - **`@noble/post-quantum` bumped `^0.2.1` → `^0.6.1`** — the FIPS 203/204/205
37
- final reference implementation. The engine's public API changed argument
38
- order for signature `sign`/`verify` and requires `.js` in subpath imports;
39
- both are absorbed inside this package's wrappers, so no downstream package
40
- or caller is affected.
41
- - Description and keywords updated to reflect SLH-DSA / FIPS 205 coverage.
42
-
43
- ### Verification
44
- - 11 node tests pass, 7 browser-smoke tests pass, 39 pinned vectors pass.
45
- - **Compatibility gate:** every ML-DSA-65, ML-KEM-768, HKDF, fingerprint and
46
- webhook vector pinned under `@noble/post-quantum@0.2.1` still matches
47
- bit-for-bit under `0.6.1`. Deterministic keys derived from existing KXCO
48
- master secrets — including Armature L1 identities — are unchanged.
49
-
50
- ## 1.1.6 — 2026-05-24
51
-
52
- Maintenance release. No breaking changes.
53
-
54
-
55
-
56
- ## 1.1.5 — 2026-05-24
57
-
58
- Maintenance release. No breaking changes.
59
-
60
-
61
-
62
- ## 1.1.4 — 2026-05-24
63
-
64
- Maintenance release. No breaking changes.
65
-
66
-
67
-
68
- ## 1.1.3 — 2026-05-23
69
-
70
- Maintenance release. No breaking changes.
71
-
72
-
73
- All notable changes to this project will be documented in this file.
74
-
75
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
76
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77
-
78
- ## [Unreleased]
79
-
80
- ## [1.1.2] — 2026-05-22
81
-
82
- Documentation correction. No code changes; no behaviour changes; no
83
- cryptographic surface changes vs `1.1.1`.
84
-
85
- ### Fixed
86
- - **AUDIT.md** §1 previously cited a 2024 Cure53 audit of
87
- `@noble/post-quantum`. That citation was incorrect — Cure53's 2023
88
- NDS-01 audit covered `@noble/ciphers`, `@noble/curves`, and
89
- `@noble/hashes` only; the post-quantum package was not in scope. As of
90
- 2026-05-22, upstream `@noble/post-quantum` has only been self-audited
91
- by its maintainer (v0.6.1, April 2026). AUDIT.md §1 has been rewritten
92
- to reflect the actual upstream audit posture. A correction notice is
93
- included at the top of the file. Reviewers who relied on the prior
94
- citation should re-read §1 of AUDIT.md.
95
- - **CHANGELOG.md** 1.0.0 entry similarly stated "audited by Cure53,
96
- 2024" alongside the upstream pin. That sentence has been corrected
97
- in-place in this release; the substance of the 1.0.0 release is
98
- otherwise unchanged.
99
-
100
- ### Why this is a patch, not an advisory
101
- The misstatement was in documentation only. No code path, signature,
102
- key-derivation routine, or wire format depends on the cited audit. The
103
- fix is a documentation rewrite; affected installs upgrade by pulling
104
- 1.1.2. If your due-diligence pack referenced AUDIT.md from 1.0.1
105
- through 1.1.1, please refresh against 1.1.2.
106
-
107
- ## [1.1.1] — 2026-05-21
108
-
109
- Operational hardening release. No source-code changes; this is the first
110
- release published via **npm Trusted Publishing** rather than a long-lived
111
- `NPM_TOKEN`.
112
-
113
- ### Changed
114
- - `.github/workflows/publish.yml` now publishes via npm Trusted Publishing
115
- (OIDC). The `NODE_AUTH_TOKEN` / `NPM_OTP` env vars are removed; the
116
- workflow's `id-token: write` permission is the entire credential.
117
- Registered at https://www.npmjs.com/package/kxco-post-quantum/access
118
- binding `org=JackKXCO`, `repo=kxco-post-quantum`, `workflow=publish.yml`.
119
- - Repo-level `NPM_TOKEN` and `NPM_OTP` secrets removed — no long-lived
120
- credentials remain in the publishing path.
121
-
122
- ### Why this matters
123
- - Every release tarball is now signed by GitHub Actions OIDC against the
124
- exact commit being published, with no human-held secret in the loop.
125
- - No more burning recovery codes per release. The publish workflow now
126
- runs hands-free on every `v*` tag push.
127
-
128
- ## [1.1.0] — 2026-05-21
129
-
130
- Same API. Same byte-for-byte outputs (all 29 pinned vectors still match).
131
- The package now runs in **browsers** as well as Node.
132
-
133
- ### Added
134
- - Isomorphic runtime — every module works identically in modern browsers
135
- (Chromium, Firefox, Safari) and Node, served from CDNs like esm.sh
136
- with zero polyfill burden
137
- - `test/browser-smoke.test.js` runs the public API with `globalThis.Buffer`
138
- removed, asserts plain `Uint8Array` outputs and a clean hybrid-signing
139
- round trip — proves browser compatibility in CI
140
-
141
- ### Changed
142
- - HKDF-SHA-512 now sourced from `@noble/hashes/hkdf` (was `node:crypto`)
143
- - HMAC-SHA-256 now sourced from `@noble/hashes/hmac` (was `node:crypto`)
144
- - SHA-256 for kid fingerprints now sourced from `@noble/hashes/sha256`
145
- (was `node:crypto`)
146
- - Constant-time comparisons are portable byte loops (replaces
147
- `node:crypto.timingSafeEqual`) — identical security property,
148
- runs in browsers
149
- - Functions return `Buffer` on Node (when `globalThis.Buffer` is defined)
150
- and plain `Uint8Array` in browsers. **Backwards compatible** for Node
151
- callers; `Buffer extends Uint8Array` so any code accepting `Uint8Array`
152
- already works.
153
- - `engines.node` bumped to `>=20.19` to match the underlying
154
- `@noble/hashes@2` requirement (Node 18 is past EOL)
155
-
156
- ### Dependencies
157
- - Added `@noble/hashes ^2.2.0` (peer of `@noble/post-quantum`)
158
- - `@noble/post-quantum ^0.2.1` unchanged
159
-
160
- ### Verification
161
- - 9 node tests pass
162
- - 6 browser-smoke tests pass
163
- - 29 pinned vectors still match — no cryptographic surface changes,
164
- bit-for-bit identical to 1.0.3 in Node
165
-
166
- ## [1.0.3] — 2026-05-21
167
-
168
- First release ships with SLSA Level 2 provenance attestation tied to a
169
- public GitHub Actions workflow run. No cryptographic surface changes
170
- vs `1.0.2` — every diff is metadata, types, CI, and hygiene.
171
-
172
- ### Added
173
- - SLSA Level 2 provenance on every published release via GitHub Actions OIDC
174
- (`publishConfig.provenance: true`)
175
- - `.github/workflows/publish.yml` triggered by `v*` tags — runs tests then
176
- `npm publish --provenance --access public`
177
- - `.github/workflows/ci.yml` matrix over Node 18 / 20 / 22 on every push and PR
178
- - Hand-written TypeScript declarations (`.d.ts`) for all six modules; wired
179
- into `exports[*].types` so TypeScript consumers get full typings without
180
- any build step
181
- - `.github/dependabot.yml` — weekly npm + github-actions ecosystem checks
182
- - `sideEffects: false` for tree-shaking
183
- - `funding` field in `package.json`
184
- - Top-level `"types"` field in `package.json` pointing at `./src/index.d.ts`
185
-
186
- ### Changed
187
- - `package.json` `files` allowlist tightened to `["src", "README.md", "LICENSE",
188
- "SECURITY.md", "CHANGELOG.md"]` — locks down what ships to npm
189
- - `package.json` `exports` now declares per-subpath `types` + `import` keys
190
- - `SECURITY.md` rewritten in the standard short-form template with explicit
191
- in-scope / out-of-scope split delegating primitive bugs upstream to
192
- `@noble/post-quantum`
193
- - All third-party actions in workflows pinned by 40-char commit SHA, never
194
- floating tags
195
- - README badge row trimmed to four (`npm`, `license`, `Socket`, `production-live`)
196
- and a 60-second live-verify quickstart added under the title
197
-
198
- ### Security
199
- - No cryptographic code changed in this release — every change is metadata,
200
- types, CI, and documentation. Production behaviour is bit-for-bit identical
201
- to `1.0.2`.
202
-
203
- ## [1.0.2] — 2026-05-21
204
-
205
- ### Changed
206
- - Repository URL on the npm package metadata now points to
207
- `github.com/JackKXCO/kxco-post-quantum`. No code change.
208
-
209
- ## [1.0.1] — 2026-05-21
210
-
211
- ### Added
212
- - `AUDIT.md` — self-attested audit posture with roadmap (external audit
213
- Q3 2026, public bug bounty Q4 2026, FIPS 140-3 CMVP application 2027)
214
- - `test/vectors.json` — 29 deterministic test vectors pinning every primitive
215
- output bit-for-bit
216
- - `test/run-vectors.js` — runner anyone can use to verify reproducibility
217
- - `npm test` runs both the functional tests and vector verification
218
- - `npm run test:vectors` for vector check only
219
-
220
- ### Changed
221
- - `SECURITY.md` sharpened with explicit threat model and pinned upstream
222
- `@noble/post-quantum@0.2.1` integrity hash
223
- - `README.md` "Used in production at" section with file refs to chain.kxco.ai
224
-
225
- No API changes from `1.0.0`.
226
-
227
- ## [1.0.0] — 2026-05-21
228
-
229
- First stable release. Committed public API surface:
230
-
231
- - `mlDsa.keypairFromMaster(master, info—)`, `mlDsa.sign`, `mlDsa.verify`
232
- - `mlKem.keypairFromMaster(master, info—)`, `mlKem.encapsulate`, `mlKem.decapsulate`
233
- - `deriveSeed(master, info, length)`
234
- - `fingerprint(publicKey)`, `kidEquals(a, b)`
235
- - `webhook.envelope`, `webhook.hmacHex`, `webhook.verifyHmac`,
236
- `webhook.pqSign`, `webhook.verifyPq`, `webhook.signDelivery`,
237
- `webhook.verifyDelivery`
238
-
239
- Verified at release: 9/9 functional tests + 29/29 vector checks pass.
240
-
241
- Underlying primitives via `@noble/post-quantum@^0.2.1`. See `AUDIT.md` for
242
- upstream audit posture (no third-party audit of the PQ package; self-audited
243
- by maintainer at v0.6.1, April 2026). ESM-only. Node.js 18+.
244
-
245
- ## [0.1.0] — 2026-05-21
246
-
247
- Initial pre-release.
248
-
249
- [Unreleased]: https://github.com/JackKXCO/kxco-post-quantum/compare/v1.1.2...HEAD
250
- [1.1.2]: https://github.com/JackKXCO/kxco-post-quantum/compare/v1.1.1...v1.1.2
251
- [1.1.1]: https://github.com/JackKXCO/kxco-post-quantum/compare/v1.1.0...v1.1.1
252
- [1.1.0]: https://github.com/JackKXCO/kxco-post-quantum/compare/v1.0.3...v1.1.0
253
- [1.0.3]: https://github.com/JackKXCO/kxco-post-quantum/compare/v1.0.2...v1.0.3
254
- [1.0.2]: https://github.com/JackKXCO/kxco-post-quantum/compare/v1.0.1...v1.0.2
255
- [1.0.1]: https://github.com/JackKXCO/kxco-post-quantum/compare/v1.0.0...v1.0.1
256
- [1.0.0]: https://github.com/JackKXCO/kxco-post-quantum/compare/v0.1.0...v1.0.0
1
+ # Changelog
2
+
3
+ ## 1.4.0
4
+
5
+ Adds the Security Category 5 parameter sets, and publishes conformance and
6
+ interoperability evidence for everything the package computes.
7
+
8
+ Additive throughout. Two new modules appear under `src/`, and no existing module,
9
+ export, default or call path changes: the dependency set is unchanged, the
10
+ default parameter sets stay at Category 3, and all 39 pinned vectors still match
11
+ bit-for-bit. Nothing here can alter the behaviour of an existing call site.
12
+
13
+ ### Added
14
+ - **`mlDsa87` (ML-DSA-87) and `mlKem1024` (ML-KEM-1024)**, Security Category 5,
15
+ as new modules with the same API as their Category 3 counterparts. Purely
16
+ additive: no existing module, export or call path changes, and the KXCO
17
+ default stays Category 3. Subpath exports `./ml-dsa-87` and `./ml-kem-1024`.
18
+ Both are exercised by the ACVP harness and the interop matrix through their
19
+ wrapper path, not only as primitives.
20
+
21
+ Default derivation info differs from the Category 3 modules
22
+ (`ml-dsa-87-v1`, `ml-kem-1024-v1`), so one master yields unrelated keys per
23
+ parameter set rather than colliding, and `test/category5.test.js` asserts that
24
+ a signature from one set does not verify under the other in either direction.
25
+
26
+ **Supporting these sets is not a CNSA 2.0 compliance claim.** CNSA 2.0 names
27
+ both, and compliance is a property of a deployment rather than of an available
28
+ function: the KXCO estate signs at Category 3, including Armature L1 from
29
+ block 0 and every issued KXCO ID, none of which these modules change. The
30
+ accurate sentence is "supports ML-DSA-87 and ML-KEM-1024". This is stated in
31
+ both module headers, both type declarations, the README, MIGRATION.md and
32
+ CONFORMANCE.md, because it is the claim most likely to drift.
33
+
34
+ Sizes, since they are the real migration cost: ML-DSA-87 public key 2592 and
35
+ signature 4627 bytes, against 1952 and 3309 at ML-DSA-65. ML-KEM-1024 public
36
+ key and ciphertext 1568 bytes each, against 1184 and 1088. The ML-KEM shared
37
+ secret stays 32 bytes at both sets, so downstream key derivation is unaffected.
38
+ - **`conformance/`, a NIST ACVP harness** for FIPS 203, 204 and 205, covering
39
+ every parameter set NIST publishes vectors for: ML-KEM-512/768/1024,
40
+ ML-DSA-44/65/87 and all twelve SLH-DSA sets. The signature sets cover the
41
+ external and internal interfaces, pure and pre-hashed, external-mu, and
42
+ deterministic and randomized signing. Vectors are pinned by upstream commit
43
+ and per-file SHA-256 in `conformance/acvp-lock.json`, so a rewritten upstream
44
+ file fails the fetch instead of quietly changing the result.
45
+ - **`conformance/interop/`, a cross-implementation matrix** against Bouncy
46
+ Castle (Java) and dilithium-py / kyber-py (Python), neither of which shares
47
+ code with our backend. Every check runs in both directions, and includes
48
+ negative controls: a tampered signature that the peer must reject, and a
49
+ corrupted ML-KEM ciphertext that must decapsulate to an unrelated secret.
50
+ Without those, a peer that always returned true would pass the whole matrix.
51
+ - **`CONFORMANCE.md`** reporting both, including what the evidence does not
52
+ cover: no side-channel claim, no FIPS 140-3 validation, no CNSA 2.0
53
+ assertion, no protocol-level encoding claim.
54
+ - **`THREAT-MODEL.md`** stating the security boundary. In particular it states
55
+ plainly that constant-time execution cannot be established from inside
56
+ JavaScript, that timing, cache and power attackers are therefore out of
57
+ scope, and what to do instead when a key needs to withstand them.
58
+ - **`MIGRATION.md`** covering the add-then-remove path off RSA or ECDSA, and
59
+ version-to-version upgrades.
60
+ - **`.github/workflows/conformance.yml`** running both harnesses on every push
61
+ and in full weekly, so the reports describe current behaviour rather than the
62
+ day someone ran them by hand. The SLH-DSA signature sets run as a separate job
63
+ because a full pass of them takes over an hour, and per-push runs subsample
64
+ with a per-group cap, which the generated report records so a subsampled run
65
+ cannot be mistaken for a full one.
66
+ - **A CycloneDX SBOM generated during publish**, from the tree that was actually
67
+ installed for the build, and attached to the release artifacts.
68
+ - Scripts: `conformance:fetch`, `conformance:acvp`, `conformance:interop`, `sbom`.
69
+
70
+ ### Notes
71
+ - **The pre-hash skips in the ACVP report are the library being stricter than
72
+ NIST's sample files, not a coverage gap.** The backend refuses a pre-hash
73
+ whose collision strength is below the parameter set's security category;
74
+ NIST's vectors pair every approved hash with every parameter set. Those cases
75
+ are counted as skipped, never as passed.
76
+ - **Hedged signing means wrapper signatures are not reproducible.** `sign` draws
77
+ fresh randomness per signature, which FIPS 204 permits and recommends, so the
78
+ byte-equality check does not apply on the wrapper path. It is asserted on the
79
+ backend path for the same parameter sets. This is reported rather than hidden.
80
+ - **Provenance:** a release published from a workstation instead of through
81
+ `publish.yml` carries no npm attestation. The Trusted Publishing binding still
82
+ names the old `JackKXCO` org after the move to `KnightsbridgeAIQ` and needs
83
+ repointing before the OIDC path can work. See the comment in `publish.yml`.
84
+
85
+ ## 1.3.0
86
+
87
+ Adds FIPS 204 / FIPS 205 context string support. Purely additive: the
88
+ cryptographic surface for every existing call site is byte-for-byte unchanged,
89
+ and all 39 pinned vectors still match.
90
+
91
+ ### Added
92
+ - **Optional `context` on `mlDsa.sign` / `mlDsa.verify`** via a trailing options
93
+ object, `{ context }`. At most 255 bytes per FIPS 204 section 5.2; strings are
94
+ encoded as UTF-8. A signature made under a context does not verify without it
95
+ or under a different one. Closes a real incompleteness relative to FIPS 204:
96
+ the library previously could not verify a counterparty's signature that used a
97
+ context.
98
+ - **The same option on `slhDsa.sign` / `slhDsa.verify`**, on the same terms.
99
+ Added alongside ML-DSA rather than after it, because one signature module
100
+ accepting an options object while its sibling silently ignored one would be a
101
+ footgun.
102
+ - `MAX_CONTEXT_BYTES` (255) exported from both modules.
103
+ - `test/context.test.js`, 26 tests, including cross-verification against
104
+ third-party ML-DSA-65 signatures produced by OpenSSL through Python
105
+ `cryptography`, covering five context shapes: short, single-byte, the 255-byte
106
+ maximum, binary, and multi-byte UTF-8.
107
+
108
+ ### Notes
109
+ - **No behaviour change without the new argument.** Omitting `opts` takes the
110
+ identical code path as before. An empty context is collapsed to no context,
111
+ which is what FIPS 204 specifies and what was verified empirically.
112
+ - **Misuse throws rather than returning `false`.** A context over 255 bytes, a
113
+ wrongly typed context, or a bare value passed where an options object belongs
114
+ raises `RangeError` / `TypeError`. These are caller bugs, not failed
115
+ verifications, and swallowing them would hide a signature that silently
116
+ carried no domain separation. No existing call site passes the argument, so
117
+ nothing can regress.
118
+ - Works identically on `@noble/post-quantum` 0.6.1 and 0.7.0, verified on both,
119
+ so this release is independent of the 0.7.0 upgrade.
120
+
121
+ ## 1.2.1 — 2026-07-22
122
+
123
+ Metadata alignment. No code changes; cryptographic surface is byte-for-byte
124
+ identical to `1.2.0` (all 39 pinned vectors match).
125
+
126
+ ### Changed
127
+ - **License now `Apache-2.0`** in package metadata, matching the repository
128
+ LICENSE. `1.2.0` was published declaring `MIT` from a pre-relicense branch;
129
+ this release corrects the published license to the canonical `Apache-2.0`.
130
+ - `author` set to **Shayne Heffernan and John Heffernan**.
131
+ - README security note corrected: `@noble/post-quantum` was **not** in scope
132
+ of Cure53's 2023 `@noble` audit (which covered `ciphers`/`curves`/`hashes`)
133
+ and is maintainer self-audited — the prior "audited by Cure53 (2024)"
134
+ wording was inaccurate. See `AUDIT.md`.
135
+
136
+ ## 1.2.0 — 2026-07-22
137
+
138
+ Adds SLH-DSA (FIPS 205) and modernises the underlying primitive engine to
139
+ `@noble/post-quantum@0.6.1`. **No breaking changes for consumers** — the
140
+ public API and all previously pinned outputs are byte-for-byte identical.
141
+
142
+ ### Added
143
+ - **`slhDsa` — SLH-DSA-SHA2-192s (NIST FIPS 205)**, exported both from the
144
+ package root and the `kxco-post-quantum/slh-dsa` subpath. Hash-based,
145
+ stateless signatures at Security Category 3 (matching ML-DSA-65), whose
146
+ security rests only on SHA-2 — the conservative hedge alongside the
147
+ lattice-based ML-DSA-65. Deterministic `keypairFromMaster(master, info?)`
148
+ via the same HKDF-SHA-512 derivation, plus `sign` / `verify`. Public key
149
+ 48 bytes, secret key 96 bytes, signature 16224 bytes.
150
+ - Test vectors extended to pin SLH-DSA keypairs and round-trip (39 checks,
151
+ up from 29).
152
+
153
+ ### Changed
154
+ - **`@noble/post-quantum` bumped `^0.2.1` → `^0.6.1`** — the FIPS 203/204/205
155
+ final reference implementation. The engine's public API changed argument
156
+ order for signature `sign`/`verify` and requires `.js` in subpath imports;
157
+ both are absorbed inside this package's wrappers, so no downstream package
158
+ or caller is affected.
159
+ - Description and keywords updated to reflect SLH-DSA / FIPS 205 coverage.
160
+
161
+ ### Verification
162
+ - 11 node tests pass, 7 browser-smoke tests pass, 39 pinned vectors pass.
163
+ - **Compatibility gate:** every ML-DSA-65, ML-KEM-768, HKDF, fingerprint and
164
+ webhook vector pinned under `@noble/post-quantum@0.2.1` still matches
165
+ bit-for-bit under `0.6.1`. Deterministic keys derived from existing KXCO
166
+ master secrets — including Armature L1 identities — are unchanged.
167
+
168
+ ## 1.1.6 — 2026-05-24
169
+
170
+ Maintenance release. No breaking changes.
171
+
172
+
173
+
174
+ ## 1.1.5 — 2026-05-24
175
+
176
+ Maintenance release. No breaking changes.
177
+
178
+
179
+
180
+ ## 1.1.4 — 2026-05-24
181
+
182
+ Maintenance release. No breaking changes.
183
+
184
+
185
+
186
+ ## 1.1.3 — 2026-05-23
187
+
188
+ Maintenance release. No breaking changes.
189
+
190
+
191
+ All notable changes to this project will be documented in this file.
192
+
193
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
194
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
195
+
196
+ ## [Unreleased]
197
+
198
+ ## [1.1.2] — 2026-05-22
199
+
200
+ Documentation correction. No code changes; no behaviour changes; no
201
+ cryptographic surface changes vs `1.1.1`.
202
+
203
+ ### Fixed
204
+ - **AUDIT.md** §1 previously cited a 2024 Cure53 audit of
205
+ `@noble/post-quantum`. That citation was incorrect — Cure53's 2023
206
+ NDS-01 audit covered `@noble/ciphers`, `@noble/curves`, and
207
+ `@noble/hashes` only; the post-quantum package was not in scope. As of
208
+ 2026-05-22, upstream `@noble/post-quantum` has only been self-audited
209
+ by its maintainer (v0.6.1, April 2026). AUDIT.md §1 has been rewritten
210
+ to reflect the actual upstream audit posture. A correction notice is
211
+ included at the top of the file. Reviewers who relied on the prior
212
+ citation should re-read §1 of AUDIT.md.
213
+ - **CHANGELOG.md** 1.0.0 entry similarly stated "audited by Cure53,
214
+ 2024" alongside the upstream pin. That sentence has been corrected
215
+ in-place in this release; the substance of the 1.0.0 release is
216
+ otherwise unchanged.
217
+
218
+ ### Why this is a patch, not an advisory
219
+ The misstatement was in documentation only. No code path, signature,
220
+ key-derivation routine, or wire format depends on the cited audit. The
221
+ fix is a documentation rewrite; affected installs upgrade by pulling
222
+ 1.1.2. If your due-diligence pack referenced AUDIT.md from 1.0.1
223
+ through 1.1.1, please refresh against 1.1.2.
224
+
225
+ ## [1.1.1] — 2026-05-21
226
+
227
+ Operational hardening release. No source-code changes; this is the first
228
+ release published via **npm Trusted Publishing** rather than a long-lived
229
+ `NPM_TOKEN`.
230
+
231
+ ### Changed
232
+ - `.github/workflows/publish.yml` now publishes via npm Trusted Publishing
233
+ (OIDC). The `NODE_AUTH_TOKEN` / `NPM_OTP` env vars are removed; the
234
+ workflow's `id-token: write` permission is the entire credential.
235
+ Registered at https://www.npmjs.com/package/kxco-post-quantum/access
236
+ binding `org=JackKXCO`, `repo=kxco-post-quantum`, `workflow=publish.yml`.
237
+ - Repo-level `NPM_TOKEN` and `NPM_OTP` secrets removed — no long-lived
238
+ credentials remain in the publishing path.
239
+
240
+ ### Why this matters
241
+ - Every release tarball is now signed by GitHub Actions OIDC against the
242
+ exact commit being published, with no human-held secret in the loop.
243
+ - No more burning recovery codes per release. The publish workflow now
244
+ runs hands-free on every `v*` tag push.
245
+
246
+ ## [1.1.0] — 2026-05-21
247
+
248
+ Same API. Same byte-for-byte outputs (all 29 pinned vectors still match).
249
+ The package now runs in **browsers** as well as Node.
250
+
251
+ ### Added
252
+ - Isomorphic runtime — every module works identically in modern browsers
253
+ (Chromium, Firefox, Safari) and Node, served from CDNs like esm.sh
254
+ with zero polyfill burden
255
+ - `test/browser-smoke.test.js` runs the public API with `globalThis.Buffer`
256
+ removed, asserts plain `Uint8Array` outputs and a clean hybrid-signing
257
+ round trip — proves browser compatibility in CI
258
+
259
+ ### Changed
260
+ - HKDF-SHA-512 now sourced from `@noble/hashes/hkdf` (was `node:crypto`)
261
+ - HMAC-SHA-256 now sourced from `@noble/hashes/hmac` (was `node:crypto`)
262
+ - SHA-256 for kid fingerprints now sourced from `@noble/hashes/sha256`
263
+ (was `node:crypto`)
264
+ - Constant-time comparisons are portable byte loops (replaces
265
+ `node:crypto.timingSafeEqual`) — identical security property,
266
+ runs in browsers
267
+ - Functions return `Buffer` on Node (when `globalThis.Buffer` is defined)
268
+ and plain `Uint8Array` in browsers. **Backwards compatible** for Node
269
+ callers; `Buffer extends Uint8Array` so any code accepting `Uint8Array`
270
+ already works.
271
+ - `engines.node` bumped to `>=20.19` to match the underlying
272
+ `@noble/hashes@2` requirement (Node 18 is past EOL)
273
+
274
+ ### Dependencies
275
+ - Added `@noble/hashes ^2.2.0` (peer of `@noble/post-quantum`)
276
+ - `@noble/post-quantum ^0.2.1` unchanged
277
+
278
+ ### Verification
279
+ - 9 node tests pass
280
+ - 6 browser-smoke tests pass
281
+ - 29 pinned vectors still match — no cryptographic surface changes,
282
+ bit-for-bit identical to 1.0.3 in Node
283
+
284
+ ## [1.0.3] — 2026-05-21
285
+
286
+ First release ships with SLSA Level 2 provenance attestation tied to a
287
+ public GitHub Actions workflow run. No cryptographic surface changes
288
+ vs `1.0.2` — every diff is metadata, types, CI, and hygiene.
289
+
290
+ ### Added
291
+ - SLSA Level 2 provenance on every published release via GitHub Actions OIDC
292
+ (`publishConfig.provenance: true`)
293
+ - `.github/workflows/publish.yml` triggered by `v*` tags — runs tests then
294
+ `npm publish --provenance --access public`
295
+ - `.github/workflows/ci.yml` matrix over Node 18 / 20 / 22 on every push and PR
296
+ - Hand-written TypeScript declarations (`.d.ts`) for all six modules; wired
297
+ into `exports[*].types` so TypeScript consumers get full typings without
298
+ any build step
299
+ - `.github/dependabot.yml` — weekly npm + github-actions ecosystem checks
300
+ - `sideEffects: false` for tree-shaking
301
+ - `funding` field in `package.json`
302
+ - Top-level `"types"` field in `package.json` pointing at `./src/index.d.ts`
303
+
304
+ ### Changed
305
+ - `package.json` `files` allowlist tightened to `["src", "README.md", "LICENSE",
306
+ "SECURITY.md", "CHANGELOG.md"]` — locks down what ships to npm
307
+ - `package.json` `exports` now declares per-subpath `types` + `import` keys
308
+ - `SECURITY.md` rewritten in the standard short-form template with explicit
309
+ in-scope / out-of-scope split delegating primitive bugs upstream to
310
+ `@noble/post-quantum`
311
+ - All third-party actions in workflows pinned by 40-char commit SHA, never
312
+ floating tags
313
+ - README badge row trimmed to four (`npm`, `license`, `Socket`, `production-live`)
314
+ and a 60-second live-verify quickstart added under the title
315
+
316
+ ### Security
317
+ - No cryptographic code changed in this release — every change is metadata,
318
+ types, CI, and documentation. Production behaviour is bit-for-bit identical
319
+ to `1.0.2`.
320
+
321
+ ## [1.0.2] — 2026-05-21
322
+
323
+ ### Changed
324
+ - Repository URL on the npm package metadata now points to
325
+ `github.com/JackKXCO/kxco-post-quantum`. No code change.
326
+
327
+ ## [1.0.1] — 2026-05-21
328
+
329
+ ### Added
330
+ - `AUDIT.md` — self-attested audit posture with roadmap (external audit
331
+ Q3 2026, public bug bounty Q4 2026, FIPS 140-3 CMVP application 2027)
332
+ - `test/vectors.json` — 29 deterministic test vectors pinning every primitive
333
+ output bit-for-bit
334
+ - `test/run-vectors.js` — runner anyone can use to verify reproducibility
335
+ - `npm test` runs both the functional tests and vector verification
336
+ - `npm run test:vectors` for vector check only
337
+
338
+ ### Changed
339
+ - `SECURITY.md` sharpened with explicit threat model and pinned upstream
340
+ `@noble/post-quantum@0.2.1` integrity hash
341
+ - `README.md` "Used in production at" section with file refs to chain.kxco.ai
342
+
343
+ No API changes from `1.0.0`.
344
+
345
+ ## [1.0.0] — 2026-05-21
346
+
347
+ First stable release. Committed public API surface:
348
+
349
+ - `mlDsa.keypairFromMaster(master, info—)`, `mlDsa.sign`, `mlDsa.verify`
350
+ - `mlKem.keypairFromMaster(master, info—)`, `mlKem.encapsulate`, `mlKem.decapsulate`
351
+ - `deriveSeed(master, info, length)`
352
+ - `fingerprint(publicKey)`, `kidEquals(a, b)`
353
+ - `webhook.envelope`, `webhook.hmacHex`, `webhook.verifyHmac`,
354
+ `webhook.pqSign`, `webhook.verifyPq`, `webhook.signDelivery`,
355
+ `webhook.verifyDelivery`
356
+
357
+ Verified at release: 9/9 functional tests + 29/29 vector checks pass.
358
+
359
+ Underlying primitives via `@noble/post-quantum@^0.2.1`. See `AUDIT.md` for
360
+ upstream audit posture (no third-party audit of the PQ package; self-audited
361
+ by maintainer at v0.6.1, April 2026). ESM-only. Node.js 18+.
362
+
363
+ ## [0.1.0] — 2026-05-21
364
+
365
+ Initial pre-release.
366
+
367
+ [Unreleased]: https://github.com/JackKXCO/kxco-post-quantum/compare/v1.1.2...HEAD
368
+ [1.1.2]: https://github.com/JackKXCO/kxco-post-quantum/compare/v1.1.1...v1.1.2
369
+ [1.1.1]: https://github.com/JackKXCO/kxco-post-quantum/compare/v1.1.0...v1.1.1
370
+ [1.1.0]: https://github.com/JackKXCO/kxco-post-quantum/compare/v1.0.3...v1.1.0
371
+ [1.0.3]: https://github.com/JackKXCO/kxco-post-quantum/compare/v1.0.2...v1.0.3
372
+ [1.0.2]: https://github.com/JackKXCO/kxco-post-quantum/compare/v1.0.1...v1.0.2
373
+ [1.0.1]: https://github.com/JackKXCO/kxco-post-quantum/compare/v1.0.0...v1.0.1
374
+ [1.0.0]: https://github.com/JackKXCO/kxco-post-quantum/compare/v0.1.0...v1.0.0
257
375
  [0.1.0]: https://github.com/JackKXCO/kxco-post-quantum/releases/tag/v0.1.0