AI-generated analysisPublished automatically and not human-verified. Validated context appears in community notes below.
← Watch feed
High 82 Bitcoin

lnwallet/chancloser: fix MuSig2 nonce reuse across RBF rounds

Public commit record

What the developer wrote

Authored by Olaoluwa Osuntokun

78/100 · Adequate
lnwallet/chancloser: fix MuSig2 nonce reuse across RBF rounds

MusigChanCloser.ClosingNonce() cached the local nonce and returned
the same one on subsequent calls. Since each RBF round creates a new
MuSig2 session via ProposalClosingOpts() but passes the same SecNonce,
the btcd library's per-session nonce reuse guard was bypassed (fresh
Session each round). Signing different closing transactions (different
fees/sighashes) with the same secret nonce enables private key
extraction via simple linear algebra on the partial signatures.

Fix by adding ClearNonce() to the MusigSession interface and calling
it after each signing round completes, forcing fresh nonce generation
on every RBF iteration. Also fix a rebase issue where
updateAndValidateCloseTerms was not extracting NextCloseeNonce from
ClosingSig messages for subsequent RBF rounds.

lnwallet/chancloser: fix MuSig2 nonce reuse across RBF rounds

MusigChanCloser.ClosingNonce() cached the secret nonce and returned
the same one across RBF rounds. Since each round creates a new
MuSig2 session via ProposalClosingOpts() but passes the same
SecNonce, signing different closing transactions with different
sighashes enables private key extraction.

Fix this by:

1. Storing the full MusigPartialSig from LocalCloseStart in the
LocalOfferSent state, eliminating the second CreateCloseProposal
call in prepareClosingSignatures. This was also flagged in PR
review as wasteful.

2. Adding InvalidateNonce() to the MusigSession interface. After
the closer round completes (CompleteCooperativeClose), the closer
nonce is invalidated so the next RBF round generates fresh. For
the closee, the nonce is invalidated before generating the next
closee nonce in createClosingSigMessage.
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Names security-relevant behavior explicitly
The short version

What changed, and why it matters

This patch fixes a critical cryptographic bug in LND's taproot cooperative channel close feature. During RBF (fee-bump) rounds, the same secret random number (nonce) was being reused to sign different closing transactions. In MuSig2/taproot signing, reusing a secret nonce with different messages lets an attacker who sees the partial signatures recover your private key. The fix forces a fresh nonce for every RBF round and also stores the partial signature so it isn't regenerated (which would also reuse the nonce).

Recommended action

Upgrade LND nodes running taproot channels with RBF cooperative close to a release containing this commit. Rotate any potentially affected private keys if there is evidence of nonce reuse or exposure of partial signatures to untrusted parties. Review logs for repeated RBF cooperative close rounds prior to the patch.

Security signals we found

01

MuSig2 secret nonce reuse across signing rounds

02

Different sighashes signed with same secret nonce

03

Private key extraction risk via partial-signature linear algebra

04

Taproot cooperative close RBF path affected

05

btcd per-session nonce guard bypassed by fresh session per round

06

Fix includes interface change (InvalidateNonce) and state-machine nonce invalidation

Risk score

Why this scored 82/100

Our methodology →
Potential impact 28/30
Exploitability 18/25
Stealth signal 12/15
Affected reach 10/15
Confidence 9/10
Evidence quality 5/5
Human-validated context

Community notes

Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.

No validated notes yet.

The AI analysis stands alone for now. Submit a note if you can add evidence or important context.