pyUmbral/tests/test_keys/test_umbral_keys.py

187 lines
6.0 KiB
Python

import base64
import pytest
from umbral import keys
from umbral.config import default_params
from umbral.keys import UmbralPublicKey
from umbral.point import Point
def test_gen_key():
# Pass in the parameters to test that manual param selection works
umbral_priv_key = keys.UmbralPrivateKey.gen_key()
assert type(umbral_priv_key) == keys.UmbralPrivateKey
umbral_pub_key = umbral_priv_key.get_pubkey()
assert type(umbral_pub_key) == keys.UmbralPublicKey
def test_derive_key_from_label():
umbral_keying_material = keys.UmbralKeyingMaterial()
label = b"my_healthcare_information"
priv_key1 = umbral_keying_material.derive_privkey_by_label(label)
assert type(priv_key1) == keys.UmbralPrivateKey
pub_key1 = priv_key1.get_pubkey()
assert type(pub_key1) == keys.UmbralPublicKey
# Check that key derivation is reproducible
priv_key2 = umbral_keying_material.derive_privkey_by_label(label)
pub_key2 = priv_key2.get_pubkey()
assert priv_key1.bn_key == priv_key2.bn_key
assert pub_key1 == pub_key2
# A salt can be used too, but of course it affects the derived key
salt = b"optional, randomly generated salt"
priv_key3 = umbral_keying_material.derive_privkey_by_label(label, salt=salt)
assert priv_key3.bn_key != priv_key1.bn_key
# Different labels on the same master secret create different keys
label = b"my_tax_information"
priv_key4 = umbral_keying_material.derive_privkey_by_label(label)
pub_key4 = priv_key4.get_pubkey()
assert priv_key1.bn_key != priv_key4.bn_key
def test_private_key_serialization(random_ec_curvebn1):
priv_key = random_ec_curvebn1
umbral_key = keys.UmbralPrivateKey(priv_key, default_params())
encoded_key = umbral_key.to_bytes()
decoded_key = keys.UmbralPrivateKey.from_bytes(encoded_key)
assert priv_key == decoded_key.bn_key
def test_private_key_serialization_with_encryption(random_ec_curvebn1):
priv_key = random_ec_curvebn1
umbral_key = keys.UmbralPrivateKey(priv_key, default_params())
encoded_key = umbral_key.to_bytes(password=b'test')
decoded_key = keys.UmbralPrivateKey.from_bytes(encoded_key, password=b'test')
assert priv_key == decoded_key.bn_key
def test_public_key_serialization(random_ec_curvebn1):
priv_key = random_ec_curvebn1
params = default_params()
pub_key = priv_key * params.g
umbral_key = keys.UmbralPublicKey(pub_key, params)
encoded_key = umbral_key.to_bytes()
decoded_key = keys.UmbralPublicKey.from_bytes(encoded_key)
assert pub_key == decoded_key.point_key
def test_public_key_to_compressed_bytes(random_ec_curvebn1):
priv_key = random_ec_curvebn1
params = default_params()
pub_key = priv_key * params.g
umbral_key = keys.UmbralPublicKey(pub_key, params)
key_bytes = bytes(umbral_key)
assert len(key_bytes) == Point.expected_bytes_length(is_compressed=True)
def test_public_key_to_uncompressed_bytes(random_ec_curvebn1):
priv_key = random_ec_curvebn1
params = default_params()
pub_key = priv_key * params.g
umbral_key = keys.UmbralPublicKey(pub_key, params)
key_bytes = umbral_key.to_bytes(is_compressed=False)
assert len(key_bytes) == Point.expected_bytes_length(is_compressed=False)
def test_key_encoder_decoder(random_ec_curvebn1):
priv_key = random_ec_curvebn1
umbral_key = keys.UmbralPrivateKey(priv_key, default_params())
encoded_key = umbral_key.to_bytes(encoder=base64.urlsafe_b64encode)
decoded_key = keys.UmbralPrivateKey.from_bytes(encoded_key,
decoder=base64.urlsafe_b64decode)
assert decoded_key.to_bytes() == umbral_key.to_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)
def test_keying_material_serialization():
umbral_keying_material = keys.UmbralKeyingMaterial()
encoded_key = umbral_keying_material.to_bytes()
decoded_key = keys.UmbralKeyingMaterial.from_bytes(encoded_key)
assert umbral_keying_material.keying_material == decoded_key.keying_material
def test_keying_material_serialization_with_encryption():
umbral_keying_material = keys.UmbralKeyingMaterial()
encoded_key = umbral_keying_material.to_bytes(password=b'test')
decoded_key = keys.UmbralKeyingMaterial.from_bytes(encoded_key, password=b'test')
assert umbral_keying_material.keying_material == decoded_key.keying_material
def test_umbral_public_key_equality():
umbral_priv_key = keys.UmbralPrivateKey.gen_key()
umbral_pub_key = umbral_priv_key.get_pubkey()
as_bytes = bytes(umbral_pub_key)
assert umbral_pub_key == as_bytes
reconstructed = UmbralPublicKey.from_bytes(as_bytes)
assert reconstructed == umbral_pub_key
assert not umbral_pub_key == b"some whatever bytes"
another_umbral_priv_key = keys.UmbralPrivateKey.gen_key()
another_umbral_pub_key = another_umbral_priv_key.get_pubkey()
assert not umbral_pub_key == another_umbral_pub_key
# Also not equal to a totally disparate type.
assert not umbral_pub_key == 47
def test_umbral_public_key_as_dict_key():
umbral_priv_key = keys.UmbralPrivateKey.gen_key()
umbral_pub_key = umbral_priv_key.get_pubkey()
d = {umbral_pub_key: 19}
assert d[umbral_pub_key] == 19
another_umbral_priv_key = keys.UmbralPrivateKey.gen_key()
another_umbral_pub_key = another_umbral_priv_key.get_pubkey()
with pytest.raises(KeyError):
d[another_umbral_pub_key]
d[another_umbral_pub_key] = False
assert d[umbral_pub_key] == 19
d[umbral_pub_key] = 20
assert d[umbral_pub_key] == 20
assert d[another_umbral_pub_key] is False