11use bitcoin:: secp256k1;
22
3- use bitcoin:: hashes:: { Hash , HashEngine } ;
3+ use bitcoin:: hashes:: Hash ;
44use bitcoin:: hashes:: sha256:: Hash as Sha256 ;
55use bitcoin:: secp256k1:: { SecretKey , PublicKey } ;
66
77use ln:: peers:: { chacha, hkdf5869rfc} ;
88use ln:: peers:: conduit:: { Conduit , SymmetricKey } ;
99use 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+ use ln:: peers:: handshake:: handshake_hash:: HandshakeHash ;
1011
1112// Alias type to help differentiate between temporary key and chaining key when passing bytes around
1213type ChainingKey = [ u8 ; 32 ] ;
1314
14- // Generate a SHA-256 hash from one or more elements concatenated together
15- macro_rules! concat_then_sha256 {
16- ( $( $x: expr ) ,+ ) => { {
17- let mut sha = Sha256 :: engine( ) ;
18- $(
19- sha. input( $x. as_ref( ) ) ;
20- ) +
21- Sha256 :: from_engine( sha)
22- } }
23- }
24-
2515pub ( super ) enum HandshakeState {
2616 InitiatorStarting ( InitiatorStartingState ) ,
2717 ResponderAwaitingActOne ( ResponderAwaitingActOneState ) ,
@@ -66,17 +56,17 @@ pub(super) struct InitiatorStartingState {
6656 initiator_ephemeral_private_key : SecretKey ,
6757 initiator_ephemeral_public_key : PublicKey ,
6858 responder_static_public_key : PublicKey ,
69- chaining_key : Sha256 ,
70- hash : Sha256
59+ chaining_key : ChainingKey ,
60+ hash : HandshakeHash ,
7161}
7262
7363// Handshake state of the Responder prior to receiving Act 1
7464pub ( super ) struct ResponderAwaitingActOneState {
7565 responder_static_private_key : SecretKey ,
7666 responder_ephemeral_private_key : SecretKey ,
7767 responder_ephemeral_public_key : PublicKey ,
78- chaining_key : Sha256 ,
79- hash : Sha256 ,
68+ chaining_key : ChainingKey ,
69+ hash : HandshakeHash ,
8070 act_one_builder : ActBuilder
8171}
8272
@@ -87,13 +77,13 @@ pub(super) struct InitiatorAwaitingActTwoState {
8777 initiator_ephemeral_private_key : SecretKey ,
8878 responder_static_public_key : PublicKey ,
8979 chaining_key : ChainingKey ,
90- hash : Sha256 ,
80+ hash : HandshakeHash ,
9181 act_two_builder : ActBuilder
9282}
9383
9484// Handshake state of the Responder prior to receiving Act 3
9585pub ( super ) struct ResponderAwaitingActThreeState {
96- hash : Sha256 ,
86+ hash : HandshakeHash ,
9787 responder_ephemeral_private_key : SecretKey ,
9888 chaining_key : ChainingKey ,
9989 temporary_key : [ u8 ; 32 ] ,
@@ -139,7 +129,7 @@ impl IHandshakeState for InitiatorStartingState {
139129 & initiator_ephemeral_private_key,
140130 & initiator_ephemeral_public_key,
141131 & responder_static_public_key,
142- chaining_key. into_inner ( ) ,
132+ chaining_key,
143133 hash,
144134 & mut act_one
145135 ) ;
@@ -215,7 +205,7 @@ impl IHandshakeState for ResponderAwaitingActOneState {
215205 let ( initiator_ephemeral_public_key, hash, chaining_key, _) = process_act_message (
216206 & act_one,
217207 & responder_static_private_key,
218- chaining_key. into_inner ( ) ,
208+ chaining_key,
219209 hash,
220210 ) ?;
221211
@@ -280,7 +270,7 @@ impl IHandshakeState for InitiatorAwaitingActTwoState {
280270 let chaining_key = self . chaining_key ;
281271 let act_two = Act :: from ( act_two_builder) ;
282272
283- let ( responder_ephemeral_public_key, hash, chaining_key, temporary_key) = process_act_message (
273+ let ( responder_ephemeral_public_key, mut hash, chaining_key, temporary_key) = process_act_message (
284274 & act_two,
285275 & initiator_ephemeral_private_key,
286276 chaining_key,
@@ -291,10 +281,10 @@ impl IHandshakeState for InitiatorAwaitingActTwoState {
291281
292282 // start serializing act three
293283 // 1. c = encryptWithAD(temp_k2, 1, h, s.pub.serializeCompressed())
294- chacha:: encrypt ( & temporary_key, 1 , & hash, & initiator_static_public_key. serialize ( ) , & mut act_three[ 1 ..50 ] ) ;
284+ chacha:: encrypt ( & temporary_key, 1 , & hash. value , & initiator_static_public_key. serialize ( ) , & mut act_three[ 1 ..50 ] ) ;
295285
296286 // 2. h = SHA-256(h || c)
297- let hash = concat_then_sha256 ! ( hash , act_three[ 1 ..50 ] ) ;
287+ hash. update ( & act_three[ 1 ..50 ] ) ;
298288
299289 // 3. se = ECDH(s.priv, re)
300290 let ecdh = ecdh ( & initiator_static_private_key, & responder_ephemeral_public_key) ;
@@ -303,7 +293,7 @@ impl IHandshakeState for InitiatorAwaitingActTwoState {
303293 let ( chaining_key, temporary_key) = hkdf5869rfc:: derive ( & chaining_key, & ecdh) ;
304294
305295 // 5. t = encryptWithAD(temp_k3, 0, h, zero)
306- chacha:: encrypt ( & temporary_key, 0 , & hash, & [ 0 ; 0 ] , & mut act_three[ 50 ..] ) ;
296+ chacha:: encrypt ( & temporary_key, 0 , & hash. value , & [ 0 ; 0 ] , & mut act_three[ 50 ..] ) ;
307297
308298 // 6. sk, rk = HKDF(ck, zero)
309299 let ( sending_key, receiving_key) = hkdf5869rfc:: derive ( & chaining_key, & [ 0 ; 0 ] ) ;
@@ -342,7 +332,7 @@ impl IHandshakeState for ResponderAwaitingActThreeState {
342332 ) ) ;
343333 }
344334
345- let hash = self . hash ;
335+ let mut hash = self . hash ;
346336 let temporary_key = self . temporary_key ;
347337 let responder_ephemeral_private_key = self . responder_ephemeral_private_key ;
348338 let chaining_key = self . chaining_key ;
@@ -364,15 +354,15 @@ impl IHandshakeState for ResponderAwaitingActThreeState {
364354
365355 // 4. rs = decryptWithAD(temp_k2, 1, h, c)
366356 let mut remote_pubkey = [ 0 ; 33 ] ;
367- chacha:: decrypt ( & temporary_key, 1 , & hash, & tagged_encrypted_pubkey, & mut remote_pubkey) ?;
357+ chacha:: decrypt ( & temporary_key, 1 , & hash. value , & tagged_encrypted_pubkey, & mut remote_pubkey) ?;
368358 let initiator_pubkey = if let Ok ( public_key) = PublicKey :: from_slice ( & remote_pubkey) {
369359 public_key
370360 } else {
371361 return Err ( "invalid remote public key" . to_string ( ) ) ;
372362 } ;
373363
374364 // 5. h = SHA-256(h || c)
375- let hash = concat_then_sha256 ! ( hash , tagged_encrypted_pubkey) ;
365+ hash. update ( tagged_encrypted_pubkey) ;
376366
377367 // 6. se = ECDH(e.priv, rs)
378368 let ecdh = ecdh ( & responder_ephemeral_private_key, & initiator_pubkey) ;
@@ -381,7 +371,7 @@ impl IHandshakeState for ResponderAwaitingActThreeState {
381371 let ( chaining_key, temporary_key) = hkdf5869rfc:: derive ( & chaining_key, & ecdh) ;
382372
383373 // 8. p = decryptWithAD(temp_k3, 0, h, t)
384- chacha:: decrypt ( & temporary_key, 0 , & hash, & chacha_tag, & mut [ 0 ; 0 ] ) ?;
374+ chacha:: decrypt ( & temporary_key, 0 , & hash. value , & chacha_tag, & mut [ 0 ; 0 ] ) ?;
385375
386376 // 9. rk, sk = HKDF(ck, zero)
387377 let ( receiving_key, sending_key) = hkdf5869rfc:: derive ( & chaining_key, & [ 0 ; 0 ] ) ;
@@ -405,31 +395,32 @@ impl IHandshakeState for ResponderAwaitingActThreeState {
405395// the initiator provides the remote's static public key and running on the responder they provide
406396// their own.
407397// https://github.com/lightningnetwork/lightning-rfc/blob/master/08-transport.md#handshake-state-initialization
408- fn initialize_handshake_state ( responder_static_public_key : & PublicKey ) -> ( Sha256 , Sha256 ) {
398+ fn initialize_handshake_state ( responder_static_public_key : & PublicKey ) -> ( HandshakeHash , [ u8 ; 32 ] ) {
409399 let protocol_name = b"Noise_XK_secp256k1_ChaChaPoly_SHA256" ;
410400 let prologue = b"lightning" ;
411401
412402 // 1. h = SHA-256(protocolName)
413403 // 2. ck = h
414- let chaining_key = concat_then_sha256 ! ( protocol_name) ;
404+ let mut hash = HandshakeHash :: new ( protocol_name) ;
405+ let chaining_key = hash. value . clone ( ) ;
415406
416407 // 3. h = SHA-256(h || prologue)
417- let hash = concat_then_sha256 ! ( chaining_key , prologue) ;
408+ hash. update ( prologue) ;
418409
419410 // h = SHA-256(h || responderPublicKey)
420- let hash = concat_then_sha256 ! ( hash , responder_static_public_key. serialize( ) ) ;
411+ hash. update ( & responder_static_public_key. serialize ( ) ) ;
421412
422413 ( hash, chaining_key)
423414}
424415
425416// Due to the very high similarity of acts 1 and 2, this method is used to process both
426417// https://github.com/lightningnetwork/lightning-rfc/blob/master/08-transport.md#act-one (sender)
427418// https://github.com/lightningnetwork/lightning-rfc/blob/master/08-transport.md#act-two (sender)
428- 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 ) {
419+ fn calculate_act_message ( local_private_ephemeral_key : & SecretKey , local_public_ephemeral_key : & PublicKey , remote_public_key : & PublicKey , chaining_key : ChainingKey , mut hash : HandshakeHash , act_out : & mut [ u8 ] ) -> ( HandshakeHash , SymmetricKey , SymmetricKey ) {
429420 // 1. e = generateKey() (passed in)
430421 // 2. h = SHA-256(h || e.pub.serializeCompressed())
431422 let serialized_local_public_key = local_public_ephemeral_key. serialize ( ) ;
432- let hash = concat_then_sha256 ! ( hash , serialized_local_public_key) ;
423+ hash. update ( & serialized_local_public_key) ;
433424
434425 // 3. ACT1: es = ECDH(e.priv, rs)
435426 // 3. ACT2: es = ECDH(e.priv, re)
@@ -441,10 +432,10 @@ fn calculate_act_message(local_private_ephemeral_key: &SecretKey, local_public_e
441432
442433 // 5. ACT1: c = encryptWithAD(temp_k1, 0, h, zero)
443434 // 5. ACT2: c = encryptWithAD(temp_k2, 0, h, zero)
444- chacha:: encrypt ( & temporary_key, 0 , & hash, & [ 0 ; 0 ] , & mut act_out[ 34 ..] ) ;
435+ chacha:: encrypt ( & temporary_key, 0 , & hash. value , & [ 0 ; 0 ] , & mut act_out[ 34 ..] ) ;
445436
446437 // 6. h = SHA-256(h || c)
447- let hash = concat_then_sha256 ! ( hash , & act_out[ 34 ..] ) ;
438+ hash. update ( & act_out[ 34 ..] ) ;
448439
449440 // Send m = 0 || e.pub.serializeCompressed() || c
450441 act_out[ 0 ] = 0 ;
@@ -456,7 +447,7 @@ fn calculate_act_message(local_private_ephemeral_key: &SecretKey, local_public_e
456447// Due to the very high similarity of acts 1 and 2, this method is used to process both
457448// https://github.com/lightningnetwork/lightning-rfc/blob/master/08-transport.md#act-one (receiver)
458449// https://github.com/lightningnetwork/lightning-rfc/blob/master/08-transport.md#act-two (receiver)
459- fn process_act_message ( act_bytes : & [ u8 ] , local_private_key : & SecretKey , chaining_key : ChainingKey , hash : Sha256 ) -> Result < ( PublicKey , Sha256 , SymmetricKey , SymmetricKey ) , String > {
450+ fn process_act_message ( act_bytes : & [ u8 ] , local_private_key : & SecretKey , chaining_key : ChainingKey , mut hash : HandshakeHash ) -> Result < ( PublicKey , HandshakeHash , SymmetricKey , SymmetricKey ) , String > {
460451 // 1. Read exactly 50 bytes from the network buffer
461452 // Partial act messages are handled by the callers. By the time it gets here, it
462453 // must be the correct size.
@@ -481,7 +472,7 @@ fn process_act_message(act_bytes: &[u8], local_private_key: &SecretKey, chaining
481472 }
482473
483474 // 4. h = SHA-256(h || re.serializeCompressed())
484- let hash = concat_then_sha256 ! ( hash , ephemeral_public_key_bytes) ;
475+ hash. update ( ephemeral_public_key_bytes) ;
485476
486477 // 5. Act1: es = ECDH(s.priv, re)
487478 // 5. Act2: ee = ECDH(e.priv, ee)
@@ -493,10 +484,10 @@ fn process_act_message(act_bytes: &[u8], local_private_key: &SecretKey, chaining
493484
494485 // 7. Act1: p = decryptWithAD(temp_k1, 0, h, c)
495486 // 7. Act2: p = decryptWithAD(temp_k2, 0, h, c)
496- chacha:: decrypt ( & temporary_key, 0 , & hash, & chacha_tag, & mut [ 0 ; 0 ] ) ?;
487+ chacha:: decrypt ( & temporary_key, 0 , & hash. value , & chacha_tag, & mut [ 0 ; 0 ] ) ?;
497488
498489 // 8. h = SHA-256(h || c)
499- let hash = concat_then_sha256 ! ( hash , chacha_tag) ;
490+ hash. update ( chacha_tag) ;
500491
501492 Ok ( ( ephemeral_public_key, hash, chaining_key, temporary_key) )
502493}
@@ -513,7 +504,7 @@ fn ecdh(private_key: &SecretKey, public_key: &PublicKey) -> SymmetricKey {
513504 pk_object. mul_assign ( & curve, & private_key[ ..] ) . expect ( "invalid multiplication" ) ;
514505
515506 let preimage = pk_object. serialize ( ) ;
516- concat_then_sha256 ! ( preimage) . into_inner ( )
507+ Sha256 :: hash ( & preimage) . into_inner ( )
517508}
518509
519510#[ cfg( test) ]
0 commit comments