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

検証サービス

Rust ベースの STARK レシート検証サービスの設計を解説します。

Receipt::verify(expected_image_id) により、レシートが期待されるゲストプログラムの実行結果であることをサーバー側で検証します。検証結果はレポートとして永続化され、クライアントに提供されます。

概要

検証サービスは、ホストプログラムが生成したレシートの STARK 検証をサーバー側で行う Rust ベースのコンポーネントです。

STARK 証明の検証は計算コストが証明生成に比べて低いものの、ブラウザ上で RISC Zero の検証ロジックを実行することは現時点では実用的ではありません。そのため、本システムではサーバー側で検証を行い、その結果をレポートとしてクライアントに提供する設計を採用しています。

flowchart LR
  subgraph 入力
    RCP[レシート JSON]
    EID["期待 Image ID"]
  end

  RCP --> VS[検証サービス]
  EID --> VS
  VS --> RPT[検証レポート]

検証フロー

検証サービスは以下の手順でレシートを検証します。

flowchart TD
  START[レシート読み込み] --> PARSE[JSON パース]
  PARSE --> FORMAT{レシート形式<br/>の判定}
  FORMAT -->|フラット JSON| F1[直接パース]
  FORMAT -->|ネスト JSON| F2[receipt フィールドを抽出]
  FORMAT -->|ZIP アーカイブ| F3[末尾が receipt.json のファイルを探索]
  F1 --> EXTRACT[Image ID 抽出]
  F2 --> EXTRACT
  F3 --> EXTRACT

  EXTRACT --> MODE[InnerReceipt を判定<br/>Fake は dev_mode 候補として記録]
  MODE --> MATCH{メタデータ Image ID<br/>= 期待 Image ID ?}
  MATCH -->|不一致| FAIL1[検証失敗:<br/>Image ID 不一致]
  MATCH -->|一致| VERIFY["Receipt::verify()<br/>STARK 検証実行"]
  VERIFY -->|成功 かつ Fake| DEVMODE[dev_mode]
  VERIFY -->|失敗 かつ Fake + InvalidProof| DEVMODE
  VERIFY -->|成功 かつ 非 Fake| SUCCESS[success]
  VERIFY -->|失敗(その他)| FAIL2[failed]

1. レシートの読み込みとパース

検証サービスは複数のレシート形式に対応しています。

形式説明
フラット JSONレシートオブジェクトが直接 JSON のトップレベルにある
ネスト JSON{ "receipt": {...}, "image_id": "0x..." } 構造
ZIP アーカイブエントリ名の末尾が receipt.json のファイルを探索

2. 開発モードの検出

レシートの内部構造(InnerReceipt)がフェイク(Fake)型の場合、開発モードで生成されたレシートとして扱います。開発モードのレシートは本物の STARK 証明としては成立しません。

ただし、Fake 検出だけで即 dev_mode にはなりません。Image ID メタデータが不一致の場合は failed となります。照合後の Receipt::verify()Fake レシートが InvalidProof を返したケースは dev_mode として分類します。

補足として、image_id メタデータが欠落している場合は、非 Fake レシートでは failedFake レシートでは Receipt::verify() の結果(通常 InvalidProof)に基づいて dev_mode になる経路があります。

3. Image ID の照合

レシート JSON のメタデータ image_id を期待値と照合します。不一致は failed として即時拒否され、Receipt::verify() には進みません。

この事前チェックにより、異なるゲストプログラムで生成されたレシートを早期に拒否できます。Image ID の管理については Image ID を参照してください。

4. STARK 検証の実行

Image ID の照合に成功した後、RISC Zero SDK の Receipt::verify() メソッドを使用して STARK 証明の暗号学的検証を行います。

この検証は以下のことを証明します:

  • レシートに含まれる seal(証明データ)が有効である
  • ジャーナルの内容が、指定された Image ID のゲストプログラムの正当な実行結果である
  • 証明の生成時にデータの改ざんが行われていない

検証レポート

検証サービスは検証結果を構造化されたレポートとして出力します。

フィールド説明
status列挙型success / failed / dev_mode
expected_image_id文字列検証に使用した期待 Image ID
receipt_image_id文字列?レシートから抽出した Image ID(null 可)
dev_mode_receipt真偽値フェイクレシートであるか
errors文字列[]失敗時の診断情報の配列

ステータスの判定基準

flowchart TD
  S{検証結果}
  S -->|"metadata image_id 不一致"| F1["failed<br/>errors: image_id_mismatch"]
  S -->|"Receipt::verify 成功 + 非 Fake"| OK["success"]
  S -->|"Receipt::verify 成功 + Fake"| DM["dev_mode"]
  S -->|"Receipt::verify 失敗 + Fake + InvalidProof"| DM2["dev_mode"]
  S -->|"Receipt::verify 失敗(その他)"| F2["failed<br/>errors: verification_failed"]
ステータス意味UI への影響
successSTARK 検証が成功し、Image ID も一致STARK Verified を表示可能
failedImage ID 不一致または STARK 検証失敗検証失敗として表示
dev_mode開発モードのフェイクレシート開発モード警告を表示

デプロイメントモデル

検証サービス(Rust バイナリ verifier-service)は、呼び出し経路ごとに実行場所が異なります。

  • 同期ファイナライズ(POST /api/finalize): real executor 利用時のみ API サーバープロセスがローカルに配置されたバイナリを直接実行(mock executor 利用時は verifier-service を呼ばず dev_mode 扱い)
  • 明示的検証(POST /api/verification/run): verifier-service-runner Lambda が S3 バンドルを展開してバイナリを実行
sequenceDiagram
  participant C as クライアント
  participant API as API サーバー
  participant RUNNER as verifier-service-runner Lambda
  participant VS as verifier-service バイナリ
  participant S3 as S3

  C->>API: POST /api/verification/run
  API->>RUNNER: 実行要求(sessionId, executionId, expectedImageId)
  RUNNER->>S3: レシートバンドルを取得・展開
  RUNNER->>VS: レシート + 期待 Image ID
  VS->>VS: STARK 検証実行
  VS-->>RUNNER: 検証レポート
  RUNNER-->>API: 検証レポート
  API->>API: verification.json として保存
  API-->>C: 検証結果

呼び出しパターン

検証サービスの呼び出しには 2 つのパターンがあります。

パターントリガー説明
同期実行同期ファイナライズ (POST /api/finalize)real executor 時のみ、サーバー内の proof-bundle 処理で verifier-service を実行
明示的実行クライアントが検証を要求POST /api/verification/run 経由で実行

非同期ファイナライズのコールバック Lambda は、結果の復元と保存を担当します。STARK 検証は自動実行されず、POST /api/verification/run で実行します。

検証パイプラインにおける役割

検証サービスは、4 段階検証モデルの最終段階である STARK 検証を担当します。

チェック ID検証内容
stark_image_id_matchレシートの Image ID が期待されるゲストプログラムの ID と一致するか
stark_receipt_verifySTARK 証明が暗号学的に有効であるか

これらのチェックが両方成功した場合に限り、「STARK Verified」のステータスが付与されます。詳細は 4 段階検証モデル を参照してください。

セキュリティ上の考慮事項

サーバー側検証の信頼境界

検証サービスはサーバー側で実行されるため、クライアントはサーバーの検証結果を信頼する必要があります。この PoC における信頼モデルは以下の通りです:

  • STARK 証明自体は公開データ: レシートと Image ID が公開されていれば、第三者が独立に検証可能
  • 検証サービスは利便性のための委任: ブラウザでの STARK 検証が実用的になれば、クライアント側検証に移行可能
  • 公開バンドル: レシートと公開入力は ZIP ローカル検証(Ubuntu) の手順で独立検証できる

verification.json の非公開性

verification.json は公開バンドル(bundle.zip)には含まれません。必要に応じてレポート用エンドポイント経由で配布されますが、第三者検証ではレシートファイルを直接使った独立検証が推奨されます。