Greetings! New to Zcash?
The Zcash network is young, but evolving quickly! Sign up and we'll be in touch with monthly highlights on ecosystem growth, network development and how to get started with Zcash!

言語

保護されたアドレス間での取引方法について

Ariel Gabizon | Nov 29, 2016

'Zcashトランザクションの基本' において、Zcashトランザクションの一般的な概要をお見せしました。 この記事の目的は、Zcashにおいて*プライバシーが保護された*トランザクションがどのように作用しているのか、どこにゼロ知識証明が姿を表すのかについて単純な説明を行うことにあります。 この投稿の用語においては、ここでは特に保護されたアドレス(一般にz-addrsと呼ばれるもの)間のトランザクションについて焦点を当てています。

プライバシー保護の要素の理解に焦点を当てるため、プルーフ・オブ・ワークとブロックチェーンを使った合意到達に関するものをすべて一度脇に置いて、使われていないトランザクションのアウトプットの正確なリストを入手した特定のノードに集中してみてみましょう。

最初に、このリストがビットコイン・ブロックチェーンにおいてどのように見えるか思い出してください。 使用していないトランザクションのアウトプット(UTXO)は、それぞれ、所有者のアドレス/公開鍵とそれが含むBTCの量によって説明された、使用されていない'ノート'とみなされます。 わかりやすく、それぞれのノートはちょうど 1 BTC保有していると推定しましょう。 アドレスごとに、多くても1つのノートが存在します。つまり、ある時点において、ノードのデータベースには未使用ノートのリストで構成されることになります。各ノートは、単純に所有者のアドレスによって説明されることになります。 例えば、データベースは次のようになります。

\(\mathsf{Note}_1=\) \((\mathsf{PK}_1)\), \(\mathsf{Note}_2=\) \((\mathsf{PK}_2)\), \(\mathsf{Note}_3=\) \((\mathsf{PK}_3)\)

\(\mathsf{PK}_1\) がAliceのアドレスで、AliceはBobのアドレス \(\mathsf{PK}_4\) に1 BTCノートを 送りたいと考えていると仮定します。 Aliceは、全てのノードに対して、要は" \(\mathsf{PK}_1\) から \(\mathsf{PK}_4\) に1 BTCを移動"という内容のメッセージを送ります。 Aliceは \(\mathsf{PK}_1\) に相当する秘密鍵 \(\mathsf{sk}_1\) で一緒にこのメッセージに署名し、 これによりノードがAliceには \(\mathsf{PK}_1\) からコインを動かす権利があることを確認します。 ノードが署名をチェックし、アドレス \(\mathsf{PK}_1\) には本当に1 BTCのノートがあることを確認したら、 それに従いデータベースがアップデートされます。

\(\mathsf{Note}_4=\) \((\mathsf{PK}_4)\), \(\mathsf{Note}_2=\) \((\mathsf{PK}_2)\), \(\mathsf{Note}_3=\) \((\mathsf{PK}_3)\)

各ノートが、無作為な 'シリアルナンバー'(または固有のID)|r| を含んでいると仮定しましょう。 すぐに、これがプライバシーの入手に役立つことがわかります。 従って、データベースは以下のようになります。

\(\mathsf{Note}_1=\) \((\) \(\mathsf{PK}_1\) \(,\) \(r_1)\), \(\mathsf{Note}_2=\) \((\) \(\mathsf{PK}_2\) \(,\) \(r_2)\), \(\mathsf{Note}_3=\) \((\) \(\mathsf{PK}_3\) \(,\) \(r_3)\)

プライバシーへの自然な第一歩は、ノートそのものではなく、ノートの"暗号化"、または単純なハッシュを保存したノードを持つことです。

\(\mathsf{H}_1=\) \(\mathbf{HASH}(\mathsf{Note}_1)\), \(\mathsf{H}_2=\) \(\mathbf{HASH}(\mathsf{Note}_2)\), \(\mathsf{H}_3=\) \(\mathbf{HASH}(\mathsf{Note}_3)\)

プライバシー保護の第二ステップとしては、使用された後であっても ノードが引き続きノートのハッシュを保管し続けることです。 これによって、未使用のノートのデータベースではなく、むしろ これまでに存在したすべてのノート のデータベースとなるのです。

現在の主な疑問点は、プライバシーを破壊せずに、使用されたノートとそうでないものの間をどのように区別するかという点です。 ここに nullセット が絡んできます。 これは、使用されたノートの全てのシリアルナンバーのハッシュ値のリストです。 各ノードがハッシュ値を持つノートと共に、nullセットを保管します。 例えば、 \(\mathsf{Note}_2\) が使用された後、ノードのデータベースは以下のようになります。

Hashed notes Nullifier set
\(\mathsf{H}_1=\) \(\mathbf{HASH}(\mathsf{Note}_1)\) \(\mathsf{nf}_1=\) \(\mathbf{HASH}(\mathsf{r}_2)\)
\(\mathsf{H}_2=\) \(\mathbf{HASH}(\mathsf{Note}_2)\)  
\(\mathsf{H}_3=\) \(\mathbf{HASH}(\mathsf{Note}_3)\)  

トランザクションが行われるしくみ

ここで、Aliceが \(\mathsf{Note}_1\) を所有しており、これをBobに送りたいと考えているとします。ボブの公開鍵は \(\mathsf{PK}_4\) です。Zcashでは実際には必要とはしませんが、単純化するために、AliceとBobは相互間のプライベートチャネルを持っていると仮定しましょう。基本的に、Aliceはそのnullを公開することで自分のノートを無効化でき、同時にBobによってコントロールされる新しいノートを作ることができます。

より正確には、彼女は以下を行うことになります。

  1. 彼女は無作為に新規のシリアルナンバー \(r_4\) を選び、新規のノート \(\mathsf{Note}_4=\)\((\) \(\mathsf{PK}_4\) \(,\) \(r_4)\) と定義しました。
  2. 彼女は \(\mathsf{Note}_4\) をボブにプライベートに送信しました。
  3. 彼女はnull化した \(\mathsf{Note}_1\)\(\mathsf{nf}_2=\) \(\mathbf{HASH}(\mathsf{r}_1)\) を全てのノードに送りました。
  4. 彼女は新規のノートに対するハッシュ値 \(\mathsf{H}_4=\) \(\mathbf{HASH}(\mathsf{Note}_4)\) を全てのノードに送りました。

ノードが \(\mathsf{nf}_2\)\(\mathsf{H}_4\) を受信したら、\(\mathsf{nf}_2\) に相当するノートが既に使用されて いるかは、nullセットにおいて \(\mathsf{nf}_2\) が存在するかどうかを確認するだけで チェックすることができます。 存在していなければ、ノードを \(\mathsf{nf}_2\) をnullセットに加え、\(\mathsf{H}_4\) をハッシュ値のついたノートに加えることで、AliceとBobのトランザクションが妥当化されます。

Hashed notes Nullifier set
\(\mathsf{H}_1=\) \(\mathbf{HASH}(\mathsf{Note}_1)\) \(\mathsf{nf}_1=\) \(\mathbf{HASH}(\mathsf{r}_2)\)
\(\mathsf{H}_2=\) \(\mathbf{HASH}(\mathsf{Note}_2)\) \(\mathsf{nf}_2=\) \(\mathbf{HASH}(\mathsf{r}_1)\)
\(\mathsf{H}_3=\) \(\mathbf{HASH}(\mathsf{Note}_3)\)  
\(\mathsf{H}_4=\) \(\mathbf{HASH}(\mathsf{Note}_4)\)  

..でもちょっと待ってください。\(\mathsf{Note}_1\) は使用されていないとすでに確認したはずです.. しかし、それがAliceに帰属していたかについては確認していませんでした。実際、私たちは、それが '本物の' ノートかどうかもチェックしていません。本物とは、そのハッシュ値がハッシュ値がついたノートのノードテーブルに存在するか、という意味です。 これを修正する単純な方法は、Aliceがハッシュ値でなく、単純に \(\mathsf{Note}_1\) を公開することです。 しかしもちろん、これは私たちが実現させようとしているプライバシーを侵害することになります。

ここで、 ゼロ知識証明 がヘルプに入ります。

上記に挙げたステップに加え、 Aliceはプルーフ・ストリング \(\pi\) を発行します。これは、ノードに対して このトランザクションを発行した者は誰であろうと \(\mathsf{PK}_1\)\(\mathsf{sk}_1\) そして \(r_1\) などの値を知っている ことを証明するものになります。

  1. ノート|note1=| (\(\mathsf{PK}_1\) \(r_1)\) でのハッシュ値は、ハッシュ値のついたノートのセットの中に存在します。
  2. \(\mathsf{sk}_1\)\(\mathsf{PK}_1\) に相当する秘密鍵です(よって、これを知る者は誰でも、\(\mathsf{Note}_1\) の正当な所有者となります)。
  3. \(r_1\) のハッシュ値は \(\mathsf{nf}_2\) です(つまり、もし \(\mathsf{Note}_1\) のnullとわかっている \(\mathsf{nf}_2\) が現在nullのセットになかった場合、\(\mathsf{Note}_1\) はまだ使われていないことになります)。

ゼロ知識証明のプロパティにより、\(\mathsf{PK}_1\)\(\mathsf{sk}_1\)、または|r1|についての どんな情報も \(\pi\) によって開示されないことが保証されます。

割愛または詳細を省いた箇所

これは非常に単純化した解説であることを改めてご理解いただき、 完全な詳細については、 プロトコル仕様書 でご確認いただくことをおすすめします。

見逃してきた主要事項をいくつか挙げます。

  1. ハッシュ値のついたノートはリストとだけでなく、マークルツリーの中に保存される必要があります。これは、ゼロ知識証明に効果を生じさせるのに重要な役割を果たします。更に、単にハッシュ値だけでなく、ノートの 計算上隠れている、コミットメントを結んでいるもの も保存する必要があります。
  2. 送信者との関係における受信者の将来的なプライバシーを確実なものにするため、nullはもう少し複雑な方法で定義する必要があります。
  3. 送信者と受信者の間のプライベートなチャネルの必要性をどのようになくすかについては詳細にまで踏み込みませんでした。