TgWitness / ドキュメント

参考文献 / 証拠

証拠の仕組み

ハッシュチェーン、署名、チェックポイント、およびウィットネスについて、検証者が使用する正確な数式を用いて解説しています。

TgWitnessは、収集アカウントが観測した内容を保存し、それらの観測結果を 署名付きジャーナルにリンクさせ、信頼できる 鍵と以前に保存されたチェックポイントを用いて、別の担当者がエクスポート内容を検証できるようにします。

このローカルドキュメントサイトには、 /docs/concepts/ にインタラクティブな例、 /docs/witness/ にチェックポイント決定エクスプローラーが追加されています。すべての例示メッセージ、 カウント、および遅延は架空のものです。チェーンサンドボックス内のハッシュは、 ブラウザ上で SHA-256 を使用して計算されます。Telegram には一切送信されません。

メッセージは変化し、観察結果は蓄積されていきます#

シーケンス図Telegram → コレクター: 新しいメッセージ:10:00に集合してください; コレクター → 署名付きジャーナル: メッセージを追加。new; Telegram → コレクター: 編集:11:00に集合してください; コレクター → 署名付きジャーナル: メッセージ.editedを追加; Telegram → コレクター: 削除に関するお知らせ; コレクター → 署名付きジャーナル: メッセージ.deleted を追加する; 署名付きジャーナル に関する注記: 元のメッセージ、編集、削除の記録がすべて残りますTelegramコレクター署名付きジャーナル新しいメッセージ:10:00に集合してくださいメッセージを追加。new編集:11:00に集合してくださいメッセージ.editedを追加削除に関するお知らせメッセージ.deleted を追加する元のメッセージ、編集、削除の記録がすべて残ります
図表をテキストで記述
  1. Telegram → コレクター: 新しいメッセージ:10:00に集合してください
  2. コレクター → 署名付きジャーナル: メッセージを追加。new
  3. Telegram → コレクター: 編集:11:00に集合してください
  4. コレクター → 署名付きジャーナル: メッセージ.editedを追加
  5. Telegram → コレクター: 削除に関するお知らせ
  6. コレクター → 署名付きジャーナル: メッセージ.deleted を追加する
  7. 署名付きジャーナル に関する注記: 元のメッセージ、編集、削除の記録がすべて残ります

この簡略化された手順では、Telegramが各更新を配信し、選択された アカウントがそれを確認できたことを前提としています。操作イベントもジャーナルに記録されます。削除通知には、 削除者や正確な削除時刻は記載されません。配信の繰り返しは 個別の観測として扱われ、ジャーナル全体での重複排除は行われません。

ハッシュの対象範囲#

観測、エンコード、ハッシュ化、署名:新しいイベントごとに、直前のハッシュが含まれます。

式を内側から外側に向かって読み解いてみましょう。Cは9つのフィールドを正確なバイト列に変換し、 SHA-256はそのダイジェストを生成し、hexはそのダイジェストの保存形式です。前の ハッシュはすでにイベント内に含まれています。unhexは、保存されたハッシュをEd25519が署名する32 バイトのバイト列に戻します。

静的チェーン図

C(ei)を、9つのイベントフィールドからなる正規のUTF-8形式のJSONとします。最初の previous_hashは64個のゼロ文字で構成されます。それ以降の各レコードには、直前の レコードの16進数ハッシュが含まれます:

hi = hex(SHA256(C(ei)))
σi = Ed25519.Sign(sk,unhex(hi))

署名は32バイトの生のダイジェストをカバーします。ハッシュの入力には、 seq、observed_at、source_at、kind、chat_id、message_id、actor_id、 payload、previous_hashが正確に含まれます。オブジェクトキーはソートされており、空白およびASCII エスケープは省略され、NaNおよび無限大は拒否されます。 正確なエンコーディングについてはこちらをご覧ください。

フローチャート64個のゼロ文字 → 記録 1 / ハッシュ h1; 記録 1 / ハッシュ h1 → レコード2にはh1 / ハッシュh2が含まれています; レコード2にはh1 / ハッシュh2が含まれています → レコード3にはh2 / ハッシュh3が含まれています; レコード3にはh2 / ハッシュh3が含まれています → 署名付きチェックポイント:カウント 3、見出し h3 (別の場所に保存する)64個のゼロ文字記録 1 / ハッシュ h1レコード2にはh1 /ハッシュh2が含まれていますレコード3にはh2 /ハッシュh3が含まれています署名付きチェックポイント:カウント 3、見出しh3別の場所に保存する
図表をテキストで記述
  1. 64個のゼロ文字 → 記録 1 / ハッシュ h1
  2. 記録 1 / ハッシュ h1 → レコード2にはh1 / ハッシュh2が含まれています
  3. レコード2にはh1 / ハッシュh2が含まれています → レコード3にはh2 / ハッシュh3が含まれています
  4. レコード3にはh2 / ハッシュh3が含まれています → 署名付きチェックポイント:カウント 3、見出し h3 (別の場所に保存する)
提供されたジャーナルに変更してください どのような場合に検出されるか
保存済みのハッシュを残したまま、レコード2を編集する 再計算されたイベントのハッシュ値が異なります。その署名は、変更されたイベントをカバーしなくなりました。
改変された記録およびその後のすべてのハッシュを再構築します 元の署名が失敗しました。影響を受けた境界に保持されていたチェックポイントも一致していません。
末尾を削除し、残りの接頭辞はそのまま残してください 指定されたプレフィックスより前の、以前に保持されていたチェックポイントによると、エクスポートされたデータが短すぎることが判明しました
別の鍵を使用して、代替のジャーナルに再署名する 別途信頼された鍵のフィンガープリントにより、IDの置き換えは拒否されます

保存済みのフィールドを変更すると、そのダイジェストが変更されます。ハッシュを再計算しても、元の署名は復元されません。

レコード2でこのロジックを試してみてください。保存されたイベント内のMeet at 11:00をMeet at 12:00に変更すると、 再計算されたハッシュは一致しなくなります。後のチェーンを再計算することで リンクを修復することはできますが、元の署名が新しいダイジェストをカバーするようにすることはできません。 対照的に、Telegramでの編集が検出された場合は、新しいジャーナルレコードとして記録されます。

変更履歴図(静的)

ハッシュリンクだけでは、誰かが代替チェーンを再計算することを防ぐことはできません。 信頼性は、独立して信頼されている鍵を用いて署名を検証し、 コレクターの外部に保持されている参照情報と比較することによって得られます。

以前のチェックポイントで追加された内容#

カウント「3」と見出し「h3」はそのまま残してください。後でエクスポートされた4件のレコードは、位置3で確認されます。

ジャーナルが拡大しても、参照位置は変わりません。チェックポイントが 「3件のレコード、ヘッダー h3」と指定している場合、4件のレコードを含むエクスポートでも、3番目の位置にある h3 と一致すれば通過できます。 最新のヘッダーは h4 であり、これが異なることが想定されます。2件のレコードのみを含むエクスポートは失敗します。

静的チェックポイント図

チェックポイントの署名を検証した後、以下を要求してください:

Nexport ≥ Ncheckpoint   and   hexport[Ncheckpoint] = Hcheckpoint

エクスポートデータはチェックポイントの範囲を超える場合があります。その場合、保持された境界において整合性が保たれている必要があります。 実際の検証ツールは、各イベントの順序、前のリンク、ハッシュ、および 署名についても確認します。保存された最終ヘッダーのみを比較すると、内部の レコードが改ざんされていても、保存されたハッシュが更新されていないため、その改ざんを見逃すことになります。

証人の居場所#

フローチャートコレクター/アカウントセッション/キー A → 読み取り専用チェックポイントのエンドポイント; Witness / 固定されたコレクターキー / 独自のキー B → 個別の署名付き証言記録; Witness / 固定されたコレクターキー / 独自のキー B → 読み取り専用チェックポイントのエンドポイント (確認を依頼する); 読み取り専用チェックポイントのエンドポイント → Witness / 固定されたコレクターキー / 独自のキー B (署名付き回答); Witness / 固定されたコレクターキー / 独自のキー B → 署名付きTGW1投稿を配信するチャンネル (Bot API / 独自のトークン)ホスト Aホスト Bコレクター/アカウントセッション/キー A読み取り専用チェックポイントのエンドポイントWitness /固定されたコレクターキー /独自のキー B個別の署名付き証言記録署名付きTGW1投稿を配信するチャンネル確認を依頼する署名付き回答Bot API / 独自のトークン
図表をテキストで記述
  1. コレクター/アカウントセッション/キー A → 読み取り専用チェックポイントのエンドポイント
  2. Witness / 固定されたコレクターキー / 独自のキー B → 個別の署名付き証言記録
  3. Witness / 固定されたコレクターキー / 独自のキー B → 読み取り専用チェックポイントのエンドポイント (確認を依頼する)
  4. 読み取り専用チェックポイントのエンドポイント → Witness / 固定されたコレクターキー / 独自のキー B (署名付き回答)
  5. Witness / 固定されたコレクターキー / 独自のキー B → 署名付きTGW1投稿を配信するチャンネル (Bot API / 独自のトークン)

このウィットネスは、ロールバック、同じカウント数で異なるヘッダー、変更されたキー、 無効な回答、および欠落した応答を記録します。カウント数が増加しただけでは、 それ以前のすべての記録が変更されていないとは断定できません。エクスポートデータを、保存されている チェックポイントと比較してください。別のホスト上のウィットネスを利用することで、コレクターのホストの障害の影響を受けずに済みます。 また、別のオペレーターが運用することで、さらなる独立性が確保されます。

この「witness」は、コレクターから報告されたジャーナルの状態を証明するものです。 Telegramのすべてのメッセージを独自に監視するものではありません。witnessの設定についてはこちらをご覧ください。

既知のアクションに対するテストの実施#

管理されたグループ、個別の収集用アカウント、および新しいマーカーを使用してください。意図的に送信、 編集、削除を行い、各段階の間で記録が正しく行われているかを確認してください。結果を検証する前に、 想定される動作とカットオフを定義してください。

R = |observed∩expected| / |expected|      Δ t = treceipt - taction

想定されたアクションのみがカウントされます。重複する受信記録は 分子を増やしません。分母はゼロ以外でなければなりません。受信記録が欠落している場合、測定された 遅延はありません。クロックの不確実性を明記してください。Telegramは正確な削除時刻を提供しないため、 ご自身で管理した削除アクションの時刻を使用してください。 5/6 (83.3%) といった結果は、テスト対象のアクションについて示すものであり、Telegramの全トラフィックの完全性を示すものではありません。

ワークフローを選択してください#

調査の完全な手順は、 チャンネル、グループ、ボット、プライベートチャットにまたがるインシデントを例に解説しています:

  1. アカウント全体の調査モードを有効にし、アクセス可能なすべてのチャットを網羅的に記録します。
  2. ジャーナルのスナップショット、チャットごとの完全な履歴、および保存された添付データを取得できます。
  3. リアルタイムの変更や、パネルとの意図的なやり取りを、その記録とともに保存します。
  4. 引用された記録や人物プロフィールを通じて、数値の送信者ID、返信の関係性、繰り返される宛先、およびファイルの ハッシュを追跡します。
  5. タイムスタンプと明示的な空白期間の両方を含め、チャット間のタイムラインを再構築します。
  6. 他のアカウントのワークスペースを比較しつつ、それぞれの起源と鍵を分離して管理します。
  7. 署名付きジャーナル、プロフィール、履歴のエクスポートデータを、ケースノートとともにまとめ、検証してください。

当サイトの「/docs/cases/」ガイドには、インタラクティブなケースマップや、 ボットをめぐる紛争、削除されたメッセージ、参加者の名前変更などに関する対応例が掲載されています。ケースノート やワークスペース横断的な分析は外部で行われます。本アプリケーションは、 グローバルな調査グラフや統合されたケースアーカイブを自動的に生成するものではありません。

検証完了事項および残りの作業 · エクスポートと検証 · まずは1つのアカウントから始めましょう