¡Bienvenido! ¿Eres nuevo en Zcash?
The Zcash network is young, but evolving quickly! Sign up and we'll be in touch with monthly highlights on ecosystem growth, network development and how to get started with Zcash!

Idioma

Corrigiendo Vulnerabilidades en el Protocolo Zcash

Taylor Hornby, Zooko Wilcox | Apr 26, 2016

Introducción

por Zooko

He trabajado en criptografía, seguridad de la información y dinero digital la mitad de mi vida (20 años, pero quién está contando?), y nunca he trabajado en un criptosistema tan ambicioso como Zcash. Adicionalmente, nunca he trabajado con un equipo tan singularmente cualificado para la exigente tarea de construir criptosistemas seguros y prácticos.

Una parte esencial de la práctica de la seguridad informática es un proceso "antagonístico" en el cual intentas atacar un sistema ─para encontrar sus debilidades─ al mismo tiempo que estás tratando de fortalecerlo. Este proceso puede ser desconcertante cuando es visto desde fuera, pero para los expertos en seguridad informática, si vemos que alguien encuentra, corrige y publica problemas de seguridad, esto nos da confianza en que el sistema se está haciendo más fuerte.

Algunos miembros de nuestro equipo han realizado previamente este tipo de trabajo de auditorías de seguridad para otros, incluyendo Cryptocat, GlobaLeaks, SpiderOak y Ethereum.

En este artículo del blog, informamos sobre los problemas de seguridad que hemos encontrado en el protocolo de Zcash mientras nos preparamos para presentarlo como un sistema financiero abierto y sin permisos.

Algunos de los miembros de nuestro equipo publicaron el 'paper' de ciencia original de Zerocash, con reviews científicos de pares, en 2014. Recientemente, hemos ampliado y mejorado el protocolo, escrito una nueva y detallada especificación de protocolo, y lo hemos purgado de vulnerabilidades de seguridad.

Al día de la fecha, hemos encontrado y corregido tres vulnerabilidades de seguridad:

  1. Zooko Wilcox encontró la vulnerabilidad Faerie Gold, u 'Oro de Hadas', que habría hecho posible engañar a un usuario de Zcash llevándolo a pensar que recibió un montón de notas pasibles de ser gastadas. De hecho, cuando tratara de gastar las notas se encontraría con que sólo una de ellas puede ser gastada.
  2. Taylor Hornby encontró la vulnerabilidad Colisión InternalH, que permitiría a alguien gastar dos veces una nota especialmente diseñada, si tuviera una computadora lo suficientemente potente como para encontrar colisiones de hash de 128 bits.
  3. Daira Hopwood encontró un error no explotable en la prueba de seguridad, donde si una de las funciones pseudoaleatorias que el protocolo utiliza no es a su vez resistente a las colisiones, entonces las notas enviadas a una dirección privada especialmente diseñada, podrían gastarse dos veces. (Esto no era explotable porque la función que es en realidad utilizada es resistente a las colisiones.)

Aquí está el informe de Taylor sobre la que tiene más impacto de estas tres ─la vulnerabilidad de Colisión InternalH, que él encontró.

— Zooko Wilcox, 2016-04-25

La Vulnerabilidad de Colisión InternalH

by Taylor

Si hubiéramos lanzado Zcash sin haber encontrado y corregido la vulnerabilidad de Colisión InternalH, podría haber sido explotada para falsificar moneda. Alguien con suficiente potencia de cálculo para encontrar colisiones de hash de 128 bits, habría sido capaz de gastar el dinero dos veces hacía sí mismo, creando Zcash de la nada.

Encontrar colisiones de hash de 128 bits requiere operaciones paralelizables de \(2^{64}\), que están hoy en día al alcance de los atacantes, por lo que la vulnerabilidad habría sido explotable en la práctica. Veamos cómo funciona el ataque, y lo que hemos hecho para arreglarlo.

El Error

La debilidad estaba en el esquema de compromiso para las notas. Los esquemas de compromiso son herramientas criptográficas útiles porque te permiten publicar un compromiso con una cierta información sin revelarla. Luego, en algún momento futuro, puedes abrir el compromiso para revelar la información y demostrar a todos que es la misma información a la que te comprometiste en primer lugar.

Para que esto funcione, los esquemas de compromiso deben satisfacer dos propiedades:

  1. Ocultamiento: No se llega a saber nada sobre la información por ver el compromiso. Incluso si estuvieras bastante seguro de cuál era la información, no deberías ser capaz de confirmar tu conjetura.
  2. Enlazabilidad: Si te comprometes a algún valor, no deberías ser capaz de cambiar de opinión más tarde y decir que en realidad te comprometiste a un valor diferente. Un compromiso debería abrirse a un único valor, y no debería ser posible abrir el compromiso a cualquier otro valor.

En Zcash, al objeto de valor fundamental se le llama una "nota", que consiste en los valores \((a_{pk}, v, \rho , r)\), los cuales tienen significados especiales en el protocolo. Como parte del protocolo, los compromisos con las notas se publican en el blockchain. Así es como se calculó ese compromiso en el diseño original:

\(InternalH = \text{SHA256Compress}(a_{pk} \text{ \| } \rho ) \text{ truncated to 128 bits }\)
\(k = \text{SHA256Compress}(r \text{ \| } InternalH)\)
\(cm = \text{SHA256Compress}(k \text{ \| } [0]^{192} \text{ \| } v)\)

Aquí, SHA256Compress es la función de compresión utilizada internamente por la función hash SHA256.

La vulnerabilidad de Colisión InternalH existe porque este esquema no contiene la propiedad de enlazabilidad. Es posible comprometerse con una nota y luego abrir el compromiso más tarde con una nota diferente.

Es fácil ver cómo se puede hacer esto si se puede colisionar hashes de 128 bits. El compromiso empieza por calcular \(InternalH\), un hash de 128 bits de \(a_{pk}\) y \(\rho \), y luego establecer un compromiso con ese hash. Si encuentras una colisión de InternalH, entonces tienes dos pares diferentes de \(a_{pk}\) y \(\rho \), \((a_{pk}, \rho )\) y \((a_{pk}\prime, \rho \prime)\) que dan como resultado el mismo \(InternalH\), y podrás abrir el compromiso tanto con \((a_{pk}, v, \rho , r)\) como con \((a_{pk}\prime, v, \rho \prime, r)\). Así que el esquema de compromiso no es vinculante, carece de enlazabilidad. ¿Cómo se traduce esta debilidad en un ataque?

El Ataque

Los compromisos con todas las notas en existencia se almacenan en el blockchain. Para poder gastar una nota, debes demostrar mediante conocimiento-cero que conoces la clave de gasto de una nota cuyo compromiso se registró en el blockchain y debes revelar el anulador de la nota. El anulador es un valor que se supone que es único para cada nota. Para asegurarse de que ninguna nota puede gastarse dos veces, todos los nodos de la red comprueban que no han visto antes el anulador que les es revelado.

El anulador de una nota \((a_{pk}, v, \rho , r)\) perteneciente a una clave de gasto \(a_{sk}\) es calculado aplicando una función pseudoaleatoria a \(\rho \), lo que quiere decir que el anulador es \(PRF_{a_{sk}}^{nf}(\rho )\). Quien gasta la nota debe probar por Conocimiento-Cero (sin revelar \(\rho \) o \(a_{sk}\)) que calculó correctamente el anulador.

La debilidad de InternalH permite a un atacante elaborar un compromiso de nota para el cual existen dos valores \(\rho \) válidos. Ellos pueden encontrar \(\rho _1\) y un \(\rho _2\) diferente, tal que el compromiso se abre tanto a \((a_{pk}, v, \rho _1, r)\) como a \((a_{pk}, v, \rho _2, r)\). El atacante puede gastar el compromiso de nota una primera vez usando \(\rho _1\) y revelando el anulador \(PRF_{a_{sk}}^{nf}(\rho _1)\), y luego gastarlo una segunda vez usando \(\rho _2\) y revelando el anulador \(PRF_{a_{sk}}^{nf}(\rho _2)\). En efecto, esta nota tiene dos diferentes anuladores en lugar de uno solo, por lo que se puede gastar dos veces. Dado que todo esto se hace en conocimiento cero, ninguno de los nodos de la red puede darse cuenta de que ambos gastos están haciendo referencia al mismo compromiso de nota. Otra variante del ataque funciona encontrando dos diferentes \(a_{pk}\), en lugar de dos diferentes \(\rho \).

Por cada colisión de hash de 128 bits que encuentre el atacante, puede efectivamente duplicar su riqueza al combinar todo su dinero Zcash en una nota de gasto doble y luego gastarla dos veces a sí mismo. Así que a pesar de que las operaciones de \(2^64\) para encontrar una colisión no son baratas, el ataque hace que rápidamente valga la pena.

La Corrección

Si lees la Sección 5.1 del 'paper' de ciencia original de Zerocash, encontrarás que elegimos que \(InternalH\) fuera de 128 bits para dar al esquema de compromiso una propiedad muy potente llamada ocultamiento estadístico. La propiedad de ocultación ordinaria es computacional: dice que no puedes llegar a saber nada sobre la entrada a menos que tengas un ordenador absurdamente rápido (es decir, capaz de quebrar SHA256). El ocultamiento estadístico dice que incluso si tienes una computadora infinitamente rápida, todavía no puedes llegar a saber nada sobre la entrada. Esto permitiría a Zcash mantener sus garantías de privacidad incluso si un día fuera quebrada la función hash SHA256.

Para solucionar la vulnerabilidad, cambiamos a un esquema de compromiso diferente que tiene enlazabilidad segura. Con el fin de mantener las pruebas de conocimiento-cero de Zcash eficientes para calcular, abandonamos la poderosa propiedad de ocultación estadística y nos quedamos con la regular. Esto no debería importar en la práctica, ya que para romper la propiedad de ocultamiento de nuestro nuevo esquema de compromiso, tendrías que romper una bien estudiada propiedad de seguridad de SHA256, lo cual parece poco probable que suceda en el corto plazo. Aquí está nuestro diseño actual para el esquema de compromiso de nota:

\(cm = \text{SHA256}(\text{0xB0} \text{ \| } a_{pk} \text{ \| } v \text{ \| } \rho \text{ \| } r)\)

Puedes encontrar los detalles completos en nuestra especificación de protocolo.

Conclusión

Construir protocolos de cifrado seguros es difícil, e incluso nuestro equipo de criptógrafos e ingenieros de seguridad de primera clase cometerán errores en el camino. A pesar del desafío, somos optimistas de que nuestras prácticas de cuidadosa revisión de seguridad y de transparencia conducirán a un producto seguro.

En este punto, el protocolo Zcash ha sido sometido a una intensa revisión de seguridad, primero a través de la revisión científica por pares, y luego por nuestro equipo interno de expertos. Pero necesitamos incluso más escrutinio para obtener la certeza de que el protocolo es seguro.

Si te gusta el reto de cazar bugs en protocolos criptográficos, nos encantaría que echaras un vistazo a nuestra especificación de protocolo. Si puedes romper nuestro protocolo y decirnos cómo lo has hecho, estarás ayudando a toda la humanidad a obtener un sistema financiero abierto, sin permisos, que preserve la privacidad!

— Taylor Hornby junto a Zooko Wilcox, 2016-04-25