Using Alice's DelegatingPower to make a Policy.

pull/217/head
jMyles 2018-04-11 08:15:08 -07:00
parent 9db6a23e4f
commit 67376fe607
4 changed files with 33 additions and 28 deletions

View File

@ -19,7 +19,7 @@ from nkms.config.configs import KMSConfig
from nkms.crypto.api import secure_random, keccak_digest
from nkms.crypto.constants import PUBLIC_KEY_LENGTH
from nkms.crypto.kits import UmbralMessageKit
from nkms.crypto.powers import CryptoPower, SigningPower, EncryptingPower
from nkms.crypto.powers import CryptoPower, SigningPower, EncryptingPower, DelegatingPower
from nkms.crypto.signature import Signature
from nkms.crypto.splitters import signature_splitter
from nkms.network import blockchain_client
@ -303,7 +303,7 @@ class FakePolicyAgent: # TODO: #192
class Alice(Character, PolicyAuthor):
_server_class = NuCypherSeedOnlyDHTServer
_default_crypto_powerups = [SigningPower, EncryptingPower]
_default_crypto_powerups = [SigningPower, EncryptingPower, DelegatingPower]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@ -320,7 +320,7 @@ class Alice(Character, PolicyAuthor):
:param n: Total number of kfrags to generate
"""
bob_pubkey_enc = bob.public_key(EncryptingPower)
return self._crypto_power.power_ups(EncryptingPower).generate_kfrags(bob_pubkey_enc, m, n)
return self._crypto_power.power_ups(DelegatingPower).generate_kfrags(bob_pubkey_enc, m, n)
def create_policy(self, bob: "Bob", uri: bytes, m: int, n: int):
"""

View File

@ -114,7 +114,7 @@ class EncryptingPower(KeyPairBasedPower):
class DelegatingPower(KeyPairBasedPower):
_keypair_class = SigningKeypair
not_found_error = NoSigningPower
_keypair_class = EncryptingKeypair
not_found_error = PowerUpError
provides = ("generate_kfrags",)

View File

@ -26,7 +26,7 @@ def test_bob_can_follow_treasure_map(enacted_policy, ursulas, alice, bob):
def test_bob_can_issue_a_work_order_to_a_specific_ursula(enacted_policy, alice, bob, ursulas,
alicebob_side_channel):
capsule_side_channel):
"""
Now that Bob has his list of Ursulas, he can issue a WorkOrder to one. Upon receiving the WorkOrder, Ursula
saves it and responds by re-encrypting and giving Bob a cFrag.
@ -48,7 +48,7 @@ def test_bob_can_issue_a_work_order_to_a_specific_ursula(enacted_policy, alice,
# We'll test against just a single Ursula - here, we make a WorkOrder for just one.
# We can pass any number of capsules as args; here we pass just one.
work_orders = bob.generate_work_orders(the_hrac, alicebob_side_channel.capsule, num_ursulas=1)
work_orders = bob.generate_work_orders(the_hrac, capsule_side_channel.capsule, num_ursulas=1)
# Again: one Ursula, one work_order.
assert len(work_orders) == 1
@ -72,7 +72,7 @@ def test_bob_can_issue_a_work_order_to_a_specific_ursula(enacted_policy, alice,
the_cfrag = cfrags[0]
# Attach the CFrag to the Capsule.
alicebob_side_channel.capsule.attach_cfrag(the_cfrag)
capsule_side_channel.capsule.attach_cfrag(the_cfrag)
# Having received the cFrag, Bob also saved the WorkOrder as complete.
assert len(bob._saved_work_orders) == 1
@ -83,7 +83,7 @@ def test_bob_can_issue_a_work_order_to_a_specific_ursula(enacted_policy, alice,
kfrag_bytes = ursula.datastore.get_policy_arrangement(
work_order.kfrag_hrac.hex().encode()).k_frag
the_kfrag = KFrag.from_bytes(kfrag_bytes)
the_correct_cfrag = pre.reencrypt(the_kfrag, alicebob_side_channel.capsule)
the_correct_cfrag = pre.reencrypt(the_kfrag, capsule_side_channel.capsule)
assert bytes(the_cfrag) == bytes(the_correct_cfrag) # It's the correct cfrag!
# Now we'll show that Ursula saved the correct WorkOrder.
@ -93,14 +93,14 @@ def test_bob_can_issue_a_work_order_to_a_specific_ursula(enacted_policy, alice,
def test_bob_remembers_that_he_has_cfrags_for_a_particular_capsule(enacted_policy, alice, bob,
ursulas, alicebob_side_channel):
ursulas, capsule_side_channel):
# In our last episode, Bob made a WorkOrder for the capsule...
assert len(bob._saved_work_orders.by_capsule(alicebob_side_channel.capsule)) == 1
assert len(bob._saved_work_orders.by_capsule(capsule_side_channel.capsule)) == 1
# ...and he used it to obtain a CFrag from Ursula.
assert len(alicebob_side_channel.capsule._attached_cfrags) == 1
assert len(capsule_side_channel.capsule._attached_cfrags) == 1
# He can also get a dict of {Ursula:WorkOrder} by looking them up from the capsule.
workorders_by_capsule = bob._saved_work_orders.by_capsule(alicebob_side_channel.capsule)
workorders_by_capsule = bob._saved_work_orders.by_capsule(capsule_side_channel.capsule)
# Bob has just one WorkOrder from that one Ursula.
assert len(workorders_by_capsule) == 1
@ -108,7 +108,7 @@ def test_bob_remembers_that_he_has_cfrags_for_a_particular_capsule(enacted_polic
# The rest of this test will show that if Bob generates another WorkOrder, it's for a *different* Ursula.
generated_work_orders = bob.generate_work_orders(enacted_policy.hrac(),
alicebob_side_channel.capsule,
capsule_side_channel.capsule,
num_ursulas=1)
id_of_this_new_ursula, new_work_order = list(generated_work_orders.items())[0]
@ -134,10 +134,10 @@ def test_bob_remembers_that_he_has_cfrags_for_a_particular_capsule(enacted_polic
new_cfrag = cfrags[0]
# Attach the CFrag to the Capsule.
alicebob_side_channel.capsule.attach_cfrag(new_cfrag)
capsule_side_channel.capsule.attach_cfrag(new_cfrag)
def test_bob_gathers_and_combines(enacted_policy, alice, bob, ursulas, alicebob_side_channel):
def test_bob_gathers_and_combines(enacted_policy, alice, bob, ursulas, capsule_side_channel):
# Bob has saved two WorkOrders so far.
assert len(bob._saved_work_orders) == 2
@ -146,12 +146,12 @@ def test_bob_gathers_and_combines(enacted_policy, alice, bob, ursulas, alicebob_
# Bob can't decrypt yet with just two CFrags. He needs to gather at least m.
with pytest.raises(pre.GenericUmbralError):
bob.decrypt(alicebob_side_channel)
bob.decrypt(capsule_side_channel)
number_left_to_collect = enacted_policy.m - len(bob._saved_work_orders)
new_work_orders = bob.generate_work_orders(enacted_policy.hrac(),
alicebob_side_channel.capsule,
capsule_side_channel.capsule,
num_ursulas=number_left_to_collect)
_id_of_yet_another_ursula, new_work_order = list(new_work_orders.items())[0]
@ -159,8 +159,8 @@ def test_bob_gathers_and_combines(enacted_policy, alice, bob, ursulas, alicebob_
# In the real world, we'll have a full Ursula node here. But in this case, we need to fake it.
new_work_order.ursula = ursulas[2]
cfrags = bob.get_reencrypted_c_frags(networky_stuff, new_work_order)
alicebob_side_channel.capsule.attach_cfrag(cfrags[0])
capsule_side_channel.capsule.attach_cfrag(cfrags[0])
# Now.
# At long last.
assert bob.decrypt(alicebob_side_channel) == b'Welcome to the flippering.'
assert bob.decrypt(capsule_side_channel) == b'Welcome to the flippering.'

View File

@ -3,9 +3,9 @@ import os
import pytest
from constant_sorrow import constants
from nkms.characters import Alice, Bob
from nkms.characters import Alice, Bob, Enrique
from nkms.crypto.kits import MessageKit
from nkms.crypto.powers import SigningPower, EncryptingPower
from nkms.crypto.powers import SigningPower, EncryptingPower, DelegatingPower
from nkms.network import blockchain_client
from tests.utilities import NUMBER_OF_URSULAS_IN_NETWORK, MockNetworkyStuff, make_ursulas, \
URSULA_PORT, EVENT_LOOP
@ -19,18 +19,18 @@ import maya
@pytest.fixture(scope="module")
def idle_policy(alice, bob):
"""
Creates a PolicyGroup, in a manner typical of how Alice might do it, with a unique uri.
Creates a Policy, in a manner typical of how Alice might do it, with a unique uri (soon to be "label" - see #183)
"""
alice.__resource_id += b"/unique-again" # A unique name each time, like a path.
n = NUMBER_OF_URSULAS_IN_NETWORK
policy_group = alice.create_policy(
policy = alice.create_policy(
bob,
alice.__resource_id,
m=3,
n=n,
)
return policy_group
return policy
@pytest.fixture(scope="module")
@ -65,6 +65,11 @@ def bob():
return BOB
@pytest.fixture(scope="module")
def enrique():
return Enrique()
@pytest.fixture(scope="module")
def ursulas():
URSULAS = make_ursulas(NUMBER_OF_URSULAS_IN_NETWORK, URSULA_PORT)
@ -90,10 +95,10 @@ def test_keystore():
@pytest.fixture(scope="module")
def alicebob_side_channel(alice):
def capsule_side_channel(alice):
plaintext = b"Welcome to the flippering."
ciphertext, capsule = pre.encrypt(alice.public_key(EncryptingPower), plaintext)
ciphertext, capsule = pre.encrypt(alice.public_key(DelegatingPower), plaintext)
return MessageKit(ciphertext=ciphertext, capsule=capsule,
alice_pubkey=alice.public_key(EncryptingPower))
alice_pubkey=alice.public_key(DelegatingPower))