Come zk-ASM può fornire un Internet sicuro e affidabile
Web3.com Ventures Analisi della ricerca originale
0xFishylosopher
Nota: questo articolo è un pezzo abbastanza denso dal punto di vista tecnico e presuppone una familiarità concettuale di base con zk-Proofs e/o zk-Rollups. Un'introduzione più generale a questi principi può essere trovata qui.

introduzione
Zero Knowledge Proofs, in particolare zk-SNARKs (Succinct Non-interactive Arguments of Knowledge) è forse una delle tecnologie più importanti alle frontiere del Web 3. Mentre la maggior parte dell'attenzione dei media e degli investimenti in questo sottocampo si è spostata verso zk -Rollup, soluzioni di scalabilità che forniscono grande scalabilità alle blockchain L1 come Ethereum, questa non è affatto l'unica applicazione di zk-SNARK. In questo saggio analizzerò in modo approfondito il concetto di codice Zero-Knowledge Assembly (o zkASM), valutando i suoi casi d'uso sia negli zk-Rollup che oltre, esplorando le sue possibilità teoriche nel reinventare Internet come la conosciamo.
Principi tecnici
zk-ASM, come suggerisce il nome, contiene due parti tecniche principali: ZK e ASM. La parte ZK si riferisce a zk-SNARK, o argomenti di conoscenza succinti non interattivi, mentre la parte ASM si riferisce al codice Assembly. Per comprendere il potenziale di zk-ASM, dobbiamo prima comprendere i fondamenti teorici di entrambi questi concetti apparentemente arcani.
zk-SNARK
Gli zk-SNARK sono il fiore all'occhiello delle zk-Proofs: sono una prova succinta che una certa affermazione è vera laddove la prova non rivela nulla sui dati da dimostrare. Ad esempio, considera qualcuno che afferma l'affermazione "Conosco un m tale che C(m) = 0", dove m è un messaggio lungo un gigabyte e C è una funzione. Una zk-SNARK sarebbe una prova molto breve (< 1 GB) che può essere rapidamente verificata e in cui non viene rivelato nulla su m (oltre alle informazioni disponibili al pubblico) [1].
Allora, cos’è questa “C(m)”? Come è utile? Questa funzione è in realtà un circuito aritmetico, o una rappresentazione del Grafico Aciclico Diretto (DAG) di una funzione specifica che vogliamo eseguire, come mostra il diagramma [2]. La "m" è essenzialmente i dati di ingresso nel circuito e i "nodi" specifici nel circuito sono porte logiche individuali o operazioni aritmetiche. Ad esempio, un nodo "+" può avere "2" e "3" come input e restituire un "5" all'operatore successivo. Pertanto, un’operazione aritmetica o logica arbitraria può essere codificata in un “circuito aritmetico”.

Una volta che abbiamo questo circuito aritmetico come rappresentazione del codice su cui vogliamo eseguire zk-SNARK, possiamo iniziare a costruire questo zk-SNARK. Fondamentalmente, uno zk-SNARK è possibile grazie al “teorema fondamentale dell’algebra”, che afferma che un polinomio di grado “d” ha al più radici “d” [3]. Il trucco matematico consiste in due passaggi: (1) convertire in qualche modo la funzione "f(m)" che vogliamo dimostrare in un polinomio (e attenersi a quello), e (2) utilizzare il "teorema fondamentale dell'algebra" per interagire con il polinomio e fornire una dimostrazione succinta. In gergo tecnico, la prima parte è chiamata “Polynomial Commitment Scheme” (PCS), e la seconda parte è chiamata “Polynomial Interactive Oracle Proof” (PIOP) [4].

Anche se le implementazioni specifiche di PCS e PIOP vanno oltre lo scopo di questo articolo, finora abbiamo ricavato uno schizzo approssimativo dei passaggi principali di zk-SNARK:
Avere una funzione a scelta (funzione di codice, equazione matematica ecc.) che si desidera eseguire zk-SNARK
Codifica questa funzione come un circuito aritmetico C(m)
Esegui un PCS per ottenere una rappresentazione polinomiale di questo circuito aritmetico
Esegui un PIOP per ottenere una prova concisa di dimensioni logaritmiche rispetto alla “m” originale
E viola, abbiamo uno zk-SNARK personalizzato che può dimostrare che qualcuno conosce un determinato messaggio senza rivelare quale sia quel messaggio.
Codice di assemblaggio
Il secondo pezzo del puzzle di zk-ASM è l'idea del codice Assembly. Il codice assembly è una classe di linguaggi contenente istruzioni in un linguaggio molto basso che sono facili da leggere per una macchina ma abbastanza difficili da decifrare per un essere umano. A differenza dei linguaggi di livello superiore, come Python, Java o anche C, i linguaggi Assembly contengono funzioni molto primitive, come spostare, confrontare, aggiungere e saltare su una serie di registri di dati sul processore e su posizioni di memoria codificate. Ad esempio, il codice Python per stampare i numeri da 1 a 9 sullo schermo è 123456789:

Abbastanza facile da capire, vero? Ora eccone la versione x86 Assembly [5]:

Molto più sgradevole, soprattutto per un'operazione così semplice. Allora perché usare il linguaggio Assembly? Come affermato sopra, anche se queste istruzioni potrebbero non essere facili da leggere per un essere umano, sono molto facili da "assemblare" nel codice byte 110011001 affinché una macchina possa leggerle ed eseguirle (questo è chiamato assemblatore) [6]. In confronto, linguaggi di livello superiore come Python e Java sono molto più facili da leggere, ma i programmi scritti in questi linguaggi non possono essere eseguiti direttamente da un processore. Dobbiamo invece fare affidamento su un “compilatore” che mastica il codice Python o Java che scriviamo e sputa un dump di codice assembly come quello sopra per essere assemblato ed eseguito dalla macchina. Possiamo aspettarci che lo stesso pezzo di Python o Java funzioni senza problemi su diversi processori e diversi sistemi operativi perché il compilatore fa il lavoro pesante, compilando il codice sorgente in un linguaggio Assembly specifico per quel processore o sistema operativo.
Poiché tutti i linguaggi vengono compilati in codice assembly (che a sua volta viene compilato in codice binario eseguibile), l'assembly è essenzialmente come una "madre di tutti i linguaggi". Supponiamo ora di essere in grado di trasformare tutti gli operandi in un linguaggio Assembly (come x86 o RISC-V) in una rappresentazione di circuito aritmetico, in modo tale da poter fornire prove zk-SNARK di tutti gli operandi in questo Assembly lingua. Ciò significa che siamo teoricamente in grado di fornire uno zk-SNARK di qualsiasi programma scritto in un linguaggio arbitrario di alto livello (come Python o Java) che si compila in questo linguaggio Assembly. Ed è per questo che dobbiamo preoccuparci di pensare agli zk-ASM.
Applicazioni pratiche
Rollup zk-EVM: poligono zk-ASM
Una delle applicazioni più importanti per zk-ASM è la creazione di zk-Rollup compatibili con Ethereum Virtual Machine o zk-EVM. Una zk-EVM è incredibilmente importante per la scalabilità della blockchain perché consente ai programmatori di eseguire la distribuzione su una catena L2 basata su zk-Rollup senza modificare gran parte (se presente) del proprio codice [7]. In questo campo, zk-EVM di Polygon è un caso di studio esemplare che dimostra come zk-ASM può essere utilizzato per raggiungere questo obiettivo.

Quando i programmatori sviluppano sulla blockchain di Ethereum L1, di solito codificano in Solidity, che è un linguaggio di alto livello simile a C. Questo codice Solidity viene compilato in una serie di codici operativi EVM, come ADD, SLOAD ed EQ, prima di essere eseguito sulla blockchain L1 [8]. Per impostazione predefinita, questo processo ovviamente non crea alcun tipo di zk-Proof. Il trucco di Polygon è creare un metodo per interpretare ciascuno degli opcode EVM nel loro zk-ASM scritto su misura, che è molto compatibile con zk-SNARK. Quindi, il loro zk-EVM L2 eseguirà zk-ASM, creando allo stesso tempo un circuito zk-SNARK dell'ASM per creare una prova zk-SNARK [9]. Ad esempio, il codice operativo ADD nell'EVM verrà tradotto in zk-ASM di Polygon come segue [10]:

Poiché il gioco di prestigio di Polygon zk-EVM avviene a livello di assemblaggio, sono due livelli rimossi dal codice che tocca il programmatore medio di Ethereum, il livello di "Solidità". Questo è il motivo per cui la maggior parte degli sviluppatori può trasferire il proprio codice EVM creato per la rete principale Ethereum direttamente su Polygon zk-EVM. Inoltre, poiché Polygon zk-EVM "mantiene" lo stack tecnologico di Ethereum al livello del codice operativo, tutta l'infrastruttura di debug che si basa sull'analisi dei codici operativi compilati sarà mantenuta utilizzabile e intatta. Questo è diverso da altri progetti zk-EVM, come zk-Sync, che non fornisce zk-Proof a livello di codice operativo. Pertanto, anche se Polygon inventa e dimostra il proprio linguaggio Assembly, Vitalik scrive che "può ancora verificare il codice EVM, utilizza semplicemente una logica interna diversa per farlo" [11].
Oltre i rollup: zk-WASM
Gli zk-EVM non sono affatto l'unica applicazione per gli zk-ASM. Ricordiamo la nostra precedente affermazione secondo cui i linguaggi Assembly sono essenzialmente "la madre di tutti i linguaggi" e che la creazione di zk-ASM sbloccherà zk-Proof per programmi generici scritti in qualsiasi linguaggio che si compila in quel linguaggio Assembly. Web Assembly, o WASM, è uno dei più importanti linguaggi assembly emergenti. Pubblicato per la prima volta nel 2018, lo scopo di WASM è creare un linguaggio Assembly che aumenti la velocità di esecuzione delle app Web e fornisca un complemento esecutivo a Javascript, il linguaggio di codifica principale dietro il Web [12].
In sostanza, con lo sviluppo del Web nel corso degli anni, la crescente dimensione e complessità delle Web App ha fatto sì che spesso sia incredibilmente lento per i browser compilare tutto ciò che è scritto in Javascript e debba fare affidamento su complessi cicli di compilazione-ottimizzazione-ricaricamento [12]. WebAssembly, d'altro canto, elimina la necessità di fare affidamento su complessi motori di esecuzione del browser fornendo un linguaggio assembly portabile, modulare e facilmente eseguibile. Inoltre, come linguaggio Assembly, WASM consente ai programmatori di scrivere direttamente frammenti di codice in C, C++, Rust, Java o Ruby che vengono eseguiti in modo nativo in un browser. WASM è quindi diventata una tecnologia di scelta per “fornire funzioni serverless distribuite” [13].
Allora perché e come entrano in gioco gli zk-SNARK? WASM è unico in quanto è una tecnologia lato client, in grado di interagire direttamente con gli input e i dati dell'utente. Poiché spesso questi includono dati sensibili come password e informazioni personali, abbiamo bisogno di una tecnologia che (1) garantisca che il programma venga eseguito correttamente e che (2) le nostre informazioni sensibili non vengano divulgate. Come descritto sopra, zk-SNARK è una soluzione perfetta per risolvere entrambi questi problemi, ed è quindi un importante pezzo del puzzle per proteggere WASM [14].
Sebbene il lavoro sullo sviluppo di zk-WASM sia ancora nelle fasi iniziali, recentemente ci sono stati alcuni progetti che hanno rilasciato prototipi di circuiti zk-SNARK per WebAssembly. Ad esempio, l’emulatore zk-SNARK “ZAWA” di Delphinus Lab presenta un metodo per codificare gli operandi e la semantica di una macchina virtuale WASM in un circuito aritmetico, che le consente di condurre prove zk-SNARK [13]. Col passare del tempo, i circuiti zk-WASM saranno senza dubbio continuamente ottimizzati, consentendo così ai programmi scritti in linguaggi generici (come C, C++, Rust e Ruby) di adottare il paradigma di zk-Proofs.
Conclusione
In questo saggio, abbiamo esplorato le basi teoriche di zk-ASM ed esaminato due casi di studio paradigmatici di zk-ASM: l'uso di zk-ASM da parte di Polygon per creare uno zk-EVM a livello di codice operativo, nonché l'applicazione di zk -SNARK su WebAssembly per creare zk-WASM. In definitiva, la promessa di zk-ASM è quella di unire l’interoperabilità e la scalabilità del Web 2 con l’affidabilità e la sicurezza del Web 3.
Da un lato, le blockchain cercano sempre più di andare oltre gli attuali colli di bottiglia in termini di throughput e potenzialmente di supportare l’esecuzione, mentre dall’altro i metodi Web 2 sono sempre più sotto attacco per la protezione inadeguata dei dati e della privacy degli utenti. Poiché i programmatori sono in grado di utilizzare i paradigmi di progettazione Web 3 nel loro codice Web 2 e di introdurre linguaggi e codici Web 2 nella blockchain, gli zk-ASM generici possono rappresentare un punto di fusione nel mondo Web 2 e Web 3 [15]. È in questo senso che zk-ASM può permetterci di reimmaginare un Internet più sicuro e senza fiducia.
🐦 @0xfishylosopher
📅 17 dicembre 2022
Dichiarazione di non responsabilità: le informazioni presentate sopra sono puramente educative, non costituiscono una consulenza finanziaria e rappresentano esclusivamente il punto di vista dell'autore. Delphinus Lab è una società in portafoglio di Web3.com Ventures.
Riferimenti
[1] https://z.cash/technology/zksnarks/
[2] https://cs251.stanford.edu/lectures/lecture14.pdf
[3] https://www.britannica.com/science/fundamental-theorem-of-algebra
[4] Creazione di SNARK efficienti: https://cs251.stanford.edu/lectures/lecture15.pdf
[5] Esempio tratto da: https://www.tutorialspoint.com/assembly_programming/assembly_loops.htm
[6] https://en.wikipedia.org/wiki/Assembly_lingual
[7] https://www.alchemy.com/overviews/zkevm
[8] Per l'elenco dei codici operativi: https://ethereum.org/en/developers/docs/evm/opcodes/
[9] https://wiki.polygon.technology/docs/zkEVM/zkASM/introduction
[10] https://wiki.polygon.technology/docs/zkEVM/zkASM/some-examples
[11] https://vitalik.ca/general/2022/08/04/zkevm.html
[12] https://blog.developer.adobe.com/understanding-webassembly-wasm-d5b592208ecc
[13] https://jhc.sjtu.edu.cn/~hongfeifu/manuscriptb.pdf
[14] https://hyperoracle.medium.com/zkwasm-the-next-chapter-of-zk-and-zkvm-471038b1fba6
[15] https://delphinuslab.com/zk-wasm/