I am trying to follow BIP341 to understand the signature hash calculation for taproot script path spends.

From the bitcoin testing framework code, I see that if the transaction is spending from a script path (as opposed to a key path spend), the sighash needs these additional bytes appended.

    if (scriptpath):
        ss += TaggedHash("TapLeaf", bytes([leaf_ver]) + ser_string(script))
        ss += bytes([0])
        ss += struct.pack("<i", codeseparator_pos)

Where are these bytes described in the BIP?

And in case it's not clear from the BIP, what is the purpose for the last two lines: 0x00 and struct.pack("<i", codeseparator_pos)?

1 Answer 1


You'll find this in BIP342, under common signature message extension. BIP342 signatures reuse most of the BIP341 signature hash structure, but add a few fields of their own, as well as changing a flag bit:

  • The tapleaf hash: spending using a BIP342 script requires committing to the actual script's hash (the "tapleaf") to make sure a signature created for one leaf can't be reused in other leaves. This makes it safe to to reuse the same keys multiple times in separate scripts of the same output.
  • The key version: since BIP342 allows the introduction of new public key types (without new witness version, leaf version, or new opcodes), there is one reserved byte for indicating what public key type is used for this signature. This is always 0 for now.
  • The code separator position: to enable (one of) the uses of OP_CODESEPARATOR to remain in this new model, its semantics were changed. Instead of truncating the "scriptCode" (a concept that no longer exists in taproot scripts), it just records when (in number of executed and/or skipped opcodes) the last OP_CODESEPARATOR was executed, and that number is included in the sighash. If no such opcode was ever executed, the number is 0xffffffff instead. The purpose of this is allowing someone to construct a script that defeats some form of malleability: a signature for a checksig operation before and after an executed OP_CODESEPARATOR cannot be reused in the other position, even if they use the same public key.

BIP341 describes the general structure of taproot outputs and spending, and the key path spending rules. It describes what script path spending is, but the actual script semantics that apply in this case are left for future extensions. BIP342 specifically describes the script semantics for taproot leaf scripts with leaf version 0xc0. Other leaf versions could be described by future BIPs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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