kxco-pq-attest 1.0.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/LICENSE +34 -0
- package/package.json +46 -0
- package/src/attest.js +79 -0
- package/src/errors.js +3 -0
- package/src/index.js +2 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction, and distribution.
|
|
10
|
+
"Licensor" shall mean KXCO by Knightsbridge.
|
|
11
|
+
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity.
|
|
12
|
+
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
|
13
|
+
"Source" form shall mean the preferred form for making modifications.
|
|
14
|
+
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form.
|
|
15
|
+
"Work" shall mean the work of authorship made available under the License.
|
|
16
|
+
"Derivative Works" shall mean any work that is based on the Work.
|
|
17
|
+
"Contribution" shall mean any work of authorship submitted to the Licensor for inclusion in the Work.
|
|
18
|
+
"Contributor" shall mean Licensor and any Legal Entity on behalf of whom a Contribution has been received by the Licensor and incorporated within the Work.
|
|
19
|
+
|
|
20
|
+
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
|
21
|
+
|
|
22
|
+
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work.
|
|
23
|
+
|
|
24
|
+
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work; and (d) If the Work includes a "NOTICE" text file, You must include a readable copy of the attribution notices contained within such NOTICE file.
|
|
25
|
+
|
|
26
|
+
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions.
|
|
27
|
+
|
|
28
|
+
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor.
|
|
29
|
+
|
|
30
|
+
7. Disclaimer of Warranty. THE WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
|
|
31
|
+
|
|
32
|
+
8. Limitation of Liability. IN NO EVENT SHALL ANY CONTRIBUTOR BE LIABLE FOR ANY DAMAGES ARISING FROM THIS LICENSE OR THE USE OF THE WORK.
|
|
33
|
+
|
|
34
|
+
Copyright 2026 KXCO by Knightsbridge
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "kxco-pq-attest",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Post-quantum attestations: sign arbitrary payloads with ML-DSA-65 (NIST FIPS 204). Produces a self-contained JSON envelope any counterparty can verify without trust delegation. Works in Node.js and Cloudflare Workers.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"post-quantum",
|
|
7
|
+
"pqc",
|
|
8
|
+
"ml-dsa",
|
|
9
|
+
"attestation",
|
|
10
|
+
"nist",
|
|
11
|
+
"fips-204",
|
|
12
|
+
"cloudflare-workers",
|
|
13
|
+
"kxco"
|
|
14
|
+
],
|
|
15
|
+
"license": "Apache-2.0",
|
|
16
|
+
"author": "KXCO by Knightsbridge <hello@kxco.ai>",
|
|
17
|
+
"homepage": "https://kxco.ai",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/JackKXCO/kxco-pq-attest.git"
|
|
21
|
+
},
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/JackKXCO/kxco-pq-attest/issues"
|
|
24
|
+
},
|
|
25
|
+
"type": "module",
|
|
26
|
+
"main": "src/index.js",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": "./src/index.js"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"src",
|
|
32
|
+
"LICENSE"
|
|
33
|
+
],
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=20.19"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"kxco-post-quantum": "^1.1.6"
|
|
39
|
+
},
|
|
40
|
+
"scripts": {
|
|
41
|
+
"test": "node --test --test-timeout=30000 test/attest.test.js"
|
|
42
|
+
},
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "public"
|
|
45
|
+
}
|
|
46
|
+
}
|
package/src/attest.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { mlDsa, fingerprint } from 'kxco-post-quantum'
|
|
2
|
+
|
|
3
|
+
const VERSION = '1'
|
|
4
|
+
|
|
5
|
+
function b64url(bytes) {
|
|
6
|
+
return Buffer.from(bytes).toString('base64url')
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function fromB64url(str) {
|
|
10
|
+
return new Uint8Array(Buffer.from(str, 'base64url'))
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function signingMsg(payloadB64, kid, issuedAt) {
|
|
14
|
+
const enc = new TextEncoder()
|
|
15
|
+
const parts = [
|
|
16
|
+
enc.encode('kxco-attest-v1\n'),
|
|
17
|
+
enc.encode(payloadB64),
|
|
18
|
+
enc.encode('\n'),
|
|
19
|
+
enc.encode(kid),
|
|
20
|
+
enc.encode('\n'),
|
|
21
|
+
enc.encode(issuedAt),
|
|
22
|
+
]
|
|
23
|
+
const len = parts.reduce((n, a) => n + a.length, 0)
|
|
24
|
+
const msg = new Uint8Array(len)
|
|
25
|
+
let off = 0
|
|
26
|
+
for (const p of parts) { msg.set(p, off); off += p.length }
|
|
27
|
+
return msg
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function attest(payload, keypair) {
|
|
31
|
+
const payloadBytes = typeof payload === 'string'
|
|
32
|
+
? new TextEncoder().encode(payload)
|
|
33
|
+
: new Uint8Array(payload)
|
|
34
|
+
|
|
35
|
+
const payloadB64 = b64url(payloadBytes)
|
|
36
|
+
const kid = fingerprint(keypair.publicKey)
|
|
37
|
+
const issuedAt = new Date().toISOString()
|
|
38
|
+
const msg = signingMsg(payloadB64, kid, issuedAt)
|
|
39
|
+
const sig = mlDsa.ml_dsa65.sign(new Uint8Array(keypair.secretKey), msg)
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
'kxco-attest': VERSION,
|
|
43
|
+
payload: payloadB64,
|
|
44
|
+
kid,
|
|
45
|
+
issuedAt,
|
|
46
|
+
signature: b64url(sig),
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function verify(envelope, publicKey) {
|
|
51
|
+
if (!envelope || typeof envelope !== 'object') {
|
|
52
|
+
return { valid: false, error: 'malformed envelope' }
|
|
53
|
+
}
|
|
54
|
+
if (envelope['kxco-attest'] !== VERSION) {
|
|
55
|
+
return { valid: false, error: 'unsupported version' }
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const { payload: payloadB64, kid, issuedAt, signature } = envelope
|
|
59
|
+
if (!payloadB64 || !kid || !issuedAt || !signature) {
|
|
60
|
+
return { valid: false, error: 'malformed envelope' }
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const msg = signingMsg(payloadB64, kid, issuedAt)
|
|
64
|
+
let ok
|
|
65
|
+
try {
|
|
66
|
+
ok = mlDsa.ml_dsa65.verify(new Uint8Array(publicKey), msg, fromB64url(signature))
|
|
67
|
+
} catch {
|
|
68
|
+
ok = false
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (!ok) return { valid: false, error: 'signature invalid' }
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
valid: true,
|
|
75
|
+
payload: fromB64url(payloadB64),
|
|
76
|
+
signerKid: kid,
|
|
77
|
+
issuedAt,
|
|
78
|
+
}
|
|
79
|
+
}
|
package/src/errors.js
ADDED
package/src/index.js
ADDED