@@ -6,8 +6,9 @@ use bitcoin::secp256k1::{SecretKey, PublicKey};
6
6
7
7
use ln:: peers:: { chacha, hkdf} ;
8
8
use ln:: peers:: conduit:: { Conduit , SymmetricKey } ;
9
- use ln:: peers:: handshake:: acts:: { Act , ActBuilder , EMPTY_ACT_ONE , EMPTY_ACT_TWO , EMPTY_ACT_THREE } ;
9
+ use ln:: peers:: handshake:: acts:: { Act , ActBuilder , ACT_ONE_LENGTH , ACT_TWO_LENGTH , ACT_THREE_LENGTH , EMPTY_ACT_ONE , EMPTY_ACT_TWO , EMPTY_ACT_THREE } ;
10
10
11
+ // Alias type to help differentiate between temporary key and chaining key when passing bytes around
11
12
type ChainingKey = [ u8 ; 32 ] ;
12
13
13
14
// Generate a SHA-256 hash from one or more elements concatenated together
@@ -30,7 +31,8 @@ pub(super) enum HandshakeState {
30
31
}
31
32
32
33
// Trait for all individual states to implement that ensure HandshakeState::next() can
33
- // delegate to a common function signature.
34
+ // delegate to a common function signature. May transition to the same state in the event there are
35
+ // not yet enough bytes to move forward with the handshake.
34
36
pub ( super ) trait IHandshakeState {
35
37
fn next ( self , input : & [ u8 ] ) -> Result < ( Option < Act > , HandshakeState ) , String > ;
36
38
}
@@ -101,7 +103,7 @@ pub(super) struct ResponderAwaitingActThreeState {
101
103
impl InitiatorStartingState {
102
104
pub ( crate ) fn new ( initiator_static_private_key : SecretKey , initiator_ephemeral_private_key : SecretKey , responder_static_public_key : PublicKey ) -> Self {
103
105
let initiator_static_public_key = private_key_to_public_key ( & initiator_static_private_key) ;
104
- let ( hash, chaining_key) = handshake_state_initialization ( & responder_static_public_key) ;
106
+ let ( hash, chaining_key) = initialize_handshake_state ( & responder_static_public_key) ;
105
107
let initiator_ephemeral_public_key = private_key_to_public_key ( & initiator_ephemeral_private_key) ;
106
108
InitiatorStartingState {
107
109
initiator_static_private_key,
@@ -160,7 +162,7 @@ impl IHandshakeState for InitiatorStartingState {
160
162
impl ResponderAwaitingActOneState {
161
163
pub ( crate ) fn new ( responder_static_private_key : SecretKey , responder_ephemeral_private_key : SecretKey ) -> Self {
162
164
let responder_static_public_key = private_key_to_public_key ( & responder_static_private_key) ;
163
- let ( hash, chaining_key) = handshake_state_initialization ( & responder_static_public_key) ;
165
+ let ( hash, chaining_key) = initialize_handshake_state ( & responder_static_public_key) ;
164
166
let responder_ephemeral_public_key = private_key_to_public_key ( & responder_ephemeral_private_key) ;
165
167
166
168
ResponderAwaitingActOneState {
@@ -181,7 +183,7 @@ impl IHandshakeState for ResponderAwaitingActOneState {
181
183
let mut act_one_builder = self . act_one_builder ;
182
184
let remaining = act_one_builder. fill ( input) ;
183
185
184
- // Any payload larger than ACT_ONE_TWO_LENGTH indicates a bad peer since initiator data
186
+ // Any payload larger than ACT_ONE_LENGTH indicates a bad peer since initiator data
185
187
// is required to generate act3 (so it can't come before we transition)
186
188
if remaining. len ( ) != 0 {
187
189
return Err ( "Act One too large" . to_string ( ) ) ;
@@ -247,7 +249,7 @@ impl IHandshakeState for InitiatorAwaitingActTwoState {
247
249
let mut act_two_builder = self . act_two_builder ;
248
250
let remaining = act_two_builder. fill ( input) ;
249
251
250
- // Any payload larger than ACT_ONE_TWO_LENGTH indicates a bad peer since responder data
252
+ // Any payload larger than ACT_TWO_LENGTH indicates a bad peer since responder data
251
253
// is required to generate post-authentication messages (so it can't come before we transition)
252
254
if remaining. len ( ) != 0 {
253
255
return Err ( "Act Two too large" . to_string ( ) ) ;
@@ -310,6 +312,7 @@ impl IHandshakeState for InitiatorAwaitingActTwoState {
310
312
// - done by Conduit
311
313
let conduit = Conduit :: new ( sending_key, receiving_key, chaining_key) ;
312
314
315
+ // 8. Send m = 0 || c || t
313
316
Ok ( (
314
317
Some ( Act :: Three ( act_three) ) ,
315
318
HandshakeState :: Complete ( Some ( ( conduit, responder_static_public_key) ) )
@@ -345,6 +348,7 @@ impl IHandshakeState for ResponderAwaitingActThreeState {
345
348
346
349
// 1. Read exactly 66 bytes from the network buffer
347
350
let act_three_bytes = Act :: from ( act_three_builder) ;
351
+ assert_eq ! ( act_three_bytes. len( ) , ACT_THREE_LENGTH ) ;
348
352
349
353
// 2. Parse the read message (m) into v, c, and t
350
354
let version = act_three_bytes[ 0 ] ;
@@ -396,8 +400,11 @@ impl IHandshakeState for ResponderAwaitingActThreeState {
396
400
}
397
401
}
398
402
403
+ // The handshake state always uses the responder's static public key. When running on the initiator,
404
+ // the initiator provides the remote's static public key and running on the responder they provide
405
+ // their own.
399
406
// https://github.com/lightningnetwork/lightning-rfc/blob/master/08-transport.md#handshake-state-initialization
400
- fn handshake_state_initialization ( responder_static_public_key : & PublicKey ) -> ( Sha256 , Sha256 ) {
407
+ fn initialize_handshake_state ( responder_static_public_key : & PublicKey ) -> ( Sha256 , Sha256 ) {
401
408
let protocol_name = b"Noise_XK_secp256k1_ChaChaPoly_SHA256" ;
402
409
let prologue = b"lightning" ;
403
410
@@ -414,6 +421,7 @@ fn handshake_state_initialization(responder_static_public_key: &PublicKey) -> (S
414
421
( hash, chaining_key)
415
422
}
416
423
424
+ // Due to the very high similarity of acts 1 and 2, this method is used to process both
417
425
// https://github.com/lightningnetwork/lightning-rfc/blob/master/08-transport.md#act-one (sender)
418
426
// https://github.com/lightningnetwork/lightning-rfc/blob/master/08-transport.md#act-two (sender)
419
427
fn calculate_act_message ( local_private_ephemeral_key : & SecretKey , local_public_ephemeral_key : & PublicKey , remote_public_key : & PublicKey , chaining_key : ChainingKey , hash : Sha256 , act_out : & mut [ u8 ] ) -> ( Sha256 , SymmetricKey , SymmetricKey ) {
@@ -448,6 +456,11 @@ fn calculate_act_message(local_private_ephemeral_key: &SecretKey, local_public_e
448
456
// https://github.com/lightningnetwork/lightning-rfc/blob/master/08-transport.md#act-two (receiver)
449
457
fn process_act_message ( act_bytes : & [ u8 ] , local_private_key : & SecretKey , chaining_key : ChainingKey , hash : Sha256 ) -> Result < ( PublicKey , Sha256 , SymmetricKey , SymmetricKey ) , String > {
450
458
// 1. Read exactly 50 bytes from the network buffer
459
+ // Partial act messages are handled by the callers. By the time it gets here, it
460
+ // must be the correct size.
461
+ assert_eq ! ( act_bytes. len( ) , ACT_ONE_LENGTH ) ;
462
+ assert_eq ! ( act_bytes. len( ) , ACT_TWO_LENGTH ) ;
463
+
451
464
// 2.Parse the read message (m) into v, re, and c
452
465
let version = act_bytes[ 0 ] ;
453
466
let ephemeral_public_key_bytes = & act_bytes[ 1 ..34 ] ;
@@ -476,7 +489,8 @@ fn process_act_message(act_bytes: &[u8], local_private_key: &SecretKey, chaining
476
489
// 6. Act2: ck, temp_k2 = HKDF(ck, ee)
477
490
let ( chaining_key, temporary_key) = hkdf:: derive ( & chaining_key, & ecdh) ;
478
491
479
- // 7. p = decryptWithAD(temp_k1, 0, h, c)
492
+ // 7. Act1: p = decryptWithAD(temp_k1, 0, h, c)
493
+ // 7. Act2: p = decryptWithAD(temp_k2, 0, h, c)
480
494
chacha:: decrypt ( & temporary_key, 0 , & hash, & chacha_tag, & mut [ 0 ; 0 ] ) ?;
481
495
482
496
// 8. h = SHA-256(h || c)
0 commit comments