
はじめに
本ページは設計文書シリーズのL1 #6 — 暗号設計である。ビットコインのあらゆる層を支える暗号学的基本要素を扱う: 所有権を表す鍵、支出を認可する署名、ブロックとトランザクションを結合するハッシュ関数、そして単一の秘密からアドレスの木を生成する導出スキーム。
これらの概念がはじめての方は、ビットコインを持つとは、実際どういうことかが鍵・署名・レシートを事前知識ゼロで紹介している。本ページは同じ暗号学的基本要素を設計文書として扱う。
元のv0.1ソースを1行ずつたどったForensicxsによる2024年のコードウォークスルーは、全31ファイルを対象に、この層を最初の実装までさかのぼっている。Base58のアドレス符号化、secp256k1の鍵管理、SHAのハッシュは、いずれも公開時から存在した。
重要な区別がある: ビットコインは暗号学の上に構築されたシステムであり、暗号化のシステムではない。ブロックチェーンは公開されている。トランザクションは平文でブロードキャストされる。プロトコルレベルで暗号化されるメッセージはない。暗号学が代わりに提供するのは、認証(トランザクションが特定の秘密鍵の保持者によって認可されたことの証明)と完全性(データが改竄されていないことの証明)である。
唯一の例外はBIP 324(v2トランスポートプロトコル)で、受動的な監視に対抗するためにピアツーピアの通信を暗号化する。これはネットワーク層の問題であり、P2P設計ページで扱う。トランザクション層の基本要素ではない。
本ページはトランザクション設計ページに依存する。同ページでは、入力・出力・スクリプトがここで記述する暗号学的基本要素をどのように消費するかを説明している。
サトシ時代の実装(v0.1、2009年1月)と現代のBitcoin Core(v27以降を基準)で挙動が異なる箇所は、双方を記載する。
v0.1実装をたどる
ホワイトペーパーはプロトコルの設計を記す。v0.1のソースコードを読むと、各要素がプログラムのどこに入るかが分かる。CKeyはOpenSSLのEC_KEYをsecp256k1用に生成し、署名と検証をECDSA_signとECDSA_verifyに委ねている。固定コミット4184ab2のsrc/key.h 49–136行にこの経路が残る。アドレス導出も明確で、src/base58.h 117–200行のPubKeyToAddressがHash160を適用し、バージョンバイト0を前置し、4バイトのHashチェック値を加えてBase58にエンコードする。スクリプト・インタープリターにはハッシュ・オペコードとOP_CHECKSIGがあり、src/script.cpp 818–901行のSignatureHashはハッシュ種別に応じてトランザクションを書き換え、直列化した結果をハッシュする。同じ固定コミットの同じ関数を、v0.1直列化境界の分析が行単位で辿っている。
これは実装の記録であり、サトシが各境界をなぜ選んだかの証拠ではない。コードから確定できるv0.1の挙動と、設計理由の解釈は分けて扱う必要がある。
1. 楕円曲線暗号
ビットコインの所有権モデルは楕円曲線暗号(ECC)に基づく。秘密鍵はランダムな256ビット整数である。対応する公開鍵はsecp256k1曲線上の点で、秘密鍵と曲線の生成点のスカラー乗算で導出される。乗算は計算上容易だが、逆演算(公開鍵から秘密鍵を復元すること)は楕円曲線離散対数問題(ECDLP)であり、この鍵サイズでは古典的コンピューターにとって解読不能と考えられている。
鍵生成フロー
正確に言えば、秘密鍵は [1, n−1] の範囲の256ビット整数kであり、公開鍵K = k × Gはsecp256k1の生成点とのスカラー倍算である。同じ点Kは、33バイトの圧縮形式(パリティビットの接頭辞 + x座標)または65バイトの非圧縮形式(固定の接頭辞 + x座標とy座標の両方)のどちらかにシリアライズされる。
secp256k1曲線パラメーター
| パラメーター | 値 | 備考 |
|---|---|---|
| 曲線方程式 | y² = x³ + 7 (mod p) | ワイエルシュトラス短縮形; a = 0, b = 7 |
| 体の素数 (p) | 2²⁵⁶ − 2³² − 977 | 効率的な剰余演算のために選ばれた素数 |
| 群の位数 (n) | FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141 | 曲線上の点の個数; 秘密鍵は [1, n−1] の範囲 |
| 生成点 (G) | SEC 2規格で定義 | すべての鍵導出の固定基点 |
| 補因子 (h) | 1 | 群は素数位数 — 単位元以外のすべての点が生成元 |
| 鍵サイズ | 256ビット(秘密鍵) | 圧縮公開鍵: 33バイト(264ビット); 非圧縮: 65バイト(520ビット) |
| 安全性水準 | 約128ビット(古典的) | ECDLPの解読には最善の既知古典アルゴリズムで約2¹²⁸ 演算が必要 |
なぜsecp256k1か。サトシはより広く展開されていたNIST P-256(secp256r1)ではなくsecp256k1を選んだ。secp256k1のパラメーターは単純な非ランダム値から構成されており、曲線定数にバックドアが埋め込まれていないことを検証できる。NIST承認の暗号学的パラメーターに意図的な弱点が仕込まれうることがDual_EC_DRBG事件で実証されて以降、この検証可能性の重要性は増した。曲線の構造はまた自己準同型最適化による署名検証の約30% の高速化を可能にし、libsecp256k1がこれを活用している。
2. ハッシュ関数
ビットコインはプロトコル全体で複数のハッシュ構成を使用する。いずれも暗号化には使われず、すべてコミットメントまたは完全性のメカニズムとして機能する。
各ハッシュの使用箇所
| ハッシュ関数 | 出力サイズ | ビットコインでの使用箇所 |
|---|---|---|
| SHA-256(単一) | 256ビット | Hash160の内側の段。P2WSHの証人スクリプトのハッシュ (BIP 141)。OP_SHA256。BIP 340シュノア署名のチャレンジ(タグ付きハッシュ構成の内部で使われる基盤ハッシュとして) |
| SHA-256d(二重SHA-256) | 256ビット | ブロックヘッダーのハッシュ化(プルーフ・オブ・ワーク)、トランザクションID (txid)、マークルツリー全階層(葉のペアのハッシュ化からルートまで)、OP_HASH256 |
| RIPEMD-160 | 160ビット | Hash160構成でSHA-256の後に使用: RIPEMD-160(SHA-256(data))。P2PKHおよびP2WPKHアドレスの20バイトペイロードを生成、OP_HASH160 |
| SHA-512 | 512ビット | BIP 32 HD鍵導出におけるHMAC-SHA512(単一操作から子鍵とチェーンコードの両方を生成) |
| タグ付きハッシュ | 256ビット | BIP 340/341は各SHA-256入力にドメイン固有のタグを接頭辞として付加し、プロトコル間のハッシュ衝突を防止する(例: SHA-256(SHA-256("BIP0340/challenge") ‖ SHA-256("BIP0340/challenge") ‖ data)) |
ハッシュ連鎖: トランザクションからプルーフ・オブ・ワークまで
なぜ二重ハッシュか。SHA-256dはSHA-256を順に2回適用する: SHA-256(SHA-256(data))。利点としてよく挙げられるのは、長さ拡張攻撃を無効にすることである。単一パスのSHA-256は、すべてのマークル・ダムゴール型ハッシュと同様に、H(m) を知る攻撃者がmを知らずにH(m ‖ padding ‖ m') を計算できる。2回目のハッシュパスは、1回目の出力を2回目への固定長入力とすることで、この性質を破壊する。
3. 電子署名
署名は、支出者がUTXOのロックスクリプトにコミットされた公開鍵に対応する秘密鍵の管理権を証明するメカニズムである。ビットコインは2つの署名方式を使用してきた。どちらもビットコインのための新発明ではない。設計系譜の分析は、ECDSAをマークルツリーや連結タイムスタンプと並び、ホワイトペーパーが独自設計ではなく借用した計算機科学一般の構成要素として位置づけている。
署名と検証のフロー
コードで言えば、sighashはsighashフラグが選ぶフィールドだけのハッシュであり、トランザクション全体のハッシュではない。公開鍵Kの出所はスクリプトタイプによって異なる。P2PKH/P2WPKHではwitnessまたはscriptSig、Taprootのkey-path spendではロックスクリプト自体だ。それでも検証ノードのVerify(K, sighash, σ) の呼び出しは、常に厳密なtrue/falseを返す。部分的・暫定的な有効性というものは存在しない。
ECDSA対シュノア
| 特性 | ECDSA(v0.1、2009年) | シュノア(BIP 340、Taproot 2021年) |
|---|---|---|
| 署名サイズ | 70〜72バイト(DERエンコード、可変長) | 64バイト(固定長) |
| エンコード | DER(可変長ASN.1) | 固定64バイト (R‖s) |
| 検証方程式 | 署名ごとに1つ | 署名ごとに1つ; ネイティブにバッチ検証可能 |
| 鍵集約 | ネイティブ非対応; 複雑な多段プロトコルが必要 | MuSig2: n-of-n参加者が単独支出と区別不能な1つの64バイト署名を生成 |
| 線形性 | 非線形 — 署名要素が単純には加算できない | 線形 — s₁ + s₂ が合成公開鍵に対する有効な署名を生成 |
| 証明可能な安全性 | 汎用群モデルまたは追加の仮定が必要 | ランダムオラクルモデルにおける離散対数仮定の下で証明可能な安全性 |
| 改竄可能性 | 署名の改竄が可能(第三者が同じメッセージに対して異なる有効な署名を生成可能) | 構成上改竄不能 |
| sighash方式 | レガシーsighash(大規模トランザクションでは二乗的ハッシュ計算) | BIP 341 sighash(線形、エポックタグ付き) |
| 暗号ライブラリー | OpenSSL(合意検証はv0.11まで); libsecp256k1(ウォレット署名はv0.10以降、合意検証はv0.12以降) | libsecp256k1シュノアモジュール |
| スクリプトコンテキスト | OP_CHECKSIG、OP_CHECKMULTISIG | OP_CHECKSIG(tapscript版)、OP_CHECKSIGADD |
OpenSSLからの離脱。サトシのv0.1でOpenSSLに依存していたのは、ECDSA署名、ECDSA検証、乱数生成、そしてHash()/Hash160() 内のSHA-256d、RIPEMD-160計算である。ただし採掘のホットパスは例外で、main.cppのBlockSHA256() はOpenSSLを介さず、同梱のCrypto++ 実装(ウェイ・ダイのsha.cpp/sha.h)を高速化のために直接呼び出していた。このCrypto++ 依存自体、ビットコインv0.5.0で除去され(2011年11月)、採掘のハッシュ経路は一旦OpenSSLに移った後、2014年にピーター・ウィーユのインツリー実装が今度はOpenSSLのSHA-256を置き換えた。
libsecp256k1は、定時間演算によるサイドチャネル耐性、決定性ナンス生成(RFC 6979)、大幅に高速なバッチ検証を備えた専用ライブラリーである。Bitcoin Coreがこれへ移行したのは2段階に分かれる(専用エントリーで詳述): v0.10(2015年2月)でウォレット署名の標準となったが、合意クリティカルなECDSA検証はOpenSSLのまま残り、v0.12(2016年1月)になって初めて標準となった。OpenSSLバージョン間のDER署名解析の差異に起因する合意形成バグのクラスを実際に排除したのはこのv0.12の変更であり、それまでの間はBIP 66の厳密DERソフトフォークが応急処置として機能していた。
4. アドレス導出
ビットコインアドレスは、ロックスクリプトのペイロードを人間が読める形式にエンコードしたものである。ブロックチェーンには保存されず、ネットワークは生のscriptPubKeyバイトで動作する。アドレスはエラー検出の追加とスクリプトタイプの識別を行うユーザーインターフェース上の利便機能である。
アドレス導出パイプライン
バイト単位で言えば、Hash160の中身はRIPEMD-160(SHA-256(pubkey))で20バイト。Taproot経路はコミットされたスクリプトのマークルルートで内部鍵を鍵調整してから32バイトのx-onlyキーに落とし込む。Base58Checkはバージョンバイトを前置しチェックサムを追加するのに対し、Bech32/Bech32mはwitnessバージョンを前置しBCHコードのチェックサムを追加する。
アドレス形式の比較
| 形式 | 接頭辞 | 導入時期 | エンコード | エラー検出 | ロックスクリプト | 典型的なサイズ |
|---|---|---|---|---|---|---|
| P2PKH | 1 | v0.1(2009年) | Base58Check | 4バイトSHA-256dチェックサム | OP_DUP OP_HASH160 <20-byte hash> OP_EQUALVERIFY OP_CHECKSIG | 26〜34文字 |
| P2SH | 3 | BIP 16(2012年) | Base58Check | 4バイトSHA-256dチェックサム | OP_HASH160 <20-byte hash> OP_EQUAL | 34文字 |
| P2WPKH | bc1q | BIP 141/173(2017年) | Bech32 | 6文字BCHコード | Witness v0 + 20バイト鍵ハッシュ | 42文字 |
| P2WSH | bc1q | BIP 141/173(2017年) | Bech32 | 6文字BCHコード | Witness v0 + 32バイトスクリプトハッシュ | 62文字 |
| P2TR | bc1p | BIP 341/350(2021年) | Bech32m | 6文字BCHコード(修正定数) | Witness v1 + 32バイトxのみの鍵 | 62文字 |
Base58Check → Bech32 → Bech32m。Base58Checkは視覚的に紛らわしい文字(0、O、I、l)を除外した文字セットを使用し、4バイトのチェックサムを含む。Bech32(BIP 173)はQRコード向けに最適化された小文字のみの英数字セットに切り替え、チェックサムを最大4つのエラーを検出し、より長いエラーバーストも確実に検出できるBCH誤り訂正符号に置き換えた。Bech32m(BIP 350)はBech32で発見された長さ変異の脆弱性をチェックサム定数の変更で修正し、witnessバージョン1以上(Taprootのv1から開始)のすべてに使用される。
5. HDウォレット
初期のビットコインウォレットは鍵を独立に生成しており、各鍵は他のどの鍵とも構造的関係のない新規乱数だった。新しい鍵が生成される前に取得されたバックアップを紛失すると、その鍵の資金が永久に失われることを意味した。
BIP 32(2012年)は階層的決定性(HD)導出を導入した: 単一のマスター秘密から鍵の木全体を生成し、1つのバックアップからすべてを復元できる。
HD導出ツリー
BIP 32 / 39 / 44の役割
| BIP | 年 | 役割 | メカニズム |
|---|---|---|---|
| BIP 32 | 2012年 | 階層的決定性鍵導出 | 数学を定義: HMAC-SHA512で親鍵 + チェーンコードから子鍵を導出。強化導出(子から親を復元不能)と通常導出(拡張公開鍵からの監視専用ウォレットが可能)をサポート。 |
| BIP 39 | 2013年 | ニーモニックシードフレーズ | 初期エントロピーを12〜24の英単語としてエンコード。サードパーティーウォレットで広く採用。Bitcoin CoreはネイティブにBIP 39を使用しない。BIP 32を介して生のエントロピーから鍵を導出する。エコシステムの慣行が広く浸透しているためここに記載。 |
| BIP 44 | 2014年 | マルチアカウント構造 | 導出パスを標準化: m / purpose' / coin_type' / account' / change / address_index。purpose 44 = P2PKH。 |
| BIP 49 | 2016年 | P2SHラップSegWitパス | purpose 49 = P2SH-P2WPKH(3で始まる後方互換SegWitアドレス)。 |
| BIP 84 | 2017年 | ネイティブSegWitパス | purpose 84 = P2WPKH(bc1qで始まるBech32アドレス)。 |
| BIP 86 | 2021年 | Taprootパス | purpose 86 = P2TR(bc1pで始まるBech32mアドレス)。 |
記述子ウォレット(v27以降基準)。現代のBitcoin Coreは暗黙的なBIP 44/49/84/86導出規約を出力記述子(BIP 380以降)で置き換える: ウォレットがアドレスをどう導出し、ロックスクリプトをどう構築するかを完全に指定する明示的で合成可能な式である。wpkh([fingerprint/84'/0'/0']xpub.../0/*) のような記述子には曖昧さがなく、スクリプトタイプ、鍵の起源、導出範囲を単一の文字列で宣言する。これにより、BIP 39/44時代を悩ませた「このウォレットはどのBIPパスを使っているのか?」という曖昧さが解消される。
6. 量子脅威への考慮
ビットコインの署名セキュリティは、ECDSAもシュノアも、すべて楕円曲線離散対数問題の困難性に依拠している。ショアのアルゴリズムを実行する十分に大規模な量子コンピューターはこの仮定を破り、攻撃者が公開鍵から秘密鍵を導出することを可能にする。脅威、タイムライン、提案されている移行パスは量子脅威分析で詳述されている。
リスクのある領域とない領域:
| 基本要素 | 量子攻撃 | ビットコインへの影響 |
|---|---|---|
| ECDSA / シュノア (secp256k1) | ショアのアルゴリズムがECDLPを多項式時間で解く | 暗号学的に有意な量子コンピューターを持つ攻撃者は、露出した公開鍵から秘密鍵を導出し、関連する資金を支出できる |
| SHA-256(プルーフ・オブ・ワーク) | グローバーのアルゴリズムが二次的高速化を提供(2²⁵⁶ → 2¹²⁸ の実効原像耐性) | 128ビットの原像耐性はセキュリティ閾値を十分に上回る; プルーフ・オブ・ワークは破られない |
| RIPEMD-160 / Hash160(アドレス) | グローバーが原像耐性を2¹⁶⁰ から2⁸⁰ に低下させる | 公開鍵ハッシュが未露出の資金(未使用のP2PKH/P2WPKH)はハッシュで保護されており、ECDLPではない。ハッシュが第二の障壁を提供するが、2⁸⁰ 演算は長期的な安全マージンを下回る |
| HD導出(BIP 32) | HMAC-SHA512は共通鍵構成を使用 | グローバーが実効安全性を半減させるが、256ビットの鍵空間は2¹²⁸ のまま — 実用的な脅威はない |
7. 二つの時代の比較
| 機能 | サトシ時代(v0.1、2009年1月) | 現代のBitcoin Core、v27以降基準 |
|---|---|---|
| 曲線 | secp256k1 | 同一 |
| 鍵形式 | 非圧縮公開鍵(65バイト)が標準 | 圧縮(33バイト)が標準; Taprootはxのみ(32バイト)を使用 |
| 署名方式 | ECDSAのみ | ECDSA(レガシー / SegWit v0)+ シュノア(Taproot、BIP 340) |
| 署名エンコード | DER(可変、70〜72バイト) | ECDSAにDER; シュノアに固定64バイト |
| 署名改竄可能性 | 可能 — 第三者がs値を変更可能 | Low-S規則(BIP 146)でECDSAを制限; シュノアは設計上改竄不能 |
| 鍵集約 | 利用不可 | MuSig2(n-of-nシュノア集約で1鍵 + 1署名に統合) |
| 暗号ライブラリー | OpenSSL | libsecp256k1(定時間、決定性ナンス、正式レビュー済み) |
| ナンス生成 | OpenSSLの擬似乱数生成器 | RFC 6979決定性ナンス(ECDSA); BIP 340合成ナンス(シュノア) |
| ハッシュ関数 | Hash()/Hash160() のSHA-256d、RIPEMD-160はOpenSSL経由; 採掘のブロックハッシュSHA-256は同梱のCrypto++(ウェイ・ダイ実装) | 同一のアルゴリズム; ハードウェアアクセラレーション(SHA-NI、ARMv8-A)付き内部実装 |
| アドレス形式 | Base58Check(P2PKH: 1...) | Base58Check(レガシー)、Bech32(P2WPKH/P2WSH: bc1q...)、Bech32m(P2TR: bc1p...) |
| 鍵管理 | 独立したランダム鍵(非決定性); 100鍵の予備はv0.3.14から | HD導出(BIP 32/44/84/86); 記述子ウォレット(BIP 380以降)。CoreはBIP 39ではなく生のBIP 32シードを使用 |
| バックアップモデル | wallet.datのエクスポート; 新しい鍵には新しいバックアップが必要 | 記述子バックアップがすべての導出鍵をカバー(Bitcoin CoreはBIP 39ニーモニックではなく生のBIP 32シードを使用) |
| sighashアルゴリズム | レガシーsighash(入力数に対して二乗的) | BIP 143 sighash(SegWit v0、線形)+ BIP 341 sighash(Taproot、エポックタグ付き) |
8. 本ページの範囲
本ページはビットコインの暗号学的基本要素を単独で扱う。以下のトピックは範囲外であり、設計文書シリーズ内のそれぞれの専門ページで扱う:
- スクリプト評価: ロックスクリプトとアンロックスクリプトが実行時に署名とハッシュをどう消費するか。トランザクション設計ページで扱う。
- プルーフ・オブ・ワークマイニング: SHA-256dがブロックヘッダーのハッシュパズルでどう使われ、難易度がどう調整されるか。合意形成設計ページで扱う。
- マークルツリー構築: トランザクションハッシュがブロックヘッダーのコミットメントにどう組み立てられるか。ブロックとチェーン設計ページで扱う。
- BIP 324暗号化トランスポート: ノード間通信を暗号化するv2 P2Pプロトコル。トランザクション層の基本要素ではなく、ネットワーク層の問題。P2P設計ページ §7で扱う。
- 量子移行提案: BIP 360(P2MR / QuBit)および耐量子署名候補。量子脅威分析で扱う。
- 閾値署名とマルチシグ方式: FROST、MuSig2プロトコルの詳細、この基本要素概説の範囲を超えるk-of-n構成。
ここに並ぶ基本要素は、セキュリティモデルが脅威モデルを組み立てる土台であり、トランザクション設計のあらゆるトランザクションが消費するものでもある。



























