Bitcoin
taproot – P2tr transaction using musig2 Rust
I’m trying to build a p2tr that uses 2-2 music aggregation addresses. My process is as follows:
- Generate a SecretKey, PublicKey pair from each party.
- Aggregate those two public keys.
- Create and post a transaction sending the deposit to the corresponding aggregated address (Tx0).
- Use musig2 to collect a valid signature to use that address.
- Create a p2tr transaction to use that address as a valid signature (Tx1).
Whenever I post Tx1 to a blockstream, it always returns an Invalid Schnoor Signature error.
I used the following code to generate the key pair in step 1:
let owner_keypair = Keypair::new(&secp, &mut rand::thread_rng());
let owner_seckey = SecretKey::from_keypair(&owner_keypair);
let owner_pubkey = PublicKey::from_keypair(&owner_keypair);
Since I know that the valid public keys in BIP340 are even-y coordinate public keys, should I adjust these keys before the aggregation step?
For reference, the function to generate aggregated keys is as follows:
pub fn aggregate_pubkeys(
owner_pubkey: PublicKey,
se_pubkey: PublicKey,
) -> (PublicKey, PublicKey, Address, KeyAggContext)
let secp = Secp256k1::new();
let mut pubkeys: Vec<PublicKey> = vec!();
pubkeys.push(owner_pubkey);
pubkeys.push(se_pubkey);
let key_agg_ctx_tw = KeyAggContext::new(pubkeys.clone())
.unwrap()
.with_unspendable_taproot_tweak()
.unwrap();
let aggregated_pubkey: PublicKey = key_agg_ctx_tw.aggregated_pubkey_untweaked();
let aggregated_pubkey_tw: PublicKey = key_agg_ctx_tw.aggregated_pubkey();
let aggregated_address = Address::p2tr(
&secp,
aggregated_pubkey.x_only_public_key().0,
None,
Network::Testnet,
);
(
aggregated_pubkey,
aggregated_pubkey_tw,
aggregated_address,
key_agg_ctx_tw,
)
Aggregated_pubkey is used to generate a scriptpubkey for Tx0, and Aggregated_pubkey_tw is used for the musig2 process. Thank you so much for your help.