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

Bitcoin Core v0.12の​合意検証で​libsecp256k1が​OpenSSLを​置換

定義: libsecp256k1 (10)

紺色を背景に、赤い×印で無効化された古い南京錠から、より小さく精密な六角形の錠前へと矢印でつながる図で、グリッド上の緑色の楕円曲線グラフ、速度計を模したバッジ、2015年から2016年にかけての二点式タイムラインバーが添えられている。

2016年1月15日、Bitcoin Core v0.12が合意クリティカルなECDSA署名検証の標準バックエンドとしてlibsecp256k1を採用し、OpenSSLを置き換えた。OpenSSLはサトシのオリジナルv0.1リリース以来7年間、ビットコインの依存ライブラリーであり続けていた。

背景

libsecp256k1プロジェクトは2013年3月5日、ピーター・ウィーユによって開始された。当初の動機は性能で、ウィーユはGLV手法の自己準同型によってOpenSSLの汎用楕円曲線コードを上回る速度向上が得られるか確かめたかった。1週間でライブラリーはビットコインの全ブロックチェーンを検証可能になった(当時のブロック高は約225,000)。

グレゴリー・マクスウェルが参加し、プロジェクトは性能実験から、OpenSSLのsecp256k1実装を完全に置き換えるビットコイン専用ライブラリーへと拡大していった。

OpenSSLを置換する理由

2014年までに、合意クリティカルなコードでOpenSSLを使用することの具体的な問題が複数特定されていた:

  1. 署名解析の不整合が予期せぬチェーン分裂を引き起こす可能性。OpenSSLのバージョンが異なると、同じ署名が有効か無効かで判定が割れる場合があり、全ノードが同じ結論に達する必要がある合意システムでは許容できない。
  2. 性能の明確な向上。libsecp256k1は最終的に署名検証で2.5〜5.5倍高速で、署名検証は新ブロック検証コストの大部分を占める。
  3. 監査可能性の確保。単一の曲線とビットコインが必要とする操作のみに焦点を絞ることで、ライブラリーは深く査読可能なサイズに収まり、サイドチャネル攻撃に対する定数時間実装も実現できた。

2014年11月、ウィーユはlibsecp256k1のテストを書きながらCVE-2014-3570を発見・報告した。これはOpenSSLのBN_sqr(二乗)ルーチンの重大なバグで、長年OpenSSLに潜在していた。

マクスウェルはBitcoin Magazineの記事で結論をこうまとめた。「OpenSSLはビットコインのような合意クリティカルなシステムには適さないライブラリーだ」

展開

  • Bitcoin Core v0.10(2015年2月): ウォレット署名の標準としてlibsecp256k1を採用。
  • Bitcoin Core v0.12(2016年1月15日): 合意クリティカルなECDSA署名検証の標準としてlibsecp256k1を採用。

暗号設計エントリーも、ビットコインの署名方式の変遷を扱う中でこの2段階の展開を記述している。

意義

libsecp256k1がOpenSSLを置き換えたのは、合意の署名検証だった。すべてのノードが同じ判定に達しなければチェーンが分裂する経路である。サトシのv0.1がOpenSSLを採用したのは、2008年当時としては自明な選択だった。Windows上のC++ プロジェクト向け標準暗号ライブラリーだったからだ。2016年までに、Bitcoin Core開発者たちは、合意システムにとって「自明」と「正しい」は同じではないと結論し、3年かけてビットコイン専用の置換実装を作り上げた。

コードベースが成熟するにつれて、サトシの設計選択はビットコイン固有の実装へ段階的に置き換えられていく。このパターンは、Bitcoin Coreの進化における繰り返し現れるテーマである。PR #4641(laanwj、2014)も同様で、サトシのハンガリアン記法による変数命名規則を新しいBitcoin Coreコードから体系的に削除する動きの始まりだった。

ウラジミール・ファン・デル・ラーン伝記は、v0.12でのlibsecp256k1への置換を、リードメンテナーとしての在任中にBitcoin Coreがリリースした成果の一つとして挙げる。ピーター・ウィーユ伝記はウィーユが2013年に開始したlibsecp256k1を取り上げ、グレゴリー・マクスウェル伝記はその共同開発をCoinJoinやConfidential Transactionsと並べて記す。2011年のビットコインv0.5 Crypto++ 依存除去エントリーは、同じ依存置換のより早い段階である2011年のCrypto++ からOpenSSLへの移行を扱い、2016年のv0.12でのOpenSSLからlibsecp256k1への移行につなげている。アーキテクチャー進化ページは、この移行を、ウィーユが手がけたv0.1以来の横断的設計の変化4件の一つに挙げている。