bip-taproot/tapscript: abstract out the common message calculation
sipa opened this issue · 4 comments
Review comment by @gmaxwell: instead of describing the tapscript signature message as a "patch" of the taproot one, describe a common "base signature message" in bip-taproot (in a separate section), and then refer to it in both bip-taproot and bip-tapscript sighashing.
My idea to do this would be to define a function that takes as input the flags value (without annex or not), and returns a byte array. In bip-taproot sighashing is then described as hash_...(base_message(0)) and in bip-tapscript as hash_...(base_message(1) || ... the extra tapscript specific fields).
I guess that might look something like:
taproot_message(uint8_t hash_type, uint8_t spend_type, tx, uint32_t input_index) {
uint8_t epoch = 0;
bm = epoch + hash_type + tx.nVersion + tx.nLockTime
if ((hash_type & ANYONECANPAY)== 0) bm += sha_prevouts(tx) + sha_amounts(tx) + sha_sequences(tx);
if ((hash_type & (NONE | SINGLE) == 0) bm += sha_outputs(tx);
bm += spend_type + scriptPubKey(tx, input_index);
if (hash_type & ANYONECANPAY) {
bm += outpoint(tx,input_index) + amount(tx,input_index) + nSequence(tx,input_index);
} else {
bm += input_index;
}
if (spend_type & 1) bm += sha_annex(tx, input_index);
if (hash_type & SINGLE) bm += sha_single_output(tx, input_index);
return bm;
}
tapscript_message(uint8_t hash_type, uint8_t spend_type, tx, uint32_t input_index,
uint8_t key_version, uint32_t codeseparator_position)
{
msg = taproot_message(hash_type, (spend_type | 0x02), tx, input_index);
msg += tapleaf_hash + key_version + codeseparator_position;
return msg;
}
presuming sha_annex
and so on are defined in text. For anyprevout (which drops outpoint(tx,input_index)
rather than just adding stuff on the end) you'd have to redefine the whole block of code that way, but that's still probably easier to follow...
I was more thinking about keeping the existing "list of serialized fields" approach, but just separated out.
Not quite sure that would look like, but sounds plausible