mirror of https://github.com/nucypher/nucypher.git
127 lines
4.3 KiB
Python
127 lines
4.3 KiB
Python
import json
|
|
import os
|
|
import sys
|
|
import shutil
|
|
import msgpack
|
|
import maya
|
|
import traceback
|
|
from timeit import default_timer as timer
|
|
|
|
from nucypher.characters.lawful import Bob, Ursula, Enrico
|
|
from nucypher.crypto.kits import UmbralMessageKit
|
|
from nucypher.crypto.powers import DecryptingPower, SigningPower
|
|
from nucypher.keystore.keypairs import DecryptingKeypair, SigningKeypair
|
|
from nucypher.network.middleware import RestMiddleware
|
|
|
|
from umbral.keys import UmbralPublicKey
|
|
|
|
from nucypher.utilities.logging import GlobalLoggerSettings
|
|
from nucypher.utilities.sandbox.constants import TEMPORARY_DOMAIN
|
|
|
|
|
|
GlobalLoggerSettings.start_console_logging()
|
|
|
|
######################
|
|
# Boring setup stuff #
|
|
######################
|
|
|
|
try:
|
|
SEEDNODE_URI = sys.argv[1]
|
|
except IndexError:
|
|
SEEDNODE_URI = "localhost:11500"
|
|
|
|
|
|
# TODO: path joins?
|
|
TEMP_DOCTOR_DIR = "{}/doctor-files".format(os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
# Remove previous demo files and create new ones
|
|
shutil.rmtree(TEMP_DOCTOR_DIR, ignore_errors=True)
|
|
|
|
ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URI,
|
|
federated_only=True,
|
|
minimum_stake=0)
|
|
|
|
# To create a Bob, we need the doctor's private keys previously generated.
|
|
from doctor_keys import get_doctor_privkeys
|
|
|
|
doctor_keys = get_doctor_privkeys()
|
|
|
|
bob_enc_keypair = DecryptingKeypair(private_key=doctor_keys["enc"])
|
|
bob_sig_keypair = SigningKeypair(private_key=doctor_keys["sig"])
|
|
enc_power = DecryptingPower(keypair=bob_enc_keypair)
|
|
sig_power = SigningPower(keypair=bob_sig_keypair)
|
|
power_ups = [enc_power, sig_power]
|
|
|
|
print("Creating the Doctor ...")
|
|
|
|
doctor = Bob(
|
|
domains={TEMPORARY_DOMAIN},
|
|
federated_only=True,
|
|
crypto_power_ups=power_ups,
|
|
start_learning_now=True,
|
|
abort_on_learning_error=True,
|
|
known_nodes=[ursula],
|
|
save_metadata=False,
|
|
network_middleware=RestMiddleware(),
|
|
)
|
|
|
|
print("Doctor = ", doctor)
|
|
|
|
# Let's join the policy generated by Alicia. We just need some info about it.
|
|
with open("policy-metadata.json", 'r') as f:
|
|
policy_data = json.load(f)
|
|
|
|
policy_pubkey = UmbralPublicKey.from_bytes(bytes.fromhex(policy_data["policy_pubkey"]))
|
|
alices_sig_pubkey = UmbralPublicKey.from_bytes(bytes.fromhex(policy_data["alice_sig_pubkey"]))
|
|
label = policy_data["label"].encode()
|
|
|
|
print("The Doctor joins policy for label '{}'".format(label.decode("utf-8")))
|
|
doctor.join_policy(label, alices_sig_pubkey)
|
|
|
|
# Now that the Doctor joined the policy in the NuCypher network,
|
|
# he can retrieve encrypted data which he can decrypt with his private key.
|
|
# But first we need some encrypted data!
|
|
# Let's read the file produced by the heart monitor and unpack the MessageKits,
|
|
# which are the individual ciphertexts.
|
|
data = msgpack.load(open("heart_data.msgpack", "rb"), raw=False)
|
|
message_kits = (UmbralMessageKit.from_bytes(k) for k in data['kits'])
|
|
|
|
# The doctor also needs to create a view of the Data Source from its public keys
|
|
data_source = Enrico.from_public_keys(
|
|
verifying_key=data['data_source'],
|
|
policy_encrypting_key=policy_pubkey
|
|
)
|
|
|
|
# Now he can ask the NuCypher network to get a re-encrypted version of each MessageKit.
|
|
for message_kit in message_kits:
|
|
try:
|
|
start = timer()
|
|
retrieved_plaintexts = doctor.retrieve(
|
|
label=label,
|
|
message_kit=message_kit,
|
|
data_source=data_source,
|
|
alice_verifying_key=alices_sig_pubkey
|
|
)
|
|
end = timer()
|
|
|
|
plaintext = msgpack.loads(retrieved_plaintexts[0], raw=False)
|
|
|
|
# Now we can get the heart rate and the associated timestamp,
|
|
# generated by the heart rate monitor.
|
|
heart_rate = plaintext['heart_rate']
|
|
timestamp = maya.MayaDT(plaintext['timestamp'])
|
|
|
|
# This code block simply pretty prints the heart rate info
|
|
terminal_size = shutil.get_terminal_size().columns
|
|
max_width = min(terminal_size, 120)
|
|
columns = max_width - 12 - 27
|
|
scale = columns / 40
|
|
scaled_heart_rate = int(scale * (heart_rate - 60))
|
|
retrieval_time = "Retrieval time: {:8.2f} ms".format(1000 * (end - start))
|
|
line = ("-" * scaled_heart_rate) + "❤︎ ({} BPM)".format(heart_rate)
|
|
line = line.ljust(max_width - 27, " ") + retrieval_time
|
|
print(line)
|
|
except Exception as e:
|
|
# We just want to know what went wrong and continue the demo
|
|
traceback.print_exc()
|