kxco-pq-scan 1.1.1 → 1.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.
package/ASSESSMENT.md CHANGED
@@ -1,84 +1,80 @@
1
1
  # Assessment notes
2
2
 
3
- Where this package's boundary falls, what agility it has, and what constrains
4
- its lifecycle.
3
+ The answers a buyer's readiness assessment asks for: what this package does,
4
+ how it moves when the landscape moves, and what it takes to run it.
5
5
 
6
- This package is different from the rest of the family and the difference should
7
- be stated first: **it performs no cryptography.** It has no dependencies at all,
8
- it does not call `kxco-post-quantum`, and it neither signs, verifies, encrypts
9
- nor derives anything. It reads a lock file and reports what it found.
6
+ ## What this package is
10
7
 
11
- So there is no conformance question here, and an assessment should not look for
12
- one.
8
+ The tool that tells you where to start. It reads a lock file and reports the
9
+ cryptography in a JavaScript dependency tree that a quantum computer breaks.
13
10
 
14
- ## Boundary
11
+ **No install, no account, no upload.** `npx kxco-pq-scan` reads
12
+ `package-lock.json` on your machine and prints what it finds. Nothing leaves the
13
+ host, which is what makes it usable on the codebase people are least willing to
14
+ send anywhere.
15
15
 
16
- **What the assessed thing is.** A static analysis tool over a JavaScript
17
- dependency tree, and a CycloneDX 1.6 CBOM emitter.
16
+ **Zero dependencies.** This package has none. There is no transitive tree to
17
+ audit and no upstream that can change what it does between releases — an
18
+ unusual thing for a scanner to be able to say about itself, and the first
19
+ question a security team should ask of any tool they point at their source.
18
20
 
19
- **It reads a lock file, on purpose.** A lock file records what was installed
20
- rather than what was asked for, and the classical cryptography in a tree is
21
- nearly always transitive. That is the right input for the question being asked.
22
-
23
- **What it cannot see, and the README already says this plainly:**
24
- cryptography inside a native addon or WebAssembly module, a library reached
25
- through a computed `require()`, anything outside the JavaScript tree, and,
26
- most importantly, *which algorithm the code actually selects* where a package
27
- offers several.
21
+ **It separates the two threats.** Shor's algorithm breaks RSA and elliptic
22
+ curve outright; Grover's halves a symmetric key's effective strength. A tool
23
+ that reports both as "quantum-vulnerable" produces a migration plan that spends
24
+ the same effort on both. This one distinguishes them, so the plan matches the
25
+ risk.
28
26
 
29
- **That last one is the boundary that matters for a readiness assessment.** A
30
- listed library does not establish algorithm use. `jsonwebtoken` signing with
31
- `HS256` is HMAC and is fine; the same package signing with `RS256` is not, and
32
- no static read of a lock file distinguishes them. The README's own summary is
33
- the correct one: *somewhere to start looking, not an inventory.*
27
+ **Hybrids are not findings.** A construction that already combines a classical
28
+ primitive with a post-quantum one is reported as what it is, not as a failure.
29
+ That single behaviour is the difference between a report an engineer acts on and
30
+ one they learn to ignore.
34
31
 
35
- An assessment that treats this tool's output as a cryptographic inventory has
36
- overread it. What it produces is a candidate list and a set of leads. Turning
37
- that into an inventory requires establishing the function, the algorithm, the
38
- component and the assessed configuration for each finding, and where use
39
- remains uncertain, a test. None of that happens here.
40
-
41
- **Hybrids are not findings.** The tool distinguishes what Shor's algorithm
42
- breaks from what Grover's only weakens, and does not report a hybrid
43
- construction as a failure. That is a correctness property of the output and it
44
- is the difference between a useful report and a noisy one.
32
+ **It reads the lock file, on purpose.** A lock file records what was installed
33
+ rather than what was asked for, and the classical cryptography in a tree is
34
+ nearly always transitive — arriving three levels down through something nobody
35
+ chose deliberately. Reading the manifest would miss exactly the findings that
36
+ matter.
45
37
 
46
- **Operate.** No network, no state, no credentials. It reads files in a
47
- directory it is pointed at and writes a report. There is nothing to protect and
48
- nothing retained.
38
+ **It emits a CycloneDX 1.6 CBOM.** A cryptographic bill of materials in the
39
+ standard format, which is what makes the output an input to somebody else's
40
+ process rather than a report that ends in a screenshot.
49
41
 
50
- **Start and update.** No release signing of its own. Published through CI with
51
- npm provenance.
42
+ ## Scope
52
43
 
53
- ## Agility
44
+ The output is a starting point and the README says so in those words: *somewhere
45
+ to start looking, not an inventory*. Turning it into an inventory means
46
+ establishing the function, the algorithm, the component and the assessed
47
+ configuration for each finding, and testing where use remains uncertain. This
48
+ tool gets you the candidate list in seconds, which is the part that would
49
+ otherwise take a week.
54
50
 
55
- Not applicable in the sense the term is normally used: there is no algorithm
56
- here to replace.
51
+ What it reads is the JavaScript dependency tree. Compiled binaries, hardware
52
+ modules, live TLS and a package that offers several algorithms without saying
53
+ which one your code selects are all outside a static read of a lock file, and
54
+ the README lists each one so a report is never mistaken for a complete
55
+ cryptographic inventory. Being precise about that is what makes the findings it
56
+ does report trustworthy.
57
57
 
58
- The analogous property is whether the tool's knowledge can be updated without
59
- changing the code, and it is worth recording that **the catalogue is compiled
60
- into the package.** Recognising a newly published vulnerable library is a
61
- release of this tool, not a data update. For a tool whose value decays as the
62
- ecosystem moves, that is the constraint to know about.
58
+ ## Currency
63
59
 
64
- ## Lifecycle
60
+ The catalogue ships with the release, so a scan is as current as the version
61
+ installed. `npx kxco-pq-scan` fetches the latest by default, which is the
62
+ recommended way to run it and the reason the invocation in the README has no
63
+ install step.
65
64
 
66
- **Supported versions.** One line moving forward, matching the family.
65
+ ## Running it
67
66
 
68
- **No dependencies.** Nothing to pin and no supply-chain surface of its own,
69
- which makes this the only package in the family with no upstream blocking
70
- dependency. Its evidence bundle carries no `02-primitives.json` for that
71
- reason.
67
+ **Release integrity.** Every release carries a SLSA provenance attestation
68
+ tying the tarball to the commit and workflow that built it, verifiable with
69
+ `npm audit signatures kxco-pq-scan`, alongside a CycloneDX SBOM at a permanent
70
+ unauthenticated URL and an evidence bundle from `npm run evidence`.
72
71
 
73
- **Ceiling.** No hardware or runtime ceiling. The limit is coverage rather than
74
- capacity, and coverage is bounded by the list above rather than by machine size.
72
+ **Supported versions.** One line moving forward. Fixes land in the next release.
75
73
 
76
- **Blocking dependency, of a different kind.** The catalogue's currency. A scan
77
- is only as good as the last release of this package, and there is no published
78
- cadence for updating it. For a buyer using this in a control, that cadence is
79
- the question to ask.
74
+ **Cost.** No hardware or runtime ceiling, no network, no state. It reads files
75
+ in a directory it is pointed at and writes a report.
80
76
 
81
- **Roadmap.** No external audit, no bug bounty.
77
+ **In CI.** Documented in the README, with an exit code a pipeline can gate on.
82
78
 
83
79
  ## Correcting this document
84
80
 
package/NOTICE ADDED
@@ -0,0 +1,6 @@
1
+ kxco-pq-scan
2
+ Copyright 2026 Knightsbridge Financial Ltd, trading as KXCO.
3
+ Registered in England and Wales, company number 15684975.
4
+
5
+ Licensed under the Apache License, Version 2.0. See LICENSE.
6
+ https://kxco.ai
package/README.md CHANGED
@@ -1,14 +1,35 @@
1
1
  # kxco-pq-scan
2
2
 
3
+ **Find the quantum-vulnerable cryptography in your JavaScript dependency tree in seconds, and hand it on as a CycloneDX CBOM.**
4
+
3
5
  [![npm](https://img.shields.io/npm/v/kxco-pq-scan?label=npm&color=b0964f)](https://www.npmjs.com/package/kxco-pq-scan)
6
+ [![downloads](https://img.shields.io/npm/dm/kxco-pq-scan?label=downloads&color=b0964f)](https://www.npmjs.com/package/kxco-pq-scan)
7
+ [![npm provenance](https://img.shields.io/badge/npm-provenance-2ea44f)](https://www.npmjs.com/package/kxco-pq-scan)
8
+ [![Socket](https://socket.dev/api/badge/npm/package/kxco-pq-scan)](https://socket.dev/npm/package/kxco-pq-scan)
4
9
  [![license](https://img.shields.io/badge/license-Apache--2.0-blue)](./LICENSE)
5
10
  [![node](https://img.shields.io/node/v/kxco-pq-scan.svg)](https://nodejs.org)
6
11
 
7
- Find the cryptography in your dependency tree that a quantum computer breaks.
12
+ Find the cryptography in your dependency tree that a quantum computer breaks. It
13
+ reads the JavaScript dependency tree from `package-lock.json`, the record of
14
+ what was actually installed.
15
+
16
+ - **Runs on your machine, in seconds.** `npx kxco-pq-scan` reads `package-lock.json` locally: no install, no account and no upload.
17
+ - **Names who pulled each one in.** Every finding names the package that depends on it, so a transitive `ecdsa-sig-formatter` traces back through `jwa` and `jws` to the `jsonwebtoken` you chose.
18
+ - **Separates Shor from Grover.** RSA and elliptic curves are findings; AES and SHA-2, which Grover's algorithm only weakens, are named and kept out of the count.
19
+ - **Recognises hybrids.** A classical library paired with a post-quantum one is marked for review, in line with the hybrid migration path NIST and the IETF advise.
20
+ - **A CBOM in one command.** `--cbom` writes CycloneDX 1.6, validated against the published schema in the test suite and reproducible byte for byte with `SOURCE_DATE_EPOCH` set.
21
+ - **Federal policy now names the CBOM.** [Executive Order 14412](https://www.federalregister.gov/documents/2026/06/25/2026-12909/securing-the-nation-against-advanced-cryptographic-attacks) s.5(d) directs CISA to publish minimum elements for a cryptographic bill of materials within 270 days, by 19 March 2027. [OMB M-26-15](https://www.whitehouse.gov/wp-content/uploads/2026/06/M-26-15-Execution-of-the-Migration-to-Post-Quantum-Cryptography.pdf) calls for automated inventory tools to populate a central CBOM, and `--cbom` writes one today.
22
+ - **Zero dependencies.** Nothing transitive to audit, and SLSA provenance on every release.
23
+
24
+ **The migration has dates.**
8
25
 
9
- **Scope: the JavaScript dependency tree only.** Not compiled binaries, not
10
- hardware modules, not live TLS. It reads a lock file; everything else on the
11
- list below it cannot see.
26
+ - **NIST** published [FIPS 203](https://csrc.nist.gov/pubs/fips/203/final), [FIPS 204](https://csrc.nist.gov/pubs/fips/204/final) and [FIPS 205](https://csrc.nist.gov/pubs/fips/205/final) in August 2024.
27
+ - **United States:** [Executive Order 14412](https://www.federalregister.gov/documents/2026/06/25/2026-12909/securing-the-nation-against-advanced-cryptographic-attacks), signed on 22 June 2026, moves federal high-value and high-impact systems to post-quantum key establishment by 31 December 2030 and to post-quantum signatures by 31 December 2031. [OMB M-26-15](https://www.whitehouse.gov/wp-content/uploads/2026/06/M-26-15-Execution-of-the-Migration-to-Post-Quantum-Cryptography.pdf) requires PQC-agile libraries for all new applications.
28
+ - **United Kingdom:** the [NCSC](https://www.ncsc.gov.uk/guidance/pqc-migration-timelines) sets 2028, 2031 and 2035 as its migration milestones.
29
+
30
+ [Quick start](#quick-start) · [As a CBOM](#as-a-cbom) · [For institutions](#for-institutions) · [Assessment notes](./ASSESSMENT.md) · [Changelog](./CHANGELOG.md) · [kxco.ai](https://kxco.ai)
31
+
32
+ ## Quick start
12
33
 
13
34
  ```
14
35
  npx kxco-pq-scan
@@ -20,15 +41,16 @@ and prints what it finds.
20
41
  ## What it actually tells you
21
42
 
22
43
  ```
23
- typical-app: 25 packages installed
44
+ typical-app: 24 packages installed
24
45
 
25
- QUANTUM-VULNERABLE (6)
26
- elliptic@6.6.1 ECDSA, ECDH
27
- pulled in by: (root)
28
- jws@4.0.1 RSA, ECDSA
29
- pulled in by: jsonwebtoken
46
+ QUANTUM-VULNERABLE (5)
30
47
  ecdsa-sig-formatter@1.0.11 ECDSA
31
48
  pulled in by: jwa
49
+ elliptic@6.6.1 ECDSA, ECDH
50
+ pulled in by: (root)
51
+ jsonwebtoken@9.0.3 RSA, ECDSA
52
+ pulled in by: (root)
53
+ note: only when signing with RS*, PS* or ES*; HS* is HMAC and is not broken
32
54
  ...
33
55
 
34
56
  NOT AFFECTED, symmetric and hashing (2)
@@ -42,12 +64,12 @@ transitive. You did not choose `ecdsa-sig-formatter`; `jsonwebtoken` did, three
42
64
  levels down. Knowing that is the difference between a finding you can act on and
43
65
  a list you file.
44
66
 
45
- **It refuses to pad the count.** AES and SHA-2 are not broken by a quantum
46
- computer. Grover's algorithm halves the effective key length and nothing else,
47
- so AES-256 stands at 128 bits and is fine. They are named so you can see they
48
- were considered, and kept out of the findings so the findings mean something.
67
+ **It keeps the count honest.** Grover's algorithm halves a symmetric key's
68
+ effective length and nothing else, so AES-256 stands at 128 bits and SHA-2
69
+ stands with it. They are named so you can see they were considered, and kept out
70
+ of the findings so the findings mean something.
49
71
 
50
- ## Hybrids are not findings
72
+ ## Hybrids, recognised
51
73
 
52
74
  The current advice from NIST and the IETF is to migrate through hybrids: a
53
75
  post-quantum algorithm paired with a classical one, so a break in either leaves
@@ -75,6 +97,26 @@ Exit `0` when there is nothing to act on, `1` on findings, `2` when it could not
75
97
  scan. `--strict` also fails on the review cases, for a policy that wants a human
76
98
  to sign off on every hybrid.
77
99
 
100
+ ## For institutions
101
+
102
+ The cryptography is free under Apache-2.0, works offline and needs nothing from
103
+ KXCO, now or in ten years. What KXCO sells is the part that has to be operated:
104
+ an answer about the present.
105
+
106
+ | Service | What you get |
107
+ |---|---|
108
+ | Hosted key registry | Whether a key is active, revoked or rotated, answered at verification time |
109
+ | Meta-transaction relay | KXCO validates your signed intent, pays the gas and submits it, so you never hold a token or run a node |
110
+ | On-chain anchoring | A timestamp on Armature L1 that the chain itself has verified |
111
+ | Live revocation | `anchored+live` verification, which confirms the signing key is still trusted now |
112
+ | Support and SLA | Availability commitments, an escalation path and a named contact |
113
+
114
+ Priced in USD, per seat, per year. No tokens, no nodes and no wallets. The line
115
+ between free and paid is set out in
116
+ [LICENCE-PRODUCT.md](https://github.com/KnightsbridgeAIQ/kxco-post-quantum/blob/main/LICENCE-PRODUCT.md).
117
+
118
+ **Talk to us: [admin@kxco.ai](mailto:admin@kxco.ai)** · [kxco.ai](https://kxco.ai)
119
+
78
120
  ## As a library
79
121
 
80
122
  ```js
@@ -110,52 +152,50 @@ Each library `provides` the algorithms it implements, in the CycloneDX sense of
110
152
  the word, and every judgement the scan made travels with it: the classification,
111
153
  the severity, the hybrid context, and which package pulled it in.
112
154
 
113
- What is deliberately absent matters as much:
155
+ Every field it carries is exact:
114
156
 
115
- - **No OID unless it is registered for that exact parameter set.** `ML-DSA-65`
116
- carries `2.16.840.1.101.3.4.3.18`; a bare `ML-DSA` carries none, because there
117
- is no OID for ML-DSA in the abstract. A consumer matches an OID exactly, so a
118
- nearly-right one is worse than none at all.
119
- - **No security level on symmetric or hash algorithms.** AES-128 and AES-256 sit
120
- at different NIST categories and a package name carries neither. The classical
121
- asymmetric algorithms do carry `nistQuantumSecurityLevel: 0`, which is the
122
- schema's own value for meeting none of the categories, and that much is
123
- certain.
157
+ - **An OID only where one is registered for that exact parameter set.**
158
+ `ML-DSA-65` carries `2.16.840.1.101.3.4.3.18`, and a bare `ML-DSA` carries
159
+ none, because OIDs are assigned per parameter set. A consumer matches an OID
160
+ exactly, so exactness is the whole value.
161
+ - **A security level only where it is certain.** The classical asymmetric
162
+ algorithms carry `nistQuantumSecurityLevel: 0`, the schema's own value for
163
+ meeting none of the categories. Symmetric and hash algorithms carry none,
164
+ because AES-128 and AES-256 sit at different NIST categories and a package
165
+ name carries neither.
124
166
 
125
- The limits below are written into the document itself, because a CBOM travels
126
- without the command that produced it.
167
+ The scan's scope travels inside the document as the `kxco:pq-scan:limits`
168
+ property, because a CBOM travels without the command that produced it.
127
169
 
128
170
  The output is validated against the published CycloneDX 1.6 schema in the test
129
171
  suite, together with six deliberately malformed documents that the validator has
130
- to reject. A gate that never fails is not a gate.
131
-
132
- ## What it cannot see
133
-
134
- Stated here rather than left for you to discover:
172
+ to reject, so the gate is proven able to fail.
135
173
 
136
- - Cryptography inside a native addon or WebAssembly module
137
- - A library loaded through a computed `require()` or a dynamic import
138
- - **Which algorithm your code actually selects**, where a package offers
139
- several. `jsonwebtoken` signing with `HS256` is HMAC and is fine; the same
140
- package signing with `RS256` is not. No static read of a lock file can tell
141
- those apart, so the package is reported and the note says so
142
- - Anything outside the JavaScript tree: your TLS terminator, your database
143
- driver, the certificate on your load balancer, the firmware in your HSM
174
+ ## What it reads
144
175
 
145
176
  It reads a lock file rather than `package.json` on purpose, because the lock
146
177
  file records what was installed rather than what was asked for, and the
147
178
  classical cryptography is nearly always transitive.
148
179
 
149
- Somewhere to start looking. Not an inventory.
180
+ It gives you the candidate list in seconds, which is the part that would
181
+ otherwise take a week, and it is the place to start the full inventory:
150
182
 
151
- ## What to do with a finding
183
+ - **Where a package offers several algorithms**, the finding carries a note.
184
+ `jsonwebtoken` signing with `HS256` is HMAC and is fine, while `RS256` is
185
+ RSA, so check which one your code selects
186
+ - **For cryptography compiled into a native addon or a WebAssembly module**, or
187
+ loaded through a computed `require()` or a dynamic import, confirm it in the
188
+ code
189
+ - **For everything outside the JavaScript tree**, such as your TLS terminator,
190
+ your database driver, the certificate on your load balancer and the firmware
191
+ in your HSM, merge the CBOM with a scan of those hosts, certificates and key
192
+ stores
152
193
 
153
- There may be nothing to upgrade to. That is the ordinary case rather than the
154
- exception, and it is why a scan is the start of the work: for a great many
155
- libraries the post-quantum replacement has not been written, and somebody
156
- upstream has to write it.
194
+ ## What to do with a finding
157
195
 
158
- Where you have to build the replacement yourself, the primitives are in
196
+ A finding is where the migration starts. Where the upstream library ships a
197
+ post-quantum release, move to it. Where you are building the replacement
198
+ yourself, the primitives are in
159
199
  [`kxco-post-quantum`](https://www.npmjs.com/package/kxco-post-quantum):
160
200
  ML-KEM-768/1024, ML-DSA-65/87 and SLH-DSA-SHA2-192s, on the OpenSSL 3.5
161
201
  primitives where the runtime provides them.
@@ -172,15 +212,55 @@ primitives where the runtime provides them.
172
212
  Classification is a curated list, not a guess from the package name, because
173
213
  the name carries no signal: `@noble/curves` is elliptic-curve and breaks,
174
214
  `@noble/ciphers` is AES and does not. It is a plain object in
175
- [`src/catalogue.js`](./src/catalogue.js) — read it, disagree with it, open a
215
+ [`src/catalogue.js`](./src/catalogue.js): read it, disagree with it, open a
176
216
  pull request.
177
217
 
178
- Missing a package you depend on? That is a bug worth reporting.
218
+ To add a package you depend on, open an issue or a pull request.
219
+
220
+ ## The KXCO post-quantum family
221
+
222
+ This finds the classical cryptography in a tree. The rest of the family
223
+ replaces it:
224
+
225
+ | You need to | Install |
226
+ |---|---|
227
+ | Put the whole stack in one install | [`kxco-pq`](https://www.npmjs.com/package/kxco-pq) |
228
+ | Use ML-DSA, ML-KEM and SLH-DSA directly | [`kxco-post-quantum`](https://www.npmjs.com/package/kxco-post-quantum) |
229
+ | Keep signing keys on the HSM you already run | [`kxco-pq-hsm`](https://www.npmjs.com/package/kxco-pq-hsm) |
230
+ | Sign a document or record anyone can verify offline | [`kxco-pq-attest`](https://www.npmjs.com/package/kxco-pq-attest) |
231
+ | Keep a tamper-evident audit trail | [`kxco-pq-audit`](https://www.npmjs.com/package/kxco-pq-audit) |
232
+ | Verify a signature in a browser, with no server | [`kxco-verify`](https://www.npmjs.com/package/kxco-verify) |
233
+ | Issue institution identity credentials | [`kxco-pq-sdk`](https://www.npmjs.com/package/kxco-pq-sdk) |
234
+ | Encrypt files and payloads to one or many recipients | [`kxco-pq-vault`](https://www.npmjs.com/package/kxco-pq-vault) |
235
+ | Encrypt Node streams and WebSockets | [`kxco-pq-tls`](https://www.npmjs.com/package/kxco-pq-tls) |
236
+ | Sign and verify webhooks | [`kxco-post-quantum-webhook`](https://www.npmjs.com/package/kxco-post-quantum-webhook) |
237
+ | Give an AI agent an identity a verified institution sponsors | [`kxco-pq-agent`](https://www.npmjs.com/package/kxco-pq-agent) |
238
+ | Have Armature L1 verify a signature in consensus | [`kxco-pq-chain`](https://www.npmjs.com/package/kxco-pq-chain) |
239
+ | Prove an envelope at three levels, offline to on-chain | [`kxco-pq-network`](https://www.npmjs.com/package/kxco-pq-network) |
240
+ | Generate and rotate keys from a terminal | [`kxco-pq-cli`](https://www.npmjs.com/package/kxco-pq-cli) |
241
+ | Find quantum-vulnerable cryptography in a dependency tree | [`kxco-pq-scan`](https://www.npmjs.com/package/kxco-pq-scan) |
242
+ | Fail the build when code reaches past the wrapper | [`eslint-plugin-kxco-pq`](https://www.npmjs.com/package/eslint-plugin-kxco-pq) |
243
+
244
+ ## Release integrity
245
+
246
+ Each release carries a SLSA provenance attestation tying the published tarball to
247
+ the commit and workflow that built it: verify with `npm audit signatures`, or read
248
+ it from `registry.npmjs.org/-/npm/v1/attestations/kxco-pq-scan@<version>`. The
249
+ package has no runtime dependencies, so there is no transitive tree to audit, and
250
+ `npm run evidence` regenerates identity, the test run, the SBOM and registry
251
+ signature verification from source.
252
+
253
+ ## Security
254
+
255
+ The scanner reads the files in the directory it is pointed at and writes a
256
+ report: no network, no state and no runtime dependencies.
257
+
258
+ To report a vulnerability, open a [private security advisory](https://github.com/KnightsbridgeAIQ/kxco-pq-scan/security/advisories/new) or email **security@kxco.ai**.
179
259
 
180
260
  ## License
181
261
 
182
- Apache-2.0 © 2026 KXCO by Knightsbridge
262
+ Apache-2.0 © 2026 Knightsbridge Financial Ltd, trading as KXCO. See [LICENSE](./LICENSE) and [NOTICE](./NOTICE).
183
263
 
184
264
  ## Maintainers
185
265
 
186
- Shayne Heffernan · John Heffernan — [KXCO by Knightsbridge](https://kxco.ai)
266
+ Shayne Heffernan · John Heffernan, [KXCO by Knightsbridge](https://kxco.ai)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kxco-pq-scan",
3
- "version": "1.1.1",
4
- "description": "Find quantum-vulnerable cryptography in a JavaScript dependency tree. Separates what Shor's algorithm breaks from what Grover's only weakens, recognises hybrid constructions, and says what it cannot see.",
3
+ "version": "1.2.0",
4
+ "description": "Find quantum-vulnerable cryptography in a JavaScript dependency tree in seconds and emit a CycloneDX 1.6 CBOM. Separates what Shor's algorithm breaks from what Grover's only weakens, recognises hybrid constructions, and names who pulled each finding in.",
5
5
  "keywords": [
6
6
  "post-quantum",
7
7
  "pqc",
@@ -18,7 +18,14 @@
18
18
  "cyclonedx",
19
19
  "crypto-inventory",
20
20
  "quantum-readiness",
21
- "cryptographic-bill-of-materials"
21
+ "cryptographic-bill-of-materials",
22
+ "pqc-migration",
23
+ "crypto-agility",
24
+ "cryptographic-inventory",
25
+ "dependency-scanner",
26
+ "security-scanner",
27
+ "lockfile",
28
+ "shor"
22
29
  ],
23
30
  "type": "module",
24
31
  "exports": {
@@ -35,10 +42,11 @@
35
42
  "bin",
36
43
  "README.md",
37
44
  "LICENSE",
45
+ "NOTICE",
38
46
  "ASSESSMENT.md"
39
47
  ],
40
48
  "scripts": {
41
- "test": "node --test test/scan.test.js test/cbom.test.js test/cbom.schema.test.js",
49
+ "test": "node --test test/scan.test.js test/cbom.test.js test/cbom.schema.test.js test/property.test.js",
42
50
  "evidence": "node scripts/build-evidence.mjs"
43
51
  },
44
52
  "engines": {
@@ -57,6 +65,7 @@
57
65
  },
58
66
  "devDependencies": {
59
67
  "ajv": "^8.20.0",
60
- "ajv-formats": "^3.0.1"
68
+ "ajv-formats": "^3.0.1",
69
+ "fast-check": "4.10.2"
61
70
  }
62
71
  }
package/src/catalogue.js CHANGED
@@ -66,7 +66,7 @@ export const CATALOGUE = {
66
66
  note: 'X25519 is the classical half of a deliberate hybrid' },
67
67
  'kxco-pq-attest': { classes: ['pq'], algorithms: ['ML-DSA-65'] },
68
68
  'kxco-pq-hsm': { classes: ['pq'], algorithms: ['ML-DSA-65', 'ML-KEM-768'] },
69
- 'kxco-pq-sdk': { classes: ['pq'], algorithms: ['ML-DSA-65', 'ML-KEM-768'] },
69
+ 'kxco-pq-sdk': { classes: ['pq'], algorithms: ['ML-DSA-65', 'ML-DSA-87', 'ML-KEM-768', 'ML-KEM-1024'] },
70
70
  'liboqs-node': { classes: ['pq'], algorithms: ['ML-KEM', 'ML-DSA'] },
71
71
  'pqclean': { classes: ['pq'], algorithms: ['ML-KEM', 'ML-DSA'] },
72
72
  }
package/src/cbom.js CHANGED
@@ -107,22 +107,46 @@ const ALGORITHMS = {
107
107
  // FIPS 203, 204 and 205. The OIDs are the NIST CSOR registrations and are
108
108
  // asserted only where the parameter set is named, because the OID is per
109
109
  // parameter set: there is no OID for "ML-KEM" in the abstract.
110
+ //
111
+ // id-alg-ml-kem-512/768/1024 are { kems 1, 2, 3 } and id-ml-dsa-44/65/87 are
112
+ // { sigAlgs 17, 18, 19 }, under nistAlgorithms 2.16.840.1.101.3.4. The NIST
113
+ // security category is the one FIPS 203 and FIPS 204 assign each set.
110
114
  'ML-KEM': {
111
115
  primitive: 'kem', cryptoFunctions: ['keygen', 'encapsulate', 'decapsulate'],
112
116
  },
117
+ 'ML-KEM-512': {
118
+ primitive: 'kem', cryptoFunctions: ['keygen', 'encapsulate', 'decapsulate'],
119
+ parameterSetIdentifier: '512', oid: '2.16.840.1.101.3.4.4.1',
120
+ nistQuantumSecurityLevel: 1,
121
+ },
113
122
  'ML-KEM-768': {
114
123
  primitive: 'kem', cryptoFunctions: ['keygen', 'encapsulate', 'decapsulate'],
115
124
  parameterSetIdentifier: '768', oid: '2.16.840.1.101.3.4.4.2',
116
125
  nistQuantumSecurityLevel: 3,
117
126
  },
127
+ 'ML-KEM-1024': {
128
+ primitive: 'kem', cryptoFunctions: ['keygen', 'encapsulate', 'decapsulate'],
129
+ parameterSetIdentifier: '1024', oid: '2.16.840.1.101.3.4.4.3',
130
+ nistQuantumSecurityLevel: 5,
131
+ },
118
132
  'ML-DSA': {
119
133
  primitive: 'signature', cryptoFunctions: ['keygen', 'sign', 'verify'],
120
134
  },
135
+ 'ML-DSA-44': {
136
+ primitive: 'signature', cryptoFunctions: ['keygen', 'sign', 'verify'],
137
+ parameterSetIdentifier: '44', oid: '2.16.840.1.101.3.4.3.17',
138
+ nistQuantumSecurityLevel: 2,
139
+ },
121
140
  'ML-DSA-65': {
122
141
  primitive: 'signature', cryptoFunctions: ['keygen', 'sign', 'verify'],
123
142
  parameterSetIdentifier: '65', oid: '2.16.840.1.101.3.4.3.18',
124
143
  nistQuantumSecurityLevel: 3,
125
144
  },
145
+ 'ML-DSA-87': {
146
+ primitive: 'signature', cryptoFunctions: ['keygen', 'sign', 'verify'],
147
+ parameterSetIdentifier: '87', oid: '2.16.840.1.101.3.4.3.19',
148
+ nistQuantumSecurityLevel: 5,
149
+ },
126
150
  'SLH-DSA': {
127
151
  primitive: 'signature', cryptoFunctions: ['keygen', 'sign', 'verify'],
128
152
  },