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

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 へ変換する際に特に注意を払う必要がある。ここでウィットネスバージョンnOP_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 進数で示す。

  • BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T40014751e76e8199196d454941c45d1b3a323f1433bd6
  • tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k700201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262
  • bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx5128751e76e8199196d454941c45d1b3a323f1433bd6751e76e8199196d454941c45d1b3a323f1433bd6
  • BC1SW50QA3JX3S6002751e
  • bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj5210751e76e8199196d454941c45d1b3a323
  • tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy0020000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433

以下の一覧は、無効な 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 出力のみに用いることを提案している。