BitcoinJ Merkle Tree

Dieser Artikel bringt Euch eine Erfindung am Rande des Bitcoin-Universums näher, nämlich den „Merkle Tree“ oder auf deutsch „Hash-Baum“.

Laut deutscher Wikipedia (Artikel: https://de.wikipedia.org/wiki/Hash-Baum) lautet die Erläuterung wie folgt: „Ein Hash-Baum (englisch hash tree oder Merkle tree, nach dem Wissenschaftler Ralph Merkle) ist eine Datenstruktur in der Kryptographie und Informatik. Ein Hash-Baum ist ein Baum aus Hashwerten von Datenblöcken, beispielsweise von einer Datei. Hash-Bäume sind eine Erweiterung von Hash-Listen und dienen gleichermaßen dazu, die Integrität von Daten sicherzustellen.“

Was ist der Sinn und Zweck dieser Konstruktion? Ein kurzer Rückblick in den Aufbau einer Blockchain zeigt uns, das in einem Block viele Transaktionen enthalten sind und „in einem Rutsch“ verarbeitet werden. Jede dieser Transaktionen hat einen eigenen Transaktions-Hashwert – aber wie kann ich einfach und schnell sicherstellen, das mein Block auch alle Transaktionen beinhaltet, ohne die Datenmenge aufzublähen? Die Antwort liegt im Merkle Tree, der wie ein „umgekehrt“ wachsender Baum aufgezeichnet wird und ganz oben nur noch ein Element hat, die Wurzel oder „Root“. Der Hashwert dieses Wurzelelementes ist im Datensatz des Blockes verankert und wiederum ein Teil des Block-Hashwertes und damit vor nachträglichen Änderungen geschützt.

Wie wird nun ein Merkle Tree aufgebaut? Schauen wir uns eine Grafikdarstellung eines einfachen Baumes an (die Werte wurden mit dem nachfolgenden Testprogramm errechnet und sind damit auch nachvollziehbar):

Fangen wir unten an: wir haben insgesamt 8 Rohwerte („1“ bis „8“) und wir möchten sicherstellen, das alle 8 Rohwerte in unserem Baum enthalten sind. In Runde 1 bilden wir von jedem Rohwert des Hashwert. Wir nutzen hier das CRC32-Verfahren, da es uns ein kurzes Ergebnis liefert. Beim Bitcoin wird an dieser Stelle das SHA256-Hash Verfahren genutzt. Um an die Ergebnisse von Runde 2 zu gelangen, füge ich einfach die beiden CRC32-Werte vom Rohwert „1“ = „83dcefb7“ und Rohwert „2“ = „1ad5be0d“ zu einem neuen String „83dcefb71ad5be0d“ zusammen und bilde davon dann den CRC32-Hashwert „d658193f“. So verfahre ich mit allen Werten und am Ende (also ganz oben) erhalte ich den Wurzel- oder Root-Wert „686159e3“. Sollte der Merkle Tree nicht die exakt passende Anzahl an Rohwerten enthalten gibt es einfache Regeln, die für eine passende Anzahl sorgen.

Wie kann ich nun eine einfache Prüfroutine aufbauen, welche mir die gewünschte Bestätigung gibt, das „mein“ Rohwert auch im Merkle Tree beinhaltet ist? Schauen wir uns das zweite Bild an, bei dem die passenden Felder farblich eingefärbt sind:

Nehmen wir an, das sich unsere Frage auf das Rohelement „5“ bezieht. Dann liefert mir die sogenannte „Proof-Routine nur 3 weitere Werte: ich bekomme die Wertkombinationen „rechts 1db87a14“, „rechts 8a861521“ und „links d89aba0d“ genannt. Damit kann ich wieder die einzelnen CRC32-Hash Werte berechnen und komme am Ende zu meinem Root-Element „686159e3“. Die Worte „rechts“ und „links“ beziehen sich darauf, ob dieser Wert auf der rechten oder linken Seite der String-Zusammenfügung bezieht. Somit kann ich in 4 Schritten selber errechnen, das „mein“ Rohwert tatsächlich im gesamten Hash-Baum enthalten ist.

Natürlich ist es wichtig, das die verwendete Hashfunktion „einzigartige“ Werte liefert und die Funktion kryptografisch ungebrochen ist (daher noch einmal der Hinweis: die CRC32-Methode dient nur der Veranschaulichung, sollte aber nicht für „echte“ Bäume eingesetzt werden).

Hier nun das Programm und die Ausgabe auf der Konsole:

Den Quellcode zum Programm findet Ihr auch zum Download in meinem Github-Repository Timestamping, welches Ihr über diesen Link erreicht: https://github.com/java-crypto/Timestamping. Alle Programme sind unter Java 11 lauffähig (vermutlich auch unter Java 8) und wurden mit intelliJ IDEA entwickelt, welches für dieses Programm aber nicht notwendig ist.

Noch ein Wort zum Thema „Lizenz“: Die von mir erstellten Beispiele stehen unter der „Unlicense“-Lizenz.

Letzte Bearbeitung: 06.05.2020