def to_affine(self): """ Returns a tuple of Python ints in the format of (x, y) that represents the point in the curve. """ affine_x, affine_y = openssl._get_affine_coords_via_EC_POINT( self.ec_point, self.curve) return (backend._bn_to_int(affine_x), backend._bn_to_int(affine_y))
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)
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)
def to_affine(self): """ Returns a tuple of Python ints in the format of (x, y) that represents the point in the curve. """ affine_x = backend._lib.BN_new() backend.openssl_assert(affine_x != backend._ffi.NULL) affine_x = backend._ffi.gc(affine_x, backend._lib.BN_clear_free) affine_y = backend._lib.BN_new() backend.openssl_assert(affine_y != backend._ffi.NULL) affine_y = backend._ffi.gc(affine_y, backend._lib.BN_clear_free) with backend._tmp_bn_ctx() as bn_ctx: res = backend._lib.EC_POINT_get_affine_coordinates_GFp( self.group, self.ec_point, affine_x, affine_y, bn_ctx) backend.openssl_assert(res == 1) return (backend._bn_to_int(affine_x), backend._bn_to_int(affine_y))
def test_mocked_openssl_curvebn_arithmetic(mock_openssl, random_ec_curvebn1, random_ec_curvebn2): operations_that_construct = ( random_ec_curvebn1 * random_ec_curvebn2, # __mul__ random_ec_curvebn1**random_ec_curvebn2, # __pow__ random_ec_curvebn1**int(random_ec_curvebn2), # __pow__ (as int) random_ec_curvebn1 + random_ec_curvebn2, # __add__ random_ec_curvebn1 - random_ec_curvebn2, # __sub__ -random_ec_curvebn1, # __neg__ random_ec_curvebn1 % random_ec_curvebn2, # __mod__ random_ec_curvebn1 % int(random_ec_curvebn2), # __mod__ (as int) ~random_ec_curvebn1, # __invert__ random_ec_curvebn1 / random_ec_curvebn2 # __truediv__ ) with mock_openssl(): assert random_ec_curvebn1 == random_ec_curvebn1 # __eq__ for operator_result in operations_that_construct: assert operator_result assert isinstance(operator_result, CurveBN) order = backend._bn_to_int(random_ec_curvebn1.curve.order) random_ec_curvebn1 = int(random_ec_curvebn1) random_ec_curvebn2 = int(random_ec_curvebn2) # For simplicity, we test these two cases separately assert (int(operations_that_construct[-2]) * random_ec_curvebn1) % order == 1 assert (int(operations_that_construct[-1]) * random_ec_curvebn2) % order == random_ec_curvebn1 # The remaining cases can be tested in bulk expected_results = ( (random_ec_curvebn1 * random_ec_curvebn2) % order, # __mul__ pow(random_ec_curvebn1, random_ec_curvebn2, order), # __pow__ pow(random_ec_curvebn1, random_ec_curvebn2, order), # __pow__ (as int) (random_ec_curvebn1 + random_ec_curvebn2) % order, # __add__ (random_ec_curvebn1 - random_ec_curvebn2) % order, # __sub__ (-random_ec_curvebn1) % order, # __neg__ random_ec_curvebn1 % random_ec_curvebn2, # __mod__ random_ec_curvebn1 % int(random_ec_curvebn2), # __mod__ (as int) ) for (result, expected) in zip(operations_that_construct[:-2], expected_results): assert result == expected
def __int__(self) -> int: """ Converts the CurveBN to a Python int. """ return backend._bn_to_int(self.bignum)
def __int__(self): """ Converts the BigNum to a Python int. """ return backend._bn_to_int(self.bignum)
from umbral.keys import UmbralPrivateKey, UmbralPublicKey from umbral.params import UmbralParameters from umbral.point import Point from umbral.random_oracles import unsafe_hash_to_point from umbral.pre import Capsule # test parameters max_examples = 1000 # crypto constants curve = default_curve() params = UmbralParameters(curve) bn_size = curve.group_order_size_in_bytes # generators bns = integers(min_value=1, max_value=backend._bn_to_int(curve.order)).map( lambda x: CurveBN.from_int(x)) points = binary(min_size=1).map( lambda x: unsafe_hash_to_point(x, label=b'hypothesis', params=params)) signatures = tuples(integers(min_value=1, max_value=backend._bn_to_int(curve.order)), integers(min_value=1, max_value=backend._bn_to_int(curve.order))).map( lambda tup: tup[0].to_bytes(bn_size, 'big') + tup[1].to_bytes(bn_size, 'big')) # # utility def assert_kfrag_eq(k0, k1): assert(all([ k0.id == k1.id , k0.bn_key == k1.bn_key , k0.point_precursor == k1.point_precursor , k0.point_commitment == k1.point_commitment
from umbral.keys import UmbralPrivateKey, UmbralPublicKey from umbral.params import UmbralParameters from umbral.point import Point from umbral.random_oracles import unsafe_hash_to_point from umbral.pre import Capsule # test parameters max_examples = 1000 # crypto constants curve = default_curve() params = UmbralParameters(curve) bn_size = curve.group_order_size_in_bytes # generators bns = integers(min_value=1, max_value=backend._bn_to_int( curve.order)).map(lambda x: CurveBN.from_int(x)) points = binary(min_size=1).map( lambda x: unsafe_hash_to_point(x, label=b'hypothesis', params=params)) signatures = tuples( integers(min_value=1, max_value=backend._bn_to_int(curve.order)), integers(min_value=1, max_value=backend._bn_to_int(curve.order))).map(lambda tup: tup[ 0].to_bytes(bn_size, 'big') + tup[1].to_bytes(bn_size, 'big')) # # utility def assert_kfrag_eq(k0, k1): assert (all([ k0.id == k1.id, k0.bn_key == k1.bn_key,
def bn_to_int(bn) -> int: return backend._bn_to_int(bn)