Texte original : "IOSG Weekly Brief | Comment survivre au ZKVM, une explication détaillée des conflits entre factions #159"
Auteur : Bryan, IOSG Ventures
Table des matières
Implémentation de circuit du système de preuve ZKP - basé sur un circuit VS basé sur une machine virtuelle (basé sur une machine virtuelle)
Principes de conception ZKVM
Comparaison entre les machines virtuelles basées sur STARK
Pourquoi Risc0 est passionnant
Au cours de l’année 2022, les discussions sur le rollup semblent avoir porté principalement sur ZkEVM, mais n’oubliez pas que ZkVM est également un autre moyen d’expansion. Bien que ZkEVM ne soit pas l’objet de cet article, il convient de rappeler les différences entre ZkVM et ZkEVM dans plusieurs dimensions :
Compatibilité : bien que les deux soient des extensions, leurs objectifs sont différents. ZkEVM se concentre sur la compatibilité directe avec les EVM existants, tandis que ZkVM est positionné pour réaliser une expansion complète, c'est-à-dire optimiser la logique et les performances des dapps, la compatibilité n'est pas la priorité. Une fois la couche inférieure configurée, la compatibilité EVM peut également être obtenue. Performances : les deux présentent des goulots d'étranglement en termes de performances relativement prévisibles. Le principal goulot d'étranglement de ZkEVM est le coût supplémentaire encouru lorsque la compatibilité avec EVM n'est pas adaptée au packaging dans le système de certification ZK. Le goulot d'étranglement de ZkVM est qu'en raison de l'introduction du jeu d'instructions ISA, les contraintes sur la sortie finale sont plus complexes. Expérience du développeur : les ZkEVM de type II (tels que Scroll, Taiko) se concentrent sur la compatibilité avec le bytecode EVM. En d'autres termes, les codes EVM au niveau du bytecode et au-dessus peuvent générer des preuves de connaissance nulle correspondantes via ZkEVM. Pour ZkVM, il y a deux directions. L'une est de créer son propre DSL (comme Cairo) et l'autre est d'être compatible avec les langages existants plus matures tels que C++/Rust (comme Risc0). À l’avenir, nous prévoyons que les développeurs Ethereum à solidité native pourront migrer vers ZkEVM sans frais, et que des applications plus récentes et plus puissantes fonctionneront sur ZkVM. Beaucoup de gens devraient encore se souvenir de cette image. CairoVM n'a rien à voir avec ZkEVM. La raison essentielle de la lutte entre factions est la différence dans les idées de conception.
Avant de discuter de ZkVM, réfléchissons d’abord à la manière d’implémenter le système de preuve ZK dans la blockchain. D'une manière générale, il existe deux manières d'implémenter des circuits : les systèmes basés sur des circuits et les systèmes basés sur des machines virtuelles (basés sur vm).
Tout d'abord, la fonction du système basé sur des circuits est de convertir directement le programme en contraintes et de les envoyer au système de démonstration ; le système basé sur une machine virtuelle exécute le programme via le jeu d'instructions (ISA). Dans ce processus, génère l'exécution. tracer. Cette trace d'exécution sera ensuite mappée en contraintes puis envoyée au système de preuve.
Pour un système basé sur des circuits, le calcul d'un programme est limité par chaque machine qui exécute le programme. Pour les systèmes basés sur des machines virtuelles, ISA est intégré dans un générateur de circuits et génère des contraintes de programme. En même temps, le générateur de circuits a des limitations sur le jeu d'instructions, le cycle d'exécution, la mémoire, etc. Les machines virtuelles offrent une polyvalence, c'est-à-dire que n'importe quelle machine peut exécuter un programme tant que les conditions d'exécution du programme respectent les restrictions ci-dessus.
Un programme zkp dans une machine virtuelle passe probablement par le processus suivant :
Crédit image : Bryan, IOSG Ventures
Avantages et inconvénients :
Du point de vue du développeur, le développement de systèmes basés sur des circuits nécessite souvent une compréhension approfondie du coût de chaque contrainte. Cependant, pour écrire des programmes de machine virtuelle, le circuit est statique et les développeurs doivent se préoccuper davantage des instructions. Du point de vue du vérificateur, les systèmes basés sur des circuits et les machines virtuelles diffèrent considérablement dans la généralité des circuits, en supposant que le même SNARK pur soit utilisé comme backend. Le système de circuits produit un circuit différent pour chaque programme, tandis que la machine virtuelle produit le même circuit pour différents programmes. Cela signifie que dans un cumul, le système de circuits doit déployer plusieurs contrats de vérificateur sur L1. Du point de vue de l'application, une machine virtuelle rend la logique de l'application plus complexe en intégrant le modèle de mémoire dans la conception, et le but de l'utilisation du système de circuits est d'améliorer les performances du programme. Du point de vue de la complexité du système, les machines virtuelles intègrent plus de complexité dans le système, comme les modèles de mémoire, la communication entre l'hôte et l'invité, etc. En comparaison, le système de circuits est plus simple.
Ce qui suit est un aperçu des différents projets basés sur des circuits et des machines virtuelles actuellement en L1/L2 :
Crédit d'image : Bryan, IOSG Ventures Principes de conception des machines virtuelles
Dans les machines virtuelles, il existe deux principes de conception clés. Tout d’abord, assurez-vous que le programme est exécuté correctement. En d’autres termes, la sortie (c’est-à-dire la contrainte) et l’entrée (c’est-à-dire le programme) doivent correspondre correctement. Cela se fait généralement via le jeu d'instructions ISA. Deuxièmement, assurez-vous que le compilateur fonctionne correctement lors de la conversion du langage de haut niveau vers le format de contrainte approprié.
1. Jeu d'instructions ISA
Spécifie le fonctionnement du générateur de circuit. Sa principale responsabilité est de mapper correctement les instructions en contraintes, qui sont ensuite introduites dans le système de preuve. Les systèmes zk utilisent tous RISC (jeu d'instructions réduit). Il existe deux options ISA :
La première consiste à créer un ISA personnalisé (custom ISA), comme le montre la conception du Caire. De manière générale, il existe quatre types de logique de contraintes :
L'objectif de base de la conception d'un ISA personnalisé est de garantir qu'il y a le moins de contraintes possible afin que l'exécution et la vérification du programme s'exécutent rapidement.
La seconde consiste à utiliser l'ISA existante (ISA existante), qui est adoptée dans la conception de Risc0. En plus de viser des temps d'exécution propres, les ISA existants tels que Risc-V offrent des avantages supplémentaires tels que la convivialité avec les langages front-end et le matériel back-end. Une question (possible encore à résoudre) est de savoir si les ISA existantes prendront du retard en termes de temps de vérification (puisque le temps de vérification n'est pas un objectif principal de conception de Risc-V).
2. Compilateur
D'une manière générale, un compilateur traduit progressivement un langage de programmation en code machine. Dans le contexte de ZK, il fait référence à une représentation de code de bas niveau compilé dans un système de contraintes (R1CS, QAP, AIR, etc.) utilisant des langages de haut niveau tels que C, C++, Rust, etc. Il existe deux méthodes,
Concevez un compilateur basé sur des représentations de circuits existantes dans ZK - par exemple, dans ZK, les représentations de circuits partent de bibliothèques directement appelables comme Bellman et de langages de bas niveau comme Circom. Afin d'agréger différentes représentations, un compilateur comme Zokrates (lui-même un DSL) vise à fournir une couche d'abstraction pouvant être compilée en représentations arbitraires de niveau inférieur. S'appuyer sur l'infrastructure (existante) du compilateur. La logique de base consiste à utiliser une représentation intermédiaire pour plusieurs frontends et backends.
Le compilateur de Risc0 est basé sur une représentation intermédiaire multi-niveaux (MLIR) et peut générer plusieurs IR (similaires à LLVM). Différents IR apportent de la flexibilité aux développeurs, car différents IR ont leurs propres priorités de conception. Par exemple, certains d'entre eux sont optimisés spécifiquement pour le matériel, afin que les développeurs puissent choisir en fonction de leurs propres souhaits. Des idées similaires peuvent être vues dans vnTinyRAM et TinyRAM utilisant GCC. ZkSync est un autre exemple d'exploitation de l'infrastructure du compilateur.
De plus, vous pouvez également voir une infrastructure de compilateur pour zk, telle que CirC, qui emprunte également certaines idées de conception à LLVM.
En plus des deux étapes de conception les plus critiques ci-dessus, il y a quelques autres considérations :
1. Le compromis entre la sécurité du système (sécurité) et le coût de la vérification (coût du vérificateur)
Plus le nombre de bits utilisés par le système est élevé (c'est-à-dire plus la sécurité est élevée), plus le coût de la vérification est élevé. La sécurité se reflète dans le générateur de clé (comme la courbe elliptique représentée dans SNARK).
2. Compatibilité avec le front-end et le back-end
La compatibilité dépend de la disponibilité d'une représentation intermédiaire pour le circuit. L'IR nécessite un équilibre entre l'exactitude (la sortie du programme correspond-elle à l'entrée + la sortie est-elle conforme au système de preuve) et la flexibilité (prend en charge plusieurs front-ends et back-ends). Si l’IR était initialement conçu pour résoudre des systèmes de contraintes de bas degré comme R1CS, la compatibilité avec d’autres systèmes de contraintes de plus haut degré tels que AIR serait difficile.
3. Des circuits fabriqués à la main sont nécessaires pour améliorer l’efficacité
L’inconvénient de l’utilisation d’un modèle à usage général est qu’il est moins efficace pour certaines opérations simples ne nécessitant pas d’instructions complexes.
Décrivons brièvement quelques théories précédentes,
Avant le protocole Pinocchio : implémentait des calculs vérifiables, mais le temps de vérification était très lent. Protocole Pinocchio : fournissait une faisabilité théorique en termes de vérifiabilité et de taux de réussite de la vérification (c'est-à-dire que le temps de vérification est plus court que le temps d'exécution du programme), et est basé sur sur le protocole TinyRAM du système de circuit : comparé au protocole Pinocchio, TinyRAM ressemble davantage à une machine virtuelle, introduisant ISA, il supprime donc certaines restrictions, telles que l'accès à la mémoire (RAM), le flux de contrôle (flux de contrôle), etc. Protocole vnTinyRAM : permet la génération de clés ( génération de clés) ne dépend pas de chaque programme, offrant une polyvalence supplémentaire. Développez le générateur de circuits, c'est-à-dire soyez capable de gérer des programmes plus volumineux.
Les modèles ci-dessus utilisent tous SNARK comme système de preuve back-end, mais surtout lorsqu'il s'agit de machines virtuelles, STARK et Plonk semblent être un backend plus approprié, fondamentalement parce que leurs systèmes de contraintes sont plus adaptés à la mise en œuvre d'une logique de type CPU.
Ensuite, cet article présentera trois machines virtuelles basées sur STARK : Risc0, MidenVM et CairoVM. Bref, sauf qu'ils utilisent tous les deux STARK comme système de preuve, ils présentent chacun quelques différences :
Risc0 exploite Risc-V pour la simplicité du jeu d'instructions. R0 compile en MLIR, une variante de LLVM-IR conçue pour prendre en charge plusieurs langages de programmation à usage général existants tels que Rust et C++. Risc-V présente également des avantages supplémentaires, tels qu'être plus convivial pour le matériel.
Miden vise à être compatible avec la machine virtuelle Ethereum (EVM) et est essentiellement un rollup d'EVM. Miden dispose désormais de son propre langage de programmation, mais travaille également à prendre en charge Move à l'avenir.
Cairo VM est développé par Starkware. Le système de preuve STARK utilisé par ces trois systèmes a été inventé par Eli Ben-Sasson, actuellement président de Starkware.
Regardons de plus près leurs différences :
* Comment lire le tableau ci-dessus ? Quelques remarques...
Taille des mots - Étant donné que le système de contraintes sur lequel ces machines virtuelles sont basées est AIR, il fonctionne de manière similaire à l'architecture du processeur. Il est donc plus approprié de choisir la longueur du mot CPU (32/64 bits).
Accès à la mémoire - Risc0 utilise des registres principalement parce que le jeu d'instructions Risc-V est basé sur des registres. Miden utilise principalement des piles pour stocker des données car AIR fonctionne comme une pile. CairoVM n'utilise pas de registres à usage général car le coût d'accès à la mémoire (mémoire principale) dans le modèle Cairo est faible.
Flux de programme (exécution du programme) - Il existe des compromis entre les différentes méthodes. Par exemple, pour la méthode racine du mât, elle doit être décodée au fur et à mesure que l'instruction est traitée, de sorte que le coût du prouveur est plus élevé dans les programmes comportant plus d'étapes d'exécution. Les méthodes de démarrage tentent de trouver un équilibre entre le coût du prouveur et celui du vérificateur tout en préservant la confidentialité.
Non-déterminisme - Le non-déterminisme est une propriété importante des problèmes NP-complets. L’exploitation du non-déterminisme permet de vérifier rapidement les exécutions passées. D'un autre côté, cela ajoute plus de contraintes et donc quelques compromis dans la validation.
Accélération sur les opérations complexes - Certains calculs s'exécutent très lentement sur le CPU. Par exemple, les opérations sur bits telles que XOR et AND, les programmes de hachage tels que ECDSA et la vérification de plage... pour la plupart natives de la technologie blockchain/chiffrement, mais pas les opérations natives du processeur (à l'exception des opérations sur bits). La mise en œuvre de ces opérations directement via DSL peut facilement conduire à l'épuisement des cycles de preuve.
Permutation/multiset - largement utilisé dans la plupart des zkVM à deux fins - 1. Réduire le coût du vérificateur en réduisant la nécessité de stocker la trace d'exécution complète 2. Prouver que le vérificateur connaît la trace d'exécution complète
À la fin de l'article, j'aimerais parler du développement actuel de Risc0 et pourquoi cela me passionne.
Développement actuel du R0 :
a. L'infrastructure du compilateur "Zirgen" auto-développée est en cours de développement. Il serait intéressant de comparer les performances de Zirgen avec certains compilateurs spécifiques à zk existants.
b. Certaines innovations intéressantes, telles que l'extension de champ, peuvent atteindre des paramètres de sécurité plus solides et fonctionner sur des entiers plus grands.
c. Témoin des défis observés dans l'intégration entre les sociétés ZK Hardware et ZK Software, Risc0 utilise une couche d'abstraction matérielle pour permettre un meilleur développement côté matériel.
d.Toujours un travail en cours !
Prend en charge les circuits fabriqués à la main et prend en charge plusieurs algorithmes de hachage. Actuellement, des circuits SHA256 dédiés ont été implémentés, mais ils ne répondent pas à tous les besoins. L'auteur estime que le choix spécifique du type de circuit à optimiser dépend du cas d'utilisation fourni par Risc0. SHA256 est un très bon point de départ. D'un autre côté, ZKVM est positionné pour donner aux gens la possibilité, par exemple, de ne pas avoir à s'inquiéter de Keccak s'ils ne le souhaitent pas :)
Récursion : c'est un vaste sujet et je préfère ne pas l'approfondir dans ce rapport. Ce qu'il est important de savoir, c'est que comme Risc0 a tendance à prendre en charge des cas d'utilisation/programmes plus complexes, le besoin de récursivité devient plus pressant. Pour mieux prendre en charge la récursivité, ils travaillent actuellement sur une solution d'accélération GPU côté matériel.
Gestion du non-déterminisme : C'est une propriété que ZKVM doit gérer, alors que les machines virtuelles traditionnelles n'ont pas ce problème. Le non-déterminisme peut aider les machines virtuelles à fonctionner plus rapidement. MLIR est relativement meilleur pour traiter les problèmes liés aux machines virtuelles traditionnelles, et il vaut la peine d'attendre avec impatience de voir comment Risc0 intègre le non-déterminisme dans la conception du système ZKVM.
CE QUI M'EXCITE :
a. Simple et vérifiable !
Dans un système distribué, PoW nécessite un niveau élevé de redondance, car les utilisateurs ne font pas confiance aux autres et doivent donc effectuer les mêmes calculs à plusieurs reprises pour parvenir à un consensus. Et en tirant parti de preuves sans connaissance, réaliser l’état devrait être aussi simple que d’accepter que 1+1=2.
b. Cas d'utilisation plus pratiques :
En plus de l'expansion la plus directe, des cas d'utilisation plus intéressants deviendront réalisables, tels que l'apprentissage automatique sans connaissance, l'analyse de données, etc. Comparé aux langages ZK spécifiques comme Cairo, Rust/C++ a des fonctions plus universelles et puissantes, et davantage de cas d'utilisation Web2 s'exécutent sur la VM Risc0.
c. Communauté de développeurs plus inclusive/mature :
Les développeurs intéressés par STARK et la blockchain n'ont plus besoin de réapprendre le DSL, ils peuvent simplement utiliser Rust/C++.
Merci à Xin Gao, Boyuan de p0xeidon, Daniel de Taiko et Sin7Y pour leur soutien et leurs suggestions de révisions de cet article !
