示例#1
0
    def __eq__(self, other):

        self_curve_nid = backend._elliptic_curve_to_nid(self.curve)
        other_curve_nid = backend._elliptic_curve_to_nid(other.curve)

        # TODO: This is not comparing the order, which currently is an OpenSSL pointer
        self_attributes = self_curve_nid, self.g, self.CURVE_KEY_SIZE_BYTES, self.u
        others_attributes = other_curve_nid, other.g, other.CURVE_KEY_SIZE_BYTES, other.u

        return self_attributes == others_attributes
示例#2
0
    def gen_rand(cls, curve: ec.EllipticCurve = None):
        """
        Returns a Point object with a cryptographically secure EC_POINT based
        on the provided curve.
        """
        curve = curve if curve is not None else default_curve()
        curve_nid = backend._elliptic_curve_to_nid(curve)

        group = backend._lib.EC_GROUP_new_by_curve_name(curve_nid)
        backend.openssl_assert(group != backend._ffi.NULL)

        generator = backend._lib.EC_GROUP_get0_generator(group)
        backend.openssl_assert(generator != backend._ffi.NULL)

        rand_point = backend._lib.EC_POINT_new(group)
        backend.openssl_assert(rand_point != backend._ffi.NULL)
        rand_point = backend._ffi.gc(rand_point,
                                     backend._lib.EC_POINT_clear_free)

        rand_bn = BigNum.gen_rand(curve).bignum

        with backend._tmp_bn_ctx() as bn_ctx:
            res = backend._lib.EC_POINT_mul(group, rand_point,
                                            backend._ffi.NULL, generator,
                                            rand_bn, bn_ctx)
            backend.openssl_assert(res == 1)

        return Point(rand_point, curve_nid, group)
示例#3
0
文件: point.py 项目: cygnusv/pyUmbral
    def from_affine(cls, coords, curve: ec.EllipticCurve = None):
        """
        Returns a Point object from the given affine coordinates in a tuple in
        the format of (x, y) and a given curve.
        """
        curve = curve if curve is not None else default_curve()
        try:
            curve_nid = backend._elliptic_curve_to_nid(curve)
        except AttributeError:
            # Presume that the user passed in the curve_nid
            curve_nid = curve

        affine_x, affine_y = coords
        if type(affine_x) == int:
            affine_x = openssl._int_to_bn(affine_x)

        if type(affine_y) == int:
            affine_y = openssl._int_to_bn(affine_y)

        group = openssl._get_ec_group_by_curve_nid(curve_nid)
        ec_point = openssl._get_EC_POINT_via_affine(affine_x,
                                                    affine_y,
                                                    ec_group=group)

        return cls(ec_point, curve_nid, group)
示例#4
0
    def gen_rand(cls, curve: ec.EllipticCurve = None):
        """
        Returns a BigNum object with a cryptographically secure BigNum based
        on the given curve.
        """
        curve = curve if curve is not None else default_curve()
        curve_nid = backend._elliptic_curve_to_nid(curve)

        group = backend._lib.EC_GROUP_new_by_curve_name(curve_nid)
        backend.openssl_assert(group != backend._ffi.NULL)

        order = backend._lib.BN_new()
        backend.openssl_assert(order != backend._ffi.NULL)
        order = backend._ffi.gc(order, backend._lib.BN_free)

        with backend._tmp_bn_ctx() as bn_ctx:
            res = backend._lib.EC_GROUP_get_order(group, order, bn_ctx)
            backend.openssl_assert(res == 1)

        order_int = backend._bn_to_int(order)

        # Generate random number on curve
        key_size = get_curve_keysize_bytes(curve)
        rand_num = int.from_bytes(os.urandom(key_size), 'big')
        while rand_num >= order_int or rand_num <= 0:
            rand_num = int.from_bytes(os.urandom(key_size), 'big')

        new_rand_bn = backend._int_to_bn(rand_num)
        new_rand_bn = backend._ffi.gc(new_rand_bn, backend._lib.BN_free)

        return cls(new_rand_bn, curve_nid, group, order)
示例#5
0
    def gen_rand(cls, curve: ec.EllipticCurve = None):
        """
        Returns a BigNum object with a cryptographically secure BigNum based
        on the given curve.
        """
        curve = curve if curve is not None else default_curve()
        curve_nid = backend._elliptic_curve_to_nid(curve)

        group = backend._lib.EC_GROUP_new_by_curve_name(curve_nid)
        backend.openssl_assert(group != backend._ffi.NULL)

        order = backend._lib.BN_new()
        backend.openssl_assert(order != backend._ffi.NULL)
        order = backend._ffi.gc(order, backend._lib.BN_clear_free)

        with backend._tmp_bn_ctx() as bn_ctx:
            res = backend._lib.EC_GROUP_get_order(group, order, bn_ctx)
            backend.openssl_assert(res == 1)

        new_rand_bn = backend._lib.BN_new()
        backend.openssl_assert(new_rand_bn != backend._ffi.NULL)
        new_rand_bn = backend._ffi.gc(new_rand_bn, backend._lib.BN_clear_free)

        rand_res = backend._lib.BN_rand_range(new_rand_bn, order)
        backend.openssl_assert(rand_res == 1)

        return cls(new_rand_bn, curve_nid, group, order)
示例#6
0
    def from_int(cls, num, curve: ec.EllipticCurve = None):
        """
        Returns a BigNum object from a given integer on a curve.
        """
        curve = curve if curve is not None else default_curve()
        try:
            curve_nid = backend._elliptic_curve_to_nid(curve)
        except AttributeError:
            # Presume that the user passed in the curve_nid
            curve_nid = curve

        group = backend._lib.EC_GROUP_new_by_curve_name(curve_nid)
        backend.openssl_assert(group != backend._ffi.NULL)

        order = backend._lib.BN_new()
        backend.openssl_assert(order != backend._ffi.NULL)
        order = backend._ffi.gc(order, backend._lib.BN_clear_free)

        with backend._tmp_bn_ctx() as bn_ctx:
            res = backend._lib.EC_GROUP_get_order(group, order, bn_ctx)
            backend.openssl_assert(res == 1)

        order_int = backend._bn_to_int(order)
        if num <= 0 or num >= order_int:
            # TODO: Handle this better maybe? Ask David.
            raise ValueError("Integer provided is not on the given curve.")

        bignum = backend._int_to_bn(num)
        bignum = backend._ffi.gc(bignum, backend._lib.BN_clear_free)

        return cls(bignum, curve_nid, group, order)
示例#7
0
    def from_affine(cls, coords, curve: ec.EllipticCurve = None):
        """
        Returns a Point object from the given affine coordinates in a tuple in
        the format of (x, y) and a given curve.
        """
        curve = curve if curve is not None else default_curve()
        try:
            curve_nid = backend._elliptic_curve_to_nid(curve)
        except AttributeError:
            # Presume that the user passed in the curve_nid
            curve_nid = curve

        affine_x, affine_y = coords
        if type(affine_x) == int:
            affine_x = backend._int_to_bn(affine_x)
            affine_x = backend._ffi.gc(affine_x, backend._lib.BN_clear_free)

        if type(affine_y) == int:
            affine_y = backend._int_to_bn(affine_y)
            affine_y = backend._ffi.gc(affine_y, backend._lib.BN_clear_free)

        group = backend._lib.EC_GROUP_new_by_curve_name(curve_nid)
        backend.openssl_assert(group != backend._ffi.NULL)

        ec_point = backend._lib.EC_POINT_new(group)
        backend.openssl_assert(ec_point != backend._ffi.NULL)

        with backend._tmp_bn_ctx() as bn_ctx:
            res = backend._lib.EC_POINT_set_affine_coordinates_GFp(
                group, ec_point, affine_x, affine_y, bn_ctx)
            backend.openssl_assert(res == 1)

        return Point(ec_point, curve_nid, group)
示例#8
0
    def get_order_from_curve(cls, curve: ec.EllipticCurve=None):
        """
        Returns the order from the given curve as a CurveBN.
        """
        curve = curve if curve is not None else default_curve()
        try:
            curve_nid = backend._elliptic_curve_to_nid(curve)
        except AttributeError:
            # Presume that the user passed in the curve_nid
            curve_nid = curve

        group = openssl._get_ec_group_by_curve_nid(curve_nid)
        order = openssl._get_ec_order_by_curve_nid(curve_nid)

        return CurveBN(order, curve_nid, group, order)
示例#9
0
    def get_generator_from_curve(cls, curve: ec.EllipticCurve=None):
        """
        Returns the generator Point from the given curve as a Point object.
        """
        curve = curve if curve is not None else default_curve()
        try:
            curve_nid = backend._elliptic_curve_to_nid(curve)
        except AttributeError:
            # Presume that the user passed in the curve_nid
            curve_nid = curve

        group = openssl._get_ec_group_by_curve_nid(curve_nid)
        generator = openssl._get_ec_generator_by_curve_nid(curve_nid)

        return cls(generator, curve_nid, group)
示例#10
0
    def __init__(self, curve: ec.EllipticCurve):
        from umbral.point import Point, unsafe_hash_to_point
        from umbral.utils import get_curve_keysize_bytes

        self.curve = curve
        curve_nid = backend._elliptic_curve_to_nid(curve)

        self.g = Point.get_generator_from_curve(self.curve)

        self.order = openssl._get_ec_order_by_curve_nid(curve_nid)

        g_bytes = self.g.to_bytes(is_compressed=True)

        self.CURVE_KEY_SIZE_BYTES = get_curve_keysize_bytes(self.curve)

        parameters_seed = b'NuCypherKMS/UmbralParameters/'
        self.u = unsafe_hash_to_point(g_bytes, self, parameters_seed + b'u')
示例#11
0
    def get_generator_from_curve(cls, curve: ec.EllipticCurve = None):
        """
        Returns the generator Point from the given curve as a Point object.
        """
        curve = curve if curve is not None else default_curve()
        try:
            curve_nid = backend._elliptic_curve_to_nid(curve)
        except AttributeError:
            # Presume that the user passed in the curve_nid
            curve_nid = curve

        group = backend._lib.EC_GROUP_new_by_curve_name(curve_nid)
        backend.openssl_assert(group != backend._ffi.NULL)

        generator = backend._lib.EC_GROUP_get0_generator(group)
        backend.openssl_assert(generator != backend._ffi.NULL)

        return cls(generator, curve_nid, group)
示例#12
0
    def hash(cls, *crypto_items, params=None):
        params = params if params is not None else default_params()

        curve_nid = backend._elliptic_curve_to_nid(params.curve)
        order = openssl._get_ec_order_by_curve_nid(curve_nid)
        group = openssl._get_ec_group_by_curve_nid(curve_nid)

        # TODO: Clean this in an upcoming cleanup of pyUmbral
        blake2b = hashes.Hash(hashes.BLAKE2b(64), backend=backend)
        for item in crypto_items:
            try:
                item_bytes = item.to_bytes()
            except AttributeError:
                if isinstance(item, bytes):
                    item_bytes = item
                else:
                    raise TypeError(
                        "{} is not acceptable type, received {}".format(
                            item, type(item)))
            blake2b.update(item_bytes)

        hash_digest = blake2b.finalize()
        hash_digest = int.from_bytes(hash_digest,
                                     byteorder='big',
                                     signed=False)
        hash_digest = openssl._int_to_bn(hash_digest)

        _1 = backend._lib.BN_value_one()

        order_minus_1 = openssl._get_new_BN()
        res = backend._lib.BN_sub(order_minus_1, order, _1)
        backend.openssl_assert(res == 1)

        bignum = openssl._get_new_BN()
        with backend._tmp_bn_ctx() as bn_ctx:
            res = backend._lib.BN_mod(bignum, hash_digest, order_minus_1,
                                      bn_ctx)
            backend.openssl_assert(res == 1)

        res = backend._lib.BN_add(bignum, bignum, _1)
        backend.openssl_assert(res == 1)

        return cls(bignum, curve_nid, group, order)
示例#13
0
    def from_int(cls, num, curve: ec.EllipticCurve = None):
        """
        Returns a CurveBN object from a given integer on a curve.
        By default, the underlying OpenSSL BIGNUM has BN_FLG_CONSTTIME set for
        constant time operations.
        """
        curve = curve if curve is not None else default_curve()
        try:
            curve_nid = backend._elliptic_curve_to_nid(curve)
        except AttributeError:
            # Presume that the user passed in the curve_nid
            curve_nid = curve

        group = openssl._get_ec_group_by_curve_nid(curve_nid)
        order = openssl._get_ec_order_by_curve_nid(curve_nid)

        conv_bn = openssl._int_to_bn(num, curve_nid)

        return cls(conv_bn, curve_nid, group, order)
示例#14
0
def CURVE_GET_ORDER(curve) -> _EllipticCurvePrivateKey:
    """
    Returns the order of the curve provided.
    This returns it as a private key to use in the above operations, if needed.
    """
    curve_nid = backend._elliptic_curve_to_nid(curve)

    group = backend._lib.EC_GROUP_new_by_curve_name(curve_nid)
    backend.openssl_assert(group != backend._ffi.NULL)

    order = backend._lib.BN_new()
    backend.openssl_assert(order != backend._ffi.NULL)
    order = backend._ffi.gc(order, backend._lib.BN_free)

    with backend._tmp_bn_ctx() as bn_ctx:
        res = backend._lib.EC_GROUP_get_order(group, order, bn_ctx)
        backend.openssl_assert(res == 1)

    return _bignum_to_private_key(backend, group, order)
示例#15
0
    def from_bytes(cls, data, curve: ec.EllipticCurve = None):
        """
        Returns a Point object from the given byte data on the curve provided.
        """
        curve = curve if curve is not None else default_curve()
        try:
            curve_nid = backend._elliptic_curve_to_nid(curve)
        except AttributeError:
            # Presume that the user passed in the curve_nid
            curve_nid = curve

        # Check if compressed
        if data[0] in [2, 3]:
            type_y = data[0] - 2

            if len(data[1:]) > get_curve_keysize_bytes(curve):
                raise ValueError("X coordinate too large for curve.")

            affine_x = BigNum.from_bytes(data[1:], curve)

            ec_point = backend._lib.EC_POINT_new(affine_x.group)
            backend.openssl_assert(ec_point != backend._ffi.NULL)
            ec_point = backend._ffi.gc(ec_point,
                                       backend._lib.EC_POINT_clear_free)

            with backend._tmp_bn_ctx() as bn_ctx:
                res = backend._lib.EC_POINT_set_compressed_coordinates_GFp(
                    affine_x.group, ec_point, affine_x.bignum, type_y, bn_ctx)
                backend.openssl_assert(res == 1)

            return cls(ec_point, curve_nid, affine_x.group)

        # Handle uncompressed point
        elif data[0] == 4:
            key_size = get_curve_keysize_bytes(curve)
            affine_x = int.from_bytes(data[1:key_size + 1], 'big')
            affine_y = int.from_bytes(data[1 + key_size:], 'big')

            return Point.from_affine((affine_x, affine_y), curve)
        else:
            raise ValueError("Invalid point serialization.")
示例#16
0
    def gen_rand(cls, curve: ec.EllipticCurve=None):
        """
        Returns a Point object with a cryptographically secure EC_POINT based
        on the provided curve.
        """
        curve = curve if curve is not None else default_curve()
        curve_nid = backend._elliptic_curve_to_nid(curve)

        group = openssl._get_ec_group_by_curve_nid(curve_nid)
        generator = openssl._get_ec_generator_by_curve_nid(curve_nid)

        rand_point = openssl._get_new_EC_POINT(ec_group=group)
        rand_bn = CurveBN.gen_rand(curve).bignum

        with backend._tmp_bn_ctx() as bn_ctx:
            res = backend._lib.EC_POINT_mul(
                group, rand_point, backend._ffi.NULL, generator, rand_bn, bn_ctx
            )
            backend.openssl_assert(res == 1)

        return Point(rand_point, curve_nid, group)
示例#17
0
def CURVE_GET_GENERATOR(curve) -> _EllipticCurvePublicKey:
    """
    Returns the generator point of the curve provided.
    This returns it as a public key to use in the above operations, if needed.
    """
    curve_nid = backend._elliptic_curve_to_nid(curve)

    group = backend._lib.EC_GROUP_new_by_curve_name(curve_nid)
    backend.openssl_assert(group != backend._ffi.NULL)

    gen_point = backend._lib.EC_POINT_new(group)
    backend.openssl_assert(gen_point != backend._ffi.NULL)
    gen_point = backend._ffi.gc(gen_point, backend._lib.EC_POINT_free)

    generator = backend._lib.EC_GROUP_get0_generator(group)
    backend.openssl_assert(generator != backend._ffi.NULL)

    res = backend._lib.EC_POINT_copy(gen_point, generator)
    backend.openssl_assert(res == 1)

    return _point_to_public_key(backend, group, generator)
示例#18
0
文件: point.py 项目: cygnusv/pyUmbral
    def from_bytes(cls, data, curve: ec.EllipticCurve = None):
        """
        Returns a Point object from the given byte data on the curve provided.
        """
        curve = curve if curve is not None else default_curve()
        try:
            curve_nid = backend._elliptic_curve_to_nid(curve)
        except AttributeError:
            # Presume that the user passed in the curve_nid
            curve_nid = curve

        compressed_size = cls.expected_bytes_length(curve)
        # Check if compressed
        if data[0] in [2, 3]:
            if len(data) != compressed_size:
                raise ValueError("X coordinate too large for curve.")

            affine_x = CurveBN.from_bytes(data[1:], curve)
            type_y = data[0] - 2

            ec_point = openssl._get_new_EC_POINT(ec_group=affine_x.group)
            with backend._tmp_bn_ctx() as bn_ctx:
                res = backend._lib.EC_POINT_set_compressed_coordinates_GFp(
                    affine_x.group, ec_point, affine_x.bignum, type_y, bn_ctx)
                backend.openssl_assert(res == 1)
            return cls(ec_point, curve_nid, affine_x.group)

        # Handle uncompressed point
        elif data[0] == 4:
            coord_size = compressed_size - 1
            uncompressed_size = 1 + 2 * coord_size
            if len(data) != uncompressed_size:
                raise ValueError(
                    "uncompressed point does not have right size.")
            affine_x = int.from_bytes(data[1:coord_size + 1], 'big')
            affine_y = int.from_bytes(data[1 + coord_size:], 'big')

            return cls.from_affine((affine_x, affine_y), curve)
        else:
            raise ValueError("Invalid point serialization.")
示例#19
0
    def gen_rand(cls, curve: ec.EllipticCurve = None):
        """
        Returns a CurveBN object with a cryptographically secure OpenSSL BIGNUM
        based on the given curve.
        By default, the underlying OpenSSL BIGNUM has BN_FLG_CONSTTIME set for
        constant time operations.
        """
        curve = curve if curve is not None else default_curve()
        curve_nid = backend._elliptic_curve_to_nid(curve)

        group = openssl._get_ec_group_by_curve_nid(curve_nid)
        order = openssl._get_ec_order_by_curve_nid(curve_nid)

        new_rand_bn = openssl._get_new_BN()
        rand_res = backend._lib.BN_rand_range(new_rand_bn, order)
        backend.openssl_assert(rand_res == 1)

        if not openssl._bn_is_on_curve(new_rand_bn, curve_nid):
            new_rand_bn = cls.gen_rand(curve=curve)
            return new_rand_bn

        return cls(new_rand_bn, curve_nid, group, order)
示例#20
0
    def get_order_from_curve(cls, curve: ec.EllipticCurve = None):
        """
        Returns the order from the given curve as a BigNum.
        """
        curve = curve if curve is not None else default_curve()
        try:
            curve_nid = backend._elliptic_curve_to_nid(curve)
        except AttributeError:
            # Presume that the user passed in the curve_nid
            curve_nid = curve

        group = backend._lib.EC_GROUP_new_by_curve_name(curve_nid)
        backend.openssl_assert(group != backend._ffi.NULL)

        order = backend._lib.BN_new()
        backend.openssl_assert(order != backend._ffi.NULL)
        order = backend._ffi.gc(order, backend._lib.BN_clear_free)

        with backend._tmp_bn_ctx() as bn_ctx:
            res = backend._lib.EC_GROUP_get_order(group, order, bn_ctx)
            backend.openssl_assert(res == 1)

        return BigNum(order, curve_nid, group, order)