現在、パブリックなブロックチェーンで大きな課題となっているのが、スケーラビリティ問題とプライバシー問題です。スケーラビリティ問題はすでに送金遅延や手数料増加などユーザーにとっても実害が現れているので、一番深刻な問題であるとされています。
しかし、ブロックチェーンでのプライバシー問題も解決されなければならない問題です。普通に送金をするだけなら特にプライバシーについて意識することはありませんが、イーサリアムではスマートコントクトに記述した内容を他者に公開したくない場面(位置情報などプライベートな情報)はよく出てくるはずです。
イーサリアムではZcashという仮想通貨に導入されたzk-SNARKというトランザクションの機密化技術を組み入れることでプライバシー問題に対処しようとしています。そこで、当記事ではzk-SNARKの概要とその仕組みについて紹介していきます。
イーサリアムにおけるプライバシー保護
「匿名な取引」と聞くとマネーロンダリングやダークマーケットでの利用などネガティブなことを連想してしまいますが、イーサリアムにおいて匿名な取引を実現することはとても大切です。
例えば匿名化していないトランザクションにおいては、アリスがボブに10ETHを送金するトランザクションを作り実行した場合、「送金者:アリス」「受け手:ボブ」「送金額:10ETH」という情報は誰でも見ることが可能です。一方、zk-SNARKで匿名化されていると上記の送金者、受け手、送金額の情報は第三者は確認することはできません。しかし、そのトランザクションに不正がないということは確認することができます。
イーサリアムではzk-SNARK実装以前にもハッシュを使った機密化技術は導入されていましたが、デジタルアセットの交換などシンプルな取引でしか使用することができず、かつ効率的ではありませんでした。このようなシンプルな取引において非効率な機密化技術の必要性はほとんどありません。
しかし、zk-SNARKを導入することで匿名化するアルゴリズムをプリコンパイルされたコントラクトとして作りブロックチェーンに追加できるので、効率的で柔軟な機密化をスマートコントラクトでも行うことができるようになることが期待されています。
これにより、位置情報や過去の取引履歴などのプライベートな情報あるいはビジネスでの利用場面で競合他社に知られたくない情報を公開することなくスマートコントラクトを実行することができます。
zk-SNARKとは
zk-SNARKとは、Zero Knowledge – Succinct Non-interactive ARgument of Knowledge の略になります。
Zero Knowledgeとは、後述するゼロ知識(証明)のことであり「相手に情報の内容を公開することなく、情報自体は知っていることを証明する技術」です
Succinctとは、実際に実行する計算量よりメッセージのサイズがとても小さいことです。Non-interactiveとは、証明者と承認者がリアルタイムで互いにやり取りをすることなく証明を行えるということです。argument of knowledgeは、計算による知識の証明のことを言っています。
要はSNARKとは、承認者が証明者に問いを出すことなく承認作業を短時間かつ少ない計算量で行うことができるという概念になります。
まず、zk-SNARKの基本概念となるゼロ知識証明について紹介していきます。
ゼロ知識証明(ZKP)とは
ゼロ知識証明とは、相手にその知識を教えずに自分がその知識を知っていることを証明する方法です。その情報の内容は一切明らかにすることなく、その情報を知っていることだけを相手に知らせるのです。
例えば、アリスだけが知っているXという情報についてアリスは直接Xを提示して知っていることを証明するのではなく、Xをハッシュ関数に通してH(X)というハッシュ値を提示することで、ボブはアリスがXを知っていることが分かります。
この例において、アリスは「その情報を知っていること」を証明しているので証明者(prover)と呼び、ボブは「相手がその情報を知っていること」を確かめることができているので承認者(verifier)と呼びます。
つまり、証明者が直接その情報の内容を明らかにすることなく、その情報を知っていることを承認者に証明するのがゼロ知識証明と言えます。ゼロ知識証明として成立するためには以下の3つの条件を満たすことが必要です。
- 証明者が正しい情報であると証明することができていたら、承認者は承認をする
- 証明者が嘘をついていたら(本当はその情報を知らないのに知っているものとして証明をしていたら)、承認者は承認をしない
- 承認者は証明者が証明した情報の内容自体は知ることはできない(情報の存在性のみ知れる)
このようなゼロ知識証明を応用することで、ブロックチェーンネットワークにおいて、送信者(証明者)はトランザクションの内容を明らかにすることなく、ネットワークのノード(承認者)はそのトランザクションが正当であると承認することができるのです。
しかし、一般的にゼロ知識証明を行うには証明者が本当にその情報を知っているのか確認するために、証明者と承認者が互いにコミュニケーションを取る必要があります。つまり、証明者と承認者は同時にリアルタイムでオンラインで、かつ複数回やり取りをしなければならないということです。
イーサリアムでzk-SNARKをスマートコントラクトに利用しようとする場合、スマートコントクトに資金をロックしておき、スマートコントクトでのコードが記述した条件で資金がアンロックされるので証明者と承認者がリアルタイムでオンラインであることは現実的ではありません。interactiveではなくnon-interactiveでなければならないのです。non-interactiveにするには後述するようにハッシュ関数を上手く使うことで実現できます。
このようなゼロ知識証明の欠点を補うために、zk-SNARKでは証明者が承認者に対してメッセージを1回送信するだけでゼロ知識証明が可能にしています。
zk-SNARKの仕組み
ここではzk-SNARKを使って一部の情報を隠したトランザクションが承認されるまでの流れを見ていきます。ハッシュ関数の知識を前提としていきますので以下の記事もあわせてご覧ください。
参考:ブロックチェーンの技術「一方向性ハッシュ関数」を理解しよう
証明者アリスは機密情報Xの内容を明かすことはできないけれど、機密情報Xの内容が正しければネットワークの承認者は承認しトランザクションを実行することができます。正しくなければ承認をできず、トランザクションは実行できません。
zk-SNARKは、以下の3つのアルゴリズムから成っています。
G:鍵を生成するアルゴリズム(ある秘密の値RとプログラムCから証明鍵(pk)と承認鍵(vk)を生成する。(pk, vk) = G(R,C) )
P:証明者が証明をするアルゴリズム(証明鍵(pk)と証明する情報(X)とプログラムCへのインプット(h)から証明(prf)を生成する。prf = P(pk, X, h) )
V:承認者が証明を正当かどうか承認するアルゴリズム(承認鍵(vk)とプログラムCへのインプット(h)と証明(prf)から「正当か不正か」を返す。 V(vk, h, prf) = True or False )
これらG、P、Vのアルゴリズムを使った実際の流れは以下のようになります。
まず、承認者はある値RとプログラムCをアルゴリズムGにインプットして、証明鍵と承認鍵を生成します。
証明鍵と承認鍵は公開しても問題ありませんが、値Rはアリスに知られてはいけません。もし値Rがアリスに知られてしまったら、アリスは不正な証明を行えてしまいます。つまり、不正なXをネットワークで承認させることができてしまうのです。なので値Rはアリスには伝えないようにしておきます。
続いて、証明者アリスは公開された証明鍵と機密情報Xと機密情報Xのハッシュ値hをアルゴリズムPにインプットして証明prfを生成します。
アリスはこの証明prfを承認者にブロードキャストし承認者は承認鍵と機密情報Xのハッシュ値hと証明prfをアルゴリズムVにインプットすることでアリスが不正をしていないか確認し承認することができます。つまり、アルゴリズムVのでTrueが返ってきたら機密情報Xは正当であり、Falseが返ってきたらアリスが提示した機密情報Xは誤っていることになります。
この一連のセットアッププロセスにより、アリスは機密情報Xの内容を明らかにすることなく承認者はアリスが機密情報Xを知っていると確信できるのです。
機密情報Xは証明者が実行するアルゴリズムPにしかインプットされず、そのアウトプットからXを推測することはできません。また、アルゴリズムGによって証明鍵と承認鍵が生成されることで、この一連の承認プロセスを素早く実行することができます。
アルゴリズムの中身の数学的な部分はこちらの記事で詳しく解説されています。(zkSNARKs in a nutshell | ethereum blog)
zk-SNARKの具体的な使用例
アリスがボブに10ETH送金するというトランザクションを考えていきます。ここで、アリスとボブのアカウント残高と送金額10ETHはビジネス上の競合他社に知られたくない機密情報となります。この機密情報をXとします。(送り手と受け手のアドレスを匿名にすることも可能です)
この場合、2つのzk-SNARKが使われます。つまりアリスとボブそれぞれがzk-SNARKを実行するのです。
アリスとボブは、それぞれの取引前のアカウント残高と取引額を機密情報X(証明する値)とします。そして、それぞれの取引前のアカウント残高と取引後のアカウント残高と取引額のハッシュ値をhとして上記のセットアッププロセスを実行するのです。
また、アルゴリズムGはオフチェーンで実行され証明鍵と承認鍵を生成します。そして、証明者も同様にオフチェーンでアルゴリズムPを実行し、証明を生成します。アルゴリズムVはスマートコントラクト内で実行され、その出力(承認or不承認)に合わせて次のオンチェーンでのコントラクトが実行されるのです。
zk-SNARKの問題点とその解決策
上記のトランザクションを機密化するための一連のセットアップでは主に3つの解決すべき課題点があげられます。
- 証明鍵と承認鍵の再利用
- Rの秘匿化
- 信頼されたセットアップ(trusted setup)
証明鍵と承認鍵の再利用
一つ目が、1回のセットアップでゼロ知識証明できる情報は1つだけということです。なぜなら値Rは安全性のためプロセス中に破棄してしまうからです。もし同じ値Rを再利用することができれば、同じ証明鍵と承認鍵を生成することができるので、1回のセットアップで複数の情報をゼロ知識証明することができます。
このような制限はイーサリアムでのzk-SNARKを適用した任意のスマートコントラクトを実行するには大きなデメリットとなります。なぜなら、それぞれの新しいコントラクトを行うごとに新しいセットアップを行わなければならないからです。このセットアップはgas(イーサリアムでの手数料)を非常に多く消費します。
zCashでは、信用できる独立したグループが値Rを使ってアルゴリズムGから証明鍵と承認鍵を生成し保持しています。それにより、証明鍵と承認鍵を再利用できるようにしているのです。
イーサリアムでは、この問題に対処するために2つの対策法が提案されています。1つ目が、上記の一連のセットアップを基本的な考え方としてイーサリアムでの利用に適するように改善していくという方法です。もう1つが、zk-SNARKのためのバーチャルマシンを用意して、新しく利用するときにセットアップを必要としないようにするという方法です。
Rの秘匿化
もうひとつの課題点は、アリスに知られてはいけない値Rを複数の承認者で共有しなければならないことです。
承認者が1人だけであれば値Rを安全に保持しておくだけで不正が起こることはありませんが、承認者が複数の場合は値Rがアリスに知られないように安全性を維持することがより難しくなります。なぜなら、アリスに悪意があった場合、スパイを承認者に送り込み値Rを盗むことが可能になってしまうからです。
そのため、実際にはRの値自体は誰も知ることができず、どこにも保存することができないようにとても安全なプロセスをアルゴリズムGが実行することになります。つまり、プロセスの中で値Rは必ず消去されなければならないのです。
信頼されたセットアップ(trusted setup)
一連の安全な信頼されたセットアップ(trusted setup)は、イーサリアムではzk-STARKという技術を導入することが実現しています。
zk-STARKにより上記のアルゴリズムで楕円曲線などを使うのではなく、ハッシュ関数などを使うことで量子コンピューター対策などのセキュリティ面を高めているのです。また、上述した鍵の再利用による新しいセットアッププロセスの立ち上げもzk-STARKにより改善されています。
イーサリアムに導入されたzk-SNARKはgasの大量消費など解決しなければならない部分がいくつかありますが、zk-SNARKが導入されたことでコントラクトにおける柔軟なプライバシー保護を実現できるようになってきています。