def map_to_curve(x, P=curve_secp256k1.p()):
    """
        Maps an integer to an elliptic curve.


        PARAMS
        ------
            x: (int) number to be mapped into E.

            P: (ecdsa.curves.curve_secp256k1.p) Modulo for elliptic curve.

        RETURNS
        -------
            (ecdsa.ellipticcurve.Point) Point in Curve
    """
    x = x - 1
    found = False

    while not found:
        x = x + 1
        alpha = (((pow(x, 3, P) +
                   (curve_secp256k1.a() * x))) + curve_secp256k1.b()) % P
        try:
            beta = numbertheory.square_root_mod_prime(alpha, P)
            if [beta % 2 == 0] != [x % 2 != 0]:
                y = beta
            else:
                y = P - beta
            found = True
        except Exception as e:
            pass

    return ecdsa.ellipticcurve.Point(curve_secp256k1, x, y)
Esempio n. 2
0
def verifying_key_from_hex(key: bytes):
    """Load the VerifyingKey from a compressed or uncompressed hex public key.
    """
    id_byte = key[0]
    if not isinstance(id_byte, int):
        id_byte = ord(id_byte)
    if id_byte == 4:
        # Uncompressed public point
        # 1B ID + 32B x coord + 32B y coord = 65 B
        if len(key) != 65:
            raise Exception("Invalid key length")
        return create_verifying_key(int(hexlify(key[1:33]), 16),
                                    int(hexlify(key[33:]), 16))
    elif id_byte in [2, 3]:
        # Compressed public point
        if len(key) != 33:
            raise Exception("Invalid key length")
        y_odd = bool(id_byte & 0x01)  # 0 even, 1 odd
        x = int(hexlify(key[1:]), 16)
        # The following x-to-pair algorithm was lifted from pycoin
        # I still need to sit down an understand it. It is also described
        # in http://www.secg.org/collateral/sec1_final.pdf
        curve = SECP256k1.curve
        p = curve.p()
        # For SECP256k1, curve.a() is 0 and curve.b() is 7, so this is
        # effectively (x ** 3 + 7) % p, but the full equation is kept
        # for just-in-case-the-curve-is-broken future-proofing
        alpha = (pow(x, 3, p) + curve.a() * x + curve.b()) % p
        beta = square_root_mod_prime(alpha, p)
        y_even = not y_odd
        if y_even == bool(beta & 1):
            return create_verifying_key(x, p - beta)
        else:
            return create_verifying_key(x, beta)
    raise Exception("The given key is not in a known format.")
Esempio n. 3
0
def extract_coordinates(g, curve):
    """
    Return the coordinates x and y as integers,
    regardless of the point format of string g.
    Second expected parameter is a CurveFp.
    """
    p = curve.p()
    point_format = g[0]
    point = g[1:]
    if point_format == '\x04':
        point_len = len(point)
        if point_len % 2 != 0:
            raise Exception("Point length is not even.")
        x_bytes = point[:point_len >> 1]
        x = pkcs_os2ip(x_bytes) % p
        y_bytes = point[point_len >> 1:]
        y = pkcs_os2ip(y_bytes) % p
    elif point_format in ['\x02', '\x03']:
        x_bytes = point
        x = pkcs_os2ip(x_bytes) % p
        # perform the y coordinate computation with self.tls_ec
        y_square = (x * x * x + curve.a() * x + curve.b()) % p
        y = square_root_mod_prime(y_square, p)
        y_parity = ord(point_format) % 2    # \x02 means even, \x03 means odd
        if y % 2 != y_parity:
            y = -y % p
    else:
        raise Exception("Point starts with %s. This encoding "
                        "is not recognized." % repr(point_format))
    if not curve.contains_point(x, y):
        raise Exception("The point we extracted does not belong on the curve!")
    return x, y
Esempio n. 4
0
def uncompress_public_key(public_key):
    """
    Uncompress the compressed public key.

    :param public_key: compressed public key
    :return: uncompressed public key
    """
    is_even = public_key.startswith(b'\x02')
    x = string_to_number(public_key[1:])

    curve = ecdsa.NIST256p.curve
    order = ecdsa.NIST256p.order
    p = curve.p()
    alpha = (pow(x, 3, p) + (curve.a() * x) + curve.b()) % p

    beta = square_root_mod_prime(alpha, p)

    if is_even == bool(beta & 1):
        y = p - beta
    else:
        y = beta

    point = ellipticcurve.Point(curve, x, y, order)
    from ecdsa.util import number_to_string
    return b''.join([
        number_to_string(point.x(), order),
        number_to_string(point.y(), order)
    ])
Esempio n. 5
0
def from_sec(string,
             curve=curves.SECP256k1,
             hashfunc=sha1,
             validate_point=True):
    """Convert a public key in SEC binary format to a verifying key."""
    # based on code from https://github.com/richardkiss/pycoin
    if string.startswith(b('\x04')):
        # uncompressed
        return VerifyingKey.from_string(string[1:], curve, hashfunc,
                                        validate_point)
    elif string.startswith(b('\x02')) or string.startswith(b('\x03')):
        # compressed
        is_even = string.startswith(b('\x02'))
        x = string_to_number(string[1:])
        order = curve.order
        p = curve.curve.p()
        alpha = (pow(x, 3, p) + (curve.curve.a() * x) + curve.curve.b()) % p
        beta = square_root_mod_prime(alpha, p)
        if is_even == bool(beta & 1):
            y = p - beta
        else:
            y = beta
        if validate_point:
            assert ecdsa.point_is_valid(curve.generator, x, y)
        point = ellipticcurve.Point(curve.curve, x, y, order)
        return VerifyingKey.from_public_point(point, curve, hashfunc)
Esempio n. 6
0
    def get_ecdsa_verifying_key(pub):
        #some shenanigans required to validate a transaction sig; see
        #python.ecdsa PR #54. This will be a lot simpler when that's merged.
        #https://github.com/warner/python-ecdsa/pull/54/files
        if not pub[0] in ["\x02", "\x03"]:
            log.debug("Invalid pubkey")
            return None
        is_even = pub.startswith('\x02')
        x = string_to_number(pub[1:])
        order = SECP256k1.order
        p = SECP256k1.curve.p()
        alpha = (pow(x, 3, p) +
                 (SECP256k1.curve.a() * x) + SECP256k1.curve.b()) % p
        beta = square_root_mod_prime(alpha, p)
        if is_even == bool(beta & 1):
            y = p - beta
        else:
            y = beta
        if not point_is_valid(SECP256k1.generator, x, y):
            return None

        point = Point(SECP256k1.curve, x, y, order)
        return VerifyingKey.from_public_point(point,
                                              SECP256k1,
                                              hashfunc=hashlib.sha256)
Esempio n. 7
0
def extract_coordinates(g, curve):
    """
    Return the coordinates x and y as integers,
    regardless of the point format of string g.
    Second expected parameter is a CurveFp.
    """
    p = curve.p()
    point_format = g[0]
    point = g[1:]
    if point_format == '\x04':
        point_len = len(point)
        if point_len % 2 != 0:
            raise Exception("Point length is not even.")
        x_bytes = point[:point_len>>1]
        x = pkcs_os2ip(x_bytes) % p
        y_bytes = point[point_len>>1:]
        y = pkcs_os2ip(y_bytes) % p
    elif point_format in ['\x02', '\x03']:
        x_bytes = point
        x = pkcs_os2ip(x_bytes) % p
        # perform the y coordinate computation with self.tls_ec
        y_square = (x*x*x + curve.a()*x + curve.b()) % p
        y = square_root_mod_prime(y_square, p)
        y_parity = ord(point_format) % 2    # \x02 means even, \x03 means odd
        if y % 2 != y_parity:
            y = -y % p
    else:
        raise Exception("Point starts with %s. This encoding "
                        "is not recognized." % repr(point_format))
    if not curve.contains_point(x, y):
        raise Exception("The point we extracted does not belong on the curve!")
    return x, y
def map_to_curve(x, P=curve_secp256k1.p()):
    """ 
        Maps an integer to an elliptic curve.
        
        Using the try and increment algorithm, not quite
        as efficient as I would like, but c'est la vie.

        PARAMS
        ------
            x: (int) number to be mapped into E.
            
            P: (ecdsa.curves.curve_secp256k1.p) Modulo for elliptic curve.

        RETURNS
        -------
            (ecdsa.ellipticcurve.Point) Point in Curve
    """
    x -= 1
    y = 0
    found = False

    while not found:
        x += 1
        f_x = (x * x * x + 7) % P

        try:
            y = numbertheory.square_root_mod_prime(f_x, P)
            found = True
        except Exception as e:
            pass

    return ecdsa.ellipticcurve.Point(curve_secp256k1, x, y)
Esempio n. 9
0
def decode_point(point, curve=BASE_CURVE):
    # See http://www.secg.org/download/aid-780/sec1-v2.pdf section 2.3.4
    elliptic_curve = curve
    order = elliptic_curve.q
    base_length = orderlen(order)

    if point[0] == 4:
        # 3
        x_str = point[1:base_length + 1]
        y_str = point[base_length + 1:]
        return Point(string_to_number(x_str),
                     string_to_number(y_str),
                     curve=elliptic_curve)
    else:
        # 2.3
        if point[0] == 2:
            yp = 0
        elif point[0] == 3:
            yp = 1
        else:
            return None
        # 2.2
        x_str = point[1:base_length + 1]
        x = string_to_number(x_str)
        # 2.4.1
        alpha = ((x * x * x) +
                 (elliptic_curve.a * x) + elliptic_curve.b) % elliptic_curve.p
        beta = numbertheory.square_root_mod_prime(alpha, elliptic_curve.p)
        if (beta - yp) % 2 == 0:
            y = beta
        else:
            y = elliptic_curve.p - beta

    return Point(x, y, curve=elliptic_curve)
Esempio n. 10
0
File: e.py Progetto: bcpki/bitcoin
def pubkey2point(pubkey):
  x = int(tohex(pubkey)[2:],16)
  fx = (x * x * x + C.a() * x + C.b()) % C.p()
  y = numbertheory.square_root_mod_prime(fx,C.p())
  P = ellipticcurve.Point(C,x,y)
  if point2pubkey(P) != toraw(pubkey):
      P = ellipticcurve.Point(C,x,C.p()-y)
  return P
Esempio n. 11
0
def point_decompress(curve, data):
    prefix = data[0]
    assert (prefix in ['\x02', '\x03'])
    parity = 1 if prefix == '\x02' else -1

    x = util.string_to_number(data[1:])

    y = numbertheory.square_root_mod_prime(
        (x * x * x + curve.a() * x + curve.b()) % curve.p(), curve.p())

    y = parity * y % curve.p()
    return ellipticcurve.Point(curve, x, y)
Esempio n. 12
0
def point_decompress(curve, data):
	prefix = data[0]
	assert(prefix in ['\x02', '\x03'])
	parity = 1 if prefix == '\x02' else -1

	x = util.string_to_number(data[1:])

	y = numbertheory.square_root_mod_prime( 
	  ( x * x * x + curve.a() * x + curve.b() ) % curve.p(),  curve.p()
	)

	y = parity * y % curve.p()
	return ellipticcurve.Point(curve, x, y)
Esempio n. 13
0
    def from_hex_key(cls, key, network=BitcoinMainNet):
        """Load the PublicKey from a compressed or uncompressed hex key.

        This format is defined in PublicKey.get_key()
        """
        if len(key) == 130 or len(key) == 66:
            # It might be a hexlified byte array
            try:
                key = unhexlify(ensure_bytes(key))
            except (TypeError, binascii.Error):
                pass
        key = ensure_bytes(key)

        compressed = False
        id_byte = key[0]
        if not isinstance(id_byte, six.integer_types):
            id_byte = ord(id_byte)
        if id_byte == 4:
            # Uncompressed public point
            # 1B ID + 32B x coord + 32B y coord = 65 B
            if len(key) != 65:
                raise KeyParseError("Invalid key length")
            public_pair = PublicPair(long_or_int(hexlify(key[1:33]), 16),
                                     long_or_int(hexlify(key[33:]), 16))
        elif id_byte in [2, 3]:
            # Compressed public point!
            compressed = True
            if len(key) != 33:
                raise KeyParseError("Invalid key length")
            y_odd = bool(id_byte & 0x01)  # 0 even, 1 odd
            x = long_or_int(hexlify(key[1:]), 16)
            # The following x-to-pair algorithm was lifted from pycoin
            # I still need to sit down an understand it. It is also described
            # in http://www.secg.org/collateral/sec1_final.pdf
            curve = SECP256k1.curve
            p = curve.p()
            # For SECP256k1, curve.a() is 0 and curve.b() is 7, so this is
            # effectively (x ** 3 + 7) % p, but the full equation is kept
            # for just-in-case-the-curve-is-broken future-proofing
            alpha = (pow(x, 3, p) + curve.a() * x + curve.b()) % p
            beta = square_root_mod_prime(alpha, p)
            y_even = not y_odd
            if y_even == bool(beta & 1):
                public_pair = PublicPair(x, p - beta)
            else:
                public_pair = PublicPair(x, beta)
        else:
            raise KeyParseError("The given key is not in a known format.")
        return cls.from_public_pair(public_pair,
                                    network=network,
                                    compressed=compressed)
Esempio n. 14
0
    def from_hex_key(cls, key, network=BitcoinMainNet):
        """Load the PublicKey from a compressed or uncompressed hex key.

        This format is defined in PublicKey.get_key()
        """
        if len(key) == 130 or len(key) == 66:
            # It might be a hexlified byte array
            try:
                key = unhexlify(ensure_bytes(key))
            except (TypeError, binascii.Error):
                pass
        key = ensure_bytes(key)

        compressed = False
        id_byte = key[0]
        if not isinstance(id_byte, six.integer_types):
            id_byte = ord(id_byte)
        if id_byte == 4:
            # Uncompressed public point
            # 1B ID + 32B x coord + 32B y coord = 65 B
            if len(key) != 65:
                raise KeyParseError("Invalid key length")
            public_pair = PublicPair(
                long_or_int(hexlify(key[1:33]), 16),
                long_or_int(hexlify(key[33:]), 16))
        elif id_byte in [2, 3]:
            # Compressed public point!
            compressed = True
            if len(key) != 33:
                raise KeyParseError("Invalid key length")
            y_odd = bool(id_byte & 0x01)  # 0 even, 1 odd
            x = long_or_int(hexlify(key[1:]), 16)
            # The following x-to-pair algorithm was lifted from pycoin
            # I still need to sit down an understand it. It is also described
            # in http://www.secg.org/collateral/sec1_final.pdf
            curve = SECP256k1.curve
            p = curve.p()
            # For SECP256k1, curve.a() is 0 and curve.b() is 7, so this is
            # effectively (x ** 3 + 7) % p, but the full equation is kept
            # for just-in-case-the-curve-is-broken future-proofing
            alpha = (pow(x, 3, p) + curve.a() * x + curve.b()) % p
            beta = square_root_mod_prime(alpha, p)
            y_even = not y_odd
            if y_even == bool(beta & 1):
                public_pair = PublicPair(x, p - beta)
            else:
                public_pair = PublicPair(x, beta)
        else:
            raise KeyParseError("The given key is not in a known format.")
        return cls.from_public_pair(public_pair, network=network,
                                    compressed=compressed)
Esempio n. 15
0
def point_decompress(curve, data):
	prefix = data[0]
	assert(prefix in ['\x02', '\x03'])
	is_even = prefix == '\x02'

	x = util.string_to_number(data[1:])

	y = numbertheory.square_root_mod_prime( 
	  ( x * x * x + curve.a() * x + curve.b() ) % curve.p(),  curve.p()
	)
	
	if is_even == bool(y & 1):
		return ellipticcurve.Point(curve, x, curve.p() - y)

	return ellipticcurve.Point(curve, x, y)
Esempio n. 16
0
    def from_bytes(cls, data: bytes):
        """ Generates either a HDPublicKey from the underlying bytes.

        The serialization must conform to the description in:
        https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#serialization-format
        """
        if len(data) < 78:
            raise ValueError("b must be at least 78 bytes long.")

        version = int.from_bytes(data[:4], 'big')
        depth = data[4]
        parent_fingerprint = data[5:9]
        index = int.from_bytes(data[9:13], 'big')
        chain_code = data[13:45]
        key_bytes = data[45:78]

        if version != HDPublicKey.__VERSION:
            raise ValueError('invalid HD Public Key.')

        if key_bytes[0] != 0x02 and key_bytes[0] != 0x03:
            raise ValueError("First byte of public key must be 0x02 or 0x03!")

        # The curve of points satisfying y^2 = x^3 + a*x + b (mod p).
        curve = ecdsa.curve_256
        x = util.string_to_number(key_bytes[1:])
        y = (x * x * x + curve.a() * x + curve.b()) % curve.p()
        y = numbertheory.square_root_mod_prime(y, curve.p())
        if (key_bytes[0] == 0x03 and y % 2 == 0) or (key_bytes[0] == 0x02
                                                     and y % 2 != 0):
            y = (y * -1) % curve.p()
        order = curves.NIST256p.order
        s_key = util.number_to_string(x, order) + util.number_to_string(
            y, order)

        public_key = VerifyingKey.from_string(string=s_key,
                                              curve=curves.NIST256p)
        rv = cls(public_key=public_key,
                 chain_code=chain_code,
                 index=index,
                 depth=depth,
                 parent_fingerprint=parent_fingerprint)
        return rv
Esempio n. 17
0
def from_sec(string, curve=curves.SECP256k1, hashfunc=sha1, validate_point=True):
    """Convert a public key in SEC binary format to a verifying key."""
    # based on code from https://github.com/richardkiss/pycoin
    if string.startswith(b("\x04")):
        # uncompressed
        return VerifyingKey.from_string(string[1:], curve, hashfunc, validate_point)
    elif string.startswith(b("\x02")) or string.startswith(b("\x03")):
        # compressed
        is_even = string.startswith(b("\x02"))
        x = string_to_number(string[1:])
        order = curve.order
        p = curve.curve.p()
        alpha = (pow(x, 3, p) + (curve.curve.a() * x) + curve.curve.b()) % p
        beta = square_root_mod_prime(alpha, p)
        if is_even == bool(beta & 1):
            y = p - beta
        else:
            y = beta
        if validate_point:
            assert ecdsa.point_is_valid(curve.generator, x, y)
        point = ellipticcurve.Point(curve.curve, x, y, order)
        return VerifyingKey.from_public_point(point, curve, hashfunc)
Esempio n. 18
0
def uncompress(string: bytes, curve=SECP256k1) -> Point:
    if string[:1] not in (b'\x02', b'\x03'):
        raise MalformedPoint("Malformed compressed point encoding")
            
    is_even = string[:1] == b'\x02'
    x = string_to_number(string[1:])
    order = curve.order
    p = curve.curve.p()
    alpha = (pow(x, 3, p) + (curve.curve.a() * x) + curve.curve.b()) % p
    try:
        beta = square_root_mod_prime(alpha, p)
    except SquareRootError as e:
        raise MalformedPoint(
            "Encoding does not correspond to a point on curve", e
        )                                 
    if is_even == bool(beta & 1):
        y = p - beta
    else:
        y = beta
    if not ecdsa.point_is_valid(curve.generator, x, y):
        raise MalformedPoint("Point does not lie on curve")
    return point_to_pubkey_bytes(Point(curve.curve, x, y, order))
Esempio n. 19
0
    def _verifying_key_from_pubkey(cls, pubkey):
        """ Converts a 33-byte compressed pubkey into an ecdsa.VerifyingKey object. """
        if not isinstance(pubkey, (bytes, bytearray)):
            raise TypeError('pubkey must be raw bytes')
        if len(pubkey) != 33:
            raise ValueError('pubkey must be 33 bytes')
        if pubkey[0] not in (2, 3):
            raise ValueError('invalid pubkey prefix byte')
        curve = cls.CURVE.curve

        is_odd = pubkey[0] == 3
        x = bytes_to_int(pubkey[1:])

        # p is the finite field order
        a, b, p = curve.a(), curve.b(), curve.p()  # pylint: disable=invalid-name
        y2 = pow(x, 3, p) + b  # pylint: disable=invalid-name
        assert a == 0  # Otherwise y2 += a * pow(x, 2, p)
        y = NT.square_root_mod_prime(y2 % p, p)
        if bool(y & 1) != is_odd:
            y = p - y
        point = EC.Point(curve, x, y)

        return ecdsa.VerifyingKey.from_public_point(point, curve=cls.CURVE)
Esempio n. 20
0
 def get_ecdsa_verifying_key(pub):
     #some shenanigans required to validate a transaction sig; see
     #python.ecdsa PR #54. This will be a lot simpler when that's merged.
     #https://github.com/warner/python-ecdsa/pull/54/files
     if not pub[0] in ["\x02", "\x03"]:
         log.debug("Invalid pubkey")
         return None    
     is_even = pub.startswith('\x02')
     x = string_to_number(pub[1:])
     order = SECP256k1.order
     p = SECP256k1.curve.p()
     alpha = (pow(x, 3, p) + (SECP256k1.curve.a() * x) + SECP256k1.curve.b()) % p
     beta = square_root_mod_prime(alpha, p)
     if is_even == bool(beta & 1):
         y = p - beta
     else:
         y = beta
     if not point_is_valid(SECP256k1.generator, x, y):
         return None
     
     point = Point(SECP256k1.curve, x, y, order)
     return VerifyingKey.from_public_point(point, SECP256k1,
                                                hashfunc=hashlib.sha256)
Esempio n. 21
0
def curve25519_x_to_y(x):
    t = (x**3 + CURVE_A * x**2 + x) % CURVE_P
    try:
        return square_root_mod_prime(t, CURVE_P)
    except SquareRootError:
        return None
Esempio n. 22
0
 def _curve25519_x_to_y(self, x):
     t = (x ** 3 + self.CURVE_A * x ** 2 + x) % self.CURVE_P
     try:
         return square_root_mod_prime( t, self.CURVE_P)
     except SquareRootError:
         return None
Esempio n. 23
0
def curve25519_x_to_y(x):
    t = (x ** 3 + CURVE_A * x ** 2 + x) % CURVE_P
    try:
        return square_root_mod_prime(t, CURVE_P)
    except SquareRootError:
        return None