-
Notifications
You must be signed in to change notification settings - Fork 73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MuSig2 support #294
MuSig2 support #294
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #294 +/- ##
===========================================
- Coverage 84.76% 84.70% -0.06%
===========================================
Files 17 17
Lines 2186 2230 +44
===========================================
+ Hits 1853 1889 +36
- Misses 333 341 +8
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
Quality Gate failedFailed conditions See analysis details on SonarCloud Catch issues before they fail your Quality Gate with our IDE extension SonarLint |
…icies to more general key expressions
…ed some comments. Generalizing to key expressions containing musig() makes it necessary to distinguish the key expressions in the wallet policy from the actual key placeholders that are just indexes to the list of key informations (@num in the descriptor template), whereas the two concepts were often not clearly separated in the code base. Renaming to "key expressions" makes the distinction more clear.
…on type is used; generalized some parts of the code that are not generalized to musig key expressions, and annotated some others.
256f790
to
4616d67
Compare
aae5a24
to
261d7d6
Compare
This is redundant with the current implementation. However, the musigsession module is written in such a way that the calling code has no knowledge about its internal working. Therefore, it should not assume that zeroing out is the correct way of initializing it.
b23a9ad
to
daa79a3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed the C part mostly, need to dive more into the Python bits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing interesting to say, that all sounds fair 👍
ecd07db
to
57e5d93
Compare
Co-authored-by: lpascal-ledger <[email protected]>
Add full support for
musig()
in wallet policies.Unlike typical signatures, where the client sends a transaction to the device and receives a signed transaction back, MuSig2 is a 2-party protocol among a group of cosigners, where:
Any (untrusted) coordinator, once all the partial signatures are collected, can produce the final signature.
Security considerations
Special care needs to be taken in the handling of nonces, and the way nonces are persisted in storage.
See more in the
musig.md
document added as part of the PR.UX consideration
As it is a two round protocol, there were some choices to be made on how to handle it: software wallets will in fact send the same PSBT to the device twice in order to complete the protocol.
In order to minimize the UX impact for the device - but also for wallets implementing it, the following choice was made:
This is not a security problem, because the first round of MuSig2 just produces and stores a random number; private keys are not even accessed.
In cases when the other cosigners are online at the same time, this allows software wallets to use MuSig2 while essentially providing identical UX to a non-MuSig2 wallet (connect the device, , inspect and confirm the transaction).
If the first and second round happen in two separate sessions, only the second one will require user confirmation, while of course the first one still needs the device to be unlocked and connected with the bitcoin app open.
BIPs related to this PR
The details of the signing protocol are detailed in BIP-327, but there are other related BIPs: BIP-328, BIP-390, BIP-373.
BIP-388 is in process of being updated.
Structure of the implementation
The PR required some refactoring that have a fairly big impact on the codebase, particularly in order to generalize the 'key expressions' in wallet policies to support the
musig()
expression, whereas in the past it was always limited to a single xpub; the code to handle the PSBT fields in the transaction and identify the correct derivation path for each input also needed to be generalized.However, most of the musig-related code is relatively self-contained and modularized in the following files:
doc/musig.md
- Technical details, and security details, about the MuSig2 feature.src/handler/sign_psbt/musig_signing.{c,j}
- portions of thesign_psbt
handler that are handling the logic of Round 1 and Round 2 of MuSig2,src/musig/musig.{c,h}
- implementation of the relevant algorithms defined in BIP-327, closely matching the Python reference implementationsrc/musig/musig_sessions.{c,h}
- encapsulates the logic to handle the persistence in NVRAM after the end of MuSig's round 1, until the beginning of Round 2.Status of test coverage
There are some e2e tests with the corresponding bitcoin-core implementation which is still a WIP and does not support complex policies. Testing will be needed with musig nested inside miniscript as soon as possible - to be done in a separate PR ahead of release. Created issue #302 for tracking.
Incidental changes
Also improves the signing flow to only sign for spending paths that are filled in in the PSBT (that is, the corresponding
PSBT_IN_BIP32_DERIVATION
orPSBT_IN_TAP_BIP32_DERIVATION
fields are present), optimizing certain use cases for wallet policies with multiple alternative spending paths.Closes: #208
Closes: #177