18.4: Using Bitcoin with FROST
There are two major Schnorr signature systems that have been built to allow Schnorr multisigs. The first was MuSig2 and the second is FROST.
Understand FROST
FROST, which stands for Flexible Round-Optimized Schnorr Threshold Signatures is a threshold signature that allows for m-of-n Schnorr multisigs without succumbing to the cancellation attack. It does this through "signing shares" that can either be generated on a single machine and then distributed or (more securely) generated using secure multi-party computation (SMPC) so that the full key never exists in a single place.
FROST being able to natively offer threshold signatures is a big advantage over MuSig2's multisig-only signatures. However, MuSig2 also has an advantage of its own: accountability. In FROST, you need insider information to know who signed a multisig. In MuSig2, you can always guarantee every signator. As with most tools, you should choose the proper one for your needs.
Use FROST
Any Bitcoin wallet can create a Taproot address that is built on a FROST-generated key rather than a singular Schnorr key. That's the beauty of Schnorr: a multisig FROST key looks exactly the same as a singular Schnorr key. They're indistinguishable, and so they look just the same to a wallet.
The trick comes in signing, in order to unlock the puzzle box of the FROST lock. A wallet could support this functionality, but (unlike with MuSig2) Bitcoin Core does not. In order to unlock funds locked into an address defined by a FROST public key, you therefore have to generate the appropriate signature outside of Bitcoin Core and then sneak it into a Bitcoin transaction. This is possible, but only with quite a few additional tools.
Our Learning FROST from the Command Line course is a four-chapter course that's largely focused on this end product: signing a transaction with a FROST signature. Early chapters demonstrate how to install the ZF FROST tools, which are some of the best tools to date to do this work from the command line, and how to create signature shares among the members of a "FROST group". Learning FROST §4.2 then shows the precise methodology for signing with FROST, once you have everything installed and built.
What follows are just the outlines to explain the methodology; you should consult Learning FROST from the Command Line for the specifics.
Create a FROST Address
Creating a FROST address is a simple creation of a FROST group (which also isn't supported by Bitcoin Core) followed by implementation of the techniques that you've previously used to work with descriptor-based content.
- Choose the "n" members of a FROST group.
- Choose what the "m" threshold will be.
- Apply the FROST protocol to generate individual signing shares and an aggregate public key using ZF Tools or another FROST toolkit.
- Generate a descriptor by pairing "tr(aggregate public key)" with a generated checksum, per the technique in §4.2.
- Use
deriveaddressesto generate one or more addresses for the descriptor.
Spend a FROST Address
Spending from a FROST address requires even more complexity that's not supported by Bitcoin Core.
- Generate a PSBT to spend funds.
- Extract the sighash from the PSBT using a special tool.
- Use a FROST tool such as ZF FROST to create a threshold signature of the sighash. This is a multiround process, just like MuSig2.
- Use a special tool to place the signature into the UTXO with the proper
sighashflag. - Finalize and send the PSBT.
Again, Learning FROST from the Command Line contains all the tools you'll need for this process.
📖 What is a Sighash? When Bitcoin signs a transaction, it actually signs a hash of the transaction: the sighash. Each transaction has multiple inputs (where funds are coming from) and multiple outputs (where funds are going to). Whether a sighash contains all, some, or none of the inputs and all, some, or none of the outputs is determined by a specific
sighashflag, which is applied to each signature.
Summary: Using Bitcoin with FROST
Bitcoin Core doesn't directly support FROST signatures. But, the aggregatable nature of FROST signatures, which results in all of them looking the same, means that it will correctly process a FROST signature if you give it one. You can create a FROST address with "tr(public-key)", where the public key is a FROST aggregated key; you can generate an address from that descriptor as usual; and then you can spend funds by signing with the appropriate signing shares and inserting that signature into a transaction.
What's Next?
Continue "Using Taproot" with Chapter Nineteen: Using Schnorr.