VocertVocert← Back to site

Trust & verification

How to verify a Vocert recording

Every Vocert recording is sealed with a cryptographic receipt. That seal lets anyone — you, the other party, a lawyer, a court, a journalist — check two things without having to trust Vocert: that the recording hasn't been altered since it was sealed, and that Vocert is the one who sealed it. This page explains exactly how, in plain language and in full technical detail, and points you at a tool that does it in your browser.

Don't take our word for it

Export the evidence package from the app and drop it into our verifier. It recomputes the hash chain and checks the signature entirely in your browser — no account, no network, nothing to trust.

Verify a recording yourself →

The one-sentence version

When Vocert seals a recording, our server signs a short fingerprint of it with a private key. Anyone can re-derive that fingerprint from the audio and check the signature against Vocert's public key — which we publish openly below and inside the open-source verifier — so a changed recording, or a fake that wasn't sealed by Vocert, fails the check.

What you can check

A sealed Vocert record answers three questions, and you can confirm each of them independently:

  1. Has it been altered? — No, if the hash chain still recomputes to the sealed fingerprint. Changing a single byte of the audio breaks it.
  2. Did Vocert really seal it? — Yes, if the receipt's signature verifies against Vocert's published key. A forged file signed with someone else's key fails.
  3. When was it sealed? — The receipt carries Vocert's sealed-at time. (Independent third-party timestamping is rolling out — see below.)

How it works

1 · A hash chain proves integrity

The recording is split into short chunks. Each chunk is fingerprinted with SHA-256, and those fingerprints are folded together, in order, into a single value called the manifest digest. Because SHA-256 is one-way and collision-resistant, changing, inserting, reordering or deleting any audio changes the digest — so a recomputed digest that still matches the sealed one means the audio is byte-for-byte what was sealed.

2 · An Ed25519 receipt proves it was Vocert — verified against a pinned public key

When the recording is sealed, Vocert's server signs a receipt message that binds the recordingId, the manifestDigest, any bound transcript and Merkle-root commitments, and its sealed-at time, with its private Ed25519 key (exact grammar in the technical reference below). You verify that signature against Vocert's public key.

The part that makes this trustworthy rather than circular: the public key is pinned in the open-source verifier and published on this page — it is never read from the file being checked. So a forger can't simply drop their own key into a fake package; the signature is always tested against the one, public Vocert key. The verification math runs offline, in your browser, with no call back to us.

3 · A Merkle structure allows selective disclosure

The chunk fingerprints are also arranged as a Merkle tree. This lets a holder disclose a single excerpt — say, one minute of a conversation — and prove it belongs to the sealed whole, withoutrevealing the rest. The redacted portions appear only as opaque hashes.

4 · Zero audio retention

Vocert never permanently stores your audio. It lives on your device (the system of record); for paid transcription it is forwarded transiently and deleted. The seal is computed over the fingerprints, so integrity can be proven without us keeping a copy of your recording. See our Privacy Policy.

5 · Independent time (rolling out)

Today the receipt records Vocert's own sealed-at time. We are adding RFC-3161 trusted timestamps, which anchor the seal to an independent timestamp authority so the time can be confirmed against a third party rather than taken on our word. The verifier already displays the timestamp block and marks whether it is a trusted token; full cryptographic timestamp verification is being added.

How to verify it yourself

The easy way (anyone, ~30 seconds):

  1. In the Vocert app, open the recording and choose Export evidence. You get a .json package (and, on the original device, the audio).
  2. Go to vocert.com/verify.
  3. Drop the .json in. It recomputes the hash chain and checks the signature and tells you PASS or FAIL — with every intermediate value shown.

The independent way (for engineers & expert witnesses): the whole scheme is standard and open. You don't need our tool — reimplement the steps below in any language, using the published key. Our browser verifier is open source, so you can also read exactly what it does.

What this does — and does not — prove

Honesty here is the point: an overstated claim gets torn apart under scrutiny, so here is the precise scope.

It proves:

  • The audio and its sealed metadata are unchanged since the receipt was signed (tamper-evidence).
  • The seal was produced by Vocert — the signature verifies against Vocert's published key.
  • The sealed-at time Vocert recorded (with independent timestamping rolling out).
  • That a disclosed excerpt belongs to the sealed whole (selective disclosure).

It does not prove:

  • That the audio reflects reality. The seal protects a recording after capture; it cannot tell whether the sound presented to the microphone was genuine, staged, or synthetic.
  • Who spoke. Speaker labels come from automated transcription and are estimates, not identity proof.
  • Legal admissibility. Whether a recording is admissible or lawful is decided by a court under the law of your jurisdiction — this is a technical integrity check, not legal advice.
  • Independence from Vocert's key. Authenticity ultimately rests on Vocert's signing key being genuine and uncompromised — which is why we publish it openly, keep the verifier open source, and are adding third-party timestamping.

Technical reference

Everything needed to verify a package independently. All hashing is SHA-256; the signature is Ed25519.

Vocert's published signing key (Ed25519 public key, base64)

Signatures are only ever valid against this key. It is the same key hardcoded in the open-source verifier.

2E5+/GTNvDuasKtsGyzo+xbXdsWXvTnjwYU3j+WjmXk=

Manifest digest (hash chain)

The per-chunk payload is versioned by the manifest's chainVersion: each version appends limbs to the previous one, so v1 packages stay byte-identical to the baseline. Bracketed limbs are folded only from the version noted.

seed = SHA256( utf8(lowercase(recordingId)) [ ‖ utf8(B) ] )   // B folded when a public "not-before" beacon is bound
acc  = seed
for each chunk, in ascending "index" order:
    payload = "|" + lowercase(chunk.sha256) + "|" + chunk.index + "|" + chunk.startOffsetMs   // v1
            [ + "|" + chunk.durationMs + "|" + chunk.gapAfterMs ]                              // v2+
            [ + "|" + (chunk.ctxCommit or "-") ]                                               // v3+  salted context commitment
            [ + "|" + (effective checkpoint commitment or "-") ]                               // v4   mid-recording beacon checkpoints
    acc = SHA256( acc ‖ utf8(payload) )
manifestDigest = lowercase_hex(acc)

// beacon commitment    B = "|beacon|" + kind + "|" + outputValue + "|" + locator + "|" + beaconTime + "|" + source
//   (multiple start beacons: primary, then extras sorted ascending by their B string, concatenated)
// checkpoint commitment  = "|ckpt|" + chunkIndex + B(that checkpoint's beacon)
//   (a chunk's "effective" checkpoint is the latest one whose chunkIndex ≤ the chunk's index)

Signed receipt message

message = lowercase(recordingId) + "|" + lowercase(manifestDigest)
        [ + "|t=" + lowercase(transcriptDigest) ]       // when a transcript is bound
        [ + "|m=" + lowercase(merkleRoot) ]             // when the redaction Merkle root is bound
        [ + "|x=" + lowercase(transcriptMerkleRoot) ]   // when the transcript Merkle root is bound
        + "|" + isoUTCSeconds(receivedAt)
verify Ed25519( signature = receipt.serverSignature,
                message   = utf8(message),
                publicKey = <the published key above> )

The t/m/x limbs are appended only when present, in that fixed order. transcriptDigest = receipt.transcriptDigest, merkleRoot = receipt.merkleRoot, and transcriptMerkleRoot = the receipt's tx.merkleRoot attestation. isoUTCSeconds is ISO-8601 UTC at second precision with a trailing Z (e.g. 2026-07-03T15:09:55Z). Verify against the message bytes exactly as sealed.

Vocert's evidence method is patent-pending. This page is a technical explanation of how integrity verification works — it is not legal advice, and it does not determine the admissibility of any recording. Technical or expert-witness questions: contact@vocert.com.


© 2026 Vanillapha Inc. · Vocert is a product of Vanillapha Inc.