diff --git a/tests/test_keys/test_umbral_keys.py b/tests/test_keys/test_umbral_keys.py index ccde83b..9e1e9bc 100644 --- a/tests/test_keys/test_umbral_keys.py +++ b/tests/test_keys/test_umbral_keys.py @@ -50,3 +50,16 @@ def test_public_key_to_bytes(): key_bytes = bytes(umbral_key) assert type(key_bytes) == bytes + + +def test_umbral_key_to_cryptography_keys(): + umbral_priv_key = keys.UmbralPrivateKey.gen_key() + umbral_pub_key = umbral_priv_key.get_pubkey() + + crypto_privkey = umbral_priv_key.to_cryptography_privkey() + assert int(umbral_priv_key.bn_key) == crypto_privkey.private_numbers().private_value + + crypto_pubkey = umbral_pub_key.to_cryptography_pubkey() + umbral_affine = umbral_pub_key.point_key.to_affine() + x, y = crypto_pubkey.public_numbers().x, crypto_pubkey.public_numbers().y + assert umbral_affine == (x, y) diff --git a/tests/test_primitives/test_bignum/test_bignum_methods.py b/tests/test_primitives/test_bignum/test_bignum_methods.py index 3a3c600..83cc287 100644 --- a/tests/test_primitives/test_bignum/test_bignum_methods.py +++ b/tests/test_primitives/test_bignum/test_bignum_methods.py @@ -11,9 +11,3 @@ def test_cast_bignum_to_int(): y = BigNum.from_int(x) assert x == y - - -def test_bignum_to_cryptography_privkey(): - bn = BigNum.gen_rand() - crypto_privkey = bn.to_cryptography_priv_key() - assert int(bn) == crypto_privkey.private_numbers().private_value diff --git a/tests/test_primitives/test_point/test_point_serializers.py b/tests/test_primitives/test_point/test_point_serializers.py index 5964eff..39d1788 100644 --- a/tests/test_primitives/test_point/test_point_serializers.py +++ b/tests/test_primitives/test_point/test_point_serializers.py @@ -65,14 +65,6 @@ def test_affine(point_affine, nid, curve): assert point_affine == point_affine2 -def test_point_to_cryptography_pubkey(random_ec_point2): - crypto_pub_key = random_ec_point2.to_cryptography_pub_key() - p_affine = random_ec_point2.to_affine() - x, y = crypto_pub_key.public_numbers().x, crypto_pub_key.public_numbers().y - crypto_affine = (x, y) - assert p_affine == crypto_affine - - def test_invalid_points(random_ec_point2): point_bytes = bytearray(random_ec_point2.to_bytes(is_compressed=False)) diff --git a/umbral/bignum.py b/umbral/bignum.py index 2e74568..ce1c2b2 100644 --- a/umbral/bignum.py +++ b/umbral/bignum.py @@ -3,7 +3,6 @@ import os from cryptography.hazmat.backends.openssl import backend from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives import hashes -from cryptography.hazmat.backends.openssl.ec import _EllipticCurvePrivateKey from umbral.config import default_curve from umbral.utils import get_curve_keysize_bytes @@ -105,41 +104,6 @@ class BigNum(object): return int.to_bytes(int(self), size, 'big') - def to_cryptography_priv_key(self): - """ - Converts the BigNum object to a cryptography.io EllipticCurvePrivateKey - """ - backend.openssl_assert(self.group != backend._ffi.NULL) - backend.openssl_assert(self.bignum != backend._ffi.NULL) - - ec_key = backend._lib.EC_KEY_new() - backend.openssl_assert(ec_key != backend._ffi.NULL) - ec_key = backend._ffi.gc(ec_key, backend._lib.EC_KEY_free) - - res = backend._lib.EC_KEY_set_group(ec_key, self.group) - backend.openssl_assert(res == 1) - - res = backend._lib.EC_KEY_set_private_key(ec_key, self.bignum) - backend.openssl_assert(res == 1) - - # Get public key - point = backend._lib.EC_POINT_new(self.group) - backend.openssl_assert(point != backend._ffi.NULL) - point = backend._ffi.gc(point, backend._lib.EC_POINT_free) - - with backend._tmp_bn_ctx() as bn_ctx: - res = backend._lib.EC_POINT_mul( - self.group, point, self.bignum, backend._ffi.NULL, - backend._ffi.NULL, bn_ctx - ) - backend.openssl_assert(res == 1) - - res = backend._lib.EC_KEY_set_public_key(ec_key, point) - backend.openssl_assert(res == 1) - - evp_pkey = backend._ec_cdata_to_evp_pkey(ec_key) - return _EllipticCurvePrivateKey(backend, ec_key, evp_pkey) - def __int__(self): """ Converts the BigNum to a Python int. diff --git a/umbral/keys.py b/umbral/keys.py index 3f19dce..eb362a1 100644 --- a/umbral/keys.py +++ b/umbral/keys.py @@ -3,10 +3,13 @@ import base64 from typing import Union +from nacl.secret import SecretBox from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives.kdf.scrypt import Scrypt from cryptography.hazmat.backends import default_backend -from nacl.secret import SecretBox +from cryptography.hazmat.backends.openssl.ec import ( + _EllipticCurvePublicKey, _EllipticCurvePrivateKey +) from umbral.config import default_params from umbral.point import Point, BigNum @@ -108,6 +111,47 @@ class UmbralPrivateKey(object): """ return UmbralPublicKey(self.bn_key * self.params.g) + def to_cryptography_privkey(self): + """ + Returns a cryptography.io EllipticCurvePrivateKey from the Umbral key. + """ + backend = default_backend() + + backend.openssl_assert(self.bn_key.group != backend._ffi.NULL) + backend.openssl_assert(self.bn_key.bignum != backend._ffi.NULL) + + ec_key = backend._lib.EC_KEY_new() + backend.openssl_assert(ec_key != backend._ffi.NULL) + ec_key = backend._ffi.gc(ec_key, backend._lib.EC_KEY_free) + + set_group_result = backend._lib.EC_KEY_set_group( + ec_key, self.bn_key.group + ) + backend.openssl_assert(set_group_result == 1) + + set_privkey_result = backend._lib.EC_KEY_set_private_key( + ec_key, self.bn_key.bignum + ) + backend.openssl_assert(set_privkey_result == 1) + + # Get public key + point = backend._lib.EC_POINT_new(self.bn_key.group) + backend.openssl_assert(point != backend._ffi.NULL) + point = backend._ffi.gc(point, backend._lib.EC_POINT_free) + + with backend._tmp_bn_ctx() as bn_ctx: + mult_result = backend._lib.EC_POINT_mul( + self.bn_key.group, point, self.bn_key.bignum, backend._ffi.NULL, + backend._ffi.NULL, bn_ctx + ) + backend.openssl_assert(mult_result == 1) + + set_pubkey_result = backend._lib.EC_KEY_set_public_key(ec_key, point) + backend.openssl_assert(set_pubkey_result == 1) + + evp_pkey = backend._ec_cdata_to_evp_pkey(ec_key) + return _EllipticCurvePrivateKey(backend, ec_key, evp_pkey) + class UmbralPublicKey(object): def __init__(self, point_key, params: UmbralParameters=None): @@ -152,6 +196,32 @@ class UmbralPublicKey(object): def get_pubkey(self): raise NotImplementedError + def to_cryptography_pubkey(self): + """ + Returns a cryptography.io EllipticCurvePublicKey from the Umbral key. + """ + backend = default_backend() + + backend.openssl_assert(self.point_key.group != backend._ffi.NULL) + backend.openssl_assert(self.point_key.ec_point != backend._ffi.NULL) + + ec_key = backend._lib.EC_KEY_new() + backend.openssl_assert(ec_key != backend._ffi.NULL) + ec_key = backend._ffi.gc(ec_key, backend._lib.EC_KEY_free) + + set_group_result = backend._lib.EC_KEY_set_group( + ec_key, self.point_key.group + ) + backend.openssl_assert(set_group_result == 1) + + set_pubkey_result = backend._lib.EC_KEY_set_public_key( + ec_key, self.point_key.ec_point + ) + backend.openssl_assert(set_pubkey_result == 1) + + evp_pkey = backend._ec_cdata_to_evp_pkey(ec_key) + return _EllipticCurvePublicKey(backend, ec_key, evp_pkey) + def __bytes__(self): """ Returns an Umbral Public key as a bytestring. diff --git a/umbral/point.py b/umbral/point.py index f3993de..cd6ffbc 100644 --- a/umbral/point.py +++ b/umbral/point.py @@ -3,7 +3,6 @@ from cryptography.hazmat.backends.openssl import backend from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives import hashes from cryptography.exceptions import InternalError -from cryptography.hazmat.backends.openssl.ec import _EllipticCurvePublicKey from umbral.config import default_curve from umbral.utils import get_curve_keysize_bytes @@ -214,26 +213,6 @@ class Point(object): return BigNum(order, curve_nid, group, order) - def to_cryptography_pub_key(self): - """ - Converts the Point object to a cryptography.io EllipticCurvePublicKey - """ - backend.openssl_assert(self.group != backend._ffi.NULL) - backend.openssl_assert(self.ec_point != backend._ffi.NULL) - - ec_key = backend._lib.EC_KEY_new() - backend.openssl_assert(ec_key != backend._ffi.NULL) - ec_key = backend._ffi.gc(ec_key, backend._lib.EC_KEY_free) - - res = backend._lib.EC_KEY_set_group(ec_key, self.group) - backend.openssl_assert(res == 1) - - res = backend._lib.EC_KEY_set_public_key(ec_key, self.ec_point) - backend.openssl_assert(res == 1) - - evp_pkey = backend._ec_cdata_to_evp_pkey(ec_key) - return _EllipticCurvePublicKey(backend, ec_key, evp_pkey) - def __eq__(self, other): """ Compares two EC_POINTS for equality. diff --git a/umbral/pre.py b/umbral/pre.py index d5839c7..cedcf5a 100644 --- a/umbral/pre.py +++ b/umbral/pre.py @@ -3,7 +3,6 @@ import hmac from typing import Tuple, Union, List from cryptography.hazmat.primitives.asymmetric import ec -from nacl.secret import SecretBox from umbral.bignum import BigNum, hash_to_bn from umbral.config import default_params, default_curve @@ -17,6 +16,9 @@ from umbral.utils import poly_eval, lambda_coeff, kdf, get_curve_keysize_bytes from io import BytesIO +CHACHA20_KEY_SIZE = 32 + + class GenericUmbralError(Exception): pass @@ -445,7 +447,7 @@ def encrypt(alice_pubkey: UmbralPublicKey, plaintext: bytes) -> Tuple[bytes, Cap Returns the ciphertext and the KEM Capsule. """ - key, capsule = _encapsulate(alice_pubkey.point_key, SecretBox.KEY_SIZE) + key, capsule = _encapsulate(alice_pubkey.point_key, CHACHA20_KEY_SIZE) capsule_bytes = bytes(capsule)