Creé una nueva billetera Electrum, y aquí hay una dirección:
1JkZLnmFfpVFLT2ZMtKzc6BuXMdmY41EHA
Al hacer clic derecho sobre él, elijo "Clave privada", que da:
Kzuucz58MiTbbedeVuqBaPYwG1TQrV3n2NYU2dJRZ7HEHnHsUXWx
Ahora quiero poder (aprender cómo funciona) pasar de esta clave privada a la dirección, a través de la multiplicación de curvas elípticas.
Esto es lo que probé:
import bitcoin #pybitcointools
import base58
import binascii
pvt = 'Kzuucz58MiTbbedeVuqBaPYwG1TQrV3n2NYU2dJRZ7HEHnHsUXWx'
pvtdecoded = base58.b58decode(pvt)
pvthex = binascii.hexlify(pvtdecoded)[2:-8] # remove the first initial byte for version and 4 final bytes for checksum
pvt2 = bitcoin.decode_privkey(pvthex, 'hex') # decode as a decimal
# generate pubkey from pvtkey with elliptic curve multiplication
public_key = bitcoin.fast_multiply(bitcoin.G, pvt2)
addr = bitcoin.pubkey_to_address(public_key)
print addr
que da: 1LNSuE4NKHTyHygeKwnU1equ7MjPMhayxB
que no es la dirección original.
¿Qué ocurre? ¿Cómo recuperar la dirección original ( 1JkZLnmFfpVFLT2ZMtKzc6BuXMdmY41EHA
) de la clave privada usando la multiplicación de curva elíptica?
Editar : como Kz....Wx
la clave privada parece una comprimida con WIF, traté de reemplazar:
pvt2 = bitcoin.decode_privkey(pvthex, 'hex') # decode as a decimal
por
pvt2 = bitcoin.decode_privkey('Kzuucz58MiTbbedeVuqBaPYwG1TQrV3n2NYU2dJRZ7HEHnHsUXWx', 'wif')
pero luego, después de la multiplicación de la curva elíptica, da otra dirección, ¡que todavía no es la buena! ( 18dFF3EQoPxR44TygdGxHPMe3LSLFeQe4U
)
En ambos casos, no está generando la dirección que corresponde a la clave pública comprimida.
En el primer caso, está creando lo que parece ser una dirección no válida. Como mínimo, la clave privada que está utilizando es incorrecta porque tiene el byte de compresión. Esto cambiará el valor que obtiene para la clave privada cuando se decodifica. Para obtener el mismo resultado que en el segundo caso, deberá eliminar un byte adicional de la clave WIF decodificada, ya que ese byte especifica la compresión. La clave que está utilizando allí tiene 33 bytes en lugar de los 32 bytes de las claves privadas reales.
En el segundo caso, no está creando la clave pública comprimida para generar la dirección. Todavía está usando la clave pública sin comprimir. En lugar de usar fast_multiply
y crear la clave pública usted mismo, debería usar privkey_to_pubkey
. fast_multiply
es una operación matemática, no tiene concepto de claves públicas comprimidas. Sin embargo privkey_to_pubkey
, si lo hace, creará la clave pública adecuada. Luego puede usar esa clave pública para generar la dirección.
en lugar de hacer
public_key = bitcoin.fast_multiply(bitcoin.G, pvt2)
deberías estar haciendo
public_key = bitcoin.privkey_to_pubkey(pvt)
fast_multiply
?public_key = bitcoin.privkey_to_pubkey(pvt2)
pero sigo recibiendo 18dFF3EQoPxR44TygdGxHPMe3LSLFeQe4U
en lugar de la dirección original 1JkZLnmFfpVFLT2ZMtKzc6BuXMdmY41EHA
. ¿Qué puede estar mal?pybitcointools
, no necesita decodificar la clave privada cuando usa privkey_to_pubkey
. Más bien, es decodificado para usted por esa función en sí. Actualizaré mi respuesta con el código correcto.1JkZLnmFfpVFLT2ZMtKzc6BuXMdmY41EHA
como salida :)Según la sugerencia de use de la respuesta aceptada privkey_to_pubkey
, analicé su código, y esto también funciona:
pvt = 'Kzuucz58MiTbbedeVuqBaPYwG1TQrV3n2NYU2dJRZ7HEHnHsUXWx'
pvtdecoded = base58.b58decode(pvt)
pvthex = binascii.hexlify(pvtdecoded)[2:-10] # remove the first initial byte for version and 4 final bytes for checksum
pvt2 = bitcoin.decode_privkey(pvthex, 'hex') # decode as a decimal
# generate pubkey from pvtkey with elliptic curve multiplication
public_key = bitcoin.fast_multiply(bitcoin.G, pvt2)
public_key = bitcoin.encode_pubkey(public_key, 'hex_compressed')
addr = bitcoin.pubkey_to_address(public_key)
print addr # 1JkZLnmFfpVFLT2ZMtKzc6BuXMdmY41EHA
bajo
WIF to private key
, pero todavía estoy atascado.