From 895b7624ac33ffa75d0929cc22e4a606753789ae Mon Sep 17 00:00:00 2001 From: Boris Nagaev Date: Tue, 5 May 2026 17:47:50 -0500 Subject: [PATCH] utils: document raw-key normalization semantics Document that Loop's raw-key MuSig2 helper and hash-derived internal-key helper both rely on btcec.PrivKeyFromBytes normalization semantics. This makes the current protocol behavior explicit without changing it. --- loopin.go | 5 ++++- utils/musig.go | 8 ++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/loopin.go b/loopin.go index ae6802c8..0c8cb9f1 100644 --- a/loopin.go +++ b/loopin.go @@ -1214,7 +1214,10 @@ func (s *loopInSwap) setState(state loopdb.SwapState) { } // sharedSecretFromHash derives the shared secret from the swap hash using the -// swap.KeyFamily family and zero as index. +// swap.KeyFamily family and zero as index. The swap hash is first interpreted +// with btcec.PrivKeyFromBytes semantics, so the derived ephemeral pubkey uses +// the same modulo-N normalization as the internal-key code paths that consume +// the resulting shared secret. func sharedSecretFromHash(ctx context.Context, signer lndclient.SignerClient, hash lntypes.Hash) ([32]byte, error) { diff --git a/utils/musig.go b/utils/musig.go index cc1675bf..e8a1e2a6 100644 --- a/utils/musig.go +++ b/utils/musig.go @@ -10,7 +10,10 @@ import ( ) // MuSig2Sign will create a MuSig2 signature for the passed message using the -// passed raw private keys. It expects at least two signing keys. +// passed raw private keys. Raw keys are interpreted with +// btcec.PrivKeyFromBytes semantics, which normalize 32-byte inputs modulo the +// secp256k1 group order instead of rejecting out-of-range values. It expects +// at least two signing keys. func MuSig2Sign(version input.MuSig2Version, keys [][32]byte, tweaks *input.MuSig2Tweaks, msg [32]byte) ([]byte, error) { @@ -18,7 +21,8 @@ func MuSig2Sign(version input.MuSig2Version, keys [][32]byte, pubKeys := make([]*btcec.PublicKey, len(keys)) // First parse the raw private keys and also create the corresponding - // public keys. + // public keys. This preserves the same normalization semantics used + // when these raw keys are turned into pubkeys elsewhere in the protocol. for i, key := range keys { privKeys[i], pubKeys[i] = btcec.PrivKeyFromBytes(key[:])