I think we should not be offering any API that operates on tweaked keys (See #563). It is a discouraged practice and is not supported in descriptors. Given that we already shipped this in a release version, I am looking for input on how to fix this.
I commented to fix this before release (#563 (comment)), but we forgot about it :) despite creating an issue about it. #585
Text from BIP-341:
Why should the output key always have a taproot commitment, even if there is no script path? If the taproot output key is an aggregate of keys, there is the possibility for a malicious party to add a script path without being noticed by the other parties. This allows to bypass the multiparty policy and to steal the coin. MuSig key aggregation does not have this issue because it already causes the internal key to be randomized. The attack works as follows: Assume Alice and Mallory want to aggregate their keys into a taproot output key without a script path. In order to prevent key cancellation and related attacks they use MSDL-pop instead of MuSig. The MSDL-pop protocol requires all parties to provide a proof of possession of their corresponding secret key and the aggregated key is just the sum of the individual keys. After Mallory receives Alice's key A, Mallory creates M = M0 + int(t)G where M0 is Mallory's original key and t allows a script path spend with internal key P = A + M0 and a script that only contains Mallory's key. Mallory sends a proof of possession of M to Alice and both parties compute output key Q = A + M = P + int(t)G. Alice will not be able to notice the script path, but Mallory can unilaterally spend any coin with output key Q.
As for rust-bitcoin library, I think all APIs should deal with untweaked keys. There should not be any type of Tweaked keys.
Current function signature.
/// Create a pay to taproot address
pub fn p2tr(taptweaked_key: schnorrsig::PublicKey, network: Network) -> Address {
}
Expect function signature
pub fn p2tr<C: secp256k1::Verification>(
secp: Secp256k1<C>,
internal_key: schnorrsig::PublicKey,
merkle_root: Option<TapBranchHash>,
network: Network)
-> Address {
}
I think we should not be offering any API that operates on tweaked keys (See #563). It is a discouraged practice and is not supported in descriptors. Given that we already shipped this in a release version, I am looking for input on how to fix this.
I commented to fix this before release (#563 (comment)), but we forgot about it :) despite creating an issue about it. #585
Text from BIP-341:
Why should the output key always have a taproot commitment, even if there is no script path? If the taproot output key is an aggregate of keys, there is the possibility for a malicious party to add a script path without being noticed by the other parties. This allows to bypass the multiparty policy and to steal the coin. MuSig key aggregation does not have this issue because it already causes the internal key to be randomized. The attack works as follows: Assume Alice and Mallory want to aggregate their keys into a taproot output key without a script path. In order to prevent key cancellation and related attacks they use MSDL-pop instead of MuSig. The MSDL-pop protocol requires all parties to provide a proof of possession of their corresponding secret key and the aggregated key is just the sum of the individual keys. After Mallory receives Alice's key A, Mallory creates M = M0 + int(t)G where M0 is Mallory's original key and t allows a script path spend with internal key P = A + M0 and a script that only contains Mallory's key. Mallory sends a proof of possession of M to Alice and both parties compute output key Q = A + M = P + int(t)G. Alice will not be able to notice the script path, but Mallory can unilaterally spend any coin with output key Q.As for rust-bitcoin library, I think all APIs should deal with untweaked keys. There should not be any type of Tweaked keys.
Current function signature.
Expect function signature