mirror of https://github.com/nucypher/nucypher.git
Deprecate CLI demo module; Respond to RFC & cleanup
parent
d615587e64
commit
293f9c158c
|
@ -1,165 +0,0 @@
|
|||
# This is an example of Alice setting a Policy on the NuCypher network.
|
||||
# In this example, Alice uses n=1, which is almost always a bad idea. Don't do it.
|
||||
|
||||
# WIP w/ hendrix@3.0.0
|
||||
import sys
|
||||
|
||||
import click
|
||||
import datetime
|
||||
import maya
|
||||
|
||||
from nucypher.blockchain.eth.chains import Blockchain
|
||||
from nucypher.characters.lawful import Alice, Bob
|
||||
from nucypher.characters.lawful import Ursula
|
||||
from nucypher.config.characters import UrsulaConfiguration, AliceConfiguration, BobConfiguration
|
||||
from nucypher.data_sources import DataSource
|
||||
from nucypher.network.middleware import RestMiddleware
|
||||
from umbral.keys import UmbralPublicKey
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option('--federated-only', is_flag=True)
|
||||
def run_demo(federated_only):
|
||||
|
||||
##############################################
|
||||
# This is already running in another process.
|
||||
##############################################
|
||||
|
||||
if federated_only is False:
|
||||
BLOCKCHAIN = Blockchain.connect()
|
||||
|
||||
#########
|
||||
# Alice #
|
||||
#########
|
||||
|
||||
ALICE = AliceConfiguration(federated_only=federated_only,
|
||||
network_middleware=RestMiddleware(),
|
||||
start_learning_now=True,
|
||||
load_metadata=True,
|
||||
abort_on_learning_error=True,
|
||||
learn_on_same_thread=False).produce() # TODO: 289
|
||||
|
||||
# Here are our Policy details.
|
||||
policy_end_datetime = maya.now() + datetime.timedelta(days=5)
|
||||
m = 2
|
||||
n = 3
|
||||
label = b"secret/files/and/stuff"
|
||||
|
||||
# Alice grants to Bob.
|
||||
BOB = BobConfiguration(federated_only=federated_only,
|
||||
learn_on_same_thread=False,
|
||||
start_learning_now=True).produce()
|
||||
|
||||
ALICE.start_learning_loop(now=True)
|
||||
policy = ALICE.grant(BOB,
|
||||
label,
|
||||
m=m,
|
||||
n=n,
|
||||
expiration=policy_end_datetime)
|
||||
|
||||
# Alice puts her public key somewhere for Bob to find later...
|
||||
alices_pubkey_bytes_saved_for_posterity = bytes(ALICE.stamp)
|
||||
|
||||
# ...and then disappears from the internet.
|
||||
del ALICE
|
||||
# (this is optional of course - she may wish to remain in order to create
|
||||
# new policies in the future. The point is - she is no longer obligated.
|
||||
|
||||
#####################
|
||||
# some time passes. #
|
||||
# ... #
|
||||
# #
|
||||
# ... #
|
||||
# And now for Bob. #
|
||||
#####################
|
||||
|
||||
# Bob wants to join the policy so that he can receive any future
|
||||
# data shared on it.
|
||||
# He needs a few pieces of knowledge to do that.
|
||||
BOB.join_policy(label, # The label - he needs to know what data he's after.
|
||||
alices_pubkey_bytes_saved_for_posterity, # To verify the signature, he'll need Alice's public key.
|
||||
# He can also bootstrap himself onto the network more quickly
|
||||
# by providing a list of known nodes at this time.
|
||||
# node_list=[("localhost", 3601)]
|
||||
)
|
||||
|
||||
# Now that Bob has joined the Policy, let's show how DataSources
|
||||
# can share data with the members of this Policy and then how Bob retrieves it.
|
||||
finnegans_wake = open(sys.argv[1], 'rb')
|
||||
|
||||
# We'll also keep track of some metadata to gauge performance.
|
||||
# You can safely ignore from here until...
|
||||
################################################################################
|
||||
|
||||
start_time = datetime.datetime.now()
|
||||
|
||||
for counter, plaintext in enumerate(finnegans_wake):
|
||||
if counter % 20 == 0:
|
||||
now_time = datetime.datetime.now()
|
||||
time_delta = now_time - start_time
|
||||
seconds = time_delta.total_seconds()
|
||||
print("********************************")
|
||||
print("Performed {} PREs".format(counter))
|
||||
print("Elapsed: {}".format(time_delta.total_seconds()))
|
||||
print("PREs per second: {}".format(counter / seconds))
|
||||
print("********************************")
|
||||
|
||||
################################################################################
|
||||
# ...here. OK, pay attention again.
|
||||
# Now it's time for...
|
||||
|
||||
#####################
|
||||
# Using DataSources #
|
||||
#####################
|
||||
|
||||
# Now Alice has set a Policy and Bob has joined it.
|
||||
# You're ready to make some DataSources and encrypt for Bob.
|
||||
|
||||
# It may also be helpful to imagine that you have multiple Bobs,
|
||||
# multiple Labels, or both.
|
||||
|
||||
# First we make a DataSource for this policy.
|
||||
data_source = DataSource(policy_pubkey_enc=policy.public_key)
|
||||
|
||||
# Here's how we generate a MessageKit for the Policy. We also get a signature
|
||||
# here, which can be passed via a side-channel (or posted somewhere public as
|
||||
# testimony) and verified if desired. In this case, the plaintext is a
|
||||
# single passage from James Joyce's Finnegan's Wake.
|
||||
# The matter of whether encryption makes the passage more or less readable
|
||||
# is left to the reader to determine.
|
||||
message_kit, _signature = data_source.encapsulate_single_message(plaintext)
|
||||
|
||||
# The DataSource will want to be able to be verified by Bob, so it leaves
|
||||
# its Public Key somewhere.
|
||||
data_source_public_key = bytes(data_source.stamp)
|
||||
|
||||
# It can save the MessageKit somewhere (IPFS, etc) and then it too can
|
||||
# choose to disappear (although it may also opt to continue transmitting
|
||||
# as many messages as may be appropriate).
|
||||
del data_source
|
||||
|
||||
###############
|
||||
# Back to Bob #
|
||||
###############
|
||||
|
||||
# Bob needs to reconstruct the DataSource.
|
||||
datasource_as_understood_by_bob = DataSource.from_public_keys(
|
||||
policy_public_key=policy.public_key,
|
||||
datasource_public_key=data_source_public_key,
|
||||
label=label
|
||||
)
|
||||
|
||||
# Now Bob can retrieve the original message. He just needs the MessageKit
|
||||
# and the DataSource which produced it.
|
||||
alice_pubkey_restored_from_ancient_scroll = UmbralPublicKey.from_bytes(alices_pubkey_bytes_saved_for_posterity)
|
||||
delivered_cleartexts = BOB.retrieve(message_kit=message_kit,
|
||||
data_source=datasource_as_understood_by_bob,
|
||||
alice_verifying_key=alice_pubkey_restored_from_ancient_scroll)
|
||||
|
||||
# We show that indeed this is the passage originally encrypted by the DataSource.
|
||||
assert plaintext == delivered_cleartexts[0]
|
||||
print("Retrieved: {}".format(delivered_cleartexts[0]))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run_demo()
|
|
@ -52,12 +52,12 @@ URSULA.save_certificate_to_disk(CERTIFICATE_DIR)
|
|||
#########
|
||||
|
||||
|
||||
ALICE = AliceConfiguration(network_middleware=RestMiddleware(),
|
||||
known_nodes=(URSULA,),
|
||||
federated_only=True,
|
||||
always_be_learning=True,
|
||||
known_certificates_dir=CERTIFICATE_DIR,
|
||||
) # TODO: 289
|
||||
ALICE = Alice(network_middleware=RestMiddleware(),
|
||||
known_nodes=(URSULA,),
|
||||
federated_only=True,
|
||||
always_be_learning=True,
|
||||
known_certificates_dir=CERTIFICATE_DIR,
|
||||
)
|
||||
|
||||
# Here are our Policy details.
|
||||
policy_end_datetime = maya.now() + datetime.timedelta(days=5)
|
||||
|
|
|
@ -241,7 +241,7 @@ class Bob(Character):
|
|||
if not self.known_nodes and not self._learning_task.running:
|
||||
# Quick sanity check - if we don't know of *any* Ursulas, and we have no
|
||||
# plans to learn about any more, than this function will surely fail.
|
||||
raise Ursula.NotEnoughUrsulas
|
||||
raise self.NotEnoughTeachers
|
||||
|
||||
treasure_map = self.get_treasure_map_from_known_ursulas(self.network_middleware,
|
||||
map_id)
|
||||
|
|
|
@ -116,7 +116,7 @@ def ecdsa_verify(message: bytes,
|
|||
|
||||
def _save_tls_certificate(certificate: Certificate,
|
||||
full_filepath: str,
|
||||
force: bool = True, # TODO
|
||||
force: bool = True, # TODO: Make configurable, or set to False by default.
|
||||
) -> str:
|
||||
if force is False and os.path.isfile(full_filepath):
|
||||
raise FileExistsError('A TLS certificate already exists at {}.'.format(full_filepath))
|
||||
|
|
|
@ -29,10 +29,6 @@ class VerifiableNode:
|
|||
self.certificate_filepath = certificate_filepath
|
||||
self._interface_signature_object = interface_signature
|
||||
|
||||
# TODO: This gets messy when it is None
|
||||
# (although it being None is actually reasonable in some cases, at least for testing).
|
||||
# Let's make this a method instead that inspects the TLSHostingPower (similar to get_deployer()).
|
||||
|
||||
class InvalidNode(SuspiciousActivity):
|
||||
"""
|
||||
Raised when a node has an invalid characteristic - stamp, interface, or address.
|
||||
|
@ -68,7 +64,10 @@ class VerifiableNode:
|
|||
self.verified_stamp = True
|
||||
return True
|
||||
elif self.federated_only and signature is constants.NOT_SIGNED:
|
||||
raise self.WrongMode("This node can't be verified in this manner, but is OK to use in federated mode if you have reason to believe it is trustworthy.")
|
||||
message = "This node can't be verified in this manner, " \
|
||||
"but is OK to use in federated mode if you" \
|
||||
" have reason to believe it is trustworthy."
|
||||
raise self.WrongMode(message)
|
||||
else:
|
||||
raise self.InvalidNode
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ def test_bob_can_retreive_the_treasure_map_and_decrypt_it(enacted_federated_poli
|
|||
# through a side-channel with Alice.
|
||||
|
||||
# If Bob doesn't know about any Ursulas, he can't find the TreasureMap via the REST swarm:
|
||||
with pytest.raises(Ursula.NotEnoughUrsulas):
|
||||
with pytest.raises(bob.NotEnoughTeachers):
|
||||
treasure_map_from_wire = bob.get_treasure_map(enacted_federated_policy.alice.stamp,
|
||||
enacted_federated_policy.label)
|
||||
|
||||
|
|
Loading…
Reference in New Issue