I want to announce a prototype for a design and implementation of a vault-like scheme that can be used on Bitcoin today, achieved by outsourcing the signing quorum to a set of blinded co-signers.
Unlike traditional setups involving co-signers, this scheme uses a blinded version of Musig2 to ensure the signers learn as little as possible about the on-chain movements of the funds they are involved in co-signing.
In order to have the co-signers add to the security of the funds (and not just blindly sign whatever is thrown at them), we attach a ZK proof to the signing requests, proving that the transaction is valid according to a pre-determined policy. In this case that is the timelock of the final tx.
classDiagram
vault_deposit <|-- vault_recovery
vault_deposit <|-- unvault
unvault <|-- unvault_recovery
unvault <|-- final
class vault_deposit{
aggregate_key
}
class vault_recovery{
recovery_address
}
class unvault{
aggregate_key'
}
class final{
destination_address
timelock(blocks)
}
class unvault_recovery{
recovery_address
}
Looking at the graph above, the four transactions vault_deposit, vault_recovery, unvault and unvault_recovery will be pre-signed before funds are deposited into the vault. At the time of unvaulting, the co-signers will be asked to sign the final tx, at which point they will also require a proof that the blinded transaction they are signing has the relative timelock set correctly.
This gives the owner of the funds an assurance that he (or a watchtower) has time to sweep the funds back into the recovery address in case of an unauthorized unvault. The scheme is safe as long as at least one of the signer’s key only signs according to the protocol.
More details about the protocol and blinded signature scheme can be found here: blind-vault/doc/vault.md at d98ad46d43c757dbf79409f5663daebd07164689 · halseth/blind-vault · GitHub
Prototype
There’s a prototype implementation of the scheme available for regtest and signet at GitHub - halseth/blind-vault. Keep in mind that this is very much a proof-of-concept and should not be used with real funds.
Refer to blind-vault/VAULT_TOOL.md at d98ad46d43c757dbf79409f5663daebd07164689 · halseth/blind-vault · GitHub for details of how you can test the flow using a simplified bash script.
graph TD;
Depositor<-->Client;
Client<-->Signer1;
Client<-->Signer2;
Proving time
Since the signers should learn nothing about the the messages they sign, the other signers or any of the parameters used during the signing session, it is all blinded by the client. This creates a challenge for the signers to verify that key and nonce aggregation is performed correctly, since this in regular Musig2 is performed by every signer. To mitigate this the client will attaches a ZK proof that shows the signers that aggregation and blinding is done according to protocol.
Proving proper Musig2 aggregation is by far the most time consuming part of the protocol, and takes around 4 minutes per tx per signer on an Apple M1 Max. I suspect this can be reduced significantly by using a more optimized ZK prover and/or a signing scheme that involves fewer EC operations.
Future work
The goal is to generalize this framework to be available for other policies than the vault transaction graph. I hope to also improve on the proving time to make it practically usable on less powerful devices.
Feedback is greatly appreciated!