← case-guardian.com

Verify a record

Confirm that any CaseGuardian evidence file is authentic, unaltered, and anchored to the Bitcoin blockchain.

🔒
No file stored on our servers
Bitcoin blockchain anchored
Result in under 15 seconds
Attorney-ready output
or upload the evidence file directly
Attorney or legal professional? Protect your clients’ evidence. Learn about CaseGuardian for attorneys →
Details Independent verification, signatures, and trust controls

2. Verify a device signature (offline)

Each entry's hash is also signed with the originating device's Ed25519 key. This check runs entirely in your browser no file, and no CaseGuardian server, is involved. Paste the three values from the entry's "Vault integrity seal" (or from the JSON / Attorney Package appendix) to confirm the signature matches the hash and the public key.

Honest scope: a valid result proves the signature was produced by this exact key over this exact hash, i.e. the originating device, and that the hash has not changed since signing. It is a software-protected key, not a hardware-attested identity, and it does not verify a person's legal identity.

3. Decrypt a share without the browser page (headless)

If you consume a CaseGuardian share from a script instead of this page, such as an intake pipeline, an e-discovery tool, or a CI verifier, request it as JSON and decrypt locally. Fetch the share URL with Accept: application/json; the response carries the share metadata plus, for encrypted shares, wrapped_to_share_key (the AES-256-KW-wrapped case key) on the share object. The per-share key K_s arrives only in the URL fragment (#k=…), which is never sent to our server.

Decryption is AES-KW unwrap → AES-256-GCM with AAD = utf8(entry_id) || crypto_version byte, over the blob layout [1B version][12B nonce][ciphertext+16B GCM tag]. Field ciphertexts (title, summary, transcript) and attachment bytes are all base64 of that blob. crypto_version=0 rows are already plaintext.

Copy-paste reference (zero dependencies, pure WebCrypto)
// Node 18+ / Deno / modern browser. Pure WebCrypto, no dependencies.
const b64ToBytes = (b64) =>
  Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));

function decodeShareKeyFromUrl(fragment) {
  const s = fragment.replace(/-/g, "+").replace(/_/g, "/");
  const key = b64ToBytes(s);
  if (key.length !== 32) throw new Error("Share key is the wrong length.");
  return key;
}

async function unwrapDek(wrapped, ks) {
  const kek = await crypto.subtle.importKey(
    "raw", ks, { name: "AES-KW" }, false, ["unwrapKey"]
  );
  return new Uint8Array(await crypto.subtle.exportKey("raw",
    await crypto.subtle.unwrapKey(
      "raw", wrapped, kek, "AES-KW", { name: "AES-GCM" }, true, ["decrypt"]
    )
  ));
}

function buildAad(entryId, cryptoVersion = 1) {
  const id = new TextEncoder().encode(entryId);
  const aad = new Uint8Array(id.length + 1);
  aad.set(id, 0); aad[id.length] = cryptoVersion & 0xff;
  return aad;
}

async function decryptBytes(blob, dek, entryId, cryptoVersion = 1) {
  if (blob.length < 1 + 12 + 16) throw new Error("Ciphertext blob is too short.");
  if (blob[0] !== 1) throw new Error(`Unsupported blob version ${blob[0]}.`);
  const key = await crypto.subtle.importKey(
    "raw", dek, { name: "AES-GCM" }, false, ["decrypt"]
  );
  return new Uint8Array(await crypto.subtle.decrypt(
    { name: "AES-GCM", iv: blob.subarray(1, 13),
      additionalData: buildAad(entryId, cryptoVersion) },
    key, blob.subarray(13)
  ));
}

async function decryptText(blob, dek, entryId, cryptoVersion = 1) {
  return new TextDecoder().decode(
    await decryptBytes(blob, dek, entryId, cryptoVersion)
  );
}

The server never sees K_s or plaintext. A wrong key, tampered ciphertext, or mismatched entry_id all fail the GCM tag and throw. There is no silent-corruption path.

4. The four possible outcomes

When the live verifier opens, every check returns exactly one of these:

Bitcoin-anchored

The hash has been included in a confirmed Bitcoin block. The capture provably existed at or before that block's timestamp. This is the result a judge wants to see.

Awaiting Bitcoin block

The hash was submitted to OpenTimestamps and is queued for the next aggregation window (typically under 6 hours). Still valid evidence, just not yet permanently anchored.

Hash mismatch

The file you have produces a different hash than the receipt claims. Someone modified the file after it was captured. This is the result that catches tampering.

Unknown

No OpenTimestamps calendar has ever seen this hash. Either it was never anchored, or the hash was mistyped. Not evidence of tampering, just no record exists.

✓ Signed by device

Each entry's hash carries an Ed25519 signature from a key registered to the account before the evidence was created. This proves which device produced the record. It is a software-protected key, not a hardware-attested identity, and does not verify a person's legal identity.

How does this prove anything?
  1. The device hashed the capture's metadata and every attachment byte into a 32-byte fingerprint.
  2. That fingerprint was submitted to OpenTimestamps, which aggregated it into a Merkle tree and committed the root to Bitcoin.
  3. The upgraded receipt contains the Bitcoin block header that includes that Merkle root.
  4. If the calendar returns the receipt, the hash provably existed at or before that Bitcoin block. No central authority, including CaseGuardian, can backdate it.
What does the "✓ signed by device" badge mean?
  1. When the app first runs on a device, it generates an Ed25519 keypair. The private key never leaves the device.
  2. That registration is written into the Bitcoin-anchored custody log, so a verifier can prove the key existed before any evidence it signed.
  3. At capture, the device signs the entry's SHA-256 hash with its private key.
  4. The Attorney Package view re-verifies that signature against the registered public key.
  5. Honest scope: this is a software-protected key, not a Secure Enclave key. It proves the originating device and that the record has not changed since signing.

Why this matters in court

Tamper-evident timestamps shift the burden of proof. If the opposing party claims a capture was fabricated after the fact, the Bitcoin block height in the OTS receipt is a public, immutable upper bound on when the evidence could have been created. Bitcoin block timestamps are independently checkable by any full node operator on Earth.

CaseGuardian is not a substitute for legal counsel. Authentication, chain of custody, and admissibility are decided by the court. We give your attorney a starting point that is mathematically harder to dismiss than a screenshot.

Act 02 Trust & security: how we protect your record on the way there
Trust & Security

How we protect your record

Verification proves your record to the outside world. These five controls protect it from the moment you capture it until you choose to share it. This is the full explanation our Privacy Policy points to.

01

Your evidence never leaves your device until you approve it

Every sealed package, share links, Attorney Packages, and Kid Calendar exports, is shown to you in a full review screen before anything is transmitted. You can remove items, edit captions, or cancel the seal entirely. Nothing is uploaded until you explicitly confirm.

The only thing that ever leaves your device automatically is the 64-character hash sent to OpenTimestamps, a one-way fingerprint that reveals nothing about the underlying file.

02

AI parsing is opt-in, and hardened against attack

CaseGuardian does not send your captures, documents, or Kid Calendar entries to any AI service unless you explicitly turn on the "Parse with AI" toggle for that specific item. It is off by default on every capture and every document.

When you do turn it on, the device first runs an output-side redaction pass that strips your name, phone number, email, address, payment details, and the names of people in your life from the parsed output before anything is stored or shared. Only the redacted output is retained; your original evidence file remains in encrypted storage at full fidelity.

How we harden the pipeline

Every AI request wraps your file in safety instructions telling the model to treat the contents as data, not commands, so hidden text cannot hijack the parser. We enforce an 8 MB input ceiling, clamp every output field to a safe length, and strip document contents from every diagnostic error log before it is written.

AI output is informational only. It is not legal advice and may contain errors. Always confirm with your attorney before relying on it.

03

Destructive actions are gated behind your biometrics

Account deletion, profile deletion, and other irreversible actions require your device's biometric authentication (Face ID, Touch ID, or Android biometric prompt), with a passcode fallback. We never see or store your biometric data. Verification happens entirely on your device using the operating system's secure enclave.

When you delete your account, your data is purged from active systems within 30 days, with encrypted backups overwritten within 90. Bitcoin anchors on the public ledger remain. They are cryptographic fingerprints only, with no personal information attached.

04

Three separate pieces for sealed shares

When you share a sealed package, the recipient must hold all three pieces before the materials decrypt. CaseGuardian emails a notice of the contents and texts a one-time access code. Neither of those can unlock anything. The third piece is the link itself, which carries the decryption key and is sent by you, from your own phone. We never hold that key, so we could not send it for you even if we wanted to.

Before you create the share, you attest that you have the recipient's permission to be contacted at that phone and email for this purpose. Share links can be set to auto-expire (24 hours to forever) and revoked instantly from your Vault.

05

No trackers. No ad SDKs. No selling your data.

We ship zero third-party trackers, zero ad SDKs, and zero IDFA collection. Your evidence never trains a model, never feeds an ad network, and never leaves your device until you personally review and approve it. We do not sell, rent, or share your phone number, consent records, or personal information with third parties for their marketing.

Backed by GDPR & CCPA right-to-erasure: you can export or delete your data at any time, and we will action verified requests within 30 days. Full detail in our Privacy Policy and Terms of Service.

Verification proves the record. Trust protects the person behind it. We engineer for both.