Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save dgpv/f875e021905eb113070a23eb7fa981f6 to your computer and use it in GitHub Desktop.
Save dgpv/f875e021905eb113070a23eb7fa981f6 to your computer and use it in GitHub Desktop.
// bsst-name-alias(wit0): precomputed_sig_sans_last_byte
// bsst-name-alias(wit1): fee_script_pubkey_buffer
// bsst-name-alias(wit2): fee_amount_buffer
// bsst-name-alias(wit3): script_pubkey_buffer
// bsst-name-alias(wit4): amount_buffer
// bsst-name-alias(wit5): target_script_pubkey_buffer
// bsst-name-alias(wit6): code_separator_pos
// bsst-name-alias(wit7): key_version_0
// bsst-name-alias(wit8): leaf_hash
// bsst-name-alias(wit9): input_idx
// bsst-name-alias(wit10): spend_type
// bsst-name-alias(wit11): prev_sequences_single_hash
// bsst-name-alias(wit12): prevouts_single_hash
// bsst-name-alias(wit13): lock_time
// bsst-name-alias(wit14): tx_version
// bsst-name-alias(wit15): control
// bsst-name-alias(wit16): epoch
OP_TOALTSTACK // move pre-computed signature minus last byte to alt stack
OP_TOALTSTACK // push the fee-paying scriptpubkey to the alt stack
OP_TOALTSTACK // push the fee amount to the alt stack
OP_2DUP // make a second copy of the vault scriptpubkey and amount so we can check input = output
OP_TOALTSTACK // push the first copy of the vault scriptpubkey to the alt stack
OP_TOALTSTACK // push the first copy of the vault amount to the alt stack
OP_TOALTSTACK // push the second copy of the vault scriptpubkey to the alt stack
OP_TOALTSTACK // push the second copy of the vault amount to the alt stack
OP_TOALTSTACK // move the target scriptpubkey to the alt stack
// start with encoded leaf hash
OP_CAT // encoded leaf hash
OP_CAT // encoded leaf hash
OP_CAT // input index
OP_CAT // spend type
$DUST_AMOUNT // push the dust amount for the target output
OP_FROMALTSTACK // get the target scriptpubkey
OP_CAT // cat the dust amount and the target scriptpubkey
OP_FROMALTSTACK // get the output amount
OP_FROMALTSTACK // get the second copy of the scriptpubkey
OP_CAT // cat the output amount and the second copy of the scriptpubkey
OP_SWAP // put the outputs in the right order (vault then target)
OP_CAT // cat the vault output and target output together
OP_SHA256 // hash the output
// =>outputs_single_hash
OP_SWAP // move the hashed encoded outputs below our working sigmsg
OP_CAT // outputs
OP_CAT // prev sequences
OP_FROMALTSTACK // get the other copy of the vault amount
OP_FROMALTSTACK // get the other copy of the vault scriptpubkey
OP_FROMALTSTACK // get the fee amount
OP_FROMALTSTACK // get the fee-paying scriptpubkey
OP_SWAP // move the fee-paying scriptpubkey below the fee amount
OP_TOALTSTACK // move fee amount to alt stack
OP_CAT // cat the vault scriptpubkey fee-paying scriptpubkey
OP_SWAP // move the vault amount to the top of the stack
OP_TOALTSTACK // move the vault amount to the alt stack
OP_SHA256 // hash the scriptpubkeys, should now be consensus encoding
// =>spent_scripts_single_hash
OP_SWAP // move the hashed encoded scriptpubkeys below our working sigmsg
OP_CAT // prev scriptpubkeys
OP_FROMALTSTACK // get the vault amount
OP_FROMALTSTACK // get the fee amount
OP_CAT // cat the vault amount and the fee amount
OP_SHA256 // hash the amounts
// =>spent_amounts_single_hash
OP_SWAP // move the hashed encoded amounts below our working sigmsg
OP_CAT // prev amounts
OP_CAT // prevouts
OP_CAT // lock time
OP_CAT // version
OP_CAT // control
OP_CAT // epoch
// =>sig_hash
$TAPSIGHASH_TAG // push tag
OP_SHA256 // hash tag
OP_DUP // dup hash
OP_ROT // move the sighash to the top of the stack
OP_CAT
OP_CAT
OP_SHA256 // tagged hash of the sighash
// =>tagged_sig_hash
$BIP0340_CHALLENGE_TAG // push tag
OP_SHA256
OP_DUP
OP_ROT // bring challenge to the top of the stack
$G_X // G is used for the pubkey and K
OP_DUP
OP_DUP
OP_TOALTSTACK // we'll need a copy of G later to be our R value in the signature
OP_ROT // bring the challenge to the top of the stack
OP_CAT
OP_CAT
OP_CAT
OP_CAT // cat the two tags, R, P, and M values together
OP_SHA256 // hash the whole thing to get the s value for the signature
OP_FROMALTSTACK // bring G back from the alt stack to use as the R value in the signature
OP_SWAP
// =>s_value
OP_CAT // cat the R value with the s value for a complete signature
OP_FROMALTSTACK // grab the pre-computed signature minus the last byte from the alt stack
OP_DUP // we'll need a second copy later to do the actual signature verification
0x00 // add the last byte of the signature, which should match what we computed. NOTE ⚠️: push_int(0 will not work here because it will push OP_FALSE, but we want an actual 0 byte
OP_CAT
OP_ROT // bring the script-computed signature to the top of the stack
// =>script_computed_sig
OP_EQUALVERIFY // check that the script-computed and pre-computed signatures match
0x01 // we need the last byte of the signature to be 0x01 because our k value is 1 (because K is G)
OP_CAT
$G_X // push G again. TODO: DUP this from before and stick it in the alt stack or something
OP_CHECKSIG
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment