ビットコイン・インスティテュート

BIP 173 — ネイティブv0-16ウィットネス出力向けBase32アドレス形式

  BIP: 173
  Layer: Applications
  Title: Base32 address format for native v0-16 witness outputs
  Authors: Pieter Wuille <pieter.wuille@gmail.com>
           Greg Maxwell <greg@xiph.org>
  Comments-Summary: No comments yet.
  Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0173
  Status: Deployed
  Type: Informational
  Assigned: 2017-03-20
  License: BSD-2-Clause
  Replaces: 142
  Proposed-Replacement: 350

はじめに

概要

本文書は、チェックサム付きbase32形式「Bech32」と、それを用いたネイティブsegregated witness出力アドレスの標準を提案する。

著作権

本BIPは2条項BSDライセンスの下でライセンスされる。

動機

ビットコインは、その歴史の大半において、末尾切り詰め二重SHA256チェックサム付きのbase58アドレスに依拠してきた。これらはオリジナルのソフトウェアの一部であり、その適用範囲はPay-to-script-hash(P2SH (https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki))向けのBIP13 (https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki)で拡張された。しかし、文字集合とチェックサムアルゴリズムの双方に限界がある。

  • base58はalphanumeric modeを使えないため、QRコード内で多くの空間を必要とする。
  • base58の大文字小文字混在は、確実に書き留めたり、モバイル端末のキーボードで入力したり、声に出して読み上げたりする際に不便である。
  • 二重SHA256チェックサムは低速であり、誤り検出の保証を持たない。
  • 誤り検出符号に関する研究の大半は、文字集合サイズが素数のべき乗 (https://en.wikipedia.org/wiki/Prime_power)である場合にしか適用できないが、58はそれに該当しない。
  • base58のデコードは複雑であり、比較的低速である。

Segregated Witness提案には、新しい種類の出力(ウィットネスプログラム、BIP141 (https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki)参照)と、その2つのインスタンス(「P2WPKH」および「P2WSH」、BIP143 (https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki)参照)が含まれる。これらの機能は、P2SH出力に埋め込むことで旧クライアントからも間接的に利用できるが、最適な効率性とセキュリティのためには直接利用するのが最善である。本文書では、(現行および将来の)ネイティブウィットネス出力向けの新しいアドレス形式を提案する。

これはBIP142 (https://github.com/bitcoin/bips/blob/master/bip-0142.mediawiki)を置き換えるものであり、以前はこちら (https://bitcoincore.org/logs/2016-05-zurich-meeting-notes.html#base32)で議論された(こちら (https://bitcoincore.org/en/meetings/2016/05/20/#error-correcting-codes-for-future-address-types)で要約)。

例

以下のすべての例では公開鍵0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798を用いる。P2WSHの例ではスクリプトとしてkey OP_CHECKSIGを用いる。

  • メインネットP2WPKH:bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4
  • テストネットP2WPKH:tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx
  • メインネットP2WSH:bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3
  • テストネットP2WSH:tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7

仕様

まず、チェックサム付きの一般的なbase32そもそもなぜbase32を使うのか? 大文字小文字混在がないことで、声に出して読み上げたりQRコードに収めたりする際の効率が高まる。長さが15%増加するという代償を伴うが、コピー&ペーストでアドレスをやり取りする限りは問題にならない。形式「Bech32」を説明し、その後にこれを用いたSegregated Witnessアドレスを定義する。

Bech32

Bech32なぜBech32と呼ぶのか? 「Bech」には(用いられている誤り検出アルゴリズムである)BCHの文字が含まれており、また「base」に少し似た響きを持つ。文字列は最大90文字であり、以下から構成される。

  • 人間可読部:データの種別や、読み手にとって関連するその他の情報を伝えることを意図した部分。この部分は1〜83文字のUS-ASCII文字を含まなければならず(MUST)、各文字の値は範囲 [33-126]内でなければならない。HRPの妥当性は、個々のアプリケーションによってさらに制限されてよい。
  • 区切り文字:常に「1」である。人間可読部の内部に「1」が現れうる場合、文字列内で最後に現れる「1」が区切り文字となるなぜアドレスに区切り文字を含めるのか? これにより、人間可読部がデータ部から曖昧さなく分離され、同じプレフィックスを共有する他の人間可読部との潜在的な衝突を避けられる。また、人間可読部に文字集合の制約を課さずに済む。区切り文字が1である理由は、非英数字を用いると(一部のアプリケーションではダブルクリック選択が効かないため)アドレスのコピー&ペーストが煩雑になるためである。したがって、通常の文字集合の外にある英数字が選ばれた。。
  • データ部:最低6文字で、「1」「b」「i」「o」を除く英数字のみから構成されるRFC3548 (http://www.faqs.org/rfcs/rfc3548.html)やz-base-32 (https://philzimmermann.com/docs/human-oriented-base-32-encoding.txt)のような既存の文字集合をなぜ使わないのか? この文字集合は、この (https://hissa.nist.gov/~black/GTLD/)視覚的類似性データに基づき曖昧さを最小化するよう選ばれており、また、(同じデータに基づき)1ビットを超えて異なる類似文字の組の数を最小化するよう順序が選ばれている。チェックサムは少数のビット誤りに対する検出能力を最大化するよう選ばれているため、この選択によりいくつかの誤りモデルの下での性能が向上する。。
01234567
+0qpzry9x8
+8gf2tvdw0
+16s3jn54kh
+24ce6mua7l

チェックサム

データ部の末尾6文字はチェックサムを構成し、情報を持たない。有効な文字列は、下記のPython3コードスニペットで規定される妥当性の基準を満たさなければならない(MUST)。関数bech32_verify_checksumは、以下の引数が与えられたときにtrueを返さなければならない。

  • hrp:人間可読部を表す文字列
  • data:上記の表を用いた変換後の各文字を表す整数のリストとしてのデータ部
def bech32_polymod(values):
  GEN = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3]
  chk = 1
  for v in values:
    b = (chk >> 25)
    chk = (chk & 0x1ffffff) << 5 ^ v
    for i in range(5):
      chk ^= GEN[i] if ((b >> i) & 1) else 0
  return chk

def bech32_hrp_expand(s):
  return [ord(x) >> 5 for x in s] + [0] + [ord(x) & 31 for x in s]

def bech32_verify_checksum(hrp, data):
  return bech32_polymod(bech32_hrp_expand(hrp) + data) == 1

これはBCH符号 (https://en.wikipedia.org/wiki/BCH_code)を実装しており、最大4文字に影響する誤りの検出を保証し、それを超える誤りを検出し損なう確率は109分の1未満である。この性質の詳細は、チェックサム設計の付録にまとめられている。人間可読部は、まず各文字のUS-ASCII値の上位ビットをチェックサム計算に投入し、続いてゼロを1つ、その後各文字の下位ビットを投入することで処理されるなぜ人間可読部の上位ビットが先に処理されるのか? これにより、実際にチェックサム計算される対象データは*[hrpの上位ビット] 0 [hrpの下位ビット] [データ]という形になる。これは、人間可読部への誤りが下位5ビットのみを変化させる(アルファベット文字を別のアルファベット文字に変えるような)ものだと仮定すると、誤りは最大89文字である[hrpの下位ビット] [データ]*部分に限定され、したがって(付録参照の)誤り検出特性がすべて引き続き適用可能であることを意味する。。

人間可読部と、(チェックサムを除く)データ部の各文字の値が与えられたとき、有効なチェックサムを構成するには以下のコードを用いることができる。

def bech32_create_checksum(hrp, data):
  values = bech32_hrp_expand(hrp) + data
  polymod = bech32_polymod(values + [0,0,0,0,0,0]) ^ 1
  return [(polymod >> 5 * (5 - i)) & 31 for i in range(6)]

誤り訂正

こうしたBCH符号の性質の1つとして、誤り訂正に利用できる点が挙げられる。誤り訂正の望ましくない副作用は、それが誤り検出の能力を損なうことである。訂正は無効な入力を有効な入力へ変えるが、誤りが数個より多く生じていた場合、その有効な入力は正しい入力ではないかもしれない。誤っているが有効な入力を使ってしまうと、資金が回復不能な形で失われうる。このため、実装は、文字列内のどこに誤りがありうるかをユーザーに示すこと(どう訂正するかは示さない)を超えた訂正機能を実装すべきではない(SHOULD NOT)。

大文字・小文字

チェックサムの目的で文字の値を判定する際には、小文字形式が用いられる。

エンコーダーは、常にすべて小文字のBech32文字列を出力しなければならない(MUST)。(表示目的やQRコード用途などのために)エンコード結果の大文字版が望ましい場合、エンコード処理とは別に大文字化処理を行うことができる。

デコーダーは、一部の文字が大文字で一部が小文字である文字列(このような文字列は「大文字小文字混在文字列」と呼ばれる)を受け入れてはならない(MUST NOT)。

表示用途では小文字が通常望ましいが、QRコード内では、通常の*バイトモード (http://www.thonky.com/qr-code-tutorial/byte-mode-encoding)より45%コンパクトな英数字モード (http://www.thonky.com/qr-code-tutorial/alphanumeric-mode-encoding)*の使用が許容されるため、大文字を用いるべきである(SHOULD)。

segwitアドレス形式

segwitアドレスなぜすべてのscriptPubKeyに汎用的なアドレス形式を作らないのか? それは既存のscriptPubKey種別向けアドレスについて混乱を招くことになる。さらに、scriptPubKeyと一対一で対応しないアドレス(ECDHベースのアドレス等)が将来導入された場合、完全に汎用な旧アドレス種別が利用可能であると、結果として生じるscriptPubKeyを旧アドレス形式で再解釈することが許されてしまい、そのアドレスへビットコインが送られた場合に資金喪失を招く。は、以下のBech32エンコーディングである。

  • メインネット向けの人間可読部「bc」なぜ「btc」ではなく「bc」を人間可読部として使うのか? 「bc」の方が短いためである。、およびテストネット向けの「tb」なぜテストネット向けの人間可読部として「tb」を使うのか? (長さに関する実装の想定を単純化するため)メインネット側と同じ長さでありながら、視覚的に区別できるものとして選ばれた。。
  • データ部の値:
    • 1文字(5ビットのデータを表す):ウィットネスバージョン
    • (BIP141 (https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki)で定義される)2〜40バイトのウィットネスプログラムをbase32へ変換したもの:
      • ウィットネスプログラムのビット列を、各バイトの最上位ビットから順に並べる。
      • それらのビットを5ビットずつのグループへ再編成し、必要であれば末尾をゼロで埋める。
      • それらのビットを、上記の表を用いて文字へ変換する。

デコード

segwitアドレスを解釈するソフトウェアは以下を行う。

  • 人間可読部がメインネットでは「bc」、テストネットでは「tb」であることを検証しなければならない(MUST)。
  • 最初にデコードされたデータ値(ウィットネスバージョン)が0から16の間(両端含む)であることを検証しなければならない(MUST)。
  • 残りのデータをバイトへ変換する:
    • 各値を、最上位ビットから順に5ビットへ変換する。
    • それらのビットを8ビットずつのグループへ再編成する。末尾の不完全なグループは4ビット以下でなければならず(MUST)、すべてゼロでなければならず(MUST)、破棄される。
    • グループの数は2から40の間でなければならず(MUST)、それらはウィットネスプログラムの各バイトとして解釈される。

デコーダーは、ウィットネスプログラムに関する既知の長さの制約を強制すべきである(SHOULD)。たとえばBIP141は「バージョンバイトが0であるにもかかわらず、ウィットネスプログラムが20バイトでも32バイトでもない場合、スクリプトは失敗しなければならない」と規定している。

以上の規則の結果として、アドレスは常に14文字から74文字の長さであり、その長さを8で割った余りは0、3、5のいずれにもなり得ない。バージョン0のウィットネスアドレスは常に42文字または62文字であるが、実装はどのバージョンの使用も許容しなければならない(MUST)。

実装は、アドレスをscriptPubKeyへ変換する際に特に注意を払う必要がある。ここでウィットネスバージョンnはOP_nとして格納される。OP_0は0x00としてエンコードされるが、OP_1からOP_16は0x51から0x60(10進数で81から96)としてエンコードされる。bech32アドレスが誤ったscriptPubKeyへ変換された場合、その結果はおそらく使用不能になるか、あるいは安全性を欠くことになる。

互換性

これらのアドレスを利用できるのは新しいソフトウェアのみであり、かつsegwitが有効化された新しいソフトウェアの受信者に対してのみである。それ以外のすべての場合には、P2SHまたはP2PKHアドレスを利用できる。

正当性

参照実装

  • 参照エンコーダー・デコーダー:

    • C向け (https://github.com/sipa/bech32/tree/master/ref/c)
    • C++向け (https://github.com/sipa/bech32/tree/master/ref/c++)
    • JavaScript向け (https://github.com/sipa/bech32/tree/master/ref/javascript)
    • Go向け (https://github.com/sipa/bech32/tree/master/ref/go)
    • Python向け (https://github.com/sipa/bech32/tree/master/ref/python)
    • Haskell向け (https://github.com/sipa/bech32/tree/master/ref/haskell)
    • Ruby向け (https://github.com/sipa/bech32/tree/master/ref/ruby)
    • Rust向け (https://github.com/sipa/bech32/tree/master/ref/rust)
  • 誤りの位置を特定する高機能デコーダー:

    • JavaScript向け (https://github.com/sipa/bech32/tree/master/ecc/javascript)(デモサイト (http://bitcoin.sipa.be/bech32/demo/demo.html))

登録済み人間可読プレフィックス

SatoshiLabsは、他の暗号通貨向けに登録された人間可読部の完全な一覧を管理している。

SLIP-0173:BIP-0173向け登録済み人間可読部 (https://github.com/satoshilabs/slips/blob/master/slip-0173.md)

付録

テストベクター

以下の文字列は有効なBech32である。

  • A12UEL5L
  • a12uel5l
  • an83characterlonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1tt5tgs
  • abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw
  • 11qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqc8247j
  • split1checkupstagehandshakeupstreamerranterredcaperred2y9e3w
  • ?1ezyfcl警告:US-ASCIIへの変換において、一部のエンコーダーはマッピングできない文字を’?‘のような有効なUS-ASCII文字に置き換えることがある。例:
>>> bech32_encode('\x80'.encode('ascii', 'replace').decode('ascii'), [])
'?1ezyfcl'

以下の文字列は有効なBech32ではない(無効である理由とともに)。

  • 0x20 + 1nwldj5:HRP文字が範囲外
  • 0x7F + 1axkwrx:HRP文字が範囲外
  • 0x80 + 1eym55h:HRP文字が範囲外
  • an84characterslonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1569pvx:全体の最大長を超過
  • pzry9x0s0muk:区切り文字がない
  • 1pzry9x0s0muk:空のHRP
  • x1b4n0q5v:無効なデータ文字
  • li1dgmt3:チェックサムが短すぎる
  • de1lg7wt + 0xFF:チェックサム内の無効な文字
  • A1G7SGD8:HRPの大文字形式でチェックサムが計算されている
  • 10a06t8:空のHRP
  • 1qzzfhee:空のHRP

以下の一覧は、有効なsegwitアドレスと、それらが変換されるscriptPubKeyを16進数で示す。

  • BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4:0014751e76e8199196d454941c45d1b3a323f1433bd6
  • tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7:00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262
  • bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx:5128751e76e8199196d454941c45d1b3a323f1433bd6751e76e8199196d454941c45d1b3a323f1433bd6
  • BC1SW50QA3JX3S:6002751e
  • bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj:5210751e76e8199196d454941c45d1b3a323
  • tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy:0020000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433

以下の一覧は、無効なsegwitアドレスとその無効である理由を示す。

  • tc1qw508d6qejxtdg4y5r3zarvary0c5xw7kg3g4ty:無効な人間可読部
  • bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5:無効なチェックサム
  • BC13W508D6QEJXTDG4Y5R3ZARVARY0C5XW7KN40WF2:無効なウィットネスバージョン
  • bc1rw5uspcuh:無効なプログラム長
  • bc10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90:無効なプログラム長
  • BC1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P:(BIP141による)ウィットネスバージョン0における無効なプログラム長
  • tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sL5k7:大文字小文字混在
  • bc1zw508d6qejxtdg4y5r3zarvaryvqyzf3du:4ビットを超えるゼロパディング
  • tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv:8→5変換における非ゼロパディング
  • bc1gmk9yu:空のデータ部

チェックサム設計

設計上の選択

BCH符号は任意の素数べき乗アルファベット上で構成でき、サイズと誤り検出能力の間で良好なトレードオフとなるよう選ぶことができる。BCH符号に関する研究の大半は二値アルファベットを用いているが、それは必須ではない。このため、CRC符号 (https://en.wikipedia.org/wiki/Cyclic_redundancy_check)よりも本用途に適している。リード・ソロモン符号 (https://en.wikipedia.org/wiki/Reed%E2%80%93Solomon_error_correction)と異なり、長さがアルファベットサイズ引く1に制限されることもない。効率的な誤り訂正にも対応可能だが、誤り検出のみの実装は非常に単純である。

アドレスの長さと誤り検出能力の間のトレードオフとして、チェックサム文字数を6文字選んでいる。これは、偶発的な失敗確率を10億分の1未満に抑えるのに十分な最小の文字数である。保護対象として関心のあるデータ長(将来の40バイトウィットネスプログラムを想定した最大71バイト)については、最大4個の誤りの検出を保証するBCH符号を構成できる。

選定された性質

これらの符号の多くは、設計時に想定した数を超える誤りを扱う際に性能が悪化するが、すべてがそうというわけではない。そのため、3個の誤りのみを検出するよう設計された符号と、4個の誤りを検出するよう設計された符号の両方を検討し、実際にどの程度うまく機能するかを分析した。

ここで選ばれた具体的な符号は、以下の手順の結果である。

  • 長さ93、151、165、341、1023、1057までの範囲で3個または4個の誤りを検出するよう設計された、159605件のBCH符号の網羅的リストから出発する。
  • そこから、長さ71までで4個の誤りの検出を必須とすることで、28825件の符号に絞り込む。
  • そこから、5文字誤りに対する最良の最悪ケースウィンドウを持つ符号を選び、310件に絞り込む。
  • そこから、少数のビット誤りを検出し損なう確率が最も低い符号を選ぶ。

素朴な探索では6.5 * 1019回を超えるチェックサム評価が必要となるため、分析には衝突探索によるアプローチが用いられた。コードはこちら (https://github.com/sipa/ezbase32/)にある。

性質

以下の表は、検出失敗の確率(10億分の1を単位とする倍数として)をまとめたものである。列はウィンドウ長(Length、Description)と誤り文字数(≤4から≥9まで)のグループに分かれる。

LengthDescription≤45678≥9
86個の誤りを検出する最長ウィンドウ0001.1270.909n/a
185個の誤りを検出する最長ウィンドウ000.9650.9290.9320.931
196個の誤りに対する最悪ケース00.0930.9720.9280.9310.931
39P2WPKHアドレスの長さ00.7560.9350.9320.9310.931
59P2WSHアドレスの長さ00.8050.9330.9310.9310.931
7140バイトプログラムアドレスの長さ00.8300.9340.9310.9310.931
894個の誤りを検出する最長ウィンドウ00.8670.9330.9310.9310.931

これは、P2WPKHアドレスの39文字のうちランダムに分布した5文字が変化した場合、それが検出されずに見過ごされる確率が10億分の0.756であることを意味する。その5つの変化が19文字のウィンドウ内でランダムに生じる場合、その確率は10億分の0.093まで下がる。誤りの数が増えるにつれ、確率は230分の1 = 10億分の0.931へ収束する。

選ばれた符号は1023文字まで妥当な性能を発揮するが、(区切り文字を除いて)89文字を超える長さについては、他の設計の方が望ましい。

謝辞

本文書は、ラスティ・ラッセルによるアドレス提案 (https://rusty.ozlabs.org/?p=578)、マーク・フリーデンバッハによるbase32 (https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2014-February/004402.html)提案に着想を得ており、ルーク・ダッシュジュニア、ジョンソン・ラウ、エリック・ロンブロゾ、ピーター・トッド、その他多くのレビュアーからの意見が反映されている。

開示事項(2024年追加)

bech32の設計上の見落としにより、このチェックサム方式は、5文字未満の連続した文字の挿入・削除 (https://gist.github.com/sipa/a9845b37c1b298a7301c33a04090b2eb)に対して常に頑健というわけではない。この弱点があるため、BIP-350は、本BIPで説明される方式をNative Segwit v0出力のみに用いることを提案している。