kxco-pq-attest 2.0.1 → 2.0.2

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 ADDED
@@ -0,0 +1,126 @@
1
+ # Assessment notes
2
+
3
+ Where this package's boundary falls, what agility it has, and what constrains
4
+ its lifecycle.
5
+
6
+ Algorithm conformance belongs to
7
+ [`kxco-post-quantum`](https://www.npmjs.com/package/kxco-post-quantum) and is
8
+ published in that package's evidence bundle. It is referenced here, never
9
+ restated.
10
+
11
+ ## Boundary
12
+
13
+ **What the assessed thing is.** A library that wraps a payload in a
14
+ self-contained JSON envelope carrying an ML-DSA-65 signature, the signer's key
15
+ fingerprint, an issue time and, optionally, a chain anchor.
16
+
17
+ **Operate: verification makes no network calls, and that is the product.**
18
+ `verify(envelope, publicKey)` returns synchronously from the JSON alone. A
19
+ counterparty holding the envelope and the public key needs nothing from KXCO,
20
+ no endpoint, no account and no cooperation. Anything that made verification
21
+ depend on us would undo the reason to use this.
22
+
23
+ The corollary is that trust in the key is entirely outside this package.
24
+ `verify` tells you the envelope was signed by the holder of the key you passed
25
+ in. It cannot tell you that key belongs to who you think, and it does not try.
26
+ [`kxco-pq-network`](https://www.npmjs.com/package/kxco-pq-network) is the
27
+ package that answers key identity, in three explicit levels; this one answers
28
+ one question and answers it offline.
29
+
30
+ **Signing binds every field, by construction.** The signed message is
31
+ `kxco-attest-v1\n<payloadB64>\n<kid>\n<issuedAt>`, a deterministic
32
+ concatenation with a version prefix. No field can be reordered, and an envelope
33
+ cannot be replayed against a different timestamp without invalidating the
34
+ signature.
35
+
36
+ **`issuedAt` is the signer's clock.** It is signed, so it cannot be altered
37
+ after the fact, and a signed clock is still the signer's clock. A signer who
38
+ sets their system time back produces a valid envelope with an earlier time.
39
+ Where the time matters, the independent bound is `chainAnchor`, which is
40
+ present only when the envelope was anchored, and the anchor is what a verifier
41
+ should be reading rather than the field.
42
+
43
+ **Start and update.** No release signing of its own. Published through CI with
44
+ npm provenance.
45
+
46
+ **Protect records.** Not this package's role: an envelope travels, it is not a
47
+ log. [`kxco-pq-audit`](https://www.npmjs.com/package/kxco-pq-audit) is the
48
+ append-only record.
49
+
50
+ **Retain history, and this package is better placed than its siblings.** The
51
+ envelope carries a `kid`, so a verifier holding several keys can select the
52
+ right one, which is what makes an envelope signed under a since-rotated key
53
+ still verifiable. `kxco-pq-audit` has no equivalent and cannot do this.
54
+
55
+ What is still missing is validity: nothing here records whether the key was
56
+ trusted at `issuedAt`, and there is no revocation. So an envelope signed by a
57
+ key that was later compromised verifies exactly as cleanly as one that was not.
58
+ For long-lived attestations the anchor is the thing that pins the signature to a
59
+ point in time, and the key-status question at that point in time is not
60
+ answered anywhere in this stack.
61
+
62
+ ## Agility
63
+
64
+ **Inherited.** Parameter sets and backends belong to `kxco-post-quantum`. See
65
+ that package's `AGILITY.md`.
66
+
67
+ **The addition: a version prefix inside the signed bytes.** `kxco-attest-v1`
68
+ is signed, not merely written alongside. A v2 envelope format is therefore
69
+ distinguishable from v1 by something an attacker cannot strip, which is the
70
+ property a format migration needs and the reason the prefix is inside the
71
+ signature rather than beside it.
72
+
73
+ **The limit: the algorithm is not named in the envelope.** The format carries
74
+ `kid` and a signature, and no algorithm identifier. A verifier resolves the
75
+ algorithm by knowing it is ML-DSA-65, not by reading it. Compare
76
+ `kxco-pq-vault`, whose header carries an explicit `algorithm:` line, and
77
+ `kxco-pq-tls`, whose frame sizes make the algorithm unambiguous on the wire.
78
+
79
+ That is workable while exactly one algorithm exists, and it is the field a
80
+ second one would need. Adding it later means a v2 format, which the version
81
+ prefix already allows for; the point is that the move is a release of this
82
+ package rather than a configuration.
83
+
84
+ ## Lifecycle
85
+
86
+ **Assess `origin/main`, and know that this working tree is ahead of it.**
87
+ Verified 8 September 2026: `origin/main`, this checkout and npm all read 2.0.1,
88
+ so the published artefact does correspond to `origin/main`.
89
+
90
+ What differs is the local working branch. `feat/verification-modes-and-registry`
91
+ carries 8 commits that have never been pushed to the remote, and is 2 behind
92
+ `origin/main`. The same pattern holds in `kxco-pq-sdk`, `kxco-pq-cli` and
93
+ `kxco-pq`. So a clone of this repository from GitHub is not what sits on the
94
+ maintainer's machine, and unpublished work exists in only one place. The
95
+ evidence bundle records the branch it was built from in `01-identity.json`,
96
+ which is why that field is there.
97
+
98
+ **Supported versions.** One line moving forward, matching the family. This
99
+ package is at 2.x while much of the family is at 1.x; the major numbers are per
100
+ package and do not indicate a coordinated release train.
101
+
102
+ **Pins.** `kxco-post-quantum` is declared `^1.6.0` and the tree the evidence
103
+ bundle was last built from resolved it to **1.6.0**, against a current
104
+ primitives release of 1.7.2. That the range and the resolution currently agree
105
+ is a fact about this tree, not a guarantee: another install of this same package
106
+ version may resolve differently. `02-primitives.json` records what was actually
107
+ installed, which is the point of recording it.
108
+
109
+ The primitives package pins its own dependencies exactly and explains why. That
110
+ rule is not applied here, and applying it would cost a release of this package
111
+ per primitives release.
112
+
113
+ **Ceiling.** No hardware ceiling. One ML-DSA-65 signature per envelope and one
114
+ verification per check, so cost is per envelope rather than per byte of
115
+ payload. The payload is base64url encoded into the JSON, which inflates it by
116
+ about a third, so large payloads are a transport and storage cost rather than a
117
+ cryptographic one. Attest a digest instead where that matters.
118
+
119
+ **Roadmap.** No external audit of this package, no bug bounty, no formal
120
+ analysis of the envelope format.
121
+
122
+ ## Correcting this document
123
+
124
+ Every claim here is checkable against `src/` and the envelope format in the
125
+ README. If one does not match, that is a defect worth reporting through the
126
+ repository's issues.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.0.2
4
+
5
+ Documentation and a dependency refresh. No source change.
6
+
7
+ **ASSESSMENT.md.** Where this package's boundary falls, what cryptographic
8
+ agility it has beyond what the primitives provide, and what constrains its
9
+ lifecycle. It references the `kxco-post-quantum` evidence rather than restating
10
+ it, because a second copy of a conformance claim invites the reader to count it
11
+ twice.
12
+
13
+ **`npm run evidence` now exists.** The README already told you to run it and
14
+ there was no such script, so the command failed for anyone who followed it.
15
+ The bundle records identity, this package's own tests, its SBOM, registry
16
+ signature verification, and the `kxco-post-quantum` version actually installed
17
+ rather than the range declared.
18
+
19
+ **`kxco-post-quantum` refreshed to 1.7.2**, from 1.6.0 in the previous
20
+ lockfile. Within the existing range, so no declared dependency changed. Tests
21
+ pass unchanged.
22
+
3
23
  ## 2.0.0
4
24
 
5
25
  **Version 1 envelopes still verify. That is not going to change.** An archive
package/README.md CHANGED
@@ -30,7 +30,7 @@ Every release of this package is checkable without asking us for anything.
30
30
  Every GitHub Action is pinned by 40-character commit SHA.
31
31
  - **Conformance underneath.** The cryptography comes from
32
32
  [`kxco-post-quantum`](https://www.npmjs.com/package/kxco-post-quantum), which
33
- is run against **2,103 NIST ACVP vectors (0 failed)** and a **225-check
33
+ is run against **2,103 NIST ACVP vectors: 1,793 passed, 0 failed, 310 skipped** and a **225-check
34
34
  cross-implementation interoperability matrix** against liboqs, Bouncy Castle
35
35
  and two pure-Python implementations, in both directions and with negative
36
36
  controls. Its published tarball also rebuilds bit-for-bit from its own tag,
@@ -165,8 +165,8 @@ a key exchange, offline, years later.
165
165
 
166
166
  Evidenced, and reproducible on your own machine:
167
167
 
168
- - **2,103 NIST ACVP vectors** across FIPS 203, 204 and 205, pinned by digest
169
- - **225 interoperability checks** against OpenSSL 3.5, liboqs, Bouncy Castle and dilithium-py/kyber-py, in both directions
168
+ - **2,103 NIST ACVP vectors** across FIPS 203, 204 and 205, pinned by digest: 1,793 passed, 0 failed, 310 skipped, where each skip is the library refusing a pre-hash weaker than the parameter set
169
+ - **225 interoperability checks passed, 0 failed, 42 not applicable** against OpenSSL 3.5, liboqs, Bouncy Castle and dilithium-py/kyber-py, in both directions
170
170
  - **SLSA provenance** on every published release — verify with `npm audit signatures`
171
171
  - **CycloneDX SBOM** published with each release
172
172
  - `npm run evidence` regenerates the whole bundle from source
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kxco-pq-attest",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "description": "Post-quantum document signing and on-chain attestation. ML-DSA-65 (FIPS 204) over any payload, producing a self-contained JSON envelope a counterparty verifies offline. Anchor it on Armature L1 for a timestamped record the chain itself has verified.",
5
5
  "keywords": [
6
6
  "post-quantum",
@@ -52,7 +52,8 @@
52
52
  "CHANGELOG.md",
53
53
  "LICENSE",
54
54
  "README.md",
55
- "src"
55
+ "src",
56
+ "ASSESSMENT.md"
56
57
  ],
57
58
  "engines": {
58
59
  "node": ">=20.19"
@@ -62,7 +63,8 @@
62
63
  "kxco-pq-network": "^1.0.0"
63
64
  },
64
65
  "scripts": {
65
- "test": "node --test --test-timeout=30000 test/attest.test.js test/envelope-v2.test.js"
66
+ "test": "node --test --test-timeout=30000 test/attest.test.js test/envelope-v2.test.js",
67
+ "evidence": "node scripts/build-evidence.mjs"
66
68
  },
67
69
  "funding": "https://kxco.ai",
68
70
  "publishConfig": {