El “hashing” alude al proceso de generar un output de extensión fija, a partir de un input de extensión variable. Esto se logra mediante el uso de unas fórmulas matemáticas denominadas funciones hash (y que se implementan como algoritmos hashing).
A pesar de que no todas las funciones hash conllevan el uso de criptografía, las llamadas funciones hash criptográficas son una parte fundamental de las criptomonedas. Gracias a ellas, las blockchains y otros sistemas distribuidos son capaces de alcanzar niveles significativos de integridad y seguridad en los datos.
Tanto las funciones hash convencionales como las criptográficas son determinísticas. Que sean “determinísticas” significa que, en la medida que el input no se modifique, el algoritmo hashing producirá siempre el mismo output (también conocido como “digest” o “hash”).
Usualmente, los algoritmos hashing de las criptomonedas se diseñan como funciones unidireccionales, lo que significa que no pueden revertirse fácilmente, y sin emplear una gran cantidad de tiempo y recursos computacionales. En otras palabras, resulta bastante fácil crear el output a partir del input, pero es relativamente difícil ejecutar la operación inversa (es decir, generar el input sólo a partir del output). En términos generales, cuanto más complicado sea encontrar el input, más seguro se considerará el algoritmo hashing.
¿Cómo funciona una función hash?
Funciones hash distintas producirán outputs que diferirán en la extensión, pero el tamaño efectivo del output de cada algoritmo hashing será siempre constante. Por ejemplo, el algoritmo SHA-256 sólo podrá producir outputs de 256 bits, mientras que el SHA-1 generará siempre un digest de 160 bits.
Para ilustrarlo, procesaremos las palabras “Binance” y “binance” mediante el algoritmo hashing SHA-256 (que es el utilizado por Bitcoin).
SHA-256 | |
Input | Output (256 bits) |
Binance | f1624fcc63b615ac0e95daf9ab78434ec2e8ffe402144dc631b055f711225191 |
binance | 59bba357145ca539dcd1ac957abc1ec5833319ddcae7f5e8b5da0c36624784b2 |
Véase como un cambio menor (la mayúscula de la primera letra) produce como resultado un valor de hash radicalmente distinto. Pero dado que estamos empleando el SHA-256, los outputs tendrán siempre una extensión fija de 256 bits (o 64 caracteres) -independientemente del tamaño del input. Asimismo, no importará la cantidad de veces que se procesen las dos palabras a través del algoritmo, los dos outputs se mantendrán inalterables.
Por otro lado, si procesamos los mismos inputs a través del algoritmo hashing SHA-1, obtendremos los siguientes resultados:
SHA-1 | |
Input | Output (160 bits) |
Binance | 7f0dc9146570c608ac9d6e0d11f8d409a1ee6ed1 |
binance | e58605c14a76ff98679322cca0eae7b3c4e08936 |
Cabe destacar que el acrónimo “SHA” significa “Secure Hash Algorithms”. Designa una serie de funciones hash criptográficas que incluyen a los algoritmos SHA-0 y SHA-1, junto con los grupos SHA-2 y SHA-3. El SHA-256 forma parte del grupo SHA-2, junto con el SHA-512 y otras variantes. En la actualidad, solamente los grupos SHA-2 y SHA-3 se consideran seguros.
¿Por qué son importantes?
Las funciones hash convencionales presentan una amplia variedad de casos de uso, entre los que se incluyen lookups de bases de datos, análisis de grandes archivos y gestión de datos. Por el contrario, las funciones hash criptográficas se utilizan ampliamente en aplicaciones de seguridad de la información, tales como la autenticación de mensajes y las huellas digitales. En lo que respecta a Bitcoin, las funciones hash criptográficas constituyen una parte esencial del proceso de minado, y también juegan un papel destacado en la generación de nuevas direcciones y claves.
Pero el auténtico potencial del hashing se revela cuando es necesario lidiar con cantidades enormes de información. Por ejemplo, es posible procesar un archivo grande o un conjunto de datos a través de una función hash, y a continuación utilizar su output para rápidamente verificar la exactitud e integridad de los datos. Esto es posible debido a la naturaleza determinística de las funciones hash: el input producirá siempre un output simplificado y condensado (hash). Dicha técnica elimina la necesidad de almacenar y recordar grandes cantidades de datos.
El hashing es particularmente útil en el contexto de la tecnología blockchain. La blockchain de Bitcoin lleva a cabo diversas operaciones que conllevan hashing, la mayoría de ellas en el marco del proceso de minado. De hecho, casi todos los protocolos de criptomonedas dependen del hashing para condensar grupos de transacciones en bloques, así como para producir enlaces criptográficos entre cada uno de estos últimos -lo que, de forma efectiva, acaba generando una blockchain.
Funciones hash criptográficas
Como ya hemos explicado, una función hash que despliega técnicas criptográficas puede ser definida como una función hash criptográfica. En términos generales, la vulneración de una función hash criptográfica requiere un gran número de tentativas de ataques de fuerza bruta (“brute-force attempts”). Alguien que quisiera revertir una función hash criptográfica necesitaría adivinar el input, mediante prueba error, hasta lograr producir el output correspondiente. Sin embargo, cabe la posibilidad de que diferentes inputs produzcan exactamente el mismo output, en cuyo caso se producirá lo que viene denominándose una “collision” (colisión).
Técnicamente, una función hash criptográfica debe presentar tres propiedades para ser considerada efectivamente segura. Dichas propiedades pueden ser denominadas “collision resistance” (resistencia a la colisión), “preimage resistance” (resistencia a preimagen) y “second preimage resistance” (resistencia a segunda preimagen).
Antes de discutir cada una de estas propiedades, procederemos a esbozar la lógica subyacente a las mismas en tres cortas frases:
- Resistencia a la colisión: inviable encontrar dos inputs distintos, cualesquiera, que produzcan el mismo hash como output.
- Resistencia a preimagen: inviable “revertir” la función hash (encontrar el input a partir de un output determinado).
- Resistencia a la segunda preimagen: inviable para encontrar cualquier segundo input que colisione con un input específico.
Resistencia a la colisión
Como se ha mencionado, ocurre una colisión cuando diferentes entradas producen exactamente el mismo hash. Así, una función hash se considera resistente a la colisión hasta el momento en que alguien encuentra una colisión. Ten en cuenta que las colisiones siempre existirán para cualquier función hash porque las posibles entradas son infinitas, mientras que las posibles salidas son finitas.
Dicho de otro modo, una función hash es resistente a las colisiones cuando la posibilidad de encontrar una colisión es tan baja que requeriría millones de años de computaciones. Así que a pesar de que no hay ninguna función de hash sin colisión, algunas de ellos son lo suficientemente fuertes como para ser considerados resistentes (por ejemplo, SHA-256).
Entre los diversos algoritmos SHA, los grupos SHA-0 y SHA-1 ya no son seguros porque se han encontrado colisiones. Actualmente, los grupos SHA-2 y SHA-3 se consideran resistentes a las colisiones.
Resistencia a preimagen
La propiedad de la resistencia a preimagen está relacionada con el concepto de funciones unidireccionales. Una función hash se considera resistente a la preimagen cuando hay una probabilidad muy baja de que alguien encuentre la entrada que generó una salida particular.
Ten en cuenta que esta propiedad es diferente de la anterior porque un atacante intentaría adivinar cuál era la entrada al observar una salida determinada. Una colisión, por otro lado, ocurre cuando alguien encuentra dos entradas diferentes que generan la misma salida, pero no importa qué entradas se usaron.
La propiedad de la resistencia a preimagen es valiosa para proteger datos porque un simple hash de un mensaje puede demostrar su autenticidad, sin la necesidad de divulgar la información. En la práctica, muchos proveedores de servicios y aplicaciones web almacenan y utilizan hashes generados a partir de contraseñas en lugar de contraseñas en texto plano.
Resistencia a segunda preimagen
Para simplificar, podemos decir que la resistencia de la segunda preimagen está en algún lugar entre las otras dos propiedades. Un ataque de la segunda preimagen ocurre cuando alguien puede encontrar un input específico que genera el mismo output de otro input que ya conocen.
En otras palabras, un ataque de segunda preimagen implica encontrar una colisión, pero en lugar de buscar dos inputs aleatorios que generen el mismo hash, buscan un input que genere el mismo hash que fue generado por otro input específico.
Por lo tanto, cualquier función de hash que sea resistente a las colisiones también es resistente a los ataques de segunda preimagen, ya que esto último siempre implicará una colisión. Sin embargo, aún se puede realizar un ataque de preimagen en una función resistente a la colisión, ya que implica encontrar un solo input desde un solo output.
Minería
Hay muchos pasos en la minería de Bitcoin que involucran funciones hash, como verificar saldos, vincular entradas y salidas de transacciones, y transacciones hash dentro de un bloque para formar un árbol Merkle. Pero una de las razones principales por las que Bitcoin y blockchain son seguros es el hecho de que los mineros necesitan realizar una gran cantidad de operaciones de hashing para encontrar una solución válida para el siguiente bloque.
Específicamente, un minero debe probar varios inputs diferentes al crear un valor de hash para su bloque candidato. En esencia, sólo podrán validar su bloque si generan un hash de output que comienza con un cierto número de ceros. El número de ceros es lo que determina la dificultad minera, y varía según la tasa de hash dedicada a la red.
En este caso, la tasa de hash representa cuánto poder informático se está invirtiendo en la minería Bitcoin. Si la tasa de hash de la red aumenta, el protocolo Bitcoin automáticamente ajustará la dificultad de minería para que el tiempo medio necesario para extraer un bloque siga cerca de 10 minutos. En contraste, si varios mineros deciden dejar de minar, causando que la tasa de hash disminuya significativamente, la dificultad de la minería se ajustará, facilitando la minería (hasta que el promedio de tiempo de bloqueo vuelva a 10 minutos).
Ten en cuenta que los mineros no tienen que encontrar colisiones porque hay múltiples hashes que pueden generar como un output válido (a partir de un cierto número de ceros). Por lo tanto, hay varias soluciones posibles para un determinado bloque, y los mineros sólo tienen que encontrar una de ellas – según el umbral determinado por la dificultad de minería.
Como la minería Bitcoin es una tarea que requiere un costo, los mineros no tienen razón para engañar al sistema, ya que provocaría pérdidas financieras significativas. Cuanto más mineros se unan a una blockchain, mayor y más fuerte se vuelve.
En conclusión
No cabe duda de que las funciones de hash son herramientas esenciales en la informática, especialmente cuando se trata de grandes cantidades de datos. En combinación con la criptografía, los algoritmos hashing pueden resultar bastante versátiles, ofreciendo seguridad y autenticación de múltiples formas. Como tal, las funciones de hash criptográfico son vitales para casi todas las redes criptográficas, por lo que comprender sus propiedades y mecanismos de trabajo es ciertamente útil para cualquiera interesado en la tecnología de blockchain.