Skip to content

Proof Hashes

Every verified delta produces a proof hash that is deterministic, tamper-evident, and chain-linked.

When PacSpace verifies a delta, it produces a proof hash — a verifiable value that lets you independently confirm your data was recorded accurately. Every proof hash has three fundamental properties.

Three Properties of Proof Hashes

Deterministic

Given the same input data, the proof hash is always the same. There's no randomness, no timestamps mixed into the hash, no server-specific variation. You can recompute it yourself and get the exact same result every time.

Same delta payload → Same content hash → Same proof hash

This means verification is repeatable. Today, tomorrow, a year from now — the math always checks out.

Tamper-Evident

Change a single byte of the original data and the proof hash is completely different. There's no way to make a "small" change that preserves the hash. This property makes it immediately obvious if data has been altered after verification.

Original:  { "amount": 42.50 }  → 0x8f3a9b...
Tampered:  { "amount": 42.51 }  → 0xd17c4e...  ← completely different

Chain-Linked

Each proof hash includes a reference to the previous proof hash. This creates a sequential chain where every delta is tied to the one before it. You can't insert, remove, or reorder deltas without breaking the chain.

proofHash₀ ← proofHash₁ ← proofHash₂ ← proofHash₃

If someone tampers with delta 1, then delta 2's previousProofHash no longer matches — and the break is detectable all the way forward.

Independent Verification

You don't need to trust PacSpace. When you receive a delta.verified webhook, you get everything needed to verify the proof yourself. Here's how:

Step 1: Confirm your content hash matches

Compare the contentHash from the webhook against the hash you expect for the delta you submitted. If they match, the delta PacSpace verified is the exact data you sent.

javascript
const { contentHash } = webhookData.proof;

// Your stored or recomputed hash should match
assert(myHash === contentHash, 'Content hash mismatch — data may have been altered');

Step 2: Confirm your content hash is in the verification set

Check that your contentHash appears in the itemHashes array from the webhook payload. This proves your delta was included in the verification.

javascript
const { itemHashes, contentHash } = webhookData.proof;

assert(itemHashes.includes(contentHash), 'Content hash not found in verification set');

Step 3: Confirm the proof hash

Compare the proofHash from the webhook against the receiptId you received when you originally submitted the delta.

javascript
const { proofHash } = webhookData.proof;

assert(
  proofHash === storedReceiptId,
  'Proof hash mismatch — verification check failed'
);

If you stored the previous delta's proof hash, confirm it matches previousProofHash to verify chain continuity.

javascript
const { previousProofHash } = webhookData.proof;

assert(
  previousProofHash === storedPreviousProofHash,
  'Chain broken — previous proof hash does not match'
);

Verification Summary

CheckWhat it proves
Content hash comparisonYour original data is unchanged
Presence in itemHashesYour delta was included in the verification
Proof hash comparisonThe committed proof matches your original receipt
Chain link validationNo deltas were inserted, removed, or reordered

Next Steps