Testo originale: "IOSG Weekly Brief | Come sopravvivere a ZKVM, una spiegazione dettagliata delle controversie tra fazioni #159"
Autore: Bryan, IOSG Ventures
Sommario
Implementazione del circuito del sistema di prova ZKP: basato su circuito VS basato su macchina virtuale (basato su VM)
Principi di progettazione ZKVM
Confronto tra VM basate su STARK
Perché Risc0 è entusiasmante
L'obiettivo principale della discussione sul rollup nello scorso 2022 sembra essere stato focalizzato su ZkEVM, ma non dimenticare che ZkVM è anche un altro mezzo di espansione. Sebbene ZkEVM non sia il focus di questo articolo, vale la pena ricordare le differenze tra ZkVM e ZkEVM in diverse dimensioni:
Compatibilità: sebbene entrambe siano espansioni, i loro obiettivi sono diversi. L'obiettivo di ZkEVM è ottenere direttamente la compatibilità con EVM esistente, mentre il posizionamento di ZkVM è quello di ottenere un'espansione completa, ovvero ottimizzare la logica e le prestazioni di Dapps, compatibilità non è la priorità. Una volta impostato il livello inferiore, è possibile ottenere anche la compatibilità EVM. Prestazioni: entrambi presentano colli di bottiglia prestazionali relativamente prevedibili. Il collo di bottiglia principale di ZkEVM è il costo aggiuntivo sostenuto quando la compatibilità con EVM non è adatta per il confezionamento nel sistema di certificazione ZK. Il collo di bottiglia di ZkVM è che, a causa dell'introduzione del set di istruzioni ISA, i vincoli sull'output finale sono più complessi. Esperienza dello sviluppatore: ZkEVM di tipo II (come Scroll, Taiko) si concentra sulla compatibilità con EVM Bytecode. In altre parole, i codici EVM a livello Bytecode e superiore possono generare corrispondenti prove a conoscenza zero tramite ZkEVM. Per ZkVM ci sono due direzioni. Una direzione è creare il proprio DSL (come Cairo), e l'altra è essere compatibile con linguaggi esistenti più maturi come C++/Rust (come Risc0). In futuro, prevediamo che gli sviluppatori Ethereum con solidità nativa saranno in grado di migrare a ZkEVM senza alcun costo e che le applicazioni più nuove e più potenti verranno eseguite su ZkVM. Molte persone dovrebbero ancora ricordare che CairoVM non ha nulla a che fare con ZkEVM. La ragione principale della lotta tra fazioni è la differenza nelle idee progettuali.
Prima di discutere di ZkVM, pensiamo innanzitutto a come implementare il sistema di prova ZK nella blockchain. In generale, esistono due modi per implementare i circuiti: sistemi basati su circuiti e sistemi basati su macchine virtuali (basati su VM).
Innanzitutto, la funzione del sistema basato su circuiti è convertire direttamente il programma in vincoli e inviarli al sistema di prova; il sistema basato su macchina virtuale esegue il programma tramite il set di istruzioni (ISA) In questo processo Genera esecuzione traccia. Questa traccia di esecuzione verrà quindi mappata in vincoli e quindi inviata al sistema di prova.
Per un sistema basato su circuiti, il calcolo di un programma è vincolato da ciascuna macchina che esegue il programma. Per i sistemi basati su macchine virtuali, ISA è incorporato in un generatore di circuiti e genera vincoli di programma. Allo stesso tempo, il generatore di circuiti presenta limitazioni sul set di istruzioni, sul ciclo di esecuzione, sulla memoria, ecc. Le macchine virtuali offrono versatilità, ovvero qualsiasi macchina può eseguire un programma purché le condizioni di esecuzione del programma rientrino nelle restrizioni di cui sopra.
Un programma zkp in una macchina virtuale probabilmente passa attraverso il seguente processo:
Credito immagine: Bryan, IOSG Ventures
Vantaggi e svantaggi:
Dal punto di vista dello sviluppatore, lo sviluppo in sistemi basati su circuiti spesso richiede una profonda comprensione del costo di ciascun vincolo. Tuttavia, per scrivere programmi per macchine virtuali, il circuito è statico e gli sviluppatori devono preoccuparsi maggiormente delle istruzioni. Dal punto di vista di un verificatore, i sistemi basati su circuiti e le macchine virtuali differiscono in modo significativo nella generalità dei circuiti, presupponendo che come backend venga utilizzato lo stesso SNARK puro. Il sistema circuitale produce un circuito diverso per ciascun programma, mentre la macchina virtuale produce lo stesso circuito per programmi diversi. Ciò significa che in un rollup il sistema del circuito deve distribuire più contratti di verifica su L1. Dal punto di vista dell'applicazione, una macchina virtuale rende la logica dell'applicazione più complessa incorporando il modello di memoria nel progetto e lo scopo dell'utilizzo del sistema circuitale è migliorare le prestazioni del programma. Dal punto di vista della complessità del sistema, le macchine virtuali incorporano maggiore complessità nel sistema, come modelli di memoria, comunicazione tra host e guest, ecc. In confronto, il sistema di circuiti è più semplice.
Di seguito è riportata un'anteprima dei diversi progetti basati su circuiti e macchine virtuali attualmente in L1/L2:
Credito immagine: Bryan, IOSG Ventures Principi di progettazione delle macchine virtuali
Nelle macchine virtuali esistono due principi di progettazione chiave. Innanzitutto, assicurati che il programma venga eseguito correttamente. In altre parole, l'output (ovvero il vincolo) e l'input (ovvero il programma) dovrebbero corrispondere correttamente. In genere ciò avviene tramite il set di istruzioni ISA. In secondo luogo, assicurarsi che il compilatore funzioni correttamente durante la conversione dal linguaggio di alto livello al formato di vincolo appropriato.
1. Set di istruzioni ISA
Specifica come funziona il generatore di circuiti. La sua responsabilità principale è quella di mappare correttamente le istruzioni in vincoli, che vengono poi inseriti nel sistema di prova. Tutti i sistemi zk utilizzano RISC (set di istruzioni ridotto). Sono disponibili due opzioni ISA:
Il primo è costruire un ISA personalizzato (custom ISA), che può essere visto nel design del Cairo. In generale, esistono quattro tipi di logica dei vincoli come segue.
L'obiettivo di progettazione di base di un ISA personalizzato è garantire che siano presenti meno vincoli possibili in modo che sia l'esecuzione che la verifica del programma vengano eseguite rapidamente.
Il secondo consiste nell'utilizzare l'ISA esistente (ISA esistente), adottato nella progettazione di Risc0. Oltre a puntare a tempi di esecuzione puliti, gli ISA esistenti come Risc-V offrono ulteriori vantaggi come la compatibilità con i linguaggi front-end e l'hardware back-end. Una domanda (che potrebbe essere ancora da affrontare) è se gli ISA esistenti rimarranno indietro nei tempi di verifica (poiché il tempo di verifica non è un obiettivo di progettazione primario di Risc-V).
2. Compilatore
In generale, un compilatore traduce gradualmente un linguaggio di programmazione in codice macchina. Nel contesto di ZK, si riferisce ad una rappresentazione di codice di basso livello compilato in un sistema di vincoli (R1CS, QAP, AIR, ecc.) utilizzando linguaggi di alto livello come C, C++, Rust, ecc. Ci sono due metodi,
Progetta un compilatore basato su rappresentazioni di circuiti esistenti in ZK: ad esempio, in ZK, le rappresentazioni di circuiti iniziano da librerie richiamabili direttamente come Bellman e linguaggi di basso livello come Circom. Per aggregare rappresentazioni diverse, un compilatore come Zokrates (a sua volta un DSL) mira a fornire uno strato di astrazione che può essere compilato in rappresentazioni arbitrarie di livello inferiore. Basarsi sull'infrastruttura del compilatore (esistente). La logica di base è utilizzare una rappresentazione intermedia per più frontend e backend.
Il compilatore di Risc0 si basa sulla rappresentazione intermedia multilivello (MLIR) e può generare più IR (simile a LLVM). IR diversi offrono flessibilità agli sviluppatori, perché IR diversi hanno le proprie priorità di progettazione. Ad esempio, alcuni di essi sono ottimizzati specificamente per l'hardware, quindi gli sviluppatori possono scegliere in base ai propri desideri. Idee simili possono essere viste in vnTinyRAM e TinyRAM usando GCC. ZkSync è un altro esempio di sfruttamento dell'infrastruttura del compilatore.
Inoltre, puoi anche vedere alcune infrastrutture del compilatore per zk, come CirC, che prende in prestito anche alcune idee di progettazione da LLVM.
Oltre alle due fasi di progettazione più critiche di cui sopra, ci sono alcune altre considerazioni:
1. Il compromesso tra sicurezza del sistema (sicurezza) e costo di verifica (costo del verificatore)
Maggiore è il numero di bit utilizzati dal sistema (ovvero maggiore è la sicurezza), maggiore sarà il costo della verifica. La sicurezza si riflette nel generatore di chiavi (come la curva ellittica rappresentata in SNARK).
2. Compatibilità con front-end e back-end
La compatibilità dipende dalla disponibilità di una rappresentazione intermedia per il circuito. L'IR richiede un equilibrio tra correttezza (l'output del programma corrisponde all'input + l'output è conforme al sistema di prova) e flessibilità (supporta più front-end e back-end). Se IR fosse stato originariamente progettato per risolvere sistemi di vincoli di basso grado come R1CS, la compatibilità con altri sistemi di vincoli di grado superiore come AIR sarebbe difficile.
3. Per migliorare l'efficienza sono necessari circuiti realizzati a mano
Lo svantaggio di utilizzare un modello generico è che è meno efficiente per alcune operazioni semplici che non richiedono istruzioni complesse.
Descriviamo brevemente alcune teorie precedenti,
Prima del protocollo Pinocchio: implementati calcoli verificabili, ma il tempo di verifica era molto lento Protocollo Pinocchio: forniva fattibilità teorica in termini di verificabilità e tasso di successo della verifica (ovvero, il tempo di verifica è inferiore al tempo di esecuzione del programma) ed è basato. sul sistema di circuiti Protocollo TinyRAM: rispetto al protocollo Pinocchio, TinyRAM è più simile a una macchina virtuale, introduce ISA, quindi elimina alcune restrizioni, come l'accesso alla memoria (RAM), il flusso di controllo (flusso di controllo), ecc. Protocollo vnTinyRAM : consente la generazione delle chiavi (generazione delle chiavi) non dipende da ogni programma, fornendo ulteriore versatilità. Espandi il generatore di circuiti per poter gestire programmi più grandi.
I modelli di cui sopra utilizzano tutti SNARK come sistema di prova del backend, ma soprattutto quando si ha a che fare con macchine virtuali, STARK e Plonk sembrano essere un backend più adatto, fondamentalmente perché i loro sistemi di vincolo sono più adatti all'implementazione di una logica simile alla CPU.
Successivamente, questo articolo introdurrà tre macchine virtuali basate su STARK: Risc0, MidenVM e CairoVM. In breve, a parte il fatto che entrambi utilizzano STARK come sistema di prova, presentano alcune differenze:
Risc0 sfrutta Risc-V per la semplicità del set di istruzioni. R0 si compila in MLIR, una variante di LLVM-IR progettata per supportare più linguaggi di programmazione generici esistenti come Rust e C++. Risc-V presenta anche alcuni vantaggi aggiuntivi, come essere più intuitivo per l'hardware.
Miden mira a essere compatibile con l'Ethereum Virtual Machine (EVM) ed è essenzialmente un rollup di EVM. Miden ora ha un proprio linguaggio di programmazione, ma sta anche lavorando per supportare Move in futuro.
Cairo VM è sviluppato da Starkware. Il sistema di prova STARK utilizzato da questi tre sistemi è stato inventato da Eli Ben-Sasson, attualmente presidente di Starkware.
Diamo uno sguardo più da vicino alle loro differenze:
*Come leggere la tabella sopra? Alcune note...
Dimensione parola: poiché il sistema di vincoli su cui si basano queste macchine virtuali è AIR, funziona in modo simile all'architettura della CPU. Quindi è più appropriato scegliere la lunghezza della parola della CPU (32/64 bit).
Accesso alla memoria: Risc0 utilizza i registri principalmente perché il set di istruzioni Risc-V è basato su registri. Miden utilizza principalmente gli stack per archiviare i dati perché AIR funziona come stack. CairoVM non utilizza registri di uso generale perché il costo di accesso alla memoria (memoria principale) nel modello Cairo è basso.
Feed del programma (esecuzione del programma): esistono dei compromessi tra i diversi metodi. Ad esempio, per il metodo mast root, deve essere decodificato mentre l'istruzione viene elaborata, quindi il costo del prover è maggiore nei programmi con più passaggi di esecuzione. I metodi di bootloading tentano di trovare un equilibrio tra il costo del prover e il costo del verificatore mantenendo la privacy.
Non determinismo - Il non determinismo è una proprietà importante dei problemi NP-completi. Sfruttare il non determinismo aiuta a verificare rapidamente le esecuzioni passate. D’altro canto, aggiunge ulteriori vincoli e quindi alcuni compromessi nella validazione.
Accelerazione su operazioni complesse - Alcuni calcoli vengono eseguiti molto lentamente sulla CPU. Ad esempio, operazioni bit come XOR e AND, programmi hash come ECDSA e controllo dell'intervallo... per lo più native della tecnologia blockchain/crittografia ma non operazioni native della CPU (eccetto le operazioni bit). Implementare queste operazioni direttamente tramite DSL può facilmente portare all'esaurimento dei cicli di prova.
Permutazione/multiset - ampiamente utilizzato nella maggior parte delle zkVM per due scopi: 1. Ridurre il costo del verificatore riducendo la necessità di archiviare la traccia di esecuzione completa 2. Dimostrare che il verificatore conosce la traccia di esecuzione completa
Alla fine dell'articolo vorrei parlare dell'attuale sviluppo di Risc0 e del motivo per cui mi entusiasma.
Sviluppo attuale R0:
a. L'infrastruttura del compilatore "Zirgen" sviluppata autonomamente è in fase di sviluppo. Sarebbe interessante confrontare le prestazioni di Zirgen con alcuni compilatori specifici di zk esistenti.
b. Alcune innovazioni interessanti, come l'estensione del campo, possono raggiungere parametri di sicurezza più solidi e operare su numeri interi più grandi.
c. A testimonianza delle sfide riscontrate nell'integrazione tra le società ZK Hardware e ZK Software, Risc0 utilizza un livello di astrazione hardware per consentire un migliore sviluppo dal lato hardware.
d. Ancora un lavoro in corso! Ancora in fase di sviluppo!
Supporta circuiti realizzati a mano e supporta più algoritmi di hashing. Attualmente sono stati implementati circuiti SHA256 dedicati, che tuttavia non soddisfano tutte le esigenze. L'autore ritiene che la scelta specifica di quale tipo di circuito ottimizzare dipenda dal caso d'uso fornito da Risc0. SHA256 è un ottimo punto di partenza. D'altra parte, ZKVM è posizionato per dare alle persone la flessibilità di, ad esempio, non doversi preoccupare di Keccak se non vogliono :)
Ricorsione: questo è un argomento importante e preferisco non approfondirlo in questo rapporto. Ciò che è importante sapere è che poiché Risc0 tende a supportare casi d'uso/programmi più complessi, la necessità di ricorsione diventa più urgente. Per supportare ulteriormente la ricorsione, stanno attualmente lavorando su una soluzione di accelerazione GPU lato hardware.
Gestione del non determinismo: questa è una proprietà che ZKVM deve affrontare, mentre le macchine virtuali tradizionali non hanno questo problema. Il non determinismo può aiutare le macchine virtuali a funzionare più velocemente. MLIR è relativamente migliore nell'affrontare i problemi relativi alle macchine virtuali tradizionali e vale la pena attendere con impazienza come Risc0 incorpori il non determinismo nella progettazione del sistema ZKVM.
COSA MI ENTUSIASMANTE:
a. Semplice e verificabile!
In un sistema distribuito, PoW richiede un elevato livello di ridondanza perché le persone non si fidano degli altri e quindi devono eseguire ripetutamente gli stessi calcoli per raggiungere il consenso. E sfruttando le prove a conoscenza zero, realizzare lo stato dovrebbe essere facile come concordare che 1+1=2.
b. Casi d'uso più pratici:
Oltre all’espansione più diretta, diventeranno fattibili casi d’uso più interessanti, come l’apprendimento automatico a conoscenza zero, l’analisi dei dati, ecc. Rispetto a linguaggi ZK specifici come Cairo, Rust/C++ ha funzioni più universali e potenti e sulla VM Risc0 vengono eseguiti più casi d'uso web2.
c. Comunità di sviluppatori più inclusiva/matura:
Gli sviluppatori interessati a STARK e blockchain non devono più imparare di nuovo la DSL, possono semplicemente usare Rust/C++.
Grazie a Xin Gao, Boyuan di p0xeidon, Daniel di Taiko e Sin7Y per il loro supporto e suggerimenti per la revisione di questo articolo!
