Newsticker

Tornado für Ethereum: Zero Knowledge Proofs machen einen Mixer zum Smart Contract

Ein Screenshot von Tornado Cash, als ich eine Auszahlung von Ether aus dem Smart Contract veranlasse.

Ethereum ist nicht gerade dafür bekannt, besonders privat oder gar anonym zu sein. Mit Tornado.Cash könnte sich das ändern: Der erste Mixer als Smart Contract.

Kryptowährungen sind in der Regel nicht besonders anonym. Die Blockchain speichert alle Transaktionen, was für ein großes Maß an Transparenz sorgt – und den Effekt hat, dass ein Offenlegen einer Adresse darin enden kann, dass das “Schweizer Bankkonto in der Hosentasche”, wie es der ehemalige US-Präsident Barack Obama so schön gesagt hat, zum gläsernen Bankkonto wird.

Eine der oft verwendeten Methoden, um die Privatsphäre zu erhöhen, sind Mixer oder andere Dienstleister. Man bezahlt Bitcoins oder andere Kryptowährungen auf einer anderen Wallet ein, und diese zahlt andere Coins an einen aus. Das hat den Vorteil, dass die Spur der Transaktionen gebrochen wird – geht allerdings meist damit einher, dass der zentrale Dienstleister die beteiligten Parteien identifizieren kann und man ihm vertrauen muss, das Geld nicht einfach zu entwenden. Methoden wie CashShuffle, Joinmarket oder das Coinmixing durch Wasabi sind dagegen besser gefeit. Was aber der Tornado Mixer auf Ethereum bildet, geht noch ein Stück darüber hinaus. Er setzt erstmals einen Mixer als Smart Contract um.

Theoretisch ist es kein großes Problem, einen Mixer auf Ethereum nachzubilden: Man baut einen Smart Contract, auf den Leute Guthaben ein- und auszahlen. Allerdings gibt es einige Probleme, die beinah unlösbar erscheinen: So müsste man den Smart Contract schon bei der Einzahlung instruieren, wohin er das Geld auszahlen muss – womit der ganze Sinn des Mixers dank der Transparenz der Blockchain hinfällig wäre. Tornado.cash erlaubt es nun, Geld einzuzahlen ohne eine Auszahlungsadresse zu definieren. Stattdessen legt man später einen Beweis für die Einzahlung vor, um das Geld wieder abziehen zu können. Das führt aber zum nächsten Problem: Da der Beweis in die Blockchain eingeht, darf er keinen Hinweis darauf geben, um welche Einzahlung es geht.

Die Transaktion, mit der die Ether aus dem Smart Contracts ausgezahlt werden. Von meiner Herkunftsadresse keine Spur.

Man braucht also einen Beweis dafür, eine Zahlung durchgeführt zu haben, ohne dass die Partei, die den Beweis prüft – in diesem Fall der Smart Contract – erfährt, um welche Zahlung es sich handelt. Also quasi ein blinder Beweis – ein Beweis, der geprüft wird, ohne dass der Prüfer ihn kennt. Das klingt unmöglich, ist es aber nicht.

In der Kryptographie nennt man dieses Konzept “Zero Knowledge Proof”. Zum Teil kommt dies bereits bei Kryptowährungen zum Einsatz, etwa wenn Zcash “Shielded Transactions” bildet, oder wenn Monero “Confidential Transactions” schreibt, bei denen der Betrag verschleiert ist, aber dank des Zero Knowledge Proofs dennoch prüfbar bleibt, dass die gesendete Menge korrekt ist.

Die Ethereum-Entwickler experimentieren schon seit geraumer Zeit mit den zk-Snarks genannten Zero Knowledge Proofs von Zcash. Die erste wirkliche Anwendung davon ist Tornado Cash. Der Ablauf ist gar nicht so kompliziert: Man bildet einen Beweis, kopiert diesen, und sendet dann durch eine spezielle Transaktion, die den Hash des Beweises enthält, Geld an den Smart Contract von Tornado Cash. Diese Transaktion gibt die Tornado.Cash-Dapp an Metamask oder eine andere Wallet weiter, so dass sie für den Anwender nicht schwieriger zu bilden ist als jede andere Transaktion. Später kann man dann durch die Vorlage des Beweises wieder Geld an eine andere Adresse auszahlen. Dabei empfiehlt es sich, ein Weilchen zu warten, bis auch weitere Parteien eingezahlt haben, so dass der Pool, aus dem man sein Geld abzieht, groß genug ist, damit Beobachter nicht erkennen können, wie Ein- und Auszahlungen zusammenhängen. Insgesamt aber bleibt die enorme kryptographische Komplexität, die in diesem Verfahren steckt, recht gut vor dem User verborgen.

Etherscan zeigt die Transaktion von dem Tornado Smart Contract unter “interne Transaktionen” an.

Es handelt sich dabei wohlgemerkt nicht um eine vollständige Anonymität, sondern eher um ein Mixen: Verschiedene Parteien legen ihr Geld in einen Topf, um es dann jeder für sich abzuziehen. Einem Blockchain-Beobachter ist weiterhin bekannt, welche Parteien in dem Mixing-Verfahren beteiligt sind, woraufhin Strafverfolger beispielsweise die Spur jeder einzelnen zurückverfolgen könnten, um durch Ermittlungen herauszufinden, wohin die einzelnen Gelder geflossen sind. Auch könnten die durch Tornado.Cash privatisierten Ether auf einer Black-List landen, da sich ihre Herkunft von dem Mixer nachweisen lässt. Diese Coins könnten Ether zweiter Klasse sein, die unter Umständen darin resultieren, dass man sich schwierigen Fragen stellen muss, wenn man sie auf einer Börse auflaufen lässt.

Für Ethereum dürfte es sich in Sachen Privatsphäre um einen gewaltigen Fortschritt handeln, während es im weiteren Kryptoökosystem zahlreiche Alternativen gibt, die ebenso gut, wenn nicht besser sind, wenn etwa wie bei Monero die Anonymität von Transaktionen keine Ausnahme, sondern Standard ist. Dennoch ist es technisch gesehen geradezu ein Durchbruch – ein Service, der vorher von einem Dritten erbracht wurde, dem man vertrauen muss, wird auf einen Smart Contract ausgelagert.

Über Christoph Bergmann (2552 Artikel)
Das Bitcoinblog wird von Bitcoin.de gesponsort, ist inhaltlich aber unabhängig und gibt die Meinung des Redakteurs Christoph Bergmann wieder ---

8 Kommentare zu Tornado für Ethereum: Zero Knowledge Proofs machen einen Mixer zum Smart Contract

  1. Sehr interessanter Beitrag. Vielen Dank.

  2. Dennoch ist es technisch gesehen geradezu ein Durchbruch – ein Service, der vorher von einem Dritten erbracht wurde, dem man vertrauen muss, wird auf einen Smart Contract ausgelagert.

    Naja, CoinJoins wie es Wasabi / Cashshuffle ermöglichen, sind auch permissionless und nicht als klassische Mixing “Services” zu verstehen, bei denen man seine Coins in eine Blackbox wirft mit der Hoffnung, dass sie auch wieder zurückkommen.
    Trotzdem interessanter “Smart” Contract, auch wenn die Anonymität begrenzt sein dürfte, wie Du schon angemerkt hast.

    Dennoch werden Zero-Knowledge Proofs meiner Meinung nach in Zukunft noch eine große Rolle spielen, da es unzählige Anwendungsmöglichkeiten gibt. Unter anderem lassen sich damit geheime aber dennoch manipulationsresistente Wahlen durchführen oder auch Studien, bei denen man meist personenbezogene Daten eliminieren, aber trotzdem die Integrität der Datenbasis wahren möchte.

    Selbst ein Hash ist in gewisser weise ein “Zero-Knowledge Proof”, da man mit der Veröffentlichung eines Hash-Wertes sein eigentliches Geheimnis nicht teilt, aber den Beweis ermöglicht, es zu diesem Zeitpunkt bereits gekannt zu haben.

    “Echte” Zero Knowledge Beweise sind etwas komplizierter, aber im Vergleich zu zk-SNARKs, die selbst Zcash Gründer Zooko nicht versteht (sic!) sind Pedersen Commitments wie sie bei “Confidential Transactions” eingesetzt werden, ziemlich einfach gestrickt. Es ist entfernt vergleichbar mit Hashing, aber es kommt noch ein zufällig generiertes “Geheimnis” hinzu. Am Ende kann man aber beweisen, dass der Input gleich war wie der Output. Das Problem, welches bei Monero dabei entsteht ist, dass man jeden Output (Key Image) zumindest aktuell für immer speichern muss und es nicht ausreicht wie bei Bitcoin die “Unspent” UTXO zu halten, da man bei Monero (wegen Ring-Signaturen) nicht feststellen kann, welche bereits ausgegeben wurden und welche nicht. Man signiert eine Transaktion immer mit Hilfe des Key Images, welches danach nie wieder verwendbar ist, man “zerstört” also den Input und generiert einen neuen (oder meistens zwei) Outputs. Ein Betrachter von außen kann aber nicht feststellen, welcher Input gerade zerstört wurde, er kann nur feststellen, ob ein Input gegen den Konsens wiederverwendet wurde und eine solche Transaktion ablehnen.

    Wie schon öfter gesagt, wir sind auch nach 10 Jahren Bitcoin noch sehr am Anfang und die Wissenschaft fängt erst langsam an, an der Kryptographie, die in Kryptowährungen verwendet wird, zu forschen. Interessant ist auch, dass bereits RSA (welches deutlich länger als Bitcoin existiert) auch ein Trusted Setup brauchte, aber ich wage zu behaupten, dass dies mit heutigem Wissen auch ohne ginge…
    Übrigens immer interessant zu lesen, womit sich die Wissenschaftler zu diesen Themen befassen: https://repo.getmonero.org/monero-project/ccs-proposals/merge_requests/77#note_6916
    Auch interessant in Anbetracht “über den Tellerrand schauen” und so… Jedes Paper und (Test)Code vom MRL wird übrigens auch unter komplett freien Lizenzen veröffentlicht, falls es jemand nutzen möchte. Eine solche Offenheit wünschte ich mir wieder bei Bitcoin und dessen Forks, wo jeder mittlerweile sein eigenes Süppchen kocht und bevorzugt, ohne sich mit anderen Meinungen auseinanderzusetzen. Vitalik ist bei Ethereum eher noch die Ausnahme, die sich tatsächlich noch (öffentlich) mit Dingen auseinandersetzt.

    • >Selbst ein Hash ist in gewisser weise ein „Zero-Knowledge Proof“, da man mit der Veröffentlichung eines Hash-Wertes sein eigentliches Geheimnis nicht teilt, aber den Beweis ermöglicht, es zu diesem Zeitpunkt bereits gekannt zu haben

      Ist es das, was CSW mit double Hash und Hashpuzzle meint?
      Siehe 2 Minunten ab https://www.youtube.com/watch?time_continue=1599&v=8_SoIXUBIhw

      • Schwer zu deuten, was CSW in diesem Interview meint und schade, dass der Interviewer nicht darauf eingeht. “Doppel-Hashing” ist in meinen Augen meist sicherer als einfaches Hashing, da der Input und damit die Angriffsfläche begrenzt ist. Beim Mining sucht man ja einen Hash, der bestimmte Voraussetzungen und die aktuelle Difficulty erfüllt, die sich simpel gesagt in führenden Nullen zeigt. Dafür fügt man zufallsgenerierte Zahlen an die eigentlichen Blöcke an, bis man zu einem passenden Ergebnis kommt und das machen ASIC Miner eben Millionenfach pro Sekunde.

        Beispiel für SHA1:
        “Input” ergibt “b568d47f2e244743b1fd7472db836ef9769c21f8”
        “Input01” ergibt “09589df27391f5328e7730c168f2518fa8fbe129” und würde damit die Bedingung “eine führende Null” erfüllen.

        Man kann den Input beliebig lang machen und da der Output immer gleich lang bleibt, wird sich zwangsläufig irgendwann eine Kollision finden. Gute Hashfunktionen zeichnen sich dadurch aus, dass Kollisionen nicht berechenbar zu finden sind. Beim Doppel-Hashing wird der Input der zweiten Runde stark begrenzt, denn er ist immer gleich lang und nicht beliebig veränderbar, man hasht ja den Hash des ursprünglichen Inputs und kann nur den Input selbst verändern. Falls die Hashfunktion also “gebrochen” werden sollte und man durch Hinzufügen von bestimmten Zeichen im Input eine Kollision finden könnte, ist dies beim Hashing des Hashes nicht mehr möglich.

        Ein Hash (oder auch Doppel-Hash) lässt sich im Normalfall nicht auf seinen Ursprung ableiten. Dagegen lässt sich der Ursprung immer auf den exakt gleichen Hash ableiten und ist damit beweisbar / verifizierbar.

      • @Paul Janowitz:
        Einmal vorausgesetzt, dass der verwendete Hashalgorithmus wirklich eine Einwegfunktion ist (“Gute Hashfunktionen”).

        „Doppel-Hashing“ ist in meinen Augen meist sicherer

        Ist das dann nicht eine weit verbreitete Illusion?
        Denn dagegen spricht doch folgende Überlegung: Man begreife die serielle Ausführung zweier identischer Hashes (Doppelhash) als neuen Hash: N-Hash.
        Nach Voraussetzung ist N-Hash wieder Einwegfunktion. Der zweite intrinsische Hash bildet eine Abbildung eines Strings seiner Ergebnislänge auf sich selbst. Ist das eine Permutation (was ich nicht weiß), dann ist die interne Kollisionswahrscheinlichkeit Null und N-Hash hat die gleiche Kollisionswahrscheinlichkeit wie der erste Teilhash auf den (Original-)Input. Ist die zweite Abbildung dagegen keine Permutation, so gibt es sogar zusätzliche Kollisionen (Dirichletsches Schubfachprinzip).

      • In der Tat ist diese Behauptung strittig und daher habe ich geschrieben “in meinen Augen” und dazu noch “meist”. Am Ende ist es abhängig vom verwendeten Hashing-Algorithmus und dem Angriffsvektor, den man ansetzt bzw. versucht. Einen Input beliebiger Länge, den man beim Hashing nutzt kann man auch beliebig “manipulieren”, einen Input der bereits selbst ein Hash ist, kann man hingegen nicht mehr manipulieren. Moderne Hashverfahren für Passwörter wie z.B. Bcrypt nutzen etliche “Runden” standardmäßig und sind dadurch meines Wissens nicht weniger sicher.

      • Danke für die Antwort! Aber …
        der Original-Input bleibt doch genauso variierbar, egal wie viele Durchläufe der Hashalgorithmus danach hat. Deshalb werden durch Doppel- oder Mehrfach-Hashing keineswegs Kollisionen vermieden, denke ich.
        Ein Grund für das Mehrfach-Hashing dürfte – etwa bei Bcrypt – darin liegen, den zeitlichen Aufwand hochzutreiben, den dann auch ein brute-force-attack benötigt.
        Kollisionen sind offenbar eben nicht das einzige Problem eines Kryptographen.

      • Gegen Brute-Force ist ein Doppel-Hash genauso anfällig wie ein einfacher, nur dass es eben doppelt so lange dauert, aber das ist kein starkes Argument für die Sicherheit.

        Anders sieht es aus, wenn die Hashfunktion tatsächlich “gebrochen” ist und man mit einem wie auch immer manipulierten / präparierten Input auf einen Teil des Outputs schließen und somit einfacher Kollisionen finden kann. MD5 und SHA1 sind auf diese Weise bereits gebrochen worden, aber man benötigt dafür eine ziemlich große Bandbreite für die Inputs. Ich wage jetzt nicht zu behaupten, Doppel-MD5 sei weiterhin sicher, aber erschwert durch die Längenbegrenzung des zu hashenden Hashes die Angriffsfläche sehr stark.

Kommentar verfassen

%d Bloggern gefällt das: