aqta-verify-receipt 1.2.0 → 1.2.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/README.md +30 -2
- package/dist/action.test.d.ts +10 -0
- package/dist/action.test.d.ts.map +1 -0
- package/dist/action.test.js +101 -0
- package/dist/action.test.js.map +1 -0
- package/dist/envelope.test.d.ts +9 -0
- package/dist/envelope.test.d.ts.map +1 -0
- package/dist/envelope.test.js +110 -0
- package/dist/envelope.test.js.map +1 -0
- package/dist/index.test.d.ts +6 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +161 -0
- package/dist/index.test.js.map +1 -0
- package/dist/transparency.d.ts +52 -0
- package/dist/transparency.d.ts.map +1 -0
- package/dist/transparency.js +273 -0
- package/dist/transparency.js.map +1 -0
- package/dist/verify-proof.d.ts +3 -0
- package/dist/verify-proof.d.ts.map +1 -0
- package/dist/verify-proof.js.map +1 -0
- package/package.json +2 -9
package/README.md
CHANGED
|
@@ -135,13 +135,41 @@ Default: `https://app.aqta.ai/security/pubkey.txt`. Same material as
|
|
|
135
135
|
|
|
136
136
|
## Test vectors
|
|
137
137
|
|
|
138
|
-
Conformance suite
|
|
138
|
+
Conformance suite, covering receipts, agent action records and transparency proofs:
|
|
139
139
|
[`test-vectors/`](https://github.com/Aqta-ai/attestation-spec/tree/main/test-vectors).
|
|
140
140
|
|
|
141
|
+
## Transparency proofs
|
|
142
|
+
|
|
143
|
+
A receipt signature answers what the issuer asserted. It cannot answer whether
|
|
144
|
+
that entry is in the issuer's log, or whether the log has only ever grown.
|
|
145
|
+
Those are different questions, so they get a different command.
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
npx -p aqta-verify-receipt aqta-verify-proof inclusion.json
|
|
149
|
+
npx -p aqta-verify-receipt aqta-verify-proof consistency.json
|
|
150
|
+
npx -p aqta-verify-receipt aqta-verify-proof sth.json --key <pinned>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
RFC 6962 inclusion and consistency verification, plus the signed-tree-head
|
|
154
|
+
signature. Written separately in TypeScript and Python rather than ported, and
|
|
155
|
+
checked against the transparency vectors in the repository. Adds no dependency:
|
|
156
|
+
hashing uses the runtime.
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
import { verifyInclusionProof, verifyConsistencyProof } from 'aqta-verify-receipt';
|
|
160
|
+
|
|
161
|
+
const result = verifyInclusionProof(proof);
|
|
162
|
+
if (!result.valid) throw new Error(result.reason);
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
An inclusion proof establishes that what you were shown is genuinely in the
|
|
166
|
+
log. It does not establish that what you were **not** shown is irrelevant.
|
|
167
|
+
That is omission, and it is open.
|
|
168
|
+
|
|
141
169
|
## What this is not
|
|
142
170
|
|
|
143
171
|
Not a governance dashboard. Not a cost router. Not a chain explorer.
|
|
144
|
-
A small verifier for
|
|
172
|
+
A small verifier for signed decision records and the log proofs that accompany them. The novel part is the
|
|
145
173
|
receipt format and offline verification model, not ASCII theatre.
|
|
146
174
|
|
|
147
175
|
## Security
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ACTION-v1 profile conformance tests.
|
|
3
|
+
*
|
|
4
|
+
* The vectors under test-vectors/action/ are the cross-language contract:
|
|
5
|
+
* the Python verifier's suite checks the same bytes, and the two
|
|
6
|
+
* implementations must return the same verdict (and the same reason) on
|
|
7
|
+
* every one. Run: `npm run build && node --test dist/action.test.js`.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=action.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action.test.d.ts","sourceRoot":"","sources":["../src/action.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ACTION-v1 profile conformance tests.
|
|
4
|
+
*
|
|
5
|
+
* The vectors under test-vectors/action/ are the cross-language contract:
|
|
6
|
+
* the Python verifier's suite checks the same bytes, and the two
|
|
7
|
+
* implementations must return the same verdict (and the same reason) on
|
|
8
|
+
* every one. Run: `npm run build && node --test dist/action.test.js`.
|
|
9
|
+
*/
|
|
10
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
11
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
const node_test_1 = require("node:test");
|
|
15
|
+
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
16
|
+
const node_fs_1 = require("node:fs");
|
|
17
|
+
const node_path_1 = require("node:path");
|
|
18
|
+
const index_js_1 = require("./index.js");
|
|
19
|
+
/** Pinned issuer key for the action vector suite (test-vectors/action/README.md). */
|
|
20
|
+
const ACTION_VECTOR_KEY = 'pOaccW6Csyo1POtxjixPH80oux9--YC1tzzaENT4vQ0';
|
|
21
|
+
const ACTION_VECTOR_DIR = (0, node_path_1.join)(__dirname, '..', '..', '..', 'test-vectors', 'action');
|
|
22
|
+
function loadVectors(kind) {
|
|
23
|
+
const dir = (0, node_path_1.join)(ACTION_VECTOR_DIR, kind);
|
|
24
|
+
return (0, node_fs_1.readdirSync)(dir)
|
|
25
|
+
.filter((f) => f.endsWith('.json'))
|
|
26
|
+
.sort()
|
|
27
|
+
.map((f) => [f, JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(dir, f), 'utf8'))]);
|
|
28
|
+
}
|
|
29
|
+
(0, node_test_1.test)('every valid action vector verifies under the pinned vector key', () => {
|
|
30
|
+
const vectors = loadVectors('valid');
|
|
31
|
+
strict_1.default.equal(vectors.length, 10, 'expected 10 valid action vectors');
|
|
32
|
+
for (const [name, record] of vectors) {
|
|
33
|
+
const result = (0, index_js_1.verifyReceipt)(record, {
|
|
34
|
+
trustedPublicKey: ACTION_VECTOR_KEY,
|
|
35
|
+
profile: 'ACTION-v1',
|
|
36
|
+
});
|
|
37
|
+
strict_1.default.equal(result.valid, true, `${name} must verify (${result.reason ?? 'no reason'})`);
|
|
38
|
+
strict_1.default.equal(result.envelope, 'ACTION-v1', `${name} must report the ACTION-v1 profile`);
|
|
39
|
+
strict_1.default.equal(result.keySource, 'pinned', `${name} must report a pinned key`);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
(0, node_test_1.test)('every invalid action vector is rejected', () => {
|
|
43
|
+
const vectors = loadVectors('invalid');
|
|
44
|
+
strict_1.default.equal(vectors.length, 15, 'expected 15 invalid action vectors');
|
|
45
|
+
for (const [name, record] of vectors) {
|
|
46
|
+
const result = (0, index_js_1.verifyReceipt)(record, {
|
|
47
|
+
trustedPublicKey: ACTION_VECTOR_KEY,
|
|
48
|
+
profile: 'ACTION-v1',
|
|
49
|
+
});
|
|
50
|
+
strict_1.default.equal(result.valid, false, `${name} must be rejected`);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
(0, node_test_1.test)('verifyActionRecord convenience wrapper selects the ACTION-v1 profile', () => {
|
|
54
|
+
const vectors = loadVectors('valid');
|
|
55
|
+
const [name, record] = vectors[0];
|
|
56
|
+
const result = (0, index_js_1.verifyActionRecord)(record, { trustedPublicKey: ACTION_VECTOR_KEY });
|
|
57
|
+
strict_1.default.equal(result.valid, true, `${name} must verify via verifyActionRecord`);
|
|
58
|
+
strict_1.default.equal(result.envelope, 'ACTION-v1');
|
|
59
|
+
strict_1.default.equal(result.keySource, 'pinned');
|
|
60
|
+
});
|
|
61
|
+
(0, node_test_1.test)('profile and envelope are mutually exclusive', () => {
|
|
62
|
+
const [, record] = loadVectors('valid')[0];
|
|
63
|
+
const result = (0, index_js_1.verifyReceipt)(record, {
|
|
64
|
+
trustedPublicKey: ACTION_VECTOR_KEY,
|
|
65
|
+
profile: 'ACTION-v1',
|
|
66
|
+
envelope: 'anchor-v1',
|
|
67
|
+
});
|
|
68
|
+
strict_1.default.equal(result.valid, false);
|
|
69
|
+
strict_1.default.equal(result.reason, 'profile and envelope are mutually exclusive');
|
|
70
|
+
});
|
|
71
|
+
(0, node_test_1.test)('ACTION-v1 cannot be named as a foreign envelope', () => {
|
|
72
|
+
// The foreign-envelope path is signature-only. Routing an action record
|
|
73
|
+
// through it would skip every structural and semantic rule, which is the
|
|
74
|
+
// bypass ACTION-v1 §7 exists to close.
|
|
75
|
+
const [, record] = loadVectors('valid')[0];
|
|
76
|
+
const result = (0, index_js_1.verifyReceipt)(record, {
|
|
77
|
+
trustedPublicKey: ACTION_VECTOR_KEY,
|
|
78
|
+
envelope: 'ACTION-v1',
|
|
79
|
+
});
|
|
80
|
+
strict_1.default.equal(result.valid, false);
|
|
81
|
+
strict_1.default.equal(result.reason, 'ACTION-v1 is a profile, not a foreign envelope; use the profile option');
|
|
82
|
+
});
|
|
83
|
+
(0, node_test_1.test)('a genuine ATTESTATION-v1 receipt fails the ACTION-v1 profile', () => {
|
|
84
|
+
// Invalid vector 007 is a complete, correctly signed ATTESTATION-v1
|
|
85
|
+
// receipt. Under the ACTION-v1 profile it must fail: accepting it would
|
|
86
|
+
// mean the verifier profile-sniffs by field shape.
|
|
87
|
+
const file = (0, node_path_1.join)(ACTION_VECTOR_DIR, 'invalid', '007-attestation-v1-receipt.json');
|
|
88
|
+
const receipt = JSON.parse((0, node_fs_1.readFileSync)(file, 'utf8'));
|
|
89
|
+
const asAction = (0, index_js_1.verifyActionRecord)(receipt, { trustedPublicKey: ACTION_VECTOR_KEY });
|
|
90
|
+
strict_1.default.equal(asAction.valid, false);
|
|
91
|
+
strict_1.default.equal(asAction.reason, 'missing required field: action_id');
|
|
92
|
+
// The same bytes remain a valid ATTESTATION-v1 receipt when the profile
|
|
93
|
+
// option is absent and its embedded key is pinned: the record itself is
|
|
94
|
+
// genuine, only the profile claim about it was wrong.
|
|
95
|
+
const asAttestation = (0, index_js_1.verifyReceipt)(receipt, {
|
|
96
|
+
trustedPublicKey: receipt.public_key,
|
|
97
|
+
});
|
|
98
|
+
strict_1.default.equal(asAttestation.valid, true, `007 must verify as ATTESTATION-v1 (${asAttestation.reason ?? 'no reason'})`);
|
|
99
|
+
strict_1.default.equal(asAttestation.envelope, 'ATTESTATION-v1');
|
|
100
|
+
});
|
|
101
|
+
//# sourceMappingURL=action.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action.test.js","sourceRoot":"","sources":["../src/action.test.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;;;AAEH,yCAAiC;AACjC,gEAAwC;AACxC,qCAAoD;AACpD,yCAAiC;AACjC,yCAA+D;AAE/D,qFAAqF;AACrF,MAAM,iBAAiB,GAAG,6CAA6C,CAAC;AACxE,MAAM,iBAAiB,GAAG,IAAA,gBAAI,EAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,CAAC,CAAC;AAEtF,SAAS,WAAW,CAAC,IAAyB;IAC5C,MAAM,GAAG,GAAG,IAAA,gBAAI,EAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC;IAC1C,OAAO,IAAA,qBAAW,EAAC,GAAG,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;SAClC,IAAI,EAAE;SACN,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,IAAA,gBAAI,EAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC;AAED,IAAA,gBAAI,EAAC,gEAAgE,EAAE,GAAG,EAAE;IAC1E,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACrC,gBAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,EAAE,kCAAkC,CAAC,CAAC;IACrE,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,IAAA,wBAAa,EAAC,MAAM,EAAE;YACnC,gBAAgB,EAAE,iBAAiB;YACnC,OAAO,EAAE,WAAW;SACrB,CAAC,CAAC;QACH,gBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,iBAAiB,MAAM,CAAC,MAAM,IAAI,WAAW,GAAG,CAAC,CAAC;QAC1F,gBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,IAAI,oCAAoC,CAAC,CAAC;QACxF,gBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,IAAI,2BAA2B,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,yCAAyC,EAAE,GAAG,EAAE;IACnD,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;IACvC,gBAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,EAAE,oCAAoC,CAAC,CAAC;IACvE,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,IAAA,wBAAa,EAAC,MAAM,EAAE;YACnC,gBAAgB,EAAE,iBAAiB;YACnC,OAAO,EAAE,WAAW;SACrB,CAAC,CAAC;QACH,gBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,IAAI,mBAAmB,CAAC,CAAC;IAChE,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,sEAAsE,EAAE,GAAG,EAAE;IAChF,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,IAAA,6BAAkB,EAAC,MAAM,EAAE,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,CAAC,CAAC;IACnF,gBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,qCAAqC,CAAC,CAAC;IAC/E,gBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAC3C,gBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,6CAA6C,EAAE,GAAG,EAAE;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAA,wBAAa,EAAC,MAAM,EAAE;QACnC,gBAAgB,EAAE,iBAAiB;QACnC,OAAO,EAAE,WAAW;QACpB,QAAQ,EAAE,WAAW;KACtB,CAAC,CAAC;IACH,gBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAClC,gBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,6CAA6C,CAAC,CAAC;AAC7E,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,iDAAiD,EAAE,GAAG,EAAE;IAC3D,wEAAwE;IACxE,yEAAyE;IACzE,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAA,wBAAa,EAAC,MAAM,EAAE;QACnC,gBAAgB,EAAE,iBAAiB;QACnC,QAAQ,EAAE,WAAW;KACtB,CAAC,CAAC;IACH,gBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAClC,gBAAM,CAAC,KAAK,CACV,MAAM,CAAC,MAAM,EACb,wEAAwE,CACzE,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,8DAA8D,EAAE,GAAG,EAAE;IACxE,oEAAoE;IACpE,wEAAwE;IACxE,mDAAmD;IACnD,MAAM,IAAI,GAAG,IAAA,gBAAI,EAAC,iBAAiB,EAAE,SAAS,EAAE,iCAAiC,CAAC,CAAC;IACnF,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,IAAI,EAAE,MAAM,CAAC,CAA4B,CAAC;IAElF,MAAM,QAAQ,GAAG,IAAA,6BAAkB,EAAC,OAAO,EAAE,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,CAAC,CAAC;IACtF,gBAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACpC,gBAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,mCAAmC,CAAC,CAAC;IAEnE,wEAAwE;IACxE,wEAAwE;IACxE,sDAAsD;IACtD,MAAM,aAAa,GAAG,IAAA,wBAAa,EAAC,OAAO,EAAE;QAC3C,gBAAgB,EAAE,OAAO,CAAC,UAAoB;KAC/C,CAAC,CAAC;IACH,gBAAM,CAAC,KAAK,CACV,aAAa,CAAC,KAAK,EACnB,IAAI,EACJ,sCAAsC,aAAa,CAAC,MAAM,IAAI,WAAW,GAAG,CAC7E,CAAC;IACF,gBAAM,CAAC,KAAK,CAAC,aAAa,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;AACzD,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-envelope tests.
|
|
3
|
+
*
|
|
4
|
+
* The claim being defended: an auditor installs one verifier, not one per
|
|
5
|
+
* issuer. These cover envelope detection and the shared signature path for
|
|
6
|
+
* anchor-v1 receipts, which the ATTESTATION-v1 tests do not reach.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=envelope.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envelope.test.d.ts","sourceRoot":"","sources":["../src/envelope.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Multi-envelope tests.
|
|
4
|
+
*
|
|
5
|
+
* The claim being defended: an auditor installs one verifier, not one per
|
|
6
|
+
* issuer. These cover envelope detection and the shared signature path for
|
|
7
|
+
* anchor-v1 receipts, which the ATTESTATION-v1 tests do not reach.
|
|
8
|
+
*/
|
|
9
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
const node_test_1 = require("node:test");
|
|
14
|
+
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
15
|
+
const tweetnacl_1 = __importDefault(require("tweetnacl"));
|
|
16
|
+
const index_js_1 = require("./index.js");
|
|
17
|
+
/** The canonical form both envelopes share: sorted keys, no whitespace. */
|
|
18
|
+
function canonical(v) {
|
|
19
|
+
if (v === null || typeof v !== 'object')
|
|
20
|
+
return JSON.stringify(v);
|
|
21
|
+
if (Array.isArray(v))
|
|
22
|
+
return `[${v.map(canonical).join(',')}]`;
|
|
23
|
+
const e = Object.entries(v)
|
|
24
|
+
.filter(([, x]) => x !== undefined)
|
|
25
|
+
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
|
|
26
|
+
return `{${e.map(([k, x]) => `${JSON.stringify(k)}:${canonical(x)}`).join(',')}}`;
|
|
27
|
+
}
|
|
28
|
+
const b64 = (u) => Buffer.from(u).toString('base64');
|
|
29
|
+
/** Mint a signed anchor-v1 receipt with a throwaway key. */
|
|
30
|
+
function makeAnchor(overrides = {}) {
|
|
31
|
+
const kp = tweetnacl_1.default.sign.keyPair();
|
|
32
|
+
const signed = {
|
|
33
|
+
checked_at: '2026-07-22T21:00:00Z',
|
|
34
|
+
transcript_sha256: 'a'.repeat(64),
|
|
35
|
+
summary_sha256: 'b'.repeat(64),
|
|
36
|
+
bound: 7,
|
|
37
|
+
gaps: 1,
|
|
38
|
+
public_key_b64: b64(kp.publicKey),
|
|
39
|
+
...overrides,
|
|
40
|
+
};
|
|
41
|
+
const sig = tweetnacl_1.default.sign.detached(Buffer.from(canonical(signed), 'utf8'), kp.secretKey);
|
|
42
|
+
return { receipt: { ...signed, signature_b64: b64(sig) }, key: signed.public_key_b64 };
|
|
43
|
+
}
|
|
44
|
+
(0, node_test_1.test)('detectEnvelope identifies ATTESTATION-v1 by its field names', () => {
|
|
45
|
+
strict_1.default.equal((0, index_js_1.detectEnvelope)({ signature: 'x', public_key: 'y' }), 'ATTESTATION-v1');
|
|
46
|
+
});
|
|
47
|
+
(0, node_test_1.test)('detectEnvelope identifies anchor-v1 by its field names', () => {
|
|
48
|
+
strict_1.default.equal((0, index_js_1.detectEnvelope)({ signature_b64: 'x', public_key_b64: 'y' }), 'anchor-v1');
|
|
49
|
+
});
|
|
50
|
+
(0, node_test_1.test)('detectEnvelope returns null rather than guessing', () => {
|
|
51
|
+
strict_1.default.equal((0, index_js_1.detectEnvelope)({ hello: 'world' }), null);
|
|
52
|
+
strict_1.default.equal((0, index_js_1.detectEnvelope)(null), null);
|
|
53
|
+
strict_1.default.equal((0, index_js_1.detectEnvelope)('a string'), null);
|
|
54
|
+
// present but wrong type must not be treated as an envelope
|
|
55
|
+
strict_1.default.equal((0, index_js_1.detectEnvelope)({ signature: 1, public_key: 2 }), null);
|
|
56
|
+
});
|
|
57
|
+
(0, node_test_1.test)('a genuine anchor-v1 receipt verifies against its pinned key', () => {
|
|
58
|
+
const { receipt, key } = makeAnchor();
|
|
59
|
+
const r = (0, index_js_1.verifyReceipt)(receipt, { trustedPublicKey: key, envelope: 'anchor-v1' });
|
|
60
|
+
strict_1.default.equal(r.valid, true);
|
|
61
|
+
strict_1.default.equal(r.envelope, 'anchor-v1');
|
|
62
|
+
strict_1.default.equal(r.keySource, 'pinned');
|
|
63
|
+
});
|
|
64
|
+
(0, node_test_1.test)('altering any signed field breaks an anchor-v1 receipt', () => {
|
|
65
|
+
const { receipt, key } = makeAnchor();
|
|
66
|
+
const r = (0, index_js_1.verifyReceipt)({ ...receipt, bound: 99 }, { trustedPublicKey: key, envelope: 'anchor-v1' });
|
|
67
|
+
strict_1.default.equal(r.valid, false);
|
|
68
|
+
strict_1.default.equal(r.reason, 'signature check failed');
|
|
69
|
+
});
|
|
70
|
+
(0, node_test_1.test)('anchor-v1 will not verify against a key it was not signed with', () => {
|
|
71
|
+
const { receipt } = makeAnchor();
|
|
72
|
+
const other = makeAnchor().key;
|
|
73
|
+
const r = (0, index_js_1.verifyReceipt)(receipt, { trustedPublicKey: other, envelope: 'anchor-v1' });
|
|
74
|
+
strict_1.default.equal(r.valid, false);
|
|
75
|
+
strict_1.default.equal(r.reason, 'public key does not match trusted key');
|
|
76
|
+
});
|
|
77
|
+
(0, node_test_1.test)('anchor-v1 refuses to run without a pinned key', () => {
|
|
78
|
+
const { receipt } = makeAnchor();
|
|
79
|
+
const r = (0, index_js_1.verifyReceipt)(receipt, { envelope: 'anchor-v1' });
|
|
80
|
+
strict_1.default.equal(r.valid, false);
|
|
81
|
+
strict_1.default.match(r.reason ?? '', /trustedPublicKey required/);
|
|
82
|
+
});
|
|
83
|
+
(0, node_test_1.test)('anchor-v1 integrity-only mode reports the key as untrusted', () => {
|
|
84
|
+
const { receipt } = makeAnchor();
|
|
85
|
+
const r = (0, index_js_1.verifyReceipt)(receipt, { allowUntrustedEmbeddedKey: true, envelope: 'anchor-v1' });
|
|
86
|
+
strict_1.default.equal(r.valid, true);
|
|
87
|
+
strict_1.default.equal(r.keySource, 'untrusted');
|
|
88
|
+
});
|
|
89
|
+
(0, node_test_1.test)('non-ASCII in an anchor-v1 field still verifies', () => {
|
|
90
|
+
const { receipt, key } = makeAnchor({ note: 'Größe · héllo · 世界' });
|
|
91
|
+
strict_1.default.equal((0, index_js_1.verifyReceipt)(receipt, { trustedPublicKey: key, envelope: 'anchor-v1' }).valid, true);
|
|
92
|
+
});
|
|
93
|
+
(0, node_test_1.test)('an unrecognised envelope is rejected, not assumed', () => {
|
|
94
|
+
const r = (0, index_js_1.verifyReceipt)({ some: 'object' }, { trustedPublicKey: 'k' });
|
|
95
|
+
strict_1.default.equal(r.valid, false);
|
|
96
|
+
strict_1.default.match(r.reason ?? '', /unrecognised envelope/);
|
|
97
|
+
});
|
|
98
|
+
(0, node_test_1.test)('a foreign envelope needs explicit opt-in', () => {
|
|
99
|
+
// Envelopes were detected purely by field name, so any object naming its
|
|
100
|
+
// fields signature_b64/public_key_b64 skipped every structural and semantic
|
|
101
|
+
// check: an object that was not a receipt at all verified. Exit 0 then
|
|
102
|
+
// answered 'were these bytes signed by that key' rather than 'is this a
|
|
103
|
+
// conformant receipt'.
|
|
104
|
+
const { receipt, key } = makeAnchor();
|
|
105
|
+
const without = (0, index_js_1.verifyReceipt)(receipt, { trustedPublicKey: key });
|
|
106
|
+
strict_1.default.equal(without.valid, false);
|
|
107
|
+
strict_1.default.match(without.reason ?? '', /explicit opt-in/);
|
|
108
|
+
strict_1.default.equal((0, index_js_1.verifyReceipt)(receipt, { trustedPublicKey: key, envelope: 'anchor-v1' }).valid, true);
|
|
109
|
+
});
|
|
110
|
+
//# sourceMappingURL=envelope.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envelope.test.js","sourceRoot":"","sources":["../src/envelope.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Interop tests: verify a receipt produced by the Python reference implementation
|
|
4
|
+
* against this TypeScript verifier. Run: `npm run build && node --test dist/index.test.js`.
|
|
5
|
+
*/
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
const node_test_1 = require("node:test");
|
|
11
|
+
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
12
|
+
const node_fs_1 = require("node:fs");
|
|
13
|
+
const node_path_1 = require("node:path");
|
|
14
|
+
const index_js_1 = require("./index.js");
|
|
15
|
+
/**
|
|
16
|
+
* Fixture receipt shape, used here to exercise the structural checks.
|
|
17
|
+
* Full signature-level interop is covered by the cross-implementation
|
|
18
|
+
* runner at `scripts/make-interop-fixture.mjs`, which generates a receipt
|
|
19
|
+
* with the reference issuer and verifies it with this library.
|
|
20
|
+
*/
|
|
21
|
+
const FIXTURE_RECEIPT = {
|
|
22
|
+
v: 1,
|
|
23
|
+
attestation_id: 'a3f2b1c4-9d87-4e6f-b012-34567890abcd',
|
|
24
|
+
trace_id: 'trace-fixture-v1',
|
|
25
|
+
org_id: 'org-test',
|
|
26
|
+
request_hash: '8f3a7e2b9c4d5f6a1b0c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a',
|
|
27
|
+
model: 'gpt-4o',
|
|
28
|
+
outcome: 'ALLOWED',
|
|
29
|
+
policy_applied: ['budget_guard', 'loop_guard'],
|
|
30
|
+
cost_prevented_eur: 0.0,
|
|
31
|
+
timestamp: '2026-04-23T10:15:30.123456+00:00',
|
|
32
|
+
public_key: '', // populated by make-test-fixture.py
|
|
33
|
+
signature: '', // populated by make-test-fixture.py
|
|
34
|
+
};
|
|
35
|
+
(0, node_test_1.test)('rejects empty object', () => {
|
|
36
|
+
const res = (0, index_js_1.verifyReceipt)({});
|
|
37
|
+
strict_1.default.equal(res.valid, false);
|
|
38
|
+
});
|
|
39
|
+
(0, node_test_1.test)('rejects missing required field', () => {
|
|
40
|
+
const bad = { ...FIXTURE_RECEIPT };
|
|
41
|
+
delete bad.outcome;
|
|
42
|
+
const res = (0, index_js_1.verifyReceipt)(bad);
|
|
43
|
+
strict_1.default.equal(res.valid, false);
|
|
44
|
+
strict_1.default.match(res.reason ?? '', /missing required field/);
|
|
45
|
+
});
|
|
46
|
+
(0, node_test_1.test)('rejects unknown top-level field (strict mode)', () => {
|
|
47
|
+
const bad = { ...FIXTURE_RECEIPT, extra: 'foo' };
|
|
48
|
+
const res = (0, index_js_1.verifyReceipt)(bad, { allowUntrustedEmbeddedKey: true });
|
|
49
|
+
strict_1.default.equal(res.valid, false);
|
|
50
|
+
strict_1.default.match(res.reason ?? '', /unknown top-level field/);
|
|
51
|
+
});
|
|
52
|
+
(0, node_test_1.test)('rejects unsupported version', () => {
|
|
53
|
+
const bad = { ...FIXTURE_RECEIPT, v: 2 };
|
|
54
|
+
const res = (0, index_js_1.verifyReceipt)(bad, { allowUntrustedEmbeddedKey: true });
|
|
55
|
+
strict_1.default.equal(res.valid, false);
|
|
56
|
+
strict_1.default.match(res.reason ?? '', /unsupported version/);
|
|
57
|
+
});
|
|
58
|
+
(0, node_test_1.test)('rejects invalid outcome', () => {
|
|
59
|
+
const bad = { ...FIXTURE_RECEIPT, outcome: 'YOLO' };
|
|
60
|
+
const res = (0, index_js_1.verifyReceipt)(bad, { allowUntrustedEmbeddedKey: true });
|
|
61
|
+
strict_1.default.equal(res.valid, false);
|
|
62
|
+
strict_1.default.match(res.reason ?? '', /invalid outcome/);
|
|
63
|
+
});
|
|
64
|
+
(0, node_test_1.test)('rejects malformed request_hash', () => {
|
|
65
|
+
const bad = { ...FIXTURE_RECEIPT, request_hash: 'not-a-hash' };
|
|
66
|
+
const res = (0, index_js_1.verifyReceipt)(bad, { allowUntrustedEmbeddedKey: true });
|
|
67
|
+
strict_1.default.equal(res.valid, false);
|
|
68
|
+
strict_1.default.match(res.reason ?? '', /request_hash/);
|
|
69
|
+
});
|
|
70
|
+
(0, node_test_1.test)('rejects when trustedPublicKey omitted', () => {
|
|
71
|
+
const res = (0, index_js_1.verifyReceipt)(FIXTURE_RECEIPT);
|
|
72
|
+
strict_1.default.equal(res.valid, false);
|
|
73
|
+
strict_1.default.match(res.reason ?? '', /trustedPublicKey required/);
|
|
74
|
+
});
|
|
75
|
+
(0, node_test_1.test)('rejects pinned-key mismatch', () => {
|
|
76
|
+
const res = (0, index_js_1.verifyReceipt)(FIXTURE_RECEIPT, {
|
|
77
|
+
trustedPublicKey: 'different_key_000000000000000000000000000000',
|
|
78
|
+
});
|
|
79
|
+
strict_1.default.equal(res.valid, false);
|
|
80
|
+
strict_1.default.match(res.reason ?? '', /does not match trusted key/);
|
|
81
|
+
});
|
|
82
|
+
// Note: full signature-verification interop test requires the fixture to be
|
|
83
|
+
// populated by `scripts/make-test-fixture.py` before running this suite.
|
|
84
|
+
// When FIXTURE_RECEIPT.signature is empty, the signature check is skipped.
|
|
85
|
+
(0, node_test_1.test)('signature decoder rejects empty signature when integrity-only', () => {
|
|
86
|
+
const res = (0, index_js_1.verifyReceipt)(FIXTURE_RECEIPT, {
|
|
87
|
+
allowUntrustedEmbeddedKey: true,
|
|
88
|
+
});
|
|
89
|
+
strict_1.default.equal(res.valid, false);
|
|
90
|
+
strict_1.default.ok(/signature/.test(res.reason ?? '') ||
|
|
91
|
+
/signature length/.test(res.reason ?? ''));
|
|
92
|
+
});
|
|
93
|
+
/**
|
|
94
|
+
* Conformance against the published test vectors.
|
|
95
|
+
*
|
|
96
|
+
* These files are the cross-language contract: the same bytes are checked by
|
|
97
|
+
* the Python verifier's suite. Running them here is what catches a
|
|
98
|
+
* canonicalisation change that one language accepts and the other rejects,
|
|
99
|
+
* which unit tests written against a locally-built fixture cannot see.
|
|
100
|
+
*/
|
|
101
|
+
const VECTOR_KEY = 'alWzEnrA_z9McN9z_MFfQCnH9mVgOwRZ26wrI7oix4E';
|
|
102
|
+
const VECTOR_DIR = (0, node_path_1.join)(__dirname, '..', '..', '..', 'test-vectors');
|
|
103
|
+
function loadVectors(kind) {
|
|
104
|
+
const dir = (0, node_path_1.join)(VECTOR_DIR, kind);
|
|
105
|
+
return (0, node_fs_1.readdirSync)(dir)
|
|
106
|
+
.filter((f) => f.endsWith('.json'))
|
|
107
|
+
.map((f) => [f, JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(dir, f), 'utf8'))]);
|
|
108
|
+
}
|
|
109
|
+
(0, node_test_1.test)('every valid test vector verifies under the pinned vector key', () => {
|
|
110
|
+
const vectors = loadVectors('valid');
|
|
111
|
+
strict_1.default.ok(vectors.length > 0, 'no valid vectors found');
|
|
112
|
+
for (const [name, receipt] of vectors) {
|
|
113
|
+
const result = (0, index_js_1.verifyReceipt)(receipt, { trustedPublicKey: VECTOR_KEY });
|
|
114
|
+
strict_1.default.equal(result.valid, true, `${name} must verify (${result.reason ?? 'no reason'})`);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
(0, node_test_1.test)('every invalid test vector is rejected', () => {
|
|
118
|
+
const vectors = loadVectors('invalid');
|
|
119
|
+
strict_1.default.ok(vectors.length > 0, 'no invalid vectors found');
|
|
120
|
+
for (const [name, receipt] of vectors) {
|
|
121
|
+
const result = (0, index_js_1.verifyReceipt)(receipt, { trustedPublicKey: VECTOR_KEY });
|
|
122
|
+
strict_1.default.equal(result.valid, false, `${name} must be rejected`);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
/**
|
|
126
|
+
* Parse-layer input handling, exercised through the real CLI entry point.
|
|
127
|
+
*
|
|
128
|
+
* These cannot be shared test vectors: the vector runner parses each file
|
|
129
|
+
* before verifying, and a defect in the parse step does not survive being
|
|
130
|
+
* parsed. Duplicate member names collapse to one, and NaN is not JSON at
|
|
131
|
+
* all. Both languages must reject them the same way, so both packages
|
|
132
|
+
* carry the same cases.
|
|
133
|
+
*/
|
|
134
|
+
(0, node_test_1.test)('CLI rejects malformed input at the parse layer', async () => {
|
|
135
|
+
const { execFileSync } = await import('node:child_process');
|
|
136
|
+
const { writeFileSync, mkdtempSync } = await import('node:fs');
|
|
137
|
+
const { tmpdir } = await import('node:os');
|
|
138
|
+
const dir = mkdtempSync((0, node_path_1.join)(tmpdir(), 'aqta-cli-'));
|
|
139
|
+
const bin = (0, node_path_1.join)(__dirname, '..', 'bin', 'aqta-verify-receipt.js');
|
|
140
|
+
const cases = [
|
|
141
|
+
['duplicate member name', '{"v":1,"v":1,"outcome":"ALLOWED"}'],
|
|
142
|
+
['NaN literal', '{"v":1,"cost_prevented_eur":NaN}'],
|
|
143
|
+
['Infinity literal', '{"v":1,"cost_prevented_eur":Infinity}'],
|
|
144
|
+
['-Infinity literal', '{"v":1,"cost_prevented_eur":-Infinity}'],
|
|
145
|
+
];
|
|
146
|
+
for (const [label, body] of cases) {
|
|
147
|
+
const file = (0, node_path_1.join)(dir, 'receipt.json');
|
|
148
|
+
writeFileSync(file, body);
|
|
149
|
+
let code = 0;
|
|
150
|
+
try {
|
|
151
|
+
execFileSync(process.execPath, [bin, file, '--integrity-only'], { stdio: 'pipe' });
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
code = err.status;
|
|
155
|
+
}
|
|
156
|
+
// Exit 2 is usage/IO: malformed input, not an invalid receipt. Exit 1
|
|
157
|
+
// would mean the bytes parsed and the receipt merely failed to verify.
|
|
158
|
+
strict_1.default.equal(code, 2, `${label} must exit 2, got ${code}`);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
//# sourceMappingURL=index.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** SHA-256(0x00 || entry). Exported so a caller can derive a leaf from receipt bytes. */
|
|
2
|
+
export declare function leafHash(entry: Uint8Array): Uint8Array;
|
|
3
|
+
export interface InclusionProof {
|
|
4
|
+
leaf_hash: string;
|
|
5
|
+
leaf_index: number;
|
|
6
|
+
tree_size: number;
|
|
7
|
+
root_hash: string;
|
|
8
|
+
audit_path: string[];
|
|
9
|
+
}
|
|
10
|
+
export interface ConsistencyProof {
|
|
11
|
+
old_size: number;
|
|
12
|
+
new_size: number;
|
|
13
|
+
old_root: string;
|
|
14
|
+
new_root: string;
|
|
15
|
+
consistency_path: string[];
|
|
16
|
+
}
|
|
17
|
+
export interface SignedTreeHead {
|
|
18
|
+
org_id: string;
|
|
19
|
+
tree_size: number;
|
|
20
|
+
root_hash: string;
|
|
21
|
+
signature: string;
|
|
22
|
+
}
|
|
23
|
+
export interface ProofResult {
|
|
24
|
+
valid: boolean;
|
|
25
|
+
reason?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Verify that a leaf is in a tree of the stated size with the stated root.
|
|
29
|
+
*
|
|
30
|
+
* Follows RFC 6962 §2.1.1. The walk consumes the audit path exactly; a path
|
|
31
|
+
* with a node left over, or one that runs out early, fails rather than being
|
|
32
|
+
* tolerated, because a verifier that accepts a sloppy proof accepts a forged
|
|
33
|
+
* one built the same way.
|
|
34
|
+
*/
|
|
35
|
+
export declare function verifyInclusionProof(proof: unknown): ProofResult;
|
|
36
|
+
/**
|
|
37
|
+
* Verify that a later tree is an append-only extension of an earlier one.
|
|
38
|
+
*
|
|
39
|
+
* Follows RFC 6962 §2.1.2. This is the check that makes a log a log: without
|
|
40
|
+
* it, an issuer can publish a head, then publish another that quietly drops or
|
|
41
|
+
* reorders what came before.
|
|
42
|
+
*/
|
|
43
|
+
export declare function verifyConsistencyProof(proof: unknown): ProofResult;
|
|
44
|
+
/**
|
|
45
|
+
* Verify the Ed25519 signature on a signed tree head.
|
|
46
|
+
*
|
|
47
|
+
* The head is signed over a fixed byte string rather than JSON, so there is no
|
|
48
|
+
* canonicalisation question here and no opportunity for the encoding-level
|
|
49
|
+
* divergence that JSON payloads invite.
|
|
50
|
+
*/
|
|
51
|
+
export declare function verifySignedTreeHead(head: unknown, trustedPublicKey: string): ProofResult;
|
|
52
|
+
//# sourceMappingURL=transparency.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transparency.d.ts","sourceRoot":"","sources":["../src/transparency.ts"],"names":[],"mappings":"AA0DA,yFAAyF;AACzF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAKtD;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAMD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAmDhE;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CA0ElE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,GAAG,WAAW,CA4CzF"}
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.leafHash = leafHash;
|
|
7
|
+
exports.verifyInclusionProof = verifyInclusionProof;
|
|
8
|
+
exports.verifyConsistencyProof = verifyConsistencyProof;
|
|
9
|
+
exports.verifySignedTreeHead = verifySignedTreeHead;
|
|
10
|
+
/**
|
|
11
|
+
* Transparency proof verification: RFC 6962 inclusion and consistency.
|
|
12
|
+
*
|
|
13
|
+
* A receipt signature answers "did this issuer assert this". It cannot answer
|
|
14
|
+
* "is this one of the entries the issuer has committed to, and has that
|
|
15
|
+
* commitment only ever grown". Those are log questions, and answering them
|
|
16
|
+
* needs a signed tree head plus a proof, verified without holding the log.
|
|
17
|
+
*
|
|
18
|
+
* Nothing here contacts a server. A reviewer holding a proof, a head and the
|
|
19
|
+
* published key can settle both questions offline, which is the only reason
|
|
20
|
+
* the proofs are worth issuing.
|
|
21
|
+
*
|
|
22
|
+
* What these proofs do NOT establish, and no proof in this file claims:
|
|
23
|
+
* that the entries you were not shown are irrelevant. Inclusion proves that
|
|
24
|
+
* what you were shown is genuinely in the log. Omission stays open.
|
|
25
|
+
*/
|
|
26
|
+
const tweetnacl_1 = __importDefault(require("tweetnacl"));
|
|
27
|
+
const node_crypto_1 = require("node:crypto");
|
|
28
|
+
/**
|
|
29
|
+
* SHA-256 via the Node runtime rather than a new dependency. A verifier's
|
|
30
|
+
* value is inversely proportional to how much code a reviewer has to trust,
|
|
31
|
+
* so this module adds no third-party hashing. The receipt module stays free
|
|
32
|
+
* of Node built-ins and remains isomorphic; proof checking is a CLI job.
|
|
33
|
+
*/
|
|
34
|
+
function sha256(data) {
|
|
35
|
+
return new Uint8Array((0, node_crypto_1.createHash)('sha256').update(data).digest());
|
|
36
|
+
}
|
|
37
|
+
/** RFC 6962 §2.1 domain separation. */
|
|
38
|
+
const LEAF_PREFIX = 0x00;
|
|
39
|
+
const NODE_PREFIX = 0x01;
|
|
40
|
+
function hexToBytes(hex) {
|
|
41
|
+
if (typeof hex !== 'string' || hex.length % 2 !== 0 || !/^[0-9a-f]*$/.test(hex)) {
|
|
42
|
+
throw new Error('not lowercase hex');
|
|
43
|
+
}
|
|
44
|
+
const out = new Uint8Array(hex.length / 2);
|
|
45
|
+
for (let i = 0; i < out.length; i++)
|
|
46
|
+
out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
function bytesEqual(a, b) {
|
|
50
|
+
if (a.length !== b.length)
|
|
51
|
+
return false;
|
|
52
|
+
let diff = 0;
|
|
53
|
+
for (let i = 0; i < a.length; i++)
|
|
54
|
+
diff |= a[i] ^ b[i];
|
|
55
|
+
return diff === 0;
|
|
56
|
+
}
|
|
57
|
+
/** SHA-256(0x01 || left || right). */
|
|
58
|
+
function nodeHash(left, right) {
|
|
59
|
+
const buf = new Uint8Array(1 + left.length + right.length);
|
|
60
|
+
buf[0] = NODE_PREFIX;
|
|
61
|
+
buf.set(left, 1);
|
|
62
|
+
buf.set(right, 1 + left.length);
|
|
63
|
+
return sha256(buf);
|
|
64
|
+
}
|
|
65
|
+
/** SHA-256(0x00 || entry). Exported so a caller can derive a leaf from receipt bytes. */
|
|
66
|
+
function leafHash(entry) {
|
|
67
|
+
const buf = new Uint8Array(1 + entry.length);
|
|
68
|
+
buf[0] = LEAF_PREFIX;
|
|
69
|
+
buf.set(entry, 1);
|
|
70
|
+
return sha256(buf);
|
|
71
|
+
}
|
|
72
|
+
function isSafeSize(n) {
|
|
73
|
+
return typeof n === 'number' && Number.isSafeInteger(n) && n >= 0;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Verify that a leaf is in a tree of the stated size with the stated root.
|
|
77
|
+
*
|
|
78
|
+
* Follows RFC 6962 §2.1.1. The walk consumes the audit path exactly; a path
|
|
79
|
+
* with a node left over, or one that runs out early, fails rather than being
|
|
80
|
+
* tolerated, because a verifier that accepts a sloppy proof accepts a forged
|
|
81
|
+
* one built the same way.
|
|
82
|
+
*/
|
|
83
|
+
function verifyInclusionProof(proof) {
|
|
84
|
+
if (typeof proof !== 'object' || proof === null) {
|
|
85
|
+
return { valid: false, reason: 'proof is not an object' };
|
|
86
|
+
}
|
|
87
|
+
const p = proof;
|
|
88
|
+
if (!isSafeSize(p.tree_size) || p.tree_size < 1) {
|
|
89
|
+
return { valid: false, reason: 'tree_size must be a positive integer' };
|
|
90
|
+
}
|
|
91
|
+
if (!isSafeSize(p.leaf_index) || p.leaf_index >= p.tree_size) {
|
|
92
|
+
return { valid: false, reason: 'leaf_index must be an integer inside the tree' };
|
|
93
|
+
}
|
|
94
|
+
if (!Array.isArray(p.audit_path)) {
|
|
95
|
+
return { valid: false, reason: 'audit_path must be an array' };
|
|
96
|
+
}
|
|
97
|
+
let leaf;
|
|
98
|
+
let root;
|
|
99
|
+
let path;
|
|
100
|
+
try {
|
|
101
|
+
leaf = hexToBytes(p.leaf_hash);
|
|
102
|
+
root = hexToBytes(p.root_hash);
|
|
103
|
+
path = p.audit_path.map(hexToBytes);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return { valid: false, reason: 'hashes must be lowercase hex' };
|
|
107
|
+
}
|
|
108
|
+
if (leaf.length !== 32 || root.length !== 32 || path.some((n) => n.length !== 32)) {
|
|
109
|
+
return { valid: false, reason: 'every hash must be 32 bytes' };
|
|
110
|
+
}
|
|
111
|
+
let fn = p.leaf_index;
|
|
112
|
+
let sn = p.tree_size - 1;
|
|
113
|
+
let r = leaf;
|
|
114
|
+
for (const sibling of path) {
|
|
115
|
+
if (sn === 0)
|
|
116
|
+
return { valid: false, reason: 'audit_path is longer than the tree allows' };
|
|
117
|
+
if (fn % 2 === 1 || fn === sn) {
|
|
118
|
+
r = nodeHash(sibling, r);
|
|
119
|
+
while (fn !== 0 && fn % 2 === 0) {
|
|
120
|
+
fn >>= 1;
|
|
121
|
+
sn >>= 1;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
r = nodeHash(r, sibling);
|
|
126
|
+
}
|
|
127
|
+
fn >>= 1;
|
|
128
|
+
sn >>= 1;
|
|
129
|
+
}
|
|
130
|
+
if (sn !== 0)
|
|
131
|
+
return { valid: false, reason: 'audit_path is shorter than the tree requires' };
|
|
132
|
+
if (!bytesEqual(r, root))
|
|
133
|
+
return { valid: false, reason: 'computed root does not match root_hash' };
|
|
134
|
+
return { valid: true };
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Verify that a later tree is an append-only extension of an earlier one.
|
|
138
|
+
*
|
|
139
|
+
* Follows RFC 6962 §2.1.2. This is the check that makes a log a log: without
|
|
140
|
+
* it, an issuer can publish a head, then publish another that quietly drops or
|
|
141
|
+
* reorders what came before.
|
|
142
|
+
*/
|
|
143
|
+
function verifyConsistencyProof(proof) {
|
|
144
|
+
if (typeof proof !== 'object' || proof === null) {
|
|
145
|
+
return { valid: false, reason: 'proof is not an object' };
|
|
146
|
+
}
|
|
147
|
+
const p = proof;
|
|
148
|
+
if (!isSafeSize(p.old_size) || p.old_size < 1) {
|
|
149
|
+
return { valid: false, reason: 'old_size must be a positive integer' };
|
|
150
|
+
}
|
|
151
|
+
if (!isSafeSize(p.new_size) || p.new_size < p.old_size) {
|
|
152
|
+
return { valid: false, reason: 'new_size must be an integer at least old_size' };
|
|
153
|
+
}
|
|
154
|
+
if (!Array.isArray(p.consistency_path)) {
|
|
155
|
+
return { valid: false, reason: 'consistency_path must be an array' };
|
|
156
|
+
}
|
|
157
|
+
let oldRoot;
|
|
158
|
+
let newRoot;
|
|
159
|
+
let nodes;
|
|
160
|
+
try {
|
|
161
|
+
oldRoot = hexToBytes(p.old_root);
|
|
162
|
+
newRoot = hexToBytes(p.new_root);
|
|
163
|
+
nodes = p.consistency_path.map(hexToBytes);
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
return { valid: false, reason: 'hashes must be lowercase hex' };
|
|
167
|
+
}
|
|
168
|
+
if (oldRoot.length !== 32 || newRoot.length !== 32 || nodes.some((n) => n.length !== 32)) {
|
|
169
|
+
return { valid: false, reason: 'every hash must be 32 bytes' };
|
|
170
|
+
}
|
|
171
|
+
const oldSize = p.old_size;
|
|
172
|
+
const newSize = p.new_size;
|
|
173
|
+
if (oldSize === newSize) {
|
|
174
|
+
// Nothing appended. The roots must be identical and a proof would be noise.
|
|
175
|
+
if (nodes.length > 0)
|
|
176
|
+
return { valid: false, reason: 'no consistency_path is expected when the tree has not grown' };
|
|
177
|
+
if (!bytesEqual(oldRoot, newRoot))
|
|
178
|
+
return { valid: false, reason: 'tree did not grow but roots differ' };
|
|
179
|
+
return { valid: true };
|
|
180
|
+
}
|
|
181
|
+
// When old_size is an exact power of two its root is the first node of the
|
|
182
|
+
// path, and RFC 6962 omits it because the verifier already holds it.
|
|
183
|
+
if ((oldSize & (oldSize - 1)) === 0)
|
|
184
|
+
nodes = [oldRoot, ...nodes];
|
|
185
|
+
if (nodes.length === 0)
|
|
186
|
+
return { valid: false, reason: 'consistency_path is empty' };
|
|
187
|
+
let fn = oldSize - 1;
|
|
188
|
+
let sn = newSize - 1;
|
|
189
|
+
while (fn % 2 === 1) {
|
|
190
|
+
fn >>= 1;
|
|
191
|
+
sn >>= 1;
|
|
192
|
+
}
|
|
193
|
+
let fr = nodes[0];
|
|
194
|
+
let sr = nodes[0];
|
|
195
|
+
for (const node of nodes.slice(1)) {
|
|
196
|
+
if (sn === 0)
|
|
197
|
+
return { valid: false, reason: 'consistency_path is longer than the trees allow' };
|
|
198
|
+
if (fn % 2 === 1 || fn === sn) {
|
|
199
|
+
fr = nodeHash(node, fr);
|
|
200
|
+
sr = nodeHash(node, sr);
|
|
201
|
+
while (fn !== 0 && fn % 2 === 0) {
|
|
202
|
+
fn >>= 1;
|
|
203
|
+
sn >>= 1;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
sr = nodeHash(sr, node);
|
|
208
|
+
}
|
|
209
|
+
fn >>= 1;
|
|
210
|
+
sn >>= 1;
|
|
211
|
+
}
|
|
212
|
+
if (sn !== 0)
|
|
213
|
+
return { valid: false, reason: 'consistency_path is shorter than the trees require' };
|
|
214
|
+
if (!bytesEqual(fr, oldRoot))
|
|
215
|
+
return { valid: false, reason: 'computed old root does not match old_root' };
|
|
216
|
+
if (!bytesEqual(sr, newRoot))
|
|
217
|
+
return { valid: false, reason: 'computed new root does not match new_root' };
|
|
218
|
+
return { valid: true };
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Verify the Ed25519 signature on a signed tree head.
|
|
222
|
+
*
|
|
223
|
+
* The head is signed over a fixed byte string rather than JSON, so there is no
|
|
224
|
+
* canonicalisation question here and no opportunity for the encoding-level
|
|
225
|
+
* divergence that JSON payloads invite.
|
|
226
|
+
*/
|
|
227
|
+
function verifySignedTreeHead(head, trustedPublicKey) {
|
|
228
|
+
if (typeof head !== 'object' || head === null) {
|
|
229
|
+
return { valid: false, reason: 'head is not an object' };
|
|
230
|
+
}
|
|
231
|
+
const h = head;
|
|
232
|
+
if (typeof h.org_id !== 'string' || !isSafeSize(h.tree_size)) {
|
|
233
|
+
return { valid: false, reason: 'head must carry org_id and an integer tree_size' };
|
|
234
|
+
}
|
|
235
|
+
if (typeof h.root_hash !== 'string' || typeof h.signature !== 'string') {
|
|
236
|
+
return { valid: false, reason: 'head must carry root_hash and signature' };
|
|
237
|
+
}
|
|
238
|
+
if (!/^[A-Za-z0-9_-]+$/.test(h.signature) || !/^[A-Za-z0-9_-]+$/.test(trustedPublicKey)) {
|
|
239
|
+
return { valid: false, reason: 'signature and key must be base64url without padding' };
|
|
240
|
+
}
|
|
241
|
+
let root;
|
|
242
|
+
try {
|
|
243
|
+
root = hexToBytes(h.root_hash);
|
|
244
|
+
}
|
|
245
|
+
catch {
|
|
246
|
+
return { valid: false, reason: 'root_hash must be lowercase hex' };
|
|
247
|
+
}
|
|
248
|
+
if (root.length !== 32)
|
|
249
|
+
return { valid: false, reason: 'root_hash must be 32 bytes' };
|
|
250
|
+
const prefix = new TextEncoder().encode(`aqta-sth-v1|${h.org_id}|${h.tree_size}|`);
|
|
251
|
+
const signed = new Uint8Array(prefix.length + root.length);
|
|
252
|
+
signed.set(prefix, 0);
|
|
253
|
+
signed.set(root, prefix.length);
|
|
254
|
+
const b64url = (s) => new Uint8Array(Buffer.from(s, 'base64url'));
|
|
255
|
+
let sig;
|
|
256
|
+
let pub;
|
|
257
|
+
try {
|
|
258
|
+
sig = b64url(h.signature);
|
|
259
|
+
pub = b64url(trustedPublicKey);
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
return { valid: false, reason: 'signature decode error' };
|
|
263
|
+
}
|
|
264
|
+
if (sig.length !== 64)
|
|
265
|
+
return { valid: false, reason: 'signature length != 64 bytes' };
|
|
266
|
+
if (pub.length !== 32)
|
|
267
|
+
return { valid: false, reason: 'public key length != 32 bytes' };
|
|
268
|
+
if (!tweetnacl_1.default.sign.detached.verify(signed, sig, pub)) {
|
|
269
|
+
return { valid: false, reason: 'tree head signature check failed' };
|
|
270
|
+
}
|
|
271
|
+
return { valid: true };
|
|
272
|
+
}
|
|
273
|
+
//# sourceMappingURL=transparency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transparency.js","sourceRoot":"","sources":["../src/transparency.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-proof.d.ts","sourceRoot":"","sources":["../src/verify-proof.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-proof.js","sourceRoot":"","sources":["../src/verify-proof.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aqta-verify-receipt",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "Offline CLI and library for Seal records: ATTESTATION-v1 for what an AI decided, ACTION-v1 for what an agent was allowed to do, refusals included. Ed25519, checked against a published key with no account and no Aqta server.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -10,14 +10,7 @@
|
|
|
10
10
|
},
|
|
11
11
|
"files": [
|
|
12
12
|
"bin/",
|
|
13
|
-
"dist/
|
|
14
|
-
"dist/cli.js.map",
|
|
15
|
-
"dist/cli.d.ts",
|
|
16
|
-
"dist/cli.d.ts.map",
|
|
17
|
-
"dist/index.js",
|
|
18
|
-
"dist/index.js.map",
|
|
19
|
-
"dist/index.d.ts",
|
|
20
|
-
"dist/index.d.ts.map",
|
|
13
|
+
"dist/",
|
|
21
14
|
"README.md",
|
|
22
15
|
"LICENSE"
|
|
23
16
|
],
|