You need to calculate in the field
, which basically means that you need to reduce your number to the remainder after dividing by p after each calculation. The calculation of this is called modulo acceptance and is written as % p in python.
The exponentiality in this field can be performed more efficiently than the naive way of simply multiplying and decreasing many times. This is called modular exponentiation. The Python built-in exponential function pow (n, e, p) can take care of this.
The rest of the problem is finding the square root. Fortunately, secp256k1 is selected in a special way (
), so itโs easy to take square roots: the square root of x is
.
Thus, a simplified version of your code will look like this:
import binascii p_hex = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F' p = int(p_hex, 16) compressed_key_hex = '0250863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B2352' x_hex = compressed_key_hex[2:66] x = int(x_hex, 16) prefix = compressed_key_hex[0:2] y_square = (pow(x, 3, p) + 7) % p y_square_square_root = pow(y_square, (p+1)/4, p) if (prefix == "02" and y_square_square_root & 1) or (prefix == "03" and not y_square_square_root & 1): y = (-y_square_square_root) % p else: y = y_square_square_root computed_y_hex = format(y, '064x') computed_uncompressed_key = "04" + x_hex + computed_y_hex print computed_uncompressed_key
Rasmus faber
source share