Add `SecretKeyFactory.secret_key_factory_by_label()`

pull/272/head
Bogdan Opanchuk 2021-07-19 14:52:39 -07:00
parent 7e75ecb2aa
commit a9050f4678
3 changed files with 46 additions and 9 deletions

View File

@ -42,25 +42,32 @@ def test_keys(implementations):
_restore_keys(umbral2, sk_bytes, pk_bytes)
def _create_sk_factory_and_sk(umbral, label):
def _create_sk_factory_and_sk(umbral, skf_label, key_label):
skf = umbral.SecretKeyFactory.random()
sk = skf.secret_key_by_label(label)
return skf.to_secret_bytes(), sk.to_secret_bytes()
derived_skf = skf.secret_key_factory_by_label(skf_label)
sk = derived_skf.secret_key_by_label(key_label)
return skf.to_secret_bytes(), derived_skf.to_secret_bytes(), sk.to_secret_bytes()
def _check_sk_is_same(umbral, label, skf_bytes, sk_bytes):
def _check_sk_is_same(umbral, skf_label, key_label, skf_bytes, derived_skf_bytes, sk_bytes):
skf = umbral.SecretKeyFactory.from_bytes(skf_bytes)
derived_skf_restored = umbral.SecretKeyFactory.from_bytes(derived_skf_bytes)
derived_skf_generated = skf.secret_key_factory_by_label(skf_label)
assert derived_skf_generated.to_secret_bytes() == derived_skf_restored.to_secret_bytes()
sk_restored = umbral.SecretKey.from_bytes(sk_bytes)
sk_generated = skf.secret_key_by_label(label)
sk_generated = derived_skf_generated.secret_key_by_label(key_label)
assert sk_restored.to_secret_bytes() == sk_generated.to_secret_bytes()
def test_secret_key_factory(implementations):
umbral1, umbral2 = implementations
label = b'label'
skf_label = b'skf label'
key_label = b'key label'
skf_bytes, sk_bytes = _create_sk_factory_and_sk(umbral1, label)
_check_sk_is_same(umbral2, label, skf_bytes, sk_bytes)
skf_bytes, derived_skf_bytes, sk_bytes = _create_sk_factory_and_sk(umbral1, skf_label, key_label)
_check_sk_is_same(umbral2, skf_label, key_label, skf_bytes, derived_skf_bytes, sk_bytes)
def _encrypt(umbral, plaintext, pk_bytes):

View File

@ -46,6 +46,28 @@ def test_derive_key_from_label():
assert sk1 != sk3
def test_derive_skf_from_label():
root = SecretKeyFactory.random()
skf_label = b"Alice"
skf = root.secret_key_factory_by_label(skf_label)
assert type(skf) == SecretKeyFactory
skf_same = root.secret_key_factory_by_label(skf_label)
assert skf.to_secret_bytes() == skf_same.to_secret_bytes()
# Just in case, check that they produce the same secret keys too.
key_label = b"my_healthcare_information"
key = skf.secret_key_by_label(key_label)
key_same = skf_same.secret_key_by_label(key_label)
assert key.to_secret_bytes() == key_same.to_secret_bytes()
# Different label produces a different factory
skf_different = root.secret_key_factory_by_label(b"Bob")
assert skf.to_secret_bytes() != skf_different.to_secret_bytes()
def test_secret_key_serialization():
sk = SecretKey.random()
encoded_key = sk.to_secret_bytes()

View File

@ -111,7 +111,7 @@ class SecretKeyFactory(SerializableSecret, Deserializable):
def secret_key_by_label(self, label: bytes) -> SecretKey:
"""
Creates a :py:class:`SecretKey` from the given label.
Creates a :py:class:`SecretKey` deterministically from the given label.
"""
tag = b"KEY_DERIVATION/" + label
key = kdf(self.__key_seed, self._DERIVED_KEY_SIZE, info=tag)
@ -122,6 +122,14 @@ class SecretKeyFactory(SerializableSecret, Deserializable):
return SecretKey(scalar_key)
def secret_key_factory_by_label(self, label: bytes) -> 'SecretKeyFactory':
"""
Creates a :py:class:`SecretKeyFactory` deterministically from the given label.
"""
tag = b"FACTORY_DERIVATION/" + label
key_seed = kdf(self.__key_seed, self._KEY_SEED_SIZE, info=tag)
return SecretKeyFactory(key_seed)
@classmethod
def serialized_size(cls):
return cls._KEY_SEED_SIZE