0

I know that Taproot does not use pubkey hashes, but I want to compute a HASH160 of a 32 byte Taproot X-only public key anyway. The rationale is to compare it to an existing 20 byte HASH160 from a Witness V0 ScriptPubKey, to see if the same underlying public key is used in both outputs.

Is it correct to just pre-pend 0x02 byte to the 32-byte XOnlyPublicKey? I sketched this using rust-bitcoin:

// Taproot. In the case of the key-path spend, the pub key is not tweaked.
//It is 32-byte only X-coordinate however, missing the 33-d byte Y "tie-breaker"
//https://archive.is/AsKEb
//From BIP 340: "To avoid gratuitous incompatibilities, we pick that option for P, and thus
//our X-only public keys become equivalent to a compressed public key that is the X-only key prefixed by the byte 0x02."
let witness_program_bytes = program.program().as_bytes();
//Y-coordinate absent:
assert_eq!(witness_program_bytes.len(), 32);
let mut witness_program_vec = witness_program_bytes.to_vec();
//BIP 340:
witness_program_vec.insert(0, 0x02);
// it is the actual compressed 33 byte pubkey
let pk = PublicKey::from_slice(&witness_program_vec).unwrap();

1 Answer 1

-2

I'm not 100% sure about it, but if taproot output XOnlyPublicKey is not tweaked, and if you try to compare with existing p2wpkh output which uses the same public key, you should try both 0x02 or 0x03 as both Y coordinate are possible. As far as I know, even Y(0x02) is implicitly used for efficient and compatible verifications. Therefore, it's still possible to use XOnlyPublicKey which Y coordinate is odd(0x03), as taproot key output.

You can also refer this answer, which describes the implicit Y coordinate in detail.

Not the answer you're looking for? Browse other questions tagged or ask your own question.