Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bip-taproot/tapscript: abstract out the common message calculation #99

Closed
sipa opened this issue Oct 19, 2019 · 4 comments
Closed

bip-taproot/tapscript: abstract out the common message calculation #99

sipa opened this issue Oct 19, 2019 · 4 comments

Comments

@sipa
Copy link
Owner

sipa commented Oct 19, 2019

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).

@ajtowns
Copy link

ajtowns commented Oct 19, 2019

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...

@sipa
Copy link
Owner Author

sipa commented Oct 22, 2019

I was more thinking about keeping the existing "list of serialized fields" approach, but just separated out.

@ajtowns
Copy link

ajtowns commented Oct 22, 2019

Not quite sure that would look like, but sounds plausible

@sipa
Copy link
Owner Author

sipa commented Jan 13, 2020

See #186.

@sipa sipa closed this as completed Jan 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants