@mikeargento/bitgraph 1.1.0 → 1.1.1
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__/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/package.json +10 -5
- 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__/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/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# BitGraph
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**A BitGraph gives bits a place.**
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@mikeargento/bitgraph)
|
|
6
6
|
[](https://bitgraph.ing)
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
BitGraphs are not labels or metadata added after the fact. They are new computations created when your file's hash *fills* a pre-existing cryptographic slot, constraining the commitment so it cannot be retroactively constructed. This occurs entirely off-chain and produces a proof permanently bound to that exact digital state.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Provenance can be enforced or it can be claimed. Most systems claim it: they bind a statement about the content to the content itself. That binding can be cryptographically strong, and it can be made at the moment of capture rather than afterward, so the weakness is not timing. The weakness is that a claim is something a trusted signer can attach to any artifact at all. The artifact does not have to satisfy any prior condition to receive one.
|
|
14
14
|
|
|
15
|
-
BitGraph enforces
|
|
15
|
+
BitGraph enforces it instead. A measured trusted execution environment creates an unpredictable cryptographic slot before the artifact's hash reaches it. The artifact's hash arrives later and is bound into the slot. The slot is consumed and cannot be reused. What emerges is not a description of provenance but a proof of placement.
|
|
16
16
|
|
|
17
17
|
> This exact digital state was committed through this measured process, in this order, under these constraints.
|
|
18
18
|
|
|
@@ -20,32 +20,32 @@ BitGraph enforces origin. A measured trusted execution environment creates an un
|
|
|
20
20
|
|
|
21
21
|
Nonce first. Hash second. Atomic binding third.
|
|
22
22
|
|
|
23
|
-
The TEE generates hardware entropy inside the enclave. That entropy becomes a slot, signed with the enclave's key, with an identity
|
|
23
|
+
The TEE generates hardware entropy inside the enclave. That entropy becomes a slot, signed with the enclave's key, with an identity that could not feasibly have been predicted. The slot exists as a cryptographic object before it has seen any artifact hash.
|
|
24
24
|
|
|
25
25
|
The artifact hash arrives. The TEE binds the hash into the slot, signs the binding, and advances its internal order. The slot becomes consumed.
|
|
26
26
|
|
|
27
27
|
> UNUSED slot exists first. Artifact hash enters later. TEE binds the hash to the slot. Slot becomes CONSUMED. Proof travels with the artifact.
|
|
28
28
|
|
|
29
|
-
The atomicity is the whole guarantee
|
|
29
|
+
The atomicity is the whole guarantee, and it constrains the record rather than the artifact. The artifact itself can be produced anywhere, by any process, using any tools. What matters is that when the hash arrives, the slot is already there waiting.
|
|
30
30
|
|
|
31
|
-
Most systems say: "Here is a file hash. Now let's sign it." BitGraph says: "Here is a pre-existing
|
|
31
|
+
Most systems begin with the bits. BitGraph begins with the place. They say: "Here is a file hash. Now let's sign it." BitGraph says: "Here is a pre-existing position. Now this file hash has occupied it."
|
|
32
32
|
|
|
33
33
|
## Why nonce-first matters
|
|
34
34
|
|
|
35
|
-
If a nonce, timestamp, or credential is added after the hash is already witnessed, it is just a label. It can prove someone signed something. It can prove a record existed by some moment. It cannot
|
|
35
|
+
If a nonce, timestamp, or credential is added after the hash is already witnessed, it is just a label. It can prove someone signed something. It can prove a record existed by some moment. It cannot impose a prior condition merely by being attached afterward. The credential may describe where the artifact came from, but the artifact never had to consume a pre-existing, single-use position in order to receive one.
|
|
36
36
|
|
|
37
|
-
That leaves a forgery window. A malicious actor can prepare old hashes, replay prior material, backfill records, or attach fresh randomness to something never produced through the claimed path. The label looks valid.
|
|
37
|
+
That leaves a forgery window. A malicious actor can prepare old hashes, replay prior material, backfill records, or attach fresh randomness to something never produced through the claimed path. The label looks valid. Nothing had to be true before it was attached.
|
|
38
38
|
|
|
39
|
-
BitGraph
|
|
39
|
+
BitGraph narrows that window by requiring the slot to exist first. It does not stop an old file being committed today: the hash occupies a slot allocated today, and the position claims nothing about when the bytes were made. What it stops is a position being invented after the fact, or occupied twice. The slot is not evidence added afterward. It is the condition the artifact must satisfy.
|
|
40
40
|
|
|
41
41
|
## What a BitGraph proof contains
|
|
42
42
|
|
|
43
|
-
A BitGraph proof is a portable proof object,
|
|
43
|
+
A BitGraph proof is a portable proof object, a JSON document, that travels with the artifact. It can include:
|
|
44
44
|
|
|
45
45
|
| Component | Purpose |
|
|
46
46
|
|---|---|
|
|
47
47
|
| Artifact hash | Identifies the exact file or digital state |
|
|
48
|
-
| Nonce |
|
|
48
|
+
| Nonce | Hardware entropy giving the slot an identity that cannot feasibly be predicted |
|
|
49
49
|
| Slot counter | Shows the slot was allocated before the commit |
|
|
50
50
|
| Commit counter | Shows the artifact consumed the slot later |
|
|
51
51
|
| Epoch ID | Groups an ordered run of commitments |
|
|
@@ -56,39 +56,39 @@ A BitGraph proof is a portable proof object, typically JSON, that travels with t
|
|
|
56
56
|
| Attestation | Shows the proof came from measured hardware |
|
|
57
57
|
| Public anchor | Tethers BitGraph logical time to a public reference |
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
Taken together: this hash was committed into this causal slot, by this measured environment, at this position in logical order, under this signing identity.
|
|
60
60
|
|
|
61
61
|
## Logical time
|
|
62
62
|
|
|
63
63
|
Every proof has order. Every slot and commit has a position. The system can prove that this happened after that, that this slot existed before this hash was bound, that this proof came before the next, that this epoch has an internal cryptographic history.
|
|
64
64
|
|
|
65
|
-
BitGraph proves causal order
|
|
65
|
+
BitGraph proves causal order. It does not assert a clock time.
|
|
66
66
|
|
|
67
|
-
##
|
|
67
|
+
## Establishing wall clock time
|
|
68
68
|
|
|
69
|
-
BitGraph's internal ordering does not require Ethereum. The chain creates internal order through slot allocation, consumption, counters, signatures, and chained proof history.
|
|
69
|
+
BitGraph's internal ordering does not require Ethereum. The chain creates internal order through slot allocation, consumption, counters, signatures, and chained proof history. What that order lacks, on its own, is a clock. The enclave keeps no trusted one; any clock reading inside a proof is advisory.
|
|
70
70
|
|
|
71
|
-
An Ethereum block hash
|
|
71
|
+
Ethereum is where the order meets the wall clock. An anchor is an ordinary proof on the same chain whose artifact is the hash of a recent Ethereum block. A block hash does not exist before its block is produced, so the anchor, and every proof chained after it, came after that block and its public date. Anchors recur throughout every epoch. This is the wall-clock statement every proof page shows, and it runs in one direction: provably no earlier than. The other side of the window narrows through the chain's cadence, measured enclave behavior rather than public data, which is why it is narrowed, not closed.
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
2. Artifact commitment in the middle.
|
|
75
|
-
3. Public blockchain entropy after it.
|
|
73
|
+
The anchors also fix history backward, through content. Each anchor is hash-linked to everything before it, so once an anchor exists, the history behind it is fixed: alter any earlier proof and the chain no longer reaches the anchor. When the epoch ends, its signing key is destroyed, and the set closes.
|
|
76
74
|
|
|
77
|
-
|
|
75
|
+
Ethereum is not asked to be a good source of randomness, and it is not asked to establish the artifact's position. BitGraph establishes the position. Ethereum ties the positions to the public timeline, so anyone, years later, can check the order and the earliest date each position could have existed.
|
|
78
76
|
|
|
79
|
-
|
|
77
|
+
## Compromise and containment
|
|
80
78
|
|
|
81
|
-
|
|
79
|
+
BitGraph assumes the boundary can be compromised and bounds the damage instead of claiming it cannot happen.
|
|
82
80
|
|
|
83
|
-
|
|
81
|
+
The signing key exists only in enclave memory. Every restart destroys it and begins a new epoch with a fresh key and a fresh counter. Proofs from prior epochs were signed by keys that no longer exist, so a compromise cannot reach backward.
|
|
84
82
|
|
|
85
|
-
|
|
83
|
+
Forgery requires more than key theft. Every proof carries a hardware attestation whose user_data must equal the hash of that exact proof body, and only the enclave's secure module can produce one. A useful breach must execute inside the running enclave, and it dies at the next restart.
|
|
86
84
|
|
|
87
|
-
|
|
85
|
+
Damage control is precise. Every proof names its epoch permanently, so a suspect window is identified exactly: rotate the epoch, publish the affected epochId as quarantined, and every other epoch is untouched. Verifiers that pin measurements and track epochs account for the gap.
|
|
86
|
+
|
|
87
|
+
The production deployment makes rotation routine rather than exceptional: the boundary restarts every day at 23:59 UTC, destroying the epoch key and starting a fresh one, so a normally operating epoch runs about a day. An unexpected restart ends one early and a failed rotation extends one; either way the boundary is recorded in the proofs themselves. A breach that depends on staying resident inside the enclave cannot outlive its epoch without freshly re-compromising a new one. The schedule is deliberately public: rotation times are visible on the ledger regardless, and the protection comes from the key dying, not from anyone guessing when.
|
|
88
88
|
|
|
89
89
|
## The trust model
|
|
90
90
|
|
|
91
|
-
BitGraph does not
|
|
91
|
+
BitGraph does not ask for blind trust in any single component. It has real dependencies, and the point is that each one is inspectable rather than assumed: the enclave's attestation chains to the AWS Nitro Attestation PKI root, and the measurement it carries is published, so both are things you check rather than things you take on faith. Each layer adds an independently verifiable property.
|
|
92
92
|
|
|
93
93
|
| Layer | What it contributes |
|
|
94
94
|
|---|---|
|
|
@@ -97,8 +97,7 @@ BitGraph does not depend on blind trust in any single component. Not the operato
|
|
|
97
97
|
| Atomic binding | Prevents post-hoc attachment |
|
|
98
98
|
| Counters | Internal logical order |
|
|
99
99
|
| Proof chain | Historical continuity |
|
|
100
|
-
| Ethereum anchor | Public
|
|
101
|
-
| Multi-TEE redundancy | Breach visibility |
|
|
100
|
+
| Ethereum anchor | Public wall-clock bound |
|
|
102
101
|
| Epoch rotation | Damage containment |
|
|
103
102
|
| Portable verification | Independence from the original server |
|
|
104
103
|
|
|
@@ -106,11 +105,11 @@ BitGraph does not depend on blind trust in any single component. Not the operato
|
|
|
106
105
|
|
|
107
106
|
BitGraph works on any digital state that can be hashed. The same primitive applies whether the artifact is a photograph, a contract, a model output, a dataset, or a software release.
|
|
108
107
|
|
|
109
|
-
**Media.** Photos, videos, audio, edited files, generative outputs. The question shifts from "is this real?" to "what
|
|
108
|
+
**Media.** Photos, videos, audio, edited files, generative outputs. The question shifts from "is this real?" to "what position does this exact digital state occupy?"
|
|
110
109
|
|
|
111
|
-
**AI outputs.** Model results bound to
|
|
110
|
+
**AI outputs.** Model results bound to a causal position, and optionally to a key that authorized the recording, without requiring the model to run inside an enclave.
|
|
112
111
|
|
|
113
|
-
**Software supply chain.** Build artifacts, releases, model weights, and deployment packages bound to a measured
|
|
112
|
+
**Software supply chain.** Build artifacts, releases, model weights, and deployment packages bound to a position in a measured sequence.
|
|
114
113
|
|
|
115
114
|
**Legal and clinical records.** Contracts, filings, telehealth session manifests, lab results, and consent forms with independently verifiable causal ordering.
|
|
116
115
|
|
|
@@ -124,22 +123,24 @@ BitGraph is often confused with adjacent systems. The differences are structural
|
|
|
124
123
|
|---|---|---|
|
|
125
124
|
| Signatures | This key signed this data | This key was controlled by a measured environment that consumed an unused slot |
|
|
126
125
|
| Timestamps | This hash existed by time T | This hash consumed a pre-existing slot at this position in causal order |
|
|
127
|
-
| C2PA | Here are signed claims about this content |
|
|
128
|
-
| Blockchains | Public ordering of shared transactions |
|
|
126
|
+
| C2PA | Here are signed claims about this content | This exact digital state occupied this pre-existing position |
|
|
127
|
+
| Blockchains | Public ordering of shared transactions | Ordering established inside a measured enclave, then anchored publicly |
|
|
129
128
|
|
|
130
|
-
Signatures, timestamps, content credentials, and blockchains all answer "who claimed what, when?" BitGraph answers "what
|
|
129
|
+
Signatures, timestamps, content credentials, and blockchains all answer "who claimed what, when?" BitGraph answers "what position does this exact digital state occupy?" They are complementary, not competing. A signature can be inside a BitGraph proof. A timestamp can decorate one. Content credentials can ride alongside one. None of them, alone, do what BitGraph does.
|
|
131
130
|
|
|
132
|
-
##
|
|
131
|
+
## Every copy carries the same position
|
|
133
132
|
|
|
134
|
-
Physical originality
|
|
133
|
+
Physical originality depended on singularity. There was one canvas, one negative, one signed paper, and the object's uniqueness was how you knew it came from the author's hand. Digital files broke that. Perfect copies are indistinguishable from the source, so the physical anchor for originality stopped working.
|
|
135
134
|
|
|
136
|
-
BitGraph
|
|
135
|
+
BitGraph does not restore originality. It makes it unnecessary. The artifact's hash is the proof's anchor, so any exact copy of the bytes carries the same position, and no copy has to be the special one. The proof object itself can travel with the file, stay on the server that issued it, or be stored anywhere, and each of those can have copies too. Verification does not depend on where anything lives. What used to need a unique object now needs only the exact bytes.
|
|
137
136
|
|
|
138
137
|
## The simplest version
|
|
139
138
|
|
|
140
|
-
A measured TEE creates a random unused slot before the artifact hash arrives. The hash arrives. The TEE binds it to the slot, consumes the slot, signs the result, and links it into an ordered chain.
|
|
139
|
+
A measured TEE creates a random unused slot before the artifact hash arrives. The hash arrives. The TEE binds it to the slot, consumes the slot, signs the result, and links it into an ordered chain. Every restart begins a new epoch with a new key, so a compromised boundary is bounded, never retroactive. The same mechanism periodically commits an Ethereum block hash, fixing the history behind it and giving everything after it a public date it provably followed.
|
|
140
|
+
|
|
141
|
+
The result is a protocol that does not say "someone signed this."
|
|
141
142
|
|
|
142
|
-
|
|
143
|
+
**It proves: these exact bits occupy this position.**
|
|
143
144
|
|
|
144
145
|
---
|
|
145
146
|
|
|
@@ -164,6 +165,14 @@ if (result.ok) {
|
|
|
164
165
|
|
|
165
166
|
See [bitgraph.ing/docs](https://bitgraph.ing/docs) for the full proof format, verification checklist, attestation handling, and self-host instructions.
|
|
166
167
|
|
|
168
|
+
## Verification and audit packages
|
|
169
|
+
|
|
170
|
+
Two MIT-licensed packages in this repository make BitGraph evidence checkable without permission:
|
|
171
|
+
|
|
172
|
+
**[`@mikeargento/bitgraph-verify`](https://www.npmjs.com/package/@mikeargento/bitgraph-verify)** verifies one proof. `verify()` checks a proof against the original artifact bytes: structure, canonical Ed25519 signature, slot binding, epoch link, and the digest match. `verifyProofIntegrity()` runs every check except the artifact binding for cases where the bytes are not available, and its result states explicitly that the binding was not checked.
|
|
173
|
+
|
|
174
|
+
**`@mikeargento/bitgraph-audit`** audits a whole bundle of proofs, fully offline. It ingests a directory, `.tar`, or `.tar.gz`, verifies every proof through the canonical verifier, reconstructs causal order from the hash links and counters, classifies anomalies with stable machine-readable codes, and preserves divergence between valid proofs for the reader to adjudicate instead of choosing a winner. It ships a CLI (`bitgraph-audit <bundle>`) that writes machine-readable and human-readable reports. The bundle format is specified in [docs/BUNDLE-FORMAT.md](docs/BUNDLE-FORMAT.md); the recipient walkthrough is [docs/HOW-TO-AUDIT.md](docs/HOW-TO-AUDIT.md).
|
|
175
|
+
|
|
167
176
|
## License
|
|
168
177
|
|
|
169
178
|
Copyright 2024-2026 Mike Argento. All rights reserved. Patent Pending.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-anchors.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/audit-anchors.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// Copyright (c) Mike Argento. All rights reserved. See LICENSE.
|
|
2
|
+
/**
|
|
3
|
+
* Anchor identification tests (G5): the SIGNED attribution.name is the
|
|
4
|
+
* discriminator; unsigned metadata.type is corroboration only, recorded
|
|
5
|
+
* but never trusted; the block number comes only from the signed
|
|
6
|
+
* Etherscan URL; no wall-clock time is ever derived from anything here.
|
|
7
|
+
*/
|
|
8
|
+
import { describe, it } from "node:test";
|
|
9
|
+
import * as assert from "node:assert/strict";
|
|
10
|
+
import { identifyAnchors, ingestBundle, verifyObservedProofs, } from "@mikeargento/bitgraph-audit";
|
|
11
|
+
import { makeAnchorProof, makeChainIdProof, makeTempDir, proofJson, writeBundleDir, } from "./audit-fixtures.js";
|
|
12
|
+
const BLOCK_HASH = "0x28ed3639cd705fb8cb2b915c1991e9f808b40e775bc8eb540702942729fec2c0";
|
|
13
|
+
async function ingestAndVerify(files) {
|
|
14
|
+
const dir = await makeTempDir("bg-audit-anchors-");
|
|
15
|
+
await writeBundleDir(dir, files);
|
|
16
|
+
const ingest = await ingestBundle(dir);
|
|
17
|
+
await verifyObservedProofs(ingest);
|
|
18
|
+
return ingest;
|
|
19
|
+
}
|
|
20
|
+
describe("audit anchors: identification by signed attribution", () => {
|
|
21
|
+
it("identifies an anchor by attribution.name and extracts the signed facts", async () => {
|
|
22
|
+
const anchor = await makeAnchorProof({
|
|
23
|
+
blockHash: BLOCK_HASH,
|
|
24
|
+
blockNumber: "24800448",
|
|
25
|
+
epochId: "EPOCH-A",
|
|
26
|
+
counter: "4",
|
|
27
|
+
slotCounter: "3",
|
|
28
|
+
chainId: "bitgraph:main",
|
|
29
|
+
metadata: {
|
|
30
|
+
type: "ethereum-anchor",
|
|
31
|
+
anchor: { blockNumber: 24800448, blockHash: BLOCK_HASH, blockTime: 1750000000 },
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
const user = await makeChainIdProof({ chainId: "bitgraph:main", counter: "6", epochId: "EPOCH-A" });
|
|
35
|
+
const ingest = await ingestAndVerify({
|
|
36
|
+
"proofs/anchor.json": proofJson(anchor.proof),
|
|
37
|
+
"proofs/user.json": proofJson(user.proof),
|
|
38
|
+
});
|
|
39
|
+
const result = identifyAnchors(ingest);
|
|
40
|
+
assert.equal(result.anchors.length, 1);
|
|
41
|
+
const record = result.anchors[0];
|
|
42
|
+
assert.equal(record.proofHash, anchor.proofHash);
|
|
43
|
+
assert.equal(record.epochId, "EPOCH-A");
|
|
44
|
+
assert.equal(record.chainId, "bitgraph:main");
|
|
45
|
+
assert.equal(record.counter, "4");
|
|
46
|
+
assert.equal(record.slotCounter, "3");
|
|
47
|
+
assert.equal(record.blockHash, BLOCK_HASH);
|
|
48
|
+
assert.equal(record.blockNumber, "24800448");
|
|
49
|
+
assert.equal(record.metadataCorroboration, "agrees");
|
|
50
|
+
// The unsigned metadata carries a blockTime; no time field of any kind
|
|
51
|
+
// may appear on the record.
|
|
52
|
+
assert.ok(!("timestamp" in record));
|
|
53
|
+
assert.ok(!("blockTime" in record));
|
|
54
|
+
assert.equal(result.findings.length, 0);
|
|
55
|
+
});
|
|
56
|
+
it("copies the run verification status onto the record", async () => {
|
|
57
|
+
const good = await makeAnchorProof({ blockHash: BLOCK_HASH, blockNumber: "1", epochId: "E", counter: "2" });
|
|
58
|
+
const bad = await makeAnchorProof({ blockHash: BLOCK_HASH.replace("28", "29"), blockNumber: "2", epochId: "E", counter: "4" });
|
|
59
|
+
// Tamper the signature after signing: identification still works (it
|
|
60
|
+
// reads the signed body fields), and the failed status is copied.
|
|
61
|
+
bad.proof.signer.signatureB64 = `AA${bad.proof.signer.signatureB64.slice(2)}`;
|
|
62
|
+
const ingest = await ingestAndVerify({
|
|
63
|
+
"proofs/good.json": proofJson(good.proof),
|
|
64
|
+
"proofs/bad.json": proofJson(bad.proof),
|
|
65
|
+
});
|
|
66
|
+
const result = identifyAnchors(ingest);
|
|
67
|
+
assert.equal(result.anchors.length, 2);
|
|
68
|
+
const goodRecord = result.anchors.find((a) => a.proofHash === good.proofHash);
|
|
69
|
+
assert.equal(goodRecord.verificationTier, "integrity");
|
|
70
|
+
assert.equal(goodRecord.verificationStatus, "artifact-unavailable");
|
|
71
|
+
const badRecord = result.anchors.find((a) => a.proofHash !== good.proofHash);
|
|
72
|
+
assert.equal(badRecord.verificationStatus, "failed");
|
|
73
|
+
assert.ok(badRecord.verificationReason !== undefined);
|
|
74
|
+
});
|
|
75
|
+
it("never identifies an anchor from unsigned metadata alone", async () => {
|
|
76
|
+
const user = await makeChainIdProof({ counter: "2", epochId: "E-META" });
|
|
77
|
+
user.proof["metadata"] = { type: "ethereum-anchor" };
|
|
78
|
+
const ingest = await ingestAndVerify({ "proofs/claimant.json": proofJson(user.proof) });
|
|
79
|
+
const result = identifyAnchors(ingest);
|
|
80
|
+
assert.equal(result.anchors.length, 0);
|
|
81
|
+
assert.equal(result.metadataOnlyProofHashes.length, 1);
|
|
82
|
+
const finding = result.findings.find((f) => f.code === "anchor-metadata-only-claim");
|
|
83
|
+
assert.ok(finding !== undefined);
|
|
84
|
+
assert.match(finding.message, /not treated as an anchor/);
|
|
85
|
+
});
|
|
86
|
+
it("records disagreement between the signed attribution and unsigned metadata", async () => {
|
|
87
|
+
const anchor = await makeAnchorProof({
|
|
88
|
+
blockHash: BLOCK_HASH,
|
|
89
|
+
blockNumber: "7",
|
|
90
|
+
epochId: "E-DIS",
|
|
91
|
+
counter: "2",
|
|
92
|
+
metadata: { type: "something-else" },
|
|
93
|
+
});
|
|
94
|
+
const ingest = await ingestAndVerify({ "proofs/anchor.json": proofJson(anchor.proof) });
|
|
95
|
+
const result = identifyAnchors(ingest);
|
|
96
|
+
assert.equal(result.anchors.length, 1, "the signed field governs: still an anchor");
|
|
97
|
+
assert.equal(result.anchors[0].metadataCorroboration, "disagrees");
|
|
98
|
+
assert.ok(result.findings.some((f) => f.code === "anchor-metadata-disagreement"));
|
|
99
|
+
});
|
|
100
|
+
it("treats absent metadata as absent corroboration, not disagreement", async () => {
|
|
101
|
+
const anchor = await makeAnchorProof({ blockHash: BLOCK_HASH, blockNumber: "9", epochId: "E-ABS", counter: "2" });
|
|
102
|
+
const ingest = await ingestAndVerify({ "proofs/anchor.json": proofJson(anchor.proof) });
|
|
103
|
+
const result = identifyAnchors(ingest);
|
|
104
|
+
assert.equal(result.anchors[0].metadataCorroboration, "absent");
|
|
105
|
+
assert.equal(result.findings.filter((f) => f.code === "anchor-metadata-disagreement").length, 0);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
describe("audit anchors: block number from the signed title URL", () => {
|
|
109
|
+
it("parses the number only from a strict Etherscan block URL", async () => {
|
|
110
|
+
const good = await makeAnchorProof({ blockHash: BLOCK_HASH, blockNumber: "24800448", epochId: "E-URL", counter: "2" });
|
|
111
|
+
const foreign = await makeAnchorProof({
|
|
112
|
+
blockHash: BLOCK_HASH.replace("28", "30"),
|
|
113
|
+
title: "https://example.com/block/99",
|
|
114
|
+
epochId: "E-URL",
|
|
115
|
+
counter: "4",
|
|
116
|
+
});
|
|
117
|
+
const missing = await makeAnchorProof({
|
|
118
|
+
blockHash: BLOCK_HASH.replace("28", "31"),
|
|
119
|
+
noTitle: true,
|
|
120
|
+
epochId: "E-URL",
|
|
121
|
+
counter: "6",
|
|
122
|
+
});
|
|
123
|
+
const ingest = await ingestAndVerify({
|
|
124
|
+
"proofs/good.json": proofJson(good.proof),
|
|
125
|
+
"proofs/foreign.json": proofJson(foreign.proof),
|
|
126
|
+
"proofs/missing.json": proofJson(missing.proof),
|
|
127
|
+
});
|
|
128
|
+
const result = identifyAnchors(ingest);
|
|
129
|
+
const byHash = new Map(result.anchors.map((a) => [a.proofHash, a]));
|
|
130
|
+
assert.equal(byHash.get(good.proofHash).blockNumber, "24800448");
|
|
131
|
+
assert.equal(byHash.get(foreign.proofHash).blockNumber, undefined);
|
|
132
|
+
assert.equal(byHash.get(missing.proofHash).blockNumber, undefined);
|
|
133
|
+
assert.equal(result.findings.filter((f) => f.code === "anchor-title-unparseable").length, 2);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
describe("audit anchors: non-anchor proofs are untouched", () => {
|
|
137
|
+
it("produces no records or findings for ordinary proofs and mutates nothing", async () => {
|
|
138
|
+
const a = await makeChainIdProof({ counter: "2", epochId: "E-PLAIN" });
|
|
139
|
+
const b = await makeChainIdProof({ counter: "4", epochId: "E-PLAIN" });
|
|
140
|
+
const ingest = await ingestAndVerify({
|
|
141
|
+
"proofs/a.json": proofJson(a.proof),
|
|
142
|
+
"proofs/b.json": proofJson(b.proof),
|
|
143
|
+
});
|
|
144
|
+
const statusesBefore = ingest.proofs.map((p) => p.verification?.status);
|
|
145
|
+
const result = identifyAnchors(ingest);
|
|
146
|
+
assert.equal(result.anchors.length, 0);
|
|
147
|
+
assert.equal(result.metadataOnlyProofHashes.length, 0);
|
|
148
|
+
assert.equal(result.findings.length, 0);
|
|
149
|
+
assert.deepEqual(ingest.proofs.map((p) => p.verification?.status), statusesBefore, "identification is read-only");
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
//# sourceMappingURL=audit-anchors.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-anchors.test.js","sourceRoot":"","sources":["../../src/__tests__/audit-anchors.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-anomalies.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/audit-anomalies.test.ts"],"names":[],"mappings":""}
|