Introduktion till zk-SNARKs

blogg 1NyheterUtvecklareFöretagBlockchain förklaradeHändelser och konferenserPressNyhetsbrev

Prenumerera på vårt nyhetsbrev.

E-postadress

Vi respekterar din integritet

HemBlogBlockchain utveckling

Introduktion till zk-SNARKs

En översikt över bevis på noll kunskap och hur man integrerar zk-SNARK i Ethereum. av ConsenSys 27 mars 2017 Upplagt 27 mars 2017

hemhjälte

I det här inlägget syftar vi till att ge en översikt över zk-SNARKs ur en praktisk synvinkel. Vi kommer att behandla matematiken som en svart ruta och försöka utveckla några intuitioner kring hur vi kan använda dem. Vi ger också en enkel tillämpning av det senaste arbetet med integrera zk-SNARK i Ethereum.

Nollkännedom

Målet med nollkunskapsbevis är att en verifierare ska kunna övertyga sig själv om att en bevisare har kunskap om en hemlig parameter, kallad ett vittne, som uppfyller någon relation, utan att avslöja vittnet för verifieraren eller någon annan.

Vi kan tänka på detta mer konkret som att ha ett program, betecknat C, med två ingångar: C (x, w). Ingången x är den offentliga ingången och w är den hemliga vittnesingången. Programmets resultat är booleskt, dvs. antingen sant eller falskt. Målet ges sedan en specifik allmän ingång x, bevisa att bevisaren känner till en hemlig ingång w så att C (x, w) == true.

Vi ska specifikt diskutera icke-interaktiva bevis på noll kunskap. Detta betyder att själva beviset är en flock av data som kan verifieras utan någon interaktion från bevisaren.

Exempel på program

Anta att Bob får en hash H av något värde, och han vill ha ett bevis på att Alice vet värdet s som hasar till H. Normalt skulle Alice bevisa detta genom att ge s till Bob, varefter Bob skulle beräkna hashen och kontrollera att det är lika med H.

Antag dock att Alice inte vill avslöja värdet för Bob utan i stället vill hon bevisa att hon vet värdet. Hon kan använda en zk-SNARK för detta.

Vi kan beskriva Alice scenario med följande program, här skrivet som en Javascript-funktion:

funktion C (x, w) {return (sha256 (w) == x);} Kodspråk: JavaScript (javascript)

Med andra ord: programmet tar in en offentlig hash x och ett hemligt värde w och returnerar true om SHA – 256 hash av w är lika med x.

Genom att översätta Alice problem med funktionen C (x, w) ser vi att Alice behöver skapa ett bevis på att hon har s så att C (H, s) == true utan att behöva avslöja s. Detta är det allmänna problemet som zk-SNARK löser.

Definition av en zk-SNARK

En zk-SNARK består av tre algoritmer G, P, V definierade enligt följande:

Nyckelgeneratorn G tar en hemlig parameter lambda och ett program C och genererar två allmänt tillgängliga nycklar, en bevisande nyckel pk och en verifieringsnyckel vk. Dessa nycklar är offentliga parametrar som bara behöver genereras en gång för ett givet program C.

Bevisaren P tar som inmatning provningsnyckeln pk, en offentlig ingång x och ett privat vittne w. Algoritmen genererar ett bevis prf = P (pk, x, w) för att bevisaren känner till ett vittne w och att vittnet uppfyller programmet.

Verifieraren V beräknar V (vk, x, prf) som returnerar true om beviset är korrekt och annars falskt. Således returnerar denna funktion sant om bevisaren känner till ett vittne som uppfyller C (x, w) == true.

Notera här den hemliga parametern lambda som används i generatorn. Den här parametern gör det ibland svårt att använda zk-SNARKs i verkliga applikationer. Anledningen till detta är att alla som känner till denna parameter kan skapa falska bevis. Specifikt, med tanke på vilket program som helst C och allmän ingång x kan en person som känner lambda generera ett bevis fake_prf så att V (vk, x, fake_prf) utvärderas till sant utan kunskap om hemligheten.

Att köra generatorn kräver således en mycket säker process för att se till att ingen lär sig om och sparar parametern var som helst. Detta var anledningen till extremt detaljerad ceremoni Zcash-teamet genomförde för att generera provningsnyckeln och verifieringsnyckeln, samtidigt som man säkerställde att parametern ”giftigt avfall” lambda förstördes under processen.

En zk-SNARK för vårt exempelprogram

Hur skulle Alice och Bob använda en zk-SNARK i praktiken för att Alice skulle kunna bevisa att hon känner till det hemliga värdet i exemplet ovan?

Först och främst kommer vi, som diskuterats ovan, att använda ett program som definieras av följande funktion:

funktion C (x, w) {retur (sha256 (w) == x); } Kodspråk: JavaScript (javascript)

Det första steget är att Bob ska köra generatorn G för att skapa den bevisande nyckeln pk och verifieringsnyckeln vk. Generera först slumpmässigt lambda och använd det som inmatning:

(pk, vk) = G (C, lambda)

Hantera parametern lambda med försiktighet, för om Alice lär sig värdet av lambda kommer hon att kunna skapa falska bevis. Bob delar pk och vk med Alice.

Alice kommer nu att spela rollen som bevisaren. Hon måste bevisa att hon känner till värdet s som hashes till den kända hash H. Hon kör bevisningsalgoritmen P med ingångarna pk, H och s för att generera bevisprf:

prf = P (pk, H, s)

Därefter presenterar Alice bevisprf till Bob som kör verifieringsfunktionen V (vk, H, prf) som skulle bli sant i det här fallet eftersom Alice visste ordentligt hemligheten. Bob kan vara säker på att Alice visste hemligheten, men Alice behövde inte avslöja hemligheten för Bob.

Återanvändbara prov- och verifieringsknappar

I vårt exempel ovan kan zk-SNARK inte användas om Bob vill bevisa för Alice att han känner till en hemlighet, eftersom Alice inte kan veta att Bob inte sparar lambdaparametern. Bob skulle troligtvis kunna förfalska bevis.

Om ett program är användbart för många människor (som exempel på Zcash), kan en pålitlig oberoende grupp som är skild från Alice och Bob köra generatorn och skapa den bevisande nyckeln pk och verifieringsnyckeln vk på ett sådant sätt att ingen lär sig om lambda.

Den som litar på att gruppen inte fuskar kan sedan använda dessa nycklar för framtida interaktioner.

zk-SNARKs i Ethereum

Utvecklare har redan börjat integrera zk-SNARK i Ethereum. Hur ser detta ut? Konkret kan du lägga till byggstenarna för verifieringsalgoritmen till Ethereum i form av förkompilerade kontrakt. Så här gör du: köra generatorn utanför kedjan för att producera provningsnyckeln och verifieringsnyckeln. Varje provare kan sedan använda provknappen för att skapa ett bevis, även off-chain. Du kan sedan köra den allmänna verifieringsalgoritmen i ett smart kontrakt med hjälp av beviset, verifieringsnyckeln och den offentliga inmatningen som ingångsparametrar. Du kan sedan använda resultatet av verifieringsalgoritmen för att utlösa annan on-chain aktivitet.

Exempel: Konfidentiella transaktioner

Här är ett enkelt exempel på hur zk-SNARKs kan hjälpa till med integritet på Ethereum. Antag att vi har ett enkelt tokenavtal. Normalt har ett tokenavtal i grunden en kartläggning från adresser till saldon:

mapping (adress => uint256) saldon; Kodspråk: JavaScript (javascript)

Vi kommer att behålla samma grundläggande kärna, förutom att ersätta en balans med hash av en balans:

mapping (adress => bytes32) balanceHashes; Kodspråk: JavaScript (javascript)

Vi kommer inte att dölja avsändaren eller mottagaren av transaktioner. Men vi döljer saldon och skickade belopp. Den här egenskapen kallas ibland för konfidentiella transaktioner.

Vi använder två zk-SNARK för att skicka tokens från ett konto till ett annat. Ett bevis skapas av avsändaren och ett av mottagaren.

Normalt i ett tokenavtal för att en transaktion med storleksvärde ska vara giltig måste vi verifiera följande:

saldon [fromAddress] >= värde

Våra zk-SNARKs måste bevisa att detta håller, liksom att de uppdaterade hasharna matchar de uppdaterade saldona.

Huvudidén är att avsändaren ska använda sin startbalans och transaktionsvärdet som privata ingångar. Som offentliga insatser använder de hashes av startbalans, slutbalans och värde. På samma sätt kommer mottagaren att använda startbalans och värde som hemliga ingångar. Som offentliga insatser använder de hashes av startbalans, slutbalans och värde.

Nedan följer programmet vi kommer att använda för avsändaren zk-SNARK, där x som tidigare representerar den offentliga inmatningen och w representerar den privata ingången.

function senderFunction (x, w) {return (w.senderBalanceBefore > w.värde && sha256 (w.value) == x.hashValue && sha256 (w.senderBalanceBefore) == x.hashSenderBalanceBefore && sha256 (w.senderBalanceBefore – w.value) == x.hashSenderBalanceAfter)} Kodspråk: JavaScript (javascript)

Programmet som används av mottagaren är nedan:

funktionsmottagareFunktion (x, w) {return (sha256 (w.value) == x.hashValue && sha256 (w.receiverBalanceBefore) == x.hashReceiverBalanceBefore && sha256 (w.receiverBalanceBefore + w.value) == x.hashReceiverBalanceAfter)} Kodspråk: JavaScript (javascript)

Programmen kontrollerar att sändningsbalansen är större än värdet som skickas, samt kontrollerar att alla haschar matchar. En betrodd uppsättning människor skulle generera bevis- och verifieringsnycklar för våra zk-SNARK. Låt oss kalla dem confTxSenderPk, confTxSenderVk, confTxReceiverPk och confTxReceiverVk.

Att använda zk-SNARKs i ett tokenavtal skulle se ut så här:

funktionsöverföring (adress _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; }} Kodspråk: JavaScript (javascript)

Således är de enda uppdateringarna i blockkedjan hasherna på balanserna och inte själva saldorna. Vi kan dock veta att alla saldon är korrekt uppdaterade eftersom vi själva kan kontrollera att beviset har verifierats.

Detaljer

Ovanstående konfidentiella transaktionsplan är främst för att ge ett praktiskt exempel på hur man kan använda zk-SNARKs på Ethereum. För att skapa ett robust konfidentiellt transaktionsschema måste vi ta itu med ett antal problem:

  • Användare skulle behöva hålla reda på sina saldon på klientsidan, och om du förlorar balansen är dessa tokens oåtervinnbara. Balanserna kan kanske lagras krypterade i kedjan med en nyckel härledd från signeringsnyckeln.
  • Balanser måste använda 32 byte data och koda entropi för att förhindra möjligheten att vända hash för att räkna ut balanser.
  • Behöver hantera kanten fallet att skicka till en oanvänd adress.
  • Avsändaren måste interagera med mottagaren för att kunna skicka. Man kan eventuellt ha ett system där avsändaren använder sitt bevis för att initiera transaktionen. Mottagaren kan då se på blockchain att de har en “väntande inkommande transaktion” och kan slutföra den.

Prenumerera på vårt nyhetsbrev för de senaste Ethereum-nyheterna, företagslösningar, utvecklarresurser med mera. E-postadress Exklusivt innehållHur man bygger en framgångsrik Blockchain-produktWebinar

Hur man bygger en framgångsrik Blockchain-produkt

Hur man ställer in och kör en Ethereum-nodWebinar

Hur man ställer in och kör en Ethereum-nod

Hur man bygger ditt eget Ethereum APIWebinar

Hur man bygger ditt eget Ethereum API

Hur man skapar en social tokenWebinar

Hur man skapar en social token

Använda säkerhetsverktyg i Smart Contract DevelopmentWebinar

Använda säkerhetsverktyg i Smart Contract Development

Framtiden för finansiella digitala tillgångar och DeFiWebinar

Framtiden för ekonomi: digitala tillgångar och deFi

Mike Owergreen Administrator
Sorry! The Author has not filled his profile.
follow me
Like this post? Please share to your friends:
map