[LN#002] Noise Protocol

BOLTは、ノード間でメッセージ交換する。

まず、相手ノードとのネゴシエーションを行い、成功したらその相手とBOLTのメッセージを符号化して通信する。
BOLT#8では、ネゴシエーションの方法と、その後のメッセージ符号化/復号化について説明している。
このBOLT#8だけは、他の章からほぼ独立している。


https://github.com/lightningnetwork/lightning-rfc/blob/master/08-transport.md

ネゴシエーションや符号化の仕方は、Noise Protocolという方式を用いている。
Noise Protocol自体はいくつかパラメータがあり、そのうちBOLTで使用するものだけ#8に記載されている。
シーケンスを以下の図に示す。

 

ここでは、AがBに対して接続を要求するようになっている。
相手ノードとはIPアドレスなどでTCP接続を行った後、相手をnode_id(Bitcoinの公開鍵と同じ計算で求めた33バイトのデータ)で指定してネゴシエーションを行う。
1.5往復して相手のノードに間違いが無ければ、ネゴシエーションが完了する。


それ以降は、ネゴシエーション時に交換した鍵情報で、BOLTのメッセージを符号化/復号化を行う。
メッセージ構造は、以下に記載されている。

https://github.com/lightningnetwork/lightning-rfc/blob/master/08-transport.md#lightning-message-specification

 

大きく「メッセージ長」と「メッセージ本体」に分かれる。
メッセージ長はChaChaPoly-1305で符号化+MAC付加する(2+16byte)。
メッセージ本体も同様にChaChaPoly-1305で符号化+MAC付加する(メッセージ長+16byte)。
その両者を結合して、1つのメッセージとして相手に送信する。
受信はその逆の動作を行って復号化する。

 

符号化/復号化の鍵はネゴシエーション時のものを使い続けるのではなく、1000回符号化/復号化するたびにrotation処理を行い、鍵を変更する。
1回の送信で2回の符号化を行うため、500回のメッセージ送信でrotation処理を行うことになる。
https://github.com/lightningnetwork/lightning-rfc/blob/master/08-transport.md#lightning-message-key-rotation

 

参照

https://github.com/nayutaco/ptarmigan/blob/development/ucoin/src/ln/ln_enc_auth.c