Skip to main content

原文準拠 Phase 2:ゼロ知識証明

2.3 Kachina プロトコル

Midnight Academy Phase 2 / Unit 2 / 2.3 The Kachina Protocol の原文準拠版。公開状態と秘密状態の二重構造、ゼロ知識証明という橋、トランスクリプトによる並行処理、UC セキュリティを正確に・やさしく。


📘 Academy原文準拠 | Phase 2 · Unit 2 · Lesson 2.3 The Kachina Protocol 内容に忠実な日本語版です。原文(英語)・図・動画は公式 Academy(外部リンク・別タブで開きます)を正本に。

前のレッスンでは、Midnight がトークンの目的に合わせて UTXO モデルと Account モデルを使い分けることを見ました。でもそれは「トークンがどう動くか」を説明しただけです。本当に知りたいのは、こちらの問いです。データの一部を秘密にしたまま、どうやってスマートコントラクトを動かすのか?

これこそ Kachina が解決する問題です。

スマートコントラクトのプライバシー問題

オフチェーン(ローカル)の箱に「非公開状態、残高、投票、秘密入力」、オンチェーン(公開)の箱に「公開状態、コミットメント、暗号化された値、公開鍵、約値」が並び、両者が「ZK証明」と書かれた矢印でつながれている図

Ethereum では、スマートコントラクトは「みんなで共有する世界共通の状態(global state)」を読み書きすることで動きます。その状態は誰でも見られます。関数を呼ぶと、入力・出力・状態変更がすべて公開されます。多くのアプリではそれで問題ありませんが、機密データを扱うものでは致命的です。

ビジネスが本当に必要としているものを考えてみましょう。サプライチェーンのコントラクトは在庫を追跡したいかもしれませんが、競合に取引先との関係を見られたくはありません。ヘルスケアのアプリは保険の適用資格を確認したいかもしれませんが、患者の記録を公開台帳に載せるわけにはいきません。投票システムは票を正しく数える必要がありますが、一人ひとりの投票内容は秘密でなければなりません。

従来のブロックチェーンは、こんな二択を迫ります。すべてをオンチェーンに置いてプライバシーを失うか、すべてをオフチェーンに置いて分散検証の利点を失うか。

Kachina は、そこに第三の選択肢を用意します。

1つのコントラクトに、2つの状態

Kachina スマートコントラクトの仕組み。左側「オンチェーンの公開状態」にアドレス・公開データ・回路を並べた表、右側「オフチェーンのユーザーごとの非公開状態」にアリスとボブそれぞれの非公開な値が示され、両者は波線で分けられている図

核心はとてもシンプルです。コントラクトの状態(state)(外部リンク・別タブで開きます)を2つに分けること。

  • 公開状態(public state)はブロックチェーン上にあります。誰でも見られます。ネットワークが検証できる必要のあるものを置く場所です。コミットメント、暗号化された値、公開鍵、合計値など。
  • 秘密状態(private state)はあなたの手元の端末にあります。あなたしか見られません。機密なものを置く場所です。実際の残高、投票の選択、秘密の入力など。

コントラクトのロジックは、この両方の状態に同時に作用します。コントラクトのアクションを実行すると、手元では秘密状態を更新し、同時にオンチェーンの公開状態に対応する更新を準備します。大事なのは、秘密データを露出させずに、この2つの状態を同期させる方法です。

橋としてのゼロ知識証明

ユーザー(ローカル)・ZK証明生成器・ブロックチェーンネットワークの3者によるシーケンス図。ローカルで非公開状態を更新し、ZK証明を生成、証明と公開データをネットワークへ送信、公開状態に対して検証して公開状態を更新、トランザクション確定後にローカルの非公開状態の更新を確定する一連の流れ

Kachina でトランザクションが実際にどう動くかを見てみましょう。たとえば、あるコントラクトに対して何かのアクションをしたいとします。秘密トークンを送る、あるいは投票する、など。

  1. まず手元で秘密状態を更新します。トークンを送るなら、自分の秘密の残高から差し引きます。投票するなら、選択を記録します。
  2. つぎにゼロ知識証明(zero-knowledge proof)を生成します。この証明はこう言っています。「私は、有効な秘密状態と有効な入力を持っていて、それらがコントラクトのルールに従って、公開状態に対するこの特定の変更を正当化する」。
  3. この証明は、あなたの秘密状態が何なのか、入力が何だったのかを明かしません。ただ「それらが存在し、有効である」ことだけを証明します。
  4. この証明を、トランザクションに必要な公開データ(暗号化された値、コミットメント、公開状態への参照など)と一緒に、ネットワークへ提出します。
  5. ネットワークのバリデータは、現在の公開状態に対してあなたの証明を検証します。問題なければ、彼らはあなたの提案する更新が正当だと分かります。それを正当化した秘密データが何だったかは一切知らないままです。バリデータは公開状態の変更を適用し、次へ進みます。
  6. 確定後、あなたは完了したトランザクションを反映するように、手元の秘密状態を更新します。コントラクトは正しく実行され、ルールは守られ、そしてあなたの秘密データは端末から一歩も出ませんでした

信頼できる審判(レフェリー)のように

カードゲームを想像してください。あなたの手札を見ずに、手を有効かどうか判定してくれる信頼できる審判が必要だとします。現実の世界では、審判に実際にカードを見せて、誰にも言わないと信じるしかありません。

Kachina は、いわば数学でできた審判を持つようなものです。あなたは審判に「自分の手はルールどおり有効だ」と証明しますが、その証明自体はあなたのカードについて何も明かしません。審判(ネットワーク)は証明を検証し、「はい、この手は合法です」と確認できます。何が合法にしたのかを一切見ることなく

ブロックチェーンとゼロ知識証明が一緒になって、この審判の役を演じます。誰もが「ルールが守られた」と信頼でき、しかも誰も、その手を正当化した秘密の情報を知ることはありません。

トランスクリプトによる並行処理

このモデルには、実用上の課題が1つあります。複数の人が同時に同じコントラクトを更新しようとしたら、どうなるのか?

Ethereum では、同じ状態に触れる同時トランザクションは衝突しえます。ネットワークは勝者を1つ選び、もう一方は失敗します。ZK システムではこれがさらに厄介になります。なぜなら証明の生成は計算コストが高いからです。せっかくの作業を無駄にしたくはありません。

Kachina はこれをトランスクリプト(transcript)で扱います。トランザクションを準備するとき、あなたはコントラクトの状態とのやり取り(行った問い合わせと、期待した応答)を記録したトランスクリプトを作ります。このトランスクリプトが、あなたが証明する内容の一部になります。

うれしいのは、トランスクリプトは並べ替えできる場合があることです。2つのトランザクションが実際には衝突しない(状態の別の部分に触れている)なら、たとえ少し古い公開状態のビューに対して準備されていたとしても、両方とも成功できます。システムは衝突を最小にしつつ、並行性を最大にするように最適化します。

これが必要なのは、ZK 証明の生成は一瞬では終わらないからです。トランザクションの準備を始め、証明の生成に時間をかけ、提出するころには、誰かが先に公開状態を更新しているかもしれません。

Kachina のトランスクリプトの仕組みは、安全性を損なわずに、こうした事態に対する強さ(レジリエンス)を与えてくれます。

開発者が実際に目にするもの

Midnight 上で開発するとき、こうした暗号の細部を直接考える必要はありません。Midnight のスマートコントラクト言語である Compact(外部リンク・別タブで開きます)(TypeScript をベースにしています)を使えば、どのデータが公開でどのデータが秘密かを宣言する形でコントラクトを書けます。ZK 証明の生成は、システムが自動で行います。

あなたが書くのは、たとえばこんな意図です。「この変数はユーザーの秘密。この変数はオンチェーンで公開。この関数が動くときは、これらの条件を確認して、両方の状態を更新する」。

裏側では、Compact があなたのコントラクトを ZK 回路(circuit)にコンパイルします。ユーザーがコントラクトとやり取りすると、その人の手元の環境が証明を生成します。ブロックチェーンがそれを検証します。でも開発者の視点では、あなたはプライバシーの注釈(アノテーション)が少し付いた TypeScript を書いているだけ、という感覚に近いのです。

これは、回路や制約(constraints)の言葉で考えることを要求してくる他の ZK 開発環境とは大きく違います。Kachina のモデルと Compact の抽象化が組み合わさることで、暗号の専門家でない開発者にも、プライバシーを守る開発が手の届くものになります。

セキュリティの土台

ひとつ触れておく価値のある点があります。Kachina は Universally Composable(UC)セキュリティフレームワーク(外部リンク・別タブで開きます)の上に作られています。暗号の深い部分には立ち入りませんが、UC セキュリティが意味するのは、Kachina のコントラクトは、他のプロトコルと組み合わされても、敵対的な環境で動いても、安全であり続けるということです。

あなたは「コントラクトが単体で動く」ことだけを証明しているのではありません。「他のコントラクトと並べてデプロイされ、外部システムと相互作用し、洗練された攻撃者の攻撃下にあっても、安全であり続ける」ことを証明しているのです。

この形式的なセキュリティモデルこそが、Kachina が単なる学術的な習作ではなく、エンタープライズ用途の本格的な土台とみなされる理由のひとつです。

まとめ

Kachina は、Midnight のプライバシーモデルをスマートコントラクトで実現するプロトコルです。二重状態の考え方(公開はオンチェーン、秘密はオフチェーン)を取り、それらをゼロ知識証明を通じて同期させ続けるための、厳密なフレームワークを与えます。

前のレッスンの UTXO / Account ハイブリッドと組み合わせると、次のようなシステムができあがります。

  • トークン転送は UTXO を使い、効率性と並列性を得る
  • 複雑なコントラクト状態は account を使い、シンプルさを得る
  • 秘密データは手元に留まり、チェーンには一切触れない
  • 公開状態は、検証に必要なものだけを捉える
  • ZK 証明が、秘密を明かさずにルールが守られることを保証する

次のレッスンでは、これが実際にどう展開されるか、Midnight のデュアル台帳(dual ledger)システム — これらの概念をインフラのレベルで実装する shielded 台帳と unshielded 台帳 — を見ていきます。

完全な技術的詳細・例・形式的な証明については、原論文を読んでください:Kachina – Foundations of Private Smart Contracts(外部リンク・別タブで開きます)

開発者として押さえる点

  • 状態を2つに分けるのが核心。公開状態はオンチェーン(コミットメント・暗号化値・公開鍵・合計値)、秘密状態は手元の端末(実残高・投票・秘密入力)
  • トランザクションの流れは「手元で秘密状態を更新 → ZK 証明を生成 → 公開データと一緒に提出 → バリデータが現在の公開状態に対し検証 → 公開状態を更新 → 手元の秘密状態を確定」。秘密データは端末から出ない
  • 同時更新の衝突はトランスクリプトで扱う。衝突しないトランザクションは並べ替えで両方成功でき、高コストな ZK 証明生成の無駄を防ぐ
  • 開発者は回路や制約を直接書かない。Compact(TypeScript ベース)で「公開/秘密」を宣言すると、ZK 回路へのコンパイルと証明生成は自動。書き味はプライバシー注釈付きの TypeScript に近い
  • 土台は UC(Universally Composable)セキュリティ。単体だけでなく、他プロトコルとの合成や敵対的環境でも安全であることを保証する形式モデル
  • 次の概念はデュアル台帳(shielded / unshielded)。Kachina の二重状態と UTXO / Account ハイブリッドがインフラ層でどう実装されるか

やさしい版・公式へ

つぎに読むページ

➡️ 原文準拠コースの入口へ戻る。このコースについて(次のレッスンは順次追加します)