Explicación detallada del borrador de ERC-7520: protección contra ataques de desbordamiento de entrada pública zk-SNARK

Autor: Saya & Bryce, expertos en investigación de seguridad de Beosin

** 1. ¿Qué es la prueba de conocimiento cero?

La prueba de conocimiento cero (ZKP) es un concepto criptográfico que se puede utilizar para demostrar la autenticidad de una declaración sin revelar ninguna información específica sobre la declaración. En una prueba de conocimiento cero, el probador puede demostrarle al verificador que una determinada afirmación es verdadera, y el verificador solo obtiene un resultado: aceptar la afirmación como verdadera o rechazarla, sin conocer los detalles específicos de la prueba.

Este concepto se puede explicar con un ejemplo sencillo. Supongamos que hay dos personas, una es el probador y la otra el verificador. El probador quiere demostrarle al verificador que conoce una contraseña secreta sin revelar la contraseña misma. En la forma tradicional, el probador podría decirle al verificador cuál es la contraseña, pero en la prueba de conocimiento cero, el probador puede utilizar un protocolo especial para demostrarle al verificador que conoce la exactitud de la contraseña sin revelar la contraseña misma.

Actualmente, los algoritmos comunes del sistema de prueba de conocimiento cero incluyen zk-SNARK, zk-STARK, BulletProofs, etc.

** 2. Aplicación de ZKP en blockchain **

En la tecnología blockchain, ZKP tiene una variedad de aplicaciones, como mejorar la privacidad, mejorar la escalabilidad y la seguridad, etc. Estas son algunas aplicaciones clave de ZKP en blockchain:

1 Protección de Privacidad:

La cadena de bloques es pública, lo que significa que cualquiera puede ver todas las transacciones de la cadena. A veces, sin embargo, es posible que los usuarios deseen mantener privada la información de sus transacciones. ZKP permite a los usuarios demostrar que tienen fondos suficientes para operar sin tener que revelar sus fondos totales. Esto mejora enormemente la protección de la privacidad del usuario. Por ejemplo, Zcash es una criptomoneda que utiliza tecnología de prueba de conocimiento cero, que permite a los usuarios ocultar el remitente, el destinatario y el monto de una transacción.

2 Compresión computacional y expansión blockchain:

La escalabilidad de blockchain es un desafío, especialmente en aplicaciones a gran escala. ZKP se puede utilizar para reducir la carga de los nodos y mejorar la escalabilidad de todo el sistema. Al utilizar ZKP para verificar la validez de las transacciones, los nodos no necesitan ver el historial completo de transacciones, lo que reduce la carga de almacenamiento y procesamiento. ZK Rollup, actualmente el más utilizado, es una solución de escalabilidad diseñada para mejorar Ethereum y otras áreas. Rendimiento y eficiencia de las redes blockchain. Combina las ventajas de las tecnologías Rollup y ZKP para proporcionar soluciones de expansión de aplicaciones descentralizadas (DApps) de alto rendimiento. En la red Ethereum tradicional, cada transacción debe verificarse y registrarse en la cadena de bloques, lo que genera retrasos y altos costos en el procesamiento de las transacciones. ZK Rollup agrupa y comprime una gran cantidad de transacciones en un solo bloque, y ZKP se utiliza para demostrar la validez de las transacciones por lotes para garantizar la exactitud y seguridad de las transacciones.

3 Autenticación:

Se pueden utilizar pruebas de conocimiento cero para verificar la identidad de un usuario sin revelar información personal confidencial. Por ejemplo, una persona puede utilizar pruebas de conocimiento cero para demostrar a la red que cumple con un determinado requisito de edad o posee una determinada certificación sin revelar su edad exacta u otra información de identificación.

4 Almacenamiento descentralizado:

El servidor puede demostrar a los usuarios que sus datos se guardan de forma segura y que no se filtra ningún contenido de los mismos.

En general, la prueba de conocimiento cero de **blockchain tiene amplias aplicaciones en protección de la privacidad, compresión y expansión informática, verificación de identidad, almacenamiento descentralizado, etc. Proporciona más funciones y opciones para la tecnología blockchain y promueve el desarrollo y la aplicación de blockchain en diferentes campos. **

3. Ataque de doble gasto en aplicaciones ZKP

zk-SNARK (Argumento de conocimiento sucinto no interactivo de conocimiento cero) es una tecnología basada en prueba de conocimiento cero que puede probar la autenticidad de una declaración sin revelar información real. Es una tecnología de prueba de conocimiento cero muy eficiente que puede generar y verificar pruebas en muy poco tiempo y al mismo tiempo proteger la privacidad y la seguridad, por lo que se utiliza ampliamente. Sin embargo, con la expansión de las aplicaciones, su seguridad ha atraído cada vez más atención. Descubrimos su vulnerabilidad general no hace mucho: si el rango de valores de la entrada del parámetro en la función de verificación no se verifica correctamente en el proyecto ZKP, un atacante puede falsificar múltiples entradas para pasar la verificación, provocando un ataque de doble gasto. El impacto de este ataque es muy amplio e involucra múltiples algoritmos zk-SNARK, incluidos: groth16, plonk, etc., y esta vulnerabilidad existe en muchos lenguajes de desarrollo como solidity y js. Esta vulnerabilidad fue descubierta por primera vez por poma en el proyecto de prueba de conocimiento cero Semaphore, y se dieron dos ejemplos de transacciones implementadas con éxito, como se muestra en la siguiente figura:

El principio de ataque específico de esta vulnerabilidad es que si desea generar y verificar la prueba zk-SNARK en Ethereum, debe usar el circuito de curva elíptica de campo finito aritmético F _p, donde el valor p se usa para determinar el rango. del campo finito de la curva elíptica, por lo que el circuito El rango de valores de entrada es [0,1,…,p-1]. Diferentes curvas tienen diferentes valores p:

Curva BN254 definida en EIP-196 (también conocida como curva ALT_BN128):

p = 21888242871839275222246405745257275088548364400416034343698204186575808495617

circom2 presenta dos nuevos números primos, las curvas BLS12-381:

p = 52435875175126190479447740508185965837690552500527637822603658699938581184513

y plink2:

18446744069414584321

YkMsUbmKFjMsTG6nLSo6mdggbsABtGXrkBJb8GxQ.png

Posteriormente, Semaphore confirmó y solucionó la vulnerabilidad, y las bibliotecas zk como ZoKrates y snarkjs también realizaron reparaciones de emergencia simultáneamente. Sin embargo, los investigadores de seguridad de Beosin descubrieron que actualmente no existe una solución unificada para este problema. Por ejemplo, el protocolo Semaphore escribe restricciones en el emparejamiento. biblioteca. El rango válido de datos no se verifica explícitamente en la lógica de negocios externa; el código de contrato generado por circom y Tornado.Cash verifica explícitamente SNARK_SCALAR_FIELD en la función de verificación. Esta es una solución confusa e inconsistente. Puede causar problemas y riesgos de seguridad para muchas partes nuevas del proyecto zk DApp, por lo que esperamos utilizar una forma estandarizada para resolver este problema.

4. Ataque de doble gasto en ERC-1922

Actualmente, Ethereum tiene un estándar EIP-1922 relacionado con zk, que introduce la interfaz estándar de contrato Verify para verificar zk-SNARK. El código específico es el siguiente:

pragma solidity ^0.5.6;/// @title EIP-XXXX zk-SNARK Verifier Standard/// @dev Ver /// Nota: el identificador ERC-165 para esta interfaz es 0xXXXXXXXX./// ⚠️ TODO: Calcular interfaz identifierinterface ERC1922 /* es ERC165 */ { /// @notice Comprueba los argumentos de Prueba, a través de curva elíptica /// funciones de emparejamiento. /// @dev /// DEBE devolver verdadero si la Prueba pasa todas las comprobaciones (es decir, la Prueba es /// válida). /// DEBE devolver falso si la Prueba no pasa todas las comprobaciones (es decir, si la /// Prueba no es válida). /// @param prueba A zk-SNARK. /// @param inputs Entradas públicas que acompañan a la prueba. /// @param verificarKeyId Un identificador único (conocido por este verificador /// contrato) para la clave de verificación a la que corresponde la prueba. /// @return result El resultado del cálculo de verificación. Verdadero /// si la prueba es válida; falso en caso contrario. función verificar (uint256 [] prueba de datos de llamada, uint256 [] entradas de datos de llamada, bytes32 verificarKeyId) devoluciones externas (resultado bool);}

Entre ellos, la prueba de conocimiento cero y los tipos de variables de entrada son uint256[]. Este tipo de variable es actualmente la operación de curva elíptica más utilizada en el algoritmo ZKP. Sin embargo, la protección de seguridad correspondiente no se agrega a esta interfaz, por lo que el doble -También existen ataques de gasto. Enorme peligro para la seguridad.

5. Solución ERC-7520

Con base en los problemas anteriores, Beosin propuso EIP-7520 para prevenir este tipo de riesgo de seguridad. Específicamente, todos los proyectos DApp que utilizan la tecnología zk en el ecosistema Ethereum deben implementar esta interfaz en el contrato de verificación compatible para utilizar estándares unificados y seguros. Verificación de rango válida en todas las entradas. La interfaz específica es la siguiente:

solidez pragma ^0.5.6;/// @title EIP-XXXX zk-SNARK entradas públicas Verificador Estándar/// Nota: el identificador ERC-165 para esta interfaz es 0xXXXXXXXX./// ⚠️ TODO: Calcular el identificador de interfazinterfaz EIP7520 /* es ERC165 y ERC1922 */ { /// @notice Comprueba que los argumentos de las entradas estén dentro del campo escalar /// @dev /// DEBE devolver verdadero si las entradas pasan la verificación de rango (es decir, las entradas son /// válidas). /// DEBE devolver falso si las Entradas no pasan la verificación de rango (es decir, si las /// Entradas no son válidas). /// @param inputs Entradas públicas que acompañan a la prueba. /// @paramp p Entrada pública que acompaña a la curva. función verificarPublicInput(uint256[] entradas,uint256 p) retornos externos (resultado bool);}

La función verificarPublicInput es el núcleo de este estándar. Los significados específicos de los parámetros involucrados son los siguientes:

  • entradas: definidas como tipo uint256[], que representan los parámetros de señal pública involucrados en la función de verificación en el proyecto ZKP
  • p: Definido como tipo uint256, este valor corresponde al valor p de la curva elíptica utilizada en el algoritmo

A continuación se compararán las dos situaciones de implementación y no implementación de la interfaz EIP-7520, apuntando a las diferentes manifestaciones de este ataque, para indicar los riesgos para las partes del proyecto:

1 Supongamos que usamos directamente el código del contrato de verificación para la verificación sin llamar a verificarPublicInput de esta interfaz eip, el código específico es el siguiente:

función verificar (uint [] entrada de memoria, prueba de memoria de prueba) la vista interna devuelve (uint) { memoria VerifyingKey vk = verificaringKey(); require(input.length + 1 == vk.IC.length,"verificador-entrada-mala"); // Calcula la combinación lineal vk_x Pairing.G1Point memoria vk_x = Pairing.G1Point(0, 0); para (uint i = 0; i < input.length; i++) vk_x = Pairing.addition(vk_x, Pairing.scalar_mul(vk.IC[i + 1], entrada [i] )); vk_x = Emparejamiento.adición(vk_x, vk.IC [0] ); if (!Pairing.pairingProd4( Pairing.negate(prueba.A), prueba.B, vk.alfa1, vk.beta2, vk_x, vk.gamma2, prueba.C, vk.delta2 )) devuelve 1; devolver 0;}

Captura de pantalla de los resultados experimentales originales que demuestran que se aprobó la verificación:

Al mismo tiempo, los siguientes cuatro certificados pueden falsificarse y también pasar la verificación, lo que provoca un ataque de doble gasto:

Utilizando una de las pruebas falsificadas, los resultados de la verificación se muestran a continuación:

2 Si se llama a la interfaz verificarPublicInput en este eip, la prueba falsificada anterior no se podrá verificar. Parte del código del contrato es el siguiente. Para los detalles restantes, consulte Implementación de referencia:

función verificarx(uint[] entradas de memoria, prueba de memoria de prueba, bytes32 verificarKeyId,uint256 p) retornos públicos (uint){ require(verifyPublicInput(inputs,p),"verificador-sobre-campo-escalar-snark"); require(verify(inputs,proof,verificationKeyId),"verificar falló"); devolver verdadero;}función verificarPublicInput(uint256[] entradas,uint256 p) vista interna devuelve (bool) { for (uint i = 0; i < input.length; i++) { require(input < p,"verifier-gte-snark -campo escalar"); } devolver verdadero;}

Los resultados experimentales se muestran en la siguiente figura:

En resumen, se puede encontrar que si esta interfaz no se utiliza para verificar la validez del rango de valores de la señal pública, puede existir el riesgo de ataques de doble gasto. **

Ver originales
Esta página puede contener contenido de terceros, que se proporciona únicamente con fines informativos (sin garantías ni declaraciones) y no debe considerarse como un respaldo por parte de Gate a las opiniones expresadas ni como asesoramiento financiero o profesional. Consulte el Descargo de responsabilidad para obtener más detalles.
  • Recompensa
  • Comentar
  • Compartir
Comentar
0/400
Sin comentarios
Opere con criptomonedas en cualquier momento y lugar
qrCode
Escanee para descargar la aplicación Gate
Comunidad
Español
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)