async def onRequestBuy(event): SEEDNODE_URI = os.getenv("SEEDNODE_URI") ursula = Ursula.from_seed_and_stake_info(seed_uri="localhost:11500", federated_only=True, minimum_stake=0) NEW_PASSWORD = "******" try: keyring = NucypherKeyring.generate( checksum_address='0xf61DBAbF5Ac0A3F99e91b663A590cF4cB58563D9', password=NEW_PASSWORD, # used to encrypt nucypher private keys keyring_root="//home/ghard/.local/share/nucypher/keyring") except: # Restore an existing Alice keyring keyring = NucypherKeyring( account='0xf61DBAbF5Ac0A3F99e91b663A590cF4cB58563D9') keyring.unlock(password=NEW_PASSWORD) alice = Alice(keyring=keyring, known_nodes=[ursula], federated_only=True, learn_on_same_thread=True, domain=TEMPORARY_DOMAIN) user = event.args["buyer"] keys = masterfile_contract.functions.userKeys(user).call() print(user) print(keys) bob = Bob.from_public_keys(verifying_key=keys[0], encrypting_key=keys[1], federated_only=True) policy = alice.grant(bob, label=(str(event.args["tokenId"]) + os.urandom(4).hex()).encode(), m=2, n=3, expiration=maya.now() + timedelta(days=5)) policy.treasure_map_publisher.block_until_complete() print("done")
remote_bob = Bob.from_public_keys( encrypting_key=encrypting_key, verifying_key=verifying_key, ) # These are the policy details. expiration = maya.now() + datetime.timedelta(days=1) threshold, shares = 2, 3 price = alice.payment_method.quote(expiration=expiration.epoch, shares=shares).value # Alice grants access to Bob... policy = alice.grant( remote_bob, label, threshold=threshold, shares=shares, value=price, expiration=expiration, ) # ...and then disappears from the internet. # # Note that local characters (alice and bob), as opposed to objects representing # remote characters constructed from public data (remote_alice and remote_bob) # run node discovery in a background thread and must be stopped explicitly. alice.disenchant() del alice ######################### # Enrico, the Encryptor # #########################
start_learning_now=True, learn_on_same_thread=True) ALICE.start_learning_loop(now=True) ########################################### # Creating our policies for data sharing # ########################################### print( "Alice, our patient, shares her data with researchers A, B, and D. She opts not to share with C because their trial is not relevant to her." ) print("Creating policy for trial A") policy_A = ALICE.grant(BOB_A, label_A, m=m, n=n, expiration=policy_end_datetime) assert policy_A.public_key == policy_pubkey_A print("Creating policy for trial D") policy_D = ALICE.grant(BOB_D, label_D, m=m, n=n, expiration=policy_end_datetime) assert policy_D.public_key == policy_pubkey_D #############################################
m, n = 2, 3 # Alice uses Bob's Decentralized ID on-chain to collects relevant data and create a Bob profile bob_nucypher_decrypting_pub_key_as_seen_by_alice = bob_proxy_account.functions.getData( nucypher_decrypting_key).call() bob_nucypher_signing_pub_key_as_seen_by_alice = bob_proxy_account.functions.getData( nucypher_signing_key).call() bob_as_seen_by_alice = Bob.from_public_keys( powers_and_material={ DecryptingPower: bob_nucypher_decrypting_pub_key_as_seen_by_alice, SigningPower: bob_nucypher_signing_pub_key_as_seen_by_alice }) # Alice grants access to Bob policy = alice.grant(bob_as_seen_by_alice, health_label, m=m, n=n, expiration=policy_end_datetime) assert policy.public_key == policy_pubkey # Alice can disappear from the Internet. del alice # Bob joins the Policy alice_nucypher_signing_pub_key_as_seen_by_bob = alice_proxy_account.functions.getData( nucypher_signing_key).call() bob.join_policy(health_label, alice_nucypher_signing_pub_key_as_seen_by_bob) # Threaded function simulating Bob's behaviour, watching for on-chain claims def decrypt_first_message():
policy_end_datetime = maya.now() + datetime.timedelta(days=5) m = 2 n = 3 label = b"secret/files/and/stuff" # Alice grants to Bob. BOB = Bob(seed_nodes=[ursula_seed_node], network_middleware=RestMiddleware(), federated_only=True, start_learning_now=True, learn_on_same_thread=True, known_certificates_dir=CERTIFICATE_DIR) 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. #
encrypting_key=doctor_pubkeys['enc'], federated_only=True) # Here are our remaining Policy details, such as: # - Policy expiration date policy_end_datetime = maya.now() + datetime.timedelta(days=1) # - m-out-of-n: This means Alicia splits the re-encryption key in 5 pieces and # she requires Bob to seek collaboration of at least 3 Ursulas threshold, shares = 2, 3 # With this information, Alicia creates a policy granting access to Bob. # The policy is sent to the NuCypher network. print("Creating access policy for the Doctor...") policy = alicia.grant(bob=doctor_strange, label=label, threshold=threshold, shares=shares, expiration=policy_end_datetime) print("Done!") # For the demo, we need a way to share with Bob some additional info # about the policy, so we store it in a JSON file policy_info = { "policy_pubkey": bytes(policy.public_key).hex(), "alice_sig_pubkey": bytes(alicia.stamp).hex(), "label": label.decode("utf-8"), "treasure_map": base64.b64encode(bytes(policy.treasure_map)).decode() } filename = POLICY_FILENAME with open(filename, 'w') as f:
# can encrypt data originally intended for Alice, but that # can be shared with any Bob that Alice grants access. # Alice already knows Bob's public keys from a side-channel. remote_bob = Bob.from_public_keys(encrypting_key=encrypting_key, verifying_key=verifying_key) # These are the policy details for bob. # In this example bob will be granted access for 1 day, # trusting 2 of 3 nodes paying each of them 50 gwei per period. expiration = maya.now() + datetime.timedelta(days=1) rate = Web3.toWei(50, 'gwei') m, n = 2, 3 # Alice grants access to Bob... alice.grant(remote_bob, label, m=m, n=n, rate=rate, expiration=expiration) # ...and then disappears from the internet. # # Note that local characters (alice and bob), as opposed to objects representing # remote characters constructed from public data (remote_alice and remote_bob) # run node discovery in a background thread and must be stopped explicitly. alice.disenchant() del alice ######################### # 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.
# Alice already knows Bob's public keys from a side-channel. remote_bob = Bob.from_public_keys(encrypting_key=encrypting_key, verifying_key=verifying_key) # These are the policy details for bob. # In this example bob will be granted access for 1 day, # trusting 2 of 3 nodes paying each of them 50 gwei per period. expiration = maya.now() + datetime.timedelta(days=1) rate = Web3.toWei(50, 'gwei') threshold, shares = 2, 3 # Alice grants access to Bob... policy = alice.grant(remote_bob, label, threshold=threshold, shares=shares, rate=rate, expiration=expiration) # ...and then disappears from the internet. # # Note that local characters (alice and bob), as opposed to objects representing # remote characters constructed from public data (remote_alice and remote_bob) # run node discovery in a background thread and must be stopped explicitly. alice.disenchant() del alice ######################### # Enrico, the Encryptor # #########################
alice.block_until_number_of_known_nodes_is(8, timeout=30, learn_on_this_thread=True) # Alice can get the public key even before creating the policy. # From this moment on, any Data Source that knows the public key # can encrypt data originally intended for Alice, but that can be shared with # any Bob that Alice grants access. policy_public_key = alice.get_policy_encrypting_key_from_label(label) # Alice grant access to Bob. She already knows Bob's public keys from a side-channel. remote_bob = Bob.from_public_keys(encrypting_key=encrypting_key, verifying_key=verifying_key) policy = alice.grant(remote_bob, label, threshold=threshold, shares=shares, expiration=policy_end_datetime) assert policy.public_key == policy_public_key # Alice puts her public key somewhere for Bob to find later... alice_verifying_key = alice.stamp.as_umbral_pubkey() # ...and then disappears from the internet. # # Note that local characters (alice and bob), as opposed to objects representing # remote characters constructed from public data (remote_alice and remote_bob) # run a learning loop in a background thread and need to be stopped explicitly. alice.disenchant() del alice
alice.block_until_number_of_known_nodes_is(8, timeout=30, learn_on_this_thread=True) # Alice can get the public key even before creating the policy. # From this moment on, any Data Source that knows the public key # can encrypt data originally intended for Alice, but that can be shared with # any Bob that Alice grants access. policy_public_key = alice.get_policy_encrypting_key_from_label(label) # Alice grant access to Bob. She already knows Bob's public keys from a side-channel. remote_bob = Bob.from_public_keys(encrypting_key=encrypting_key, verifying_key=verifying_key) policy = alice.grant(remote_bob, label, m=m, n=n, expiration=policy_end_datetime) assert policy.public_key == policy_public_key policy.treasure_map_publisher.block_until_complete() # Alice puts her public key somewhere for Bob to find later... alice_verifying_key = bytes(alice.stamp) # ...and then disappears from the internet. # # Note that local characters (alice and bob), as opposed to objects representing # remote characters constructed from public data (remote_alice and remote_bob) # run a learning loop in a background thread and need to be stopped explicitly. alice.disenchant()
class Client(object): URSULA_SEEDNODE_URI = "" def __init__(self, ursula_url): self.URSULA_SEEDNODE_URI = ursula_url # todo : customise ipfs host self.ipfs = ipfsapi.connect("https://ipfs.infura.io", 5001) random_name = fake.name() self.label = random_name.encode() self.m = 2 self.n = 3 def node_info(self): return self.ipfs.id() def generate_recipient_keys(self): enc_privkey = UmbralPrivateKey.gen_key() sig_privkey = UmbralPrivateKey.gen_key() recipient_privkeys = { 'enc': enc_privkey.to_bytes().hex(), 'sig': sig_privkey.to_bytes().hex(), } enc_pubkey = enc_privkey.get_pubkey() sig_pubkey = sig_privkey.get_pubkey() recipient_pubkeys = { 'enc': enc_pubkey.to_bytes().hex(), 'sig': sig_pubkey.to_bytes().hex() } return recipient_privkeys, recipient_pubkeys def generate_owner_policy_public_key(self, max_days): self.ursula = Ursula.from_seed_and_stake_info( seed_uri=self.URSULA_SEEDNODE_URI, federated_only=True, minimum_stake=0) policy_end_datetime = maya.now() + datetime.timedelta(days=max_days) self.ALICE = Alice(network_middleware=RestMiddleware(), known_nodes=[self.ursula], learn_on_same_thread=True, federated_only=True) policy_pubkey = self.ALICE.get_policy_pubkey_from_label(self.label) return policy_pubkey def uploadFile(self, filename, policy_pubkey): data_source = Enrico(policy_encrypting_key=policy_pubkey) data_source_public_key = bytes(data_source.stamp) file = open(filename, "r").read() encoded = base64.b64encode(file.encode()) encrypt_message, _signature = data_source.encrypt_message(encoded) kit_bytes = encrypt_message.to_bytes() try: os.mkdir("./tmp") except Exception as e: logging.info("temp folder exist") temp = open('./tmp/' + filename, 'wb') temp.write(kit_bytes) temp.close() res = self.ipfs.add('./tmp/' + filename) receipt_info = { "data_source_public_key": data_source_public_key.hex(), "hash_key": res['Hash'] } return receipt_info def authorize(self, recipient_pubkeys, max_days=5): powers_and_material = { DecryptingPower: UmbralPublicKey.from_bytes(bytes.fromhex( recipient_pubkeys["enc"])), SigningPower: UmbralPublicKey.from_bytes(bytes.fromhex(recipient_pubkeys["sig"])) } recipient = Bob.from_public_keys( powers_and_material=powers_and_material, federated_only=True) policy_end_datetime = maya.now() + datetime.timedelta(days=max_days) m, n = self.m, self.n self.ALICE.start_learning_loop(now=True) policy = self.ALICE.grant(recipient, self.label, m=m, n=n, expiration=policy_end_datetime) alices_pubkey = bytes(self.ALICE.stamp) policy_info = { "policy_pubkey": policy.public_key.to_bytes().hex(), "alice_sig_pubkey": alices_pubkey, "label": self.label.decode("utf-8") } return policy_info def downloadFile(self, downloadFilename, recipient_privkeys, receipt, policy_info): hash = receipt['hash_key'] input = self.ipfs.cat(hash) ursula = Ursula.from_seed_and_stake_info( seed_uri=self.URSULA_SEEDNODE_URI, federated_only=True, minimum_stake=0) bob_enc_keypair = DecryptingKeypair( private_key=UmbralPrivateKey.from_bytes( bytes.fromhex(recipient_privkeys["enc"]))) bob_sig_keypair = SigningKeypair( private_key=UmbralPrivateKey.from_bytes( bytes.fromhex(recipient_privkeys["sig"]))) enc_power = DecryptingPower(keypair=bob_enc_keypair) sig_power = SigningPower(keypair=bob_sig_keypair) power_ups = [enc_power, sig_power] authorizedRecipient = Bob( is_me=True, 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(), ) policy_pubkey = UmbralPublicKey.from_bytes( bytes.fromhex(policy_info["policy_pubkey"])) enrico_as_understood = Enrico.from_public_keys( { SigningPower: UmbralPublicKey.from_bytes( bytes.fromhex(receipt['data_source_public_key'])) }, #{SigningPower: data_source_public_key}, policy_encrypting_key=policy_pubkey) alice_pubkey_restored = UmbralPublicKey.from_bytes( (policy_info['alice_sig_pubkey'])) authorizedRecipient.join_policy(policy_info['label'].encode(), alice_pubkey_restored) kit = UmbralMessageKit.from_bytes(input) delivered_cleartexts = authorizedRecipient.retrieve( message_kit=kit, data_source=enrico_as_understood, alice_verifying_key=alice_pubkey_restored, label=(policy_info['label'].encode())) #delivered_cleartexts = authorizedRecipient.retrieve(message_kit=kit,data_source=data_source,alice_verifying_key=alice_pubkey_restored, label=(policy_info['label'].encode()) ) data = base64.b64decode(delivered_cleartexts[0]) output = open('./' + downloadFilename, 'wb') output.write(data) output.close()