Loading…
Loading…
Technology
A BitGraph is made inside an AWS Nitro enclave running a published, reproducible build. In one indivisible step the enclave takes two consecutive counts of its sequence: a fresh nonce from the hardware’s random number generator at the first, the SHA-256 of your data at the second. Both are signed together, attested by the hardware, and chained to the record before. The result is a small JSON proof anyone can check offline.
The content itself never reaches BitGraph. Only its 32-byte digest does.
What it establishes
The mechanism
Why the nonce: it is what makes the position its own. Because it is drawn after the digest arrives, a position cannot be reserved in advance and filled later, and every proof carries a value no one could have known before it existed. Work made from one BitGraph’s published nonce could not have existed before that BitGraph, which is how two BitGraphs bracket work between them.
Atomic by construction
Every step that can fail (the random draw, the signature, the attestation) comes before the counter moves. If any fails, nothing is released, the counter stays where it was, and the drawn nonce is discarded without ever leaving the enclave. Requests are serialised inside the enclave, so two binds cannot interleave.
Tested on the unmodified enclave code with injected faults in the RNG, the signer and the attestation: server/commit-service/src/enclave/__tests__/bind-failure.test.ts.
The sequence
Every proof after an epoch’s first carries prevB64, the SHA-256 of the whole previous proof. Within an epoch the counts climb by two per BitGraph, nonce then content. Given a run of proofs, the verifier checks that each is atomic, that counts are consecutive and that each links to the one before; a missing proof shows as a gap (verifyStretch). Anything bound between BitGraph A and BitGraph B was bound after A and before B (verifyBetween).
The enclave’s key and counter live only in its memory, so each start is a new epoch: a new key, a counter from zero, and an epochId signed into every proof. Epochs are independent sequences. Each one’s first BitGraph binds a record of the Base blockchain, which places that epoch’s start in public time.
The measured enclave
Each proof carries an AWS Nitro attestation document, signed by AWS’s hardware (ES384, certificate chain to the AWS Nitro root). It states the enclave image’s measurement, PCR0, and carries as its user data the SHA-256 of the exact signed body of that proof. The signing key is generated inside the enclave at start and never exported; it is tied to the hardware through that per-proof attestation.
The current image, v13, measures:
adaad0bef62292d35197ae8db19e40685229f1a1e6070a7c77a148c4ada88ee66a1ca50819eebc2017c6716a49f2692f
It is reproducible: two independent builds from the enclave-v13 branch produced this PCR0. (The image file itself differs build to build because its header holds a build time; the measurement does not.) Every published image back to the first is listed in the verifier, and only those are accepted by default.
Time
The enclave adds no clock of its own. The time in a proof is the attestation’s timestamp, set and signed by the AWS Nitro Secure Module.
Through bitgraph.ing, every BitGraph is also placed in the time of a public chain BitGraph does not operate:
No blockchain is needed to verify a proof. Base is only needed to check the floor and ceiling claims.
Collections
Many items are recorded at once as an RFC 6962 Merkle tree over their SHA-256s (leaf = SHA-256(0x00 ‖ digest), node = SHA-256(0x01 ‖ left ‖ right)). One BitGraph binds a short text naming the root and the count. Each item then proves its own inclusion with a path of sibling hashes, without the others being disclosed. The format allows up to 1,000,000 items in a tree.
Measured 2026-10-28 on the current flow, in Node on an 8-core Apple M3 laptop: one million files hashed in 1.9 s, the tree built in 2.4 s, and the root bound 6.1 s after the drop. Open the result as BitGraph #34, or download the run’s files: timings, corpus seed, root text and proof file. Reproduce it with website/scripts/bench-million.mjs.
Without disclosure
Each proof holds two signed records: the slot at count N, with the nonce, epoch and key and no field from the content; and the binding at count N+1, which names the digest. The slot record is signed on its own. So a holder can withhold the binding and the content entirely and still show the slot: an auditor checks its signature under the same key as an attested proof from that epoch, and learns that the measured enclave established that position, without learning what was bound there.
Built into the proof format today. The check uses the verifier’s existing signature and canonical-encoding steps; it is not yet a one-line command.
The proof
{
"version": "bitgraph/1",
"artifact": { "hashAlg": "sha256", "digestB64": "…" },
"commit": {
"nonceB64": "…", "counter": "16", "slotCounter": "15", "slotHashB64": "…",
"epochId": "…", "atomic": true, "prevB64": "…", "chainId": "bitgraph:main"
},
"signer": { "publicKeyB64": "…", "signatureB64": "…" },
"environment": { "enforcement": "measured-tee", "measurement": "<PCR0>",
"attestation": { "format": "aws-nitro", "reportB64": "…" } },
"slotAllocation": { "version": "bitgraph/slot/1", "nonceB64": "…", "counter": "15", … }
}The signature covers a canonical serialisation of the body. A collection member also carries its inclusion path, as unsigned metadata that is checked, not trusted. Download a real proof, or verify it.
Verification
The verifier is MIT-licensed. It needs the data, the proof, and nothing of BitGraph’s running:
npx @mikeargento/bitgraph-sdk verify <file> --proof <file>.bitgraph.json --pcr0 adaad0bef62292d35197ae8db19e40685229f1a1e6070a7c77a148c4ada88ee66a1ca50819eebc2017c6716a49f2692f
A key anyone can generate can sign a body that passes a signature check alone. It fails the attested check, because no AWS document covers it. The verifier’s own test does exactly this: packages/verify/src/__tests__/attested.test.ts.
Threat model
| Party | Cannot | Can |
|---|---|---|
| The host operator (BitGraph included) | Forge a proof that passes the attested check; see or choose a nonce; reuse a count; insert or reorder proofs inside a sequence without breaking the counts and hash links; change a proof’s attested time by releasing it late. | Choose the order in which it submits digests; delay or refuse submissions; withhold released proofs (gaps then show to anyone holding the neighbours); restart the enclave to begin a new epoch; choose which recent Base block is read as the floor; decline to write ceilings. |
| A client | Get a position without binding a digest; get its digest bound at a count of its choosing. | Bind any 32-byte digest, including one of content it does not own. Binding says nothing about authorship. |
| Someone holding a proof | Edit any signed field, swap the digest, the counter, the previous-proof link or the measurement, without the check failing. | Withhold it, or show it out of context. A proof shows its own position, not what else was bound. |
| A stolen enclave key | Pass the attested check. Keys are per epoch and live only in enclave memory. | Sign bodies that pass a signature-only check. Always verify with attestation. |
What you trust
enclave-v13 branch and its measurement reproduces, so what it does can be read and rebuilt rather than taken on trust.Not trusted: BitGraph’s website, its servers, its storage, or its word. A proof that checks offline against the published measurement checks whether or not BitGraph is still running.
Comparisons
These systems answer different questions, and most products combine several. The aim here is the difference in what is enforced, not a ranking.
| System | What it proves | What you trust | Where BitGraph differs or fits |
|---|---|---|---|
| Digital signature | A key holder signed these bytes. | The key holder, and whoever holds the key. | Says nothing about when, or where in any sequence. A BitGraph is a signature made by attested hardware at a counted position. |
| Timestamp authority (RFC 3161) | A TSA signed this hash with this time. | The TSA’s key, clock and honesty; it could issue a token with any time. | BitGraph’s issuer is measured hardware whose code is published, its time is the hardware’s, and its records are counted and chained. A product can carry both. |
| Transparency log (CT, Sigstore, SCITT) | An entry is included in an append-only log; consistency proofs expose rewrites to anyone monitoring. | The log operator’s signing, plus monitors and witnesses. | The log proves inclusion after the fact; BitGraph constrains the issuing step itself inside an enclave. A BitGraph proof can itself be a log entry. |
| Blockchain anchoring | A hash existed by a block. | The chain’s consensus. | Block time is coarse and each anchor costs a transaction. BitGraph proves each record at once and offline, and uses Base only for a batched public-time window. |
| Content Credentials (C2PA) | A signer made these assertions about an asset. | The signer’s certificate, and its clock or TSA. | Complementary: binding the asset and its manifest gives the credential an independent recording. |
| Remote attestation alone | Certain code is running in an enclave. | The hardware vendor. | Attestation is the root; BitGraph is a specific mechanism on it that produces counted, chained, per-record evidence. |
Next
The evaluation guide walks through making a BitGraph, verifying it offline, and watching each kind of tampering fail.