___
/\__\
/:/__/_
/::\/\__\
\/\::/ /
/:/ /
\/__/
HSD - Merkle Tree
Merkle hash trees are used to audit/verify large data structures. Handshake, Bitcoin and many other protocols use it with transaction hashes to provide efficient proofs of inclusion in blocks.
Handshake uses a different Merkle hash tree than Bitcoin for transactions. The Handshake hash tree is based on RFC 6962 and integrates a padding idea from RFC 7574. The motivation to switch Merkle tree algorithms was to fix known issues with the Bitcoin Merkle tree: hsd discussion, attack description.
How it works
The Handshake Merkle tree uses blake2b as the hash function. In general it follows the flow described in RFC 6962:
Define
EMPTY_HASH = blake2b(EMPTY_BUFFER)Given
ninputsd[0...n], each input is hashed asblake2b(0x00 || d[i]). These inputs are transaction hashes (txid).All internal nodes are hashed using
blake2b(0x01 || leftHash || rightHash), but ifrightHashis missing thenEMPTY_HASHis used instead. This is similar to RFC 7574.
Example 1
Block with 4 transactions:
Merkle root
/ \
/ \
/ \
/ \
e f
/ \ / \
/ \ / \
a b c d
| | | |
d0 d1 d2 d3
a=blake2b(0x00 || d0)b=blake2b(0x00 || d1)c=blake2b(0x00 || d2)d=blake2b(0x00 || d3)e=blake2b(0x01 || a || b)f=blake2b(0x01 || c || d)Merkle root=blake2b(0x01 || e || f)
Example 2
Block with 6 transactions:
Merkle root
/ \
/ \
/ \
/ \
j k
/ \ / \
/ \ / \
/ \ / \
/ \ / \
g h i EMPTY_HASH
/ \ / \ / \
/ \ / \ / \
a b c d e f
| | | | | |
d0 d1 d2 d3 d4 d5
a=blake2b(0x00 || d0)b=blake2b(0x00 || d1)c=blake2b(0x00 || d2)d=blake2b(0x00 || d3)e=blake2b(0x00 || d4)f=blake2b(0x00 || d5)g=blake2b(0x01 || a || b)h=blake2b(0x01 || c || d)i=blake2b(0x01 || e || f)j=blake2b(0x01 || g || h)k=blake2b(0x01 || i || EMPTY_HASH)Merkle root=blake2b(0x01 || j || k)
Example 3
Block with 5 transactions:
Merkle root
/ \
/ \
/ \
/ \
i j
/ \ / \
/ \ / \
/ \ / \
/ \ / \
f g h EMPTY_HASH
/ \ / \ / \
/ \ / \ / \
a b c d e EMPTY_HASH
| | | | |
d0 d1 d2 d3 d4
a=blake2b(0x00 || d0)b=blake2b(0x00 || d1)c=blake2b(0x00 || d2)d=blake2b(0x00 || d3)e=blake2b(0x00 || d4)f=blake2b(0x01 || a || b)g=blake2b(0x01 || c || d)h=blake2b(0x01 || e || EMPTY_HASH)i=blake2b(0x01 || f || g)j=blake2b(0x01 || h || EMPTY_HASH)Merkle root=blake2b(0x01 || i || j)
Example 5
Block with 1 transaction:
Merkle root
|
d0
Merkle root=blake2b(0x00 || d0)