2019年6月8日から9日にかけて、アムステルダムで Breaking Bitcoin というカンファレンスが行われました。 本コラムは、公開された動画や書きおこしをもとに、その発表内容を追いかけ、Bitcoin のセキュリティに関する取り組みの最先端を知ろうという試みです。 発表内容を日本語で、かつ実際の事例などを交えて解説することで、少しでも皆様が Bitcoin の仕組みや最新の研究について詳しくなるための一助になれることを願います。 今回で最終回となりますが、Joost Jager氏の発表についてです。前後編となります。

ライトニングネットワークのユースケース

QRコードをスキャンして支払いを確認する、理想的なモバイルアプリを考えましょう。多少の遅延は許されますが、基本的には数秒で支払いが完了してほしいでしょう。 この支払いの遅延について、もう少し考えてみます。この遅延には、ノードとクライアントのネットワーク接続の速度、そしてネットワークパスの長さが大きく関わってきます。 では、クライアントで処理が終わらず、1分後にタイムアウトしてしまったとしましょう。裏側では1分間待つだけではなく、何度かリトライを行っていることでしょう。しかしタイムアウトしたということは、接続ができなかった等の何らかの理由のため、支払いが完了しなかったことを意味します。 もちろんパス上のノードで意図しない問題が発生している可能性もありますが、悪意を持ったノードが遅延させたり拒否したりといった可能性もあります。

支払いが失敗するのであれば、お金は戻ってくるのでまだ良いでしょう。ただしノードによる決済が大きく遅延しているだけの場合、ユーザーは再度支払いを行ってしまうかもしれません。しかし、決済通知が数日経ってから届く可能性もあります。 別のネットワークパスを使えば遅延せずに支払えるかもしれませんが、ライトニングネットワーク上では任意の遅延を発生させることができる可能性があるのです。

もちろん防衛策も検討されています。最低コストのルートを探し、支払いを試みる手順に沿って説明しましょう。 まず、支払いが成功した場合ですが、これは説明の必要はありませんので割愛します。 障害が発生した場合ですが、このときには詳しい情報を集め、ノードの評価を管理するシステムに送ります。このシステムは集中化されておらず、個々のライトニングノードで持っているものと考えてください。 この評価情報は、次にネットワークパスを見つける際にフィードバックとして反映されます。つまり、以前の状態や結果を使ってパスを決めるということです。 毎回評価を行う仕組みがあれば、個々のノードには自身の評価を高めるインセンティブがはたらく上、不良ノードを回避したり、迅速に支払いを決済できる可能性が高まります。加えて、信頼できるとわかっているノードをホワイトリストとして扱うことで、最適なルーティングを選択できるでしょう。

評価システムとノードの手数料

評価システムについて、もう少し詳しく見ていきます。今回も支払いに失敗したケースを考えます。 まず、支払いに失敗したノードを正確に特定する必要があります。評価情報を正確にフィードバックするために必要な、重要な情報です。 しかし、遅延を引き起こしているのが中間ノードなのか、受信ノードなのか、区別することは困難です。送信者が分かるのは、いつ送信をしたのか、いつ結果を受け取ったのか、という程度ですので、途中の情報はわからないということです。

障害原因の特定のためには、支払いに失敗したノードから返される、玉ねぎの層のように何重にも梱包された情報を紐解く必要があります。 チャンネルには残高が必要ですが、支払いには不十分というケースもあります。これはチャンネルにおける一時的な障害です。 結果は暗号化され、ネットワークパス上の各ホップで毎回暗号化されます。元のユーザーだけがすべての情報を復元でき、特定のユーザーに対しチャンネルの残高が足りないということを指摘することができます。このときはペナルティを与える、パス上で回避するといった対応が必要でしょう。

しかし、必ずしも単純な対応が良いわけではありません。エラーが “fee_insufficient” の場合、ノードは十分な手数料を受け取っていないことを意味します。 ライトニングネットワークでは、すべてのノードが支払いを処理するために手数料を請求します。これはライトニングネットワークの基礎部分で、ノードは手数料を公開しています。 一部のノードで手数料がかかりすぎた場合、残りのノードに手数料が残らないという可能性があります。この場合は手数料が高いノードが問題という見方もできますし、そもそも十分な手数料が設定されていないという可能性もあります。

他の問題

エラーが “invalid_onion” の場合、情報の転送に失敗しており、送信者にエラーメッセージを送り返すための鍵が無いという意味です。この場合は鍵が無いので、中間ノードがエラーメッセージに自分で署名を行います。 この種の問題は、情報を送信した最初のノードか、エラーを返したノード、どちらかに問題が発生していると考えるのが妥当です。

“final_expiry_too_soon” というエラーもあります。ライトニングネットワークでは HTLC が転送され、異なるタイムロックを持たなくてはなりません。最終ノードで必要なタイムロックは 10 です。 つまり、有効期限が切れるよりも前に 10 以上のブロックがブロックチェーン上に残っていなければなりません。途中で遅延した場合、どのノードが原因で遅延したのかはわからないので、エラーメッセージ以外からも調査が必要になるでしょう。

その他、エラーが不明なケースもありえます。障害が発生したノードがでたらめな情報を送り返してきた場合、当然ですがエラーの原因はわかりません。 まとめると、以下のようになります。

  • 悪意をもったノードは、送信者に原因を気づかせず、遅延やエラーを引き起こすことができます
  • ノードは、利益を最適化するために、エラーを隠匿してペナルティを最小限に抑える可能性があります
  • 多くのエラーメッセージ、変数が提供されています

手数料不足のエラーメッセージは、障害やペナルティが複数のノードに影響します。賢いノードは、こういった問題を広く共有しようとするでしょう。ただ実際には、ペナルティを最小限に抑えるためエラーメッセージを変えてしまう可能性もあります。

前編のおわりに

ライトニングネットワーク上のセキュリティについて、次回後編では評価システムの詳細等について触れていきます。

記事中の表現については講演資料を筆者なりに読み解きつつ、前後で独自の解説を加えておりますが、なにぶん新しい技術に関する内容ですので、もしも間違いなどございましたらお気軽にご指摘くださいませ。(特に技術的な指摘は大歓迎です)

【寄稿者情報】

坪 和樹

クラウド業界で働くエンジニア、アイルランド在住。 MtGox や The DAO では被害を受けたが、ブロックチェーンのセキュリティに興味を持ち続けている。セキュリティカンファレンスでの講演、OWASP Japan の運営協力や Mini Hardening といったイベント立ち上げなど、コミュニティ活動も実績あり。
おすすめの記事