
シリーズ: Zcashの第一原理から . 第3回: ハッシュとコミットメント 対象読者: 新規ユーザー。記事1(有限体)および記事2(楕円曲線)に依存しますが、直感は独自に成り立ちます。 得られる知識: ハッシュ関数の理解、"hiding"と"binding"の意味、そしてZcashがすべてのプライベートな支払いを固定するノートコミットメントの構築方法。
記事0では、「魔法の封筒」というものを紹介しました。これは、公開されたボードにピン留めして、中に何があるかは隠しながらも存在することを証明できるもので、後から交換することはできません。このような仕組みが可能であることを説明する予定でした。それがこの記事です。2つの要素が必要です:ハッシュ関数とコミットメント。
選挙の結果を予測し、後にその予測が事前にしていたことを証明したいと想像してください。ただ単に予測を発表することはできません(それは人々の行動を変えたり、変更したという非難を受けたりするからです)。また、完全に秘密にしておくこともできません(後で証明できないからです)。
あなたが望むのは、現在公開しておき、後に開示できるようにし、嘘をつくことができない方法です:
この「今ロックし、後で開示し、嘘をつけない」仕組みはコミットメントと呼ばれ、Zcashでは至る所に使われています。ノートの価値と所有者は、ノートが作成された瞬間にコミットメントに固定されます。コミットメントを構築するには、その主役であるハッシュ関数が必要です。
ハッシュ関数は、1文字でもある図書館全体でも、すべてのデータを取り込み、短い固定長の文字列(ダイジェストまたはハッシュ)に圧縮します。これはデータの指紋と考えてください。

良い暗号化された指紋には4つの特性があります。これらは式ではなく直感として理解してください:
| 性質 | 普通の意味 | なぜ重要か |
|---|---|---|
| 決定性 | 同じ入力は常に同じ指紋を生成する | いつでも指紋を再確認できる |
| 高速計算 | 指紋の計算が迅速である | どこにでも実用可能 |
| 一方向性(逆像耐性) | 指紋から元の入力を見つけることができない | 元データを隠す |
| 衝突耐性 | 異なる2つの入力で同じ指紋ができない | 複製や偽造が不可能 |
さらに、指紋に感じさせるもう一つの特性があります:
入力をわずかでも変更すると、指紋は完全に変わります。古いものとは一切関係ありません。1文字だけ異なるメッセージの2つのSHA-256指紋を見てください:
H("Pay Bob 5 ZEC") = 6e2dc1a954c70cc865f18ea8cb70b7b56eeaf6ca42b380824a55d65dc342f34b
H("Pay Bob 6 ZEC") = 76abc346d8d3053f76a9ae18b617af71f02729a73ec6a51732d2d94934e4217f
64の16進数のうち、59個が異なります。 1文字だけ変更しただけで、完全に異なる指紋が出力されます。これは、入力を目的の指紋に向けることができない理由です:「温かく・冷たく」のような信号がないからです。
ここでは魅力的だが破綻しているアイデアがあります:秘密値vにコミットするには、その指紋H(v)を公開すればよいのです。
これは**binding(束縛)**にうまく機能します(後で別のvを主張することはできません。それは衝突が必要だからです)。しかし、**hiding(隠蔽)**は失敗します。可能な値の集合が小さい場合、攻撃者は候補すべての指紋を計算し比較します。コミットメントとして「yes」または「no」を選択した場合は、両方をハッシュ化してすぐにどちらを選んだかわかります。直前に友好的だった決定性は今や秘密を漏らしています。
解決策は1つの単語です:ランダム性(randomness)。
コミットメントとは、あなたの値と新しいランダムな数の指紋です:
commitment = H(v, r)ここでrは秘密のランダムな「ブラインド」値です。
これにより、同じvでも毎回異なるrを使うことで、コミットメントが異なります。我々が望んでいた2つの性質がようやく両方とも成り立ちます:

後で**開示(reveal)**するには、vとrを公開します;誰もが再計算してH(v, r)をチェックし一致しているか確認します。あなたは束縛されます。これは記事0の魔法の封筒であり、現実に成り立っています。
永遠に持ち続けるべき2つの要点: binding(束縛)はハッシュが衝突耐性から来ます;hiding(隠蔽)はランダムなブラインドファクター
rから来ます。
一般的なレシピは2つあり、Zcashでは両方使われています。
| ハッシュベースのコミットメント | ペドレンスコミットメント(記事2より) | |
|---|---|---|
| レシピ | H(v, r) | v.G + r.H(曲線上の点) |
| 隠蔽元 | ランダムなr | ランダムなr |
| 束縛元 | 衝突耐性 | 楕円曲線トラップドア(ECDLP) |
| 特殊な力 | 簡単で高速 | コミットメントが加算可能(準同型) |
最後の行がペドレンスコミットメントがZcashにおいて重要である理由です。commit(v_1) + commit(v_2)はcommit(v_1 + v_2)と等価なので、プロトコルはすべての金額を公開することなく入金=出金を証明できます。この事実は記事6で詳しく説明します。
これは多くの紹介では見落とされる洞察であり、まさに「数学とエンジニアリングが交差する」ポイントです。
SHA-256は日常的なコンピューティングにおいて優れた指紋です。しかしZcashではただハッシュを計算するだけでなく、ゼロ知識証明内でハッシュが正しく計算されたことを証明しなければなりません(記事5で説明します)。そしてここに問題があります:ゼロ知識証明は有限体算術(記事1)の言語で動作し、SHA-256はビット操作(シフト、AND、XORなど)から構成されています。すべてのビット操作をフィールド算術で表現することは非常に高コストであり、証明が巨大で遅くなります。
そのためZcashの暗号学者たちは、内部がすでにフィールド算術であるハッシュ関数を設計し採用しました。これにより、証明が安価になります:

この単一のエンジニアリング上のプレッシャー、「証明は安くなければならない」というものから、ZcashはSHA-256ではなく特別なハッシュ関数を発明し採用したのです。
Zcashは設計ごとに異なるハッシュを使用しており、それぞれの用途に応じて選ばれています:
| 設計 | 使用されるハッシュ | どこで |
|---|---|---|
| Sprout(最も古い) | SHA-256 | ノートコミットメントとツリー |
| Sapling | ペドレンスハッシュ、および BLAKE2 | ペドレンスはノートコミットメントとマーチェルツリーに;BLAKE2は鍵導出とnullifierに |
| Orchard(現在) | Sinsemilla、および Poseidon | Sinsemillaはノートコミットメントとマーチェルツリーに;Poseidonはnullifierに、すべてが算術回路のために設計されています |
認識すべき名前はペドレンスとSinsemilla(曲線上の点から構築されたコミットメントスタイルのハッシュで、「加算可能」なスーパーパワーを引き継ぎ、証明が安価になる)およびPoseidon(ゼロ知識回路のために設計されたフィールド算術ハッシュ)。記事0でノートの内容がコミットメントに封入されていると述べたとき、この仕組みがその封印を行っています。
したがって、記事0からのオープンループ、「なぜ封筒は中身を隠しながらも偽造不可能なのか?」は今や閉じています:ランダムなブラインドファクターによる隠蔽、衝突耐性または曲線トラップドアによる束縛。
わかりやすさのために簡略化しました。実際のコミットメント方式ではvとrがどのようにエンコードされるか、どの生成子が使われるかを正確に指定します;「hiding(隠蔽)」と「binding(束縛)」はそれぞれ完璧なものと計算的なものがあり、厳密なセキュリティ定義があります;ペドレンス、Sinsemilla、Poseidonの内部構造も示していません。これらは直感を変えません:コミットメントとは指紋にランダム性を加えたもので、今隠蔽し、永遠に束縛します。詳細はプロトコル記事が必要なときに再び戻ってきます。
H(v)だけを公開すると束縛されるが隠蔽されません。ランダムなブラインドファクターrを加えたH(v, r)を使うと解決します:rによる隠蔽、衝突耐性による束縛。| 項目 | 普通の意味 |
|---|---|
| Hash function | 任意のデータを短い固定長の指紋(ダイジェスト)に圧縮します |
| Digest | ハッシュ関数の出力指紋 |
| Preimage resistance | 指紋から入力を逆算できない(一方向性) |
| Collision resistance | 同じ指紋を持つ2つの入力を見つけることができない |
| Avalanche effect | 入力のわずかな変更で指紋が完全に変わる |
| Commitment | 今ロックし、後から開示して嘘をつくことができない |
Blinding factor (r) | コミットメントを隠すために使われる新しいランダムな数 |
| ZK-friendly hash | フィールド算術で構築されたハッシュで、証明が安価になる |
なぜ値をコミットする代わりに暗号化しないのか? 暗号化は後から解読できる秘密についてです。コミットメントは束縛: 後で答えを変更できないという保証についてです。異なる目的です。
コミットメントが値を隠すなら、誰がルールをチェックするのか? それがゼロ知識証明(記事5)の役割です:隠された値がルールに従っていることを証明しますが、それを明らかにしません。
SHA-256は破損しているのか?Zcashがいくつかの場所で避けてるから? いいえ。SHA-256は問題なく、Zcashでも使われています。ただ回路内で証明するのが高コストであるため、ゼロ知識証明に特化したハッシュ関数が存在します。
ランダムなrはどこから来るのか?誰が保管しているのか?
ノートが作成されるときに新しく生成され、ノートの所有者だけが知っています。これは各ノートがユニークでプライベートになる理由です。
あなたの選挙予測をH(v, r)としてコミットし、それを公開します。友人が「ただH(v)を公開すればいい」と主張します。2つの可能な結果しかない場合、なぜそれが悪いアイデアなのか?(答えは下にあります。)
たった2つの結果しかない場合、あなたの友人は単純に"win"と"lose"のハッシュを自分で計算し、公開されたダイジェストと比較して、あなたの予測を即座に知ることができます。裸のハッシュは束縛しますが隠蔽しません;ランダムなrがこの推測と確認攻撃を防ぐのです。
記事4 . マーチェルツリー: 今や数百万のコミットメントが積み重なっています。記事4では、Zcashがそれらを1つのツリーに整理し、その小さなルート指紋が全体の履歴を代表する方法、そしてノートがそのツリーにあることを証明しつつもどのノートであるかを明らかにしない方法を説明します。それが記事0の「公開されたボード」の実際の形です。
Zcash from First Principlesシリーズの一部で ZecHub から提供されています。CC BY-SA 4.0ライセンス。