Explication détaillée du projet ERC-7520 : protection contre les attaques par débordement d'entrée publique zk-SNARK

Auteur : Saya & Bryce, experts en recherche en sécurité chez Beosin

1. Qu'est-ce qu'une preuve de connaissance nulle

Zero-Knowledge Proof (ZKP) est un concept cryptographique qui peut être utilisé pour prouver l'authenticité d'une déclaration sans révéler d'informations spécifiques sur la déclaration. Dans une preuve sans connaissance, le prouveur peut prouver au vérificateur qu'une certaine affirmation est vraie, et le vérificateur n'obtient qu'un seul résultat : soit accepter la déclaration comme vraie, soit la rejeter, sans connaître les détails spécifiques de la preuve.

Ce concept peut être expliqué avec un exemple simple. Supposons qu’il y ait deux personnes, l’une est le prouveur et l’autre le vérificateur. Le prouveur veut prouver au vérificateur qu'il connaît un mot de passe secret sans révéler le mot de passe lui-même. De manière traditionnelle, le prouveur peut indiquer au vérificateur quel est le mot de passe, mais dans la preuve sans connaissance, le prouveur peut utiliser un protocole spécial pour prouver au vérificateur qu'il connaît l'exactitude du mot de passe sans révéler le mot de passe lui-même.

Actuellement, les algorithmes système courants à preuve de connaissance nulle incluent les zk-SNARK, les zk-STARK, les BulletProofs, etc.

2. Application de ZKP dans la blockchain

Dans la technologie blockchain, ZKP a une variété d'applications, telles que l'amélioration de la confidentialité, l'amélioration de l'évolutivité et de la sécurité, etc. Voici quelques applications clés de ZKP dans la blockchain :

1 Protection de la vie privée :

La blockchain est publique, ce qui signifie que n’importe qui peut voir toutes les transactions de la chaîne. Parfois, cependant, les utilisateurs peuvent souhaiter garder leurs informations de transaction privées. ZKP permet aux utilisateurs de prouver qu'ils disposent de fonds suffisants pour négocier sans avoir à divulguer le total de leurs fonds. Cela améliore considérablement la protection de la vie privée des utilisateurs. Par exemple, Zcash est une crypto-monnaie qui utilise une technologie de preuve sans connaissance, qui permet aux utilisateurs de masquer l'expéditeur, le destinataire et le montant d'une transaction.

2 Compression informatique et expansion de la blockchain :

L’évolutivité de la blockchain constitue un défi, en particulier dans les applications à grande échelle. ZKP peut être utilisé pour réduire la charge sur les nœuds et améliorer l'évolutivité de l'ensemble du système. En utilisant ZKP pour vérifier la validité des transactions, les nœuds n'ont pas besoin d'afficher l'historique complet des transactions, réduisant ainsi la charge de stockage et de traitement. ZK Rollup, actuellement la plus largement utilisée, est une solution d'évolutivité conçue pour améliorer Ethereum et d'autres domaines. Débit et efficacité des réseaux blockchain. Il combine les avantages des technologies Rollup et ZKP pour fournir des solutions d'extension d'applications décentralisées (DApps) hautes performances. Sur le réseau Ethereum traditionnel, chaque transaction doit être vérifiée et enregistrée sur la blockchain, ce qui entraîne des retards et des coûts élevés dans le traitement des transactions. ZK Rollup regroupe et compresse un grand nombre de transactions en un seul bloc, et ZKP est utilisé pour prouver la validité des transactions par lots afin de garantir l'exactitude et la sécurité des transactions.

3 Authentification :

Des preuves sans connaissance peuvent être utilisées pour vérifier l’identité d’un utilisateur sans révéler d’informations personnelles sensibles. Par exemple, une personne peut utiliser des preuves de connaissance nulle pour prouver au réseau qu'elle répond à une certaine condition d'âge ou qu'elle possède une certaine certification sans révéler son âge exact ou d'autres informations d'identification.

4 Stockage décentralisé :

Le serveur peut prouver aux utilisateurs que leurs données sont conservées en toute sécurité et qu'aucun contenu des données n'est divulgué.

En général, la preuve sans connaissance de la blockchain a de nombreuses applications dans la protection de la vie privée, la compression et l'expansion informatique, la vérification de l'identité, le stockage décentralisé, etc. Il fournit plus de fonctions et d'options pour la technologie blockchain et favorise le développement et l'application de la blockchain dans différents domaines. **

3. Attaque de double dépense dans les applications ZKP

zk-SNARK (Zero-Knowledge Succinct Non-Interactive Argument of Knowledge) est une technologie basée sur une preuve de connaissance nulle qui peut prouver l'authenticité d'une déclaration sans révéler d'informations réelles. Il s'agit d'une technologie de preuve sans connaissance très efficace qui peut générer et vérifier des preuves en très peu de temps tout en protégeant la confidentialité et la sécurité, elle est donc largement utilisée. Cependant, avec l’expansion des applications, sa sécurité attire de plus en plus l’attention. Nous avons découvert sa vulnérabilité générale il n'y a pas si longtemps : si la plage de valeurs du paramètre saisi dans la fonction de vérification n'est pas correctement vérifiée dans le projet ZKP, un attaquant peut falsifier plusieurs entrées pour réussir la vérification, provoquant une attaque à double dépense. L'impact de cette attaque est très large, impliquant plusieurs algorithmes zk-SNARK dont : groth16, plonk, etc., et cette vulnérabilité existe dans de nombreux langages de développement tels que solidity et js. Cette vulnérabilité a été découverte pour la première fois par poma sur le projet sans connaissance préalable Semaphore, et deux exemples de transactions implémentées avec succès ont été donnés, comme le montre la figure ci-dessous :

Le principe d'attaque spécifique de cette vulnérabilité est que si vous souhaitez générer et vérifier la preuve zk-SNARK dans Ethereum, vous devez utiliser le circuit de courbe elliptique à champ fini F_p-arithmétique, où la valeur p est utilisée pour déterminer la plage. du champ fini de la courbe elliptique, donc le circuit La plage de valeurs d'entrée est [0,1,…,p-1]. Différentes courbes ont différentes valeurs p :

Courbe BN254 définie dans EIP-196 (également connue sous le nom de courbe ALT_BN128) :

p = 218882428718392752222246405745257275088548364400416034343698204186575808495617

circom2 introduit deux nouvelles courbes premières, les courbes BLS12-381 :

p = 52435875175126190479447740508185965837690552500527637822603658699938581184513

et plink2 :

18446744069414584321

YkMsUbmKFjMsTG6nLSo6mdggbsABtGXrkBJb8GxQ.png

Semaphore a ensuite confirmé et corrigé la vulnérabilité, et les bibliothèques zk telles que ZoKrates et snarkjs ont également effectué des réparations d'urgence simultanément. Cependant, les chercheurs en sécurité de Beosin ont découvert qu'il n'existe actuellement aucune solution unifiée à ce problème. Par exemple, le protocole Semaphore écrit des contraintes dans le couplage. bibliothèque. La plage de données valide n'est pas explicitement vérifiée dans la logique métier externe ; le code de contrat généré par Circom et Tornado.Cash vérifie explicitement SNARK_SCALAR_FIELD dans la fonction de vérification. Il s'agit d'une solution déroutante et incohérente. Cela peut entraîner des problèmes et des risques de sécurité pour de nombreuses nouvelles parties au projet zk DApp, nous espérons donc utiliser une manière standardisée pour résoudre ce problème.

4. Attaque à double dépense dans ERC-1922

Actuellement, Ethereum dispose d'une norme EIP-1922 liée à zk, qui introduit l'interface standard Verify contract pour vérifier zk-SNARK. Le code spécifique est le suivant :

pragma solidity ^0.5.6;/// @title EIP-XXXX zk-SNARK Verifier Standard/// @dev Voir /// Remarque : l'identifiant ERC-165 pour cette interface est 0xXXXXXXXXX./// ⚠️ TODO : Calculer l'interface identifierinterface ERC1922 /* est ERC165 */ { /// @notice Vérifie les arguments de Proof, via des /// fonctions d'appariement de courbe elliptique. /// @dev /// DOIT retourner vrai si la preuve réussit toutes les vérifications (c'est-à-dire que la preuve est /// valide). /// DOIT renvoyer false si la preuve ne passe pas tous les contrôles (c'est-à-dire si la /// preuve n'est pas valide). /// @param preuve Un zk-SNARK. /// @param inputs Entrées publiques qui accompagnent Proof. /// @param vérificationKeyId Un identifiant unique (connu de ce vérificateur /// contrat) pour la clé de vérification à laquelle correspond Proof. /// @return result Le résultat du calcul de vérification. True /// si la preuve est valide ; faux sinon. function verify(uint256[] calldata proof, uint256[] calldata inputs, bytes32 verifyKeyId) retours externes (résultat bool);}

Parmi eux, les types de variables de preuve de preuve de connaissance nulle et d'entrée sont uint256[]. Ce type de variable est actuellement l'opération de courbe elliptique la plus couramment utilisée dans l'algorithme ZKP. Cependant, la protection de sécurité correspondante n'est pas ajoutée à cette interface, donc double Des attaques par dépenses existent également. Un énorme risque pour la sécurité.

5.Solution ERC-7520

Sur la base des problèmes ci-dessus, Beosin a proposé EIP-7520 pour prévenir ce type de risque de sécurité. Plus précisément, tous les projets DApp utilisant la technologie zk dans l'écosystème Ethereum doivent implémenter cette interface dans le contrat de vérification conforme afin d'utiliser des normes unifiées et sûres. vérification de la plage valide sur toutes les entrées. L'interface spécifique est la suivante :

pragma solidity ^0.5.6;/// @title EIP-XXXX zk-SNARK public inputs Verifier Standard/// Remarque : l'identifiant ERC-165 pour cette interface est 0xXXXXXXXX./// ⚠️ À FAIRE : Calculer l'identifiant d'interfaceinterface EIP7520 /* is ERC165 & ERC1922 */ { /// @notice Vérifie que les arguments des entrées sont dans le champ scalaire /// @dev /// DOIT retourner vrai si les entrées réussissent la vérification de plage (c'est-à-dire que les entrées sont /// valides). /// DOIT renvoyer false si les entrées ne réussissent pas la vérification de plage (c'est-à-dire si les /// entrées ne sont pas valides). /// @param inputs Entrées publiques qui accompagnent Proof. /// @param p Entrée publique qui accompagne la courbe. fonction verifyPublicInput(uint256[] entrées,uint256 p) retours externes (résultat booléen);}

La fonction verifyPublicInput est au cœur de cette norme. Les significations spécifiques des paramètres impliqués sont les suivantes :

  • entrées : définies comme type uint256[], représentant les paramètres de signal public impliqués dans la fonction de vérification du projet ZKP
  • p : Défini comme type uint256, cette valeur correspond à la valeur p de la courbe elliptique utilisée dans l'algorithme

Ce qui suit comparera les deux situations de mise en œuvre et de non mise en œuvre de l'interface EIP-7520, en visant les différentes manifestations de cette attaque, pour indiquer les risques pour les parties au projet :

1 Supposons que nous utilisons directement le code du contrat de vérification pour la vérification sans appeler le verifyPublicInput de cette interface eip. Le code spécifique est le suivant :

function verify (uint [] entrée mémoire, preuve de mémoire de preuve) la vue interne renvoie (uint) { Mémoire VerifyingKey vk = verifyKey (); require(input.length + 1 == vk.IC.length,"verifier-bad-input"); // Calcule la combinaison linéaire vk_x Mémoire Pairing.G1Point vk_x = Pairing.G1Point(0, 0); pour (uint i = 0; i < input.length; i++) vk_x = Pairing.addition(vk_x, Pairing.scalar_mul(vk.IC[i + 1], entrée [i] )); vk_x = Pairing.addition (vk_x, vk.IC [0] ); if (!Pairing.pairingProd4( Pairing.negate(proof.A), proof.B, vk.alfa1, vk.beta2, vk_x, vk.gamma2, proof.C, vk.delta2 )) renvoie 1 ; renvoie 0 ;}

Capture d'écran des résultats expérimentaux originaux prouvant que la vérification a réussi :

Dans le même temps, les quatre certificats suivants peuvent être falsifiés et peuvent également réussir la vérification, provoquant une attaque de double dépense :

En utilisant l’une des preuves falsifiées, les résultats de la vérification sont les suivants :

2 Si l'interface verifyPublicInput dans cet eip est appelée, la preuve falsifiée ci-dessus ne pourra pas être vérifiée. Une partie du code du contrat est la suivante. Pour les détails restants, veuillez vous référer à l'implémentation de référence :

function verifyx(uint[] entrées mémoire, preuve de mémoire de preuve, bytes32 vérificationKeyId,uint256 p) public return (uint){ require(verifyPublicInput(inputs,p),"verifier-over-snark-scalar-field"); require(verify(inputs,proof,verificationKeyId),"verify fail"); return true;}function verifyPublicInput(uint256[] inputs,uint256 p) la vue interne renvoie (bool) { for (uint i = 0; i < input.length; i++) { require(input < p,"verifier-gte-snark -champ-scalaire"); } renvoie vrai ;}

Les résultats expérimentaux sont présentés dans la figure ci-dessous :

En résumé, on constate que si cette interface n'est pas utilisée pour vérifier la validité de la plage de valeurs du signal public, il peut y avoir un risque d'attaques à double dépense. **

Voir l'original
Cette page peut inclure du contenu de tiers fourni à des fins d'information uniquement. Gate ne garantit ni l'exactitude ni la validité de ces contenus, n’endosse pas les opinions exprimées, et ne fournit aucun conseil financier ou professionnel à travers ces informations. Voir la section Avertissement pour plus de détails.
  • Récompense
  • Commentaire
  • Partager
Commentaire
0/400
Aucun commentaire
Trader les cryptos partout et à tout moment
qrCode
Scan pour télécharger Gate app
Communauté
Français (Afrique)
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)