Aus Electrum exportierter privater Schlüssel, Adresse kann nicht mit Python neu erstellt werden

Ich habe eine neue Electrum-Brieftasche erstellt, und hier ist eine Adresse:

1JkZLnmFfpVFLT2ZMtKzc6BuXMdmY41EHA

Durch einen Rechtsklick darauf wähle ich "Privater Schlüssel", was Folgendes ergibt:

Kzuucz58MiTbbedeVuqBaPYwG1TQrV3n2NYU2dJRZ7HEHnHsUXWx

Jetzt möchte ich in der Lage sein (um zu lernen, wie es funktioniert), von diesem privaten Schlüssel über die Multiplikation mit elliptischen Kurven zur Adresse zu gelangen.

Folgendes habe ich versucht:

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

was ergibt: 1LNSuE4NKHTyHygeKwnU1equ7MjPMhayxBdas ist nicht die ursprüngliche Adresse.

Was ist falsch? Wie stellt man die ursprüngliche Adresse ( 1JkZLnmFfpVFLT2ZMtKzc6BuXMdmY41EHA) aus dem privaten Schlüssel wieder her, indem man die Multiplikation mit elliptischen Kurven verwendet?


Bearbeiten : Da Kz....Wxder private Schlüssel wie ein WIF-komprimierter aussieht, habe ich versucht zu ersetzen:

pvt2 = bitcoin.decode_privkey(pvthex, 'hex')    # decode as a decimal

von

pvt2 = bitcoin.decode_privkey('Kzuucz58MiTbbedeVuqBaPYwG1TQrV3n2NYU2dJRZ7HEHnHsUXWx', 'wif')

aber nach der Multiplikation der elliptischen Kurve gibt es eine andere Adresse, die immer noch nicht die gute ist! ( 18dFF3EQoPxR44TygdGxHPMe3LSLFeQe4U)

Hinweis: Ich habe en.bitcoin.it/wiki/Wallet_import_format und gelesen WIF to private key, aber ich stecke immer noch fest.

Antworten (2)

In beiden Fällen generieren Sie nicht die Adresse, die dem komprimierten öffentlichen Schlüssel entspricht.

Im ersten Fall erstellen Sie scheinbar eine ungültige Adresse. Zumindest ist der verwendete private Schlüssel falsch, da er das Komprimierungsbyte enthält. Dadurch ändert sich der Wert, den Sie für den privaten Schlüssel erhalten, wenn er dekodiert wird. Um das gleiche Ergebnis wie im zweiten Fall zu erzielen, müssten Sie ein zusätzliches Byte aus dem decodierten WIF-Schlüssel löschen, da dieses Byte die Komprimierung angibt. Der Schlüssel, den Sie dort verwenden, ist 33 Bytes groß und nicht die 32 Bytes für tatsächliche private Schlüssel.

Im zweiten Fall erstellen Sie den komprimierten öffentlichen Schlüssel nicht, um die Adresse zu generieren. Es verwendet immer noch den unkomprimierten öffentlichen Schlüssel. Anstatt fast_multiplyden öffentlichen Schlüssel selbst zu verwenden und zu erstellen, sollten Sie privkey_to_pubkey. fast_multiplyeine mathematische Operation ist, hat sie kein Konzept von komprimierten öffentlichen Schlüsseln. Allerdings privkey_to_pubkeywird dadurch der richtige öffentliche Schlüssel erstellt. Dann können Sie diesen öffentlichen Schlüssel verwenden, um die Adresse zu generieren.

Anstatt zu tun

public_key = bitcoin.fast_multiply(bitcoin.G, pvt2)

du solltest tun

public_key = bitcoin.privkey_to_pubkey(pvt)
Danke für deine hilfreiche Antwort. Warum kann ich in Bezug auf Ihren letzten Absatz keine elliptische Kurvenmultiplikation verwenden (es sollte eine unter der Haube geben, selbst im komprimierten Fall, oder?)? Könnten Sie auch einfach (für zukünftige Referenzen und um sicherzugehen) die Codezeile posten, die wir anstelle von verwenden sollten fast_multiply?
Weil die Komprimierung unabhängig von den Elliptischen-Kurven-Operationen erfolgt. Operationen mit elliptischen Kurven wissen nicht, was Punktkompression ist; sie können nur auf der vollen Kurve arbeiten. Bibliotheken können jedoch Punktkomprimierung verwenden, und dies muss getrennt von den EC-Operationen geschehen.
Danke @AndrewChow. Ich habe es mit versucht public_key = bitcoin.privkey_to_pubkey(pvt2), aber ich bekomme immer noch 18dFF3EQoPxR44TygdGxHPMe3LSLFeQe4Ustatt der ursprünglichen Adresse 1JkZLnmFfpVFLT2ZMtKzc6BuXMdmY41EHA. Was kann falsch sein?
Wenn Sie sich die Implementierung ansehen pybitcointools, müssen Sie den privaten Schlüssel nicht entschlüsseln, wenn Sie verwenden privkey_to_pubkey. Vielmehr wird es von dieser Funktion selbst für Sie dekodiert. Ich werde meine Antwort mit dem richtigen Code aktualisieren.
Vielen Dank! Ich habe Mühe, 1JkZLnmFfpVFLT2ZMtKzc6BuXMdmY41EHAals Ausgabe zu kommen :)
Hast du es mit der neusten Bearbeitung versucht?

Basierend auf dem Vorschlag der akzeptierten Antwort, privkey_to_pubkey, habe ich den Code analysiert, und so funktioniert es auch:

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