Signaturüberprüfung in Python

Beim Versuch zu implementieren OP_CHECKSIG, kann ich nicht herausfinden, wie die eigentliche Signaturüberprüfung in Python (python3) durchgeführt wird.

Ich habe die Signatur, den öffentlichen Schlüssel und den gehashten Message Digest einer Transaktion erhalten und möchte jetzt die Signatur verifizieren.

message = '692678553d1b85ccf87d4d4443095f276cdf600f2bb7dd44f6effbd7458fd4c2'
pubkey = '042e930f39ba62c6534ee98ed20ca98959d34aa9e057cda01cfd422c6bab3667b76426529382c23f42b9b08d7832d4fee1d6b437a8526e59667ce9c4e9dcebcabb'
signature = '30450221009908144ca6539e09512b9295c8a27050d478fbb96f8addbc3d075544dc41328702201aa528be2b907d316d2da068dd9eb1e23243d97e444d59290d2fddf25269ee0e'

Da python-ecdsafür die Erstellung des Verifizierungsschlüssels 64 Byte Eingabe benötigt werden, habe ich das erste Byte selbst entfernt.

pubkey = pubkey[2:]

Ich habe auch rund saus der DER-codierten Signatur extrahiert und diese verkettet, um nach python-ecdsaBedarf eine 64-Byte-Signatur zu erstellen.

r = '9908144ca6539e09512b9295c8a27050d478fbb96f8addbc3d075544dc413287'
s = '1aa528be2b907d316d2da068dd9eb1e23243d97e444d59290d2fddf25269ee0e'
sig = r + s

Wenn ich jedoch versuche, die Nachricht zu überprüfen, erhalte ich eine BadSignatureErrorMeldung, dass die Überprüfung fehlgeschlagen ist.

from ecdsa import VerifyingKey, SECP256k1
vk = VerifyingKey.from_string(bytes.fromhex(pubkey), curve=SECP256k1)
vk.verify(bytes.fromhex(sig), bytes.fromhex(message))

Ich suche nach einer Möglichkeit, Signaturen zu überprüfen, die ich aus Bitcoin-Transaktionen extrahiert habe.

Danke schön.

Antworten (1)

Die Funktionsweise VerifyingKeybesteht darin, dass die Nachricht tatsächlich gehasht wird, bevor sie überprüft wird. Der Standard-Hashing-Algorithmus ist sha1, also müssen Sie ihn angeben, sha256da Bitcoin diesen verwendet. Außerdem übergeben Sie ihm die vollständig gehashte Nachricht. Was Sie tun müssen, ist den Schritt vor dem Hashen der Nachricht zu übergeben. Da Bitcoin SHA256 Double verwendet, müssen Sie ihm das Ergebnis des ersten SHA256-Hashs geben und ihn den zweiten SHA256-Hash selbst generieren lassen.

So sollte Ihre Botschaft eigentlich sein

083867478cb0d1d8bb864175bbc49728cffcc114bc2e762c6df64f2c965a9a66

und Ihr Bestätigungsaufruf sollte so aussehen

vk.verify(bytes.fromhex(sig), bytes.fromhex(message), hashlib.sha256)
Das hat funktioniert. Ich dachte immer, mein Fehler liege irgendwo im Bitcoin-Teil, aber es stellte sich heraus, dass er im ecdsa-Teil lag. Danke schön.