Develop with pleasure!

福岡でCloudとかBlockchainとか。

MimblewimbleとGrinのトランザクションフロー

Grinのトランザクショントランザクションフローを見てたら、オリジナルのMimblewimbleと署名プロセスが少し変わってたのでまとめてみた。

Mimblewimbleの基本機能

Pedersen Commitment

Gregory Maxwellが提案したConfidential Transactionで導入されたコインの量を秘匿する機能。コインの量をBitcoinのような整数値ではなく、以下のような準同型性のコミットメントとして管理することで取引の当事者以外はコインの量を知り得なくする仕組み。

Commitment = r * G + v * H

GHは同じ楕円曲線上の異なる生成点。rブランディングファクターで、vがコインの量。トランザクションのアウトプットは全てこのコミットメント持つ。MimblewimbleではConfidential Transactionを単純に量の秘匿に使うだけでなく、scriptPubkeyも無くしこのコミットメントに集約している(ブランディングファクターが秘密鍵の役割を果たす。後述)。

Confidential Transactionの仕組みの詳細については先日GBECで解説したスライド参照↓

www.youtube.com

Mimblewimbleのトランザクション

Mimblewimbleでは、Bitcoinのように各インプット毎にそれぞれ署名があるわけではなく、トランザクション毎に1つの署名が作られる。その際、署名に使用する秘密鍵は↑のPedersen Commitmentのブラインディングファクターの総計から作られる。

この辺が躓きがちなポイントなんだけど、Bitcoinの場合、アウトプットはコインの量を持つvalueとそのコインのロックスクリプトであるscriptPubkeyとセットで管理されているが、Mimblewimbleの場合は上述したようにscriptPubkeyのようなロックスクリプトはなく、上記のPedersen Commitmentのみが存在する。それ以外に、コインをロックするような公開鍵の情報などがセットされているわけではない。その状態でどうやってコインを取引するための署名を作るのか疑問に思うが、以下の手順で署名は作られる。

例えば、アリスが以下の2つのコミットメントを持っているとする。

  • c1 = 35G + 4H
  • c2 = 93G + 6H

それぞれブラインディングファクターが3593、コインの量が46で2つ合わせて10コイン持ってることになる。

この状態で、上記2つのコミットメントを使ってアリスからボブに7コイン送る場合、以下のような手順でトランザクションを構成することになる。手数料は1コインとする。

  1. アリスはお釣り用のコミットメントで使用するブラインディングファクターをランラムに選択する。これを47とする(※実際のブラインディングファクターはもっと巨大な値)。
  2. アリスはお釣り用のコミットメント c3 = 47G + 2H を作成する。
  3. アリスは自身が管理するブラインディングファクターの差分(インプットの全ブラインディングファクターからアウトプットの全ブラインディングファクターを差し引いたもの)を計算する。
    47 - (35 + 93) = −81
  4. アリスはトランザクションの雛形とブランディングファクターの総計(-81)をボブに送る。
  5. ボブはブラインディングファクターをランダムに選択する。これを153とする。
  6. ボブは選択したブラインディングファクターを使って、7コンを受け取るコミットメント c4 = 153G + 7H を作成する。
  7. ボブはアリスから受け取ったブランディングファクターの総計に自身のブランディングファクターを加味し、ブランディングファクターの超過値(excess)を算出する。
    153 - 81 = 72
  8. ボブは超過値(72)を秘密鍵として署名を生成しブロードキャストする。
  9. ネットワークのノードはトランザクションの全インプットとアウトプットのコミットメントを相殺して残った楕円曲線上の点=公開鍵(今回の場合は72 * G)に対して有効な署名があるか検証する。
    この時、有効な署名が作成できるということは、コミットメントの内、ブラインディングファクターについてはexcessが存在するが、コインの量についてはアウトプット−インプットで0Hになるということの証明にもなる。

というように、送信者のブラインディングファクターの総計を受け取った受信者が、自身が選択したブラインディングファクターを加味して受信者のみが知りうるexcessを秘密鍵としてしている。Bitcoinの場合はインプットの所有者=送信者が署名を作成するが、Mimblewimbleの場合は受信者が署名を作成することになる。

Mimblewimbleのトランザクションはインプットとアウトプットの他にトランザクションカーネルと呼ばれるデータを持ち、トランザクションカーネルは、

  • 手数料
  • 超過値(excess)
  • excessを使って作成した署名
  • lock_height

を持つ。署名は個々のCommitmentに対して存在するのではなく、トランザクション単位で有効になる。

Grinのトランザクション

GrinはMimblewimbleを実装したブロックチェーンだが、署名手順はMimblewimbleとは多少異なる。オリジナルのMimblewimbleの投稿では、送信者が自身に関連するブラインディングファクターの総計をそのまま受信者に渡すことで、受信者のみがexcess値を知り、それを使って署名を作成していたが、Grinの場合送信者はブラインディングファクターの総計をそのまま渡すのではなく、楕円曲線のベースポイントGに乗算して公開鍵として渡すようになっている。この場合、受信者は自身の受け取り用のアウトプットのコミットメントを作成し、そのブラインディングファクターを加味することで、excess * Gを算出することはできるが、その秘密鍵であるexcessの値を知ることはできない。そのため送信者と受信者は協力し、お互いが知るブラインディングファクターの情報から署名をそれぞれ作り、その署名を集約することでexcess * Gに対して有効な署名を完成させるというアプローチを採っている。

この時作成される署名は、集約特性のあるSchnorr署名が使われる。

Schnorr署名

秘密鍵x秘密鍵に対応する公開鍵をP = x * G、メッセージをMとする。尚、Bitcoinではトランザクションに署名をする際、署名対象のメッセージMトランザクションの各データ(バージョン、locktime、インプット、アウトプットなど)から生成されるが、Grin場合はトランザクションの手数料とlock heightの2つの要素で構成される。

GrinのSchnorr署名の作成手順は以下のとおり。

  1. ランダムにnonce値kを選択する。
  2. R = k * Gを計算する。
  3. e = SHA256(M | R | P)を計算する。
  4. s = k + e * xを計算する。
  5. 算出した(R, s)のペアが署名データ

そして署名の検証は、s * Gs * G = R + ePを満たすか検証する。

Grinの署名手順

Grinの詳細なトランザクションフローは↓にまとめられている。

https://raw.githubusercontent.com/mimblewimble/grin/master/doc/wallet/transaction/basic-transaction-wf.png

送信者は送金にあたって以下の作業をする(内部的な実装の手順は省略)。

  1. トランザクションカーネルに現在のチェーンの高さでlock_heightをセットする。
  2. インプットにするコミットメントを選択する。
  3. インプットのブラインディングファクターの合計x1を計算する。
  4. お釣り用のアウトプット用のブラインディングファクターxCを選択し、お釣り用のアウトプット(コミットメント)を作成する。
  5. トランザクション手数料を計算する。
  6. 全インプットとアウトプットから超過合計xS1 = xC - x1を計算する。
  7. ランダムなnonce値kSを選択する。
  8. xS1からランダムなカーネルオフセットoSを減算した、xS = xS1 - oSを計算する。
  9. 送信者側のブラインディングファクターの総計xSと署名に必要なnonceの値kSをGに乗算して、曲線上の点xS * GkS * Gを計算する。
  10. 相手インプット、アウトプットのコミット、手数料、lock_height、xS * GkS * Gを送る。

受信者は、送信者から受け取った情報を元に以下の作業をする。

  1. 受信用のブラインディングファクターxRを選択し、 受信用のアウトプット(コミットメント)を作成する。。
  2. 署名に用いるメッセージM= fee | lock_heightを作成する。
  3. 署名に使用するランダムなnonce値kRを選択する。
  4. xRとkRをそれぞれGに乗算して、曲線上の点xR * GkR * Gを計算。
  5. Schnorr署名用のチャレンジ e = SHA256(kR * G + kS * G | xR * G + xS * G | M)を計算
  6. 受信者側のSchnorr署名 sR = kR + e*xRを計算する。
  7. 送信者に受信者が計算した部分署名値sRと、xR * G, kR * Gを送る。

送信者は、受信者から受け取った情報を元に署名を完成させトランザクションをブロードキャストする。

  1. 署名に用いるメッセージM= fee | lock_heightを作成する。
  2. Schnorr署名用のチャレンジ e = SHA256(kR * G + kS * G | xR * G + xS * G | M)を計算
  3. 受信者から送られた部分署名であるsRについて、sR * G = kR * G + e * xR * Gが成立するか検証する。
  4. 送信者側のSchnorr署名 sS = kS + e * xS を計算する。
  5. Schnorr署名を完成させる。Schnorr署名のRの値はkS * G + kR * G、sの値はsR + sS
  6. sの値が公開鍵x*G = xS * G + xR * Gに対して有効な署名か検証する。

トランザクションに署名する際の秘密鍵は基本的にMimblewimbleのexcessの値であり、上記のケースであればexcess = xR + xS。このexcess値をお互い知ること無く、協力してSchnorr署名のsの値sR + sS = kR + kS + e * (xR + xS)を計算している。

↑のようにGrinの場合は、Mimblewimbleのオジリナルの投稿とは異なり、送信者と受信者が協力して署名を作成するようになってる。単純にexcess値をそのまま渡すより安全であるというのと、署名のメッセージにlock_heightが含まれることから送信者と受信者の両者がロックタイムに合意するという意味もあるのかもしれない。

自称サトシになる方法

最近また自称サトシが登場してるみたいだったので、自称サトシになるために必要なことを調べてみた。

ecdsa - If someone wanted to pretend to be Satoshi by posting a fake signature to defraud people how could they? - Bitcoin Stack Exchange

自称サトシになるには?

BitcoinGenesis Block↓のコインを移動することができれば、それは自称ではなく間違いなく本物のサトシだが、

https://en.bitcoin.it/wiki/Genesis_block

自称サトシが証明として提供しているのは、Genesis Blockのコインの送金先である公開鍵

04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f

に対して有効な署名。この有効な署名を作ることができるのは、対応する秘密鍵を知るサトシ本人であるというもの。

一見正しい論理に思えるが提供しているデータにトリックがある。まず、正しいECDSA署名についておさらいしておこう。

ECDSA署名の作成と検証

定義にあたって、以下の表記を使用する。

署名の作成

秘密鍵xとメッセージmを使って署名を作成する場合、手順をざっくり書くと以下のようになる。(他にも諸々細かい注意点はあるので詳細はRFCなど参照)

  1. ランダムな値kを選択する。
  2. R = kGを計算し、Rのx座標をrとする。
  3.  {s = \frac{H(m) + r \cdot x}{k}}を計算する。
  4. 計算してできた(r, s)が有効なECDSA署名。

署名の検証

検証者は署名(r, s)、メッセージm、公開鍵Pが与えられた状況で、以下を検証する。

  1. H(m)を計算する。
  2.  {\frac{H(m)}{s}G + \frac{r}{s}P}を計算し、算出した点のx座標がRと等しいか検証する。

自称サトシの証明の作り方

自称サトシも上記ECDSA署名(r, s)を提供しているわけだが、ここにトリックがあり上記のようなプロセスを経て作られたデータではないと思われる。どういうことかというと(r, s)とH(m)は提供しているが、m自体は提供していない。

メッセージのハッシュ値を計算する部分は、ECDSAのアルゴリズム上、必要不可欠な重要なパートであり、署名を検証する検証者は、署名対象のメッセージのハッシュを必ず自身で計算しなければならない。そうでない場合、ECDSAの安全性は保持されず、偽造が可能になる。

具体的にどういう不正ができるかとというと、以下のようにして(r, s)を計算できる。

  1. ランダムな値aとbを選択する。
  2. R = aG + bPとなるRを計算し、Rのx座標をrとする。
  3. メッセージのハッシュをH(m)を {r \cdot \frac{a}{b}}とする。
  4.  {s = \frac{r}{b}}とする。
  5. 上記(r, s)を署名とする。

これを検証するととうなるかというと、

 {\frac{H(m)}{s}G + \frac{r}{s}P =  \frac{r \cdot \frac{a}{b}}{s}G + \frac{r}{s}P = r \cdot \frac{a}{b} \cdot \frac{b}{r}G + r \cdot \frac{b}{r}P = aG + bP}

となり、R = aG + bPと等しくなり有効な署名として検証される。

このようなことで偽の署名を有効と認識しないためにも、検証者は必ずメッセージmからハッシュ値を計算し、その値を持って署名の検証をする必要がある。

今回の自称サトシが提供したのはあくまで、(r, s)とH(m)なので、これは上記のようにサトシの証明にはならない。また、ハッシュ値 {r \cdot \frac{a}{b}}となるようなプリイメージを見つけることができないかぎり、ECDSAの安全性自体を破るものでもない。

一応、しばらくしたら内容(プリイメージ)を明かすと発言しているので楽しみにしておきたい。

離散対数仮定が崩れた際にConfidential Transactionチェーンのコインを保護するSwitch Commitment

Stanford Blockchain Conference 2019のGrinのセッションで、Grinの構成要素として挙げられていたSwitch Commitmentについて↓

https://eprint.iacr.org/2017/237.pdf

Bitcoinなどの多くの暗号通貨では楕円曲線暗号を導入しており、楕円曲線暗号の安全性は離散対数仮定の下に成立している。これは離散対数問題を解くのに現時点で効率的な方法がなく、総当りの計算をする必要があり計算量的に困難であるというもの。

しかし将来的に量子コンピュータなどの登場により離散対数問題が効率的に解かれる時代が来るかもしれない。そうなった場合に既存の暗号通貨は鍵長の変更や、暗号アルゴリズムの変更を求められるようになる。これは通貨によってソフトフォーク/ハードフォークによって切り替えが行われるだろうが、切り替えのタイミングを決めて、それ以降では新しい暗号アルゴリズムを使用できるようにし、既存のUTXOを新しいアルゴリズムでロックする新しいUTXOに移す必要がある。移さずにずっと据え置かれるUTXOは、その離散対数を解いた者に資金を奪われる可能性が高い。

このようにBitcoinなどであれば新しい暗号アルゴリズムもしくはパラメータに移行することで対処が可能だ。問題がより深刻なのはConfidential Transactionを導入しているチェーンである。BlockstreamのElementsやLiquid、Mimblewimbleを実装したGrinやBEAMなどが対象だ。

Confidential Transaction

コインの量はBitcoinの場合はトランザクションのアウトプットに明示的に正数値で記録されるが、Confidential Transactionではコインの量を以下のような準同型コミットメントであるPedersen Commitmentで管理している。

commitment = rG + vH

GおよびHは楕円曲線上の生成点で、rはブラインディングファクターでvを隠すためのランダムな値、vがコインの値。ランダム値はコインの受信者が決める値で、このコミットメントにいくらのコインがあるのかはrとxの値を知らないと分からない。つまり取引の当事者以外、第三者はこのコミットメントにいくらのコインがあるのか知りようが無い。こうやってコインの量を秘匿するのがConfidential Commitmentだ。検証方法など詳細が知りたい場合は↓

techmedia-think.hatenablog.com

離散対数仮定が成立しなくなった場合にどうなる?

量子コンピューターの登場などにより離散対数問題を解くことができるようになるとPedersen Commitmentを使用しているConfidential TransactionはBitcoinなどよりも大きな問題を抱える。

Confidential Transactionのチェーンを破壊するには1つの離散対数の値が分かればいい。上記Pedersen CommitmentのHの離散対数だ。 H = xGとなるようなxの値を攻撃者に知られるとまずい。

例えば攻撃者が既にConfidential Transactionを使っているチェーン上で誰かからコインを貰っておく=自分がブラインディングファクターrを選択したCommitmentを入手する。

この状態でH = xGとなるxの値が分かると

r' = r + x(v - v')

を計算する。v'はv' > vとなる(コインを増やす)新しいコインの量である。この新しい(r', v')のペアを使うと

r'G + v'H = (r + x(v - v'))G + v' xG
          = rG + x(v - v')G + v' xG
          = rG + xvG
          = rG + vH
          = commitment

が成立し、コインの量を自由に制御可能になる。こうやって無からコインを生み出すことができる(r', v')のペアを計算できる。

Bitcoinの場合、離散対数の値が計算できるようになったとしても個人のコインが盗まれるだけで、コインを無から生み出すようなことはできない。また個人のコインが盗まれないよう暗号アルゴリズム・パラメータを変更することでこれに対処できる。Confidential Transactionの場合は、その性質上、上記のように無からコインを生み出すことができてしまい、チェーンに対する攻撃が可能になる。こういったリスクを回避するための仕組みがSwitch Commitmentだ。

Switch Commitment

上記のPedersen Commitmentは離散対数仮定に依存しているが、たとえ無制限の計算能力があったとしても性質を破ることが不可能であるコミットメントを追加し、検証処理をそのコミットメントに切り替えることでこの問題に対応する。Pedersen Commitmentに代わるコミットメント方式としてElGamal Commitmentを採用する。

ElGamal Commitment

ElGamal CommitmentはPedersen Commitmentとほとんど同じだが、Pedersen Commitmentの要素にもう1つ同じブラインディングファクター r と生成点Hを使って計算した点をコミットメントのデータとして持つ。

commitment = rG + vH, rH

rHのデータを追加することで、このコミットメントを開くには、rGとrHのrが同じなければならない。このようなrのルールがある場合、いくら計算量があってHの離散対数がわかったとしてもvを変更することはできない。このようなElGamal Commitmentの特性により、コインを無から生成するような攻撃を回避することができるようになる。

またElGamal Commitmentが都合が良いのは、rHの部分を無視すると、今まで通りのPedersen Commitmentとして扱うことができるという点だ。

Confidential Transactoinではvの値がオーバーフローしない値の範囲内であることを保証するために別途、範囲証明をする必要があるが、現在CT用に設計されている範囲証明はいずれもPedersen Commitmentには最適化されているが、ElGamal Commitmentの範囲証明はそのような最適化はされておらず効率が悪い。

そのためコミットメントのデータ自体はElGamal Commitmentとして作成するが、検証の方法を2つ用意する。

  • 部分検証 = Pedersen Commitmentによる検証
  • 完全検証 = ElGamal Commitmentによる検証

離散対数仮定が崩れるようなおそれがあるまでは、今まで通り部分検証によりPedersen Commitmentを検証する。その後実際に脅威が訪れた際に完全検証に切り替えるソフトフォークを行う。そうすることで、チェーン上で無制限にコインが発行されチェーン自体を攻撃するといったリスクは回避することができるようになる。これがSwitch Commitmentだ。

※ ただ、注意が必要なのは、これはConfidential Transactionを構成するチェーンにおいて、無からコインを生成するようなことをできなくするための対応方法であって、離散対数問題が解かれた際にコミットメント内のコインの量のプライバシーを引き続き提供するものではない。つまり離散対数問題が解けているということは、そのコミットメントのコインの量が計算可能であるということだ。そのような状況になった場合は、秘匿系の仕組みは別途新しく考える必要があるだろう。

Grinの実装

mainnetがリリースされる前のバージョンのGrinでは上記方法でElGamal Commitmentが実装されており、トランザクションのアウトプットにrHハッシュ値(switch commit hash:32バイト)が追加されていた。

その後、上記のElGamal Commitmentでアウトプット毎に追加の32バイトのデータスペースを消費することなく同様のことが可能なアイディアをTim Ruffingが提案され以下のように変更されたみたい。

通常のPedersen Commitmentではブラインディングファクターであるrの値はランダムに選択されるが、r自体はランダムにせtず、別のランダムな値r'を使ってPedersen Commitmentを作る。

commitment = rG + vH

r = r' + hash(vH + r'G, r'J)

JはHに次ぐ3つめの生成点。ハッシュ関数に渡すデータの部分がElGamal Commitmentになっていることが分かる。

検証の仕組みについてはまだよく見てないけど、基本的には初期はPedersen Commitmentで検証し、その後脅威が訪れた際にrの導出元となっているElGamal Commitmentを検証するように変更するといったアプローチか? この辺はまたElGamal Commitmentの範囲証明のやり方含めて調べてみたい。

コインの所有を証明するProof of Reserveの標準化

少し前に、取引所に自分が預けているコインが本当に存在するか一斉に引出して確認してみようとするProof of Keysというイベントがあって、どこぞの取引所が事前に引き出し制限始めたというニュースもあったけど、ユーザーにとっては預けている資産がちゃんと存在することを検証できるのは重要なこと。

進んでそういった証明を開示してくれる取引所があれば素晴らしく、そういったアプローチをする取引所もあるが、証明方法については明確な標準はない。そこで最近Blockstreamがその標準化の提案をしている↓

blockstream.com

もともとBlockstreamが提供するサイドチェーンLiquid上での監査のために着手したものみたい。BIPに提案中の仕様案が↓

https://github.com/bitcoin/bips/blob/d02588d57675d1c7782077179ce6346a1677b60a/bip-proof-of-reserves.mediawiki

プルーフのフォーマットの定義とそのコミットメントと保有するUTXOで構成されたBitcoinトランザクションとしてエンコードする仕様(BIP 174のPSBTの拡張を含む)を定義したシンプルなBIP。

このProof of Reserveの仕組みにより取引所などのカストディが保持する金額を把握できる仕組み標準化しようということだが、これだけだと自分のコインがちゃんと存在するかという証明には不十分である。証明しているのは総量だけなので、確実に取引所が預かっている顧客資産に対し十分な支払い能力があるか証明するためには、

  • 資産の証明(今回のProof of Reserve)
  • 負債の証明(顧客が取引所内で保有するBitcoin残高)
  • 支払能力の証明 = 資産−負債の証明

が必要になる。この事は実際BIPの記述でも触れられているが、最後の支払能力の証明までやろうとすると、↓のProof of Solvencyまで必要になる。

techmedia-think.hatenablog.com

今回は1つめの資産の証明をまずは、なるべく既存のウォレットと互換性のある形で標準化しようというアプローチになる。

以下BIP案を和訳したもの↓

概要

このBIPは、proof-of-reserveトランザクションを構築するための簡単な方法を説明する。この提案は、そのような証明を構築し、既存のウォレットインフラを使ってそれらの構築を容易にし、一般的な証明検証ソフトウェアを可能にするための標準フォーマットを形式化する。このフォーマットは、通常のBitcoinトランザクションのシリアライゼーション/検証およびBIP 174 PBSTフォーマットなどの既存の規格に依存する。この提案には、ユーザーエクスペリエンスを向上するためのPSBTの拡張機能の説明も含まれている。

動機

Bitcoinの歴史の初期の頃から、ユーザーのためにBitcoinを管理する会社があった。これらのユーザーは特定のサービスと引き換えにコインの管理を放棄する。必然的にそのような企業がユーザーのBitcoinを失うことがあり、そのような事が起きても事件が公に公開されることはなかった。Proof of Reserveは大量の資金を管理している企業が一定額の資金に対する所有権を証明するための方法だ。定期的な所有権の証明は、重大な損失が発生していないことを確認するのに役立つ。

Proof-of-Reserveという用語は決して新しいものではないが、この手順は多くの資金を持つカストディアン企業であまり一般化されていない。その理由の1つは、proof-of-reserveを実行しようとするすべての企業は、それぞれ独自の方法で構築する必要があること。従って、そのユーザーはその証明を検証するために証明の構造を理解しなければならない。これは管理者にとってもユーザーにとっても参入障壁を高めることになる。

このBIPでしないこと

このドキュメントで説明されているProof-of-Reserveの構造には、主にそのプライバシー特性について、いくつかの既知の欠点がある。より優れたプライバシー特性を持つ改良されたProof-of-Reserveの仕組みに関する研究があるが*1、このBIPは意図的に事実上の既存の方法を形式化するだけだ。

仕様

我々の仕様は以下の2つのパートで構成される:

  1. 実際の証明のフォーマット
  2. 証明と関連メタデータのセットをパッケージ化するために使用されるファイルフォーマット

最終的な構成は以下の特性を持つべきである:

  • 複雑なウォレットインフラをサポートするための柔軟なプルーフ構造
  • 既存のウォレットソリューション(ハードウェア、ソフトウェア両方)との簡単な統合
  • プルーフの発行元に関係なく、標準手順による検証のサポート
  • プルーフは、メッセージに対してコミットすることで他の当事者によるプルーフの再利用を防ぐ
  • 発行者が特定のブロックにおいてあるコインが自分の管理下にあることの検証を許可する(その後のブロックでどうなるかに関わらず)

プルーフフォーマット

既存のシステムと最大限の互換性を担保するため、プルーフは通常のBitcoinトランザクションとしてフォーマットされる。ただし以下の2つの機能を持つ1つの小さな適応をトランザクションに対して行う。

  1. 資金を危険にさらさないようトランザクションを使用不可能なものにする。
  2. 他のカストディによるプルーフのコピーを防ぐために、プルーフプルーフの発行者とリンクする。

結果として得られる構造は、以下の特徴を持つBitcoinトランザクションとなる。

  • 最初のインプット(コミットメントインプット)
    • 前のOutPointのtxidの部分には、"Proof-of-Reserves:"というプレフィックスが付いたコミットメントメッセージのSHA-256ハッシュ*2をセットし、indexは0とする。
  • 残りのインプット
    • コミットメントインプットにコミットする署名(例えばSIGHASH_ALLを使った)を持たなければならない。
  • トランザクションは、コミットメントインプットのコインの量を0と仮定して、すべてのインプットのコインの量の正確な合計を持つ単一のアウトプットを持たなければならない。これはトランザクションがマイニング手数料を持たないことを意味する。

最初のインプット(単なるコミットメントハッシュ)の存在は、このトランザクションが無効であり決して承認されるものではないことを保証する。

プルーフファイルフォーマット

理論的には、仕様の最初の部分は実用最小限の標準として十分である。しかし、追加のメタデータレイヤーを使って標準を拡張するする動機は多数ある。

  1. 複数のプルーフの構築と結合
    何千ものUTXOを異なるオフライン、オンラインのウォレットに分散させると、その全てのUTXOを使って単一のトランザクションプルーフを作成するのは困難な可能性がある。同一のコミットメントメッセージとブロック番号を持つ複数のプルーフトランザクションを許容することで、複雑なウォレットインフラを持つカストディにとって、結合されたプルーフの安全性を低下させることなく、さらなる柔軟性が得られる。
  2. 検証用のメタデータ
    検証に使われる全てのシステムが全てのトランザクションの完全なインデックスにアクセスできるわけではない。ただし、プルーフに使われているUTXOが既に未使用でなくなった後でも、プルーフは簡単に検証できるはずである。プルーフに存在するメタデータは、トランザクションインデックスが使えない場合でも、プルーフの比較的効率的な検証を可能にする。
  3. 将来の改善の可能性
    拡張可能なメタデータフォーマットは、将来の標準の修正を可能にする。1つの潜在的な改善はUTXOセットコミットメントを持つことだ。これらは、プルーフ構成のブロックでUTXOセット内の全ての使用されたUTXOのproof-of-inclusionをproof-of-reserveが付随することを可能にする(検証をさらに効率的にする)。

提案するproof-fileのフォーマットは、複数のプルーフと関連するメタデータを結合するための簡単な方法を提供する。フォーマットの仕様はProtocol Bufferフォーマット*3である。

syntax = "proto3";
import "google/protobuf/any.proto";

message OutputMeta {
    // OutPointの識別子
    bytes txid = 1;
    uint32 vout = 2;

    // このアウトプットが作成されたブロックのブロックハッシュ
    bytes block_hash = 3;
}

message FinalProof {
    // プルーフトランザクション。 通常のBitcoinトランザクションのようにパース可能。
    bytes proof_tx = 1;

    // プルーフトランザクションで使用されるアウトプットのメタデータ。
    repeated OutputMeta output_metadata = 2;
}

message ProofOfReserves {
    // 追加フィールドを拡張できるよう、このフォーマットのバージョン番号
    uint32 version = 1;

    // プルーフが有効なネットワークのネットワークマジック。
    // mainnetは0xD9B4BEF9, testnetは0x0709110B
    //TODO BIP44のcoin type idを代わりに検討
    // https://github.com/satoshilabs/slips/blob/master/slip-0044.md
    uint32 network_magic = 2;

    // このproof-of-reservesのコミットメントメッセージ。
    // このメッセージは全てのプルーフのためのグローバルなもの。
    string message = 3;

    // このプルーフが検証されるブロック。
    // 検証では、このブロック高でアウトプットが未使用であることを考慮する必要がある。
    bytes block_hash = 4;

    // アウトプットメタデータを含む最終プルーフトランザクションのセット。
    repeated FinalProof final_proofs = 5;

    // proof-constructionツールで使われる可能性のある予約フィールド。
    // 検証では無視される。
    repeated google.protobuf.Any pending_proofs = 6;
}

最後のフィールドpending_proofsは proof-constructionツールで使われるスペースを同じファイル内にいくつか確保する。これによりファイルフォーマットを切り替えることなく、さまざまなプルーフを段階的に構築できる。

PSBT(BIP 174)の拡張

プルーフフォーマットのセクションで詳述されているコミットメントインプットは既存のUTXOを使用するわけではないので、署名されるべきではない(scriptSigとwitnessは空)。このタイプのトランザクションに署名する際、いくつか問題を引き起こす可能性がある。例えば、ハードウェアウォレットは、よく署名しようとしているトランザクションの全インプットに関する情報(前のアウトプットや前のトランザクションなど)を提供するよう署名者に求める。しかし、このデータは明らかにコミットメントインプットには存在しない。

ほとんどの既存デバイスでは、ダミーデータを提供するか、この特定のインプットを無視するようデバイスに指示することで、こららの要件を回避することができる。それでもUXの問題が残る。ハードウェアウォレットデバイスは、そのトランザクションをproof-of-reserveトランザクションとして認識しないため、UTXOの全てのお金を使用する通常のトランザクションに署名していると捉えられる。ほとdんどのデイバスは「XXX BTCをアドレス[...]に送信してよろしいですか?」というメッセージで確認を求めるが、これは最高のUXではない。

BIP 174 PSBTフォーマットに定義を追加することで、署名デバイスがProof-of-Reserveを認識することができる。以下のフィールドがBIP 174のINPUT Mapに追加される。

  • タイプ:Proof-of-Reserve コミットメントPSBT_IN_POR_COMMITMENT = 0x09
    • キー:なし。1バイトのタイプのみ。
      • {0x09}
    • 値:Proof-of-ReserveのUTF-8エンコードされたコミットメントメッセージの文字列
      • {porCommitment}

このフィールドがセットされているインプットを処理するウォレットは、

  • 上述したように、OutPointにプレフィックス付きコミットメントメッセージの文字列のSHA-256ハッシュがセットされていることを確認しなければならない。
  • インプットの値(コインの量)は0と仮定しなければならない(前のアウトプットのトランザクションを提供する必要はない)。
  • 任意のインプットに署名する前に、確認のためコミットメントメッセージをユーザーに表示し確認を求めるべきである。
  • このインプットにコミットするSIGHASHが使われている署名のみを提供するべきである。
  • このインプットについては、(scriptPubkeyがOP_TRUEであるかのように)空のscriptSigを受け入れる必要がある。

実装

PSBT拡張のproof of conceptの実装がrust-bitcoinプロジェクトのpsbt-porブランチにある。

https://github.com/stevenroose/rust-bitcoin/tree/psbt-por

上記フォーマットのプルーフを生成、検証するツールの進行中の実装が以下にある。

https://github.com/ElementsProject/reserves

*1: Dagher, Gaby G., Benedikt Bünz, Joseph Bonneau, Jeremy Clark, and Dan Boneh. "Provisions: Privacy-preserving proofs of solvency for Bitcoin exchanges." (2015)

*2:メッセージが"Some Message"の場合、txidの部分はUTF-8エンコードされた文字列のSHA-256("Proof-of-Reserves: Some Message")となる。

*3:https://github.com/protocolbuffers/protobuf/

How Much Privacy is Enough? at Scaling Bitcoin 2018

2019年になったけど、Scaling Bitcoin 2018 復習シリーズ。今回は、Zcashのファウンダーの1人でもあるCornell TechのIan Miersによる「How Much Privacy is Enough?」↓(1時間あたりから)

youtu.be

書き起こしは↓

http://diyhpl.us/wiki/transcripts/scalingbitcoin/tokyo-2018/how-much-privacy-is-enough/

内容は、プライバシーとスケーラビリティのトレードオフを評価しながら、どれだけのプライバシーがあれば十分かについての発表。新しい技術提案というわけではないけど、今まではどちらかというとブロックチェーンの分析を行う会社による、ブロックチェーンのデータ分析によるプライバシー漏洩のリスクをふわっと考えることはあったけど、実際の脅威とは何か?その脅威を現実するエンティティは何か、さまざまなプライバシーに関する提案がある中で、デコイベースのプライバシー効果は?などが、まとめられていて個人的に暗号通貨に関するプライバシーの課題を捉え直すことができる内容でよかった。

プライバシー技術

Bitcoinが登場したばかりの頃は、送金の匿名性が注目されていたが、最近ではBitcoinで提供されるのはあくまで疑似匿名性のレベルであり、完全なプライバシーを提供するものではないということが認知されてるようになってきている。実際にブロックチェーンを監視しトランザクションの分析を行う企業も存在する。一方、暗号通貨のプライバシーを向上させるため様々な提案も活発にされている。アドレスの再利用の禁止といったものから、

  • coinjoin
  • mixcoin
  • coinswap
  • coinjoinxt
  • joinmarket
  • Tumblebit
  • Zerocash
  • Bolt
  • Confidental Transaction
  • Ring Signature

などの複雑な暗号プロトコルまで、多数の提案がある。これらの技術を実際に自分で使用する場合、使用する前にそれがどう動作し、それによってどの程度のプライバシーを得るのか正確に評価する必要がある。エンジニアはパフォーマンスベンチマークの実行方法や概算の方法を知っているが、どの程度のプライバシーを確保するか計測し判断するのは難しい。

プライバシーの評価

ではどうやってプライバシーを評価するかという点だが、これにも課題がある。暗号通貨が利用可能であるといっても現状の使用状況を考慮すると、それはcookiesやターゲット広告、監視などより前の唯一のウェブサイトがCERNであった1992年のプライバシーを評価しようとしているようなものだ。

  • 経験的な側面からは計測できない
    • ブロックチェーン上のほとんどのトランザクションは投機的なものであるため
    • 日常生活で暗号通貨を利用するほどの環境はなく、そういった意味で制限が多い
    • 研究者にはデータやコスト、倫理的な限界がある。

そのため、各プライバシー技術がどれほどのプライバシーを提供するかについて、経験的に見積もることはできず、思考実験で検討するしかない。そしてそのためには現実的な脅威を理解しなければならない。

実社会におけるプライバシーの脅威

じゃあ、現実的な脅威とは何だろうか?共通の脅威としてブロックチェーンの取引内容を見ている政府や法の執行機関が挙げられるが、それは確かに1つの脅威かもしれないが唯一の脅威でもなければ最も現実的な脅威でもない。

例えば、GoogleではVISAとMastercardから決済データを収集し、それを使ってターゲットを絞った広告を行うことでユーザーのプロファイルを作り上げることができる。同様に、企業は顧客の行動に関する豊富なプロファイルを構築したいと考えている。有名な例が↓ techland.time.com アメリカのディスカウント百貨店チェーンのTargetが、ミネソタ在住の女子高生が妊娠していることを彼女の父親より早く知って起きた事件。Targetでは顧客1人1人にポイントカードを配布し、購入内容をチェックすることができるようになっている。Targetは彼女の購買データから彼女が妊娠していると判断し、ベビーグッズのクーポンを配信した。彼女の父親は当初娘に関係の無いベビーグッズのクーポンが続くため店に抗議したが、その後妊娠の事実を知り謝罪する。

このように人々が何を買うのか、購入と習慣が何なのかというデータから起こる深刻なプライバシー問題がある。↑はブロックチェーンから取得するよりももっと細かい情報をベースにしているが、ブロックチェーンの取引履歴にも同様のことが言える。

もう1つの例は、Venmoだ。Venmoは個人間送金が可能なアプリで、友人同士でバーやレストランで支払いを割り勘できたりもする。Venmoを使用するとすべての取引について、利用者の名前、受取人の名前、金額、メモ欄がデフォルトで公開されるようになっている。これらはブロックチェーンから得られるものに近いが、Venmoの場合そういったデータを匿名化するような事はせず単純に提供しているだけで、大きなプライバシーリスクがある。

そして通常の決済と違い、暗号通貨ならではの問題としてFungibilityが挙げられる。Fiatと異なりBitcoinのような暗号通貨は、その通貨がどのように流通してきたかブロックチェーンの取引履歴を遡ることで確認することができる。そういった側面があるため、

  • マイニングされたばかりのコイン(これまでの取引履歴がなく汚染されていないことが確実なため)がプレミアで売られている。
  • 取引所は取引履歴をベースに顧客をブロックすることが可能。
  • 取引所は単なる第三者オブザーバーではない。

これはGMailGoogle MapやAndroidを使いながら、Googleからプライバシーを保護しようとするのに似ている。

暗号通貨のプライバシーのための防御とは何か?

↑のような脅威から自身を守るために、暗号通貨において必要な防御とは何だろうか?自身が何も知らなかったから問題はない、どんな使われ方ををしていようが自分はそれについて知らなかった、だから自分は関係ないというのは防御にはならない。法の執行機関はそのようなことは気にしない。そのため我々は何をする必要があるか?

Bitcoinのプライバシーを侵害しようとするエンティティは?

通常、ブロックチェーン上のプライバシーの脅威というと、サードパーティブロックチェーンの観察者などをイメージするが、そういった脅威だけではなく、現実には以下のような積極的な攻撃を行うエンティティ

  • ターゲットとなるユーザーから支払いを受け取るエンティティ
  • ターゲットとなるユーザーへ支払いを行うエンティティ
  • 三者とのやりとりが可能なエンティティ

や以下のような明確な攻撃者が考えられる。

  • 自身の顧客を追跡しようとするマーチャント
  • 受信者のリアルな身元を特定しようとするユーザー
  • 特定の取引行動をした顧客をBANする取引所

プライバシーのアプローチ

暗号通貨のプライバシーを改善するための技術は↑のように数多く広い範囲に渡って提案されているが、それらをすべて個別に調べたくはない。これらの提案は3つの種類のシステムという観点で分類できる。

  • Bitcoin:支払いのソースを明示的に識別している
  • デコイトランザクションをベースにしたシステム:
    • CoinjoinやMimblewimbleなど(現在のトランザクションからデコイを選択するタイプ)
      複数人のユーザーの送金を1トランザクションで行うミキシングベースのアプローチで、インプットのどのコインがどのアウトプットに流れたのかを難読化する。
    • Cryptonote/RingCT(Moneroなど)(全履歴からデコイを選択するタイプ)
      未使用/使用済み関係なく、ブロックチェーンからTXOをサンプリングし、本当に使用するUTXOと混ぜてどれが使用するコインか分からないようコインのソースを難読化する。
  • ZerocinやZerocashなど
    支払いのソースを識別することができないプライベートトランザクション。強力なアプローチで、コインの送信元、送金先、送金量が秘匿され、周りのノードはそれが正しいことを一緒に付与されたゼロ知識証明を使って検証する。

Bitcoinの支払いの場合

Bitcoinでマーチャントに支払いをする場合、支払いに使用するコインがどこから来たものなのかソース明確に特定する必要がある=インプットでUTXOを指定する。これが基本的にプライバシーを持たない理由。

デコイベース支払いの場合

デコイベースのシステムで支払いをする場合、この場合も同様に支払いに使用するコインがどこから来たものなのかソース明確に示す必要があるが、それとは別にデコイ用のソースを混ぜ、デコイ入りの複数のソースとして指定することで、本物のソースを隠す。トランザクションを見てもどれが本物のソースか誰も分からない。

Zerocashの支払いの場合

最後にZerocashで支払いをする場合、コインのソースを識別する情報は何もない。

デコイシステムはプライベートか?

Bitcoinのプライバシーの制限についてはよく研究されている。Zerocashのプライバシーの制限は、学術文献と実際に研究がされている。しかしデコイベースのシステムは実際どうだろうか?

f:id:techmedia-think:20190121164230p:plain

↑のTaint treeは、支払いに使われた資金について、その資金およびデコイの源(ソース)となる可能性を追っていってできる歴史のツリーだ。

そしてコインをマーチャントに支払った場合、買い手はそのコインがどこにいくのか見ることが可能だ↓

f:id:techmedia-think:20190121173358p:plain

ただ、コインはマーチャントとは別のユーザーによりデコイの支払いとして使われる可能性もあり、その場合コインがどこにいったのかは分からない。つまりコインの送信先の可能性のみが分かるというだけだ。

顧客の識別

この状態でどういったことができるだろうか?

できることの1つは、あなたがマーチャントか共謀するマーチャントグループだった場合、繰り返しの支払いにより顧客を追跡することができる。私が毎日Target(小売店)に行き、現金で買い物をする分には誰も私を追跡できないだろう。じゃあ暗号通貨で支払いをするとどうだろうか?理想的には、例えば3つ商品を別々に購入した場合、3つの購入は別々のものでリンクされるべきではない。単純に考えるとこれらが結びつくようなことは無いように思える。しかし、私が何かを購入し、代金として$20を支払い、お釣りを$5受け取る。私は3つの各支払でこれと同じことをする。すると遅かれ早かれ受け取ったお釣りを使わなくてはならなくなる。その場合、そのデコイを含むトランザクションのインプットの1つはマーチャントから前回購入した際のお釣りになる。基本的にデコイは今までのトランザクションの中から一様にランダムに選択しているため、このような状況でそれがデコイとして選ばれる可能性は低い。

また別の観点として、3つの支払いで使われたコイン(デコイを含む)についてTaint treeを構成し、それぞれ3つの支払いのコインが同じ祖先を指しているケースを考えてみよう↓

f:id:techmedia-think:20190121193121p:plain

暗号通貨で支払いをするために取引所で多額のコインを入手し、それが祖先となる支払いのリンクが形成される。デコイが含まれていても共通の祖先に遡ることができれば、同じ人物による支払いであることが特定できる情報をマーチャントに与えることになる。これは1つのマーチャントに限った話ではなく、複数のマーチャントが結託した顧客を追跡する可能性も考えられ、これも問題である。

匿名マーチャントの識別

もう1つ別の視点の攻撃について考える。あなたが民主主義の活動家で、匿名で寄附を受け付けるサイトを持っているとしよう。ただ、あなたが働いている国での生活が危険にさらされるため、自分の身元は明らかにしたくない。活動のために資金を得たいが、政府はあなたを特定したがっている。プライバシーが保護されたシステムでは、あなたがその寄付金を受け取り取引所に預けるのは安全なはずだ。例え取引所が政府によって管理されていても、彼らがあなたを特定する方法はない。あなたは安全なはずだが、これは事実ではない。

政府があなたを特定したい場合、政府いくつかの(Torでしかアクセスできないものを含む)Webサイトに載っているあなたのアドレスを知っているだろう。彼らにできるのは、3つの追跡用の支払いをすることだ。あなたはそれを受け取り取引所に預ける。すると、取引所の記録を入手した人物であれば誰でも(召喚状を入手したり、取引所にハックしたり)、預金されたコインのセットとTaint treeを見ることで、匿名の支払いを受けているこの民主主義活動家が誰なのかを調べることができる。

f:id:techmedia-think:20190122150406p:plain

3つの追跡用の支払いのペイントされたコインがデコイとして使われることも考えられる。デコイはそれぞれがランダムに選択するので、誰であろうと預金をする際にペイントされたコインをデコイとしてピックアップする可能性がある。しかしペイントされたコインの選択を3回も5回も100回もすることはないだろう。政府があなたの預金を調べてTaint treeに送った痕跡の支払いが全てにおいて存在するなら、それは圧倒的な確率で本人であることの証拠になる。その証拠を持ってあなたが民主主義活動家であることが判明してしまう。これについてはかなり問題がある。暗号通貨にはプライバシーがあると直観で思っている人が多いのに反し、実際にそれを使用する人が学ぶと驚くような方法でプライバシーの侵害が見つかるだろう。

そのため悪意ある送信者/受信者とのやりとりを繰り返すことは実際に危険だ。

ダスト攻撃:どこでお金が使われているかを確認する

さて↑でマーチャントに支払ったコインが送金される先が(正確には候補が)分かるとといった内容を覚えているだろうか? 支払いをするということは、同時に将来そのコインを含む可能性のあるトランザクションを知ることができ、これを悪用することもできる。例えば、友人がどこでお金を使っているのか調べるのに利用できる。小額の支払いを、マーチャントと友人にそれぞれする。そしてTaint treeとトランザクショングラフを監視する。するとある時点で面白いことが起こるかもしれない。

f:id:techmedia-think:20190122164220p:plain

この両方の資金を含む可能性のあるトランザクションが公開された場合、誰かがデコイとしてランダムに選択したものなのか、それとも友人とマーチャントに支払ったコインが実際一緒に使われたのか。そしてマーチャントがホットウォレットから資金をコールドウォレットに移したのか、それとも請求への支払いにあてたのか。もちろんデコイの可能性もあるが、こういうトランザクションが何度も観測される場合、あなたの友人はこのマーチャントで定期的な購入をしているという強い証拠になる。

デコイアプローチの制限

↑のようにデコイベースのアプローチには実際には限界がある。

  • 顧客の追跡が可能
  • 匿名マーチャントも特定される
  • 三者にお金の行き先が分かる

さまざまなプライバシー向上のための技術や暗号通貨について思う共通の認識は、Bitcoinはおそらくプライベートではない(チェーン的な意味ではなくて)、しかしデコイやZerocashのような仕組みにより意味のあるプライバシーが追加される。技術が何かが問題ではなく、これらの技術の間にはどれくらいプライベートであるかという点でトレードオフがある。そしてそのトレードオフが何を意味するのかについてこそ理解する必要がある。

デコイアプローチを使う場合

何らかの理由でデコイスキームを使用する場合、5つの起源ではなく5000もしくは500万の起源の可能性があるような非常に大きな匿名セットを使える場合、実行可能であるかもしれない。

以下のようなケースであれば機能すると思われる

  • デコイのセットが非常に多い(5とかではなく500万のデコイなど)
  • デコイのセットは直近のすべてのトランザクションで実質的に重なっている
  • デコイは本当に慎重に選択されること

しかし、

  • どの程度のプライバシーが提供されているのかの厳密な分析
  • 物事がどこで失敗するかを注意深く理解する
  • 制限を認める

といった点に十分注意する必要がある。実際以前、Moneroがデコイをサンプリングした分布と、実際の人々がコインを使用する分布が一致しなかったことを示す一連の論文があった。そこにはギャップがあり、これは現在やや修正されているが、Moneroの旧バージョンでは、圧倒的な確率で最後のトランザクションが本物のトランザクションであった。

もしこのデコイベースのアプローチを取るなら、繰り返しになるがそれがどれくらいのプライバシーを提供するのかについての様々な分析を知る必要がある。

スケーラビリティ

制限を定めることはスケーラビリティに帰着する。デコイシステムを利用していて、本当に大きなデコイセットを得るにはスケーリングが必要になる。

対数スケーリング

デコイの数によってリニアにスケールするシステムは持てない。例えばbulletproofをサポートしたMoneroは、デコイを追加するのトランザクション内に1〜2 KB必要とする。もしデコイの数によりトランザクションサイズがリニアに増加するなら100や500、1000個のデコイを持つトランザクションはとても現実にはワークしない。リニアスケーリングのデコイシステムはワークしないので、必要なのはトランザクションサイズやトランザクションの生成、検証時間がデコイの数に対して対数になるようなシステムが必要となる。

Zcashスタイルのシステム

デコイベースではなくZcashライクなシステムを採用する手もある。Zcashでは、トランザクションアウトプットは(金額や受診者)へのコミットメントとなり、金額や宛先は誰にも分からず、それが確かに未使用なUTXOであること、またそれを所有していることの証明をゼロ知識証明で行う。こういったZcashスタイルのシステムを設計するのも1つの方法だ。

  • ゼロ知識証明技術のピックアップ
    スケーラビリティを向上させるためには、暗号が安全で仮定が保証され、セットアップ特性があらゆる運用要件に対応したゼロ知識証明技術をピックアップする必要がある。zk-SNARKだったりbulletproofだったりzk-STARKだったり。
  • zkが効率的であるマークルツリーの深さdを選択
    ゼロ知識証明技術を選択したら、ベンチマークを行い、効率的に動作するようパラメータを選定する。ZcashではUTXOセットはマークルツリーで管理されているが、マークルツリーが長くなれば深さも深くなり、デコイセットでトランザクションは大きくなり、生成や検証は遅くなる。そのためパフォーマンス要件を満たすマークルツリーの深さdを見つける。dが決まるとデコイのセットは2dで決まる。
  • デコイをサンプリングする際の安全性

スケーラビリティ vs プライバシー

暗号通貨にはプライバシーソリューションが必要である。オンチェーンソリューション?またはオフチェーンで解決した方がいいかもしれない。

ソリューションが上手く動作することを期待するが、

  • 何が起きているのか批判的に考え
  • 現実的な脅威モデルは何か?
  • 対処しなければならない問題は何か?

を究明する必要がある。

そして、プライバシーよりもスケーリングを優先させるが、制限についてきちんと理解すること。

  • 実際の脅威モデルは傍観者ではない。
  • プライバシーを追加してもプロトコルが完全にプライベートになるわけではない。
  • 攻撃というものは良くなるだけだ。

現在は、プライバシーソリューションがどう機能するのか黎明期にあり、プライバシーソリューションを構築し、攻撃する方法について多くの経験はまだない。インターネットのプライバシー問題がどれほど悪いか理解するのに20年かかったように、暗号通貨をベースとしたプライバシー問題の理解にも時間がかかるだろう。そして最後にプライバシー問題はプロトコルへの小さな微調整で魔法のようになくすことはできない。