mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-01-18 21:35:24 +01:00
docs: add MuSig2 doc and release notes
This commit is contained in:
parent
63e93ae572
commit
93e069f3bd
117
docs/musig2.md
Normal file
117
docs/musig2.md
Normal file
@ -0,0 +1,117 @@
|
||||
# MuSig2
|
||||
|
||||
With `lnd v0.15.0-beta` a new, experimental MuSig2 API was added to the
|
||||
`signrpc` subserver RPC. With MuSig2 it is possible to combine the public keys
|
||||
of multiple signing participants into a single, combined key. The signers can
|
||||
then later come together and cooperatively produce a single signature that is
|
||||
valid for that combined public key. MuSig2 therefore is an interactive `n-of-n`
|
||||
signature scheme that produces a final/complete Schnorr signature out of `n`
|
||||
partial signatures.
|
||||
|
||||
**NOTE**: At the time the MuSig2 code in `btcd`/`lnd` was written, there was no
|
||||
"official" MuSig2 support merged to either `bitcoind` or `secp256k1`. Therefore,
|
||||
some smaller details in the signing protocol could change in the future that
|
||||
might not be backward compatible. So this API must be seen as highly
|
||||
experimental and backward compatibility can't be guaranteed at this point.
|
||||
|
||||
## References
|
||||
* [MuSig2 paper](https://eprint.iacr.org/2020/1261.pdf)
|
||||
* [Draft MuSig
|
||||
BIP](https://github.com/jonasnick/bips/blob/musig2/bip-musig2.mediawiki)
|
||||
* [MuSig2 implementation discussion in
|
||||
`bitcoind`](https://github.com/bitcoin/bitcoin/issues/23326)
|
||||
|
||||
## A note on security
|
||||
|
||||
The MuSig2 signing protocol is secure from leaking private key information of
|
||||
the signers **as long as the same secret nonce is never used multiple times**.
|
||||
If the same nonce is used for signing multiple times then the private key can
|
||||
leak. To avoid this security risk, the `signrpc.MuSig2Sign` RPC can only be
|
||||
called a single time for the same session ID. This has the implication that if a
|
||||
signing session fails or is aborted (for example because a participant isn't
|
||||
responsive or the message changes after some participants have already started
|
||||
signing), a completely new signing session needs to be initialized, which
|
||||
internally creates fresh nonces.
|
||||
|
||||
## Examples
|
||||
|
||||
An API is sometimes easiest explained by showing concrete usage examples. Here
|
||||
we take a look at the MuSig2 integration tests in `lnd`, since they both serve
|
||||
to test the RPCs and to showcase the different use cases.
|
||||
|
||||
### 3-of-3 Taproot key spend path (BIP-0086)
|
||||
|
||||
See `testTaprootMuSig2KeySpendBip86` in
|
||||
[`lntest/itest/lnd_taproot_test.go`](../lntest/itest/lnd_taproot_test.go) to see
|
||||
the full code.
|
||||
|
||||
This example uses combines the public keys of 3 participants into a shared
|
||||
MuSig2 public key that is then tweaked with the
|
||||
[BIP-0086](https://github.com/bitcoin/bips/blob/master/bip-0086.mediawiki#address-derivation)
|
||||
TapTweak to be turned into a Taproot public key that can be used directly as the
|
||||
`pkScript` of a p2tr output on chain.
|
||||
|
||||
The most notable parameter for this to work is the `TaprootTweak` parameter in
|
||||
the `MuSig2CreateSession` RPC call:
|
||||
|
||||
```go
|
||||
taprootTweak := &signrpc.TaprootTweakDesc{
|
||||
KeySpendOnly: true,
|
||||
}
|
||||
|
||||
sessResp1, err := node.SignerClient.MuSig2CreateSession(
|
||||
ctx, &signrpc.MuSig2SessionRequest{
|
||||
KeyLoc: keyDesc1.KeyLoc,
|
||||
AllSignerPubkeys: allPubKeys,
|
||||
TaprootTweak: taprootTweak,
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
### 3-of-3 Taproot key spend path with root hash commitment
|
||||
|
||||
See `testTaprootMuSig2KeySpendRootHash` in
|
||||
[`lntest/itest/lnd_taproot_test.go`](../lntest/itest/lnd_taproot_test.go) to see
|
||||
the full code.
|
||||
|
||||
This is very similar to the above example but with the main difference that the
|
||||
p2tr output on chain not only commits to a key spend path but also a script
|
||||
path. The MuSig2 combined key becomes the Taproot internal key and the TapTweak
|
||||
commits to both the internal key and the Taproot script merkle root hash.
|
||||
|
||||
The most notable parameter for this to work is the `TaprootTweak` parameter in
|
||||
the `MuSig2CreateSession` RPC call:
|
||||
|
||||
```go
|
||||
taprootTweak := &signrpc.TaprootTweakDesc{
|
||||
ScriptRoot: rootHash[:],
|
||||
}
|
||||
|
||||
sessResp1, err := node.SignerClient.MuSig2CreateSession(
|
||||
ctx, &signrpc.MuSig2SessionRequest{
|
||||
KeyLoc: keyDesc1.KeyLoc,
|
||||
AllSignerPubkeys: allPubKeys,
|
||||
TaprootTweak: taprootTweak,
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
### 3-of-3 `OP_CHECKSIG` in Taproot script spend path
|
||||
|
||||
See `testTaprootMuSig2CombinedLeafKeySpend` in
|
||||
[`lntest/itest/lnd_taproot_test.go`](../lntest/itest/lnd_taproot_test.go) to see
|
||||
the full code.
|
||||
|
||||
This example is definitely the most involved one. To be able to use a MuSig2
|
||||
combined key and then spend it through a Taproot script spend with an
|
||||
`OP_CHECKSIG` script, the following steps need to be performed:
|
||||
|
||||
1. Derive signing keys on signers, combine them through `MuSig2CombineKeys`.
|
||||
2. Create a Taproot script tree with a script leaf `<combinedKey> OP_CHECKSIG`.
|
||||
3. Create the Taproot key by committing to the script tree root hash.
|
||||
4. When spending the output, the message being signed needs to be the sighash of
|
||||
a Taproot script spend that also commits to the leaf hash.
|
||||
5. The final witness stack needs to contain the combined signature, the leaf
|
||||
script and the control block (which contains the internal public key and the
|
||||
inclusion proof if there were any other script leaves).
|
||||
|
@ -25,6 +25,16 @@ addresses](https://github.com/lightningnetwork/lnd/pull/6263). Using
|
||||
then watch it on chain. Taproot script spends are also supported through the
|
||||
`signrpc.SignOutputRaw` RPC (`/v2/signer/signraw` in REST).
|
||||
|
||||
## MuSig2
|
||||
|
||||
The [`signrpc.Signer` RPC service now supports EXPERIMENTAL MuSig2
|
||||
signing](https://github.com/lightningnetwork/lnd/pull/6361).
|
||||
|
||||
More information can be found in the [MuSig2 documentation](../musig2.md).
|
||||
Note that the MuSig2 BIP is not final yet and therefore the MuSig2 API must be
|
||||
considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
|
||||
releases. Backward compatibility is not guaranteed!
|
||||
|
||||
## `lncli`
|
||||
|
||||
* Add [auto-generated command-line completions](https://github.com/lightningnetwork/lnd/pull/4177)
|
||||
|
Loading…
Reference in New Issue
Block a user