Zilch es un marco que implementa ARgumentos de conocimiento (STARK) escalables y transparentes (sin necesidad de una configuración confiable). Zilch consta de dos componentes principales: un front-end y un back-end.
El front-end consta del lenguaje de programación ZeroJava, un subconjunto de Java diseñado para argumentos de conocimiento cero y un compilador para traducir el código ZeroJava a instrucciones ensambladoras zMIPS; zMIPS es nuestra extensión de MIPS ISA para admitir la programación de ZKP.
El back-end traduce las instrucciones de ensamblaje de zMIPS a circuitos aritméticos y genera ZKP para verificar la evaluación de estos circuitos. El back-end se basa en las construcciones ZKP de la biblioteca zkSTARK y extiende el modelo de programación de libSTARK a la máquina abstracta zMIPS.
Descargo de responsabilidad: el código es de calificación académica , destinado a la revisión y evaluación académica por pares. Los autores han probado el código con Ubuntu 20.04
.
Si encuentra útil nuestro trabajo, cite nuestra publicación (IEEE Xplore, Cryptology ePrint Archive):
D. Mouris and N. G. Tsoutsos, "Zilch: A Framework for Deploying Transparent Zero-Knowledge Proofs,"
in IEEE Transactions on Information Forensics and Security (TIFS), 2021, DOI: 10.1109/TIFS.2021.3074869
apt install g++
apt install libssl-dev
apt install libboost-all-dev
apt install libjsoncpp-dev
apt-get install libgtest-dev
Para conocer las dependencias del compilador ZeroJava, consulte el repositorio de ZeroJava.
$ git clone --recursive https://github.com/TrustworthyComputing/Zilch
$ cd Zilch
$ make -j8
$ make zilch-tests -j8
Para verificar la instalación, escriba ./zilch-tests
.
$ cd ZeroJava-compiler
$ mvn initialize
$ mvn package
$ ./zilch --asm <zMIPS assembly file path> [--tsteps <trace length log_2>] [--security <security parameter]> [--pubtape <primaryTapeFile>] [--auxtape <auxTapeFile>] [--verifier | --prover] [--address <address:port_number>]
--help : Display this help message
--examples : Display some usage examples
--show-asm : Display zMIPS assembly input
--verbose : Verbose output, print BAIR, ACSP, APR and FRI specifications
--asm : Path to the zMIPS assembly code (required)
--tsteps : trace length log_2 (optional, default = 5)
--security : security parameter (optional, default = 60)
--pubtape : path to the primary tape file (optional, default = none)
--auxtape : path to the auxiliary tape file (optional, default = none)
The flags below enable verification over the network; if neither is enabled, the execution will be locally. Verifier acts as the server and thus should be executed first.
--address : verifier-address:port-number (optional, default = 'localhost:1234')
--verifier : enables execution of the verifier, listening on port-number (optional, default = false)
--prover : enables execution of the prover, transmitting to verifier-address:port-number (optional, default = false)
vea los ejemplos a continuación sobre cómo usar las banderas.
Nota: Zilch detecta automáticamente las cintas públicas y privadas si están en el mismo directorio que el archivo ensamblador zMIPS y se denominan pubtape.txt
y auxtape.txt
.
En el directorio ejemplos-zmips incluimos varios ejemplos de zMIPS.
A nivel de ensamblador, nuestras etiquetas son etiquetas alfanuméricas que comienzan y terminan con un guión bajo doble (por ejemplo, __example_label__
), mientras que dentro de Zilch estas etiquetas se convierten en números de instrucción.
Por ejemplo, a continuación se muestra el código zMIPS para calcular el factorial de 5:
move $t3, 5
move $t1, 1
move $t2, 1
__L1__:
mult $t1, $t1, $t2
add $t2, $t2, 1
bge $t3, $t2, __L1__
answer $t1
En macros.json definimos macroinstrucciones personalizadas basadas en instrucciones zMIPS existentes. Por ejemplo, hemos definido macroinstrucciones inc
y min
como se muestra a continuación:
"inc": {
"reg1": "$x",
"macro": "add $x, $x, 1"
}
Esto significa que inc
usa un registro. Un programa zMIPS puede utilizar la instrucción inc como
move $t0, 5
inc $t0
answer $t0
la respuesta sería 6.
La macroinstrucción min
utiliza tres registros y también etiquetas:
"min": {
"reg1": "$x",
"reg2": "$y",
"reg3": "$z",
"uses_label" : "true",
"macro" : "blt $y, $z, __min_label__
move $x, $z
j __end_min_label__
__min_label__
move $x, $y
__end_min_label__"
}
La cinta primaria se llena con 1, 2, 3, 4, ...
, mientras que la cinta auxiliar contiene 101, 102, 103, 104, ...
pubread $t0 ; consume next word from public tape and store it to r0
print $t0
secread $t1 ; consume next word from auxiliary tape and store it to r1
print $t1
pubseek $t0, 3 ; read the 4th word from the public tape and store it to r0
print $t0
secseek $t1, 3 ; read the 4th word from the auxiliary tape and store it to r1
print $t1
answer $t0
Para ejecutar el programa anterior, simplemente ejecute ./zilch --asm ./examples-zmips/read_test/read_test.zmips --tsteps 5 --pubtape ./examples-zmips/read_test/read_test.pubtape --auxtape ./examples-zmips/read_test/read_test.auxtape
.
El comportamiento predeterminado (sin indicadores --address
, --verifier
, --prover
) del ejecutable zilch
da como resultado una ejecución local. Para habilitar la verificación a través de la red, primero se debe ejecutar el verificador ( --verifier
flag) y luego el prover ( --prover
flag). El verificador actúa como un servidor esperando que el probador se conecte, ejecuta, imprime y devuelve su decisión al probador.
Por ejemplo, un ejemplo simple de lectura de cintas a través de la red:
Primero ejecute el verificador escuchando en el puerto 2324
:
./zilch --asm ./examples-zmips/read_test/read_test.zmips --tsteps 10 --security 120 --pubtape ./examples-zmips/read_test/read_test.pubtape --auxtape ./examples-zmips/read_test/read_test.auxtape --verifier --address localhost:2324
Y luego el probador se conectará al puerto 2324
:
./zilch --asm ./examples-zmips/read_test/read_test.zmips --tsteps 10 --security 120 --pubtape ./examples-zmips/read_test/read_test.pubtape --auxtape ./examples-zmips/read_test/read_test.auxtape --prover --address localhost:2324