Beispiel #1
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 = 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)
Beispiel #2
0
def get_field_order_size_in_bytes(curve):

    backend = default_backend()
    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)
    size_in_bits = openssl._get_ec_group_degree(group)
    return (size_in_bits + 7) // 8
Beispiel #3
0
    def __init__(self, curve_nid: int):
        """
        Instantiates an OpenSSL curve with the provided curve_nid and derives
        the proper EC_GROUP struct and order. You can _only_ instantiate curves
        with supported nids (see `Curve.supported_curves`).
        """
        if curve_nid not in _AVAIL_CURVES.values():
            raise ValueError(
                "Curve NID passed ({}) is not supported.".format(curve_nid))

        self.curve_nid = curve_nid
        self.ec_group = openssl._get_ec_group_by_curve_nid(self.curve_nid)
        self.order = openssl._get_ec_order_by_group(self.ec_group)
        self.generator = openssl._get_ec_generator_by_group(self.ec_group)
Beispiel #4
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)
Beispiel #5
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)
Beispiel #6
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)
Beispiel #7
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)
Beispiel #8
0
    def __init__(self, nid: int) -> None:
        """
        Instantiates an OpenSSL curve with the provided curve_nid and derives
        the proper EC_GROUP struct and order. You can _only_ instantiate curves
        with supported nids (see `Curve.supported_curves`).
        """

        try:
            self.__curve_name = self._supported_curves[nid]
        except KeyError:
            raise NotImplementedError("Curve NID {} is not supported.".format(nid))

        # set only once
        self.__curve_nid = nid
        self.__ec_group = openssl._get_ec_group_by_curve_nid(self.__curve_nid)
        self.__order = openssl._get_ec_order_by_group(self.ec_group)
        self.__generator = openssl._get_ec_generator_by_group(self.ec_group)

        # Init cache
        self.__field_order_size_in_bytes = None
Beispiel #9
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)
Beispiel #10
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)