Skip to content

Commit

Permalink
Merge pull request #43 from guggero/tlv-re-numbering
Browse files Browse the repository at this point in the history
Use even/odd TLV numbers everywhere
  • Loading branch information
Roasbeef authored Oct 10, 2023
2 parents 58b218e + 1828353 commit 666d60e
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 61 deletions.
35 changes: 19 additions & 16 deletions bip-tap-addr.mediawiki
Original file line number Diff line number Diff line change
Expand Up @@ -62,40 +62,43 @@ key, 8-byte amount to send, an address is encoded as:
where <code>addr_tlv_payload</code> is a TLV payload composed of the following
types:
* type: 0 (<code>taproot_asset_version</code>)
* type: 0 (<code>taproot_address_version</code>)
** value:
*** [<code>u8</code>:<code>version</code>]
* type: 2 (<code>asset_id</code>)
* type: 2 (<code>taproot_asset_version</code>)
** value:
*** [<code>u8</code>:<code>version</code>]
* type: 4 (<code>asset_id</code>)
** value:
*** [<code>32*byte</code>:<code>asset_id</code>]
* type: 3 (<code>asset_key_family</code>)
* type: 5 (<code>asset_group_key</code>)
** value:
*** [<code>33*byte</code>:<code>family_key</code>]
* type: 4 (<code>asset_script_key</code>)
*** [<code>33*byte</code>:<code>group_key</code>]
* type: 6 (<code>asset_script_key</code>)
** value:
*** [<code>33*byte</code>:<code>script_key</code>]
* type: 6 (<code>internal_key</code>)
* type: 8 (<code>internal_key</code>)
** value:
*** [<code>33*byte</code>:<code>taproot_internal_key</code>]
* type: 7 (<code>taproot_sibling_preimage</code>)
* type: 9 (<code>taproot_sibling_preimage</code>)
** value:
*** [<code>...*byte</code>:<code>tapscript_preimage</code>]
* type: 8 (<code>amt</code>)
* type: 10 (<code>amt</code>)
** value:
*** [<code>BigSize</code>:<code>amt_to_send</code>]
* type: 10 (<code>proof_courier_addr</code>)
* type: 12 (<code>proof_courier_addr</code>)
** value:
*** [<code>...*byte</code>:<code>proof_courier_addr</code>]
Inspired by Lightning's BOLT specification, we adopt the "it's OK to be odd"
semantics here as well. This enables receivers to specify to the caller certain
information that MUST be known in order to properly complete a transfer.

The only odd keys specified in the current version are the
<code>asset_key_family</code> type and the <code>asset_type</code> field. The
<code>asset_key_family</code> field isn't always needed for assets that don't
allow for continual re-issuance. Similarly, if the <code>asset_type</code>
field isn't specified, then one can assume a normal asset is being sent.
The only odd keys specified in the current version
(<code>taproot_address_version = 0</code>) are the <code>asset_group_key</code>
type and the <code>taproot_sibling_preimage</code> field. The
<code>asset_group_key</code> field isn't always needed for assets that don't
allow for continual re-issuance.

The <code>proof_courier_addr</code> is a mandatory URI (RFC 3986) that indicates
what proof courier to use when sending the proofs from the sender to the
Expand All @@ -114,12 +117,12 @@ Construct a new blank Taproot Asset leaf according to the default
[[./bip-tap.mediawiki#asset-leaf-format|Asset Leaf Format]] with the following
values being set explicitly (and all other values being their default/zero
values):
* <code>taproot_asset_version</code>: <code>0</code>
* <code>taproot_asset_version</code>: <code>taproot_asset_version</code>
* <code>asset_genesis</code>: <code>asset_genesis</code>
* <code>amt</code>: <code>amt_to_send</code>
* <code>asset_script_version</code>: <code>0</code>
* <code>asset_script_key</code>: <code>asset_script_key</code>
* <code>asset_key_family</code>: <code>asset_key_family</code>
* <code>asset_group_key</code>: <code>asset_group_key</code>
Create a valid tapscript root, using leaf version <code>0x0c</code> with the
sole leaf being the serialized TLV blob specified above.
Expand Down
52 changes: 26 additions & 26 deletions bip-tap-proof-file.mediawiki
Original file line number Diff line number Diff line change
Expand Up @@ -67,74 +67,74 @@ blob with the following format:
* type: 0 (<code>version</code>)
** value:
*** [<code>uint32</code>:<code>version</code>]
* type: 1 (<code>prev_out</code>)
* type: 2 (<code>prev_out</code>)
** value:
*** [<code>36*byte</code>:<code>txid || output_index</code>]
* type: 2 (<code>block_header</code>)
* type: 4 (<code>block_header</code>)
** value:
*** [<code>80*byte</code>:<code>bitcoin_header</code>]
* type: 3 (<code>anchor_tx</code>)
* type: 6 (<code>anchor_tx</code>)
** value:
*** [<code>...*byte</code>:<code>serialized_bitcoin_tx</code>]
* type: 4 (<code>anchor_tx_merkle_proof</code>)
* type: 8 (<code>anchor_tx_merkle_proof</code>)
** value:
*** [<code>...*byte</code>:<code>merkle_inclusion_proof</code>]
* type: 5 (<code>taproot_asset_asset_leaf</code>)
* type: 10 (<code>taproot_asset_asset_leaf</code>)
** value:
*** [<code>tlv_blob</code>:<code>serialized_tlv_leaf</code>]
* type: 6 (<code>taproot_asset_inclusion_proofs</code>)
* type: 12 (<code>taproot_asset_inclusion_proofs</code>)
** value:
*** [<code>...*byte</code>:<code>taproot_asset_taproot_proof</code>]
**** type: 0 (<code>output_index</code>
***** value: [<code>int32</code>:<code>index</code>]
**** type: 1 (<code>internal_key</code>
**** type: 2 (<code>internal_key</code>
***** value: [<code>33*byte</code>:<code>y_parity_byte || schnorr_x_only_key</code>]
**** type: 2 (<code>taproot_asset_proof</code>)
**** type: 3 (<code>taproot_asset_proof</code>)
***** value: [<code>...*byte</code>:<code>asset_proof</code>]
****** type: 0 (<code>taproot_asset_proof</code>)
****** type: 1 (<code>taproot_asset_proof</code>)
******* value: [<code>...*byte</code>:<code>asset_inclusion_proof</code>]
******* type: 0
******** value: [<code>uint32</code>:<code>proof_version</code>]
******* type: 1
******** value: [<code>32*byte</code>:<code>asset_id</code>]
******* type: 2
******** value: [<code>32*byte</code>:<code>asset_id</code>]
******* type: 4
******** value: [<code>...*byte</code>:<code>ms_smt_inclusion_proof</code>]
****** type: 1 (<code>taproot_asset_inclusion_proof</code>)
****** type: 2 (<code>taproot_asset_inclusion_proof</code>)
******* value: [<code>...*byte</code>:<code>taproot_asset_inclusion_proof</code>]
******* type: 0
******** value: [<code>uint32</code>:<code>proof_version</code>]
******* type: 1
******* type: 2
******** value: [<code>...*byte</code>:<code>ms_smt_inclusion_proof</code>]
******* type: 2 (<code>taproot_sibling_preimage</code>)
******** value: [<code>byte</code>:<code>sibling_type</code>][<code>varint</code>:<code>num_bytes</code>][<code>...*byte</code>:<code>tapscript_preimage</code>]
**** type: 3 (<code>taproot_asset_commitment_exclusion_proof</code>
****** type: 5 (<code>taproot_sibling_preimage</code>)
******* value: [<code>byte</code>:<code>sibling_type</code>][<code>varint</code>:<code>num_bytes</code>][<code>...*byte</code>:<code>tapscript_preimage</code>]
**** type: 5 (<code>taproot_asset_commitment_exclusion_proof</code>
***** value: [<code>...*byte</code>:<code>taproot_exclusion_proof</code>]
****** type: 0 (<code>tap_image_1</code>)
****** type: 1 (<code>tap_image_1</code>)
******* value: [<code>...*byte</code>:<code>tapscript_preimage</code>]
****** type: 1 (<code>tap_image_2</code>)
****** type: 3 (<code>tap_image_2</code>)
******* value: [<code>...*byte</code>:<code>tapscript_preimage</code>]
****** type: 2 (<code>bip_86</code>)
****** type: 4 (<code>bip_86</code>)
******* value: [<code>byte 0x00/0x01</code>:<code>bip_86</code>]
* type: 7 (<code>taproot_exclusion_proofs</code>)
* type: 13 (<code>taproot_exclusion_proofs</code>)
** value:
*** [<code>uint16</code>:<code>num_proofs</code>][<code>...*byte</code>:<code>taproot_asset_taproot_proof</code>]
* type: 8 (<code>split_root_proof</code>)
* type: 15 (<code>split_root_proof</code>)
** value:
*** [<code>...*byte</code>:<code>taproot_asset_taproot_proof</code>]
* type: 9 (<code>meta_reveal</code>)
* type: 17 (<code>meta_reveal</code>)
** value:
*** [<code>...*byte</code>:<code>asset_meta_reveal</code>]
**** type: 0 (<code>meta_type</code>
***** value: [<code>uint8</code>:<code>type</code>]
**** type: 1 (<code>meta_data</code>
**** type: 2 (<code>meta_data</code>
***** value: [<code>*byte</code>:<code>meta_data_bytes</code>]
* type: 10 (<code>taproot_asset_input_splits</code>)
* type: 19 (<code>taproot_asset_input_splits</code>)
** value:
*** [<code>...*byte</code>:<code>nested_proof_map</code>]
* type: 11 (<code>challenge_witness</code>)
* type: 21 (<code>challenge_witness</code>)
** value:
*** [<code>...*byte</code>:<code>challenge_witness</code>]
* type: 12 (<code>block_height</code>)
* type: 22 (<code>block_height</code>)
** value:
*** [<code>uint32</code>:<code>block_height</code>]
Expand Down
10 changes: 5 additions & 5 deletions bip-tap-vm.mediawiki
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ follows:
# For collectible asset transfers
## Let the output value be exactly ''1'' (as each TLV leaf related to a collectible can only ever transfer that same collectible to another leaf).
## Let the output script be the first 32-bytes of an MS-SMT tree with a single element of the serialized TLV leaf of the collectible.
### The key for this single value is <code>sha256(asset_key_family || asset_id || asset_script_key)</code>. If a <code>asset_key_family</code> field isn't specified, then 32-bytes of zeroes should be used in place.
### The key for this single value is <code>sha256(asset_group_key || asset_id || asset_script_key)</code>. If a <code>asset_group_key</code> field isn't specified, then 32-bytes of zeroes should be used in place.
The following algorithm implements the output mapping required for full state
transition verification:
Expand All @@ -150,7 +150,7 @@ make_virtual_txout(leaf: TaprootAssetLeaf) -> (MerkleSumRoot, TxOut):
case Collectible:
output_smt = new_ms_smt()
output_smt.insert(
key=sha256(leaf.asset_key_family || leaf.asset_id || leaf.asset_script_key)
key=sha256(leaf.asset_group_key || leaf.asset_id || leaf.asset_script_key)
value=leaf.serialize_tlv(),
sum_value=1,
)
Expand Down Expand Up @@ -185,7 +185,7 @@ modifications:
## All signatures included in the witness MUST be exactly 64-bytes in length, which triggers <code>SIGHASH_DEFAULT</code> evaluation.
## If the <code>prev_asset_id</code> is blank, then ALL witnesses MUST be blank as well and the <code>prev_outpoint</code> values as well. In this case, verification succeeds as this is only a creation/minting transaction.
## If the <code>asset_id</code> value is NOT the same for each Taproot Asset input and output, validation MUST fail.
### Alternatively, assert that each input and output references the same <code>asset_family_key</code> field.
### Alternatively, assert that each input and output references the same <code>asset_group_key</code> field.
## Perform external lock time and relative lock time validation:
### If a <code>relative_lock_time</code> field exists, if the input age of the referenced TLV leaf is less than <code>relative_lock_time</code> validation MUST fail.
### If a <code>lock_time</code> field exists, if the block height of the block that includes the transaction is less than <code>lock_time</code> validation MUST fail.
Expand Down Expand Up @@ -231,8 +231,8 @@ verify_taproot_asset_state_transition(leaf: TaprootAssetLeaf, leaf_split: Taproo
case AssetID:
if input.asset_id != leaf.asset_id:
return false
case KeyFamily:
if input.asset_key_family != leaf.asset_key_family:
case GroupKey:
if input.asset_group_key != leaf.asset_group_key:
return false
virtual_tx = virtual_tx_template.clone()
Expand Down
30 changes: 16 additions & 14 deletions bip-tap.mediawiki
Original file line number Diff line number Diff line change
Expand Up @@ -476,11 +476,13 @@ commitments and signed digests. In addition, the TLV format supports both
backwards and forwards compatibility, making the underlying structure of the
asset commitments highly extensible.

An asset leaf is a serialized TLV blob, with the following key-value mappings:
An asset leaf is a serialized TLV blob, with the following key-value mappings
(using the same "it's OK to be odd" semantics inspired by Lightning's BOLT
specification):
* type: 0 (<code>taproot_asset_version</code>)
** value:
*** [<code>u8</code>:<code>version</code>]
* type: 1 (<code>asset_genesis</code>)
* type: 2 (<code>asset_genesis</code>)
** value:
*** [<code>32*byte</code>:<code>first_prev_out_hash</code>]
*** [<code>u32</code>:<code>first_prev_out_index</code>]
Expand All @@ -490,39 +492,39 @@ An asset leaf is a serialized TLV blob, with the following key-value mappings:
*** [<code>metadata_len*byte</code>:<code>metadata</code>]
*** [<code>u32</code>:<code>output_index</code>]
*** [<code>u8</code>:<code>type</code>]
* type: 2 (<code>asset_type</code>)
* type: 4 (<code>asset_type</code>)
** value:
*** [<code>u8</code>:<code>type</code>]
* type: 3 (<code>amt</code>)
* type: 6 (<code>amt</code>)
** value:
*** [<code>BigSize</code>:<code>amt</code>]
* type: 4 (<code>lock_time</code>)
* type: 7 (<code>lock_time</code>)
** value:
*** [<code>BigSize</code>:<code>block_height</code>]
* type: 5 (<code>relative_lock_time</code>)
* type: 9 (<code>relative_lock_time</code>)
** value:
*** [<code>BigSize</code>:<code>num_relative_blocks</code>]
* type: 6 (<code>prev_asset_witnesses</code>)
* type: 11 (<code>prev_asset_witnesses</code>)
** value:
*** [<code>u16</code>:<code>num_inputs</code>][<code>asset_witnesses...</code>], where:
**** [<code>...*byte</code>:<code>asset_witnesses</code>]:
***** [<code>asset_witness</code>]:
****** type: 0 (<code>prev_asset_id</code>)
****** type: 1 (<code>prev_asset_id</code>)
******* value: [<code>prev_outpoint || asset_id || asset_script_key</code>]
****** type: 1 (<code>asset_witness</code>)
****** type: 3 (<code>asset_witness</code>)
******* value: [<code>...*byte</code>:<code>asset_witness</code>]
****** type: 2 (<code>split_commitment</code>)
****** type: 5 (<code>split_commitment</code>)
******* value: [<code>...*byte</code>:<code>split_commitment_proof</code>]
******* value: [<code>...*byte</code>:<code>root_asset</code>]
* type: 7 (<code>split_commitment_root</code>)
* type: 13 (<code>split_commitment_root</code>)
** value: [<code>32*byte</code>:<code>split_commitment_root</code>]
* type: 8 (<code>asset_script_version</code>)
* type: 14 (<code>asset_script_version</code>)
** value:
*** [<code>u16</code>:<code>script_version</code>]
* type: 9 (<code>asset_script_key</code>)
* type: 16 (<code>asset_script_key</code>)
** value:
*** [<code>33*byte</code>:<code>pub_key</code>]
* type: 10 (<code>asset_group_key</code>)
* type: 17 (<code>asset_group_key</code>)
** value:
*** [<code>96*byte</code>:<code>pub_key || schnorr_sig</code>]
Expand Down

0 comments on commit 666d60e

Please sign in to comment.