Move PRE examples to their own subfolder.

Update .gitignore appropriately.
pull/3258/head
derekpierre 2023-09-28 11:48:51 -04:00
parent 99d2bd86ae
commit 8ac2af0272
10 changed files with 67 additions and 64 deletions

8
.gitignore vendored
View File

@ -27,10 +27,10 @@ chains
.ethash .ethash
nucypher_cli/examples/examples-runtime-cruft/* nucypher_cli/examples/examples-runtime-cruft/*
nucypher_cli/examples/finnegans-wake.txt nucypher_cli/examples/finnegans-wake.txt
examples/heartbeat_demo/*.json examples/pre/heartbeat_demo/*.json
examples/heartbeat_demo/*.msgpack examples/pre/heartbeat_demo/*.msgpack
examples/heartbeat_demo/doctor-files/ examples/pre/heartbeat_demo/doctor-files/
examples/heartbeat_demo/alicia-files/ examples/pre/heartbeat_demo/alicia-files/
mypy_reports/ mypy_reports/
reports/ reports/
test-* test-*

View File

@ -17,27 +17,26 @@ from nucypher.utilities.logging import GlobalLoggerSettings
# Boring setup stuff # # Boring setup stuff #
###################### ######################
LOG_LEVEL = 'info' LOG_LEVEL = "info"
GlobalLoggerSettings.set_log_level(log_level_name=LOG_LEVEL) GlobalLoggerSettings.set_log_level(log_level_name=LOG_LEVEL)
GlobalLoggerSettings.start_console_logging() GlobalLoggerSettings.start_console_logging()
BOOK_PATH = Path('finnegans-wake-excerpt.txt') BOOK_PATH = Path("finnegans-wake-excerpt.txt")
try: try:
# Replace with ethereum RPC endpoint # Replace with ethereum RPC endpoint
L1_PROVIDER = os.environ['DEMO_L1_PROVIDER_URI'] L1_PROVIDER = os.environ["DEMO_L1_PROVIDER_URI"]
L2_PROVIDER = os.environ['DEMO_L2_PROVIDER_URI'] L2_PROVIDER = os.environ["DEMO_L2_PROVIDER_URI"]
# Replace with wallet filepath. # Replace with wallet filepath.
WALLET_FILEPATH = os.environ['DEMO_L2_WALLET_FILEPATH'] WALLET_FILEPATH = os.environ["DEMO_L2_WALLET_FILEPATH"]
SIGNER_URI = f'keystore://{WALLET_FILEPATH}' SIGNER_URI = f"keystore://{WALLET_FILEPATH}"
# Replace with alice's ethereum address # Replace with alice's ethereum address
ALICE_ADDRESS = os.environ['DEMO_ALICE_ADDRESS'] ALICE_ADDRESS = os.environ["DEMO_ALICE_ADDRESS"]
except KeyError: except KeyError:
raise RuntimeError('Missing environment variables to run demo.') raise RuntimeError("Missing environment variables to run demo.")
print("\n************** Setup **************\n") print("\n************** Setup **************\n")
@ -76,13 +75,14 @@ connect_web3_provider(eth_provider_uri=L2_PROVIDER)
# WARNING: Never give your mainnet password or mnemonic phrase to anyone. # WARNING: Never give your mainnet password or mnemonic phrase to anyone.
# Do not use mainnet keys, create a dedicated software wallet to use for this demo. # Do not use mainnet keys, create a dedicated software wallet to use for this demo.
wallet = Signer.from_signer_uri(SIGNER_URI) wallet = Signer.from_signer_uri(SIGNER_URI)
password = os.environ.get('DEMO_ALICE_PASSWORD') or getpass(f"Enter password to unlock Alice's wallet ({ALICE_ADDRESS[:8]}): ") password = os.environ.get("DEMO_ALICE_PASSWORD") or getpass(
f"Enter password to unlock Alice's wallet ({ALICE_ADDRESS[:8]}): "
)
wallet.unlock_account(account=ALICE_ADDRESS, password=password) wallet.unlock_account(account=ALICE_ADDRESS, password=password)
# This is Alice's PRE payment method. # This is Alice's PRE payment method.
pre_payment_method = SubscriptionManagerPayment( pre_payment_method = SubscriptionManagerPayment(
network=L2_NETWORK, network=L2_NETWORK, eth_provider=L2_PROVIDER
eth_provider=L2_PROVIDER
) )
# This is Alice. # This is Alice.
@ -121,7 +121,8 @@ price = alice.pre_payment_method.quote(expiration=expiration.epoch, shares=share
# Alice grants access to Bob... # Alice grants access to Bob...
policy = alice.grant( policy = alice.grant(
remote_bob, label, remote_bob,
label,
threshold=threshold, threshold=threshold,
shares=shares, shares=shares,
value=price, value=price,
@ -142,13 +143,12 @@ del alice
# Now that Bob has access to the policy, let's show how Enrico the Encryptor # Now that Bob has access to the policy, let's show how Enrico the Encryptor
# can share data with the members of this Policy and then how Bob retrieves it. # can share data with the members of this Policy and then how Bob retrieves it.
with open(BOOK_PATH, 'rb') as file: with open(BOOK_PATH, "rb") as file:
finnegans_wake = file.readlines() finnegans_wake = file.readlines()
print("\n************** Encrypt and Retrieve **************\n") print("\n************** Encrypt and Retrieve **************\n")
for counter, plaintext in enumerate(finnegans_wake): for counter, plaintext in enumerate(finnegans_wake):
# Enrico knows the policy's public key from a side-channel. # Enrico knows the policy's public key from a side-channel.
# In this demo a new enrico is being constructed for each line of text. # In this demo a new enrico is being constructed for each line of text.
# This demonstrates how many individual encryptors may encrypt for a single policy. # This demonstrates how many individual encryptors may encrypt for a single policy.
@ -166,9 +166,11 @@ for counter, plaintext in enumerate(finnegans_wake):
############### ###############
# Now Bob can retrieve the original message by requesting re-encryption from nodes. # Now Bob can retrieve the original message by requesting re-encryption from nodes.
cleartexts = bob.retrieve_and_decrypt([message_kit], cleartexts = bob.retrieve_and_decrypt(
alice_verifying_key=alice_verifying_key, [message_kit],
encrypted_treasure_map=policy.treasure_map) alice_verifying_key=alice_verifying_key,
encrypted_treasure_map=policy.treasure_map,
)
# We show that indeed this is the passage originally encrypted by Enrico. # We show that indeed this is the passage originally encrypted by Enrico.
assert plaintext == cleartexts[0] assert plaintext == cleartexts[0]

View File

@ -34,29 +34,28 @@ from nucypher.utilities.logging import GlobalLoggerSettings
# Boring setup stuff # # Boring setup stuff #
###################### ######################
LOG_LEVEL = 'info' LOG_LEVEL = "info"
GlobalLoggerSettings.set_log_level(log_level_name=LOG_LEVEL) GlobalLoggerSettings.set_log_level(log_level_name=LOG_LEVEL)
GlobalLoggerSettings.start_console_logging() GlobalLoggerSettings.start_console_logging()
TEMP_ALICE_DIR = Path('/', 'tmp', 'heartbeat-demo-alice') TEMP_ALICE_DIR = Path("/", "tmp", "heartbeat-demo-alice")
POLICY_FILENAME = "policy-metadata.json" POLICY_FILENAME = "policy-metadata.json"
shutil.rmtree(TEMP_ALICE_DIR, ignore_errors=True) shutil.rmtree(TEMP_ALICE_DIR, ignore_errors=True)
try: try:
# Replace with ethereum RPC endpoint # Replace with ethereum RPC endpoint
L1_PROVIDER = os.environ['DEMO_L1_PROVIDER_URI'] L1_PROVIDER = os.environ["DEMO_L1_PROVIDER_URI"]
L2_PROVIDER = os.environ['DEMO_L2_PROVIDER_URI'] L2_PROVIDER = os.environ["DEMO_L2_PROVIDER_URI"]
# Replace with wallet filepath. # Replace with wallet filepath.
WALLET_FILEPATH = os.environ['DEMO_L2_WALLET_FILEPATH'] WALLET_FILEPATH = os.environ["DEMO_L2_WALLET_FILEPATH"]
SIGNER_URI = f'keystore://{WALLET_FILEPATH}' SIGNER_URI = f"keystore://{WALLET_FILEPATH}"
# Replace with alice's ethereum address # Replace with alice's ethereum address
ALICE_ADDRESS = os.environ['DEMO_ALICE_ADDRESS'] ALICE_ADDRESS = os.environ["DEMO_ALICE_ADDRESS"]
except KeyError: except KeyError:
raise RuntimeError('Missing environment variables to run demo.') raise RuntimeError("Missing environment variables to run demo.")
L1_NETWORK = "lynx" L1_NETWORK = "lynx"
L2_NETWORK = "mumbai" L2_NETWORK = "mumbai"
@ -74,13 +73,14 @@ connect_web3_provider(eth_provider_uri=L2_PROVIDER) # Connect to the layer 2 pr
# WARNING: Never give your mainnet password or mnemonic phrase to anyone. # WARNING: Never give your mainnet password or mnemonic phrase to anyone.
# Do not use mainnet keys, create a dedicated software wallet to use for this demo. # Do not use mainnet keys, create a dedicated software wallet to use for this demo.
wallet = Signer.from_signer_uri(SIGNER_URI) wallet = Signer.from_signer_uri(SIGNER_URI)
password = os.environ.get('DEMO_ALICE_PASSWORD') or getpass(f"Enter password to unlock Alice's wallet ({ALICE_ADDRESS[:8]}): ") password = os.environ.get("DEMO_ALICE_PASSWORD") or getpass(
f"Enter password to unlock Alice's wallet ({ALICE_ADDRESS[:8]}): "
)
wallet.unlock_account(account=ALICE_ADDRESS, password=password) wallet.unlock_account(account=ALICE_ADDRESS, password=password)
# This is Alice's PRE payment method. # This is Alice's PRE payment method.
pre_payment_method = SubscriptionManagerPayment( pre_payment_method = SubscriptionManagerPayment(
network=L2_NETWORK, network=L2_NETWORK, eth_provider=L2_PROVIDER
eth_provider=L2_PROVIDER
) )
# This is Alicia. # This is Alicia.
@ -101,7 +101,7 @@ alicia.start_learning_loop(now=True)
# At this point, Alicia is fully operational and can create policies. # At this point, Alicia is fully operational and can create policies.
# The Policy Label is a bytestring that categorizes the data that Alicia wants to share. # The Policy Label is a bytestring that categorizes the data that Alicia wants to share.
# Note: we add some random chars to create different policies, only for demonstration purposes # Note: we add some random chars to create different policies, only for demonstration purposes
label = "heart-data-❤️-"+os.urandom(4).hex() label = "heart-data-❤️-" + os.urandom(4).hex()
label = label.encode() label = label.encode()
# Alicia can create the public key associated to the policy label, # Alicia can create the public key associated to the policy label,
@ -121,9 +121,7 @@ print(
# heart rate measurements from a heart monitor # heart rate measurements from a heart monitor
import heart_monitor # noqa: E402 import heart_monitor # noqa: E402
heart_monitor.generate_heart_rate_samples(policy_pubkey, heart_monitor.generate_heart_rate_samples(policy_pubkey, samples=50, save_as_file=True)
samples=50,
save_as_file=True)
# Alicia now wants to share data associated with this label. # Alicia now wants to share data associated with this label.
@ -149,11 +147,13 @@ threshold, shares = 2, 3
# With this information, Alicia creates a policy granting access to Bob. # With this information, Alicia creates a policy granting access to Bob.
# The policy is sent to the TACo Application on the Threshold Network. # The policy is sent to the TACo Application on the Threshold Network.
print("Creating access policy for the Doctor...") print("Creating access policy for the Doctor...")
policy = alicia.grant(bob=doctor_strange, policy = alicia.grant(
label=label, bob=doctor_strange,
threshold=threshold, label=label,
shares=shares, threshold=threshold,
expiration=policy_end_datetime) shares=shares,
expiration=policy_end_datetime,
)
print("Done!") print("Done!")
# For the demo, we need a way to share with Bob some additional info # For the demo, we need a way to share with Bob some additional info
@ -162,9 +162,9 @@ policy_info = {
"policy_pubkey": policy.public_key.to_compressed_bytes().hex(), "policy_pubkey": policy.public_key.to_compressed_bytes().hex(),
"alice_sig_pubkey": bytes(alicia.stamp).hex(), "alice_sig_pubkey": bytes(alicia.stamp).hex(),
"label": label.decode("utf-8"), "label": label.decode("utf-8"),
"treasure_map": base64.b64encode(bytes(policy.treasure_map)).decode() "treasure_map": base64.b64encode(bytes(policy.treasure_map)).decode(),
} }
filename = POLICY_FILENAME filename = POLICY_FILENAME
with open(filename, 'w') as f: with open(filename, "w") as f:
json.dump(policy_info, f) json.dump(policy_info, f)

View File

@ -51,7 +51,7 @@ doctor = Bob(
print("Doctor = ", doctor) print("Doctor = ", doctor)
# Let's join the policy generated by Alicia. We just need some info about it. # Let's join the policy generated by Alicia. We just need some info about it.
with open("policy-metadata.json", 'r') as f: with open("policy-metadata.json", "r") as f:
policy_data = json.load(f) policy_data = json.load(f)
policy_pubkey = PublicKey.from_compressed_bytes( policy_pubkey = PublicKey.from_compressed_bytes(
@ -61,14 +61,16 @@ alices_sig_pubkey = PublicKey.from_compressed_bytes(
bytes.fromhex(policy_data["alice_sig_pubkey"]) bytes.fromhex(policy_data["alice_sig_pubkey"])
) )
label = policy_data["label"].encode() label = policy_data["label"].encode()
treasure_map = EncryptedTreasureMap.from_bytes(base64.b64decode(policy_data["treasure_map"].encode())) treasure_map = EncryptedTreasureMap.from_bytes(
base64.b64decode(policy_data["treasure_map"].encode())
)
# The Doctor can retrieve encrypted data which he can decrypt with his private key. # The Doctor can retrieve encrypted data which he can decrypt with his private key.
# But first we need some encrypted data! # But first we need some encrypted data!
# Let's read the file produced by the heart monitor and unpack the MessageKits, # Let's read the file produced by the heart monitor and unpack the MessageKits,
# which are the individual ciphertexts. # which are the individual ciphertexts.
data = msgpack.load(open("heart_data.msgpack", "rb"), raw=False) data = msgpack.load(open("heart_data.msgpack", "rb"), raw=False)
message_kits = (MessageKit.from_bytes(k) for k in data['kits']) message_kits = (MessageKit.from_bytes(k) for k in data["kits"])
# Now he can ask the TACo nodes on the Threshold Network # Now he can ask the TACo nodes on the Threshold Network
# to get a re-encrypted version of each MessageKit. # to get a re-encrypted version of each MessageKit.
@ -77,7 +79,7 @@ for message_kit in message_kits:
retrieved_plaintexts = doctor.retrieve_and_decrypt( retrieved_plaintexts = doctor.retrieve_and_decrypt(
[message_kit], [message_kit],
alice_verifying_key=alices_sig_pubkey, alice_verifying_key=alices_sig_pubkey,
encrypted_treasure_map=treasure_map encrypted_treasure_map=treasure_map,
) )
end = timer() end = timer()
@ -85,8 +87,8 @@ for message_kit in message_kits:
# Now we can get the heart rate and the associated timestamp, # Now we can get the heart rate and the associated timestamp,
# generated by the heart rate monitor. # generated by the heart rate monitor.
heart_rate = plaintext['heart_rate'] heart_rate = plaintext["heart_rate"]
timestamp = maya.MayaDT(plaintext['timestamp']) timestamp = maya.MayaDT(plaintext["timestamp"])
# This code block simply pretty prints the heart rate info # This code block simply pretty prints the heart rate info
terminal_size = shutil.get_terminal_size().columns terminal_size = shutil.get_terminal_size().columns

View File

@ -3,8 +3,8 @@ from pathlib import Path
from nucypher_core.umbral import PublicKey, SecretKey from nucypher_core.umbral import PublicKey, SecretKey
DOCTOR_PUBLIC_JSON = Path('doctor.public.json') DOCTOR_PUBLIC_JSON = Path("doctor.public.json")
DOCTOR_PRIVATE_JSON = Path('doctor.private.json') DOCTOR_PRIVATE_JSON = Path("doctor.private.json")
def generate_doctor_keys(): def generate_doctor_keys():
@ -16,7 +16,7 @@ def generate_doctor_keys():
"sig": sig_privkey.to_be_bytes().hex(), "sig": sig_privkey.to_be_bytes().hex(),
} }
with open(DOCTOR_PRIVATE_JSON, 'w') as f: with open(DOCTOR_PRIVATE_JSON, "w") as f:
json.dump(doctor_privkeys, f) json.dump(doctor_privkeys, f)
enc_pubkey = enc_privkey.public_key() enc_pubkey = enc_privkey.public_key()
@ -25,7 +25,7 @@ def generate_doctor_keys():
"enc": enc_pubkey.to_compressed_bytes().hex(), "enc": enc_pubkey.to_compressed_bytes().hex(),
"sig": sig_pubkey.to_compressed_bytes().hex(), "sig": sig_pubkey.to_compressed_bytes().hex(),
} }
with open(DOCTOR_PUBLIC_JSON, 'w') as f: with open(DOCTOR_PUBLIC_JSON, "w") as f:
json.dump(doctor_pubkeys, f) json.dump(doctor_pubkeys, f)

View File

Before

Width:  |  Height:  |  Size: 677 KiB

After

Width:  |  Height:  |  Size: 677 KiB

View File

@ -5,12 +5,12 @@ import msgpack
from nucypher.characters.lawful import Enrico from nucypher.characters.lawful import Enrico
HEART_DATA_FILENAME = 'heart_data.msgpack' HEART_DATA_FILENAME = "heart_data.msgpack"
def generate_heart_rate_samples(policy_pubkey, def generate_heart_rate_samples(
samples: int = 500, policy_pubkey, samples: int = 500, save_as_file: bool = False
save_as_file: bool = False): ):
data_source = Enrico(encrypting_key=policy_pubkey) data_source = Enrico(encrypting_key=policy_pubkey)
heart_rate = 80 heart_rate = 80
@ -20,13 +20,12 @@ def generate_heart_rate_samples(policy_pubkey,
for _ in range(samples): for _ in range(samples):
# Simulated heart rate data # Simulated heart rate data
# Normal resting heart rate for adults: between 60 to 100 BPM # Normal resting heart rate for adults: between 60 to 100 BPM
heart_rate = random.randint(max(60, heart_rate-5), heart_rate = random.randint(max(60, heart_rate - 5), min(100, heart_rate + 5))
min(100, heart_rate+5))
now += 3 now += 3
heart_rate_data = { heart_rate_data = {
'heart_rate': heart_rate, "heart_rate": heart_rate,
'timestamp': now, "timestamp": now,
} }
plaintext = msgpack.dumps(heart_rate_data, use_bin_type=True) plaintext = msgpack.dumps(heart_rate_data, use_bin_type=True)
@ -36,7 +35,7 @@ def generate_heart_rate_samples(policy_pubkey,
kits.append(kit_bytes) kits.append(kit_bytes)
data = { data = {
'kits': kits, "kits": kits,
} }
if save_as_file: if save_as_file: