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