Criptografía de Bitcoin
Para empezar este post, te pido que recordemos que en un post anterior definimos la multiplicación escalar como la posibilidad de obtener P de la siguiente fórmula P = kG, es decir multiplicar el punto G por un escalar k. esto nos será útil un poco mas abajo en este texto.
Hasta ahora hemos utilizado números primos relativamente pequeños para nuestros ejemplos, utilizar números primos pequeños harían que hacer un ejercicio de prueba y error para obtener k a partir de P fuese posible con un algoritmo sencillo en una computadora. Pero, ¿que pasa si hacemos que el número primo del orden del grupo sea mayor? La criptografía de curvas elípticas se basa en el manejo de números enormes que no permitan a computadoras hacer el ejercicio de fuerza bruta para obtener k.
La criptografía de llaves publicas para curvas elípticas define los siguientes parámetros:
- debemos especificar a y b para la curva y2 = x3 + ax + b
- debemos especificar el número primo p del cuerpo finito Fp
- debemos especificar las coordenadas x, y de punto generador G
- debemos especificar el orden del grupo generado por G y n
Curva específica de Bitcoin secp256k1
Como lo mencionamos antes la curva específica de Bitcoin se basa en el estándar secp256k1, en donde se definen los siguientes parámetros:
- a = 0, b = 7, por lo que la ecuación de la curva es:
\[y^2=x^3+7 \]
- p = 2256 - 232 - 977, es el orden del cuerpo finito
- Gx= 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798, coordenada x, en hexadecimal, del punto generador G
- Gy= 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8, coordenada y, en hexadecimal, del punto generador G
- n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141, orden del grupo de ciclo finito, en hexadecimal
Que tan grande son estos números, para darnos una idea podemos decir que 2256, ¡equivale a un número cercano al de todos los átomos en el universo!
Ahora si podemos definir lo que son las llaves privadas y publicas:
- La llave privada es un número entero aleatorio entre {1, … ,n}, como ya vimos el número n es un número inmenso.
- La llave pública P, es la multiplicación escalar de la llave privada p por el punto generador G, _P = pG.
Como ves, si conocemos p y G, obtener la llave pública P es fácil, pero si solo sabemos P y G obtener la llave privada p es difícil y requeriría resolver el problema de algoritmo discreto.
Criptografía ECDSA
A continuación, describimos los algoritmos de cifrado y verificación, para ello definiremos unos parámetros mas sencillos que los del estándar secp256k1 y que se utilizarán en un script de ejemplo en Python.
Parámetros
- Curva: y2 = x3 + 7
- ec_order = 13, orden de la curva elíptica
- punto generador G, Gx=8, Gy=1
- Llave privada k_priv = 9
- hash del mensaje z = 4
Proceso de firmado
- se tiene la llave privada k_prv
- K_pub = k_prv * G, calculamos la llave pública
- se tiene el hash del mensaje z
- se elige un número aleatorio k
- P = k * G, calculamos el punto P con la multiplicación escalar de k * G
- r = P.x() , se toma la coordenada x de P para definir r
- k_inv = pow(k, -1, ec_order), obtenemos el inverso multiplicativo de k
- s = k_inv * (z + r * k_prv), calculamos s
- El par (r, s) es la firma
proceso de verificación
- K_pub, conocemos la llave pública
- conocemos la firma, el par (r, s)
- s_inv = pow(s, -1, ec_order), obtenemos el inverso multiplicativo de s
- u = (s_inv * z) % ec_order, calculamos u
- v = (s_inv * r) % ec_order, calculamos v
- P_point = u * G + v * K_pub, calculamos el punto P_point
- P_point.x() == r, si la cordenada de x del punto P_point es igual a r, la firma es válida
En esencia lo que hace el proceso de verificación es calcular el punto A representado por u * G, después calcular el punto B representado por v * K_pub, y de la suma de A + B se obtiene el punto C, si la coordenada x de este punto C es igual a la coordenada x del punto r, que calculamos al multiplicar el numero aleatorio k * G, entonces podemos comprobar que la firma es válida, porque la firma fue creada con la llave privada conectada a esta llave pública.
Ha sido todo un reto tratar de explicar todos los temas que vimos en los últimos tres posts de forma lo mas simple posible pero que se entienda el detalle, espero que el proceso te haya llevado de la mano, a continuación, te comparto un link con un programa en Python en donde se ve un ejemplo de los procesos de cifrado y verificación, del mismo modo el programa trata de ser lo mas simple posible. script en Python
Con este post terminamos la serie de Criptografía Bitcoin.