TL;DR

Une preuve à connaissance nulle permet à une partie (un vérificateur) de déterminer la validité d’une déclaration donnée par une autre partie (le prouveur) sans aucune connaissance du contenu de la déclaration. Par exemple, Binance voudra peut-être prouver qu’elle a entièrement garanti les fonds de ses utilisateurs dans des réserves sans révéler tous les soldes individuels des utilisateurs.

Une « preuve de réserves » pourrait être construite avec un arbre Merkle qui protège contre la falsification de ses données internes, dans ce cas, ses soldes clients nets totaux, étant le passif de la bourse envers ses utilisateurs. Cela peut ensuite être combiné avec un zk-SNARK (un protocole de preuve sans connaissance) qui garantit que les utilisateurs peuvent vérifier que leur solde fait partie du solde net total des actifs de l'utilisateur sans connaître les soldes individuels.

Introduction

À la lumière des événements du marché, la sécurité des actifs cryptographiques conservés est devenue un sujet crucial. Les utilisateurs de la blockchain apprécient grandement la transparence et l'ouverture, mais soutiennent également la confidentialité. Cela crée un dilemme lorsqu’il s’agit de prouver les réserves de fonds détenus par les dépositaires. Il faut souvent trouver un compromis entre transparence, confiance et confidentialité des données.

Cependant, cela ne doit pas nécessairement être le cas. En combinant des protocoles sans connaissance comme les zk-SNARK avec des arbres Merkle, nous pouvons trouver une solution efficace pour toutes les parties.

Qu'est-ce que la preuve zéro connaissance ?

Une preuve à connaissance nulle permet à une partie (un vérificateur) de déterminer la validité d’une déclaration donnée par une autre partie (le prouveur) sans aucune connaissance du contenu de la déclaration. Regardons un exemple simple.

Vous disposez d’un coffre-fort verrouillé dont vous seul connaissez la solution. Le coffre-fort, à titre d’exemple, ne peut être saisi, forcé ou ouvert autrement qu’en connaissant la combinaison. Ce fait est également établi, vérifié et connu par votre ami participant à l'expérience.

Vous déclarez que vous connaissez la combinaison à votre ami, mais vous ne voulez pas la donner ou ouvrir la boîte devant lui. Au-dessus de la boîte se trouve un trou dans lequel votre ami peut insérer une note. Pour en faire une preuve sans connaissance, votre ami ne devrait avoir aucune information supplémentaire sur le processus autre que la déclaration donnée.

Vous pouvez prouver à votre ami que vous connaissez la combinaison en ouvrant la boîte, en lui disant ce qui était écrit sur la note et en la refermant. À aucun moment vous n’avez cependant révélé la combinaison.

Pour un exemple plus avancé, consultez notre article Qu'est-ce qu'une preuve de connaissance nulle et quel est son impact sur la blockchain ? article.

Pourquoi utilisons-nous une preuve de connaissance zéro ?

Les preuves sans connaissance permettent de prouver quelque chose sans révéler d’informations ou de détails sensibles. Cela peut être le cas si vous ne souhaitez pas divulguer vos informations financières ou personnelles qui pourraient être utilisées de manière inappropriée.

En crypto, vous pouvez prouver que vous possédez une clé privée sans la révéler ni signer numériquement quelque chose. Une bourse de crypto-monnaie peut également vouloir prouver l’état de ses réserves sans révéler d’informations confidentielles sur ses utilisateurs, y compris les soldes de leurs comptes individuels.

Pour ces exemples (et bien d’autres), une preuve sans connaissance utiliserait des algorithmes qui prennent une entrée de données et renvoient « vrai » ou « faux » en sortie.

Définir des preuves sans connaissance en termes techniques

Une preuve sans connaissance, en termes techniques, suit une structure spécifique avec certains critères. Nous avons déjà couvert les rôles de prouveur et de vérificateur, mais il y a également trois critères qu'une preuve sans connaissance devrait couvrir :

  1. Complétude. Si la déclaration est vraie, un vérificateur sera convaincu par la preuve fournie, sans avoir besoin d'aucune autre information ou vérification.

  2. Solidité. Si la déclaration est fausse, un vérificateur ne sera pas convaincu de la véracité d’une déclaration par la preuve fournie.

  3. Zéro connaissance. Si la déclaration est vraie, le vérificateur n’apprend aucune information autre que la déclaration étant vraie.

Qu'est-ce qu'un zk-SNARK ?

Un zk-SNARK (Zero-Knowledge Succinct Non-Interactive Argument of Knowledge) est un protocole de preuve qui suit les principes de connaissance zéro décrits précédemment. Avec un zk-SNARK, vous pouvez prouver que vous connaissez la valeur hachée d'origine (discutée plus loin ci-dessous) sans révéler de quoi il s'agit. Vous pouvez également prouver la validité d'une transaction sans révéler aucune information sur les montants, valeurs ou adresses spécifiques impliqués.

Les zk-SNARK sont couramment utilisés et discutés dans le monde de la blockchain et des crypto-monnaies. Mais vous vous demandez peut-être pourquoi quelqu'un prendrait la peine d'utiliser un zk-SNARK alors qu'il pourrait utiliser une simple méthode de paire de clés publiques et privées pour sécuriser les informations. Cependant, nous ne serions pas en mesure de mettre en œuvre la preuve mathématique pour garantir qu'aucun solde négatif n'est inclus ni la somme de l'arbre de Merkle.

Dans le cas des réserves d'une bourse, nous souhaitons prouver la garantie 1:1 des soldes des clients sans que les identifiants et les soldes de chaque compte ne soient rendus publics. De plus, la technologie zk-SNARK rend la falsification des données encore plus improbable.

Qu'est-ce qu'un arbre Merkle ?

Présenter la somme des fonds des comptes des utilisateurs de Binance nécessite de travailler avec un vaste ensemble de données. Une façon de présenter cette grande quantité de données de manière cryptographique consiste à utiliser un arbre Merkle. Une grande quantité d’informations peut y être stockée efficacement et sa nature cryptographique rend son intégrité facilement vérifiable.

Fonctions de hachage

Pour coder succinctement une entrée, un arbre Merkle dépend de l'utilisation de fonctions de hachage. En bref, le hachage est le processus consistant à générer une sortie de taille fixe à partir d’une entrée de taille variable. En d’autres termes, lorsqu’une entrée de n’importe quelle longueur est hachée via un algorithme, elle produira une sortie cryptée de longueur fixe.

Tant que l’entrée reste la même, la sortie le sera également. Cela signifie que nous pouvons prendre d’énormes quantités de données transactionnelles et les hacher pour obtenir un résultat gérable. La sortie sera radicalement différente si des informations sont modifiées dans l’entrée.

Par exemple, nous pourrions prendre le contenu de 100 livres et le saisir dans la fonction de hachage SHA-256. Il fournirait alors quelque chose comme ceci en sortie :

801a9be154c78caa032a37b4a4f0747f1e1addb397b64fa8581d749d704c12ea

Si nous modifiions ensuite un seul caractère de l'entrée (ces 100 livres), le hachage serait complètement différent, comme ceci :

abc5d230121d93a93a25bf7cf54ab71e8617114ccb57385a87ff12872bfda410

C’est une propriété importante des fonctions de hachage car elle permet de vérifier facilement l’exactitude des données. Si quelqu'un reproduit le processus de hachage de ces mêmes 100 livres à l'aide de l'algorithme SHA-256, il obtiendra exactement le même hachage que le résultat. Si le résultat est différent, nous pouvons affirmer avec certitude que l’entrée a été modifiée. Cela signifie qu’il n’est pas nécessaire de vérifier individuellement ou manuellement les différences entre les entrées, ce qui peut demander beaucoup de travail.

Arbres Merkle dans le monde des crypto-monnaies

Lors du stockage des données de transaction sur une blockchain, chaque nouvelle transaction est soumise via une fonction de hachage, qui génère des valeurs de hachage uniques. Imaginez que nous ayons huit transactions (A à H) que nous hachons individuellement pour obtenir leurs sorties hachées. C'est ce que nous appelons les nœuds feuilles de Merkle. Dans l'image ci-dessous, vous pouvez voir la valeur de hachage unique de chaque lettre : hA pour A, hB pour B, hC pour C, etc.

Nous pouvons ensuite prendre des paires de sorties hachées, les combiner et recevoir une nouvelle sortie hachée. Les hachages de hA et hB hachés ensemble, par exemple, nous donneraient une nouvelle sortie hachée de hAB connue sous le nom de branche Merkle. Notez que chaque fois qu'une nouvelle sortie est générée, elle a une longueur et une taille fixes, en fonction de la fonction de hachage utilisée.

Nous avons désormais les données de deux transactions (par exemple A et B) combinées en un seul hachage (hAB). Notez que si nous modifions des informations de A ou B et répétons le processus, notre sortie hachée hAB serait complètement différente.

Le processus se poursuit à mesure que nous combinons de nouvelles paires de hachages pour les hacher à nouveau (voir l'image ci-dessous). Nous hachons hAB avec hCD pour obtenir un hachage unique hABCD et faisons de même avec hEF et hGH pour obtenir hEFGH. En fin de compte, nous recevons un seul hachage représentant les sorties hachées de toutes les transactions précédentes. En d’autres termes, la sortie hachée hABCDEFGH représente toutes les informations qui la précèdent.

Le graphique affiché ci-dessus s'appelle un arbre Merkle et la sortie hachée hABCDEFGH est la racine Merkle. Nous utilisons les racines Merkle dans les en-têtes de bloc, car elles résument cryptographiquement toutes les données de transaction dans un bloc de manière succincte. Nous pouvons également vérifier rapidement si des données ont été falsifiées ou modifiées au sein du bloc.

Les limites des arbres Merkle

Revenons à notre exemple de réserves CEX. Un CEX veut prouver le soutien 1:1 de tous les actifs de ses clients et construit un arbre Merkle qui hache les UID de ses clients avec leurs avoirs nets (compensation des actifs et des passifs) au niveau symbolique. Une fois publié (et signé pour prouver la propriété de la racine Merkle fournie), un utilisateur individuel n'aurait aucun moyen de vérifier si l'arborescence Merkle est valide sans accéder à toutes ses entrées.

Un échange a peut-être manqué d'inclure certaines entrées. Cela pourrait également créer de faux comptes avec des soldes négatifs pour modifier le passif total. Par exemple, même si les actifs des clients peuvent totaliser 1 000 000 $, un faux compte pourrait être ajouté avec un solde de -500 000 $. Cela créerait un objectif de réserves de seulement 500 000 $.

Le cas de la preuve de réserves est différent de celui de la racine Merkle d’un bloc, car les utilisateurs peuvent voir toutes les transactions qu’un bloc contient sur un explorateur de blockchain. Cependant, un CEX ne voudra pas divulguer le solde de chaque compte pour des raisons de sécurité et de confidentialité des données. Les clients ne seraient pas non plus satisfaits que le solde de leur compte soit rendu public. Dans ce cas, le CEX ne peut pas prouver que les soldes des utilisateurs totalisent correctement sans rendre visibles les soldes des autres utilisateurs.

Une solution que les bourses peuvent envisager d’utiliser consiste à faire appel à un auditeur tiers de confiance. Le commissaire aux comptes peut vérifier les comptes individuels et les réserves avant d'attester définitivement de la validité de la racine Merkle fournie. Cependant, pour les utilisateurs, cette méthode nécessite une confiance dans l'auditeur et dans les données utilisées pour l'audit. Vous n’êtes pas obligé de faire appel à un tiers lorsque vous pouvez faire confiance aux données.

Combiner des zk-SNARK avec des arbres Merkle

Le problème ci-dessus est un cas parfait pour l'utilisation de zk-SNARK. Nous voulons prouver que les réserves couvrent entièrement les responsabilités des utilisateurs et ne sont pas falsifiées. Cependant, pour des raisons de confidentialité et de sécurité, nous ne souhaitons pas montrer au vérificateur la composition exacte des soldes et des réserves des utilisateurs.

En utilisant un zk-SNARK, un échange cryptographique peut prouver que tous les ensembles de soldes des nœuds feuilles de l'arbre Merkle (c'est-à-dire les soldes des comptes utilisateur) contribuent au solde total des actifs utilisateur revendiqué par l'échange. Chaque utilisateur peut facilement accéder à son nœud feuille comme ayant été inclus dans le processus. Le zk-SNARK garantit également que tout arbre Merkle généré ne contient pas d'utilisateurs avec un solde d'actif net total négatif (ce qui impliquerait une falsification des données, car tous les prêts sont sur-garantis). Un calcul de l'état global de Binance est également utilisé, c'est-à-dire une liste du solde net total de chaque actif détenu par chaque client Binance.

Jetons un coup d'œil à la manière dont Binance aborde la situation. Pour commencer, Binance définit les contraintes du calcul qu'il souhaite prouver et les définit comme un circuit programmable. Vous trouverez ci-dessous l'ensemble des trois contraintes utilisées par Binance dans son modèle.

Pour l’ensemble d’équilibre de chaque utilisateur (nœud feuille d’arbre Merkle), notre circuit garantit que :

  1. Les soldes d’actifs d’un utilisateur sont inclus dans le calcul de la somme des soldes nets totaux des utilisateurs avec Binance.

  2. Le solde net total de l'utilisateur est supérieur ou égal à zéro.

  3. Le changement de racine de l'arborescence Merkle est valide (c'est-à-dire qu'il n'utilise pas d'informations falsifiées) après la mise à jour des informations d'un utilisateur avec le hachage du nœud feuille.

Binance peut alors générer une preuve zk-SNARK pour la construction de l'arbre Merkle selon le circuit. Cela implique que l'échange exécute le calcul intensif de hachage des identifiants et des soldes des utilisateurs tout en garantissant que la preuve satisfait aux contraintes.

Un vérificateur examinera la preuve (et son code open source rendu public) pour être convaincu que le calcul est exécuté avec toutes les contraintes respectées. Le calcul de vérification prend un temps extrêmement court par rapport au temps de preuve.

À chaque publication de preuve de réserves, la bourse publiera :

1. La preuve Merkle pour chaque utilisateur.

2. La preuve zk-SNARK et l'entrée publique (un hachage de la liste du solde net total de chaque actif et racine Merkle) du circuit pour tous les utilisateurs.

Les parties intéressées peuvent vérifier la preuve Merkle, garantissant que leurs soldes individuels ont contribué à la racine de l'arbre Merkle. Ils peuvent également vérifier la preuve zk-SNARK pour garantir que la construction de l'arbre Merkle répond aux contraintes définies dans le circuit. Pour une explication plus détaillée de la solution zk-SNARK et de ses performances, reportez-vous à notre blog Comment les zk-SNARK améliorent le système de preuve de réserves de Binance.

Pensées finales

Les zk-SNARK fournissent la technologie nécessaire pour garantir à la fois l'intégrité et la confidentialité des données. Son application pour prouver les réserves et accroître la transparence du CEX devrait contribuer à renforcer la confiance dans le secteur de la blockchain. Pour beaucoup, un développement comme celui-ci est attendu depuis longtemps et arrive à un moment charnière pour les CEX.

Il s'agit de la première version de notre zk-SNARK, et nous sommes impatients de recevoir les commentaires de la communauté afin de pouvoir continuer à améliorer le système.

Lectures complémentaires

  • (Blog) Comment les zk-SNARK améliorent le système de preuve de réserves de Binance

  • (Académie) Preuve de réserves (PoR)

  • (Académie) Qu'est-ce qu'une preuve de réserves et comment elle fonctionne sur Binance

  • (Annonce)Binance lance un système de preuve de réserves