NewsDevelopersEnterpriseBlockchain ExplainedEvents and ConferencesPressButlletins informatius
Subscriu-te al nostre butlletí.
Correu electrònic
Respectem la vostra privadesa
IniciBlogDesenvolupament de la cadena de blocs
Introducció a zk-SNARKs
Una visió general de les proves de coneixement zero i de com integrar zk-SNARK a Ethereum. per ConsenSys, 27 de març de 2017 Publicat el 27 de març de 2017
En aquest post, pretenem donar una visió general dels zk-SNARK des d’un punt de vista pràctic. Tractarem les matemàtiques reals com una caixa negra i intentarem desenvolupar algunes intuïcions sobre com les podem utilitzar. També donarem una aplicació senzilla del treball recent realitzat a integrant zk-SNARKs a Ethereum.
Proves de coneixement zero
L’objectiu de les proves de coneixement zero és que un verificador pugui convèncer-se que un prover té coneixement d’un paràmetre secret, anomenat testimoni, que satisfà alguna relació, sense revelar el testimoni al verificador o a ningú.
Podem pensar-ho més concretament en tenir un programa, denominat C, que pren dues entrades: C (x, w). L’entrada x és l’entrada pública, i w és l’entrada de testimoni secret. La sortida del programa és booleana, és a dir, veritable o falsa. L’objectiu es dóna llavors a una entrada pública específica x, demostreu que el prover coneix una entrada secreta w tal que C (x, w) == true.
Anem a discutir específicament proves no interactives de coneixement zero. Això vol dir que la prova en si és un blob de dades que es pot verificar sense cap interacció del prover.
Exemple de programa
Suposem que a Bob se li dóna un hash H d’algun valor, i vol tenir una prova que Alice sap el valor que hashes a H. Normalment Alice ho demostraria donant s a Bob, després del qual Bob calcularia el hash i comprovaria que és igual a H.
Tot i així, suposem que Alice no vol revelar-li el valor a Bob, sinó que només vol demostrar que en sap el valor. Per a això pot utilitzar un zk-SNARK.
Podem descriure l’escenari d’Alice mitjançant el programa següent, escrit aquí com a funció Javascript:
funció C (x, w) {return (sha256 (w) == x);} Idioma del codi: JavaScript (javascript)
En altres paraules: el programa inclou un hash públic x i un valor secret w i retorna true si el hash SHA-256 de w és igual a x.
Traduint el problema d’Alicia mitjançant la funció C (x, w) veiem que Alice necessita crear una prova que posseeix s tal que C (H, s) == true, sense haver de revelar s. Aquest és el problema general que resolen els zk-SNARK.
Definició d’un zk-SNARK
Un zk-SNARK consta de tres algorismes G, P, V definits de la manera següent:
El generador de claus G pren un paràmetre secret lambda i un programa C i genera dues claus disponibles públicament, una clau de prova pk i una clau de verificació vk. Aquestes claus són paràmetres públics que només cal generar una vegada per a un determinat programa C.
El prover P pren com a entrada la clau de prova pk, una entrada pública x i un testimoni privat w. L’algorisme genera una prova prf = P (pk, x, w) que el prover coneix un testimoni w i que el testimoni compleix el programa.
El verificador V calcula V (vk, x, prf) que retorna cert si la prova és correcta i fals en cas contrari. Per tant, aquesta funció torna a ser vertadera si el prover coneix un testimoni que compleix amb C (x, w) == veritable.
Tingueu en compte aquí el paràmetre secret lambda utilitzat al generador. De vegades, aquest paràmetre fa difícil l’ús d’zk-SNARK en aplicacions del món real. La raó és que qualsevol persona que conegui aquest paràmetre pot generar proves falses. Concretament, tenint en compte qualsevol programa C i aportació pública x, una persona que sap lambda pot generar una prova fake_prf tal que V (vk, x, fake_prf) avalui a true sense coneixement del secret w.
Per tant, el funcionament del generador requereix un procés molt segur per assegurar-vos que ningú no coneix i desa el paràmetre en cap lloc. Aquesta va ser la raó del cerimònia extremadament elaborada l’equip de Zcash va dur a terme per generar la clau de prova i la clau de verificació, tot assegurant-se que el paràmetre lambda de “residus tòxics” va ser destruït en el procés.
Un zk-SNARK per al nostre programa d’exemple
Com utilitzarien Alice i Bob un zk-SNARK a la pràctica per tal que Alice demostri que coneix el valor secret de l’exemple anterior??
Primer de tot, tal com s’ha comentat anteriorment, utilitzarem un programa definit per la funció següent:
funció C (x, w) {return (sha256 (w) == x); } Idioma del codi: JavaScript (javascript)
El primer pas és que Bob executi el generador G per crear la clau de prova pk i la clau de verificació vk. En primer lloc, genereu lambda a l’atzar i utilitzeu-lo com a entrada:
(pk, vk) = G (C, lambda)
Gestioneu el paràmetre lambda amb cura, perquè si Alice aprèn el valor de lambda, podrà crear proves falses. Bob compartirà pk i vk amb Alice.
Alícia farà ara el paper del proverbial. Ha de demostrar que coneix el valor s que comparteix amb el hash conegut H. Executa l’algorisme de prova P utilitzant les entrades pk, H i s per generar la prova prf:
prf = P (pk, H, s)
A continuació, Alice presenta la prova prf a Bob, que executa la funció de verificació V (vk, H, prf), que tornaria a ser veritable en aquest cas, ja que Alice coneixia adequadament els secrets. Bob pot confiar que Alice coneixia el secret, però Alice no va necessitar revelar-li el secret.
Claus de comprovació i verificació reutilitzables
En el nostre exemple anterior, el zk-SNARK no es pot utilitzar si Bob vol demostrar a Alice que coneix un secret, perquè Alice no pot saber que Bob no va desar el paràmetre lambda. Bob podria plausiblement ser capaç de falsificar proves.
Si un programa és útil per a moltes persones (com l’exemple de Zcash), un grup independent de confiança separat d’Alice i Bob podria executar el generador i crear la clau de prova pk i la clau de verificació vk de tal manera que ningú aprengui sobre lambda.
Qualsevol persona que confiï que el grup no ha enganyat pot utilitzar aquestes claus per a futures interaccions.
zk-SNARKs a Ethereum
Els desenvolupadors ja han començat a integrar zk-SNARKs a Ethereum. Com és això? Concretament, podeu afegir els components bàsics de l’algorisme de verificació a Ethereum en forma de contractes precompilats. A continuació s’explica com: executeu el generador fora de la cadena per produir la clau de prova i la clau de verificació. Qualsevol prover pot utilitzar la clau de prova per crear una prova, també fora de la cadena. A continuació, podeu executar l’algorisme de verificació general dins d’un contracte intel·ligent, utilitzant la prova, la clau de verificació i l’entrada pública com a paràmetres d’entrada. A continuació, podeu utilitzar el resultat de l’algorisme de verificació per activar una altra activitat a la cadena.
Exemple: transaccions confidencials
Aquí teniu un exemple senzill de com els zk-SNARK poden ajudar amb la privadesa d’Ethereum. Suposem que tenim un simple contracte simbòlic. Normalment, un contracte simbòlic tindria com a base un mapatge d’adreces a saldos:
mapatge (adreça => uint256) saldos; idioma del codi: JavaScript (javascript)
Conservarem el mateix nucli bàsic, excepte substituir un saldo pel hash d’un saldo:
mapatge (adreça => bytes32) balanceHashes; Idioma del codi: JavaScript (javascript)
No amagarem el remitent o el receptor de les transaccions. Però amagarem els saldos i les quantitats enviades. De vegades es coneix aquesta propietat transaccions confidencials.
Utilitzarem dos zk-SNARK per enviar fitxes d’un compte a un altre. El remitent crea una prova i l’altra el receptor.
Normalment, en un contracte simbòlic perquè una transacció del valor de la mida sigui vàlida, hem de verificar el següent:
saldos [fromAddress] >= valor
Els nostres zk-SNARK han de demostrar que això és vàlid i que els hashes actualitzats coincideixen amb els saldos actualitzats.
La idea principal és que el remitent utilitzi el seu saldo inicial i el valor de la transacció com a entrades privades. Com a aportacions públiques, fan servir hashes de saldo inicial, saldo final i valor. De la mateixa manera, el receptor utilitzarà el saldo i el valor inicial com a entrades secretes. Com a aportacions públiques, fan servir hashes de saldo inicial, saldo final i valor.
A continuació es mostra el programa que utilitzarem per al remitent zk-SNARK, on com abans x representa l’entrada pública i w representa l’entrada privada.
funció senderFunction (x, w) {return (w.senderBalanceBefore > valor de w && sha256 (valor.w) == x.hashValue && sha256 (w.senderBalanceBefore) == x.hashSenderBalanceBefore && sha256 (w.senderBalanceBefore – w.value) == x.hashSenderBalanceAfter)} Idioma del codi: JavaScript (javascript)
A continuació es mostra el programa utilitzat pel receptor:
funció receptorFunció (x, w) {return (sha256 (w.value) == x.hashValue && sha256 (w.receiverBalanceBefore) == x.hashReceiverBalanceBefore && sha256 (w.receiverBalanceBefore + w.value) == x.hashReceiverBalanceAfter)} Idioma del codi: JavaScript (javascript)
Els programes comproven que el saldo d’enviament és superior al valor que s’envia, així com comproven que tots els hash coincideixen. Un conjunt de persones de confiança generaria les claus de verificació i verificació per als nostres zk-SNARK. Anomenem-los confTxSenderPk, confTxSenderVk, confTxReceiverPk i confTxReceiverVk.
L’ús dels zk-SNARKs en un contracte simbòlic es veuria així:
transferència de funcions (adreça _to, bytes32 hashValue, bytes32 hashSenderBalanceAfter, bytes32 hashReceiverBalanceAfter, bytes zkProofSender, bytes zkProofReceiver) {bytes32 hashSenderBalanceBefore = balanceHashes [msg.sender]; bytes32 hashReceiverBalanceBefore = balanceHashes [_to]; bool senderProofIsCorrect = zksnarkverify (confTxSenderVk, [hashSenderBalanceBefore, hashSenderBalanceAfter, hashValue], zkProofSender); bool receiverProofIsCorrect = zksnarkverify (confTxReceiverVk, [hashReceiverBalanceBefore, hashReceiverBalanceAfter, hashValue], zkProofReceiver); if (senderProofIsCorrect && receiverProofIsCorrect) {balanceHashes [msg.sender] = hashSenderBalanceAfter; balanceHashes [_to] = hashReceiverBalanceAfter; }} Idioma del codi: JavaScript (javascript)
Així, les úniques actualitzacions de la cadena de blocs són els hash dels saldos i no els saldos en si. Tot i això, podem saber que tots els saldos s’actualitzen correctament perquè podem comprovar que la prova s’ha verificat.
Detalls
L’esquema de transaccions confidencials anteriorment es basa principalment en un exemple pràctic de com es poden utilitzar zk-SNARK a Ethereum. Per crear un esquema de transaccions confidencial robust, hauríem d’abordar diversos problemes:
- Els usuaris haurien de fer un seguiment dels seus saldos al costat del client i, si perden el saldo, aquests tokens no es poden recuperar. Els saldos potser es podrien emmagatzemar xifrats en cadena amb una clau derivada de la clau de signatura.
- Els balanços han d’utilitzar 32 bytes de dades i codificar l’entropia per evitar la capacitat d’invertir els hashs per esbrinar els balanços.
- Necessiteu fer front al cas periòdic d’enviament a una adreça no utilitzada.
- L’emissor ha d’interactuar amb el receptor per poder enviar. Es podria tenir un sistema on el remitent utilitzi la seva prova per iniciar la transacció. El receptor pot veure a la cadena de blocs que té una “transacció entrant pendent” i pot finalitzar-la.
Subscriu-te al nostre butlletí per obtenir les últimes novetats, solucions empresarials, recursos per a desenvolupadors i molt més sobre Ethereum. Adreça de correu electrònic Contingut exclusiuSeminari web
Com es pot crear un producte Blockchain amb èxit
Seminari web
Com configurar i executar un node Ethereum
Seminari web
Com es crea la seva pròpia API Ethereum
Seminari web
Com es crea un testimoni social
Seminari web
Ús d’eines de seguretat en el desenvolupament de contractes intel·ligents
Seminari web