@mikeargento/bitgraph 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +49 -40
- package/dist/__tests__/audit-anchors.test.d.ts +2 -0
- package/dist/__tests__/audit-anchors.test.d.ts.map +1 -0
- package/dist/__tests__/audit-anchors.test.js +152 -0
- package/dist/__tests__/audit-anchors.test.js.map +1 -0
- package/dist/__tests__/audit-anomalies.test.d.ts +2 -0
- package/dist/__tests__/audit-anomalies.test.d.ts.map +1 -0
- package/dist/__tests__/audit-anomalies.test.js +663 -0
- package/dist/__tests__/audit-anomalies.test.js.map +1 -0
- package/dist/__tests__/audit-attestation.test.d.ts +2 -0
- package/dist/__tests__/audit-attestation.test.d.ts.map +1 -0
- package/dist/__tests__/audit-attestation.test.js +403 -0
- package/dist/__tests__/audit-attestation.test.js.map +1 -0
- package/dist/__tests__/audit-bench-smoke.test.d.ts +2 -0
- package/dist/__tests__/audit-bench-smoke.test.d.ts.map +1 -0
- package/dist/__tests__/audit-bench-smoke.test.js +87 -0
- package/dist/__tests__/audit-bench-smoke.test.js.map +1 -0
- package/dist/__tests__/audit-boundary.test.d.ts +20 -0
- package/dist/__tests__/audit-boundary.test.d.ts.map +1 -0
- package/dist/__tests__/audit-boundary.test.js +84 -0
- package/dist/__tests__/audit-boundary.test.js.map +1 -0
- package/dist/__tests__/audit-cli.test.d.ts +2 -0
- package/dist/__tests__/audit-cli.test.d.ts.map +1 -0
- package/dist/__tests__/audit-cli.test.js +239 -0
- package/dist/__tests__/audit-cli.test.js.map +1 -0
- package/dist/__tests__/audit-dependencies.test.d.ts +2 -0
- package/dist/__tests__/audit-dependencies.test.d.ts.map +1 -0
- package/dist/__tests__/audit-dependencies.test.js +116 -0
- package/dist/__tests__/audit-dependencies.test.js.map +1 -0
- package/dist/__tests__/audit-fixtures.d.ts +265 -0
- package/dist/__tests__/audit-fixtures.d.ts.map +1 -0
- package/dist/__tests__/audit-fixtures.js +511 -0
- package/dist/__tests__/audit-fixtures.js.map +1 -0
- package/dist/__tests__/audit-ingest.test.d.ts +2 -0
- package/dist/__tests__/audit-ingest.test.d.ts.map +1 -0
- package/dist/__tests__/audit-ingest.test.js +473 -0
- package/dist/__tests__/audit-ingest.test.js.map +1 -0
- package/dist/__tests__/audit-memory-ingest.test.d.ts +12 -0
- package/dist/__tests__/audit-memory-ingest.test.d.ts.map +1 -0
- package/dist/__tests__/audit-memory-ingest.test.js +120 -0
- package/dist/__tests__/audit-memory-ingest.test.js.map +1 -0
- package/dist/__tests__/audit-property.test.d.ts +2 -0
- package/dist/__tests__/audit-property.test.d.ts.map +1 -0
- package/dist/__tests__/audit-property.test.js +771 -0
- package/dist/__tests__/audit-property.test.js.map +1 -0
- package/dist/__tests__/audit-real-fixtures.test.d.ts +2 -0
- package/dist/__tests__/audit-real-fixtures.test.d.ts.map +1 -0
- package/dist/__tests__/audit-real-fixtures.test.js +132 -0
- package/dist/__tests__/audit-real-fixtures.test.js.map +1 -0
- package/dist/__tests__/audit-real-live.test.d.ts +2 -0
- package/dist/__tests__/audit-real-live.test.d.ts.map +1 -0
- package/dist/__tests__/audit-real-live.test.js +107 -0
- package/dist/__tests__/audit-real-live.test.js.map +1 -0
- package/dist/__tests__/audit-reconstruct.test.d.ts +2 -0
- package/dist/__tests__/audit-reconstruct.test.d.ts.map +1 -0
- package/dist/__tests__/audit-reconstruct.test.js +287 -0
- package/dist/__tests__/audit-reconstruct.test.js.map +1 -0
- package/dist/__tests__/audit-report.test.d.ts +2 -0
- package/dist/__tests__/audit-report.test.d.ts.map +1 -0
- package/dist/__tests__/audit-report.test.js +186 -0
- package/dist/__tests__/audit-report.test.js.map +1 -0
- package/dist/__tests__/audit-roundtrip.test.d.ts +2 -0
- package/dist/__tests__/audit-roundtrip.test.d.ts.map +1 -0
- package/dist/__tests__/audit-roundtrip.test.js +368 -0
- package/dist/__tests__/audit-roundtrip.test.js.map +1 -0
- package/dist/__tests__/audit-temporal.test.d.ts +2 -0
- package/dist/__tests__/audit-temporal.test.d.ts.map +1 -0
- package/dist/__tests__/audit-temporal.test.js +364 -0
- package/dist/__tests__/audit-temporal.test.js.map +1 -0
- package/dist/__tests__/audit-tiers.test.d.ts +2 -0
- package/dist/__tests__/audit-tiers.test.d.ts.map +1 -0
- package/dist/__tests__/audit-tiers.test.js +282 -0
- package/dist/__tests__/audit-tiers.test.js.map +1 -0
- package/dist/__tests__/audit-witness-real.test.d.ts +19 -0
- package/dist/__tests__/audit-witness-real.test.d.ts.map +1 -0
- package/dist/__tests__/audit-witness-real.test.js +82 -0
- package/dist/__tests__/audit-witness-real.test.js.map +1 -0
- package/dist/__tests__/audit-witness.test.d.ts +2 -0
- package/dist/__tests__/audit-witness.test.d.ts.map +1 -0
- package/dist/__tests__/audit-witness.test.js +308 -0
- package/dist/__tests__/audit-witness.test.js.map +1 -0
- package/dist/__tests__/chain-hash-anchor.test.d.ts +22 -0
- package/dist/__tests__/chain-hash-anchor.test.d.ts.map +1 -0
- package/dist/__tests__/chain-hash-anchor.test.js +55 -0
- package/dist/__tests__/chain-hash-anchor.test.js.map +1 -0
- package/dist/__tests__/declared-proof-fixture.d.ts +66 -0
- package/dist/__tests__/declared-proof-fixture.d.ts.map +1 -0
- package/dist/__tests__/declared-proof-fixture.js +66 -0
- package/dist/__tests__/declared-proof-fixture.js.map +1 -0
- package/dist/__tests__/fuse-roundtrip.test.d.ts +2 -0
- package/dist/__tests__/fuse-roundtrip.test.d.ts.map +1 -0
- package/dist/__tests__/fuse-roundtrip.test.js +172 -0
- package/dist/__tests__/fuse-roundtrip.test.js.map +1 -0
- package/dist/__tests__/fuse-sdk.test.d.ts +2 -0
- package/dist/__tests__/fuse-sdk.test.d.ts.map +1 -0
- package/dist/__tests__/fuse-sdk.test.js +117 -0
- package/dist/__tests__/fuse-sdk.test.js.map +1 -0
- package/dist/__tests__/fuse-vectors.test.d.ts +2 -0
- package/dist/__tests__/fuse-vectors.test.d.ts.map +1 -0
- package/dist/__tests__/fuse-vectors.test.js +175 -0
- package/dist/__tests__/fuse-vectors.test.js.map +1 -0
- package/dist/__tests__/fuse-verify.test.d.ts +2 -0
- package/dist/__tests__/fuse-verify.test.d.ts.map +1 -0
- package/dist/__tests__/fuse-verify.test.js +250 -0
- package/dist/__tests__/fuse-verify.test.js.map +1 -0
- package/dist/__tests__/mock-proof-fixture.d.ts +15 -0
- package/dist/__tests__/mock-proof-fixture.d.ts.map +1 -0
- package/dist/__tests__/mock-proof-fixture.js +34 -0
- package/dist/__tests__/mock-proof-fixture.js.map +1 -0
- package/dist/__tests__/proof-hash-regression.test.js +4 -43
- package/dist/__tests__/proof-hash-regression.test.js.map +1 -1
- package/dist/__tests__/proof-hash.test.js +3 -21
- package/dist/__tests__/proof-hash.test.js.map +1 -1
- package/dist/__tests__/proof-integrity.test.d.ts +2 -0
- package/dist/__tests__/proof-integrity.test.d.ts.map +1 -0
- package/dist/__tests__/proof-integrity.test.js +426 -0
- package/dist/__tests__/proof-integrity.test.js.map +1 -0
- package/dist/__tests__/realistic-proof-fixture.d.ts +56 -0
- package/dist/__tests__/realistic-proof-fixture.d.ts.map +1 -0
- package/dist/__tests__/realistic-proof-fixture.js +57 -0
- package/dist/__tests__/realistic-proof-fixture.js.map +1 -0
- package/dist/__tests__/verifier.test.js +74 -0
- package/dist/__tests__/verifier.test.js.map +1 -1
- package/dist/fuse-cli.d.ts +3 -0
- package/dist/fuse-cli.d.ts.map +1 -0
- package/dist/fuse-cli.js +210 -0
- package/dist/fuse-cli.js.map +1 -0
- package/dist/fuse.d.ts +75 -0
- package/dist/fuse.d.ts.map +1 -0
- package/dist/fuse.js +273 -0
- package/dist/fuse.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/package.json +19 -9
- package/src/__tests__/audit-anchors.test.ts +188 -0
- package/src/__tests__/audit-anomalies.test.ts +815 -0
- package/src/__tests__/audit-attestation.test.ts +529 -0
- package/src/__tests__/audit-bench-smoke.test.ts +108 -0
- package/src/__tests__/audit-boundary.test.ts +96 -0
- package/src/__tests__/audit-cli.test.ts +288 -0
- package/src/__tests__/audit-dependencies.test.ts +141 -0
- package/src/__tests__/audit-fixtures.ts +736 -0
- package/src/__tests__/audit-ingest.test.ts +575 -0
- package/src/__tests__/audit-memory-ingest.test.ts +140 -0
- package/src/__tests__/audit-property.test.ts +892 -0
- package/src/__tests__/audit-real-fixtures.test.ts +153 -0
- package/src/__tests__/audit-real-live.test.ts +128 -0
- package/src/__tests__/audit-reconstruct.test.ts +353 -0
- package/src/__tests__/audit-report.test.ts +222 -0
- package/src/__tests__/audit-roundtrip.test.ts +464 -0
- package/src/__tests__/audit-temporal.test.ts +446 -0
- package/src/__tests__/audit-tiers.test.ts +343 -0
- package/src/__tests__/audit-witness-real.test.ts +92 -0
- package/src/__tests__/audit-witness.test.ts +345 -0
- package/src/__tests__/chain-hash-anchor.test.ts +67 -0
- package/src/__tests__/declared-proof-fixture.ts +65 -0
- package/src/__tests__/fuse-roundtrip.test.ts +174 -0
- package/src/__tests__/fuse-sdk.test.ts +142 -0
- package/src/__tests__/fuse-vectors.test.ts +218 -0
- package/src/__tests__/fuse-verify.test.ts +278 -0
- package/src/__tests__/mock-proof-fixture.ts +36 -0
- package/src/__tests__/proof-hash-regression.test.ts +4 -44
- package/src/__tests__/proof-hash.test.ts +3 -22
- package/src/__tests__/proof-integrity.test.ts +541 -0
- package/src/__tests__/real-fixtures/anchor-after-112762.json +47 -0
- package/src/__tests__/real-fixtures/anchor-with-ethereum-112758.json +47 -0
- package/src/__tests__/real-fixtures/live-proof-0.json +42 -0
- package/src/__tests__/real-fixtures/live-proof-1.json +43 -0
- package/src/__tests__/real-fixtures/live-proof-2.json +43 -0
- package/src/__tests__/real-fixtures/successor-112760.json +38 -0
- package/src/__tests__/real-fixtures/witness-25525146.json +6 -0
- package/src/__tests__/real-fixtures/witness-25525147.json +6 -0
- package/src/__tests__/realistic-proof-fixture.ts +57 -0
- package/src/__tests__/verifier.test.ts +83 -0
- package/src/fuse-cli.ts +187 -0
- package/src/fuse.ts +356 -0
- package/src/index.ts +6 -0
- package/dist/canonical.d.ts +0 -54
- package/dist/canonical.d.ts.map +0 -1
- package/dist/canonical.js +0 -119
- package/dist/canonical.js.map +0 -1
- package/dist/proof-hash.d.ts +0 -9
- package/dist/proof-hash.d.ts.map +0 -1
- package/dist/proof-hash.js +0 -75
- package/dist/proof-hash.js.map +0 -1
- package/dist/types.d.ts +0 -705
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -3
- package/dist/types.js.map +0 -1
- package/dist/verifier.d.ts +0 -27
- package/dist/verifier.d.ts.map +0 -1
- package/dist/verifier.js +0 -844
- package/dist/verifier.js.map +0 -1
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
// Copyright (c) Mike Argento. All rights reserved. See LICENSE.
|
|
2
|
+
/**
|
|
3
|
+
* Tests for verifyProofIntegrity, the bytes-free proof integrity API in
|
|
4
|
+
* @mikeargento/bitgraph-verify.
|
|
5
|
+
*
|
|
6
|
+
* Also carries regression coverage asserting that verify() behavior is
|
|
7
|
+
* unchanged by the shared-pipeline refactor: same checks, same order,
|
|
8
|
+
* same failure strings.
|
|
9
|
+
*/
|
|
10
|
+
import { describe, test, before, beforeEach } from "node:test";
|
|
11
|
+
import * as assert from "node:assert/strict";
|
|
12
|
+
import { getPublicKeyAsync, signAsync } from "@noble/ed25519";
|
|
13
|
+
import { sha256 } from "@noble/hashes/sha256";
|
|
14
|
+
import { verify, verifyProofIntegrity, resetEpochLinkState, canonicalize, } from "@mikeargento/bitgraph-verify";
|
|
15
|
+
import { Constructor } from "../constructor.js";
|
|
16
|
+
/** Constructor-built fixture, mirroring makeFixture in verifier.test.ts. */
|
|
17
|
+
async function makeFixture(opts) {
|
|
18
|
+
const privateKey = crypto.getRandomValues(new Uint8Array(32));
|
|
19
|
+
const publicKeyBytes = await getPublicKeyAsync(privateKey);
|
|
20
|
+
const publicKeyB64 = Buffer.from(publicKeyBytes).toString("base64");
|
|
21
|
+
const measurement = "test-measurement-integrity";
|
|
22
|
+
let counter = 0;
|
|
23
|
+
const host = opts?.withCounter
|
|
24
|
+
? {
|
|
25
|
+
enforcementTier: "stub",
|
|
26
|
+
getMeasurement: async () => measurement,
|
|
27
|
+
getFreshNonce: async () => crypto.getRandomValues(new Uint8Array(16)),
|
|
28
|
+
sign: async (data) => signAsync(data, privateKey),
|
|
29
|
+
getPublicKey: async () => publicKeyBytes,
|
|
30
|
+
nextCounter: async () => String(++counter),
|
|
31
|
+
}
|
|
32
|
+
: {
|
|
33
|
+
enforcementTier: "stub",
|
|
34
|
+
getMeasurement: async () => measurement,
|
|
35
|
+
getFreshNonce: async () => crypto.getRandomValues(new Uint8Array(16)),
|
|
36
|
+
sign: async (data) => signAsync(data, privateKey),
|
|
37
|
+
getPublicKey: async () => publicKeyBytes,
|
|
38
|
+
};
|
|
39
|
+
const ctor = await Constructor.initialize(opts?.epochId !== undefined ? { host, epochId: opts.epochId } : { host });
|
|
40
|
+
const bytes = new TextEncoder().encode("bitgraph-integrity-test-payload");
|
|
41
|
+
const proof = await ctor.commit({ bytes });
|
|
42
|
+
return { proof, bytes, publicKeyB64, measurement };
|
|
43
|
+
}
|
|
44
|
+
/** Deep-clone a proof so mutations don't affect the original. */
|
|
45
|
+
function clone(proof) {
|
|
46
|
+
return JSON.parse(JSON.stringify(proof));
|
|
47
|
+
}
|
|
48
|
+
function b64(bytes) {
|
|
49
|
+
return Buffer.from(bytes).toString("base64");
|
|
50
|
+
}
|
|
51
|
+
async function makeKey() {
|
|
52
|
+
const privateKey = crypto.getRandomValues(new Uint8Array(32));
|
|
53
|
+
const publicKeyB64 = b64(await getPublicKeyAsync(privateKey));
|
|
54
|
+
return { privateKey, publicKeyB64 };
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Manually build and sign a proof over the exact canonical SignedBody
|
|
58
|
+
* layout the verifier reconstructs. Used for slot-carrying and
|
|
59
|
+
* epochLink-carrying proofs, which the root Constructor does not produce.
|
|
60
|
+
*/
|
|
61
|
+
async function signBody(key, artifact, commit, measurement) {
|
|
62
|
+
const signedBody = {
|
|
63
|
+
version: "bitgraph/1",
|
|
64
|
+
artifact,
|
|
65
|
+
commit,
|
|
66
|
+
publicKeyB64: key.publicKeyB64,
|
|
67
|
+
enforcement: "stub",
|
|
68
|
+
measurement,
|
|
69
|
+
};
|
|
70
|
+
const signatureB64 = b64(await signAsync(canonicalize(signedBody), key.privateKey));
|
|
71
|
+
return {
|
|
72
|
+
version: "bitgraph/1",
|
|
73
|
+
artifact,
|
|
74
|
+
commit,
|
|
75
|
+
signer: { publicKeyB64: key.publicKeyB64, signatureB64 },
|
|
76
|
+
environment: { enforcement: "stub", measurement },
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Build a slot-carrying proof: slot allocated at counter 1, commit at
|
|
81
|
+
* counter 2, slotHashB64 binding the signed commit to the exact slot body.
|
|
82
|
+
*/
|
|
83
|
+
async function makeSlotFixture(opts) {
|
|
84
|
+
const key = await makeKey();
|
|
85
|
+
const measurement = "test-measurement-slot";
|
|
86
|
+
const epochId = "epoch-slot-test";
|
|
87
|
+
const nonceB64 = b64(crypto.getRandomValues(new Uint8Array(16)));
|
|
88
|
+
const slotBody = {
|
|
89
|
+
version: "bitgraph/slot/1",
|
|
90
|
+
nonceB64,
|
|
91
|
+
counter: "1",
|
|
92
|
+
time: 1_700_000_000_000,
|
|
93
|
+
epochId,
|
|
94
|
+
publicKeyB64: key.publicKeyB64,
|
|
95
|
+
};
|
|
96
|
+
const slotCanonical = canonicalize(slotBody);
|
|
97
|
+
const slotSignatureB64 = b64(await signAsync(slotCanonical, key.privateKey));
|
|
98
|
+
const slotHashB64 = b64(sha256(slotCanonical));
|
|
99
|
+
const bytes = new TextEncoder().encode("bitgraph-integrity-slot-payload");
|
|
100
|
+
const artifact = {
|
|
101
|
+
hashAlg: "sha256",
|
|
102
|
+
digestB64: b64(sha256(bytes)),
|
|
103
|
+
};
|
|
104
|
+
const commit = {
|
|
105
|
+
nonceB64,
|
|
106
|
+
counter: opts?.commitCounter ?? "2",
|
|
107
|
+
epochId,
|
|
108
|
+
slotCounter: "1",
|
|
109
|
+
slotHashB64,
|
|
110
|
+
};
|
|
111
|
+
const proof = await signBody(key, artifact, commit, measurement);
|
|
112
|
+
proof.slotAllocation = { ...slotBody, signatureB64: slotSignatureB64 };
|
|
113
|
+
return { proof, bytes, measurement };
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Build an epoch-genesis proof carrying an epochLink. The link is inside
|
|
117
|
+
* the signed commit, so the Ed25519 signature covers it.
|
|
118
|
+
*/
|
|
119
|
+
async function makeEpochLinkFixture(opts) {
|
|
120
|
+
const key = await makeKey();
|
|
121
|
+
const prevKey = await makeKey();
|
|
122
|
+
const toEpochId = opts?.toEpochId ?? "epoch-successor-a";
|
|
123
|
+
const epochLink = {
|
|
124
|
+
prevEpochId: "epoch-predecessor-a",
|
|
125
|
+
prevPublicKeyB64: opts?.samePrevKey === true ? key.publicKeyB64 : prevKey.publicKeyB64,
|
|
126
|
+
prevCounter: "42",
|
|
127
|
+
prevProofHashB64: b64(sha256(new TextEncoder().encode("predecessor-terminal-proof"))),
|
|
128
|
+
toEpochId,
|
|
129
|
+
toPublicKeyB64: key.publicKeyB64,
|
|
130
|
+
};
|
|
131
|
+
const bytes = new TextEncoder().encode("bitgraph-integrity-epochlink-payload");
|
|
132
|
+
const artifact = {
|
|
133
|
+
hashAlg: "sha256",
|
|
134
|
+
digestB64: b64(sha256(bytes)),
|
|
135
|
+
};
|
|
136
|
+
const commit = {
|
|
137
|
+
nonceB64: b64(crypto.getRandomValues(new Uint8Array(16))),
|
|
138
|
+
counter: "1",
|
|
139
|
+
epochId: toEpochId,
|
|
140
|
+
epochLink,
|
|
141
|
+
};
|
|
142
|
+
const proof = await signBody(key, artifact, commit, "test-measurement-epochlink");
|
|
143
|
+
return { proof, bytes };
|
|
144
|
+
}
|
|
145
|
+
// ---------------------------------------------------------------------------
|
|
146
|
+
// Module-level fixtures
|
|
147
|
+
// ---------------------------------------------------------------------------
|
|
148
|
+
let fx;
|
|
149
|
+
before(async () => {
|
|
150
|
+
fx = await makeFixture();
|
|
151
|
+
});
|
|
152
|
+
// ---------------------------------------------------------------------------
|
|
153
|
+
// Happy path: integrity without bytes
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
155
|
+
describe("verifyProofIntegrity: valid proof, no bytes", () => {
|
|
156
|
+
test("passes for a freshly created proof and reports binding not checked", async () => {
|
|
157
|
+
const result = await verifyProofIntegrity({ proof: fx.proof });
|
|
158
|
+
assert.deepEqual(result, { valid: true, artifactBinding: "not-checked" });
|
|
159
|
+
});
|
|
160
|
+
test("passes for a proof with counter and epochId", async () => {
|
|
161
|
+
const chained = await makeFixture({ withCounter: true, epochId: "epoch-integrity-xyz" });
|
|
162
|
+
const result = await verifyProofIntegrity({ proof: chained.proof });
|
|
163
|
+
assert.deepEqual(result, { valid: true, artifactBinding: "not-checked" });
|
|
164
|
+
});
|
|
165
|
+
test("passes even when verify() with wrong bytes fails: binding is genuinely not checked", async () => {
|
|
166
|
+
const wrongBytes = new Uint8Array([1, 2, 3]);
|
|
167
|
+
const full = await verify({ proof: fx.proof, bytes: wrongBytes });
|
|
168
|
+
assert.equal(full.valid, false);
|
|
169
|
+
assert.match(full.reason ?? "", /digest mismatch/);
|
|
170
|
+
const integrity = await verifyProofIntegrity({ proof: fx.proof });
|
|
171
|
+
assert.deepEqual(integrity, { valid: true, artifactBinding: "not-checked" });
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
// ---------------------------------------------------------------------------
|
|
175
|
+
// Result shape
|
|
176
|
+
// ---------------------------------------------------------------------------
|
|
177
|
+
describe("verifyProofIntegrity: result shape", () => {
|
|
178
|
+
test("failure result also carries artifactBinding 'not-checked' plus a reason", async () => {
|
|
179
|
+
const tampered = clone(fx.proof);
|
|
180
|
+
tampered.signer.signatureB64 = Buffer.alloc(64).toString("base64");
|
|
181
|
+
const result = await verifyProofIntegrity({ proof: tampered });
|
|
182
|
+
assert.equal(result.valid, false);
|
|
183
|
+
assert.equal(result.artifactBinding, "not-checked");
|
|
184
|
+
assert.equal(typeof result.reason, "string");
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
// ---------------------------------------------------------------------------
|
|
188
|
+
// Tampering
|
|
189
|
+
// ---------------------------------------------------------------------------
|
|
190
|
+
describe("verifyProofIntegrity: tampering", () => {
|
|
191
|
+
test("fails when signatureB64 is replaced with all-zeros", async () => {
|
|
192
|
+
const tampered = clone(fx.proof);
|
|
193
|
+
tampered.signer.signatureB64 = Buffer.alloc(64).toString("base64");
|
|
194
|
+
const result = await verifyProofIntegrity({ proof: tampered });
|
|
195
|
+
assert.equal(result.valid, false);
|
|
196
|
+
assert.match(result.reason ?? "", /signature/);
|
|
197
|
+
});
|
|
198
|
+
test("fails when version is tampered, with a version reason", async () => {
|
|
199
|
+
const tampered = clone(fx.proof);
|
|
200
|
+
tampered["version"] = "bitgraph/2";
|
|
201
|
+
const result = await verifyProofIntegrity({ proof: tampered });
|
|
202
|
+
assert.equal(result.valid, false);
|
|
203
|
+
assert.equal(result.reason, "unsupported proof version: bitgraph/2");
|
|
204
|
+
});
|
|
205
|
+
test("fails when a signed field (measurement) is tampered", async () => {
|
|
206
|
+
const tampered = clone(fx.proof);
|
|
207
|
+
tampered.environment.measurement = "evil-measurement";
|
|
208
|
+
const result = await verifyProofIntegrity({ proof: tampered });
|
|
209
|
+
assert.equal(result.valid, false);
|
|
210
|
+
assert.match(result.reason ?? "", /signature/);
|
|
211
|
+
});
|
|
212
|
+
test("fails when artifact.digestB64 is not valid base64 (well-formedness still checked)", async () => {
|
|
213
|
+
const tampered = clone(fx.proof);
|
|
214
|
+
tampered.artifact.digestB64 = "!!!";
|
|
215
|
+
const result = await verifyProofIntegrity({ proof: tampered });
|
|
216
|
+
assert.equal(result.valid, false);
|
|
217
|
+
assert.equal(result.reason, "artifact.digestB64 is not valid base64");
|
|
218
|
+
});
|
|
219
|
+
test("fails for non-object proof", async () => {
|
|
220
|
+
const result = await verifyProofIntegrity({
|
|
221
|
+
proof: "not-a-proof",
|
|
222
|
+
});
|
|
223
|
+
assert.equal(result.valid, false);
|
|
224
|
+
assert.match(result.reason ?? "", /object/);
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
// ---------------------------------------------------------------------------
|
|
228
|
+
// Slot allocation (bytes-free)
|
|
229
|
+
// ---------------------------------------------------------------------------
|
|
230
|
+
describe("verifyProofIntegrity: slot allocation", () => {
|
|
231
|
+
test("passes for a valid slot-carrying proof", async () => {
|
|
232
|
+
const slotFx = await makeSlotFixture();
|
|
233
|
+
const result = await verifyProofIntegrity({ proof: slotFx.proof });
|
|
234
|
+
assert.deepEqual(result, { valid: true, artifactBinding: "not-checked" });
|
|
235
|
+
});
|
|
236
|
+
test("fails when commit.slotHashB64 is tampered (signed field)", async () => {
|
|
237
|
+
const slotFx = await makeSlotFixture();
|
|
238
|
+
const tampered = clone(slotFx.proof);
|
|
239
|
+
tampered.commit.slotHashB64 = Buffer.alloc(32, 0xee).toString("base64");
|
|
240
|
+
const result = await verifyProofIntegrity({ proof: tampered });
|
|
241
|
+
assert.equal(result.valid, false);
|
|
242
|
+
assert.match(result.reason ?? "", /signature/);
|
|
243
|
+
});
|
|
244
|
+
test("fails with a slot binding reason when the embedded slot record is swapped", async () => {
|
|
245
|
+
const slotA = await makeSlotFixture();
|
|
246
|
+
const slotB = await makeSlotFixture();
|
|
247
|
+
const tampered = clone(slotA.proof);
|
|
248
|
+
// slotB's record is validly signed by its own key, but it is not the
|
|
249
|
+
// record that slotA's signed commit.slotHashB64 binds to.
|
|
250
|
+
tampered.slotAllocation = clone(slotB.proof).slotAllocation;
|
|
251
|
+
const result = await verifyProofIntegrity({ proof: tampered });
|
|
252
|
+
assert.equal(result.valid, false);
|
|
253
|
+
assert.match(result.reason ?? "", /slotHashB64 does not match SHA-256 of canonical slot body/);
|
|
254
|
+
});
|
|
255
|
+
test("fails when slotAllocation.counter is tampered (slot signature breaks)", async () => {
|
|
256
|
+
const slotFx = await makeSlotFixture();
|
|
257
|
+
const tampered = clone(slotFx.proof);
|
|
258
|
+
tampered.slotAllocation.counter = "999";
|
|
259
|
+
const result = await verifyProofIntegrity({ proof: tampered });
|
|
260
|
+
assert.equal(result.valid, false);
|
|
261
|
+
assert.match(result.reason ?? "", /slotAllocation signature verification failed/);
|
|
262
|
+
});
|
|
263
|
+
test("fails when slot counter is not less than commit counter", async () => {
|
|
264
|
+
// Slot at counter 1, commit also at counter 1: ordering violated even
|
|
265
|
+
// though every signature is genuine.
|
|
266
|
+
const slotFx = await makeSlotFixture({ commitCounter: "1" });
|
|
267
|
+
const result = await verifyProofIntegrity({ proof: slotFx.proof });
|
|
268
|
+
assert.equal(result.valid, false);
|
|
269
|
+
assert.match(result.reason ?? "", /must be less than commit\.counter/);
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
// ---------------------------------------------------------------------------
|
|
273
|
+
// Epoch link (bytes-free)
|
|
274
|
+
// ---------------------------------------------------------------------------
|
|
275
|
+
describe("verifyProofIntegrity: epochLink", () => {
|
|
276
|
+
beforeEach(() => {
|
|
277
|
+
resetEpochLinkState();
|
|
278
|
+
});
|
|
279
|
+
test("passes for a valid epoch-genesis proof with epochLink", async () => {
|
|
280
|
+
const linkFx = await makeEpochLinkFixture();
|
|
281
|
+
const result = await verifyProofIntegrity({ proof: linkFx.proof });
|
|
282
|
+
assert.deepEqual(result, { valid: true, artifactBinding: "not-checked" });
|
|
283
|
+
});
|
|
284
|
+
test("is idempotent for the same successor epoch", async () => {
|
|
285
|
+
const linkFx = await makeEpochLinkFixture();
|
|
286
|
+
const first = await verifyProofIntegrity({ proof: linkFx.proof });
|
|
287
|
+
const second = await verifyProofIntegrity({ proof: linkFx.proof });
|
|
288
|
+
assert.equal(first.valid, true);
|
|
289
|
+
assert.equal(second.valid, true);
|
|
290
|
+
});
|
|
291
|
+
test("fails when predecessor and successor keys are identical", async () => {
|
|
292
|
+
const linkFx = await makeEpochLinkFixture({ samePrevKey: true });
|
|
293
|
+
const result = await verifyProofIntegrity({ proof: linkFx.proof });
|
|
294
|
+
assert.equal(result.valid, false);
|
|
295
|
+
assert.match(result.reason ?? "", /different keys/);
|
|
296
|
+
});
|
|
297
|
+
test("detects a fork: same predecessor consumed by two successor epochs", async () => {
|
|
298
|
+
const first = await makeEpochLinkFixture({ toEpochId: "epoch-successor-a" });
|
|
299
|
+
const second = await makeEpochLinkFixture({ toEpochId: "epoch-successor-b" });
|
|
300
|
+
const r1 = await verifyProofIntegrity({ proof: first.proof });
|
|
301
|
+
assert.equal(r1.valid, true);
|
|
302
|
+
const r2 = await verifyProofIntegrity({ proof: second.proof });
|
|
303
|
+
assert.equal(r2.valid, false);
|
|
304
|
+
assert.match(r2.reason ?? "", /FORK DETECTED/);
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
// ---------------------------------------------------------------------------
|
|
308
|
+
// Policy checks (trustAnchors)
|
|
309
|
+
// ---------------------------------------------------------------------------
|
|
310
|
+
describe("verifyProofIntegrity: policy (trustAnchors)", () => {
|
|
311
|
+
test("passes when measurement is in the allowlist", async () => {
|
|
312
|
+
const result = await verifyProofIntegrity({
|
|
313
|
+
proof: fx.proof,
|
|
314
|
+
trustAnchors: { allowedMeasurements: [fx.measurement] },
|
|
315
|
+
});
|
|
316
|
+
assert.deepEqual(result, { valid: true, artifactBinding: "not-checked" });
|
|
317
|
+
});
|
|
318
|
+
test("fails when measurement is not in the allowlist", async () => {
|
|
319
|
+
const result = await verifyProofIntegrity({
|
|
320
|
+
proof: fx.proof,
|
|
321
|
+
trustAnchors: { allowedMeasurements: ["expected-meas"] },
|
|
322
|
+
});
|
|
323
|
+
assert.equal(result.valid, false);
|
|
324
|
+
assert.match(result.reason ?? "", /measurement/);
|
|
325
|
+
});
|
|
326
|
+
test("fails when requireEnforcement does not match", async () => {
|
|
327
|
+
const result = await verifyProofIntegrity({
|
|
328
|
+
proof: fx.proof,
|
|
329
|
+
trustAnchors: { requireEnforcement: "measured-tee" },
|
|
330
|
+
});
|
|
331
|
+
assert.equal(result.valid, false);
|
|
332
|
+
assert.match(result.reason ?? "", /enforcement/);
|
|
333
|
+
});
|
|
334
|
+
test("requireSlot fails for a slotless proof and passes for a slot-carrying proof", async () => {
|
|
335
|
+
const slotless = await verifyProofIntegrity({
|
|
336
|
+
proof: fx.proof,
|
|
337
|
+
trustAnchors: { requireSlot: true },
|
|
338
|
+
});
|
|
339
|
+
assert.equal(slotless.valid, false);
|
|
340
|
+
assert.match(slotless.reason ?? "", /slotAllocation/);
|
|
341
|
+
const slotFx = await makeSlotFixture();
|
|
342
|
+
const slotted = await verifyProofIntegrity({
|
|
343
|
+
proof: slotFx.proof,
|
|
344
|
+
trustAnchors: { requireSlot: true },
|
|
345
|
+
});
|
|
346
|
+
assert.deepEqual(slotted, { valid: true, artifactBinding: "not-checked" });
|
|
347
|
+
});
|
|
348
|
+
test("counter policy applies without bytes", async () => {
|
|
349
|
+
const slotFx = await makeSlotFixture();
|
|
350
|
+
const pass = await verifyProofIntegrity({
|
|
351
|
+
proof: slotFx.proof,
|
|
352
|
+
trustAnchors: { minCounter: "1" },
|
|
353
|
+
});
|
|
354
|
+
assert.equal(pass.valid, true);
|
|
355
|
+
const failResult = await verifyProofIntegrity({
|
|
356
|
+
proof: slotFx.proof,
|
|
357
|
+
trustAnchors: { minCounter: "999" },
|
|
358
|
+
});
|
|
359
|
+
assert.equal(failResult.valid, false);
|
|
360
|
+
assert.match(failResult.reason ?? "", /counter/);
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
// ---------------------------------------------------------------------------
|
|
364
|
+
// Regression: verify() behavior unchanged by the shared-pipeline refactor
|
|
365
|
+
// ---------------------------------------------------------------------------
|
|
366
|
+
describe("regression: verify() unchanged", () => {
|
|
367
|
+
test("valid proof with bytes returns exactly { valid: true }", async () => {
|
|
368
|
+
const result = await verify({ proof: fx.proof, bytes: fx.bytes });
|
|
369
|
+
assert.deepEqual(result, { valid: true });
|
|
370
|
+
});
|
|
371
|
+
test("wrong bytes fail with the exact digest mismatch reason", async () => {
|
|
372
|
+
const result = await verify({ proof: fx.proof, bytes: new Uint8Array([9, 9, 9]) });
|
|
373
|
+
assert.equal(result.valid, false);
|
|
374
|
+
assert.equal(result.reason, "artifact digest mismatch: the provided bytes do not match the committed digest");
|
|
375
|
+
});
|
|
376
|
+
test("tampered signature fails with the exact signature reason", async () => {
|
|
377
|
+
const tampered = clone(fx.proof);
|
|
378
|
+
tampered.signer.signatureB64 = Buffer.alloc(64).toString("base64");
|
|
379
|
+
const result = await verify({ proof: tampered, bytes: fx.bytes });
|
|
380
|
+
assert.equal(result.valid, false);
|
|
381
|
+
assert.equal(result.reason, "signature verification failed: signature does not match");
|
|
382
|
+
});
|
|
383
|
+
test("tampered version fails with the exact version reason", async () => {
|
|
384
|
+
const tampered = clone(fx.proof);
|
|
385
|
+
tampered["version"] = "bitgraph/2";
|
|
386
|
+
const result = await verify({ proof: tampered, bytes: fx.bytes });
|
|
387
|
+
assert.equal(result.valid, false);
|
|
388
|
+
assert.equal(result.reason, "unsupported proof version: bitgraph/2");
|
|
389
|
+
});
|
|
390
|
+
test("verify() and verifyProofIntegrity() agree on every non-artifact failure", async () => {
|
|
391
|
+
const variants = [
|
|
392
|
+
(p) => {
|
|
393
|
+
p["version"] = "occ/1";
|
|
394
|
+
},
|
|
395
|
+
(p) => {
|
|
396
|
+
p.signer.signatureB64 = Buffer.alloc(64).toString("base64");
|
|
397
|
+
},
|
|
398
|
+
(p) => {
|
|
399
|
+
p.environment.measurement = "evil-measurement";
|
|
400
|
+
},
|
|
401
|
+
(p) => {
|
|
402
|
+
delete p["signer"];
|
|
403
|
+
},
|
|
404
|
+
];
|
|
405
|
+
for (const mutate of variants) {
|
|
406
|
+
const tampered = clone(fx.proof);
|
|
407
|
+
mutate(tampered);
|
|
408
|
+
const full = await verify({ proof: tampered, bytes: fx.bytes });
|
|
409
|
+
const integrity = await verifyProofIntegrity({ proof: tampered });
|
|
410
|
+
assert.equal(full.valid, integrity.valid);
|
|
411
|
+
assert.equal(full.reason, integrity.reason);
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
test("verify() accepts the slot-carrying fixture with its bytes", async () => {
|
|
415
|
+
const slotFx = await makeSlotFixture();
|
|
416
|
+
const result = await verify({ proof: slotFx.proof, bytes: slotFx.bytes });
|
|
417
|
+
assert.deepEqual(result, { valid: true });
|
|
418
|
+
});
|
|
419
|
+
test("verify() accepts the epochLink fixture with its bytes", async () => {
|
|
420
|
+
resetEpochLinkState();
|
|
421
|
+
const linkFx = await makeEpochLinkFixture();
|
|
422
|
+
const result = await verify({ proof: linkFx.proof, bytes: linkFx.bytes });
|
|
423
|
+
assert.deepEqual(result, { valid: true });
|
|
424
|
+
});
|
|
425
|
+
});
|
|
426
|
+
//# sourceMappingURL=proof-integrity.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proof-integrity.test.js","sourceRoot":"","sources":["../../src/__tests__/proof-integrity.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared realistic proof fixture.
|
|
3
|
+
*
|
|
4
|
+
* Extracted verbatim from proof-hash-regression.test.ts (values unchanged,
|
|
5
|
+
* byte for byte) so other suites can import the fixture without importing
|
|
6
|
+
* a test file (which would re-register its suites under node:test).
|
|
7
|
+
*
|
|
8
|
+
* This mirrors what the TEE actually produces: a real-shaped Ethereum
|
|
9
|
+
* anchor proof with a TRUNCATED attestation blob and placeholder
|
|
10
|
+
* signatures. It is a canonical-hash and ingest fixture; it fails full
|
|
11
|
+
* verification by design and its attestation document must honestly
|
|
12
|
+
* report as present-but-unvalidatable (parse error), never as a pass.
|
|
13
|
+
*/
|
|
14
|
+
export declare const REALISTIC_PROOF: {
|
|
15
|
+
version: "bitgraph/1";
|
|
16
|
+
artifact: {
|
|
17
|
+
hashAlg: "sha256";
|
|
18
|
+
digestB64: string;
|
|
19
|
+
};
|
|
20
|
+
commit: {
|
|
21
|
+
nonceB64: string;
|
|
22
|
+
counter: string;
|
|
23
|
+
slotCounter: string;
|
|
24
|
+
slotHashB64: string;
|
|
25
|
+
epochId: string;
|
|
26
|
+
prevB64: string;
|
|
27
|
+
chainId: string;
|
|
28
|
+
};
|
|
29
|
+
signer: {
|
|
30
|
+
publicKeyB64: string;
|
|
31
|
+
signatureB64: string;
|
|
32
|
+
};
|
|
33
|
+
environment: {
|
|
34
|
+
enforcement: string;
|
|
35
|
+
measurement: string;
|
|
36
|
+
attestation: {
|
|
37
|
+
format: string;
|
|
38
|
+
reportB64: string;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
slotAllocation: {
|
|
42
|
+
version: "bitgraph/slot/1";
|
|
43
|
+
nonceB64: string;
|
|
44
|
+
counter: string;
|
|
45
|
+
epochId: string;
|
|
46
|
+
publicKeyB64: string;
|
|
47
|
+
chainId: string;
|
|
48
|
+
signatureB64: string;
|
|
49
|
+
};
|
|
50
|
+
attribution: {
|
|
51
|
+
name: string;
|
|
52
|
+
title: string;
|
|
53
|
+
message: string;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=realistic-proof-fixture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realistic-proof-fixture.d.ts","sourceRoot":"","sources":["../../src/__tests__/realistic-proof-fixture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyC3B,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared realistic proof fixture.
|
|
3
|
+
*
|
|
4
|
+
* Extracted verbatim from proof-hash-regression.test.ts (values unchanged,
|
|
5
|
+
* byte for byte) so other suites can import the fixture without importing
|
|
6
|
+
* a test file (which would re-register its suites under node:test).
|
|
7
|
+
*
|
|
8
|
+
* This mirrors what the TEE actually produces: a real-shaped Ethereum
|
|
9
|
+
* anchor proof with a TRUNCATED attestation blob and placeholder
|
|
10
|
+
* signatures. It is a canonical-hash and ingest fixture; it fails full
|
|
11
|
+
* verification by design and its attestation document must honestly
|
|
12
|
+
* report as present-but-unvalidatable (parse error), never as a pass.
|
|
13
|
+
*/
|
|
14
|
+
// Realistic proof: mirrors what the TEE actually produces
|
|
15
|
+
export const REALISTIC_PROOF = {
|
|
16
|
+
version: "bitgraph/1",
|
|
17
|
+
artifact: {
|
|
18
|
+
hashAlg: "sha256",
|
|
19
|
+
digestB64: "NkYJQ1Gi0hE0SIhv6c46MlqJdurmKHtbScOprDfoL6A=",
|
|
20
|
+
},
|
|
21
|
+
commit: {
|
|
22
|
+
nonceB64: "z1272XEvkMtibuBP0qG3oY37cewo6cJ/o1AuigOSVOk=",
|
|
23
|
+
counter: "1370",
|
|
24
|
+
slotCounter: "1369",
|
|
25
|
+
slotHashB64: "8IyrBOGB64ppP/RETEZTYyYesF5bfcwJ5dI9+u7r2yY=",
|
|
26
|
+
epochId: "7jU4N9703cm6A2t8YNoGsyOvbdePDpoaD8AKCFs7wko=",
|
|
27
|
+
prevB64: "KsJfA3MinpSwF+t4GuxU9vLmmaqAK8FhzhaepEnJBDc=",
|
|
28
|
+
chainId: "bitgraph:main",
|
|
29
|
+
},
|
|
30
|
+
signer: {
|
|
31
|
+
publicKeyB64: "9XjqKDS+e8NhhNoBqbisCKHpaR/HK6hH0x5AKdwc56w=",
|
|
32
|
+
signatureB64: "wbhAtN1dcF2nESBDB0sCQ4ebuZCav8ziLivYgofh7cXeupw5H97VyovHN4I/R9uS0vNaoPIP8js8uTkZnn/IBA==",
|
|
33
|
+
},
|
|
34
|
+
environment: {
|
|
35
|
+
enforcement: "measured-tee",
|
|
36
|
+
measurement: "638d655ad6091bed5c358628b7780de0cdbe138a37fe09d52bf8021a720680a2b3c730fee9f6bef79c1dbe68ef3cdd94",
|
|
37
|
+
attestation: {
|
|
38
|
+
format: "aws-nitro",
|
|
39
|
+
reportB64: "hEShATgioFkR...(truncated for test)",
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
slotAllocation: {
|
|
43
|
+
version: "bitgraph/slot/1",
|
|
44
|
+
nonceB64: "z1272XEvkMtibuBP0qG3oY37cewo6cJ/o1AuigOSVOk=",
|
|
45
|
+
counter: "1369",
|
|
46
|
+
epochId: "7jU4N9703cm6A2t8YNoGsyOvbdePDpoaD8AKCFs7wko=",
|
|
47
|
+
publicKeyB64: "9XjqKDS+e8NhhNoBqbisCKHpaR/HK6hH0x5AKdwc56w=",
|
|
48
|
+
chainId: "bitgraph:main",
|
|
49
|
+
signatureB64: "yO34pHfmkjGY6HgDxcPIaFd/lnt/UFZuHQa10LmUvTHgsQP3S3bIEJX/xcXPRENKZ9duVe7c+81rAWdmhiRMBg==",
|
|
50
|
+
},
|
|
51
|
+
attribution: {
|
|
52
|
+
name: "Ethereum Anchor",
|
|
53
|
+
title: "https://etherscan.io/block/24800448",
|
|
54
|
+
message: "0x28ed3639cd705fb8cb2b915c1991e9f808b40e775bc8eb540702942729fec2c0",
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=realistic-proof-fixture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realistic-proof-fixture.js","sourceRoot":"","sources":["../../src/__tests__/realistic-proof-fixture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,0DAA0D;AAC1D,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,OAAO,EAAE,YAAqB;IAC9B,QAAQ,EAAE;QACR,OAAO,EAAE,QAAiB;QAC1B,SAAS,EAAE,8CAA8C;KAC1D;IACD,MAAM,EAAE;QACN,QAAQ,EAAE,8CAA8C;QACxD,OAAO,EAAE,MAAM;QACf,WAAW,EAAE,MAAM;QACnB,WAAW,EAAE,8CAA8C;QAC3D,OAAO,EAAE,8CAA8C;QACvD,OAAO,EAAE,8CAA8C;QACvD,OAAO,EAAE,eAAe;KACzB;IACD,MAAM,EAAE;QACN,YAAY,EAAE,8CAA8C;QAC5D,YAAY,EAAE,0FAA0F;KACzG;IACD,WAAW,EAAE;QACX,WAAW,EAAE,cAAc;QAC3B,WAAW,EAAE,kGAAkG;QAC/G,WAAW,EAAE;YACX,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,qCAAqC;SACjD;KACF;IACD,cAAc,EAAE;QACd,OAAO,EAAE,iBAA0B;QACnC,QAAQ,EAAE,8CAA8C;QACxD,OAAO,EAAE,MAAM;QACf,OAAO,EAAE,8CAA8C;QACvD,YAAY,EAAE,8CAA8C;QAC5D,OAAO,EAAE,eAAe;QACxB,YAAY,EAAE,0FAA0F;KACzG;IACD,WAAW,EAAE;QACX,IAAI,EAAE,iBAAiB;QACvB,KAAK,EAAE,qCAAqC;QAC5C,OAAO,EAAE,oEAAoE;KAC9E;CACF,CAAC"}
|