TgWitness / Documentation

Documentation / 08

See how evidence works

A message can change. The record of what you observed should remain checkable.

Explore two small experiments below. They use fictional messages, stay in your browser and never connect to Telegram.

One message, three observations

When Telegram delivers a new message, an edit and a deletion notice, the collector appends three separate observations. The edit does not replace the first record. A deletion notice does not erase it.

01 / MESSAGE JOURNEYIllustrative sequence
Telegram delivers an update to the collector, which appends a journal record. TelegramCollectorJournal update →append →
CURRENT CHAT VIEW Message #42
Message deleted

The message has disappeared from the chat view.

OBSERVATION JOURNAL 3 records
  1. 01
    message.new

    Meet at 10:00

    ✓
  2. 02
    message.edited

    Meet at 11:00

    ✓
  3. 03
    message.deleted

    Deletion notice for #42

    ✓

All three received observations remain in the journal.

Simplified path for one already selected source. Operational records also share the real journal. Capture depends on what the account can see and what Telegram delivers.

A deletion notice supplies neither a reliable deletion time nor the person who deleted the message. Keeping those values unknown preserves the distinction between an observation and a guess.

Change a record. Follow the hash.

Each record contains the previous record’s hash. Its own hash covers the event fields, including that link. An externally retained checkpoint pins a specific journal length and head hash.

02 / HASH-CHAIN SANDBOXReal SHA-256 · sample records
RECORD 01Message receivedh₁ = SHA-256(e₁)Links to 64 zeroes
RECORD 02Meet at 11:00h₂ = SHA-256(e₂)Includes h₁
RECORD 03Deletion observedh₃ = SHA-256(e₃)Includes h₂
RETAINED ELSEWHERE3 records · head h₃Compare this fixed boundary with the supplied journal.

Altering an event changes its hash. Rebuilding the chain changes its head. Removing the tail makes it shorter than the retained checkpoint.

This sandbox computes hashes, not signatures. The real verifier also checks every event’s Ed25519 signature, sequence and link. Rebuilding hashes alone cannot create valid signatures under the trusted key.

The actual rules, in a few lines

HASH + SIGNATURE
h0 = 064
hi = hex(SHA-256(C(ei)))
σi = Ed25519.Sign(sk, unhex(hi))

C serializes the nine event fields as UTF-8 JSON: sorted keys, no extra whitespace, no ASCII escaping and no NaN/infinity. The event’s previous_hash is hi−1. The displayed h0 means 64 zero characters; signatures cover the 32 raw digest bytes.

The nine fields are seq, observed_at, source_at, kind, chat_id, message_id, actor_id, payload and previous_hash. This is TgWitness’s documented JSON encoding; the hash and signature themselves are not hash-input fields.

RETAINED CHECKPOINT
Nexport ≥ Ncheckpoint
hexport[Ncheckpoint] = Hcheckpoint

Verify the checkpoint signature under the pinned collector key, then compare its boundary with the verified journal. A later export may contain more records; it must still agree at the earlier checkpoint.

Three questions, three different checks

A matching hash chain answers an integrity question. It does not establish complete Telegram delivery, the truth of a message or an independently trusted observation time.

Follow the whole-account investigation from acquisition to case package.