@mikeargento/bitgraph-player 0.2.1 → 0.4.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/README.md +40 -0
- package/SPEC.md +95 -6
- package/dist/__tests__/check.test.d.ts +2 -0
- package/dist/__tests__/check.test.d.ts.map +1 -0
- package/dist/__tests__/check.test.js +358 -0
- package/dist/__tests__/check.test.js.map +1 -0
- package/dist/__tests__/sig-v2.test.d.ts +2 -0
- package/dist/__tests__/sig-v2.test.d.ts.map +1 -0
- package/dist/__tests__/sig-v2.test.js +266 -0
- package/dist/__tests__/sig-v2.test.js.map +1 -0
- package/dist/check.d.ts +156 -0
- package/dist/check.d.ts.map +1 -0
- package/dist/check.js +640 -0
- package/dist/check.js.map +1 -0
- package/dist/cli.js +84 -15
- package/dist/cli.js.map +1 -1
- package/dist/evaluate.d.ts +8 -21
- package/dist/evaluate.d.ts.map +1 -1
- package/dist/evaluate.js +93 -2
- package/dist/evaluate.js.map +1 -1
- package/dist/index.d.ts +8 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/play.d.ts +12 -2
- package/dist/play.d.ts.map +1 -1
- package/dist/play.js +39 -4
- package/dist/play.js.map +1 -1
- package/dist/rule.d.ts +0 -13
- package/dist/rule.d.ts.map +1 -1
- package/dist/rule.js +84 -8
- package/dist/rule.js.map +1 -1
- package/dist/sig.d.ts +38 -0
- package/dist/sig.d.ts.map +1 -0
- package/dist/sig.js +154 -0
- package/dist/sig.js.map +1 -0
- package/dist/types.d.ts +21 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/verdict.d.ts +1 -1
- package/dist/verdict.d.ts.map +1 -1
- package/dist/verdict.js +17 -2
- package/dist/verdict.js.map +1 -1
- package/dist-web/verify.html +159 -0
- package/package.json +8 -3
- package/src/__tests__/check.test.ts +417 -0
- package/src/__tests__/fixtures/export-random-043/ethereum-anchors/anchor-after-witness.json +6 -0
- package/src/__tests__/fixtures/export-random-043/ethereum-anchors/anchor-after.json +43 -0
- package/src/__tests__/fixtures/export-random-043/ethereum-anchors/anchor-before-witness.json +6 -0
- package/src/__tests__/fixtures/export-random-043/ethereum-anchors/anchor-before.json +47 -0
- package/src/__tests__/fixtures/export-random-043/proof.json +38 -0
- package/src/__tests__/fixtures/export-random-043/random-043.txt +1 -0
- package/src/__tests__/sig-v2.test.ts +315 -0
- package/src/check.ts +873 -0
- package/src/cli.ts +82 -16
- package/src/evaluate.ts +107 -2
- package/src/index.ts +9 -2
- package/src/play.ts +43 -5
- package/src/rule.ts +93 -9
- package/src/sig.ts +170 -0
- package/src/types.ts +21 -4
- package/src/verdict.ts +18 -2
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
// Copyright (c) 2024-2026 Mike Argento. Licensed under the MIT License. See LICENSE.
|
|
2
|
+
/**
|
|
3
|
+
* Format 2: trustedKeys + signedBy.
|
|
4
|
+
*
|
|
5
|
+
* The invariants under test:
|
|
6
|
+
* - signedBy is TRUE or UNDETERMINED, never FALSE, so not(signedBy)
|
|
7
|
+
* is permanently UNDETERMINED: no open-world negative escapes.
|
|
8
|
+
* - Signature math is derived; the name-to-key binding is declared.
|
|
9
|
+
* - A /1 rule parses and evaluates exactly as before (verdict/1), and
|
|
10
|
+
* /2-only syntax in a /1 rule is a parse error.
|
|
11
|
+
* - Broken signature files are noise, never evidence and never errors.
|
|
12
|
+
*
|
|
13
|
+
* All evidence is synthetic and in-memory. No ledger writes, ever.
|
|
14
|
+
*/
|
|
15
|
+
import { strict as assert } from "node:assert";
|
|
16
|
+
import { createHash, generateKeyPairSync, sign as cryptoSign } from "node:crypto";
|
|
17
|
+
import { test } from "node:test";
|
|
18
|
+
import { evaluate } from "../evaluate.js";
|
|
19
|
+
import { playAudit, claimUsesSignatures } from "../play.js";
|
|
20
|
+
import { parseRule, RuleError } from "../rule.js";
|
|
21
|
+
import { parseSigFile, sigMessage } from "../sig.js";
|
|
22
|
+
import { resolveCast } from "../cast.js";
|
|
23
|
+
import { digestFor, makeAudit } from "./fixtures.js";
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
// Key + signature helpers (in-memory, per-run keys; verification is the
|
|
26
|
+
// deterministic part under test, not key generation)
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
function ed25519Pair() {
|
|
29
|
+
const { publicKey, privateKey } = generateKeyPairSync("ed25519");
|
|
30
|
+
const spki = publicKey.export({ format: "der", type: "spki" });
|
|
31
|
+
// Raw key = last 32 bytes of the SPKI encoding.
|
|
32
|
+
return { publicKeyB64: spki.subarray(spki.length - 32).toString("base64"), privateKey };
|
|
33
|
+
}
|
|
34
|
+
function es256Pair() {
|
|
35
|
+
const { publicKey, privateKey } = generateKeyPairSync("ec", { namedCurve: "P-256" });
|
|
36
|
+
const spki = publicKey.export({ format: "der", type: "spki" });
|
|
37
|
+
return { publicKeyB64: spki.toString("base64"), privateKey };
|
|
38
|
+
}
|
|
39
|
+
function hexOfB64(digestB64) {
|
|
40
|
+
return Buffer.from(digestB64, "base64").toString("hex");
|
|
41
|
+
}
|
|
42
|
+
function makeSigBytes(alg, publicKeyB64, privateKey, overHex) {
|
|
43
|
+
const message = sigMessage(overHex);
|
|
44
|
+
const signature = alg === "ed25519"
|
|
45
|
+
? cryptoSign(null, message, privateKey)
|
|
46
|
+
: cryptoSign("sha256", message, privateKey);
|
|
47
|
+
return Buffer.from(JSON.stringify({
|
|
48
|
+
sig: "bitgraph-sig/1",
|
|
49
|
+
over: `sha256:${overHex}`,
|
|
50
|
+
alg,
|
|
51
|
+
publicKey: publicKeyB64,
|
|
52
|
+
signature: signature.toString("base64"),
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
function evidenceOf(...items) {
|
|
56
|
+
const map = new Map();
|
|
57
|
+
for (const bytes of items) {
|
|
58
|
+
map.set(createHash("sha256").update(bytes).digest("hex"), bytes);
|
|
59
|
+
}
|
|
60
|
+
return map;
|
|
61
|
+
}
|
|
62
|
+
const WORK = digestFor("work");
|
|
63
|
+
function v2Rule(publicKeyB64, alg, claim) {
|
|
64
|
+
return JSON.stringify({
|
|
65
|
+
rule: "bitgraph-player/2",
|
|
66
|
+
id: "test-v2",
|
|
67
|
+
cast: { work: { digest: WORK } },
|
|
68
|
+
world: "closed",
|
|
69
|
+
requires: { ordering: "assumption-dependent" },
|
|
70
|
+
trustedKeys: { mike: { alg, publicKey: publicKeyB64 } },
|
|
71
|
+
claim,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
function auditWithWork() {
|
|
75
|
+
return makeAudit({
|
|
76
|
+
proofs: [{ name: "w", digestB64: WORK, epochId: "e1", counter: "1" }],
|
|
77
|
+
partitions: [{ epochId: "e1", members: ["w"] }],
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
// Parsing
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
test("signedBy in a /1 rule is a parse error", () => {
|
|
84
|
+
const text = JSON.stringify({
|
|
85
|
+
rule: "bitgraph-player/1",
|
|
86
|
+
id: "r",
|
|
87
|
+
cast: { work: { digest: WORK } },
|
|
88
|
+
world: "closed",
|
|
89
|
+
requires: { ordering: "hash-linked" },
|
|
90
|
+
claim: { signedBy: ["work", "mike"] },
|
|
91
|
+
});
|
|
92
|
+
assert.throws(() => parseRule(text), RuleError);
|
|
93
|
+
});
|
|
94
|
+
test("trustedKeys in a /1 rule is a parse error", () => {
|
|
95
|
+
const text = JSON.stringify({
|
|
96
|
+
rule: "bitgraph-player/1",
|
|
97
|
+
id: "r",
|
|
98
|
+
cast: { work: { digest: WORK } },
|
|
99
|
+
world: "closed",
|
|
100
|
+
requires: { ordering: "hash-linked" },
|
|
101
|
+
trustedKeys: { mike: { alg: "ed25519", publicKey: "A".repeat(43) + "=" } },
|
|
102
|
+
claim: { exists: "work" },
|
|
103
|
+
});
|
|
104
|
+
assert.throws(() => parseRule(text), RuleError);
|
|
105
|
+
});
|
|
106
|
+
test("signedBy referencing an undeclared trusted key is a parse error", () => {
|
|
107
|
+
const { publicKeyB64 } = ed25519Pair();
|
|
108
|
+
const text = v2Rule(publicKeyB64, "ed25519", { signedBy: ["work", "ghost"] });
|
|
109
|
+
assert.throws(() => parseRule(text), /does not declare/);
|
|
110
|
+
});
|
|
111
|
+
test("trustedKeys entries are strictly validated", () => {
|
|
112
|
+
for (const bad of [
|
|
113
|
+
{ alg: "rsa", publicKey: "x" },
|
|
114
|
+
{ alg: "ed25519" },
|
|
115
|
+
{ publicKey: "x" },
|
|
116
|
+
{ alg: "ed25519", publicKey: "x", extra: 1 },
|
|
117
|
+
]) {
|
|
118
|
+
const text = JSON.stringify({
|
|
119
|
+
rule: "bitgraph-player/2",
|
|
120
|
+
id: "r",
|
|
121
|
+
cast: { work: { digest: WORK } },
|
|
122
|
+
world: "closed",
|
|
123
|
+
requires: { ordering: "hash-linked" },
|
|
124
|
+
trustedKeys: { mike: bad },
|
|
125
|
+
claim: { exists: "work" },
|
|
126
|
+
});
|
|
127
|
+
assert.throws(() => parseRule(text), RuleError, JSON.stringify(bad));
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
test("pure-integer trusted key names are rejected", () => {
|
|
131
|
+
const text = JSON.stringify({
|
|
132
|
+
rule: "bitgraph-player/2",
|
|
133
|
+
id: "r",
|
|
134
|
+
cast: { work: { digest: WORK } },
|
|
135
|
+
world: "closed",
|
|
136
|
+
requires: { ordering: "hash-linked" },
|
|
137
|
+
trustedKeys: { "42": { alg: "ed25519", publicKey: "A".repeat(43) + "=" } },
|
|
138
|
+
claim: { exists: "work" },
|
|
139
|
+
});
|
|
140
|
+
assert.throws(() => parseRule(text), /non-digit/);
|
|
141
|
+
});
|
|
142
|
+
test("claimUsesSignatures walks the tree", () => {
|
|
143
|
+
assert.equal(claimUsesSignatures({ exists: "x" }), false);
|
|
144
|
+
assert.equal(claimUsesSignatures({ all: [{ exists: "x" }, { not: { signedBy: ["x", "k"] } }] }), true);
|
|
145
|
+
});
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
// Signature file parsing
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
test("parseSigFile accepts a well-formed file and rejects noise", () => {
|
|
150
|
+
const { publicKeyB64, privateKey } = ed25519Pair();
|
|
151
|
+
const good = makeSigBytes("ed25519", publicKeyB64, privateKey, hexOfB64(WORK));
|
|
152
|
+
assert.notEqual(parseSigFile(good), undefined);
|
|
153
|
+
assert.equal(parseSigFile(Buffer.from("not json")), undefined);
|
|
154
|
+
assert.equal(parseSigFile(Buffer.from(JSON.stringify({ sig: "other/1" }))), undefined);
|
|
155
|
+
assert.equal(parseSigFile(Buffer.from(JSON.stringify({ sig: "bitgraph-sig/1", over: "x", alg: "rsa" }))), undefined);
|
|
156
|
+
});
|
|
157
|
+
// ---------------------------------------------------------------------------
|
|
158
|
+
// Evaluation: ed25519 and es256
|
|
159
|
+
// ---------------------------------------------------------------------------
|
|
160
|
+
for (const alg of ["ed25519", "es256"]) {
|
|
161
|
+
test(`signedBy(${alg}): valid signature in evidence evaluates TRUE with derived math`, () => {
|
|
162
|
+
const pair = alg === "ed25519" ? ed25519Pair() : es256Pair();
|
|
163
|
+
const rule = parseRule(v2Rule(pair.publicKeyB64, alg, { signedBy: ["work", "mike"] }));
|
|
164
|
+
const audit = auditWithWork();
|
|
165
|
+
const evidence = evidenceOf(makeSigBytes(alg, pair.publicKeyB64, pair.privateKey, hexOfB64(WORK)));
|
|
166
|
+
const result = playAudit(rule, "0".repeat(64), audit, evidence);
|
|
167
|
+
assert.equal(result.verdict.result, "TRUE");
|
|
168
|
+
assert.equal(result.verdict.verdict, "bitgraph-player-verdict/2");
|
|
169
|
+
const step = result.verdict.derived.find((s) => s.claim.startsWith("signedBy"));
|
|
170
|
+
assert.ok(step !== undefined);
|
|
171
|
+
assert.equal(step.result, "TRUE");
|
|
172
|
+
// The binding is declared, alongside the math being derived.
|
|
173
|
+
const trusted = result.verdict.declared.find((d) => d.assertion === "trusted-key");
|
|
174
|
+
assert.ok(trusted !== undefined);
|
|
175
|
+
assert.equal(trusted["keyName"], "mike");
|
|
176
|
+
assert.equal(trusted.verifiedHere, false);
|
|
177
|
+
});
|
|
178
|
+
test(`signedBy(${alg}): tampered signature is noise, evaluates UNDETERMINED`, () => {
|
|
179
|
+
const pair = alg === "ed25519" ? ed25519Pair() : es256Pair();
|
|
180
|
+
const rule = parseRule(v2Rule(pair.publicKeyB64, alg, { signedBy: ["work", "mike"] }));
|
|
181
|
+
const bytes = makeSigBytes(alg, pair.publicKeyB64, pair.privateKey, hexOfB64(WORK));
|
|
182
|
+
const parsed = JSON.parse(Buffer.from(bytes).toString("utf8"));
|
|
183
|
+
const sigBytes = Buffer.from(parsed["signature"], "base64");
|
|
184
|
+
sigBytes[0] = sigBytes[0] ^ 0xff;
|
|
185
|
+
parsed["signature"] = sigBytes.toString("base64");
|
|
186
|
+
const tampered = Buffer.from(JSON.stringify(parsed));
|
|
187
|
+
const result = playAudit(rule, "0".repeat(64), auditWithWork(), evidenceOf(tampered));
|
|
188
|
+
assert.equal(result.verdict.result, "UNDETERMINED");
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
test("a non-P-256 key declared as es256 is undecodable key material: UNDETERMINED, never a verify", () => {
|
|
192
|
+
const { publicKey, privateKey } = generateKeyPairSync("ec", { namedCurve: "secp384r1" });
|
|
193
|
+
const spki = publicKey.export({ format: "der", type: "spki" }).toString("base64");
|
|
194
|
+
const rule = parseRule(v2Rule(spki, "es256", { signedBy: ["work", "mike"] }));
|
|
195
|
+
const evidence = evidenceOf(makeSigBytes("es256", spki, privateKey, hexOfB64(WORK)));
|
|
196
|
+
const result = playAudit(rule, "0".repeat(64), auditWithWork(), evidence);
|
|
197
|
+
assert.equal(result.verdict.result, "UNDETERMINED");
|
|
198
|
+
const step = result.verdict.derived.find((s) => s.claim.startsWith("signedBy"));
|
|
199
|
+
assert.ok(step !== undefined);
|
|
200
|
+
assert.match(String(step.because["reason"]), /not decodable/);
|
|
201
|
+
});
|
|
202
|
+
test("signedBy with empty evidence is UNDETERMINED, and not(signedBy) stays UNDETERMINED", () => {
|
|
203
|
+
const { publicKeyB64 } = ed25519Pair();
|
|
204
|
+
const rule = parseRule(v2Rule(publicKeyB64, "ed25519", { not: { signedBy: ["work", "mike"] } }));
|
|
205
|
+
const result = playAudit(rule, "0".repeat(64), auditWithWork());
|
|
206
|
+
// Never FALSE and never TRUE: the open world stays open.
|
|
207
|
+
assert.equal(result.verdict.result, "UNDETERMINED");
|
|
208
|
+
});
|
|
209
|
+
test("signedBy by the wrong key is UNDETERMINED, never FALSE", () => {
|
|
210
|
+
const right = ed25519Pair();
|
|
211
|
+
const wrong = ed25519Pair();
|
|
212
|
+
const rule = parseRule(v2Rule(right.publicKeyB64, "ed25519", { signedBy: ["work", "mike"] }));
|
|
213
|
+
const evidence = evidenceOf(makeSigBytes("ed25519", wrong.publicKeyB64, wrong.privateKey, hexOfB64(WORK)));
|
|
214
|
+
const result = playAudit(rule, "0".repeat(64), auditWithWork(), evidence);
|
|
215
|
+
assert.equal(result.verdict.result, "UNDETERMINED");
|
|
216
|
+
});
|
|
217
|
+
test("signedBy over a different digest does not satisfy the role's claim", () => {
|
|
218
|
+
const pair = ed25519Pair();
|
|
219
|
+
const rule = parseRule(v2Rule(pair.publicKeyB64, "ed25519", { signedBy: ["work", "mike"] }));
|
|
220
|
+
const other = digestFor("other");
|
|
221
|
+
const evidence = evidenceOf(makeSigBytes("ed25519", pair.publicKeyB64, pair.privateKey, hexOfB64(other)));
|
|
222
|
+
const result = playAudit(rule, "0".repeat(64), auditWithWork(), evidence);
|
|
223
|
+
assert.equal(result.verdict.result, "UNDETERMINED");
|
|
224
|
+
});
|
|
225
|
+
test("signedBy evaluates against the declared digest even when the role has no recording", () => {
|
|
226
|
+
const pair = ed25519Pair();
|
|
227
|
+
const text = JSON.stringify({
|
|
228
|
+
rule: "bitgraph-player/2",
|
|
229
|
+
id: "r",
|
|
230
|
+
cast: { work: { digest: WORK, optional: true } },
|
|
231
|
+
world: "closed",
|
|
232
|
+
requires: { ordering: "hash-linked" },
|
|
233
|
+
trustedKeys: { mike: { alg: "ed25519", publicKey: pair.publicKeyB64 } },
|
|
234
|
+
claim: { signedBy: ["work", "mike"] },
|
|
235
|
+
});
|
|
236
|
+
const rule = parseRule(text);
|
|
237
|
+
const audit = makeAudit({ proofs: [], partitions: [] });
|
|
238
|
+
const evidence = evidenceOf(makeSigBytes("ed25519", pair.publicKeyB64, pair.privateKey, hexOfB64(WORK)));
|
|
239
|
+
const resolutions = resolveCast(rule.cast, audit);
|
|
240
|
+
const evaluation = evaluate(rule, resolutions, audit, evidence);
|
|
241
|
+
assert.equal(evaluation.result, "TRUE");
|
|
242
|
+
});
|
|
243
|
+
test("a /1 rule still yields a /1 verdict and ignores supplied evidence", () => {
|
|
244
|
+
const text = JSON.stringify({
|
|
245
|
+
rule: "bitgraph-player/1",
|
|
246
|
+
id: "r",
|
|
247
|
+
cast: { work: { digest: WORK } },
|
|
248
|
+
world: "closed",
|
|
249
|
+
requires: { ordering: "assumption-dependent" },
|
|
250
|
+
claim: { exists: "work" },
|
|
251
|
+
});
|
|
252
|
+
const rule = parseRule(text);
|
|
253
|
+
const result = playAudit(rule, "0".repeat(64), auditWithWork(), evidenceOf(Buffer.from("junk")));
|
|
254
|
+
assert.equal(result.verdict.verdict, "bitgraph-player-verdict/1");
|
|
255
|
+
assert.equal(result.verdict.result, "TRUE");
|
|
256
|
+
});
|
|
257
|
+
test("multiple candidates: the winner is deterministic and reported by content hash", () => {
|
|
258
|
+
const pair = ed25519Pair();
|
|
259
|
+
const rule = parseRule(v2Rule(pair.publicKeyB64, "ed25519", { signedBy: ["work", "mike"] }));
|
|
260
|
+
const sig = makeSigBytes("ed25519", pair.publicKeyB64, pair.privateKey, hexOfB64(WORK));
|
|
261
|
+
const junk = Buffer.from("{}");
|
|
262
|
+
const a = playAudit(rule, "0".repeat(64), auditWithWork(), evidenceOf(sig, junk));
|
|
263
|
+
const b = playAudit(rule, "0".repeat(64), auditWithWork(), evidenceOf(junk, sig));
|
|
264
|
+
assert.equal(a.bytes, b.bytes);
|
|
265
|
+
});
|
|
266
|
+
//# sourceMappingURL=sig-v2.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sig-v2.test.js","sourceRoot":"","sources":["../../src/__tests__/sig-v2.test.ts"],"names":[],"mappings":"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"}
|
package/dist/check.d.ts
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `check`: what a bundle establishes about the recordings it holds, said
|
|
3
|
+
* plainly, offline, in the Player's three values.
|
|
4
|
+
*
|
|
5
|
+
* This is a SPEC section 8 convenience: a distinct subcommand that never
|
|
6
|
+
* touches evaluation semantics. It asks no rule-author question ("was A
|
|
7
|
+
* before B"); it asks the reader's question ("is this recording sound, and
|
|
8
|
+
* what bounds it"), over the audit pipeline's canonical interpretation of
|
|
9
|
+
* the bundle, and answers per line with TRUE, FALSE, or UNDETERMINED.
|
|
10
|
+
*
|
|
11
|
+
* The vocabulary, and the line it lives or dies on:
|
|
12
|
+
*
|
|
13
|
+
* TRUE evidence in hand establishes the property.
|
|
14
|
+
* FALSE evidence in hand CONTRADICTS the property: bytes that do
|
|
15
|
+
* not hash to the digest they sit beside, a signature that
|
|
16
|
+
* fails, an attestation whose user_data is not this proof, a
|
|
17
|
+
* block header that does not hash to its anchor's block hash,
|
|
18
|
+
* two recordings that cannot both be right.
|
|
19
|
+
* UNDETERMINED the evidence does not decide. Missing bytes, a missing
|
|
20
|
+
* witness, an environment that cannot run a check, a
|
|
21
|
+
* measurement this verifier does not know. Absence is never
|
|
22
|
+
* a verdict, and this command never degrades a failed or
|
|
23
|
+
* missing check into a FALSE (project rule: a failed read is
|
|
24
|
+
* never a verdict).
|
|
25
|
+
*
|
|
26
|
+
* The overall result is the strong-Kleene `all` over every line the report
|
|
27
|
+
* emits: each recording's lines, each anchor's lines, and each structural
|
|
28
|
+
* contradiction. Ethereum BOUNDS are reported descriptively per recording
|
|
29
|
+
* and never enter the conjunction: a bundle without an anchor has an
|
|
30
|
+
* unbounded recording, not an unsound one. A witness that is PRESENT and
|
|
31
|
+
* fails is a contradiction and does enter.
|
|
32
|
+
*
|
|
33
|
+
* Excerpt honesty. A single export is an excerpt of a chain: its recording
|
|
34
|
+
* links to a predecessor that is not in the bundle, and the counter
|
|
35
|
+
* positions between its anchors are absent. The audit reports those as
|
|
36
|
+
* anomalies because it is built to audit whole epochs; here they are
|
|
37
|
+
* expected and are reported as notes, never as verdicts. Real
|
|
38
|
+
* contradictions (collisions, forks, malformed links, signer changes)
|
|
39
|
+
* still surface as FALSE.
|
|
40
|
+
*
|
|
41
|
+
* Enclave identity. An attestation proves that SOME AWS Nitro enclave
|
|
42
|
+
* running code with the attested PCR0 signed this proof's key. Whether
|
|
43
|
+
* that PCR0 is a published BitGraph enclave measurement is a fact this
|
|
44
|
+
* verifier carries as DECLARED knowledge (KNOWN_ENCLAVE_MEASUREMENTS, from
|
|
45
|
+
* server/commit-service/reproducible-build/PINS.md). A measurement outside
|
|
46
|
+
* that list is UNDETERMINED, never FALSE: it is beyond what this build of
|
|
47
|
+
* the verifier knows, which is exactly how an offline verifier should age.
|
|
48
|
+
*
|
|
49
|
+
* Determinism. The report contains no wall-clock time, no machine path, and
|
|
50
|
+
* no run-local value; bundle-relative entry paths are bundle content and
|
|
51
|
+
* are allowed. Same bundle bytes, same report bytes.
|
|
52
|
+
*/
|
|
53
|
+
import type { AuditResult, IngestResult } from "@mikeargento/bitgraph-audit";
|
|
54
|
+
import type { ThreeValued } from "./types.js";
|
|
55
|
+
/**
|
|
56
|
+
* Published BitGraph enclave PCR0 measurements, per PINS.md, oldest first.
|
|
57
|
+
* Each remains correct for proofs minted during its own period; a proof
|
|
58
|
+
* carries its own measurement, so nothing here needs to be "current" for
|
|
59
|
+
* an old proof to check. Lowercase hex, exactly as attestations report.
|
|
60
|
+
*/
|
|
61
|
+
export declare const KNOWN_ENCLAVE_MEASUREMENTS: ReadonlyArray<{
|
|
62
|
+
pcr0: string;
|
|
63
|
+
label: string;
|
|
64
|
+
period: string;
|
|
65
|
+
}>;
|
|
66
|
+
/** One checked property, three-valued, with a plain-language reason. */
|
|
67
|
+
export interface CheckLine {
|
|
68
|
+
name: "file" | "signature" | "attestation" | "enclave" | "witness" | "contradiction";
|
|
69
|
+
result: ThreeValued;
|
|
70
|
+
detail: string;
|
|
71
|
+
}
|
|
72
|
+
/** A verified Ethereum bound on a recording, from a witness in the bundle. */
|
|
73
|
+
export interface CheckBound {
|
|
74
|
+
blockNumber?: string;
|
|
75
|
+
blockHash: string;
|
|
76
|
+
/** Unix seconds from the verified block header. */
|
|
77
|
+
timestamp: number;
|
|
78
|
+
anchorProofHash: string;
|
|
79
|
+
evidence: "chain-link" | "counter-order";
|
|
80
|
+
weaker: boolean;
|
|
81
|
+
}
|
|
82
|
+
export interface CheckBounds {
|
|
83
|
+
status: "bracketed" | "lower-bounded" | "upper-bounded" | "unanchored";
|
|
84
|
+
notBefore?: CheckBound;
|
|
85
|
+
notAfter?: CheckBound;
|
|
86
|
+
detail: string;
|
|
87
|
+
}
|
|
88
|
+
/** A non-anchor recording in the bundle. */
|
|
89
|
+
export interface CheckRecording {
|
|
90
|
+
proofHash: string;
|
|
91
|
+
digestB64: string;
|
|
92
|
+
epochId?: string;
|
|
93
|
+
chainId: string;
|
|
94
|
+
counter?: string;
|
|
95
|
+
slotCounter?: string;
|
|
96
|
+
publicKeyB64?: string;
|
|
97
|
+
/** Bundle-relative path of the matched artifact, when its bytes were present. */
|
|
98
|
+
filePath?: string;
|
|
99
|
+
lines: CheckLine[];
|
|
100
|
+
/** Kleene all over `lines`. */
|
|
101
|
+
result: ThreeValued;
|
|
102
|
+
bounds: CheckBounds;
|
|
103
|
+
}
|
|
104
|
+
/** An Ethereum anchor recording in the bundle. */
|
|
105
|
+
export interface CheckAnchor {
|
|
106
|
+
proofHash: string;
|
|
107
|
+
epochId?: string;
|
|
108
|
+
chainId: string;
|
|
109
|
+
counter?: string;
|
|
110
|
+
blockNumber?: string;
|
|
111
|
+
blockHash?: string;
|
|
112
|
+
/** Bundle-relative path of the witness file, when one matched this anchor. */
|
|
113
|
+
witnessPath?: string;
|
|
114
|
+
lines: CheckLine[];
|
|
115
|
+
result: ThreeValued;
|
|
116
|
+
}
|
|
117
|
+
export interface CheckReport {
|
|
118
|
+
check: "bitgraph-check/1";
|
|
119
|
+
result: ThreeValued;
|
|
120
|
+
/** One-sentence plain-language conclusion, deterministic. */
|
|
121
|
+
summary: string;
|
|
122
|
+
recordings: CheckRecording[];
|
|
123
|
+
anchors: CheckAnchor[];
|
|
124
|
+
/** Structural findings the bundle contradicts itself on. Every entry is FALSE. */
|
|
125
|
+
contradictions: CheckLine[];
|
|
126
|
+
/** Informational: excerpt gaps, unmatched files, duplicates. Never verdicts. */
|
|
127
|
+
notes: string[];
|
|
128
|
+
/** What no offline check can establish, stated rather than implied. */
|
|
129
|
+
notChecked: string[];
|
|
130
|
+
evaluator: {
|
|
131
|
+
name: "bitgraph-player";
|
|
132
|
+
version: string;
|
|
133
|
+
audit: string;
|
|
134
|
+
};
|
|
135
|
+
network: "none";
|
|
136
|
+
}
|
|
137
|
+
export interface CheckOptions {
|
|
138
|
+
/**
|
|
139
|
+
* False when the environment cannot run the attestation's ECDSA P-384
|
|
140
|
+
* verification (no WebCrypto). Attestation lines are then UNDETERMINED
|
|
141
|
+
* with that reason instead of a false FALSE. Defaults to true.
|
|
142
|
+
*/
|
|
143
|
+
webCryptoAvailable?: boolean;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Check an already-ingested bundle: runs the audit's pure tail (no
|
|
147
|
+
* filesystem, no network) and builds the report. Both the CLI and the
|
|
148
|
+
* browser page call this, so they cannot drift.
|
|
149
|
+
*/
|
|
150
|
+
export declare function checkIngest(ingest: IngestResult, options?: CheckOptions): Promise<CheckReport>;
|
|
151
|
+
/** The pure report builder over an AuditResult. */
|
|
152
|
+
export declare function buildCheckReport(audit: AuditResult, options?: CheckOptions): CheckReport;
|
|
153
|
+
export declare function renderCheckText(report: CheckReport): string;
|
|
154
|
+
/** Deterministic JSON bytes for the report: two-space indent, one trailing newline. */
|
|
155
|
+
export declare function serializeCheckReport(report: CheckReport): string;
|
|
156
|
+
//# sourceMappingURL=check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAEH,OAAO,KAAK,EAEV,WAAW,EAEX,YAAY,EAKb,MAAM,6BAA6B,CAAC;AAErC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAQ9C;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,EAAE,aAAa,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAqBrG,CAAC;AAMF,wEAAwE;AACxE,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,eAAe,CAAC;IACrF,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,YAAY,GAAG,eAAe,CAAC;IACzC,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,WAAW,GAAG,eAAe,GAAG,eAAe,GAAG,YAAY,CAAC;IACvE,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,4CAA4C;AAC5C,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,+BAA+B;IAC/B,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,kDAAkD;AAClD,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,MAAM,EAAE,WAAW,CAAC;IACpB,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,kFAAkF;IAClF,cAAc,EAAE,SAAS,EAAE,CAAC;IAC5B,gFAAgF;IAChF,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,uEAAuE;IACvE,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE;QAAE,IAAI,EAAE,iBAAiB,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACvE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAwBD;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAGpG;AAED,mDAAmD;AACnD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,WAAW,CAuExF;AAqgBD,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAuC3D;AAED,uFAAuF;AACvF,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAEhE"}
|