Skip to content

Commit f006cbd

Browse files
committed
utils: validate MuSig2 signer inputs
1 parent 30472d0 commit f006cbd

File tree

2 files changed

+53
-2
lines changed

2 files changed

+53
-2
lines changed

utils/musig.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,21 @@ import (
99
)
1010

1111
// MuSig2Sign will create a MuSig2 signature for the passed message using the
12-
// passed private keys.
12+
// passed private keys. It expects at least two signing keys, and the number of
13+
// private keys and public keys must match.
1314
func MuSig2Sign(version input.MuSig2Version, privKeys []*btcec.PrivateKey,
1415
pubKeys []*btcec.PublicKey, tweaks *input.MuSig2Tweaks,
1516
msg [32]byte) ([]byte, error) {
1617

18+
if len(privKeys) != len(pubKeys) {
19+
return nil, fmt.Errorf("number of private keys (%d) must "+
20+
"match number of public keys (%d)",
21+
len(privKeys), len(pubKeys))
22+
}
23+
if len(privKeys) < 2 {
24+
return nil, fmt.Errorf("need at least two signing keys")
25+
}
26+
1727
// Next we'll create MuSig2 sessions for each individual private
1828
// signing key.
1929
sessions := make([]input.MuSig2Session, len(privKeys))
@@ -74,7 +84,7 @@ func MuSig2Sign(version input.MuSig2Version, privKeys []*btcec.PrivateKey,
7484
}
7585

7686
if !haveAllSigs {
77-
return nil, fmt.Errorf("combinging MuSig2 signatures " +
87+
return nil, fmt.Errorf("combining MuSig2 signatures " +
7888
"failed")
7989
}
8090

utils/musig_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package utils
2+
3+
import (
4+
"testing"
5+
6+
"github.com/btcsuite/btcd/btcec/v2"
7+
"github.com/lightninglabs/loop/test"
8+
"github.com/lightningnetwork/lnd/input"
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
// TestMuSig2SignRejectsSingleSigner ensures the helper fails fast with a clear
13+
// error instead of entering an invalid one-party MuSig2 flow.
14+
func TestMuSig2SignRejectsSingleSigner(t *testing.T) {
15+
privKey, pubKey := test.CreateKey(1)
16+
17+
_, err := MuSig2Sign(
18+
input.MuSig2Version100RC2,
19+
[]*btcec.PrivateKey{privKey},
20+
[]*btcec.PublicKey{pubKey},
21+
&input.MuSig2Tweaks{},
22+
[32]byte{},
23+
)
24+
require.ErrorContains(t, err, "need at least two signing keys")
25+
}
26+
27+
// TestMuSig2SignRejectsMismatchedKeyCounts ensures we fail before creating any
28+
// MuSig2 sessions when the signer sets are inconsistent.
29+
func TestMuSig2SignRejectsMismatchedKeyCounts(t *testing.T) {
30+
privKey, pubKey1 := test.CreateKey(1)
31+
_, pubKey2 := test.CreateKey(2)
32+
33+
_, err := MuSig2Sign(
34+
input.MuSig2Version100RC2,
35+
[]*btcec.PrivateKey{privKey},
36+
[]*btcec.PublicKey{pubKey1, pubKey2},
37+
&input.MuSig2Tweaks{},
38+
[32]byte{},
39+
)
40+
require.ErrorContains(t, err, "must match number of public keys")
41+
}

0 commit comments

Comments
 (0)