Wie konvertiere ich den x-Wert des öffentlichen Schlüssels in Python in y und verifiziere ihn?

Ich habe das BTC-Adressdienstprogramm verwendet, mit dem ich Folgendes eingeben kann:

020F031CA83F3FB372BD6C2430119E0B947CF059D19CDEA98F4CEFFEF620C584F9

Wenn Sie dann auf eine Schaltfläche klicken, kann das Programm den Y-Wert ausspucken oder mir mitteilen, ob dieser X-Wert nicht gültig ist (dh: keinen gültigen Y-Wert hat).

Als Beispiel wäre das Ergebnis von diesem gültig und würde erweitert werden, um Folgendes zu erzeugen:

040F031CA83F3FB372BD6C2430119E0B947CF059D19CDEA98F4CEFFEF620C584F9F064F1FDE4BC07D4F48C5114680AD1ADAF5F6EAA2166F7E4B4887703A681B548

Kennt jemand den Code, um eine oder beide Funktionen in Python auszuführen? (Ob der Code hexadezimal oder dezimal ist, spielt keine Rolle)

Es ist erwähnenswert, dass die 1. Hexadezimalzahl ein „komprimierter öffentlicher Schlüssel“ und die 2. der zugehörige „unkomprimierte öffentliche Schlüssel“ ist. Ausgehend von einem gemeinsamen privaten Schlüssel ist es möglich, beide öffentlichen Schlüssel zu synthetisieren, die eng miteinander korreliert sind.

Antworten (1)

Zunächst müssen Sie verstehen, was die beiden Formate eigentlich sind. Das erste ist das komprimierte SEC-Format und das zweite das unkomprimierte SEC-Format. Der Unterschied zwischen den beiden besteht darin, dass das komprimierte Format nur den X-Wert und die Parität des Y-Werts enthält, während das unkomprimierte Format sowohl den X- als auch den Y-Wert enthält.

Das 02am Anfang des komprimierten Werts zeigt an, dass der Y-Wert gerade sein sollte. 03würde den ungeraden Wert anzeigen. Das 04am Anfang des unkomprimierten Werts zeigt an, dass sowohl der X- als auch der Y-Wert folgen. Deshalb 0F031CA83F3FB372BD6C2430119E0B947CF059D19CDEA98F4CEFFEF620C584F9ist er für beide Werte gleich.

Den Y-Wert zu bekommen, ist eigentlich gar nicht so schwer. Sie müssen ein wenig über Elliptical Curve Cryptography wissen. Insbesondere verwendet Bitcoin SECP256K1, dessen Kurve durch dargestellt wird y^2 = x^3 + 7. Dies geschieht modulo P, was in unserem Fall ist FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F. Wenn Sie also X = 0F031CA83F3FB372BD6C2430119E0B947CF059D19CDEA98F4CEFFEF620C584F9auf der linken Seite der Formel einsetzen, erhalten Sie:

(x^3 + 7) mod p = EBD56984BA6A88F5D40BB496D9A7C70AC3D8DDF5F7C287E8AABEC904E3D41DB5

Der Python-Code dafür ist ziemlich einfach:

$ python
>>> p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
>>> x = 0x0F031CA83F3FB372BD6C2430119E0B947CF059D19CDEA98F4CEFFEF620C584F9
>>> "%X" % ((x**3 + 7) % p)
'EBD56984BA6A88F5D40BB496D9A7C70AC3D8DDF5F7C287E8AABEC904E3D41DB5'

Jetzt müssen Sie die Quadratwurzel ziehen, um Y zu erhalten, was zwei Werte ergeben sollte, einen geraden und einen ungeraden (weil p ungerade ist). Dies ist eine viel kompliziertere Berechnung, die Sie hier nachlesen können: http://eli.thegreenplace.net/2009/03/07/computing-modular-square-roots-in-python

Dies ist in einer Bibliothek namens pycoin implementiert: https://github.com/richardkiss/pycoin

Du kannst es so berechnen:

>>> import pycoin
>>> from pycoin.ecdsa.numbertheory import modular_sqrt
$ python
>>> p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
>>> x = 0x0F031CA83F3FB372BD6C2430119E0B947CF059D19CDEA98F4CEFFEF620C584F9
>>> y_squared = (x**3 + 7) % p
>>> modular_sqrt(y_squared, p)
7058650705029786666096901756991264635816989543710944821299269679858359092967
>>> y = modular_sqrt(y_squared, p)
>>> "%X" % y
'F9B0E021B43F82B0B73AEEB97F52E5250A09155E99081B4B7788FB597E46E7'

Dies ist zufällig der ungerade Wert (er endet auf 7), also müssen Sie den anderen möglichen y-Wert berechnen, der einfach p - y ist

>>> "%X" % (p-y)
`F064F1FDE4BC07D4F48C5114680AD1ADAF5F6EAA2166F7E4B4887703A681B548`

Dies ist die gerade Zahl, die aus den letzten 64 Zeichen des Hexadezimalzeichens besteht, das mit beginnt 04.

Beachten Sie, dass die Adresse entweder aus dem komprimierten oder dem unkomprimierten SEC-Format berechnet wird. Diese Berechnung ist ein SHA256-Hash gefolgt von einem RIPEMD160-Hash. Dies ist nicht umkehrbar, sodass Sie das SEC-Format nicht von der Adresse erhalten können, obwohl Sie den anderen Weg gehen können.