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

チェック一覧

全検証チェック ID の定義、判定ロジック、失敗時の影響を一覧で解説します。

各チェックは一意の ID を持ち、success / failed / not_run / running / pending のステータスで管理されます。not_run のチェックが残っている場合、「Verified」は表示されません。

チェックの属性

各チェックには以下の属性が定義されています。

属性説明
IDチェックの一意な識別子(スネークケース)
カテゴリ所属する検証段階
証拠種別チェックに使用するデータの出所
重要度required(必須)または optional(任意)
派生元他のチェックから結果を導出する場合のソースチェック ID

証拠種別

種別説明
local投票時に確定したユーザー固有データ(現行 /api/verify では主にセッション保存値)
public掲示板や公開 API から取得可能なデータ
zkzkVM ジャーナル(公開出力)に含まれるデータ

重要度

重要度説明
required「Verified」表示に必須。失敗すれば即座にブロック
optional補助的な検証。失敗しても単独では「Verified」をブロックしない

Cast-as-Intended(4 チェック)

投票者の意図通りにコミットメントが生成されたかを検証するチェック群です。 現行実装では、このカテゴリの入力は /api/verify が返す voteReceipt / userVote(セッション復元データ)を起点に評価されます。

ID説明証拠種別重要度
cast_receipt_presentレシートが存在し、voteId とコミットメントを含むlocalrequired
cast_choice_range選択肢が有効範囲内(A〜E)localrequired
cast_random_format乱数が 32 バイトの 16 進数文字列localrequired
cast_commitment_match投票時データから再計算したコミットメントがレシートと一致localrequired

判定ロジックの詳細

cast_receipt_present: voteReceipt が存在し、voteIdcommitment フィールドが存在することを確認します(このチェック単体では UUID/hex 形式までは検証しません)。

cast_choice_range: 投票時データの選択肢が AE のいずれかであることを確認します。範囲外の値は不正な入力として failed となります。

cast_random_format: 投票時データの乱数が 32 バイト(64 文字)の 16 進数文字列であることを確認します。0x プレフィックスの有無は正規化により吸収されます。

cast_commitment_match: 投票時データ(選挙 ID、選択肢、乱数)からコミットメントを再計算し、レシートのコミットメント値と照合します。ドメインタグ "stark-ballot:commit|v1.0" を含む正準フォーマットに従います。


Recorded-as-Cast(6 チェック)

コミットメントが掲示板に正しく記録されたかを検証するチェック群です。

ID説明証拠種別重要度派生元
recorded_commitment_in_bulletinコミットメントが掲示板ツリーに存在するpublicoptionalrecorded_inclusion_proof
recorded_index_in_range掲示板インデックスが 0 以上かつツリーサイズ未満publicrequired
recorded_root_at_cast_consistent投票時のルートがルート履歴に存在するpublicoptionalrecorded_consistency_proof
recorded_inclusion_proofRFC 6962 包含証明が暗号学的に検証成功publicrequired
recorded_consistency_proofRFC 6962 整合性証明が暗号学的に検証成功publicrequired
recorded_sth_third_party第三者 STH ソース間で合意が成立(比較可能応答間)publicoptional

判定ロジックの詳細

recorded_commitment_in_bulletin: 包含証明(recorded_inclusion_proof)の結果から派生します。包含証明が成功すれば、コミットメントがツリーに存在することが暗号学的に証明されています。

recorded_index_in_range: 掲示板インデックスが 0 <= index < treeSize の範囲内であることを確認します。範囲外のインデックスは、データの不整合を示します。

recorded_root_at_cast_consistent: 整合性証明(recorded_consistency_proof)の結果から派生します。整合性証明が成功すれば、投票時のルートが最終ツリーの有効なプレフィックスであることが証明されています。

recorded_inclusion_proof: 投票者のコミットメントに対する RFC 6962 包含証明(監査パス)を検証します。リーフハッシュと監査パスからルートを再計算し、期待するルートハッシュと照合します。

recorded_consistency_proof: 投票時のツリー(oldSize, oldRoot)から最終ツリー(newSize, newRoot)への RFC 6962 整合性証明を検証します。この証明は、古いツリーが新しいツリーの追記専用プレフィックスであることを保証します。

recorded_sth_third_party: 設定された STH ソースからスナップショットを取得し、比較可能な応答同士で合意を確認します。判定は matchingSources >= minMatches(デフォルト: 2)に加えて、比較対象になった応答間の全会一致(consensus)が必要です。照合対象は STH ダイジェストが必須で、bulletinRoot / treeSize は各ソースが返した場合に追加で照合されます。STH ソースが未設定の場合は not_run になります。

このチェック定義の criticalityoptional ですが、サマリー判定では STH ソースが設定されている場合に実質的な必須条件として扱われます。

派生チェックについて

recorded_commitment_in_bulletinrecorded_root_at_cast_consistent は、それぞれ recorded_inclusion_proofrecorded_consistency_proof から結果を派生します。これは、包含証明の検証成功がそのまま「コミットメントの存在」の証明となり、整合性証明の検証成功がそのまま「ルートの一貫性」の証明となるためです。

派生チェックの重要度が optional であるのは、派生元の required チェックが既にカバーしているためです。


Counted-as-Recorded(8 チェック)

記録された全投票が正しく集計に含まれたかを検証するチェック群です。

ID説明証拠種別重要度
counted_input_sanity公開入力サマリーが有効publicrequired
counted_unique_indices入力中の全インデックスが一意publicrequired
counted_unique_commitments入力中の全コミットメントが一意publicrequired
counted_tally_consistentclaimed tally と zkVM の検証済み集計が一致(fallback: 合計整合)zkrequired
counted_missing_indices_zero除外された投票数が 0zkrequired
counted_expected_vs_tree_sizetotalExpected がツリーサイズと一致zkrequired
counted_my_vote_includedビットマップ証明により自分のインデックスが集計に含まれたことを確認zkrequired
counted_input_commitment_match公開入力から計算した入力コミットメントがジャーナルの値と一致publicrequired

判定ロジックの詳細

counted_input_sanity: 公開入力サマリー(publicInputSummary)が存在し、必要なフィールド(選挙 ID、掲示板ルート、ツリーサイズ、投票数等)を含んでいることを確認します。

counted_unique_indices: zkVM に渡された全投票のインデックスが重複なく一意であることを確認します。重複インデックスは、同一投票の二重カウントを示す可能性があります。

counted_unique_commitments: zkVM に渡された全投票のコミットメントが重複なく一意であることを確認します。重複コミットメントは、同一コミットメントに対する複数投票を示す可能性があります。

counted_tally_consistent: 主経路では、公開される claimed tally(tally.counts)が zkVM の verifiedTally と選択肢ごとに一致し、かつ verifiedTally の合計が tally.totalVotes と一致することを確認します。これにより「公開表示された集計値」と「zkVM が証明した集計値」の不一致を検出します。claimed tally が利用できない場合は、フォールバックとして journal.verifiedTally の合計と journal.validVotes の一致を検証します。

counted_missing_indices_zero: zkVM ジャーナルの excludedCount が 0 であることを確認します。このチェックは本システムの最重要不変条件であり、0 でない場合は即座に検証を失敗とします。

counted_expected_vs_tree_size: totalExpected(期待される投票数)が掲示板のツリーサイズと一致することを確認します。不一致は、暗黙の投票除外を示す可能性があります。

counted_my_vote_included: ビットマップ Merkle 証明を検証し、投票者のインデックスに対応するビットが 1(集計に含まれた)であることを確認します。サーバーから取得した leafChunkauditPath を使用し、ビットマップルートまでの Merkle パスを検証します。

counted_input_commitment_match: 公開入力から入力コミットメント(全投票 + Merkle パスの正準ハッシュ)を計算し、zkVM ジャーナルに記録された入力コミットメント値と照合します。一致すれば、zkVM が公開入力と同一のデータを処理したことが保証されます。


STARK Verification(2 チェック)

STARK 証明の暗号学的正当性を検証するチェック群です。

ID説明証拠種別重要度
stark_image_id_matchレシートの Image ID が期待値と一致zkrequired
stark_receipt_verifySTARK レシートが暗号学的に検証成功zkrequired

判定ロジックの詳細

stark_image_id_match: レシートに記録された Image ID が、imageId-mapping.json で定義された期待 Image ID と一致することを確認します。不一致は、異なるゲストプログラムで生成された証明であることを示します。

stark_receipt_verify: サーバー側の Rust 検証サービスが Receipt::verify(image_id) を実行し、Seal(STARK 証明)が暗号学的に正当であることを確認します。チェック結果としては success / failed / not_run / running が使われ、dev_mode は許可設定に応じて success または not_run に正規化されます。


チェックステータスの遷移

stateDiagram-v2
  [*] --> not_run: 初期状態
  not_run --> pending: 依存条件の待機
  not_run --> running: 検証開始
  pending --> running: 依存条件の解消
  running --> success: 検証成功
  running --> failed: 検証失敗
ステータス説明「Verified」への影響
not_run関連データが未取得、または検証未開始ブロック
pending依存する検証の完了を待機中ブロック
running検証を実行中ブロック
success検証成功許可
failed検証失敗ブロック

全チェック早見表

#チェック IDカテゴリ証拠重要度派生元
1cast_receipt_presentCastlocalrequired
2cast_choice_rangeCastlocalrequired
3cast_random_formatCastlocalrequired
4cast_commitment_matchCastlocalrequired
5recorded_commitment_in_bulletinRecordedpublicoptionalrecorded_inclusion_proof
6recorded_index_in_rangeRecordedpublicrequired
7recorded_root_at_cast_consistentRecordedpublicoptionalrecorded_consistency_proof
8recorded_inclusion_proofRecordedpublicrequired
9recorded_consistency_proofRecordedpublicrequired
10recorded_sth_third_partyRecordedpublicoptional
11counted_input_sanityCountedpublicrequired
12counted_unique_indicesCountedpublicrequired
13counted_unique_commitmentsCountedpublicrequired
14counted_tally_consistentCountedzkrequired
15counted_missing_indices_zeroCountedzkrequired
16counted_expected_vs_tree_sizeCountedzkrequired
17counted_my_vote_includedCountedzkrequired
18counted_input_commitment_matchCountedpublicrequired
19stark_image_id_matchSTARKzkrequired
20stark_receipt_verifySTARKzkrequired