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

バンドル構造

証明バンドル(proof bundle)の構成と公開・非公開アーティファクトの区分を解説します。

同期モードと非同期モードで生成されるバンドルの構成、公開許可リスト、および非公開アーティファクト(input.json, verification.json)の保護について説明します。

概要

証明バンドルは、zkVM の実行結果を検証可能な形で保存・配布するためのアーティファクト群です。バンドルには公開可能なファイルと非公開ファイルが含まれ、厳格な許可リストによって第三者に公開するファイルが制御されます。

flowchart TB
  subgraph "バンドルディレクトリ"
    subgraph "公開アーティファクト"
      PI["public-input.json<br/>公開入力"]
      RC["receipt.json<br/>STARK レシート"]
      JN["journal.json<br/>zkVM ジャーナル"]
      MT["metadata.json<br/>メタデータ"]
      STH["sth.json<br/>STH スナップショット"]
      CP["consistency-proof.json<br/>整合性証明"]
    end

    subgraph "非公開アーティファクト"
      IN["input.json<br/>秘匿入力(ウィットネス)"]
      VR["verification.json<br/>検証レポート"]
    end

    BZ["bundle.zip<br/>公開アーカイブ"]
  end

  PI --> BZ
  RC --> BZ
  JN --> BZ
  MT --> BZ
  STH -.-> BZ
  CP -.-> BZ
  IN -.-x BZ
  VR -.-x BZ

公開許可リスト

バンドルアーカイブ(bundle.zip)に含められるファイルは、許可リストによって厳格に制限されています。

公開可能なアーティファクト

ファイル内容用途
public-input.jsonzkVM に渡された入力の公開可能部分第三者が入力コミットメントを再計算するため
receipt.jsonSTARK 証明(Seal)+ ジャーナル + Image ID第三者がレシートを独立に検証するため
journal.jsonzkVM ゲストの公開出力(集計結果、除外情報、ビットマップルート等)集計結果と整合性データの確認
metadata.jsonバンドルの作成日時、セッション ID、メソッドバージョンバンドルの来歴追跡
sth.json第三者 STH 検証のスナップショット(任意)STH 合意の再現可能な証拠
consistency-proof.jsonRFC 6962 整合性証明(任意)追記専用性の独立検証

sth.jsonconsistency-proof.json は許可リストに含まれますが、現行フローでは通常生成されません。

非公開アーティファクト

ファイル内容非公開の理由
input.jsonzkVM への完全な入力(全投票データ + Merkle パス)投票の秘匿入力(ウィットネス)を含む
verification.json検証サービスの詳細レポートbundle.zip の許可リスト外(必要時は専用エンドポイントで参照)

input.json は zkVM ゲストへの完全な入力であり、個々の投票者の選択肢と乱数が含まれます。これが公開されると、投票の秘匿性が失われます。verification.jsonbundle.zip の公開配布対象ではなく、必要時のみ専用エンドポイント経由で扱います。


公開入力の構造

public-input.json は、input.json(秘匿入力)から秘密情報を除外した公開版です。

フィールド説明
schemaスキーマ識別子("stark-ballot.public_input"
versionスキーマバージョン("1.0"
electionId選挙 ID(UUID)
electionConfigHash選挙設定のハッシュ
bulletinRoot掲示板の最終ルートハッシュ
treeSize掲示板のツリーサイズ
totalExpected期待される投票数
logId掲示板ログ ID
timestamp集計時のタイムスタンプ
methodVersionzkVM メソッドバージョン
votes各投票のインデックス、コミットメント、Merkle パスの配列

votes 配列には各投票のインデックスとコミットメント、Merkle パスが含まれますが、選択肢と乱数は含まれません。これにより、入力コミットメントの再計算が可能でありながら、投票内容の秘匿性は維持されます。


同期バンドルと非同期バンドルの違い

証明生成には同期モード(ローカル実行)と非同期モード(ECS Fargate)の 2 つのパスがあり、生成されるバンドルの構成が異なります。

flowchart LR
  subgraph "同期モード"
    S1["ローカルプロセスで<br/>ホストバイナリ実行"]
    S2["TypeScript で<br/>全アーティファクト生成"]
    S3["検証サービスを呼び出し<br/>verification.json を保存"]
    S4["許可リストで<br/>bundle.zip を作成"]
    S1 --> S2 --> S3 --> S4
  end

  subgraph "非同期モード"
    A1["ECS Fargate で<br/>ホストバイナリ実行"]
    A2["entrypoint.sh で<br/>公開アーティファクト生成"]
    A3["bundle.zip を<br/>S3 にアップロード"]
    A4["コールバック Lambda で<br/>結果をセッションに保存"]
    A1 --> A2 --> A3 --> A4
  end
項目同期モード非同期モード
実行環境ローカルプロセス / LambdaECS Fargate コンテナ
input.json生成される(非公開保存)ワーク入力として S3 に置かれる(公開配布対象外)
public-input.jsonTypeScript で生成entrypoint.sh 内で生成
journal.jsonTypeScript で生成*-output.json から bundle.zip 用に生成
receipt.jsonホストバイナリ出力を保存*-receipt.jsonreceipt.json としてコピーして同梱
metadata.json生成される生成されない
verification.json検証サービス呼び出し後に保存コールバック処理では生成されない
bundle.zip許可リストに基づき作成receipt.json / journal.json / public-input.json を同梱して作成
保存先ローカルファイルシステム(+ 任意で S3)S3
presigned URLS3 アップロード時に生成コールバック Lambda が生成

非同期バンドルの生成フロー

非同期モードでは、ECS Fargate コンテナの entrypoint.sh が以下の手順でバンドルを構築します。

  1. S3 から入力 JSON をダウンロード
  2. ホストバイナリを実行し、レシートと出力を生成
  3. 出力から journal.json を変換生成
  4. 入力と出力から public-input.json を構築
  5. receipt.jsonjournal.jsonpublic-input.jsonbundle.zip にアーカイブ
  6. *-receipt.json / *-output.json / public-input.json / bundle.zip などを S3 にアップロード

コールバック Lambda は S3 のバンドルからジャーナルとレシートを取得し、presigned URL を生成してセッションデータに保存します。 非同期モードでは、journal.json*-output.json から変換され、receipt.json*-receipt.json をコピーしたものを bundle.zip に格納します。


バンドルディレクトリ構造

同期モード(ローカルファイルシステム)

{VERIFIER_WORK_DIR}/
  {sessionId}/
    {executionId}/
      input.json               ← 非公開: ウィットネス
      public-input.json        ← 公開
      journal.json             ← 公開
      receipt.json             ← 公開
      metadata.json            ← 公開
      verification.json        ← 非公開: 検証レポート
      bundle.zip               ← 公開: 許可リストファイルのアーカイブ

非同期モード(S3)

s3://{BUCKET}/sessions/{sessionId}/{executionId}/
  input.json                 ← 非公開: ワーク入力
  {inputBase}-receipt.json   ← ホストの生出力
  {inputBase}-output.json    ← ホストの生出力
  {inputBase}-journal.json   ← ホストが生成した場合のみ
  public-input.json          ← 公開
  bundle.zip                 ← 公開: 内部は receipt.json / journal.json / public-input.json
  verification.json          ← `/api/verification/run` 後に追加される場合がある

inputBase はコンテナ実行時に生成される一時入力ファイル名に依存するため、非同期モードの S3 オブジェクト名は固定の receipt.json / journal.json になりません。


バンドルのアクセス方法

ダウンロードエンドポイント

エンドポイント内容
GET /api/verification/bundles/:sessionId/:executionIdbundle.zip のダウンロード
GET /api/verification/bundles/:sessionId/:executionId/reportverification.json の取得

S3 にアップロードされたバンドルは presigned URL 経由でアクセスされます。presigned URL は有効期限付きであり、期限切れの場合はクライアントが /api/verify?refreshS3=1 で新しい URL を取得できます。

アーカイブの再現性

同期モード(verification-bundle.ts)の bundle.zip は再現性を確保するため、以下の措置を講じています。

  • エントリのタイムスタンプをゼロに固定
  • 許可リストに一致するファイルのみを含める
  • ファイル名のアルファベット順でエントリを追加

非同期モード(docker/entrypoint.sh)は zip -r で作成され、上記の再現性制御とは実装が異なります。


セキュリティ上の制約

パストラバーサル防止

バンドルのパスセグメント(セッション ID、実行 ID)は英数字とハイフンのみに制限されています。.. を含むパスや許可されていない文字を含むパスは拒否されます。

非公開ファイルの保護

input.jsonverification.json は、bundle.zip には含まれません。これらのファイルがバンドルディレクトリに存在していても、許可リストに含まれていないため、アーカイブ作成時に除外されます。