Exemple #1
0
    def to_bytes(self):
        """TODO"""

        public_numbers = self.key.public_numbers()
        key_size = tools.elliptic_curve_key_size(self.network.curve)

        prefix = SEC1_MAGIC_NOT_COMPRESSED

        if self.compressed:
            if public_numbers.y % 2 == 0:
                prefix = SEC1_MAGIC_COMPRESSED_0
            else:
                prefix = SEC1_MAGIC_COMPRESSED_1

        data = bytearray()
        data.append(prefix)

        x = encoding.i2b_bigendian(public_numbers.x, key_size)
        data.extend(x)

        if not self.compressed:
            y = encoding.i2b_bigendian(public_numbers.y, key_size)
            data.extend(y)

        return bytes(data)
Exemple #2
0
    def to_bytes(self):
        """TODO"""

        public_numbers = self.key.public_numbers()
        key_size = tools.elliptic_curve_key_size(self.network.curve)

        prefix = SEC1_MAGIC_NOT_COMPRESSED

        if self.compressed:
            if public_numbers.y % 2 == 0:
                prefix = SEC1_MAGIC_COMPRESSED_0
            else:
                prefix = SEC1_MAGIC_COMPRESSED_1

        data = bytearray()
        data.append(prefix)

        x = encoding.i2b_bigendian(public_numbers.x, key_size)
        data.extend(x)

        if not self.compressed:
            y = encoding.i2b_bigendian(public_numbers.y, key_size)
            data.extend(y)

        return bytes(data)
Exemple #3
0
    def to_bytes(self):
        """TODO"""

        key_size = tools.elliptic_curve_key_size(self.network.curve)

        exponent = self.key.private_numbers().private_value

        return encoding.i2b_bigendian(exponent, key_size)
Exemple #4
0
    def to_bytes(self):
        """TODO"""

        key_size = tools.elliptic_curve_key_size(self.network.curve)

        exponent = self.key.private_numbers().private_value

        return encoding.i2b_bigendian(exponent, key_size)
Exemple #5
0
    def from_bytes(cls,
                   data,
                   network=network.default,
                   backend=default_backend()):
        """Create a public key from its raw binary encoding (in SEC1 format).

        For more info on this format, see:

        http://www.secg.org/sec1-v2.pdf, section 2.3.4
        """

        data = bytearray(data)

        # A public key is a point (x, y) in the elliptic curve, and each
        # coordinate is represented by a unsigned integer of key_size bytes
        key_size = tools.elliptic_curve_key_size(network.curve)

        # The first byte determines whether the key is compressed
        try:
            prefix = data.pop(0)

        except IndexError:
            raise InvalidEncoding('Invalid key length (buffer is empty)')

        # If the key is compressed-encoded, only the x coordinate is present
        compressed = True if len(data) == key_size else False

        if not compressed and len(data) != 2 * key_size:
            raise InvalidEncoding('Invalid key length')

        # The first key_size bytes after the prefix are the x coordinate
        x = encoding.b2i_bigendian(bytes(data[:key_size]))

        if compressed:
            # If the key is compressed, the y coordinate should be computed

            if prefix == SEC1_MAGIC_COMPRESSED_0:
                y_parity = 0
            elif prefix == SEC1_MAGIC_COMPRESSED_1:
                y_parity = 1
            else:
                raise InvalidEncoding('Invalid prefix for compressed key')

            y = tools.ec_public_y_from_x_and_curve(x, y_parity, network.curve)
            if y is None:
                raise InvalidPoint()
        else:
            # If the key isn't compressed, the last key_size bytes are the y
            # coordinate

            if prefix != SEC1_MAGIC_NOT_COMPRESSED:
                raise InvalidEncoding('Invalid prefix for non-compressed key')

            y = encoding.b2i_bigendian(bytes(data[key_size:]))

        return cls.from_point(x, y, network, compressed, backend)
Exemple #6
0
    def from_bytes(cls, data, network=network.default, backend=default_backend()):
        """Create a public key from its raw binary encoding (in SEC1 format).

        For more info on this format, see:

        http://www.secg.org/sec1-v2.pdf, section 2.3.4
        """

        data = bytearray(data)

        # A public key is a point (x, y) in the elliptic curve, and each
        # coordinate is represented by a unsigned integer of key_size bytes
        key_size = tools.elliptic_curve_key_size(network.curve)

        # The first byte determines whether the key is compressed
        try:
            prefix = data.pop(0)

        except IndexError:
            raise InvalidEncoding('Invalid key length (buffer is empty)')

        # If the key is compressed-encoded, only the x coordinate is present
        compressed = True if len(data) == key_size else False

        if not compressed and len(data) != 2 * key_size:
            raise InvalidEncoding('Invalid key length')

        # The first key_size bytes after the prefix are the x coordinate
        x = encoding.b2i_bigendian(bytes(data[:key_size]))

        if compressed:
            # If the key is compressed, the y coordinate should be computed

            if prefix == SEC1_MAGIC_COMPRESSED_0:
                y_parity = 0
            elif prefix == SEC1_MAGIC_COMPRESSED_1:
                y_parity = 1
            else:
                raise InvalidEncoding('Invalid prefix for compressed key')

            y = tools.ec_public_y_from_x_and_curve(x, y_parity, network.curve)
            if y is None:
                raise InvalidPoint()
        else:
            # If the key isn't compressed, the last key_size bytes are the y
            # coordinate

            if prefix != SEC1_MAGIC_NOT_COMPRESSED:
                raise InvalidEncoding('Invalid prefix for non-compressed key')

            y = encoding.b2i_bigendian(bytes(data[key_size:]))

        return cls.from_point(x, y, network, compressed, backend)
Exemple #7
0
    def from_bytes(cls, data, network=network.default, compressed=True, backend=default_backend()):
        """Create a private key from its raw binary encoding (in SEC1 format).

        The input buffer should be a zero-padded big endian unsigned integer.
        For more info on this format, see:

        http://www.secg.org/sec1-v2.pdf, section 2.3.6
        """

        if len(data) != tools.elliptic_curve_key_size(network.curve):
            raise InvalidEncoding('Invalid key length')

        exponent = encoding.b2i_bigendian(data)

        try:
            return cls.from_secret_exponent(exponent, network, compressed, backend)

        except InvalidExponent as e:
            raise InvalidEncoding(e.message)
Exemple #8
0
    def from_wif(cls, wif, backend=default_backend()):
        """Create a private key from its WIF encoding.

        The Wallet Import Format encoding is used for serializing Bitcoin
        private keys. For more info on this encoding, see:

        https://en.bitcoin.it/wiki/Wallet_import_format
        """

        # A WIF private key is base58check encoded
        try:
            data = bytearray(encoding.a2b_base58check(wif))

        except encoding.Error as e:
            raise InvalidEncoding(e.message)

        # The first byte determines the network
        try:
            prefix = data.pop(0)

        except IndexError:
            raise InvalidEncoding('Invalid WIF length')

        try:
            network_ = network.Network.get_by_field('wif_prefix', prefix)

        except network.UnknownNetwork as e:
            raise InvalidEncoding(e.message)

        # If the public key should be compressed-encoded, there will be an
        # extra 1 byte at the end
        key_size = tools.elliptic_curve_key_size(network_.curve)

        compressed = True if len(data) == key_size + 1 else False

        if compressed and data[-1] == 1:
            data.pop(-1)

        # What remains should be the raw private key exponent
        return cls.from_bytes(bytes(data), network_, compressed, backend)
Exemple #9
0
    def from_wif(cls, wif, backend=default_backend()):
        """Create a private key from its WIF encoding.

        The Wallet Import Format encoding is used for serializing Bitcoin
        private keys. For more info on this encoding, see:

        https://en.bitcoin.it/wiki/Wallet_import_format
        """

        # A WIF private key is base58check encoded
        try:
            data = bytearray(encoding.a2b_base58check(wif))

        except encoding.Error as e:
            raise InvalidEncoding(e.message)

        # The first byte determines the network
        try:
            prefix = data.pop(0)

        except IndexError:
            raise InvalidEncoding('Invalid WIF length')

        try:
            network_ = network.Network.get_by_field('wif_prefix', prefix)

        except network.UnknownNetwork as e:
            raise InvalidEncoding(e.message)

        # If the public key should be compressed-encoded, there will be an
        # extra 1 byte at the end
        key_size = tools.elliptic_curve_key_size(network_.curve)

        compressed = True if len(data) == key_size + 1 else False

        if compressed and data[-1] == 1:
            data.pop(-1)

        # What remains should be the raw private key exponent
        return cls.from_bytes(bytes(data), network_, compressed, backend)
Exemple #10
0
    def from_bytes(cls,
                   data,
                   network=network.default,
                   compressed=True,
                   backend=default_backend()):
        """Create a private key from its raw binary encoding (in SEC1 format).

        The input buffer should be a zero-padded big endian unsigned integer.
        For more info on this format, see:

        http://www.secg.org/sec1-v2.pdf, section 2.3.6
        """

        if len(data) != tools.elliptic_curve_key_size(network.curve):
            raise InvalidEncoding('Invalid key length')

        exponent = encoding.b2i_bigendian(data)

        try:
            return cls.from_secret_exponent(exponent, network, compressed,
                                            backend)

        except InvalidExponent as e:
            raise InvalidEncoding(e.message)