TL;DR
Ett nollkunskapsbevis gör det möjligt för en part (en som verifierar) att bestämma giltigheten av ett uttalande från en annan part (den som tillhandahåller) utan någon kunskap om uttalandets innehåll. Binance kanske till exempel vill bevisa att de helt har backat sina användares tillgångar i reserver, utan att avslöja alla enskilda användarbalanser.
Ett ”bevis på reserver” kan konstrueras med ett Merkle-träd som skyddar mot förfalskning av dess interna data, i detta fall dess totala nettokundbalans, som börsens skulder till sina användare. Detta kan sedan kombineras med ett zk-Snark (ett protokoll för nollkunskapsbevis) som säkerställer att användarna kan kontrollera att deras balans utgör en del av användarnas totala nettotillgångsbalans, utan att känna till individuella balanser.
Introduktion
På grund av tidigare marknadshändelser har säkerheten för kryptotillgångar i förvar blivit ett viktigt ämne. Blockkedjeanvändare värdesätter transparens och öppenhet, men stöder också integritet och konfidentialitet. Detta skapar ett dilemma när du bevisar reserver av tillgångar som innehas av förvaltare. Ofta finns en avvägning mellan transparens, förtroende och datakonfidentialitet.
Detta behöver dock inte alltid vara fallet. Genom att kombinera protokoll för nollkunskapsbevis som zk-Snarks med Merkle-träd kan vi hitta en effektiv lösning för alla parter.
Vad är nollkunskapsbevis?
Ett nollkunskapsbevis gör det möjligt för en part (en som verifierar) att bestämma giltigheten av ett uttalande från en annan part (den som tillhandahåller) utan någon kunskap om uttalandets innehåll. Här följer ett enkelt exempel:
Du har ett låst kassaskåp som bara du kan koden till. Kassaskåpet kan, i detta exempel, inte brytas upp eller öppnas på något annat sätt än genom att känna till kodens kombination. Detta faktum är även etablerat, verifierat och känt av din vän som deltar i experimentet.
Du säger till din vän att du kan kombinationen, men du vill inte ge bort den eller öppna kassaskåpet framför hen. Ovanpå kassaskåpet finns ett hål som din vän kan sticka in en lapp igenom. För att göra detta till ett nollkunskapsbevis, bör din vän inte ha någon extra information om processen annat än det givna uttalandet.
Du kan bevisa för din vän att du känner till kombinationen genom att öppna kassaskåpet, berätta för hen vad som skrevs på lappen och stänga kassaskåpet igen. Du avslöjade dock aldrig kombinationen till hen.
För ett mer avancerat exempel kan du läsa vår artikel Vad är nollkunskapsbevis och hur påverkar det blockkedjan?
Varför ska jag använda nollkunskapsbevis?
Nollkunskapsbevis är lämpliga för att bevisa något utan att avslöja känslig information eller uppgifter. Detta kan vara fallet om du inte vill avslöja din ekonomiska eller personliga information, som skulle kunna användas på ett olämpligt sätt.
Inom krypto kan du bevisa att du äger en privat nyckel utan att avslöja den eller digitalt signera något. En kryptovalutabörs kanske också vill bevisa statusen för sina reserver utan att avslöja konfidentiell information om sina användare, inklusive deras individuella kontobalanser.
För dessa exempel (och många andra) skulle ett nollkunskapsbevis använda algoritmer som tar en datainmatning och returnerar ”sant” eller ”falskt” som utdata.
Definiering av nollkunskapsbevis i tekniska termer
I tekniska termer följer ett nollkunskapsbevis en specifik struktur med vissa kriterier. Vi har redan gått igenom rollerna för den som tillhandahåller och verifierar, men det finns också tre kriterier som ett nollkunskapsbevis bör omfatta:
Fullständighet. Om uttalandet är sant, kommer den som verifierar att övertygas av det tillhandahållna beviset, utan behov av någon annan information eller verifiering.
Sundhet. Om uttalandet är falskt kommer den som verifierar inte att övertygas om ett uttalandes sanning genom det tillhandahållna beviset.
Nollkunskap. Om uttalandet är sant lär sig den som verifierar inte någon annan information än att uttalandet är sant.
Vad är ett zk-Snark?
Ett zk-Snark (Zero-Knowledge Succinct Non-Interactive Argument of Knowledge) är ett bevisprotokoll som följer de nollkunskapsprinciper som tidigare beskrivits. Med ett zk-Snark kan du bevisa att du känner till det ursprungliga hashade värdet (gå igenom nedan) utan att avslöja vad det är. Du kan också bevisa giltigheten av en transaktion utan att avslöja någon information om specifika belopp, värden eller adresser som är inblandade.
Zk-Snarks används och diskuteras ofta inom blockkedje- och kryptovalutavärlden. Men du kanske undrar varför någon skulle bry sig om att använda ett zk-Snark när det går att använda en enkel metod med ett offentligt och privat nyckelpar för att säkra informationen. Vi skulle dock inte kunna implementera det matematiska beviset för att säkerställa att inga negativa balanser ingår, eller summan av Merkle-trädet.
När det gäller en börs reserver vill de bevisa ett 1:1-stöd av kundernas balanser, utan att identifierare och balanser för varje konto offentliggörs. Dessutom gör tekniken med zk-Snarks förfalskning av data ännu mer osannolik.
Vad är ett Merkle-träd?
För att presentera summerade tillgångar för Binance-användares konton krävs det att du arbetar med en stor datamängd. Ett sätt att presentera denna stora mängd data kryptografiskt är att använda ett Merkle-träd. En stor mängd information kan lagras effektivt i det och dess kryptografiska natur gör dess integritet lätt verifierbar.
Hashfunktioner
För att kortfattat koda en inmatning måste ett Merkle-träd använda sig av hashfunktioner. Kort sagt är hashning processen att generera utdata med fast storlek från indata av variabel storlek. När indata av vilken längd som helst hashas genom en algoritm, kommer de med andra ord att producera krypterade utdata med fast längd.
Så länge indata förblir desamma kommer utdata också att bli det. Det betyder att vi kan ta enorma mängder transaktionsdata och hasha de till hanterbar utdata. Utdata kommer att vara radikalt annorlunda om någon information ändras i indata.
Vi kan till exempel ta innehållet i 100 böcker och mata in dem i hashfunktionen SHA-256. Det skulle då ge utdata som ser ut ungefär så här:
801a9be154c78caa032a37b4a4f0747f1e1addb397b64fa8581d749d704c12ea
Om vi sedan ändrade ett enda tecken för våra indata (de 100 böckerna), skulle hashen bli helt annorlunda och se ut så här:
abc5d230121d93a93a25bf7cf54ab71e8617114ccb57385a87ff12872bfda410
Detta är en viktig egenskap hos hashfunktioner, eftersom de möjliggör enkel verifiering av hur noggranna data är. Om någon replikerar processen med hashning av samma 100 böcker med algoritmen SHA-256, kommer de att få exakt samma hash som utdata. Om utdata är annorlunda kan vi med säkerhet bekräfta att indata ändrades. Det betyder att det inte finns något behov av att individuellt eller manuellt kontrollera om det finns skillnader mellan olika indata, vilket kan kräva massor av jobb.
Merkle-träd i kryptovalutavärlden
Vid lagring av transaktionsdata på en blockkedja skickas varje ny transaktion via en hashfunktion, som genererar unika hashvärden. Föreställ dig att vi har åtta transaktioner (A till H) som vi individuellt hashar för att få deras hashade utdata. Detta är vad vi kallar för Merkle-bladnoder. På bilden nedan kan du se det unika hashvärdet för varje bokstav: hA för A, hB för B, hC för C, etc.
Vi kan sedan ta olika par av hashade utdata och kombinera dem för att få nya hashade utdata. Hasharna av hA och hB hashade tillsammans skulle till exempel ge oss nya hashade utdata av hAB, känd som en Merkle-gren. Observera att varje gång nya utdata genereras får de en fast längd och storlek, enligt den hashfunktion som används.
Nu har vi data från två transaktioner (alltså A och B) kombinerade i en hash (hAB). Observera att om vi ändrar någon information från A eller B och upprepar processen, skulle vår hashade utdata hAB bli helt annorlunda.
Processen fortsätter när vi kombinerar nya par av hashar för att hasha dem igen (se bilden nedan). Vi hashar hAB med hCD för att få den unika hashen hABCD och gör samma sak med hEF och hGH för att få hEFGH. I slutändan får vi en enda hash som representerar hashade utdata från alla tidigare transaktioners hashar. Vår hashade utdata hABCDEFGH representerar med andra ord all information som kom före den.
Grafen som visas ovan kallas för ett Merkle-träd och våra hashade utdata hABCDEFGH är Merkle-roten. Vi använder Merkle-rötter i block-titlar, eftersom de kryptografiskt sammanfattar alla transaktionsdata i ett block på ett kortfattat sätt. Vi kan också snabbt verifiera om några data har manipulerats eller ändrats inom blocket.
Merkle-trädens begränsningar
Låt oss återvända till vårt exempel med CEX-reserver. En CEX vill bevisa ett 1:1-stöd av alla sina kunders tillgångar och bygger ett Merkle-träd som hashar ihop sina kund-användar-id:n med sina nettotillgångsinnehav (räknat efter tillgångar och skulder) på en tokennivå. När den har frisläppts (och undertecknats för att bevisa äganderätten över Merkle-roten), skulle en enskild användare inte ha något sätt att kontrollera om Merkle-trädet är giltigt utan att komma åt alla dess indata.
En börs kan ha missat att ta med vissa indata. Den kan också skapa falska konton med negativa balanser för att ändra den totala skulden. Även om kundernas tillgångar kan uppgå till 1 000 000 dollar, kan till exempel ett falskt konto läggas till med en balans på minus 500 000 dollar. Detta skulle skapa ett reservmål på endast 500 000 dollar.
Fallet med bevis på reserver skiljer sig från ett blocks Merkle-rot, eftersom användarna kan se alla transaktioner som ett block innehåller på en blockkedjeutforskare. En CEX vill dock inte avslöja alla kontobalanser på grund av säkerhets- och datasekretesskäl. Kunderna skulle inte heller gilla att deras kontobalanser offentliggjordes. I detta fall kan CEX:en inte bevisa att användarbalanser uppgår till rätt summa utan att göra andra användarbalanser synliga.
En lösning som börser kan överväga är att använda en betrodd tredjepartsrevisor. Revisorn kan kontrollera de enskilda kontona och reserverna innan denne slutligen intygar giltigheten av den tillhandahållna Merkle-roten. För användarna kräver dock denna metod förtroende för revisorn och de data som används för revisionen. Du behöver inte lita på en tredje part när du kan lita på data.
Kombinering av zk-Snarks och Merkle-träd
Ovanstående problem är ett perfekt exempel på där zk-Snarks kan användas. Vi vill bevisa att reserverna helt täcker användarnas skulder och inte har förfalskats. Av sekretess- och säkerhetsskäl vill vi dock inte visa verifieraren den exakta sammansättningen av användarnas balanser och reserver.
Genom att använda en zk-Snarks kan ett kryptobörs bevisa att alla balansuppsättningarna för Merkle-trädbladsnoder (det vill säga användarkontobalanser) bidrar till börsens påstådda totala balans från användartillgångarna. Varje användare kan enkelt komma åt sin bladnod som inkluderats i processen. Zk-Snarks säkerställer också att alla Merkle-träd som genereras inte innehåller användare med en negativ total nettotillgångsbalans (vilket skulle innebära förfalskning av data, eftersom alla lån är översäkerställda). Dessutom används en beräkning av Binances globala tillstånd, det vill säga en lista över den totala nettobalansen för varje tillgång som varje Binance-kund innehar.
Låt oss ta en titt på hur Binance tar sig an situationen. Till att börja med definierar Binance begränsningarna för beräkningen som de vill bevisa och definierar dessa som en programmerbar krets. Nedan följer uppsättningen av tre begränsningar som Binance använder i sin modell.
För varje användares balansuppsättning (Merkle-trädbladsnoder) säkerställer vår krets att:
En användares tillgångsbalans ingår i beräkningen av summan av den totala nettoanvändarbalansen hos Binance.
Den totala nettobalansen för användaren är större än eller lika med noll.
Ändringen av Merkle-trädroten är giltig (det vill säga inte använder förfalskad information) efter uppdateringen av en användares information till bladnodens hash.
Binance kan sedan generera ett bevis för zk-Snark för Merkle-trädets konstruktion enligt kretsen. Detta innebär att börsen utför den tunga beräkningen med att hasha användarnas id och balanser, samtidigt som beviset går igenom begränsningarna.
En kontrollör kommer att undersöka beviset (och dess offentligt frisläppta öppna källkod) för att övertygas om att beräkningen utförs med alla begränsningar uppfyllda. Verifieringsberäkningen tar extremt kort tid jämfört med bevistiden.
Vid varje frisläppande av bevis på reserver publicerar börsen:
1. Merkle-beviset för varje användare.
2. Bevisen för zk-Snarks och offentliga indata (en hash av listan över den totala nettobalansen för varje tillgång och Merkle-rot) av kretsen för alla användare.
De som är intresserade kan verifiera Merkle-beviset och säkerställa att dess individuella balanser bidrog till Merkle-trädroten. De kan också verifiera beviset för zk-Snark för att säkerställa att konstruktionen av Merkle-trädet uppfyller de begränsningar som definieras i kretsen. Läs bloggen Så förbättrar zk-Snarks Binances bevis på reserver-system för en mer detaljerad förklaring av lösningen med zk-Snarks och dess prestanda.
Sammanfattningsvis
ZK-Snarks tillhandahåller den teknik som behövs för att säkerställa både datasekretess och integritet på samma gång. Dess förmåga att bevisa reserver och öka CEX-transparensen bör hjälpa till att bygga förtroende för blockkedjebranschen. Många har väntat länge på en utveckling som denna och den kommer vid en avgörande tidpunkt för CEX:er.
Detta är den första versionen av vår zk-Snark och vi ser fram emot att få feedback från communityn så att vi kan fortsätta förbättra systemet.