Originaltext: „IOSG Weekly Brief | Wie man ZKVM überlebt, eine detaillierte Erklärung von Fraktionsstreitigkeiten #159“
Autor: Bryan, IOSG Ventures
Inhaltsverzeichnis
Schaltungsimplementierung des ZKP-Proof-Systems – schaltungsbasiert VS-basiert auf virtuellen Maschinen (vm-basiert)
ZKVM-Designprinzipien
Vergleich zwischen STARK-basierten VMs
Warum Risc0 spannend ist
Der Schwerpunkt der Diskussionen zum Rollup im vergangenen Jahr 2022 schien sich auf ZkEVM zu konzentrieren, aber vergessen Sie nicht, dass ZkVM auch ein weiteres Mittel zur Erweiterung ist. Obwohl ZkEVM nicht der Schwerpunkt dieses Artikels ist, lohnt es sich, die Unterschiede zwischen ZkVM und ZkEVM in mehreren Dimensionen in Erinnerung zu rufen:
Kompatibilität: Obwohl es sich bei beiden um Erweiterungen handelt, liegt der Schwerpunkt von ZkEVM auf der direkten Kompatibilität mit vorhandenen EVMs, während die Positionierung von ZkVM auf der Optimierung der Logik und Leistung von Dapps liegt ist nicht die Priorität. Sobald die unterste Ebene eingerichtet ist, kann auch EVM-Kompatibilität erreicht werden. Leistung: Beide haben relativ vorhersehbare Leistungsengpässe. Der Hauptengpass von ZkEVM sind die zusätzlichen Kosten, die entstehen, wenn die Kompatibilität mit EVM nicht für die Verpackung im ZK-Zertifizierungssystem geeignet ist. Der Engpass von ZkVM besteht darin, dass die Einführung des Befehlssatzes ISA die endgültigen Ausgabebeschränkungen komplexer macht. Entwicklererfahrung: ZkEVM vom Typ II (wie Scroll, Taiko) konzentriert sich auf die Kompatibilität mit EVM-Bytecode. Mit anderen Worten: EVM-Codes auf Bytecode-Ebene und höher können über ZkEVM entsprechende Zero-Knowledge-Beweise generieren. Für ZkVM gibt es zwei Richtungen: Eine Richtung besteht darin, ein eigenes DSL zu erstellen (z. B. Kairo), und die andere darin, mit vorhandenen ausgereifteren Sprachen wie C++/Rust (z. B. Risc0) kompatibel zu sein. Wir gehen davon aus, dass native Solidity-Ethereum-Entwickler in Zukunft kostenlos auf ZkEVM migrieren können und neuere und leistungsfähigere Anwendungen auf ZkVM laufen werden. Viele Menschen dürften sich noch an dieses Bild erinnern. CairoVM hat nichts mit ZkEVM zu tun. Der wesentliche Grund für den Fraktionskampf ist der Unterschied in den Designvorstellungen.
Bevor wir über ZkVM sprechen, überlegen wir zunächst, wie das ZK-Proof-System in der Blockchain implementiert werden kann. Im Großen und Ganzen gibt es zwei Möglichkeiten, Schaltkreise zu implementieren: schaltkreisbasierte Systeme und virtuelle Maschinen-basierte Systeme (VM-basiert).
Die Funktion des schaltungsbasierten Systems besteht zunächst darin, das Programm direkt in Einschränkungen umzuwandeln und an das Prüfsystem zu senden. Das auf einer virtuellen Maschine basierende System führt das Programm in diesem Prozess aus verfolgen. Dieser Ausführungs-Trace wird dann in Einschränkungen abgebildet und dann an das Proof-System gesendet.
Bei einem schaltungsbasierten System wird die Berechnung eines Programms durch jede Maschine eingeschränkt, die das Programm ausführt. Bei Systemen, die auf virtuellen Maschinen basieren, ist ISA in einen Schaltkreisgenerator eingebettet und erzeugt Programmbeschränkungen. Gleichzeitig weist der Schaltkreisgenerator Einschränkungen hinsichtlich Befehlssatz, Laufzyklus, Speicher usw. auf. Virtuelle Maschinen bieten Vielseitigkeit, das heißt, jede Maschine kann ein Programm ausführen, solange die Ausführungsbedingungen des Programms innerhalb der oben genannten Einschränkungen liegen.
Ein ZKP-Programm in einer virtuellen Maschine durchläuft wahrscheinlich den folgenden Prozess:
Bildnachweis: Bryan, IOSG Ventures
Vorteile und Nachteile:
Aus der Sicht eines Entwicklers erfordert die Entwicklung schaltungsbasierter Systeme oft ein tiefes Verständnis der Kosten jeder Einschränkung. Beim Schreiben von Programmen für virtuelle Maschinen ist die Schaltung jedoch statisch, und Entwickler müssen sich mehr um Anweisungen kümmern. Aus der Sicht eines Verifizierers unterscheiden sich schaltungsbasierte Systeme und virtuelle Maschinen erheblich in der Allgemeinheit der Schaltungen, vorausgesetzt, dass dasselbe reine SNARK als Backend verwendet wird. Das Schaltungssystem erzeugt für jedes Programm eine andere Schaltung, während die virtuelle Maschine für verschiedene Programme dieselbe Schaltung erzeugt. Das bedeutet, dass das Schaltungssystem bei einem Rollup mehrere Verifiziererverträge auf L1 bereitstellen muss. Aus Anwendungssicht macht eine virtuelle Maschine die Anwendungslogik komplexer, indem sie das Speichermodell in das Design einbettet. Der Zweck der Verwendung des Schaltungssystems besteht darin, die Leistung des Programms zu verbessern. Aus Sicht der Systemkomplexität integrieren virtuelle Maschinen mehr Komplexität in das System, z. B. Speichermodelle, Kommunikation zwischen Host und Gast usw. Im Vergleich dazu ist das Schaltungssystem einfacher.
Im Folgenden finden Sie eine Vorschau auf die verschiedenen leitungsbasierten und virtuellen Maschinen-basierten Projekte, die sich derzeit in L1/L2 befinden:
Bildquelle: Bryan, IOSG Ventures Designprinzipien virtueller Maschinen
Bei virtuellen Maschinen gibt es zwei wichtige Designprinzipien. Stellen Sie zunächst sicher, dass das Programm korrekt ausgeführt wird. Mit anderen Worten: Die Ausgabe (d. h. die Einschränkung) und die Eingabe (d. h. das Programm) sollten korrekt übereinstimmen. Typischerweise erfolgt dies über den ISA-Befehlssatz. Stellen Sie zweitens sicher, dass der Compiler beim Konvertieren von der Hochsprache in das entsprechende Einschränkungsformat ordnungsgemäß funktioniert.
1. ISA-Befehlssatz
Gibt an, wie der Schaltungsgenerator funktioniert. Seine Hauptaufgabe besteht darin, Anweisungen korrekt in Einschränkungen abzubilden, die dann in das Prüfsystem eingespeist werden. Alle zk-Systeme verwenden RISC (reduzierter Befehlssatz). Es gibt zwei ISA-Optionen:
Die erste besteht darin, eine benutzerdefinierte ISA (benutzerdefinierte ISA) zu erstellen, die im Design von Cairo zu sehen ist. Im Allgemeinen gibt es vier Arten von Einschränkungslogik:
Der grundlegende Entwurfsschwerpunkt einer benutzerdefinierten ISA besteht darin, sicherzustellen, dass es so wenige Einschränkungen wie möglich gibt, damit sowohl die Ausführung als auch die Überprüfung des Programms schnell erfolgen.
Die zweite besteht darin, vorhandene ISA (existierende ISA) zu verwenden, die in das Design von Risc0 übernommen werden. Bestehende ISAs wie Risc-V zielen nicht nur auf saubere Ausführungszeiten ab, sondern bieten auch weitere Vorteile, wie z. B. die Freundlichkeit gegenüber Front-End-Sprachen und Backend-Hardware. Eine (möglicherweise noch zu klärende) Frage ist, ob bestehende ISAs bei der Verifizierungszeit ins Hintertreffen geraten (da die Verifizierungszeit kein primäres Designziel von Risc-V ist).
2. Compiler
Im Großen und Ganzen übersetzt ein Compiler eine Programmiersprache nach und nach in Maschinencode. Im Kontext von ZK bezieht es sich auf eine Low-Level-Codedarstellung, die unter Verwendung von High-Level-Sprachen wie C, C++, Rust usw. in ein Einschränkungssystem (R1CS, QAP, AIR usw.) kompiliert wird. Es gibt zwei Methoden:
Entwerfen Sie einen Compiler auf der Grundlage vorhandener Schaltungsdarstellungen in ZK. In ZK beginnen Schaltungsdarstellungen beispielsweise aus direkt aufrufbaren Bibliotheken wie Bellman und Low-Level-Sprachen wie Circom. Um verschiedene Darstellungen zu aggregieren, zielt ein Compiler wie Zokrates (selbst ein DSL) darauf ab, eine Abstraktionsschicht bereitzustellen, die in beliebige Darstellungen niedrigerer Ebenen kompiliert werden kann. Bauen Sie auf der (vorhandenen) Compiler-Infrastruktur auf. Die Grundlogik besteht darin, eine Zwischendarstellung für mehrere Frontends und Backends zu verwenden.
Der Compiler von Risc0 basiert auf Multi-Level Intermediate Representation (MLIR) und kann mehrere IRs generieren (ähnlich wie LLVM). Unterschiedliche IRs bieten Entwicklern Flexibilität, da unterschiedliche IRs ihre eigenen Designprioritäten haben. Einige von ihnen sind beispielsweise speziell für die Hardware optimiert, sodass Entwickler nach ihren eigenen Wünschen wählen können. Ähnliche Ideen sind in vnTinyRAM und TinyRAM mit GCC zu sehen. ZkSync ist ein weiteres Beispiel für die Nutzung der Compiler-Infrastruktur.
Darüber hinaus können Sie auch einige Compiler-Infrastrukturen für zk sehen, beispielsweise CirC, das ebenfalls einige Designideen von LLVM übernimmt.
Zusätzlich zu den beiden oben genannten wichtigsten Entwurfsschritten gibt es noch einige weitere Überlegungen:
1. Der Kompromiss zwischen Systemsicherheit (Sicherheit) und Verifizierungskosten (Verifiziererkosten)
Je höher die Anzahl der vom System verwendeten Bits (d. h. je höher die Sicherheit), desto höher sind die Kosten für die Überprüfung. Die Sicherheit spiegelt sich im Schlüsselgenerator wider (wie die in SNARK dargestellte elliptische Kurve).
2. Kompatibilität mit Front-End und Back-End
Die Kompatibilität hängt von der Verfügbarkeit einer Zwischendarstellung für die Schaltung ab. IR muss ein Gleichgewicht zwischen Korrektheit (stimmt die Ausgabe des Programms mit der Eingabe überein + entspricht die Ausgabe dem Proofsystem) und Flexibilität (unterstützt mehrere Front-Ends und Back-Ends) herstellen. Wenn IR ursprünglich für die Lösung von Systemen mit Einschränkungen niedrigen Grades wie R1CS konzipiert wäre, wäre die Kompatibilität mit anderen Systemen mit Einschränkungen höheren Grades wie AIR schwierig.
3. Zur Verbesserung der Effizienz sind handgefertigte Schaltkreise erforderlich
Der Nachteil der Verwendung eines Allzweckmodells besteht darin, dass es für einige einfache Vorgänge, die keine komplexen Anweisungen erfordern, weniger effizient ist.
Lassen Sie uns kurz einige frühere Theorien beschreiben:
Vor dem Pinocchio-Protokoll: Implementierte überprüfbare Berechnungen, aber die Überprüfungszeit war sehr langsam. Pinocchio-Protokoll: Bietet theoretische Machbarkeit in Bezug auf Überprüfbarkeit und Überprüfungserfolgsrate (d. h. die Überprüfungszeit ist kürzer als die Ausführungszeit des Programms) und basiert auf im Circuit-System TinyRAM-Protokoll: Im Vergleich zum Pinocchio-Protokoll ähnelt TinyRAM eher einer virtuellen Maschine und führt ISA ein, sodass einige Einschränkungen wie Speicherzugriff (RAM), Kontrollfluss (Control Flow) usw. beseitigt werden. vnTinyRAM-Protokoll: ermöglicht die Schlüsselgenerierung (Schlüsselgenerierung), ist nicht von jedem Programm abhängig und bietet zusätzliche Vielseitigkeit. Erweitern Sie den Schaltungsgenerator, d. h. können Sie größere Programme abwickeln.
Die oben genannten Modelle verwenden alle SNARK als Backend-Proof-System, aber insbesondere beim Umgang mit virtuellen Maschinen scheinen STARK und Plonk ein geeigneteres Backend zu sein, vor allem weil ihre Einschränkungssysteme besser für die Implementierung von CPU-ähnlicher Logik geeignet sind.
Als Nächstes werden in diesem Artikel drei STARK-basierte virtuelle Maschinen vorgestellt: Risc0, MidenVM und CairoVM. Kurz gesagt, abgesehen davon, dass beide STARK als Beweissystem verwenden, weisen sie jeweils einige Unterschiede auf:
Risc0 nutzt Risc-V zur Vereinfachung des Befehlssatzes. R0 kompiliert in MLIR, einer Variante von LLVM-IR, die zur Unterstützung mehrerer bestehender allgemeiner Programmiersprachen wie Rust und C++ entwickelt wurde. Risc-V bietet außerdem einige zusätzliche Vorteile, beispielsweise ist es hardwarefreundlicher.
Miden soll mit der Ethereum Virtual Machine (EVM) kompatibel sein und ist im Wesentlichen ein Rollup von EVM. Miden verfügt mittlerweile über eine eigene Programmiersprache, arbeitet aber auch daran, Move in Zukunft zu unterstützen.
Cairo VM wird von Starkware entwickelt. Das von diesen drei Systemen verwendete STARK-Proof-System wurde von Eli Ben-Sasson, dem derzeitigen Präsidenten von Starkware, erfunden.
Schauen wir uns ihre Unterschiede genauer an:
* Wie ist die obige Tabelle zu lesen? Einige Notizen...
Wortgröße – Da das Einschränkungssystem, auf dem diese virtuellen Maschinen basieren, AIR ist, funktioniert es ähnlich wie die CPU-Architektur. Daher ist es sinnvoller, die CPU-Wortlänge (32/64 Bit) zu wählen.
Speicherzugriff – Risc0 verwendet Register hauptsächlich, weil der Risc-V-Befehlssatz registerbasiert ist. Miden verwendet hauptsächlich Stacks zum Speichern von Daten, da AIR wie ein Stack funktioniert. CairoVM verwendet keine Allzweckregister, da die Kosten für den Speicherzugriff (Hauptspeicher) im Cairo-Modell niedrig sind.
Programm-Feed (Programmausführung) – Es gibt Kompromisse zwischen verschiedenen Methoden. Bei der Mast-Root-Methode muss sie beispielsweise dekodiert werden, während die Anweisung verarbeitet wird, sodass die Prüferkosten in Programmen mit mehr Ausführungsschritten höher sind. Bootloading-Methoden versuchen, ein Gleichgewicht zwischen Prüfer- und Verifiziererkosten zu finden und gleichzeitig die Privatsphäre zu wahren.
Nichtdeterminismus – Nichtdeterminismus ist eine wichtige Eigenschaft NP-vollständiger Probleme. Die Ausnutzung des Nichtdeterminismus hilft dabei, frühere Ausführungen schnell zu überprüfen. Auf der anderen Seite führt es zu weiteren Einschränkungen und damit zu einigen Kompromissen bei der Validierung.
Beschleunigung bei komplexen Vorgängen – Einige Berechnungen laufen auf der CPU sehr langsam. Zum Beispiel Bitoperationen wie XOR und AND, Hash-Programme wie ECDSA und Bereichsprüfung ... meist nativ für die Blockchain-/Verschlüsselungstechnologie, aber keine CPU-nativen Operationen (außer Bitoperationen). Die direkte Implementierung dieser Vorgänge über DSL kann leicht zur Erschöpfung der Proof-Zyklen führen.
Permutation/Multiset – wird in den meisten zkVMs häufig für zwei Zwecke verwendet: 1. Reduzieren Sie die Kosten des Verifizierers, indem Sie die Notwendigkeit reduzieren, den vollständigen Ausführungs-Trace zu speichern. 2. Beweisen Sie, dass der Verifizierer den vollständigen Ausführungs-Trace kennt
Am Ende des Artikels möchte ich über die aktuelle Entwicklung von Risc0 sprechen und warum sie mich begeistert.
R0 aktuelle Entwicklung:
a. Die selbst entwickelte Compiler-Infrastruktur „Zirgen“ befindet sich in der Entwicklung. Es wäre interessant, die Leistung von Zirgen mit einigen vorhandenen ZK-spezifischen Compilern zu vergleichen.
b. Einige interessante Innovationen, wie z. B. die Felderweiterung, können solidere Sicherheitsparameter erreichen und mit größeren Ganzzahlen arbeiten.
c. Angesichts der Herausforderungen bei der Integration zwischen ZK-Hardware- und ZK-Softwareunternehmen nutzt Risc0 eine Hardware-Abstraktionsschicht, um eine bessere Entwicklung auf der Hardwareseite zu ermöglichen.
d. Noch in Arbeit!
Unterstützt handgefertigte Schaltkreise und unterstützt mehrere Hashing-Algorithmen. Derzeit sind dedizierte SHA256-Schaltkreise implementiert, die jedoch nicht alle Anforderungen erfüllen. Der Autor ist der Ansicht, dass die konkrete Wahl des zu optimierenden Schaltungstyps vom von Risc0 bereitgestellten Anwendungsfall abhängt. SHA256 ist ein sehr guter Ausgangspunkt. Andererseits ist ZKVM so positioniert, dass es den Menschen die Flexibilität gibt, sich beispielsweise keine Sorgen um Keccak machen zu müssen, wenn sie dies nicht möchten :)
Rekursion: Das ist ein großes Thema und ich möchte in diesem Bericht lieber nicht näher darauf eingehen. Wichtig zu wissen ist, dass die Notwendigkeit einer Rekursion immer dringender wird, da Risc0 tendenziell komplexere Anwendungsfälle/Programme unterstützt. Um die Rekursion weiter zu unterstützen, arbeiten sie derzeit an einer hardwareseitigen GPU-Beschleunigungslösung.
Umgang mit Nichtdeterminismus: Dies ist eine Eigenschaft, mit der sich ZKVM befassen muss, während herkömmliche virtuelle Maschinen dieses Problem nicht haben. Nichtdeterminismus kann dazu beitragen, dass virtuelle Maschinen schneller arbeiten. MLIR ist relativ besser im Umgang mit Problemen im Zusammenhang mit herkömmlichen virtuellen Maschinen, und es lohnt sich, gespannt zu sein, wie Risc0 den Nichtdeterminismus in das ZKVM-Systemdesign einbettet.
WAS MICH BEGEISTERT:
a. Einfach und nachweisbar!
In einem verteilten System erfordert PoW ein hohes Maß an Redundanz, da die Menschen anderen nicht vertrauen und daher wiederholt dieselben Berechnungen durchführen müssen, um einen Konsens zu erzielen. Und durch die Nutzung von Zero-Knowledge-Beweisen sollte die Erkenntnis des Staates so einfach sein wie die Einigung, dass 1+1=2 ist.
b. Weitere praktische Anwendungsfälle:
Neben der direktesten Erweiterung werden weitere interessante Anwendungsfälle möglich, wie z. B. wissensfreies maschinelles Lernen, Datenanalyse usw. Im Vergleich zu bestimmten ZK-Sprachen wie Cairo verfügt Rust/C++ über universellere und leistungsfähigere Funktionen und es werden mehr Web2-Anwendungsfälle auf der Risc0-VM ausgeführt.
c. Inklusivere/reifere Entwickler-Community:
Entwickler, die sich für STARK und Blockchain interessieren, müssen das DSL nicht mehr neu erlernen, sondern können einfach Rust/C++ verwenden.
Vielen Dank an Xin Gao, Boyuan von p0xeidon, Daniel von Taiko und Sin7Y für ihre Unterstützung und Vorschläge zur Überarbeitung dieses Artikels!
