More Related Content
More from shigeyuki azuchi (12)
【暗号通貨輪読会#14】confidential transaction
- 1. Copyright ©2017 HAW International Inc. all rights reserved.
暗号通貨読書会#14
Confidential Transaction
2017 / 12 / 19
株式会社ハウインターナショナル
安土 茂亨
- 2. Copyright ©2017 HAW International Inc. all rights reserved.
自己紹介
安土 茂亨 @techmedia_think
福岡で主にRubyでBlockchain関連のプロダクトの開発や
PoC、大学との共同研究とか
● openassets-ruby
https://github.com/haw-itn/openassets-ruby
● bitcoin-rubyへのsegwit実装
● Bech32のrubyライブラリ
https://github.com/azuchi/bech32rb
● bitcoinrb
https://github.com/haw-itn/bitcoinrb
● ブログ
http://techmedia-think.hatenablog.com/
● ブロックチェーン・プログラミング 仮想通貨入門 執筆
https://www.amazon.co.jp/dp/4061538314/
- 3. Copyright ©2017 HAW International Inc. all rights reserved.
Confidential Transaction
Greg Maxwellによって発表された、Bitcoinの送金量を秘匿するための仕組み
https://people.xiph.org/~greg/confidential_values.txt
オリジナルのアイディアはBitcointalkでのAdam Backのポスト
https://bitcointalk.org/index.php?topic=305791.0
ブロックチェーン上には個人情報は記載されないが、外的要因でアドレスと個人が結びつくと
アドレス間の送金履歴などから、誰がいくら誰に支払いをしていたか分かってしまうため、その
プライバシーを強化するためのプロトコル。
※トランザクションの発生やアドレス(scriptPubkey)は通常のBitcoinと同様記載され、秘匿さ
れるのはあくまで量だけ。
● BlockstreamのサイドチェーンElementsで実装
https://github.com/ElementsProject/elements
- 4. Copyright ©2017 HAW International Inc. all rights reserved.
Pedersen Commitment
1991年にPedersenによって提案された、離散対数を利用した秘密分散の仕組み
https://www.cs.cornell.edu/courses/cs754/2001fa/129.PDF
● シンプルなcommitment
commitment = SHA-256(blinding_factor || data)
● commitmentの加算
C(BF1, data1) + C(BF2, data2) == C(BF1 + BF2, data1 + data2)
C(BF1, data1) − C(BF1, data1) == 0
data1〜3={1, 1, 2}、BF1〜BF3={5, 10, 15}の場合
C(BF1, data1) + C(BF2, data2) - C(BF3, data3) == 0
C(1 + 1, 5 + 10) − C(2, 15) == 0
- 5. Copyright ©2017 HAW International Inc. all rights reserved.
楕円曲線を利用したPedersen Commitment
● 楕円曲線暗号の秘密鍵(x)と公開鍵(Pub)
Pub = xG (※Gは楕円曲線のベースグループ)
● 楕円曲線の準同型の加法性
Pub1 + Pub2 = (x1 + x2 (mod n))G
※この性質を利用したのがBIP-32のHDウォレット
● 楕円曲線を利用したcommitment
commitment = xG + aH
※ xは秘密のblinding factor, a はコミットするコインの量
HはGとは異なるベースグループでGから計算する
H = to_point(SHA256(ENCODE(G)))
※楕円曲線上の点Hのx座標が(SHA256(ENCODE(G)))
- 6. Copyright ©2017 HAW International Inc. all rights reserved.
Hの計算方法
require 'ecdsa'
G = ECDSA::Group::Secp256k1
# 1. Gのジェネレーター(点)の x座標をSHA256し、Hのx座標を算出する
encoded_g = ECDSA::Format::PointOctetString.encode(G.generator)
coordinate_x = Digest::SHA256.hexdigest(encoded_g).to_i(16)
=> 36444060476547731421425013472121489344383018981262552973668657287772036414144
# 2. 算出したx座標からy座標を計算(yは2つ候補がある) y^2 = x^3 + 7
P = G.field.prime
coordinate_y1 = G.field.power((coordinate_x**3 + 7) % P, (P + 1)/4)
=> 93254584761608041185240733468443117438813272608612929589951789286136240436011
coordinate_y2 = coordinate_y1 * -1 % P
=> 22537504475708154238330251540244790414456712057027634449505794721772594235652
# ※Elementsの実装ではcoordinate_y2を使用
# 3. x座標とy座標が分かったので Hの点が分かる。CTの場合Hは固定値なので都度計算する必要はない。
H = ECDSA::Point.new(G, coordinate_x, coordinate_y2)
- 7. Copyright ©2017 HAW International Inc. all rights reserved.
Bitcoinのトランザクションに適用
TxOut
value(8 bytes)
scriptPubkey
commitment = xG + aH (32 bytes)
“value”: 0.0050000
“commitment”: “08e6cb1c2118fa492df6782f84d496882ced45b4e759d7cafd507cc2211d217cef”
※ commitment = 楕円曲線の公開鍵
↑はElementsが出力するcommitmentだが通常のECDSAの公開鍵のフォーマットとは異なる。
blinding factor(x)とaを知らない第三者は
コインの量が分からない
- 8. Copyright ©2017 HAW International Inc. all rights reserved.
秘匿された量の検証
秘密を知らないユーザーには送金される量は分からないが、そのトランザクションで送金され
ている量が正しい量かは誰もが検証できる必要がある。(インプットの量 − アウトプットの量 = 手数料)
インプットのcommitment − アウトプットのcommitment = 0 になればいい。
※但し、手数料は明示的に設定する必要がある。
楕円曲線の点(x, y)の減算をする場合は、点 (x, -y)を加算する。
問題点
(1 + 1) − (-5 + 7) == 0
も成立し、もともとインプットは 2BTCしかないが、7 BTCのアウトプットが成立(=通貨発行)してしまう。
※ グループGは巡回群なのでオーバーフローさせることでマイナスのような振る舞いをする。
commitmentがマイナスの値でない( 0〜2^64の範囲である)ことを証明する別の仕組みが必要。
(In1 + In2 + In3 + … ) - (Out1 + Out2 + Out3 + … + fee * H) == 0
- 9. Copyright ©2017 HAW International Inc. all rights reserved.
Range Proof
commitment(P) = xG + aH
● 前提
Gに加えてHも付加しているため、誰もPの秘密鍵が分からない=誰もこの公開鍵に対
応した署名は作れない。
a = 0の場合、P=xGとなりxを知っているユーザーはPの秘密鍵を知っていることになり、
Pに対応した署名を作成できる。
● a = 1(a != 0)の場合の証明
1. Cを使って新しいcommitment C’ = C - 1H を作る。
2. a=1ならC'の秘密鍵はxで、C'の署名を作ることができる。
3. a != 1なら、誰もC'の署名に必要な秘密鍵はわからないので署名は作れない。
- 10. Copyright ©2017 HAW International Inc. all rights reserved.
Range Proof
OR Proofはcommitmentがあるデータ・セットの中のいずれかの値にコミットしたものであるこ
とを証明する仕組み。
C = xG + aH, C’ = C - 1H
リング署名{C, C’}が提供された場合Cは0 か1 どちらかのコミットメントである。
コミットされた値が0..32の範囲にあること証明する場合は以下を用意する。
○ C1(0 or 1),C2(0 or 2),C3(0 or 4),C4(0 or 8),C5(0 or 16)
○ OR Proof
リング署名をさらに効率的にするためボロミアン・リング署名を採用。
https://github.com/Blockstream/borromean_paper/raw/master/borromean_draft_0.01_8c3f9e7.pdf
※ アウトプットが1つだけの場合は、range proofは不要
- 11. Copyright ©2017 HAW International Inc. all rights reserved.
量の表現方法と通知
● 量の表現
量は浮動小数点で表現する。(0.0112345 → 112345 × 10^-7)
性能とproofのサイズは仮数部のbit数に比例。
● Blinding Factorと量の通知
送信者はBlinding Factorと量を送信者と受信者のECDHの鍵共有の前提で、量と
blinding factorを暗号化したメッセージをproofにセットすることで相手に通知する。(他に
も任意のメッセージを送るのに利用可)
- 12. Copyright ©2017 HAW International Inc. all rights reserved.
ElementsでのBlinding Factorの共有
Blinding factorはコインの受信者が送信者に伝える。
Elementsの場合、commitmentのxGを含むConfidential Addressを相手に伝える。
CTErPjNQRCAK6r3Nd3oARyrNhVRecmn6fuAQ7YJABN7KWQdML5uwPyLE7sLmY6wXVrCCnrCqytNYukyJ
04eb (version bytes)
02f7b3997676d9c9f78630b335a99c383f620a7d4630ad7c2d989838b15346768(confidential key = xG)
aabe7c2cb93edaa3448aa9607ff95849f101d908(公開鍵ハッシュ)
ef4201bd(チェックサム)
Base58デコード
送信者はアドレスのconfidential keyと送るコインの量からcommitmentを作成し、公開鍵
ハッシュからP2PKHのscriptPubkeyを作成して、コインを送金するトランザクションを作る。
※ Blinding Factor(x)を直接渡しているわけではない。
- 13. Copyright ©2017 HAW International Inc. all rights reserved.
range proofのサイズ問題とBulletproofs
現在の実装では、2つのアウトプットを持つトランザクションのサイズは5.5 KBほどで、そのう
ちrange proofのサイズは5.3 KBを占める。ブロックサイズ1MBのような制限下では現実的に
採用しづらい。
Bulletproofs: Short Proofs for Confidential Transactions and More
http://web.stanford.edu/~buenz/pubs/bulletproofs.pdf
http://diyhpl.us/wiki/transcripts/scalingbitcoin/stanford-2017/state-of-cryptography/
● range proofのサイズを大幅に削減(4KB→670B: 2/10のサイズ)
範囲のビット長nについて 2 log(n) + 9 の要素で証明が作成でき、対数的なデータ増加になる。
● range proofの集約をサポート(2つのrange proof 8KB→736B : 1/10のサイズ)
単一の証明にO(log(m))の追加要素が必要なだけ(m はコミットメントの数)
署名を集約できるのでアウトプットが多いCTほどrange proofの圧縮効果が高い。
- 14. Copyright ©2017 HAW International Inc. all rights reserved.
Bulletproofsの効果
さまざまなrange proofを必要とする仕組みに適用可能
● Confidential Transaction, Confidential Assets
● Monero
https://github.com/b-g-goodell/research-lab/tree/master/source-code/StringCT-jav
a/src/how/monero/hodl/bulletproof
通常のrange proofに比べ90%のスペースの節約と25%の検証の高速化
● Mimblewimble(160GB→17GB)
● Provisoins Protocol(Proof of Solvency:200万ユーザー18GB→62MB)
http://www.jbonneau.com/doc/DBBCB15-CCS-provisions.pdf
● ValueShuffle(CoinJoin + Confidential Transaction)
https://eprint.iacr.org/2017/238.pdf
- 15. Copyright ©2017 HAW International Inc. all rights reserved.
Confidential Assets
Confidential Transactionを使ってネイティブのコイン以外に任意のアセットの発行・送付を
するプロトコル。https://blockstream.com/bitcoin17-final41.pdf
各アウトプットにアセットのタイプ識別するasset tagを付与する。
各アウトプットのcommitmentは
commitment = xG + aH
commitmentの構築に使っていた固定値Hをアセットの識別子として置き換える。
aがHコインの量となり、range proofなどはConfidential Transactionと同様に機能する。
- 16. Copyright ©2017 HAW International Inc. all rights reserved.
asset tag
● asset tagの構成要素
○ Ricardian Contract
アセットの使用条件や償還ルールを記載したマシンリーダブルなドキュメント
○ Asset Entropy
アセット発行に使用するUTXOとRicardian Contractから生成するエントロピー
● asset tagの導出
1. UTXOのOutPoint(I)とRicardian Contract(C)からエントロピーを計算
E = Hash(Hash(I)||Hash(C))
※ ElementsではIとCのハッシュをリーフにしたマークルツリーのルート
2. エントロピーからasset tagを計算
H(E || 0)
※ H(E || 0) の0は追加発行フラグで、0は追加発行無し、1は追加発行有り。
H(E || 1)が追加発行時のトークンとなり、このトークンを持っているウォレットで同じアセットの追加発行が可
能
3. 計算したasset tagを使ってcommitmentを作成する
- 17. Copyright ©2017 HAW International Inc. all rights reserved.
range proof
commitment1 = xG + aH
commitment2 = xG + aI
コインの量aは同じだが、HとI異なるアセットを表現したコミットメント
HとIのアセットについて2つのインプットと4つのアウトプットをもつ場合
● Input: xG + aH、yG + bI
● Output:uG + cH、vG + dI、wG + eH、zG + fI
量の検証は
Out1 + Out2 + Out3 + Out4 - In1 - In2 == 0
(uG + cH) + (vG + dI) + (wG + eH) + (zG + fI) - (xG + aH) - (yG + bI) == 0
(u + v + w + g - x - y)G + (c + e - a)H + (d + f - b)I == 0
CTと同様range proofを付与するが、その際固定のHでなくasset tagを使う。
- 18. Copyright ©2017 HAW International Inc. all rights reserved.
asset tagの秘匿
アセットの量だけでなく何のアセットなのかasset tagも秘匿したい場合、asset tagをblinded
asset tagに置き換える。
blinded asset tag(A) = H + rG
※Hはasset tagで、rはランダムなシークレット
このblinded asset tag を使ったcommitmentは、
commitment = xG + aA = xG + a(H+ rG) = (x + ra)G + aH
問題点
● 正しいasset tagであることはどうやったら検証できるか?
● A' = -H + rGのようなマイナスのアセット量を持つblinded asset tagが作れる
- 19. Copyright ©2017 HAW International Inc. all rights reserved.
asset surjection proof
トランザクション内のどのインプットがどのアウトプットに対応しているかを秘匿したまま、あるイ
ンプットのasset tagがあるアウトプットのasset tagと同じであることを暗号学的に証明する仕
組み。
asset tag Hにコミットするblinded asset tag A, Bがあるとして、
A - B = (H + aG) - (H + bG) = (a - b)G
秘密鍵 a - bを使ってを署名することができる。
トランザクションのblinded asset tagを持つアウトプットに対して、全てのインプットを引きou1
- in1, out1 - in2, out1 - in3…、これら計算値でリング署名を構成する。
※実際に有効な署名が作れるのはアウトプットとインプットのasset tagが同じ場合のみ
このリング署名をasset surjection proofと呼ぶ。
- 20. Copyright ©2017 HAW International Inc. all rights reserved.
soft forkで実装するConfidential Transaction
2016.1.6にFelix Weissが提案 Confidential Transactions as a soft fork (using segwit)
https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2016-January/012194.html
※以降の話は全て↑の提案の話で、実際にこの仕組みが採用されると決まった話ではありません。
● script witnessの後にアウトプット用のwitnessOuts領域を追加
○ CTのアウトプットの量は0(※SFに対応していないノードには 0 satoshiに見える)
○ commitmentとrange proofをwitnessOutsにセット
● 手数料は、誰もが使用可能なアウトプットに明示的にセット(GCTXO)する。
- 21. Copyright ©2017 HAW International Inc. all rights reserved.
Blinding Transaction
量が秘匿されていないコインの量を秘匿するトランザクション
● アウトプットのコインの量は0が指定され、そのコインはコインベーストランザク
ションの特殊なアウトプット(GCTXO[coinbase])にロックされる。
● 秘匿化されたコインは全てGCTXOで管理される。
Ins: 全て秘匿されていない通常のUTXOを参照する
Outs:
0..N: 新しい秘匿対象の出力
量: 0
scriptPubkey: `OP_2 <32バイトのハッシュ値>`
witnessOut: `0x{petersen-commitment}> <0x{range-proof}>`
最後の出力:
量: 0
scriptPubkey: `OP_RETURN OP_2 {blinding-fee-amount}`
Fee: 全入力のコインの合計
- 22. Copyright ©2017 HAW International Inc. all rights reserved.
Confidential Transaction
量が秘匿されたコインを秘匿したまま送金するトランザクション
● インプット・アウトプット共に全て量は 0(アウトプットは誰もが使用可能なスクリプト)
● commitmentとrage proofが有効なこと
● 最後のアウトプットがマイナーへの手数料
Ins:
prev: CTXO[n]
scriptSig: 空
witnessIn: `<署名> <0x{redeem script}>`
Outs:
0..N: 新しい秘匿対象の出力
量: 0
scriptPubkey: `OP_2 <32バイトのハッシュ値>`
witnessOut: `0x{petersen-commitment}> <0x{range-proof}>`
最後の出力:
量: 0
scriptPubkey: `OP_RETURN OP_2 {confidential-fee-amount}`
Fee: 0
- 23. Copyright ©2017 HAW International Inc. all rights reserved.
Unblinding Transaction
量が秘匿されたコインの秘匿を解除するトランザクション
● アウトプットは全てOP_RETURN
● アンブラインドされたコインは Confidential base Transactionの1つめのアウトプットで通常の
UTXOにされる。
Ins:
prev: CTXO[n]
scriptSig: 空
witnessIn: `<署名> <0x{redeem script}>`
Outs:
0..N:
量: 0
scriptPubkey: `OP_RETURN OP_2 {アンブラインドするコインの量} {p2sh-destination}`
witnessOut: 空
最後の出力:
量: 0
scriptPubkey: `OP_RETURN OP_2 {unblinding-fee-amount}`
Fee: 0
- 24. Copyright ©2017 HAW International Inc. all rights reserved.
Confidential base Transaction
CTに関するトランザクションが含まれるブロックの最後のトランザクションとして登
録されるトランザクション
● GCTXO[coinbase] : ブロックに含まれる全ての秘匿されたコインの量を持つ
● GCTXO[last_block] : 前のブロックConfidential base Transactionの0番目のアウトプットのコ
イン(前のブロックの秘匿化されたコインからアンブラインドされたコインを引いた量)
● 1番め以降のアウトプットはアンブラインドしたコインの UTXO
Ins:
GCTXO[last_block],
GCTXO[coinbase]
Outs:
0: GCTXO[current_block]
量: {last_block + coinbase - unblindings}
scriptPubkey: `OP_TRUE`
1..N:
量/scriptPubkey: このブロック内のトランザクションでアンブラインドしたコインの量
- 25. Copyright ©2017 HAW International Inc. all rights reserved.
Block
トランザクションフロー
Blinding Tx
UTXO
CTXO
秘匿された手数料のアウトプット
手数料=全インプットの合計
Coinbase Tx
GCTXO
Confidential base Tx
GCTXO [ coinbase ]
GCTXO [ last_block ]
GCTXO [ current_block ]
UTXO
Unblinding Tx
CTXO
OP_RETURN アンブラインド量 script
秘匿された手数料のアウトプット
手数料=0
Confidential Tx
CTXO
CTXO
秘匿された手数料のアウトプット
手数料=0
Block
Coinbase Tx
GCTXO
秘匿化されたコインは全てGCTXOが保持する。
Confidential base Tx
GCTXO [ coinbase ]
GCTXO [ last_block ]
GCTXO [ current_block ]
UTXO
前ブロック時点の秘匿されたコインの送料
このブロックで秘匿されたコインの量
マイナーが作成するTxで手数料も徴収