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)
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 02
am Anfang des komprimierten Werts zeigt an, dass der Y-Wert gerade sein sollte. 03
würde den ungeraden Wert anzeigen. Das 04
am Anfang des unkomprimierten Werts zeigt an, dass sowohl der X- als auch der Y-Wert folgen. Deshalb 0F031CA83F3FB372BD6C2430119E0B947CF059D19CDEA98F4CEFFEF620C584F9
ist 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 = 0F031CA83F3FB372BD6C2430119E0B947CF059D19CDEA98F4CEFFEF620C584F9
auf 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.
skaht