Bulletproofs とは?秘匿された金額を検証する仕組み

· 9 分で読めます

Bulletproofs は短いゼロ知識範囲証明で、暗号資産がすべての取引金額を隠しながら、各ノードがコインが生み出されていないことを確認できるようにします。このガイドでは、ペダーセンコミットメント、秘匿された金額に範囲証明が必要な理由、Bulletproofs が証明を小さく保つ仕組み、そして Blocknet がすべてのアウトプットでそれをどう使っているかを説明します。

Bulletproofs とは何ですか?

簡単な答え

Bulletproofs は、2018 年に Bünz、Bootle、Boneh、Poelstra、Wuille、Maxwell が発表した短いゼロ知識証明です。暗号資産では、隠された金額が 0 から 2^64 のような有効な範囲にあることを、金額を明かさずに証明します。トラステッドセットアップは不要で、サイズは範囲の対数に比例してしか増えません。

論文 Bulletproofs: Short Proofs for Confidential Transactions and More は、2018 年の IEEE Symposium on Security and Privacy で発表されました。著者たちは、ブロックチェーン上の金額をコミットメントに置き換えるコンフィデンシャルトランザクションのためにこれを設計しました。そもそもなぜこのような証明が必要なのかを理解するには、まずコミットメントから見ていきます。

ペダーセンコミットメントとは何ですか?

コミットメントは、封をした封筒を暗号技術で実現したものです。数値を中に入れ、封筒を全員に見せ、後で中身が何だったかを証明できます。封筒から数値を読み取ることは誰にもできず、後から別の数値に差し替えることもできません。

1991 年に Torben Pedersen が考案したペダーセンコミットメントは、これを楕円曲線上の点で実現します。金額 v をコミットするには、ウォレットはブラインディングファクターと呼ばれるランダムな秘密 r を選び、次を計算します。

C = v·G + r·H

G と H は曲線上の 2 つの固定された公開点で、一方をもう一方の倍数として表す方法を誰も知らないように選ばれています。結果の C は 32 バイトの 1 つの点です。これには 2 つの性質があります。

読めないトランザクションをノードはどうやって確認するのですか?

簡単な答え

ペダーセンコミットメントは足し合わせることができます。2 つのコミットメントの和は、金額の和に対するコミットメントになり、ブラインディングファクターも足し合わされます。ノードはトランザクションのインプットのコミットメントと、アウトプットのコミットメントに手数料を加えたものをそれぞれ合計し、2 つの合計が一致することを確認するので、金額を見ずに収支を確認できます。

2 つのコミットメントを足すと (v1 + v2)·G + (r1 + r2)·H になり、これ自体が v1 + v2 に対するコミットメントです。送信者は、インプットのブラインディングの合計がアウトプットの合計と等しくなるようにブラインディングファクターを調整します。金額も釣り合っていれば、インプットの和とアウトプットの和の差はちょうどゼロになり、どのノードでもそれを検証できます。

ネットワーク手数料は、トランザクションの中で唯一公開される数値です。ノードはそれをブラインディングファクターがゼロのコミットメントにしてアウトプット側に加えるので、確認の式は「インプット = アウトプット + 手数料」になります。

秘匿された金額になぜ範囲証明が必要なのですか?

コミットメントの計算は、曲線群の位数という約 2^252 の非常に大きな数を法として行われます。この計算では「負」の金額は単なる巨大な正の数です。誰かが 10 コインのインプットを使って、11 コインのアウトプットと「マイナス 1」コインのアウトプットの 2 つを作ることもできてしまいます。コミットメントは完全に釣り合い、1 コインが無から現れ、それはどの第三者からも隠されます。

範囲証明はこの穴をふさぎます。コミットメント内の金額が 0 から 2^64 の間にあることを、金額を明かさずに証明します。すべてのアウトプットがこのように制限されていれば、少数のアウトプットを足しても群の位数を一周するほど大きな数にはならないので、コミットメントが釣り合えば金額も釣り合います。

以前のコンフィデンシャルトランザクションの設計では、ビット数に比例して大きくなる範囲証明が使われていました。Bulletproofs は対数に比例してしか大きくならないので、64 ビットの証明が数百バイトに収まります。

Bulletproofs はどのように機能しますか?

Bulletproof は 3 つのステップで範囲を証明します。

  1. 金額をビットに分解する。 64 ビットの金額は 64 個のビットからなるベクトルになります。証明者はそのベクトルにコミットし、2 つの事実を示します。各要素が 0 か 1 であること、そしてビットを 2 のべき乗で重み付けして足すとコミットした金額になることです。
  2. それらの事実を 1 つの内積にまとめる。 ランダムなチャレンジを使い、証明者はそれらの条件をすべて、2 つのベクトルの内積に関する 1 つの主張に畳み込みます。チャレンジがランダムなので、誤った主張が通る確率は無視できるほど小さくなります。
  3. 半分にしながら内積を証明する。 各ラウンドで証明者は 2 つの曲線上の点 L と R を送り、両方のベクトルが半分の長さに畳み込まれます。log2(64) = 6 ラウンドの後には、数値のペアが 1 つだけ残ります。

サイズが小さいのは、この半分にする処理のおかげです。論文の要旨では、n ビットの範囲に対する範囲証明は 2·log2(n) + 9 個の群と体の要素になるとしています。64 ビットなら 6 ラウンドからの 12 個の点に 9 個を加えた合計 21 個の要素で、各要素が 32 バイトなら 672 バイトです。

この証明は非対話型です。検証者がその場でチャレンジを送る代わりに、双方が証明のトランスクリプトをハッシュしてチャレンジを導出します。これは Fiat-Shamir ヒューリスティックとして知られる標準的な手法です。Bulletproofs はトラステッドセットアップも不要です。生成元は公開されていて誰でも導出でき、安全性は離散対数仮定だけに依存します。複数の証明を集約しても要素は対数的にしか増えず、検証もバッチ処理できます。

Bulletproofs を使っているのは誰ですか?

Monero は、トランザクションサイズを小さくするため、2018 年 10 月 18 日のネットワークアップグレード(v0.13.0 リリース)で Bulletproofs を有効にしました。dalek-cryptography プロジェクトの Rust bulletproofs ライブラリは Curve25519 の Ristretto 群上でこれを実装しており、Blocknet の暗号ライブラリはその上に構築されています。

Blocknet はどのようにすべての金額を隠していますか?

Blocknet では、すべてのトランザクションのすべてのアウトプットが金額の代わりにペダーセンコミットメントを持ち、すべてのアウトプットが専用の 64 ビット Bulletproof を持ちます。プライバシーはトランザクション形式の一部で透明なモードはないので、金額が見える支払いを送る方法はありません。

ノードがトランザクションを受け入れる前に確認することは次のとおりです。

これは Blocknet エクスプローラーで確認できます。トランザクションのページでは金額が「hidden · Pedersen commitments」と表示され、各アウトプットにはコミットメント、暗号化メモ、そして「672 bytes · Bulletproof」という範囲証明が表示されます。これは上の計算で予測されるサイズです。

受信者には実際の金額が見えます。各アウトプットには送信者と受信者のウォレットが共有する秘密で暗号化された金額が付いており、受信者のウォレットは秘密ビューキーでそれを復号します。金額が見えるのは支払いに関わる 2 人だけで、ほかの誰にも見えません。

秘匿された金額は、Blocknet のほかのレイヤーと組み合わさって機能します。16 のアウトプットにわたるリング署名が送信者を、使い捨てステルスアドレスが受信者を、Dandelion++ がトランザクションがネットワークに入った場所を隠します。それぞれについては Blocknet のプライバシー機能のガイドで説明しています。

自分のプライベートな BNT を手に入れる

金額が秘匿されたコインを手に入れる簡単な方法は、マイニングすることです。Blocknet は一般的なコンピューターでマイニングできるメモリハードな Argon2id プルーフ・オブ・ワークを使っており、seine は CPU と、搭載されていれば NVIDIA GPU も一緒に使ってマイニングし、設定なしで自動で調整します。bntpool.com から届く支払いはすべて、コミットメントと Bulletproof の付いたプライベートなアウトプットとして届きます。マイニングガイドを読めば、ダウンロードからシェアの受理まで数分で進めます。

よくある質問

Bulletproofs にトラステッドセットアップは必要ですか?

いいえ。Bulletproofs は、楕円曲線署名と同じ離散対数仮定だけに依存し、誰でも導出できる公開パラメーターを使います。セットアップの儀式も、後で誰かが破棄しなければならない秘密もなく、Monero や Blocknet などのプライバシーコインが範囲証明に使っています。

Bulletproofs の範囲証明の大きさはどれくらいですか?

64 ビットの Bulletproof 1 つは 2 × log2(64) + 9 = 21 個の要素からなります。Ristretto 群では各要素が 32 バイトなので、証明はどれも 672 バイトで、Blocknet のエクスプローラーでも各アウトプットについてちょうどその値が表示されます。サイズは範囲の対数に比例して増えるので、ビット長を 2 倍にしても要素は 2 つ増えるだけです。

Blocknet のトランザクションの金額を見られるのは誰ですか?

送信者と受信者だけです。チェーンには、アウトプットごとにペダーセンコミットメントと範囲証明、そして 2 つのウォレットが共有する秘密で暗号化された金額が保存されます。受信者のウォレットは秘密ビューキーでそれを復号します。公開される数値はネットワーク手数料だけで、ノードはそれを残高の確認に加えます。

金額が隠されているのに、コインが生み出されていないことをノードはどうやって知るのですか?

すべてのノードは、トランザクションごとに 2 つのことを確認します。ペダーセンコミットメントの合計が一致し、インプットがアウトプットと手数料の合計に等しいこと、そしてすべてのアウトプットに、金額が 0 から 2^64 の間にあることを示す有効な範囲証明が付いていることです。この 2 つで、金額を 1 つも明かさずに隠れたインフレを防ぎます。