The issue is a double tweak.
python-bitcoinutils applies a BIP86 tweak internally whenever you name get_taproot_address(). You probably have already utilized a BIP86 tweak manually to the mixture key, the on-chain output key has been tweaked twice.
Native schnorr_verify passes as a result of it checks in opposition to the important thing you present — it doesn’t know what is definitely on-chain. Bitcoin Core checks in opposition to the true output key, which has two tweaks utilized. The signature constructed with just one tweak is invalid in opposition to that key.
The repair: SessionContext should carry each tweaks explicitly:
pythonsession_ctx = SessionContext(
aggnonce, pubkeys,
[tweak1, tweak2], # each tweaks required
[True, True],
msg
)
This isn’t a bug — the library handles BIP86 mechanically for typical single-key use. In MuSig2, the place you handle tweaks manually, the abstraction leaks.
Verified on testnet: af6fdae8…9d1f
The issue is a double tweak.
python-bitcoinutils applies a BIP86 tweak internally whenever you name get_taproot_address(). You probably have already utilized a BIP86 tweak manually to the mixture key, the on-chain output key has been tweaked twice.
Native schnorr_verify passes as a result of it checks in opposition to the important thing you present — it doesn’t know what is definitely on-chain. Bitcoin Core checks in opposition to the true output key, which has two tweaks utilized. The signature constructed with just one tweak is invalid in opposition to that key.
The repair: SessionContext should carry each tweaks explicitly:
pythonsession_ctx = SessionContext(
aggnonce, pubkeys,
[tweak1, tweak2], # each tweaks required
[True, True],
msg
)
This isn’t a bug — the library handles BIP86 mechanically for typical single-key use. In MuSig2, the place you handle tweaks manually, the abstraction leaks.
Verified on testnet: af6fdae8…9d1f
















