Skip to content

Commit

Permalink
Tests simple api with intermediate serialization
Browse files Browse the repository at this point in the history
* Added a multicurve variant of the test, but it fails, so it's set to skip
  • Loading branch information
cygnusv committed Jun 1, 2018
1 parent 55868a3 commit c0d5c3b
Showing 1 changed file with 122 additions and 4 deletions.
126 changes: 122 additions & 4 deletions tests/test_simple_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
from cryptography.exceptions import InvalidTag
from cryptography.hazmat.primitives.asymmetric import ec

from umbral import pre, keys
from umbral import pre
from umbral.fragments import KFrag, CapsuleFrag
from umbral.config import default_curve
from umbral.params import UmbralParameters
from umbral.signing import Signer
from umbral.keys import UmbralPrivateKey, UmbralPublicKey
from .conftest import parameters

secp_curves = [
Expand All @@ -20,14 +22,14 @@ def test_simple_api(N, M, curve=default_curve()):

params = UmbralParameters(curve=curve)

delegating_privkey = keys.UmbralPrivateKey.gen_key(params=params)
delegating_privkey = UmbralPrivateKey.gen_key(params=params)
delegating_pubkey = delegating_privkey.get_pubkey()

signing_privkey = keys.UmbralPrivateKey.gen_key(params=params)
signing_privkey = UmbralPrivateKey.gen_key(params=params)
signing_pubkey = signing_privkey.get_pubkey()
signer = Signer(signing_privkey)

receiving_privkey = keys.UmbralPrivateKey.gen_key(params=params)
receiving_privkey = UmbralPrivateKey.gen_key(params=params)
receiving_pubkey = receiving_privkey.get_pubkey()

plain_data = b'peace at dawn'
Expand Down Expand Up @@ -57,6 +59,122 @@ def test_simple_api_on_multiple_curves(N, M, curve):
test_simple_api(N, M, curve)


@pytest.mark.parametrize("N, M", parameters)
def test_lifecycle_with_serialization(N, M, curve=default_curve()):
"""
This test is a variant of test_simple_api, but with intermediate
serialization/deserialization steps, modeling how pyUmbral artifacts
(such as keys, ciphertexts, etc) will actually be used.
These intermediate steps are in between the different 'usage domains'
in NuCypher, namely, key generation, delegation, encryption, decryption by
Alice, re-encryption by Ursula, and decryption by Bob.
Manually injects UmbralParameters for multi-curve testing.
"""

# Convenience method to avoid replicating key generation code
def new_keypair_bytes():
privkey = UmbralPrivateKey.gen_key(params=params)
return bytes(privkey), bytes(privkey.get_pubkey())

## SETUP
params = UmbralParameters(curve=curve)

delegating_privkey_bytes, delegating_pubkey_bytes = new_keypair_bytes()
signing_privkey_bytes, signing_pubkey_bytes = new_keypair_bytes()
receiving_privkey_bytes, receiving_pubkey_bytes = new_keypair_bytes()

## DELEGATION DOMAIN:
## Alice delegates decryption rights to some Bob by generating a set of
## KFrags, using her delegating private key and Bob's receiving public key

delegating_privkey = UmbralPrivateKey.from_bytes(delegating_privkey_bytes, params)
signing_privkey = UmbralPrivateKey.from_bytes(signing_privkey_bytes, params)
receiving_pubkey = UmbralPublicKey.from_bytes(receiving_pubkey_bytes, params)

signer = Signer(signing_privkey)
kfrags = pre.split_rekey(delegating_privkey, signer, receiving_pubkey, M, N)
kfrags_bytes = tuple(map(bytes, kfrags))

del kfrags
del signer
del delegating_privkey
del signing_privkey
del receiving_pubkey
del params

## ENCRYPTION DOMAIN ##

params = UmbralParameters(curve=curve)

delegating_pubkey = UmbralPublicKey.from_bytes(delegating_pubkey_bytes, params)

plain_data = b'peace at dawn'
ciphertext, capsule = pre.encrypt(delegating_pubkey, plain_data)
capsule_bytes = bytes(capsule)

del capsule
del delegating_pubkey
del params

## DECRYPTION BY ALICE ##

params = UmbralParameters(curve=curve)

delegating_privkey = UmbralPrivateKey.from_bytes(delegating_privkey_bytes, params)
capsule = pre.Capsule.from_bytes(capsule_bytes, params)
cleartext = pre.decrypt(ciphertext, capsule, delegating_privkey)
assert cleartext == plain_data

del delegating_privkey
del capsule
del params

## RE-ENCRYPTION DOMAIN (i.e., Ursula's side)

cfrags_bytes = list()
for kfrag_bytes in kfrags_bytes:
params = UmbralParameters(curve=curve)
capsule = pre.Capsule.from_bytes(capsule_bytes, params)
# TODO: use params instead of curve?
kfrag = KFrag.from_bytes(kfrag_bytes, params.curve)

cfrag_bytes = bytes(pre.reencrypt(kfrag, capsule))
cfrags_bytes.append(cfrag_bytes)

del capsule
del kfrag
del params

## DECRYPTION DOMAIN (i.e., Bob's side)
params = UmbralParameters(curve=curve)

capsule = pre.Capsule.from_bytes(capsule_bytes, params)
delegating_pubkey = UmbralPublicKey.from_bytes(delegating_pubkey_bytes, params)
signing_pubkey = UmbralPublicKey.from_bytes(signing_pubkey_bytes, params)
receiving_privkey = UmbralPrivateKey.from_bytes(receiving_privkey_bytes, params)
receiving_pubkey = receiving_privkey.get_pubkey()

capsule.set_correctness_keys(delegating=delegating_pubkey,
receiving=receiving_pubkey,
verifying=signing_pubkey)

for cfrag_bytes in cfrags_bytes:
# TODO: use params instead of curve?
cfrag = CapsuleFrag.from_bytes(cfrag_bytes, params.curve)
capsule.attach_cfrag(cfrag)

reenc_cleartext = pre.decrypt(ciphertext, capsule, receiving_privkey,
delegating_pubkey, signing_pubkey)
assert reenc_cleartext == plain_data

@pytest.mark.skip(reason="several bugs with multi-curve support")
@pytest.mark.parametrize("curve", secp_curves)
@pytest.mark.parametrize("N, M", parameters)
def test_lifecycle_with_serialization_on_multiple_curves(N, M, curve):
test_lifecycle_with_serialization(N, M, curve)


def test_public_key_encryption(alices_keys):
delegating_privkey, _ = alices_keys
plain_data = b'peace at dawn'
Expand Down

0 comments on commit c0d5c3b

Please sign in to comment.