En el ecosistema de Bitcoin, la seguridad y la privacidad son fundamentales. Uno de los elementos más cruciales para garantizar estos aspectos es la clave pública, que se deriva de la clave privada. Este artículo te guiará a través del proceso de generar una clave pública en Bitcoin, comenzando desde la construcción de la clave privada, explorando los algoritmos involucrados y proporcionando un ejemplo en Python para hacerlo vos mismo.
¿Qué es una Clave Privada? La clave privada es un número secreto, generalmente representado en formato hexadecimal, que permite al propietario gastar los bitcoins asociados a su dirección. La clave privada debe mantenerse en secreto, ya que cualquiera que la posea puede acceder a los fondos vinculados a ella.
La clave privada en Bitcoin es simplemente un número aleatorio entre 1 y un número máximo definido por el protocolo (que es (2^{256} - 1)). Imaginá que tenés una moneda y la lanzas 256 veces. Cada vez que la moneda cae en "cara", anotas un 1, y cuando cae en "cruz", anotas un 0. Este proceso generará una secuencia de 256 bits que representará tu clave privada. Podemos simular este proceso de lanzamiento de monedas utilizando un generador de números aleatorios en Python:
# Instalación de dependencias necesarias
!pip install pycryptodome
!pip install ecdsa
!pip install bech32
import random
import hashlib
from ecdsa import SigningKey, SECP256k1
from Crypto.Hash import RIPEMD160
import bech32
# Función para simular 256 lanzamientos de moneda y generar la clave privada
def flip_coin_256_times():
binary_key = ''.join([str(random.randint(0, 1)) for _ in range(256)])
return binary_key
# Genera la clave privada en binario y luego la convierte a hexadecimal
binary_private_key = flip_coin_256_times()
hex_private_key = hex(int(binary_private_key, 2))[2:]
print(f"Clave privada en binario: {binary_private_key}")
print(f"Clave privada en hexadecimal: {hex_private_key}")
Explicación: Esta función simula 256 lanzamientos de una moneda, donde cada resultado es 0 o 1. Esto genera una secuencia de 256 bits (unos y ceros) que es la representación binaria de nuestra clave privada en Bitcoin. Luego, convertimos esta clave privada a formato hexadecimal, que es más compacto y fácil de manejar para un humano.
¿Qué es una Clave Pública? Una clave pública en Bitcoin se deriva de la clave privada utilizando la criptografía de curva elíptica (ECC). La clave pública es lo que se puede compartir con otros para recibir pagos y es la base para generar una dirección de Bitcoin. Bitcoin utiliza la curva elíptica secp256k1 para generar la clave pública. Este proceso consiste en realizar una multiplicación escalar de la clave privada por un punto generador en la curva.
# Función para derivar la clave pública a partir de la clave privada
def private_key_to_public_key(private_key):
private_key_bytes = bytes.fromhex(private_key)
sk = SigningKey.from_string(private_key_bytes, curve=SECP256k1)
vk = sk.verifying_key
return vk.to_string().hex()
# Deriva la clave pública de la clave privada generada anteriormente
public_key = private_key_to_public_key(hex_private_key)
print(f"Clave privada: {hex_private_key}")
print(f"Clave pública: {public_key}")
Explicación: La clave pública en Bitcoin se deriva de la clave privada usando un tipo especial de matemática llamada criptografía de curva elíptica, específicamente la curva SECP256k1. Primero, convertimos la clave privada de hexadecimal a bytes. Luego, utilizamos la biblioteca ecdsa
para generar la clave pública correspondiente. La función private_key_to_public_key()
devuelve la clave pública en formato hexadecimal.
A continuación, generamos la dirección SegWit utilizando la clave pública.
# Función para generar la dirección P2WPKH (SegWit) con formato Bech32
def public_key_to_p2wpkh_bech32(public_key):
sha256 = hashlib.sha256(bytes.fromhex(public_key)).digest()
ripemd160 = RIPEMD160.new(sha256).digest()
return bech32.encode('bc', 0, ripemd160)
# Generación de la dirección SegWit
p2wpkh_bech32_address = public_key_to_p2wpkh_bech32(public_key)
print(f"Dirección P2WPKH (SegWit) con formato Bech32: {p2wpkh_bech32_address}")
Explicación: En esta parte, generamos una dirección SegWit utilizando la clave pública generada en el paso anterior. Primero, aplicamos un hash SHA-256 a la clave pública y luego un hash RIPEMD-160 al resultado del SHA-256. Este proceso de doble hashing es estándar en Bitcoin para crear direcciones. Finalmente, la dirección se codifica en formato Bech32, que es específico para direcciones SegWit. Este formato incluye el prefijo bc1q
, indicando que es una dirección SegWit.
Genera una clave privada: Una secuencia de 256 bits generada aleatoriamente.
Convierte la clave privada a formato hexadecimal: Para facilitar su manejo.
Deriva la clave pública: Utilizando la curva elíptica SECP256k1.
Genera la dirección SegWit (P2WPKH): Aplicando una doble función hash (SHA-256 y RIPEMD-160) sobre la clave pública y codificando el resultado en formato Bech32.
Imprime la dirección final: La dirección que un usuario de Bitcoin puede utilizar para recibir pagos.
Conclusión
Generar una clave pública en Bitcoin es un proceso que comienza con la creación de una clave privada aleatoria y luego se aplica criptografía de curva elíptica para obtener la clave pública. La seguridad de tus bitcoins depende de mantener la clave privada en secreto, mientras que la clave pública puede compartirse libremente. Con los ejemplos en Python proporcionados, podes experimentar generando tus propias claves y comprender mejor el proceso subyacente que protege la red de Bitcoin. Este es un aspecto fundamental para cualquiera que desee adentrarse en el mundo de Bitcoin y la criptografía.
Dejamos aquí un Colab con el código completo explicado paso a paso: