From d2bc4f29e119d99e463f4441daf9766df5cf848e Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Mon, 10 Jul 2023 18:25:06 -0700 Subject: [PATCH] lnwallet: fix bug in deriveMusig2Shachain In this commit, we fix a bug in the `deriveMusig2Shachain` function where it didn't actually use the passed in revocation root as part of the hmac invocation. We also modify the function to be more generally useable as well, as now the caller can just pass in the revocation root things should be derived from. --- lnwallet/channel.go | 14 +++----------- lnwallet/musig_session.go | 16 +++++++++++++++- lnwallet/revocation_producer.go | 2 +- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/lnwallet/channel.go b/lnwallet/channel.go index 52fbbf422..58400079f 100644 --- a/lnwallet/channel.go +++ b/lnwallet/channel.go @@ -1396,17 +1396,9 @@ func NewLightningChannel(signer input.Signer, logPrefix := fmt.Sprintf("ChannelPoint(%v):", state.FundingOutpoint) - // In order to obtain the revocation root hash to create the taproot - // revocation, we'll encode the producer into a buffer, then use that - // to derive the shachain root needed. - var rootHashBuf bytes.Buffer - if err := state.RevocationProducer.Encode(&rootHashBuf); err != nil { - return nil, fmt.Errorf("unable to encode producer: %v", err) - } - - revRootHash := chainhash.HashH(rootHashBuf.Bytes()) - - taprootNonceProducer, err := deriveMusig2Shachain(revRootHash) + taprootNonceProducer, err := deriveMusig2Shachain( + state.RevocationProducer, + ) if err != nil { return nil, fmt.Errorf("unable to derive shachain: %v", err) } diff --git a/lnwallet/musig_session.go b/lnwallet/musig_session.go index 9ddc12ab2..30d28e414 100644 --- a/lnwallet/musig_session.go +++ b/lnwallet/musig_session.go @@ -585,12 +585,26 @@ var ( // deriveMusig2Shachain derives a shachain producer for the taproot channel // from normal shachain revocation root. -func deriveMusig2Shachain(revRoot chainhash.Hash) (shachain.Producer, error) { +func deriveMusig2Shachain(revRoot shachain.Producer) (shachain.Producer, error) { + // In order to obtain the revocation root hash to create the taproot + // revocation, we'll encode the producer into a buffer, then use that + // to derive the shachain root needed. + var rootHashBuf bytes.Buffer + if err := revRoot.Encode(&rootHashBuf); err != nil { + return nil, fmt.Errorf("unable to encode producer: %v", err) + } + + revRootHash := chainhash.HashH(rootHashBuf.Bytes()) + // For taproot channel types, we'll also generate a distinct shachain // root using the same seed information. We'll use this to generate // verification nonces for the channel. We'll bind with this a simple // hmac. taprootRevHmac := hmac.New(sha256.New, taprootRevRootKey) + if _, err := taprootRevHmac.Write(revRootHash[:]); err != nil { + return nil, err + } + taprootRevRoot := taprootRevHmac.Sum(nil) // Once we have the root, we can then generate our shachain producer diff --git a/lnwallet/revocation_producer.go b/lnwallet/revocation_producer.go index 5945c2faf..7b8349950 100644 --- a/lnwallet/revocation_producer.go +++ b/lnwallet/revocation_producer.go @@ -50,7 +50,7 @@ func (l *LightningWallet) nextRevocationProducer(res *ChannelReservation, // Once we have the root, we can then generate our shachain producer // and from that generate the per-commitment point. shaChainRoot := shachain.NewRevocationProducer(revRoot) - taprootShaChainRoot, err := deriveMusig2Shachain(revRoot) + taprootShaChainRoot, err := deriveMusig2Shachain(shaChainRoot) if err != nil { return nil, nil, err }