This is my actual profile picture:
Many told me I look like an inmate, anyway it’s not the point here, let’s hash the file with sha256, from a terminal:
Or I can drop the file into Eternity Wall notarization service and get the following message:
It has been notarized on the blockchain at Sun Jan 31 2016 09:46:31 GMT+0100 (CET)
First of all, the resulting hash is the same. There is also a message saying the message has been notarized in the blockchain on Jan 31 2016. This means the document hash is written in a transaction confirmed in a block broadcasted that day. Since no one can rewrite the blockchain this assure the document existed at that time. The proof is reachable from the notarized link and contains the following json:
Let’s see what parameters means:
1454229991 is the date time information in unix format which translate to Sun Jan 31 2016 09:46:31 GMT+0100
ok is pretty straightforward, other possible results are
processing which means the hash commitment was already requested but still not being written in the blockchain. The last possible result is
not found when the hash was never seen before. In the latter case, you will be prompted if you want to notarize it.
bdbe9044539777f12cb6162f40e3aeb419ef1b2d3e9bd80d4a8c84f0a34d33c0 is the hash of the bitcoin transaction containing the root of the merkle tree representing the commitment in the blockchain. If you check on a block explorer this transaction, you will find the merkle root
53a1df014de8c698e25c1733aa2d3571e51f12b3578b268b318ac71af734480e in the tx op_return output (before this data there is the EW tag which is
4557 in hex for this example and EWC
455753 for actual production transactions).
But this is not yet the hash of my picture!
To understand how to verify the proof we need a digression on Merkle Tree
In cryptography and computer science, a hash tree or Merkle tree is a tree in which every non-leaf node is labelled with the hash of the labels or values (in case of leaves) of its children nodes. Hash trees are useful because they allow efficient and secure verification of the contents of large data structures. Hash trees are a generalization of hash lists and hash chains. - wikipedia
Eternity Wall is committing more than a single hash every time is writing on the blockchain. When it’s time to write all the hashes being queued are taken and sorted. In the following pictures they represent the leaf of the tree (Hash 0-0 Hash 0-1 Hash 1-0 Hash 1-1). The top hash is the root of the tree.
To prove the hash of my document is in the merkle tree, i need all off the leaf of the tree or the sibling till the root. If my Hash is 1-0, to derive the root I will need just the siblings Hash 1-1 and Hash 0 because I can compute:
Hash 1 = hash( Hash 1-0 + Hash 1-1 )
Top Hash = hash( Hash 0 + 1 )
Why can’t I just give all the tree leafs ? Because they are
N, while the siblings are just
log N. A proof of a very big merkle tree could be really compact.
Now that we now know more about merkle trees we come back to our data. Our siblings are:
["4c822a3b88741e8e83e7b9a289ffc97ba5dbb330cfbbf0cf67b94776edad9dcd", "414c7dd644620431dfd2636c27aadb7c59845258ab0f1efb813857b9edc38e94", "6e8d8f6163ef68207d6432bd6b368e90fbac65d0068bdcaf6b227066694b1a34"]
My hash is
20c7ba9c57f653b7c079df5171c196f494a5446d684c1b26a63bc5fc3fa2e25e which is the
sha256 of my document.
2 is representing the leaf position of my hash. The position is needed to understand the order of the hash in the concatenation, since the index
2 represent the third element (since index start from
0) the hash will be concateneted in the first position. So I compute:
Hash 536b = hash2( Hash 20c7 + Hash 4c82 )
Hash 20c7 is the hash of my picture and
Hash 4c82 is the first sibling.
hash2 is a double sha256.
Hash 2451 = hash2( Hash 414c + Hash 536b )
Hash 414c is the second sibling and
Hash 536b is the hash of the previous computation. At this level my index is
1 (previous index divided by two) so the previous Hash is in the second position.
Hash 0e48 = hash2( Hash 2451 + Hash 6e8d )
Hash 2451 is the hash of the previous computation and
Hash 6e8d is the first sibling
Hash 53a1 = reverse( Hash 0e48 )
Hash 0e48 is the hash of the previous computation and
Hash 53a1 is the merkle root. What was to be demonstrated.
What are you waiting for? Notarize documents on Eternity Wall :)