Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ゲーティングロジック

「Verified」表示の条件と、表示を阻止する不変条件を解説します。

「必要な検証が未実行または失敗なら Verified を表示しない」 という原則に基づき、各検証チェックの結果がどのように最終判定に集約されるかを説明します。

最終判定の種類

検証パイプラインの結果は、verificationChecks の集約結果として以下に分類されます。

表示ステータス条件UI 表示
Verified必須チェックがすべて success かつ任意チェックも劣化なし緑色
Verification Failed必須チェックのいずれかが failed赤色
Warning必須チェックに not_run / pending / running が残る、または任意チェックが劣化している黄色

ステータスの判定順序

優先順判定条件最終ステータス
1必須チェックに failed が 1 つでもあるVerification Failed
21 に該当せず、必須チェックに not_run / pending / running が 1 つでもあるWarning
31,2 に該当せず、任意チェックに failed / not_run が 1 つでもあるWarning
4上記いずれにも該当しないVerified

補助判定のゲーティング(validateVotingIntegrity

validateVotingIntegrity はクライアント側の補助判定として実装されています。この関数は 5 つのゲートを順に評価し、いずれかが失敗した時点で canShowVerified = false を返します。

ただし通常の /verify 取得では journal が省略されるため(includeJournal=1 未指定)、この補助判定は標準フローで常時実行されるわけではありません。最終サマリ表示は verificationChecks の集約(deriveVerificationSummary)が優先されます。

ゲート 1: 整合性証明

RFC 6962 の整合性証明により、掲示板が追記専用であることを検証します。

条件結果
整合性証明が暗号学的に検証成功通過
証明の検証失敗canShowVerified = false(スプリットビュー攻撃の可能性)
ルートの不一致(old/new)canShowVerified = false
API エラーで証明を取得できないcanShowVerified = false

ゲート 2: 完全性(Completeness)

zkVM の集計に全投票が含まれたことを検証します。

条件結果
excludedCount が非負整数として存在し、excludedCount == 0通過
excludedCount > 0canShowVerified = false最重要不変条件
excludedCount / missingIndices / invalidIndices が欠落・不正値canShowVerified = false

excludedCount > 0 は、投票が意図的に集計から除外されたことを意味します。これは投票システムにおいて最も深刻な不正であり、いかなる場合も「Verified」を表示してはなりません。

ゲート 3: 警告の収集

validateVotingIntegrity では totalExpected != treeSizeinvalidIndices > 0 を警告として収集します(excludedCount == 0 の場合)。

ただし、verificationChecks 側では counted_expected_vs_tree_size が必須チェックであり、totalExpected != treeSizefailed として最終的に Verified をブロックします。

ゲート 4: 第三者 STH 検証(有効時のみ)

STH ソースが設定されている場合のみ評価されます。

条件結果
STH ソースが未設定このゲートをスキップ
比較可能な応答群で合意成立 かつ matchingSources >= minMatches通過
合意が成立しないcanShowVerified = false
一致ソース数が最小要件未満canShowVerified = false

STH 合意の検証では、STH ダイジェストは必須照合です。bulletinRoottreeSize は各ソースが値を返した場合にのみ照合対象になります。

  • STH ダイジェスト(logId || treeSize || timestamp || bulletinRoot の SHA-256)
  • 掲示板ルート(返却時)
  • ツリーサイズ(返却時)

ゲート 5: ユーザーインデックスの範囲検証

投票者のインデックスがツリーサイズの範囲内であることを確認します。

条件結果
userIndex < treeSize通過
userIndex >= treeSizecanShowVerified = false

STARK 検証のゲーティング

STARK 検証は整合性検証とは独立に評価されます。

STARK ステータス説明最終判定への影響
success暗号学的に検証成功他の必須チェックも success なら Verified 可能
failed検証失敗Verified をブロック
dev_mode開発モードのフェイクレシートallowDevModeVerification=true なら success、それ以外は not_run
not_run未実行missing_evidence(Warning)扱い。Verified をブロック
running実行中in_progress(Warning)扱い。Verified をブロック

現在の実装では、STARK not_run の状態で「Verified(整合性)」を緑表示する経路はありません。

zkGate: STARK 結果に基づく Counted チェックの制御

STARK 検証の結果は、Counted-as-Recorded 段階のチェック評価にも影響します。これを zkGate と呼びます。

STARK 解決後ステータスCounted チェックへの反映
runningpending
not_runnot_run
failedfailed
successゲートなしで通常評価

dev_mode は事前に success または not_run に正規化されてから zkGate に入力されます。


ステップとチェックの対応関係

UI に表示される 4 つのステップは、20 個のチェックのサブセットから派生します。

ステップ対応するチェック ID
Cast-as-Intendedcast_receipt_present, cast_choice_range, cast_random_format, cast_commitment_match
Recorded-as-Castrecorded_inclusion_proof
Counted-as-Recordedcounted_missing_indices_zero, counted_tally_consistent
STARK Verificationstark_receipt_verify

ステップのステータスは、対応するチェックのステータスから集約されます。

集約ルール条件
failedいずれかの対応チェックが failed
runningfailed がなく、いずれかが running
pendingfailed/running がなく、いずれかが pending
success全対応チェックが success
not_run上記のいずれにも該当しない

UI シーケンスとポーリング

検証ページでは、4 つのステップが順次アニメーション表示されます。

sequenceDiagram
  participant U as ブラウザ
  participant S as サーバー

  Note over U: ページロード時
  U->>S: GET /api/verify
  S-->>U: 検証ペイロード

  Note over U: STARK 完了まで待機

  loop STARK ポーリング
    U->>S: GET /api/verify
    S-->>U: verificationStatus 確認
  end

  Note over U: STARK 解決後に<br/>ステップを順次表示

  Note over U: Step 1: Cast-as-Intended
  Note over U: Step 2: Recorded-as-Cast
  Note over U: Step 3: Counted-as-Recorded
  Note over U: Step 4: STARK Verification

  Note over U: 最終判定を表示

重要な制約として、STARK 検証が完了するまで、ステップの表示シーケンスは開始されません。これは、STARK の結果が Counted チェックの評価(zkGate)に影響するためです。


不変条件のまとめ

以下の不変条件は、コードの変更によっても決して緩和してはなりません。

不変条件根拠
excludedCount > 0 → Verified を表示しない投票除外は最も深刻な不正
整合性証明の失敗 → Verified を表示しない追記専用性が保証されない
STH 合意の不成立(有効時) → Verified を表示しないスプリットビュー攻撃の可能性
not_run チェックの存在 → Verified を表示しない証拠の不在を成功として扱わない
STARK 検証の失敗 → Verified を表示しないジャーナルの正当性が保証されない
非公開アーティファクトをバンドルに含めない投票の秘匿性を維持

これらの不変条件は、改ざんシナリオ(S0〜S5)の検出を保証する基盤です。各シナリオがどの不変条件によって検出されるかは、改ざんシナリオ を参照してください。