Blockstreamが新しくConfidential Assetsなる機能をリリースしていたので、どういったものなのか見てみる。
Open Assets ProtocolやCounterpartyやColuなどBitcoinのブロックチェーン上で、Bitcoin以外のアセットを発行・送付するプロトコルが登場しているように、同じチェーン上で複数のアセットタイプをサポートするのはブロックチェーン技術の自然な進化と考えられる。複数のアセットタイプが同一のチェーンで扱えることで、それぞれのアセットタイプで同じチェーンのセキュリティ特性を共有可能になり、マルチアセットのアトミック・スワップのような新しいユースケースが可能になる。
複数のアセットタイプをサポートするには、各トランザクションの出力にasset tagをラベル付けするだけで実現できるが、この場合ユーザがそのトランザクションでどれだけの量を取引しているのか誰もが確認することができてしまう。Confidential Assetsは、Confidential Transactionの秘匿技術を利用してマルチアセットタイプをサポートする際にasset tagをブラインディングする技術になる。
Confidential Transaction*1と同様、Confidential Assetsではそのトランザクションが正しいトランザクションであることを誰もが暗号的に検証することができ、予期せずアセットが作成、破棄、変更されることが無いことを保証する。一方、そのトランザクションで取引されているアセットタイプやその量は、取引の当事者のみしか知ることができず、アセットタイプや量を他のユーザーから秘匿できる。
マルチアセットを扱うチェーンでは、通常特定のタイプのアセットの作成と破棄が行われる。Confidential Assetsにおけるアセットの発行というのは、新しいasset tagの作成とアセットの量を指定する発行用のトランザクションを作成することを指す。その後のアセットの再発行は、アセットに関連付けられた再発行トークンに関する権限を証明することで実行できる。この発行トークンはアセット作成時に一緒に作成できるが、アセットが再発行をサポートしない場合この発行トークンは作成しない。
発行トランザクションは、入力と出力のバランスを取らなくていいという点で独特なトランザクションになる。この時、発行量が公開されていれば、そのアセットの発行量は周知になる。
では、具体的にConfidential Assetsの仕組みをみていく。
Confidential Assetsの技術
Asset TagとRangeproofs
Confidential Assetsの技術を知るためにはまずConfidential TransactionのベースになっているPedersen commitmentsについて知る必要がある。
commitment = xG + aH
ここでG
は楕円曲線の標準のベースポイントで、H
は2つめのベースポイントで、Commitment TransactionではH = to_point(SHA256(ENCODE(G)))
といったロジックで算出される。このようなベースポイントをnothing-up-my-sleeve
= NUMS
と呼ぶ。
Commitment Transactionで↑はx
を使ってコインの量a
をブラインディングするcommitmentとして説明されている。Confidential Assetsでは、H
をa
コインとして扱う(= H
をアセットタイプとして扱う)ことができるのではないかという点に注目している。
別のNUMS
ベースポイントI
を追加し、以下の2つのcommitmentを考えたとき、
commitment_1 = xG + aH commitment_2 = xG + aI
ここでH
とI
は異なるアセットを表すものとして考えることができ、この2つのcommitmentは、量は同じa
を持つ異なるアセット(H
とI
)へのcommitmentであると言える。
以下のようなアセットタイプの異なる2つの入力と2つの出力を持つトランザクションを考えてみる。
in1 = xG + aH, H --\ /-- uG + cH, H = out1 |---| in2 = yG + bI, I --/ \-- vG + dI, I = out2
Commitment Transactionの場合ベースポイントは1つだったので、トランザクションの入力と出力で量が合っているかどうかは
out1 + out2 - in1 - in2 = 0
を検証すればよかった。複数アセットの場合も同様の式が成立する↓
0 = out1 + out2 - in1 - in2 = (uG + cH) + (vG + dI) - (xG + aH) - (yG + bI) = (u + v - x - y)G + (c - a)H + (d - b)I
H
とI
は両方とも NUMS
ポイントなので、この式が成り立つのは個々の項が0の場合か、c = a
かつ b = d
の場合。言い換えると、この式はアセットH
の総量が入力と出力で同じで、アセットI
の総量が入力と出力で同じ場合に成立する。
これは2つ以上のasset tagでも成立し、実際にそれぞれ一意のNUMS
ポイントを割り当てることができる限り、無制限の種類のアセットをサポートすることができる。
Commitment Transactionと同様、この式だけでは値のオーバーフローやマイナス値への考慮が不十分なため、Commitment Transactionと同様、各出力にrangeproofをアタッチすることでこれを解決する。唯一違うのは、検証者が予め決まっていた固定ベースポイントH
を使う代わりに、asset tagを使って検証しなければならない点だけ。
Blinded Asset TagとAsset Surjection Proofs
↑の例では、各トランザクション出力にNUMS
ポイント、もしくはasset tagが関連付けられており、同じアセットタイプの出力では同じtagが使用される前提だった。これだと出力毎にどんな種類のアセットが取引されているのか分かってしまうというプライバシー上の問題が残る。
これは各asset tagを以下の形式のblinded asset tagに置き換えることで解決できる。
A = H + rG
H
は↑のasset tagで、r
はランダムなシークレット値。r
を知る人は誰でもこのタグが表すアセットが分かるが、r
を知らない人にとってはランダムな楕円曲線上のポイントにしかみえない。A
を持つ値へのコミットメントはH
を持つ値へのコミットメントなので、"出力の総量 - 入力の総量 = 0"というルールはトランザクションの検証時に引き続き機能する↓
commitment_A = xG + aA = xG + a(H + rG) = (x + ra)G + aH = commitment_H
このブラインディングファクターの導入は、ユーザーがrangeproofを生成するのに影響を与えないが、入出力のバランスの計算が少し複雑になる。
というのも各blinded asset tagは検証者から見るとランダムな値に見えるので、そのトランザクションのasset tagが正しいか検証する際に(以下のようなblinded asset tagの悪用を考えると)"出力の総量 - 入力の総量 = 0"という検証だけでは充分でないという問題がある。
A′ = -H + rG
この場合ブラインドされたアセットA′ の量は、アセットH
の負の値をとり、攻撃者が違法に資金供給量を増やすのに使われることになってしまう。
この問題を解決するためasset surjection proofという仕組みが導入される。これはトランザクション内のどの出力がその入力に対応しているのかをブラインディングした状態で、各トランザクション出力のアセットタイプがある入力のアセットタイプと同じであることを暗号的に証明する仕組みになる。
この仕組みは簡単で、同じasset tagアセットH
にコミットするblinded asset tagA
とB
があるとして、
A - B = (H + aG) - (H + bG) = (a - b)G
が秘密鍵a-b
に対応する署名鍵となる。
トランザクション出力out1
が与えられると、トランザクションの全ての入力に対し、out1 - in1
、out1 - in2
..の鍵で(いくつかの秘密鍵の内のどれかで署名されたことは分かるがどの秘密鍵が使われたのかは分からない)リング署名を使う。out1
がある入力と同じasset tagを持つ場合、トランザクションの署名者は署名鍵の中から対応する秘密鍵を知り、リング署名をすることができる。
asset surjection proof はこのリング署名で構成されている。
デモ
DG LabがOSSで公開してる↓
まとめ&所感
- どうやってアセットを表現するのかと思ったけど、Commitment Transactionのcommitment作成する際の2つめのベースポイントをアセットタイプとしてみなすことで実現してる。
- そのためアセットの量の秘匿もCommitment Transactionのロジックそのままで秘匿可能。
- 量は秘匿できても、各出力に割り当てられたasset tagから出力でどのアセットが取引されているかわかるので、アセットタイプも秘匿したい場合はblinded asset tagを使う。
- blinded asset tagは、ランダムなシークレット値
r
を使用してH + rG
を計算した値で、r
を知るものしか本当にアセットタイプが何か知ることができない。 - ただ、 blinded asset tagを悪用してマイナスの量を組みこめてしまうので、単純な入出力のバランス以外にasset surjection proof という仕組みで不正がないか検証できるようにしてる。
- ベースポイントを拡張アイテムとして使うアプローチは楕円曲線の特性を上手く活かしてて面白い。
- 時間のある時にホワイトペーパーの方も読んでおきたい。
*1:Blockstreamのサイドチェーンで実装されているコインの取引量を秘匿する技術。詳細は以前書いた↓参照。techmedia-think.hatenablog.com