def test_derive_key_from_label(): umbral_keying_material = UmbralKeyingMaterial() label = b"my_healthcare_information" priv_key1 = umbral_keying_material.derive_privkey_by_label(label) assert type(priv_key1) == UmbralPrivateKey pub_key1 = priv_key1.get_pubkey() assert type(pub_key1) == 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_keying_material_serialization(): umbral_keying_material = UmbralKeyingMaterial() encoded_keying_material = umbral_keying_material.to_bytes() decoded_keying_material = UmbralKeyingMaterial.from_bytes(encoded_keying_material) label = os.urandom(32) privkey_bytes = umbral_keying_material.derive_privkey_by_label(label).to_bytes() assert privkey_bytes == decoded_keying_material.derive_privkey_by_label(label).to_bytes()
class DelegatingPower(DerivedKeyBasedPower): def __init__(self, keying_material: Optional[bytes] = None, password: Optional[bytes] = None) -> None: if keying_material is None: self.__umbral_keying_material = UmbralKeyingMaterial() else: self.__umbral_keying_material = UmbralKeyingMaterial.from_bytes(key_bytes=keying_material, password=password) def _get_privkey_from_label(self, label): return self.__umbral_keying_material.derive_privkey_by_label(label) def get_pubkey_from_label(self, label): return self._get_privkey_from_label(label).get_pubkey() def generate_kfrags(self, bob_pubkey_enc, signer, label: bytes, m: int, n: int ) -> Tuple[UmbralPublicKey, List]: """ Generates re-encryption key frags ("KFrags") and returns them. These KFrags can be used by Ursula to re-encrypt a Capsule for Bob so that he can activate the Capsule. :param bob_pubkey_enc: Bob's public key :param m: Minimum number of KFrags needed to rebuild ciphertext :param n: Total number of KFrags to generate """ # TODO: salt? #265 __private_key = self._get_privkey_from_label(label) kfrags = pre.generate_kfrags(delegating_privkey=__private_key, receiving_pubkey=bob_pubkey_enc, threshold=m, N=n, signer=signer, sign_delegating_key=False, sign_receiving_key=False, ) return __private_key.get_pubkey(), kfrags def get_decrypting_power_from_label(self, label): label_privkey = self._get_privkey_from_label(label) label_keypair = keypairs.DecryptingKeypair(private_key=label_privkey) decrypting_power = DecryptingPower(keypair=label_keypair) return decrypting_power
def test_keying_material_serialization_with_encryption(): umbral_keying_material = UmbralKeyingMaterial() insecure_cost = 15 # This is deliberately insecure, just to make the tests faster encoded_keying_material = umbral_keying_material.to_bytes(password=b'test', _scrypt_cost=insecure_cost) decoded_keying_material = UmbralKeyingMaterial.from_bytes(encoded_keying_material, password=b'test', _scrypt_cost=insecure_cost) label = os.urandom(32) privkey_bytes = umbral_keying_material.derive_privkey_by_label(label).to_bytes() assert privkey_bytes == decoded_keying_material.derive_privkey_by_label(label).to_bytes()
class DelegatingPower(DerivedKeyBasedPower): def __init__(self): self.umbral_keying_material = UmbralKeyingMaterial() def generate_kfrags(self, bob_pubkey_enc, signer, label, m, n) -> Union[UmbralPublicKey, List]: """ Generates re-encryption key frags ("KFrags") and returns them. These KFrags can be used by Ursula to re-encrypt a Capsule for Bob so that he can activate the Capsule. :param bob_pubkey_enc: Bob's public key :param m: Minimum number of KFrags needed to rebuild ciphertext :param n: Total number of rekey shares to generate """ # TODO: salt? #265 __private_key = self.umbral_keying_material.derive_privkey_by_label(label) kfrags = pre.split_rekey(__private_key, signer, bob_pubkey_enc, m, n) return __private_key.get_pubkey(), kfrags