Saltar al contenido

Curva Elíptica en Bitcoin

Tiempo de lectura aprox: 8 minutos, 36 segundos

Recientemente estaba ayudando a un amigo a configurar su nuevo watch-only wallet. Como era de esperar, surgió una inquietud común cuando se utiliza este tipo de monederos:

“Si siempre me dices que debo mantener mis claves privadas en secreto, ¿por qué puedo ingresar mi clave pública1 en el monedero sin poner en riesgo mis fondos?”

Fue entonces cuando aproveché para explicarle el concepto de las funciones criptográficas unidireccionales. Específicamente, aquella función que conforma la base técnica para generar la clave pública: la Curva Elíptica.

Tras hablar de este tema durante un buen rato, algo hizo “click” en mi mente: recordé que cuando tuve que entender el funcionamiento de la Curva Elíptica me llevo muchas horas, porque en la mayoría de las fuentes a consultar no estaba toda la información o estaba mal planteada.

Además, mi amigo había sido capaz de entender el funcionamiento de la Curva Elíptica tras mi explicación en menos de 30 minutos.

Es por ello, que basándome en el planteamiento que utilicé para explicarle este maravilloso concepto, fue que escribí el artículo que lees. Espero que, tras esta lectura, no tengas nunca más dudas de cómo funciona, y que siempre puedas volver para resolverlas. Comenzamos.

Indagando en la Criptografía de Curva Elíptica

La Criptografía de Curva Elíptica (ECC, por sus siglas en inglés) es uno de los conceptos más interesantes – e importantes – de la unión entre la Matemática y la Tecnología. Sus capacidades son muy superiores a otros sistemas con el mismo fin, y ha sido probada hasta la extenuación para probar su seguridad.

En términos generales, la ECC es un tipo de función criptográfica unidireccional, es decir, permite convertir una entrada (input) en una salida (output) de tal manera que sea inviable obtener los datos de entrada original a partir de la salida.

Teniendo este concepto en mente y aplicándolo a Bitcoin, ECC es esencial en un paso crucial: la derivación de la Clave Pública a partir de la Clave Privada. Sin una función unidireccional como ECC, cuando compartiésemos nuestra clave pública, nuestra clave privada se vería expuesta y, por tanto, un atacante podría obtener nuestros fondos. De ahí que sea tan necesaria una función unidireccional como ECC.

Dentro de ECC existen muchas variantes de curvas elípticas y parámetros distintos. Para el caso de Bitcoin, Satoshi Nakamoto eligió la Curva Elíptica llamada “secp256k1”, una variante utilizada tanto para derivar las claves públicas como para firmar transacciones en Bitcoin.

¿Por qué eligió Satoshi a ECC?

La cuestión es, habiendo múltiples funciones criptográficas que consiguen la unidireccionalidad del resultado, ¿cuál es la razón detrás de que Satoshi Nakamoto eligiese en concreto la Curva Elíptica, y no otras funciones como la RSA2?

Si buscamos una gran seguridad a la hora de utilizar la función unidireccional, un buen nivel sería 128 bits de seguridad equivalente3, es decir, que tenga el mismo nivel de seguridad que una clave en criptografía simétrica de 128bits.

Para este nivel de seguridad, con ECC necesitamos la curva «secp256k1» que genera claves de 256 bits de longitud, mientras que con RSA necesitaríamos generar claves de 3072 bits de longitud. Es evidente que ECC es mucho más eficiente.

Esto ocurre porque cuando se diseñó RSA en 1977, el problema matemático involucrado (factorización de número primos muy elevados) tenía un nivel de dificultad alto para las computadoras de ese momento. Sin embargo, con el aumento exponencial de la capacidad de cálculo, actualmente ese problema matemático es mucho más fácil de abordar. Es tal la ventaja de ECC sobre RSA, que una clave RSA de 256 bits, del mismo tamaño que las de ECC, hoy puede descifrarse en apenas 50 segundos con hardware comúnmente disponible.

La diferencia tan marcada en eficiencia entre los dos sistemas es inherente al problema matemático involucrado. En RSA el nivel de complejidad es menor que en ECC, haciendo que se necesiten claves mucho más largas para lograr el mismo grado de seguridad contra ataques de fuerza bruta. Es observable que la diferencia se amplía exponencialmente conforme crece la longitud de clave necesaria.

Comparativamente, la Criptografía de Curva Elíptica (ECC) se basa en operaciones matemáticas que son computacionalmente inviables de resolver incluso con las supercomputadoras actuales. Esto permite que ECC alcance altos niveles de seguridad con claves muy cortas comparado con RSA.

Por lo que, con objeto de hacer más eficaz el espacio que ocupan las claves dentro de bitcoin, teniendo así un mejor equilibrio entre seguridad y tamaño, es lógico que Satoshi Nakamoto eligiera la ECC sobre la RSA.

Ecuación general de la Curva Elíptica y parámetros de secp256k1

La Curva Elíptica es una función matemática que viene dada por la siguiente fórmula:

Donde a y b son parámetros que definen cada curva específica. Cada combinación de valores de a y b genera una Curva Elíptica distinta con propiedades únicas.

En el caso de la Curva Elíptica secp256k1 utilizada en Bitcoin, “a” toma el valor 0 y “b” toma el valor 7. Por tanto, la ecuación queda de la siguiente forma:

Gráficamente, la Curva Elíptica secp256k1 presenta simetría respecto al eje x. Esto significa que, para un valor dado de x, la coordenada en y puede tomar dos valores: positivo o negativo.

Esta duplicidad de valores se origina en la resolución de la ecuación que define a secp256k1 (y^2 = x^3 + 7), la cual involucra el cálculo de raíces cuadradas. Concretamente, despejando y resulta en y = ±raíz cuadrada(x^3 + 7):

Tomando por ejemplo x = 2, se obtienen dos puntos simétricos de la forma (2, +3.87) y (2, -3.87). Cada valor de x genera así dos opciones para y, una positiva y otra negativa.

La duplicidad de valores para una misma x, es una característica crucial a la hora de calcular la Clave Pública.

Calculando la Clave Pública

La Clave Pública se obtiene a partir de la Clave Privada y una constante G conocida como Punto Generador, la cual es estática y está definida en los parámetros de la curva secp256k1, mediante la siguiente operación:

K (Clave Pública) = k (Clave Privada) x G (Punto Generador)

Esta operación no se realiza sobre los números reales, sino sobre las coordenadas en la Curva Elíptica, y en ese dominio multiplicar es mejor interpretarlo como sumar tantas veces el Punto Generador como indique el valor de la clave privada.

Si la Clave Privada fuera “5”, para obtener la Clave Publica habría que sumar G+G+G+G+G = 5G.

Como hemos dicho antes, el Punto Generador (G) es una constante ya determinada en los parámetros iniciales de la Curva Elíptica secp256k1:

04 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798 483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8

Siendo este número en hexadecimal las coordenadas x e y en las que se posiciona el Punto Generador (G) dentro la Curva Elíptica secp256k1.

Veamos esta operación de manera más visual:

Imaginemos que hay que sumar los puntos “A” y “B” sobre la Curva Elíptica. Para ello trazaremos una recta que pase por ambos, y el punto donde ésta cruce de nuevo la curva, será la suma de ambos en negativo “-C”. Ahora reflejamos ese mismo punto respecto del eje x, obteniendo así el punto “C”, el cual es la suma de A y B.

Y ahora consideremos como sumar un punto a si mismo, es decir, si tenemos el punto “P” queremos obtener “2P”. Para ello trazaremos una tangente al punto que queremos duplicar. Allá donde cruce la tangente, será -2P. Reflejamos -2P respecto del eje x, y obtenemos 2P.

Ahora podríamos utilizar ambos métodos para, a partir de P, conseguir 3P. Esto es, 2P + P.

Como se ve, podemos tomar un punto cualquiera e ir sumando y duplicando hasta conseguir la multiplicidad deseada del mismo.

Apliquemos esto al Punto Generador (G). Imaginemos que se encuentra en la coordenadas (1, 2.82) y queremos obtener 5G, suponiendo que 5 es el valor de la Clave Privada. Una forma de hacerlo será duplicar G, volverlo a duplicar y finalmente sumarle la G original. Las coordenadas del punto 5G resultante serán las de la Clave Pública:

5G = (2(2G)) + G

Teniendo en cuenta lo anterior, si partimos de un punto K, el cual representa las coordenadas de una clave pública, conociendo además el Punto Generador (G), ¿cuál sería el valor de la Clave Privada utilizada para obtener K?

Es imposible determinarlo, ¿verdad?

Esta es la gracia de la Curva Elíptica, lo que da razón a su existencia. El único método para encontrar el multiplicador (la Clave Privada) partiendo del Punto Generador y la Clave Pública, sería a través de fuerza bruta, esto es, probar cada número de entre todos los posibles hasta dar con aquel que multiplicado por el Punto Generador nos devuelve la Clave Pública (y todo esto siendo operaciones sobre la Curva Elíptica, las cuales requieren de un mayor procesamiento.)

En el caso de Bitcoin, la Clave Privada no es un numero de un solo dígito, sino un número que se representa con 256 bits, es decir, puede estar entre 0 y 115792089237316195423570985008687907853269984665640564039457584007913129639936.

Si tuviéramos acceso a 1.000.000 de ordenadores como el ordenador más potente que se encuentra en nuestro país, el MareNostrum4, necesitaríamos nada más y nada menos que 24478287087205351645436112169940788908514621232681 años para tener probabilidades de acertar una clave específica que se adecuase a los requerimientos de la Curva Elíptica, o lo que es lo mismo:  1773788919362706640973631316662376007863 edades del universo (13800 millones de años).

Como dirían en mi tierra: “Ahí es na’ ”.

He aquí la magia de la Criptografía mediante Curva Elíptica, es muy fácil ir en un sentido (derivar la Clave Pública) y virtualmente imposible ir en el contrario. 

Queda asegurada de esta forma la unidireccionalidad de la derivación de la clave publica y la robustez de este sistema.

Eficiencia en el Formato

Una vez hemos obtenido la Clave Pública a partir de la Clave Privada, nos encontramos con un número tal que así:

04 becf1cf6ef54423889aca53644398f14fd6e9531bd01980a38e6c7b2ca3fb426 6efd97cb9392ed186761526d2063032759b122e179be6fb8bf3575ece29d3621

Siendo “04” un prefijo que denota el tipo de formato de la Clave Pública, en azul la coordenada en x y en rojo la coordenada en y. Sin duda es un número bastante largo, que cuando es transmitido por la red, ocupa mucho espacio.

¿Y si pudiéramos reducirlo a la mitad? Recuerda, que la Curva Elíptica viene definida por la función:

Y que, por tanto, podemos despejar y solo conociendo x. Es decir, podemos comprimir el espacio que ocupa la Clave Pública, eliminando la parte que ocupa la y, dejando solo la x. Cuando se necesite conocer la Clave Pública, el ordenador en cuestión despejará y, obteniendo así ambas coordenadas.

Muy fácil, ¿no? Pues todavía queda un detalle:

Cuando se almacena la Clave Pública solo con la coordenada x, se denomina “Comprimida”. En este caso, para identificarla, lleva como prefijo “02” si la coordenada y es positiva, o “03” si es negativa.

Esta distinción del signo de y mediante el prefijo es necesaria para resolver adecuadamente la ecuación de la Curva Elíptica secp256k1. Esto es debido a que involucra la resolución de una raíz cuadrada, por ende, para cada x válido existirán dos posibles puntos sobre la curva, (x, +y) o (x, -y), simétricos respecto al eje x. Es decir, indicar el signo de y permite identificar de forma inequívoca al punto sobre la curva que representa la clave pública correspondiente a una determinada clave privada.

Por ejemplo, esta es la Clave Pública de unas líneas más arriba, ya comprimida, con el prefijo 03 indicando que su coordenada y es negativa. Pues comprobar que la coordenada x, la que se mantiene, tiene el mismo valor que antes.

03 becf1cf6ef54423889aca53644398f14fd6e9531bd01980a38e6c7b2ca3fb426

De esta forma se logra reducir el tamaño de la representación de la clave pública a la mitad en comparación a almacenar ambas coordenadas, sin que se pierda en ningún momento la información necesaria para verificar transacciones. Esto optimiza su almacenamiento y transmisión cuando se realiza una transacción, resultando en menores costes en fees.


Conclusión

A la hora de construir el sistema de propiedad que rige en Bitcoin, Satoshi sin duda eligió sabiamente la Curva Elíptica secp256k1: sus características singulares permiten asegurar nuestra Clave Privada y, por ende, nuestros fondos.

Gracias a la ECC podemos compartir nuestra Clave Pública con un watch-only wallet sin temer a que obtengan la Clave Privada, dado que sencillamente imposible.

Eso sí, si compartimos nuestra Clave Pública, pueden ver las transacciones que realizamos quedando nuestra privacidad afectada, aunque este tema lo dejo para otro día.

Gracias por llegar hasta aquí. Abajo dejo un apunte adicional para los más frikis (como yo) y un listado de las fuentes principales utilizadas para preparar este artículo.


Nube de Puntos

A nivel más técnico, la Curva Elíptica secp256k1 no se define sobre el plano cartesiano como previamente había mostrado para simplificar, sino sobre un Campo Fp con p igual a (2^256 – 2^32 – 2^9 – 2^8 – 2^7 – 2^6 – 2^4 – 1), un número primo muy alto.

La Curva Elíptica sobre el Campo Fp luce tal que así:

Este campo Fp se construye a partir de elementos obtenidos como el resto de dividir un número (la coordenada x e y de cada punto de la curva en el plano cartesiano) por p. Al realizar esta operación, cuando se grafican los nuevos puntos, pasan de ser una línea continua a una nube de puntos. A pesar de esta conversión, la Curva Elíptica mantiene las propiedades que explicábamos anteriormente: Existe simetría con respecto al eje x, así como se puede trazar una línea entre dos puntos para sumarlos.

Con fines ilustrativos, en el gráfico he empleado el valor de p = 43.5 para que se pueda observar claramente como se conforma la nube de puntos. Puedes probar ha modificar el valor de P, así como el rango de los valores de X y el tipo de Curva Elíptica por tu cuenta, cambiando los valores de la variable “parameters” en el código de Python que he preparado «elliptic-curve-field-p-chart.py»:

https://github.com/SalvaZaraes/bitcoin


Notas

  1. Clave Pública Extendida
  2. RSA (Rivest–Shamir–Adleman) es un algoritmo de cifrado asimétrico desarrollado en 1977 utilizado para la seguridad de datos. Se basa en la dificultad de factorizar grandes números compuestos en sus dos factores primos. Está siendo sustituido por ECC.
  3. Bits de Seguridad Equivalente: Este concepto se refiere al número de bits de fortaleza criptográfica que se obtiene con algoritmos de cifrado asimétrico como la Criptografía de Curva Elíptica (ECC), en comparación con el cifrado simétrico. Por ejemplo, cuando decimos que ECC con curva secp256k1 provee 128 bits de seguridad equivalente, significa que ofrece un nivel de protección similar al que se obtendría con un algoritmo de cifrado simétrico de 128 bits de longitud de clave como AES-128.

Fuentes

  • Antonopoulos, A. M. (2014). Mastering Bitcoin: Unlocking Digital Crypto-currencies. Oreilly & Associates Incorporated.
  • Codigo utilizado para calcular la Clave Publica sin Comprimir: https://bitcointalk.org/index.php?topic=644919.msg7205689#msg7205689
  • SECP256K1 – Bitcoin Wiki. (n.d.-b). https://en.bitcoin.it/wiki/Secp256k1
  • Standards for Efficient Cryptography 2 (SEC 2) (2010). https://www.secg.org/sec2-v2.pdf
  • ‌Clave RSA Desencriptación en 50 segundos:  https://formtek.com/blog/encryption-256-bit-rsa-cracked-by-a-laptop-in-50-sec/
  • Todas las imágenes son elaboración propia mediante la librería matplotlib en Python y posteriormente editadas.