Consider a simple Merkle Tree with leaves alice +100
and bob +50
. Using the SHA256 hash algorithm, the digest of the respective strings are:
# alice +100
dc2cac4a8aaeccc0199eeb77df68b22eaa6e319d3f2b425d078dbd73419e28ac
# bob +50
7e15e5bc1b84f458db7ced4df762ba70204f19e3a613738756f9b00653f0aee1
Being a hash function, SHA-256 is deterministic, so it doesn't matter which programming language we're implementing this in. For completeness sake, this can be done through the crypto-js
library:
const hash256 = (string) => {
const val =
require('crypto').createHash('sha256').update(string).digest('hex');
return val;
}
# apply
hash256('alice +100')
# results:
dc2cac4a8aaeccc0199eeb77df68b22eaa6e319d3f2b425d078dbd73419e28ac
When one refers to the Merkle Tree implementation, one see the following description:
A hash tree is a tree of hashes in which the leaves are hashes of data blocks in, for instance, a file or set of files. Nodes farther up in the tree are the hashes of their respective children. For example, in the above picture hash 0 is the result of hashing the concatenation of hash 0-0 and hash 0-1. That is, hash 0 = hash( hash(0-0) + hash(0-1) ) where +
denotes concatenation.
I've seen higher level library abstractions that implement this concatenation in the case of Buffer.concat()
, but I'd like to know how exactly would one implement this from a purely mathematical point of view.
One would assume (incorrectly):
alice_hash = hash256('alice +100')
bob_hash = hash256('bob +50')
# wrong
hash256(alice_hash + bob_hash)
# wrong also: adding the 0x-prefix
hash256(
'0xdc2cac4a8aaeccc0199eeb77df68b22eaa6e319d3f2b425d078dbd73419e28ac'
+
'0x7e15e5bc1b84f458db7ced4df762ba70204f19e3a613738756f9b00653f0aee1'
)
So without any abstractions, how would one concatenate the two hashes to obtain the resulting parent node?
For anyone trying to help, the correct value of hash(hash(alice) + hash(bob)) should be edf9a9a0e56b58fc9caccb97d85c628d5b9dc50cb94dfc41e83026d37704400f
. I tried adding / removing the 0x
prefix, adding one space character between them, and none of these attempts were fruitful. I also read papers I can get my hands on, but never got any farther than "concatenate them to obtain the value for the parent node" with very little implementation reference.