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)
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
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)
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)
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)
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)
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)
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
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)
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)