mirror of https://github.com/nucypher/nucypher.git
Added more Policy and PolicyGroup logic. Now conforms to @tux's crypto APIs.
parent
f6b9111b63
commit
9e314d8b81
|
@ -0,0 +1,10 @@
|
||||||
|
import random
|
||||||
|
|
||||||
|
# TODO: Replace these with actual hash functions.
|
||||||
|
|
||||||
|
def signature_hash(hash_input):
|
||||||
|
return random.getrandbits(128)
|
||||||
|
|
||||||
|
|
||||||
|
def content_hash(hash_input):
|
||||||
|
return random.getrandbits(128)
|
|
@ -0,0 +1,12 @@
|
||||||
|
# TODO: Make this actually work.
|
||||||
|
def generate_re_encryption_keys(seckey_enc_alice,
|
||||||
|
pubkey_enc_bob,
|
||||||
|
m,
|
||||||
|
n):
|
||||||
|
kfrags = [
|
||||||
|
'sfasdfsd9',
|
||||||
|
'dfasd09fi',
|
||||||
|
'sdfksd3f9',
|
||||||
|
]
|
||||||
|
|
||||||
|
return kfrags
|
|
@ -0,0 +1 @@
|
||||||
|
UNKNOWN_KFRAG = 550
|
|
@ -1,5 +1,6 @@
|
||||||
from nkms.crypto.pre.keys import generate_re_encryption_keys
|
from nkms.crypto.hash import content_hash
|
||||||
from nkms.crypto import nkms_hash
|
from nkms.crypto.pre.keygen import generate_re_encryption_keys
|
||||||
|
from nkms.policy.constants import UNKNOWN_KFRAG
|
||||||
|
|
||||||
|
|
||||||
class PolicyGroup(object):
|
class PolicyGroup(object):
|
||||||
|
@ -7,38 +8,42 @@ class PolicyGroup(object):
|
||||||
The terms and conditions by which Alice shares with Bob.
|
The terms and conditions by which Alice shares with Bob.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, policies=None):
|
||||||
self.policies = []
|
self.policies = policies or []
|
||||||
|
|
||||||
def craft(self,
|
@staticmethod
|
||||||
keychain_alice: "KeyChain",
|
def craft(keychain_alice: "KeyChain",
|
||||||
pubkey_enc_bob: tuple,
|
pubkey_enc_bob: tuple,
|
||||||
uri: bytes,
|
uri: bytes,
|
||||||
m: int,
|
m: int,
|
||||||
n: int
|
n: int
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Alice dictates a new group of policies.
|
Alice dictates a new group of policies.
|
||||||
"""
|
"""
|
||||||
re_enc_keys = generate_re_encryption_keys(keychain_alice.seckey_end,
|
re_enc_keys = generate_re_encryption_keys(keychain_alice.enc_keypair.priv_key,
|
||||||
pubkey_enc_bob,
|
pubkey_enc_bob,
|
||||||
m,
|
m,
|
||||||
n)
|
n)
|
||||||
|
policies = []
|
||||||
for kfrag_id, key in enumerate(re_enc_keys):
|
for kfrag_id, key in enumerate(re_enc_keys):
|
||||||
policy = Policy.from_alice(
|
policy = Policy.from_alice(
|
||||||
key, # Bob won't know this.
|
key, # Bob won't know this.
|
||||||
keychain_alice.pubkey_sig,
|
keychain_alice.sig_keypair.pub_key,
|
||||||
pubkey_enc_bob,
|
pubkey_enc_bob,
|
||||||
uri, # Ursula won't know this.
|
uri, # Ursula won't know this.
|
||||||
kfrag_id,
|
kfrag_id,
|
||||||
)
|
)
|
||||||
self.policies.append(policy)
|
policies.append(policy)
|
||||||
|
|
||||||
|
return PolicyGroup(policies)
|
||||||
|
|
||||||
|
|
||||||
def transmit(self, networky_stuff):
|
def transmit(self, networky_stuff):
|
||||||
for policy in self.policies:
|
for policy in self.policies:
|
||||||
policy_offer = policy.craft_offer()
|
policy_offer = policy.craft_offer(networky_stuff)
|
||||||
result = networky_stuff.transmit_offer(policy.ursula, policy_offer)
|
result = networky_stuff.transmit_offer(policy.ursula, policy_offer)
|
||||||
if result.was_accepted():
|
if result.was_accepted:
|
||||||
policy.update_treasure_map(result)
|
policy.update_treasure_map(result)
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,6 +60,11 @@ class Policy(object):
|
||||||
ursula = None
|
ursula = None
|
||||||
hashed_part = None
|
hashed_part = None
|
||||||
|
|
||||||
|
def __init__(self, kfrag=UNKNOWN_KFRAG, challenge_size=20):
|
||||||
|
self.kfrag = kfrag
|
||||||
|
self.challenge_size = challenge_size
|
||||||
|
self.treasure_map = []
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_alice(kfrag,
|
def from_alice(kfrag,
|
||||||
pubkey_sig_alice,
|
pubkey_sig_alice,
|
||||||
|
@ -62,16 +72,16 @@ class Policy(object):
|
||||||
uri,
|
uri,
|
||||||
kfrag_id
|
kfrag_id
|
||||||
):
|
):
|
||||||
|
policy = Policy(kfrag)
|
||||||
policy = Policy()
|
policy.generate_challenge_pack()
|
||||||
policy.generate_challenge_pack(kfrag)
|
policy.hash(pubkey_sig_alice=pubkey_sig_alice, hash_input=(pubkey_enc_bob, uri, kfrag_id))
|
||||||
policy.hash(pubkey_enc_bob, uri, kfrag_id, pubkey_sig_alice=pubkey_sig_alice)
|
|
||||||
|
|
||||||
return policy
|
return policy
|
||||||
|
|
||||||
def hash(self, pubkey_sig_alice, *args):
|
def hash(self, pubkey_sig_alice, hash_input):
|
||||||
self.hashed_part = nkms_hash(*args)
|
self.hashed_part = content_hash(hash_input)
|
||||||
self.id = nkms_hash(pubkey_sig_alice, self.hashed_part)
|
hash_input_for_id = (pubkey_sig_alice, self.hashed_part)
|
||||||
|
self.id = content_hash(hash_input_for_id)
|
||||||
return self.id
|
return self.id
|
||||||
|
|
||||||
def craft_offer(self, networky_stuff):
|
def craft_offer(self, networky_stuff):
|
||||||
|
@ -79,4 +89,18 @@ class Policy(object):
|
||||||
Find an Ursula and craft an offer for her.
|
Find an Ursula and craft an offer for her.
|
||||||
"""
|
"""
|
||||||
self.ursula = networky_stuff.find_ursula(self.id, self.hashed_part)
|
self.ursula = networky_stuff.find_ursula(self.id, self.hashed_part)
|
||||||
return self.ursula.encrypt_for(self.kfrag, self.challenge_pack, self.treasure_map)
|
return self.ursula.encrypt_for((self.kfrag, self.challenge_pack, self.treasure_map))
|
||||||
|
|
||||||
|
def generate_challenge_pack(self):
|
||||||
|
if self.kfrag == UNKNOWN_KFRAG:
|
||||||
|
raise TypeError("Can't generate a challenge pack unless we know the kfrag. Are you Alice?")
|
||||||
|
|
||||||
|
# TODO: make this work instead of being random.
|
||||||
|
import random
|
||||||
|
self.challenge_pack = [(random.getrandbits(32), random.getrandbits(32)) for x in range(self.challenge_size)]
|
||||||
|
return True
|
||||||
|
|
||||||
|
def update_treasure_map(self, policy_offer_result):
|
||||||
|
# TODO: parse the result and add the node information to the treasure map.
|
||||||
|
self.treasure_map.append(policy_offer_result)
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,45 @@
|
||||||
from nkms.crypto.keys import KeyChain
|
from nkms.crypto.keyring import KeyRing
|
||||||
|
|
||||||
from nkms.policy.models import PolicyGroup
|
from nkms.policy.models import PolicyGroup
|
||||||
|
|
||||||
|
|
||||||
|
class MockUrsula(object):
|
||||||
|
def encrypt_for(self, payload):
|
||||||
|
# TODO: Make this a testable result
|
||||||
|
import random
|
||||||
|
return random.getrandbits(32)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class MockPolicyOfferResponse(object):
|
||||||
|
was_accepted = True
|
||||||
|
|
||||||
|
|
||||||
|
class MockNetworkyStuff(object):
|
||||||
|
|
||||||
|
def transmit_offer(self, ursula, policy_offer):
|
||||||
|
return MockPolicyOfferResponse()
|
||||||
|
|
||||||
|
def find_ursula(self, id, hashed_part):
|
||||||
|
return MockUrsula()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_alice_has_ursulas_public_key_and_uses_it_to_encode_policy_payload():
|
def test_alice_has_ursulas_public_key_and_uses_it_to_encode_policy_payload():
|
||||||
keychain_alice = KeyChain()
|
keychain_alice = KeyRing()
|
||||||
keychain_bob = KeyChain()
|
keychain_bob = KeyRing()
|
||||||
keychain_ursula = KeyChain()
|
keychain_ursula = KeyRing()
|
||||||
|
|
||||||
# For example, a hashed path.
|
# For example, a hashed path.
|
||||||
resource_id = b"as098duasdlkj213098asf"
|
resource_id = b"as098duasdlkj213098asf"
|
||||||
kfrag_id = 74
|
|
||||||
|
|
||||||
# Alice runs this to get a policy object.
|
# Alice runs this to get a policy object.
|
||||||
policy_group = PolicyGroup.craft(keychain_alice.pubkey_sig,
|
policy_group = PolicyGroup.craft(keychain_alice,
|
||||||
keychain_bob.pubkey_sig,
|
keychain_bob.enc_keypair.pub_key,
|
||||||
resource_id,
|
resource_id,
|
||||||
kfrag_id
|
m=20,
|
||||||
)
|
n=50
|
||||||
|
)
|
||||||
policy_group.transmit()
|
networky_stuff = MockNetworkyStuff()
|
||||||
|
policy_group.transmit(networky_stuff)
|
||||||
|
|
Loading…
Reference in New Issue