
ビットコインのセキュリティ脆弱性:タイムワープ攻撃
TechFlow厳選深潮セレクト

ビットコインのセキュリティ脆弱性:タイムワープ攻撃
本稿では、ビットコインのセキュリティ上の脆弱性である「タイムワープ攻撃」について分析する。
執筆:BitMEX Research

概要
2025年3月26日、ビットコイン開発者のAntoine Poinsotが新たなビットコイン改善提案(BIP)を公開した。これは「大規模コンセンサスクリーンアップ」と呼ばれるソフトフォーク提案であり、長年にわたりビットコインプロトコルに存在するいくつかの脆弱性やバグを修正するものである。そのうちの一つは、最近議論されたトランザクションの重複問題である。もう一つより深刻な脆弱性は「タイムワープ攻撃」と呼ばれるもので、それが本稿の主題である。
ビットコインブロックタイムスタンプ保護ルール
タイムワープ攻撃について議論する前に、現行の時間操作防止ルールを確認しよう。
中央値過去時間(MPT)ルール ― タイムスタンプは直近11ブロックの中央値時間よりも後でなければならない。
未来ブロック時間ルール ― MAX_FUTURE_BLOCK_TIME定数に基づき、タイムスタンプはノードピアの中央値時刻から2時間以上先に設定できない。また、ノードの提供する時刻とローカルシステム時計の間には最大90分のずれが許容されるが、これも別途のセーフガードである。
MPTルールはブロックが過去に遡りすぎないよう保証し、未来ブロックルールは未来へ進みすぎることを防ぐ。未来のようなルールを過去方向に適用してタイムスタンプが古すぎるのを防ぐことはできないことに注意が必要だ。なぜなら、それは初期のブロックチェーン同期に影響を与える可能性があるためである。タイムワープ攻撃では、意図的に非常に古いタイムスタンプを偽造することで行われる。
中本聪の「オフバイワン」エラー
ビットコインでは、難易度調整周期は2016ブロックで構成され、10分間隔の目標に基づくと約2週間となる。マイニング難易度の調整計算において、プロトコルは対象となる2016ブロックウィンドウ内の最初と最後のブロック間のタイムスタンプ差を使用する。この2016ブロックのウィンドウには、実際には2015の区間(つまり2016-1)しか存在しない。したがって、関連する目標時間は60秒×10分×2015=1,209,000秒とするべきである。しかし、ビットコインプロトコルは2016という数字を使用しており、60秒×10分×2016=1,209,600秒としている。これは「オフバイワン(1ずれた)」エラーである。これは犯しやすいミスであり、中本聪はブロックとブロックの間の「区間」とブロック自体を混同したように見える。
オリジナルの中本聪コード

出典:https://sourceforge.net/p/bitcoin/code/1/tree//trunk/main.cpp#l687
このエラーにより、目標時間が本来より0.05%長くなっている。つまり、ビットコインの目標間隔は実際には10分ではなく、10分0.3秒となっている。このバグ自体は重要ではない。実際、ビットコイン導入以来、平均間隔は9分36秒であり、10分を明らかに下回っている。これは2009年以降、平均的なハッシュレートが継続的に増加してきたためである。そのため、最終的な半減期は2025年1月ではなく2024年4月に到来した。我々は予定を前倒ししているのだ。いずれにせよ、中本聪のこの0.3秒のエラーは全体としては無視できるほど小さい。あるいは遠い将来、価格とハッシュレートの成長が止まったとき、このバグがむしろスケジュールを元に戻す役割を果たすかもしれない。

この0.3秒のバグ自体は重大ではないが、それに関連してより深刻な問題が存在する。難易度計算は各2016ブロックウィンドウの最初と最後のブロックに基づいているが、これも誤りである。我々の見解では、適切な期間は「前の2016ブロックウィンドウの最終ブロック」と「現在のウィンドウの最終ブロック」の間の差分であるべきだ。異なる調整ウィンドウを跨ぐ時間幅をカバーすることが重要であり、これが最も合理的な方法と考えられる。そうすれば、2016という数値も目標計算における正しい区間数となる。おそらく中本聪がこのミスを犯したのは、初回の難易度調整周期を考慮しなければならず、その際には「前の周期の最終ブロック」が利用できなかったためだろう。
タイムワープ攻撃
ビットコインのタイムワープ攻撃は約2011年に初めて発見され、中本聪の難易度計算におけるエラーを悪用するものである。この攻撃を実行するには、マイニングが100%中央集権的であり、マイナーがプロトコルが許可する限り任意のタイムスタンプを設定できると仮定する。攻撃では、ほぼすべてのブロックについて、マイナーは前のブロックから1秒だけ進んだタイムスタンプを設定する。これにより、ブロックチェーンは時間的に前進し、MTPルールを遵守する。時間をできるだけ遅く進めたい場合、マイナーは6つのブロックにわたって同じタイムスタンプを維持し、次のブロックで1秒進める、といった動作を繰り返す。つまり、ブロックタイムスタンプは6ブロックごとに1秒ずつ進むことになる。
この攻撃により、ブロックチェーンは現実時間に対してますます遅れていく。その結果、難易度は上昇し、マイニングはますます困難になる。しかし、攻撃効果を高めるために、各難易度調整周期の最終ブロックでは、マイナーは現実世界の時刻をタイムスタンプとして設定する。次に、各難易度調整ウィンドウの最初のブロックでは、前の難易度調整ウィンドウの最後から2番目のブロックよりも1秒だけ早いタイムスタンプに「戻す」。これは依然としてMTPルールに違反しない。なぜなら、このような異常は11ブロックの中央値に影響を与えないためである。
こうした攻撃が行われると、最初の周期後の難易度には変化がない。しかし、攻撃開始後の2回目の調整周期では、難易度が下方調整される。その後、マイナーは極めて高速にブロックを作成でき、大量のビットコインを生成して売却・利益を得ることが可能になる。
簡略化された説明
難易度周期が2016ブロックあるため、この攻撃を図で示すのは難しい。そこで、以下のシナリオを用いてこの攻撃を説明する。
-
各難易度調整ウィンドウは5ブロック
-
目標間隔は10分
-
MTPルールは直近3ブロックに基づく
-
各ブロックのタイムスタンプは毎回1分進めるが、各周期の最終ブロックのみ現実のタイムスタンプを使用
タイムワープ攻撃の概念図

上図には2つの曲線がある:
-
各難易度調整ウィンドウの最終ブロックにおける現実時間の曲線。マイナーがブロックをより速く見つけ始めるにつれて難易度が低下し、この曲線の傾きは緩やかになっていく
-
他のブロックの操作されたタイムスタンプを表す直線
ビットコインのタイムワープ攻撃計算
下表は、マイナーがこの攻撃を極限まで活用して難易度を下方操作する方法を示している。

注:プロトコルが許可する周期ごとの最大難易度調整は4倍であるが、上記の表ではその上限に達していない
各周期での難易度の下方調整は、漸近的に2.8倍をわずかに超える程度に収束する。これは、各周期が時間的に短くなるにつれ、難易度調整の減速率が低下するためである。
上表の第11周期、つまり攻撃開始後39日目には、1秒あたり6ブロック以上が生成され、正確には1秒あたり10.9ブロックとなる。この時点で、ブロックに割り当てられたタイムスタンプの制限が別の形で作用する。MTPルールによれば、時間は6ブロックごとに最低1秒は前進しなければならない。したがって、この時点からは、私たちの理解では、タイムスタンプが現実時間よりも速く進み始め、ブロックチェーンの時計が現実時間に近づきつつも、依然として大きく遅れている状態となる。それでも攻撃は継続可能であり、難易度は許容最小値に達するまで不断に低下し続ける。
攻撃の実行可能性
理論的にはこの攻撃は破壊的だが、実際に実行するにはいくつかの課題がある。この攻撃を実行するには、大部分のハッシュパワーを必要とするだろう。誠実なマイナーが正しいタイムスタンプを挿入していれば、攻撃はさらに困難になる。MTPルールと誠実なマイナーのタイムスタンプによって、悪意のあるマイナーがタイムスタンプをどれだけ過去に遡れるかが制限される可能性がある。また、誠実なマイナーが難易度調整ウィンドウの最初のブロックを生成してしまえば、その周期の攻撃は失敗する。さらに、この攻撃は誰にでも可視化可能なため、緩和要因ともなる。誰もがタイムスタンプを見ることができ、難易度が下方調整される前に約4週間にわたるタイムスタンプ操作が行われているのが分かるため、緊急のソフトフォークによる修正を準備する時間的余裕が生まれる可能性がある。
解決策
この脆弱性を修正することは比較的簡単であるが、ソフトフォークによるプロトコル変更が必要になるかもしれない。差一エラーを完全に修正しつつ、異なる2016ブロックウィンドウ間の時間スパンに基づいて難易度調整アルゴリズムを変更する方法は直接的だが、非常に複雑になり得る。また、これはハードフォークを伴う可能性もある。別の修正案として、MTPルールを廃止し、各ブロックで常に時間が前進することを要求する方法がある。しかし、これにより時間が極端に先に進んでしまう可能性があり、また別のマイナーの時計が数秒進んでいるだけで、正当な時刻を使用しているマイナーが無効なタイムスタンプを持つリスクが生じる。
幸運にも、より簡単な解決策が存在する。タイムワープ攻撃を防ぐには、新しい難易度周期の最初のブロックのタイムスタンプが、前の周期の最終ブロックから一定の分数以上遡らないようにするだけでよい。この新ルールにおける猶予時間(分)については既に議論されており、10分から2時間までの提案がある。タイムワープ攻撃の緩和という観点では、どちらも機能する可能性がある。
Poinsotの「大規模コンセンサスクリーンアップ」提案では、この猶予時間を2時間に設定している。2時間は難易度調整周期の目標時間の約0.6%に過ぎないため、難易度を下方に操作する能力は厳しく制限される。以下に、どの猶予時間を使用すべきかに関する議論をまとめた表を示す。

TechFlow公式コミュニティへようこそ
Telegram購読グループ:https://t.me/TechFlowDaily
Twitter公式アカウント:https://x.com/TechFlowPost
Twitter英語アカウント:https://x.com/BlockFlow_News














