In diesem Beitrag soll es rund um das Thema Ableitungspfade gehen und wie eine Wallet es schafft aus unserer Mnemonic, also den 12 bzw. 24 Wörtern, praktisch unendlich viele Schlüssel abzuleiten. Es ist klar, dass es sich hier um ein eher unwichtiges Thema, zumindest für den Endnutzer, handelt, weshalb der Beitrag auch in aufsteigender Schwierigkeit geschrieben wurde.

Das heißt, die ersten Absätze sollten für alle verständlich - und wichtig - sein, während es gegen Ende etwas mehr ins Detail geht. Das Thema ist teilweise sehr abstrakt, deswegen scheut euch nicht unklare Fragen direkt im entsprechenden Thread im Blocktrainer-Forum zu stellen. 

Nur ein Schlüssel(bund)

Um wirklich alle abzuholen, müssen wir uns zunächst einmal klarmachen, was eine Wallet konkret überhaupt ist. Hier ein paar Mythen, die wir zunächst aus dem Weg räumen bzw. einige Formulierungen eindeutig ausführen müssen:

  • Eine Wallet kontrolliert keine Bitcoin, sondern Schlüssel zu den Bitcoin.
  • Bitcoin liegen nicht auf einer Wallet, sondern Schlüssel liegen auf der Wallet.
  • Eine Mnemonic bzw. eine Seedphrase ist kein Backup der Bitcoin - sondern ein Backup der Schlüssel zu den Bitcoin.
  • Der Seed, die Schlüssel und sogar Adressen sind nichts anderes als sehr große Zahlen.

Lese-Tipp: Was ist eine Wallet?

Vielleicht denkt man sich nun: Wo ist denn da der Unterschied?

Ein Ersatzschlüssel eurer Wohnung ist kein Ersatz für eure Wohnung, sondern ein Ersatz für den Zugang zur Wohnung. Anders als bei einer Wohnung müssen wir uns um die Sicherheit der Bitcoin selbst absolut keine Gedanken machen, da diese unveränderlich auf einer dezentralen Datenbank (der Blockchain) gesichert sind. Deshalb verändert auch eine ein- oder ausgehende Transaktion nichts an den Backups, da die Schlüssel immer noch dieselben sind. Egal, wie viele Bitcoin wir empfangen oder ausgeben, unser Anfangs erstelltes Backup ist immer noch gültig, da die Schlüssel gleich geblieben sind.

Wieder das Beispiel Wohnung: Wenn wir uns einen neuen Schrank ins Schlafzimmer stellen, bleibt der Haustürschlüssel der gleiche. Worüber wir uns also Gedanken machen müssen: Die Sicherheit unserer Schlüssel!

Nicht-deterministische Wallets

Heutzutage benutzen die wenigsten von uns noch sogenannte nicht-deterministische Wallets (auch random wallets gennant), da sie in der Benutzung extrem unpraktisch sind. Viele von uns kennen das Konzept einer Mnemonic Phrase, also den Wiederherstellungswörtern, doch diese gibt es bei einer nicht-deterministischen Wallet gar nicht.

Vereinfacht: Zu jeder Adresse gehört ein öffentlicher Schlüssel, und zu diesem öffentlichen Schlüssel gehört ein privater Schlüssel. Diese Ableitung funktioniert nur in eine Richtung:

Die Adresse brauche ich, um Bitcoin zu empfangen, den privaten Schlüssel, um die Bitcoin auf der Adresse auszugeben und den öffentlichen Schlüssel, um zu beweisen, dass der private Schlüssel auch wirklich zu dieser Adresse gehört. Bei einer nicht-deterministischen Wallet stehen alle Schlüsselpaare für sich und haben nichts miteinander zu tun. Das bedeutet: Jeder private Schlüssel muss einzeln abgesichert werden, da ich keinen „Hauptschlüssel“ habe, mit dem ich auf alle anderen Schlüssel zurückschließen kann.

Das ist extrem unpraktisch. Erstens, weil es sowieso schon mühsamer ist einen komplexen Schlüssel zu notieren (anstatt einfache englische Wörter) und zweitens, weil ich für jede neue Adresse, die ich generiere, auch wieder ein neues Backup machen muss. Das kollidiert mit dem gewünschten Anreiz aufgrund von Privatsphäre immer neue Adressen zu verwenden.

Viele von euch haben so eine Wallet trotzdem schon einmal benutzt, denn eine einfache Paper-Wallet ist nichts anderes als eine nicht-deterministische Wallet. Auch die allererste Bitcoin Wallet (in Bitcoin Core) ist bis heute eine solche zufällige und ungeordnete Wallet.

Wir merken uns: Unsere Schlüssel fliegen wahllos im Geldbeutel herum und haben keinen Bezug zueinander. Das ist unpraktisch und in der Nutzung auch mit erheblichen Risiken behaftet.

Bild: Mastering Bitcoin, Kapitel 5 – LINK

HD Wallets

Jetzt bringen wir etwas mehr Ordnung ins Spiel und kommen zur heute gängigen hierarchisch-deterministischen (HD) Wallet, die wahrscheinlich jeder von euch selbst nutzt. Anders als beim vorherigen Beispiel stehen unsere Schlüssel in direkter Beziehung zueinander und wurden alle aus einem Generalschlüssel abgeleitet, auch bekannt als Seed.

Bild: Mastering Bitcoin, Kapitel 5 – LINK

Wir haben jetzt nur noch einen Generalschlüssel, mit dem wir beliebig viele, ja sogar praktisch unendlich viele Schlüssel bzw. Adressen ableiten können. Diesen Generalschlüssel erzeugen wir mithilfe einer langen Zufallszahl und diese Zufallszahl können wir auch in lesbare Wörter codieren, um einen einfachen Backup-Prozess zu ermöglichen:

worth unknown mean plastic neglect flip guilt library ripple explain destroy thing rival put usage tackle craft cheese

256 bit Entropie (inkl. Checksumme) codiert als Mnemonic

fdfdbe27530940b219ec08ba4a10f0f05bab5dbbe6e83204

Dieselben 256 bit Entropie in Hexadezimaler Schreibweise

Auch wenn uns dieses geordnete Konstrukt das Leben deutlich leichter macht, stehen wir jetzt vor einem Problem. Der Begriff hierarchisch bedeutet, dass wir in einer baumartigen Struktur von unten (Seed bzw. Wurzel) nach oben (Krone) ableiten. Wie bei einem Baum gibt es hier keinen eindeutigen Weg, sondern wir können beliebige Verästelungen einschlagen auf dem Weg bis zur Krone.

Bild: Mastering Bitcoin, Kapitel 5 – LINK

Auf dieser Grafik sehen wir, wie aus dem Seed ein Schlüssel generiert wird. Aus diesem Schlüssel werden wiederum neue Schlüssel generiert, aus denen wiederum neue Schlüssel generiert werden, aus denen wiederum... immer so weiter.

Wer schon einmal einen vollständigen Familien-Stammbaum zusammengesetzt hat, weiß, wie schwierig es sein kann, überhaupt den nötigen Platz zu finden, um alles passend anzuordnen, da aus Uroma und Uropa ganz schön viele Urenkel entstanden sind. Anders als bei einer Familie haben wir in unserer Wallet aber keine biologischen Grenzen, sondern können uns komplett austoben. 

Ein Beispiel mit willkürlichen Zahlen

Ich könnte aus dem Hauptschlüssel 1000 neue Schlüssel ableiten, dann den 476-sten nehmen und daraus 30 Schlüssel ableiten, dann den 4-ten Schlüssel nehmen und daraus 5.000.000 Schlüssel ableiten, dann den 3.993.127-sten Schlüssel nehmen und daraus dann einen Schlüssel ableiten. Diesen Schlüssel nehme ich, um mir eine Adresse zu erzeugen und meine Bitcoin abzusichern. Bis hier kein Problem.

Sobald ich aber mit meiner Mnemonic (d.h. dem Hauptschlüssel) wiederherstellen will, muss ich den exakten Pfad zu dem Schlüssel der Adresse kennen, um meine Bitcoin ausgeben zu können. Ich kontrolliere zwar mit meiner Mnemonic auch diesen einen Schlüssel, das bringt mir aber relativ wenig, wenn ich nicht weiß, wo er ist.


Derivation Paths

Jetzt, da wir das Problem verstanden haben, können wir eine relativ einfache Lösung dafür finden: Einen Wegweiser. Den sogenannten Master Private Key (der direkt aus dem Seed abgeleitet wird) nennen wir im Folgenden m und den entsprechenden Master Public Key nennen wir M.

m/0 ist entsprechend der erste Child Key von m, während m/1 der zweite Child Key von m wäre. Beide sind auch oben in der Grafik zu sehen. Jetzt tasten wir uns schrittweise im Ableitungspfad vor und benutzen, um Verwirrung zu vermeiden, Familienbezeichnungen aus Sicht der Eltern (m):

  • m/0/0 ist dann der erste Enkel vom ersten Kind.
  • m/1/0 ist dann der erste Enkel vom zweiten Kind.
  • m/0/0/0 ist dann der erste Urenkel vom ersten Enkel vom ersten Kind.
  • m/1/2/3/4 ist dann der fünfte Ur-Urenkel vom vierten Urenkel vom dritten Enkel vom zweiten Kind.

Langsam wird es kompliziert, aber ich denke, wir haben verstanden, wie der Wegweiser vom Prinzip her funktioniert. Falls nein: Lest euch diesen Abschnitt einfach mehrmals durch. Es ist anfangs vielleicht etwas abstrakt, das ist völlig normal. Versuchen wir mal meinen absichtlich komplizierten Ableitungspfad von weiter oben im Text in dieses System umzusetzen.

Probiere es zunächst selbst und klappe erst anschließend die Lösung auf:

Die richtige Lösung lautet: m/475/3/3993126/0

Achtung: Wir fangen bei der 0 mit dem Zählen an!

Unser Problem wurde allerdings noch nicht gelöst. Wir stehen immer noch vor unendlich vielen Ableitungspfaden, die wir jetzt zwar eindeutig benennen können, aber unsere Wallet müsste sie trotzdem erstmal alle absuchen, da sie alleine mit den 12 oder 24 Wörtern nicht weiß, wo sie hin muss. Bei der unfassbar großen Anzahl an Möglichkeiten wäre dies schlichtweg unmöglich. Wenn jeder Entwickler sein eigenes Ableitungs-Süppchen kocht, schadet das am Ende nur dem Nutzer, da er nicht weiß, wie er seine Schlüssel wiederherstellen kann.


Es braucht einen Standard

Und den gibt es. Um das einheitliche Ableiten zwischen verschiedenen Adresstypen und verschiedener Software zu ermöglichen, hat man sich auf einen bestimmten Bauplan für den Ableitungspfad geeinigt. Begonnen hat das im BIP-44 (Bitcoin Improvement Proposal), indem man eine bestimmte Funktion für jeden Ableitungsschritt vereinbart.

m/44'/0'/0'/0/0

  • Die erste Stelle steht für den Purpose, also welcher konkrete Standard verwendet wird. Der Endnutzer kann damit auch bereits auf den Adresstyp schließen, den seine Wallet am Ende für ihn ableitet. In diesem Fall generieren wir altmodische Legacy-Adressen, die mit einer 1 anfangen. Wir nehmen hier also immer den 45-sten Child Key.

  • Die zweite Stelle steht für den Coin Type, also um welches Netzwerk es gehen soll. Für Bitcoin nutzen wir 0, für das Bitcoin Testnet nutzen wir 1, für Litecoin nutzen wir 2, und so weiter. Wir nehmen hier also den ersten Grandchild Key für Bitcoin.

  • Die dritte Stelle steht für den Account. Davon haben sicherlich die meisten schonmal etwas gehört und das ist auch die einzige Schnittstelle, die man als normaler Nutzer mit dem Derivation Path hat. Wir nutzen diese Stelle im Pfad, um uns effektiv so etwas wie „Unterkonten“ in unserer Wallet zu erstellen. Das hat einen reinen organisatorischen Vorteil, da wir bestimmte Adressen voneinander trennen und bestimmte Teile unserer Wallet für bestimmte Funktionen reservieren können (z.B. Sparen, Shoppen und Kinder).

    Da wir immer noch von einem Standard sprechen, können wir diese Accounts einfach zwischen verschiedenen Wallets (Software) übertragen und landen immer bei den gleichen Schlüsseln und damit Accounts. Die Funktionen in der Ledger Live oder BitBoxApp machen genau dasselbe. Sie kennen diesen Standard und wissen, wo sie im Ableitungsbaum suchen müssen, um zu anderen Accounts zu gelangen. Wir benutzen hier also 0 um in unserem „Standard Account“ zu landen und können dann durch Erhöhen des Index beliebig viele Konten „erstellen“, die natürlich alle zu unserer Mnemonic gehören und jederzeit abgeleitet werden können. Wir gehen jeweils einfach auf einen anderen Ast.

  • Die vierte Stelle unterscheidet zwischen Receiving und Change Adressen. Um zu verstehen, was das ist, empfehle ich dir unseren Beitrag zu Unspent Transaction Outputs (UTXO) zu lesen. Wir benutzen 0 für normale Empfangsadressen und 1 für Wechseladressen.

  • Die letzte Stelle steht dann letztendlich für die eigentlichen Schlüsselpaare, die wir für unsere Adressen alltäglich verwenden. Index 0 steht also für die erste Adresse bzw. die ersten Schlüssel, Index 1 für die zweite und immer so weiter. Wenn wir eine neue Adresse „generieren“ schaltet unsere Wallet einfach den Derivation Path an dieser Stelle um einen Index weiter. Jede Adresse respektive jeder private Schlüssel hat einen eindeutigen Ableitungspfad.

Hier noch einmal zusammengefasst in einer Grafik:

Quelle: Greg Walker, learnmeabitcoin.com/technical/derivation-paths

Beispiele

  • m/44'/0'/0'/0/0 leitet also die Schlüssel für die erste Bitcoin Legacy Empfangsadresse, die sich im ersten Account befindet, ab.

  • m/84'/0'/1'/0/3 leitet also die Schlüssel für die vierte Bitcoin Native-Segwit Empfangsadresse, die sich im zweiten Account befindet, ab.

  • m/86'/0'/3'/1/8 leitet also die Schlüssel für die neunte Bitcoin Taproot Wechseladresse, die sich im vierten Account befindet, ab.

Verschwundene Bitcoin

Mit unserem neuen Wissen können wir uns jetzt einen häufigen Grund für scheinbar „verschwundene“ Bitcoin erschließen: Etwas stimmt mit der Ableitung bzw. dem Ableitungspfad nicht.

Sichern wir einen Teil unserer Bitcoin z.B. in einem zusätzlichen Account (z.B. im zweiten Account: m/44’/0’/2') und unsere Wallet weiß nichts davon, dann werden diese Bestände in der Übersicht auch nicht angezeigt. Natürlich kontrollieren wir diese Bestände trotzdem – unsere Bitcoin sind in Sicherheit, nur haben wir die entsprechende „Schublade“ noch nicht geöffnet. Das erneute „hinzufügen“ oder besser gesagt abrufen des Accounts führt dann dazu, dass die Wallet-Software auf dem entsprechenden Ableitungspfad nachschaut und alle Bestände, die sie dabei findet, auch wieder anzeigt.

Bei der von Blocktrainer.de empfohlenen BitBox02 wird dieses Problem mittlerweile vermieden, indem ganz automatisch nach potenziell verwendeten Accounts gesucht wird. Bevor man den Nutzer also mit einem vermeintlich leeren Account schockiert, werden zunächst einige der "Schubladen" geöffnet.

Gap Limits

In der Regel zeigt euch eure Wallet-Software nur die nächste (also eine) Adresse an, in vielen Fällen aber auch die nächsten 20 Adressen, die noch nicht verwendet worden sind. Diese Zählung beginnt immer ab der letzten verwendeten Adresse. Eine Adresse gilt erst dann als verwendet, sobald eine Bitcoin-Transaktion mit ihr bestätigt wurde.

Das bedeutet allerdings auch: Selbst wenn Adressen 1-19 unbenutzt sind, ihr aber Adresse 20 verwendet habt, dann werden euch fortan die Adressen 21-40 angezeigt. Lasst euch davon also nicht verwirren. Es kann (z.B. nach einem CoinJoin) passieren, dass eure Bitcoin auf Adressen mit einem sehr hohen Index landen, der vom Gap-Limit eurer Software nicht abgedeckt ist, d.h. euch werden die Bestände nicht korrekt angezeigt. Genau das ist z.B. einem Nutzer in diesem Thread im Blocktrainer-Forum passiert.

Die Lösung lautet hier, ähnlich wie mit den Accounts, die entsprechenden Adressen einfach abzusuchen. Wallet-Software wie die Sparrow Wallet unterstützen hierfür das manuelle Erhöhen des Gap-Limits, also der Anzahl an Adressen, die nach der Adresse mit höchstem Index abgesucht werden sollen.

Auch die BitBoxApp kann man mit einem Argument starten, um das Gap-Limit anzupassen.


Verstecken spielen

Wer jetzt auf die raffinierte Idee kommt, dass man manuell seine Bitcoin auf einem unkonventionellen Ableitungspfad absichern könnte, damit man selbst mit der Mnemonic die richtigen Schlüssel zunächst nicht findet, den versuche ich hier direkt aufzufangen. Nein, bitte macht das nicht! Es ist grundsätzlich nicht ratsam und immer mit Risiken verbunden vom Standard abzuweichen.

Gründe die gegen dieses Vorgehen sprechen:

  • Das Verstecken im Ableitungspfad bietet keine Sicherheit, sondern höchstens einen nicht klar abschätzbaren Zeitvorteil. Mit der Mnemonic hat ein Angreifer eigentlich alles, was er wissen muss, es ist nur eine Frage der Zeit bis er den richtigen Schlüssel findet. Es ist die Suche nach der Nadel im Heuhaufen – aber die ist nicht unmöglich.
  • Es gibt standardisierte Verfahren für mehr Sicherheit. Zum Beispiel eine optionale Passphrase, die tatsächlich auch mehr Sicherheit bietet.
  • Ihr macht es euren Erben noch komplizierter, als es wahrscheinlich ohnehin schon ist.
  • Nicht jede Wallet-Software erlaubt es euch, einen beliebigen Ableitungspfad zu besuchen. Ihr schränkt eure Optionen damit extrem ein.

Erweiterte Schlüssel

Nachdem wir jetzt verstanden haben, wie HD Wallets funktionieren, können wir uns den erweiterten öffentlichen Schlüssel (xpub), der den meisten wahrscheinlich schon einmal über den Weg gelaufen ist, etwas genauer anschauen. Am besten schauen wir uns dafür wieder Ableitungspfade an, konkret diese drei Public Keys bzw. Adressen:

(Erinnerung: Großes M als Abkürzung für Public Key)

  • M/84’/0’/0’/0/0
  • M/84’/0’/0’/0/1
  • M/84’/0’/0’/0/2

Hat man einen der drei Schlüssel, kann man damit nicht auf die anderen beiden schließen. Geschwister können sich untereinander nicht ableiten (genauso wenig wie sie sich biologisch fortpflanzen können – die Analogie funktioniert immer noch). Nur der Parent Key kann alle Child Keys ableiten, nicht umgekehrt. Eltern können Kinder bekommen, aber Kinder keine Eltern. Wenn wir jemandem eine Bitcoin-Adresse für eine Bezahlung geben, dann möchten wir schließlich nicht, dass er damit alle anderen Adressen* ableiten kann und all unsere Bestände kennt. 

(*Hinweis: Könnte er sowieso nicht, solange er den Public Key nicht kennt. Dieser wird bei einer Transaktion aber veröffentlicht.)

Trotzdem brauchen wir einen Weg unsere Adressen „in einem Schlüssel“ zu speichern, ohne unsere kritischen Geheimnisse wie z.B. die Mnemonic preiszugeben. Die Wallet Software die wir mit unserer Hardware Wallet verwenden muss zwar unsere Transaktionen und Adressen kennen, darf aber nicht an private Schlüssel gelangen.

Die Lösung: Wir verwenden den öffentlichen Schlüssel des jeweiligen Accounts, also zum Beispiel:

  • M/84’/0’/0’

Dieser kann alle Adressen bzw. alle öffentlichen Schlüssel (inkl. Schlüssel für Wechseladressen) des ersten Accounts ableiten– aber keine privaten Schlüssel!

GIF: Greg Walker – learnmeabitcoin.com/technical/hd-wallets

Diesen 256 bit Schlüssel codieren wir zusammen mit dem sogenannten Chain Code, der für das derivieren notwendig ist, in einen 512 bit Extended Public Key (xpub):

xpub67xpozcx8pe95XVuZLHXZeG6XWXHpGq6Qv5cmNfi7cS5mtjJ2tgypeQbBs2UAR6KECeeMVKZBPLrtJunSDMstweyLXhRgPxdp14sk9tJPW9

Was ist der Chain Code? Der Einfachheit halber habe ich diesen Teil des Ableitungsprozesses während dieses Beitrages unterschlagen, da er für den normalen Nutzer auch völlig irrelevant ist. Ich empfehle Kapitel 5 aus Mastering Bitcoin oder learnmeabitcoin.com, wenn man hier noch tiefer einsteigen will. Selbiges gilt für das Konzept der gehärteten Ableitung (Hardened Derivation), die ebenfalls unterschlagen wurde.