Develop with pleasure!

福岡でCloudとかBlockchainとか。

lndで実装されているBIP-39に代わるシード管理方式「aezeed」

lndでBIP-39*1の欠点を修正するために実装されたシードの新しい管理方式「aezeed」について↓読んでみた。

https://github.com/lightningnetwork/lnd/tree/master/aezeed

2018年3月のSF Bitcoin Devsで@roasbeefがlnd v0.4-betaの紹介した際にも触れられてる。

www.youtube.com

docs.google.com

aezeedはBIP-39の以下の欠点を修正する:

  • バージョンの欠如
    バージョン情報がない場合、ウォレットがリカバリープロセス中にどのアドレスを再導出すべきか分からない場合がある(秘密鍵や公開鍵は導出できても、そこからどのアドレス:P2PKH、P2WPKH、P2SH-P2WSHを導出すべきか決定できない)。
  • ウォレットの誕生日の欠如
    ウォレットがいつできたかという情報がない場合、ウォレットが正しいユーザーのアドレスを全て確実に導出するために、チェーン内をどこまで見ていけば良いか分からない。

簡単に言うとこれらのデータをシードデータに含め、さらに暗号化したデータからmnemonicのワードリストを生成するようBIP-39を拡張した仕様になる。

具体的な仕様は↓

プレーンテキストのaezeedエンコーディング

aezeed方式のシードは、↑の欠点に対処するため以下の3つのフィールドを結合した値になる。

1バイトの内部バージョン || 2バイトのタイムスタンプ(ウォレットの誕生日) || 16バイトのエントロピー

内部バージョンは、ウォレットがウォレットの鍵を再導出する方法を知ることができるようにするためのフィールド。

2バイトのタイムスタンプはウォレットの誕生日を管理するためのフィールド。通常タイムスタンプは4バイトのデータ領域を必要とするが、このフィールドは2バイトでタイムスタンプを表現するためBitcoin Days Genesisで表される。これはBitcoinのジェネシスブロックのタイムスタンプからの日数を意味する。このフォーマットによりスペースを節約し、無駄な粒度を使わないようにすると。現在、これは2188年までの時間を表現することができる。

最後のエントロピーは、ウォレットのHDルートを導出するのに使用される。

BIP-39ではエントロピーからmnemonicを直接生成していたのに対し、aezeedではバージョンとタイムスタンプが加わった上記データからmnemonicが作られることになる。

aezeed 暗号化/復号化

BIP-39ではエントロピーにそのチェックサムを付与したデータを11bit毎に分割してmnemonicのワードリストを作成していたが、aezeedでは上記のプレーンテキストシードを暗号化してできた暗号テキスト(CipherSeed)からmnemonicのワードリストを生成する。

暗号化して生成される最終的なデータは以下の3つのフィールドを結合した値になる。

1バイトの外部バージョン || 暗号テキスト || 8バイトのチェックサム

1つめの外部バージョンは、暗号化方式を定義したもので、2つめの暗号テキストが実際にプレーンテキストシードを暗号化したデータ、最後がチェックサムで、以下のプロセスで生成される(暗号化プロセスでは、ユーザーが定義したパスフレーズが使われる。パスフレーズが指定されていない場合は、文字列「aezeed」が使われる)。

  1. 最初に、外部バージョンをバッファに追加する。外部バージョンは使用する暗号化方法について定義する。最初のバージョン(version 0)では、暗号化にscrypt(n=32768, r=8, p=1)とaezeedを使う。
  2. 次にscrypt(n=32768, r=8, p=1)を使って、暗号化に使用する強めの鍵を生成する。saltとして5バイト使って、32バイトの鍵を生成する(saltを使うのはレインボーテーブルを作成できなくするため)。
  3. 続いて暗号化プロセス。ナンスの誤用に耐性があるモダンなAEADであるaezを使用する。ここで重要な特性は、任意の入力長のブロック暗号であること。さらに設定可能なMACサイズを持っている点で、aezeed方式では64bitのチェックサムとして機能する8を使う。生成されたシードとAD of (version || salt)を使って暗号化する。
  4. 最後にBIP-39のデフォルトのワードリストを使って、この33バイトの暗号テキストをエンコードし、24個の英単語を生成する。

こうやってプレーンテキストシード(19バイト)から暗号シード(33バイト)が生成される。

aezeed暗号シードの特性

aezeed暗号シード方式にはいくつかの特性がある。

  • mnemonic自体が暗号テキストから生成されているので、mnemonicだけ分かってもコインを盗むのは難しく、BIP-39でパスフレーズセットしていないとmnemonicが分かればコインが盗まれるのとは対照的。
  • パスフレーズを変更することで暗号シードを変更できる。ユーザーがより強力なパスフレーズを望む場合は、古いパスフレーズで復号し、次に新しいパスフレーズで暗号化することができる。BIP-39の場合、ユーザーがパスフレーズを使ったとしても、マッピングが一方向であるため、既存のHDキーチェーンのパスフレーズを変更することはできない。
  • 暗号シードをアップブレード可能。外部バージョンがあるので、オフラインツールを使って古いパラメータを復号し、新しいパラメータを使って暗号化することができる。将来暗号を変更したり、scryptを変更したり、scryptのパラメータのみを変更するば、ユーザーはオフラインツールでシードを簡単にアップグレードできる。

ウォレットの誕生日やバージョン情報の管理は、Lightningに限らずオンチェーンでも課題よね。

*1:BIP-39はHDウォレットのマスターシードを人間が覚えやすい単語リスト(mnemonic word)に変換する仕様を定義したBIP