def createGenericAlicia(passphrase): print('createGenericAlicia') TEMP_ALICE_DIR = os.path.join('/', 'tmp', 'zkDonationFlaskApp') shutil.rmtree(TEMP_ALICE_DIR, ignore_errors=True) ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URI, federated_only=True, minimum_stake=0) alice_config = AliceConfiguration( config_root=os.path.join(TEMP_ALICE_DIR), domains={TEMPORARY_DOMAIN}, known_nodes={ursula}, start_learning_now=False, federated_only=True, learn_on_same_thread=True, ) alice_config.initialize(password=passphrase) alice_config.keyring.unlock(password=passphrase) alicia = alice_config.produce() alice_config.to_configuration_file() alicia.start_learning_loop(now=True) return alicia
def initialize_alice(): ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URI, federated_only=True, minimum_stake=0) # If anything fails, let's create Alicia from scratch # Remove previous demo files and create new ones shutil.rmtree(TEMP_ALICE_DIR, ignore_errors=True) alice_config = AliceConfiguration( config_root=os.path.join(TEMP_ALICE_DIR), domains={TEMPORARY_DOMAIN}, known_nodes={ursula}, start_learning_now=False, federated_only=True, learn_on_same_thread=True, ) alice_config.initialize(password=passphrase) alice_config.keyring.unlock(password=passphrase) # We will save Alicia's config to a file for later use alice_config_file = alice_config.to_configuration_file() with open(os.path.join(TEMP_ALICE_DIR, 'alice.config.json'), 'w') as f: f.write(open(alice_config_file).read()) alicia = alice_config.produce() # Let's get to learn about the NuCypher network alicia.start_learning_loop(now=True) return alicia, alice_config_file
def create_new_user(self, name, password): print("create_new_user") passphrase = password direco = "accounts/"+ name # alice_config = AliceConfiguration( # config_root=os.path.join(direco), # is_me=True, known_nodes={self.ursula}, start_learning_now=True, # federated_only=True, learn_on_same_thread=True, # ) # alice_config.initialize(password=passphrase) # alice_config.keyring.unlock(password=passphrase) # alice_config_file = alice_config.to_configuration_file() alice_config = AliceConfiguration( config_root=os.path.join(direco), # is_me=True, known_nodes={self.ursula}, start_learning_now=False, federated_only=True, learn_on_same_thread=True, ) alice_config.initialize(password=passphrase) alice_config.keyring.unlock(password=passphrase) # print(dir(alice_config.keyring)) alice = alice_config.produce() alice_config_file = alice_config.to_configuration_file() alice.start_learning_loop(now=True) enc_privkey = UmbralPrivateKey.gen_key() sig_privkey = UmbralPrivateKey.gen_key() doctor_privkeys = { 'enc': enc_privkey.to_bytes().hex(), 'sig': sig_privkey.to_bytes().hex(), } DOCTOR_PUBLIC_JSON = direco + '/recipent.public.json' DOCTOR_PRIVATE_JSON = direco + '/recipent.private.json' with open(DOCTOR_PRIVATE_JSON, 'w') as f: json.dump(doctor_privkeys, f) enc_pubkey = enc_privkey.get_pubkey() sig_pubkey = sig_privkey.get_pubkey() doctor_pubkeys = { 'enc': enc_pubkey.to_bytes().hex(), 'sig': sig_pubkey.to_bytes().hex() } with open(DOCTOR_PUBLIC_JSON, 'w') as f: json.dump(doctor_pubkeys, f) # print(dir(alice)) return alice
def _get_alice(self): # Gets an Alice instance #print('Getting an Alice') try: # If we had an existing Alicia in disk, let's get it from there alice_config_file = os.path.join(self.TEMP_ALICE_DIR, "config_root", "alice.config") new_alice_config = AliceConfiguration.from_configuration_file( filepath=alice_config_file, known_nodes=[self.ursula], network_middleware=RestMiddleware(), start_learning_now=False, save_metadata=False, ) #new_alice_config.keyring.unlock(password=self.passphrase) alicia = new_alice_config.produce() except: # If anything fails, let's create Alicia from scratch # Remove previous demo files and create new ones #print("Creating ALICE") shutil.rmtree(self.TEMP_ALICE_DIR, ignore_errors=True) os.mkdir(self.TEMP_ALICE_DIR) os.mkdir(self.TEMP_ALICE_URSULA_DIR) alice_config = AliceConfiguration( config_root=os.path.join(self.TEMP_ALICE_DIR, "config_root"), is_me=True, known_nodes=[self.ursula], start_learning_now=False, federated_only=True, learn_on_same_thread=True, ) alice_config.initialize(password=self.passphrase) alice_config.keyring.unlock(password=self.passphrase) alicia = alice_config.produce() # We will save Alicia's config to a file for later use alice_config_file = alice_config.to_configuration_file() # Let's get to learn about the NuCypher network alicia.start_learning_loop(now=True) return alicia
def generateKeys(): # Fetch JSON from request print('####') print(request.data) json_data = json.loads(request.data.decode('utf-8')) # Fetch username and password username = json_data['username'] print (username, "username") password = json_data['password'] # directory to store alice keys ALICE_DIR = os.path.join(os.getcwd() , 'alice/' + username) print(ALICE_DIR) alice_config = AliceConfiguration( domains={'TEMPORARY_DOMAIN'}, config_root=os.path.join(ALICE_DIR), is_me=True, known_nodes={ursula}, start_learning_now=False, federated_only=True, learn_on_same_thread=True ) alice_config.initialize(password=password) alice_config.keyring.unlock(password=password) file = alice_config.to_configuration_file() alicia = alice_config.produce() alicia.start_learning_loop(now=True) data = {} data['alice'] = file data['bob'] = generate_doctor_keys(username=username); print(data) return jsonify(data)
def test_alices_powers_are_persistent(federated_ursulas, tmpdir): # Create a non-learning AliceConfiguration alice_config = AliceConfiguration(config_root=os.path.join( tmpdir, 'nucypher-custom-alice-config'), network_middleware=MockRestMiddleware(), known_nodes=federated_ursulas, start_learning_now=False, federated_only=True, save_metadata=False, reload_metadata=False) # Generate keys and write them the disk alice_config.initialize(password=INSECURE_DEVELOPMENT_PASSWORD) # Unlock Alice's keyring alice_config.keyring.unlock(password=INSECURE_DEVELOPMENT_PASSWORD) # Produce an Alice alice = alice_config() # or alice_config.produce() # Save Alice's node configuration file to disk for later use alice_config_file = alice_config.to_configuration_file() # Let's save Alice's public keys too to check they are correctly restored later alices_verifying_key = alice.public_keys(SigningPower) alices_receiving_key = alice.public_keys(DecryptingPower) # Next, let's fix a label for all the policies we will create later. label = b"this_is_the_path_to_which_access_is_being_granted" # Even before creating the policies, we can know what will be its public key. # This can be used by Enrico (i.e., a Data Source) to encrypt messages # before Alice grants access to Bobs. policy_pubkey = alice.get_policy_encrypting_key_from_label(label) # Now, let's create a policy for some Bob. m, n = 3, 4 policy_end_datetime = maya.now() + datetime.timedelta(days=5) bob = Bob(federated_only=True, start_learning_now=False, network_middleware=MockRestMiddleware()) bob_policy = alice.grant(bob, label, m=m, n=n, expiration=policy_end_datetime) assert policy_pubkey == bob_policy.public_key # ... and Alice and her configuration disappear. del alice del alice_config ################################### # Some time passes. # # ... # # (jmyles plays the Song of Time) # # ... # # Alice appears again. # ################################### # A new Alice is restored from the configuration file new_alice_config = AliceConfiguration.from_configuration_file( filepath=alice_config_file, network_middleware=MockRestMiddleware(), known_nodes=federated_ursulas, start_learning_now=False, ) # Alice unlocks her restored keyring from disk new_alice_config.attach_keyring() new_alice_config.keyring.unlock(password=INSECURE_DEVELOPMENT_PASSWORD) new_alice = new_alice_config() # First, we check that her public keys are correctly restored assert alices_verifying_key == new_alice.public_keys(SigningPower) assert alices_receiving_key == new_alice.public_keys(DecryptingPower) # Bob's eldest brother, Roberto, appears too roberto = Bob(federated_only=True, start_learning_now=False, network_middleware=MockRestMiddleware()) # Alice creates a new policy for Roberto. Note how all the parameters # except for the label (i.e., recipient, m, n, policy_end) are different # from previous policy m, n = 2, 5 policy_end_datetime = maya.now() + datetime.timedelta(days=3) roberto_policy = new_alice.grant(roberto, label, m=m, n=n, expiration=policy_end_datetime) # Both policies must share the same public key (i.e., the policy public key) assert policy_pubkey == roberto_policy.public_key
alice_config = AliceConfiguration( config_root=os.path.join(TEMP_ALICE_DIR), is_me=True, known_nodes={ursula}, start_learning_now=False, federated_only=True, learn_on_same_thread=True, ) alice_config.initialize(password=passphrase) alice_config.keyring.unlock(password=passphrase) alicia = alice_config.produce() # We will save Alicia's config to a file for later use alice_config_file = alice_config.to_configuration_file() # Let's get to learn about the NuCypher network alicia.start_learning_loop(now=True) # 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. # Note: we add some random chars to create different policies, only for demonstration purposes label = "heart-data-❤️-" + os.urandom(4).hex() label = label.encode() # Alicia can create the public key associated to the policy label, # even before creating any associated policy. policy_pubkey = alicia.get_policy_pubkey_from_label(label) print("The policy public key for "
def initialize_alice_policy_pubkey( alice_encryption_password: str = "TEST_ALICE_PASSWORD"): """ Takes in alice's encryption password as input and generates and stores the policy pubkey. """ globalLogPublisher.addObserver(SimpleObserver()) NUCYPHER_DATA_DIR = os.path.join( settings.BASE_DIR, 'nucypher_utils', 'nucypher_data', ) if not os.path.exists(NUCYPHER_DATA_DIR): os.mkdir(NUCYPHER_DATA_DIR) if os.listdir(NUCYPHER_DATA_DIR): print("data directory not clean...Cleaning...") shutil.rmtree(NUCYPHER_DATA_DIR) if not os.path.exists(NUCYPHER_DATA_DIR): os.mkdir(NUCYPHER_DATA_DIR) if os.listdir(NUCYPHER_DATA_DIR): print("Data Directory Cleaned") ALICE_CONFIG_DIR = os.path.join(settings.BASE_DIR, 'nucypher_utils', 'nucypher_data', 'nucypher_char_configs', 'stridon-demo-alice') # We expect the url of the seednode as the first argument. SEEDNODE_URL = 'localhost:11500' POLICY_FILENAME = "policy-metadata.json" ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URL, federated_only=True, minimum_stake=0) passphrase = alice_encryption_password alice_config = AliceConfiguration( config_root=os.path.join(ALICE_CONFIG_DIR), is_me=True, known_nodes={ursula}, start_learning_now=False, federated_only=True, learn_on_same_thread=True, ) alice_config.initialize(password=passphrase) alice_config.keyring.unlock(password=passphrase) alice_config_file = alice_config.to_configuration_file() print(alice_config_file) alice = alice_config.produce() label = "stridon-premium-service" label = label.encode() policy_pubkey = alice.get_policy_pubkey_from_label(label) print("The policy public key for label '{}' is {}".format( label.decode("utf-8"), policy_pubkey.to_bytes().hex())) policy_json = { "policy_pubkey": policy_pubkey.to_bytes().hex(), } POLICY_FILE = os.path.join( os.getcwd(), 'nucypher_utils', 'nucypher_data', POLICY_FILENAME, ) with open(POLICY_FILE, 'w') as f: json.dump(policy_json, f) from nucypher.crypto.powers import SigningPower, DecryptingPower print(alice.public_keys(SigningPower)) print(alice.public_keys(DecryptingPower))
def alicia_encrypt(data_fields, pid): POLICY_FILENAME = "policy-metadata.json" globalLogPublisher.addObserver(SimpleObserver()) TEMP_ALICE_DIR = "alicia-files".format( os.path.dirname(os.path.abspath(__file__))) SEEDNODE_URL = 'localhost:11500' passphrase = "TEST_ALICIA_INSECURE_DEVELOPMENT_PASSWORD" try: alice_config_file = os.path.join(TEMP_ALICE_DIR, "alice.config") new_alice_config = AliceConfiguration.from_configuration_file( filepath=alice_config_file, network_middleware=RestMiddleware(), start_learning_now=False, save_metadata=False, ) alicia = new_alice_config(passphrase=passphrase) except: shutil.rmtree(TEMP_ALICE_DIR, ignore_errors=True) ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URL, federated_only=True, minimum_stake=0) alice_config = AliceConfiguration( config_root=os.path.join(TEMP_ALICE_DIR), is_me=True, known_nodes={ursula}, start_learning_now=False, federated_only=True, learn_on_same_thread=True, ) alice_config.initialize(password=passphrase) alice_config.keyring.unlock(password=passphrase) alicia = alice_config.produce() alice_config_file = alice_config.to_configuration_file() alicia.start_learning_loop(now=True) label = "doctor" label = label.encode() policy_pubkey = alicia.get_policy_pubkey_from_label(label) print("The policy public key for " "label '{}' is {}".format(label.decode("utf-8"), policy_pubkey.to_bytes().hex())) import data_ipfs res = data_ipfs.encrypt_patient_data(policy_pubkey, data_fields, pid, label=label, save_as_file=True) print(res) from doctor_keys import get_doctor_pubkeys doctor_pubkeys = get_doctor_pubkeys() powers_and_material = { DecryptingPower: doctor_pubkeys['enc'], SigningPower: doctor_pubkeys['sig'] } doctor_strange = Bob.from_public_keys( powers_and_material=powers_and_material, federated_only=True) policy_end_datetime = maya.now() + datetime.timedelta(days=5) m, n = 2, 3 print("Creating access policy for the Doctor...") policy = alicia.grant(bob=doctor_strange, label=label, m=m, n=n, expiration=policy_end_datetime) print("Done!") policy_info = { "policy_pubkey": policy.public_key.to_bytes().hex(), "alice_sig_pubkey": bytes(alicia.stamp).hex(), "label": label.decode("utf-8"), } filename = POLICY_FILENAME with open(filename, 'w') as f: json.dump(policy_info, f) return res
def test_alices_powers_are_persistent(federated_ursulas, tmpdir): passphrase = TEST_URSULA_INSECURE_DEVELOPMENT_PASSWORD # Let's create an Alice from a Configuration. # This requires creating a local storage for her first. node_storage = LocalFileBasedNodeStorage( federated_only=True, character_class=Ursula, # Alice needs to store some info about Ursula known_metadata_dir=os.path.join(tmpdir, "known_metadata"), ) alice_config = AliceConfiguration( config_root=os.path.join(tmpdir, "config_root"), node_storage=node_storage, auto_initialize=True, auto_generate_keys=True, passphrase=passphrase, is_me=True, network_middleware=MockRestMiddleware(), known_nodes=federated_ursulas, start_learning_now=False, federated_only=True, save_metadata=False, load_metadata=False ) alice = alice_config(passphrase=passphrase) # We will save Alice's config to a file for later use alice_config_file = alice_config.to_configuration_file() # Let's save Alice's public keys too to check they are correctly restored later alices_verifying_key = alice.public_keys(SigningPower) alices_receiving_key = alice.public_keys(EncryptingPower) # Next, let's fix a label for all the policies we will create later. label = b"this_is_the_path_to_which_access_is_being_granted" # Even before creating the policies, we can know what will be its public key. # This can be used by DataSources to encrypt messages before Alice grants access to Bobs policy_pubkey = alice.get_policy_pubkey_from_label(label) # Now, let's create a policy for some Bob. m, n = 3, 4 policy_end_datetime = maya.now() + datetime.timedelta(days=5) bob = Bob(federated_only=True, start_learning_now=False, network_middleware=MockRestMiddleware(), ) bob_policy = alice.grant(bob, label, m=m, n=n, expiration=policy_end_datetime) assert policy_pubkey == bob_policy.public_key # ... and Alice and her configuration disappear. del alice del alice_config ################################### # Some time passes. # # ... # # (jmyles plays the Song of Time) # # ... # # Alice appears again. # ################################### # A new Alice is restored from the configuration file new_alice_config = AliceConfiguration.from_configuration_file( filepath=alice_config_file, network_middleware=MockRestMiddleware(), known_nodes=federated_ursulas, start_learning_now=False, ) new_alice = new_alice_config(passphrase=passphrase) # First, we check that her public keys are correctly restored assert alices_verifying_key == new_alice.public_keys(SigningPower) assert alices_receiving_key == new_alice.public_keys(EncryptingPower) # Bob's eldest brother, Roberto, appears too roberto = Bob(federated_only=True, start_learning_now=False, network_middleware=MockRestMiddleware(), ) # Alice creates a new policy for Roberto. Note how all the parameters # except for the label (i.e., recipient, m, n, policy_end) are different # from previous policy m, n = 2, 5 policy_end_datetime = maya.now() + datetime.timedelta(days=3) roberto_policy = new_alice.grant(roberto, label, m=m, n=n, expiration=policy_end_datetime) # Both policies must share the same public key (i.e., the policy public key) assert policy_pubkey == roberto_policy.public_key
arjun_config = AliceConfiguration( config_root=os.path.join(TEMP_ARJUN_DIR), is_me=True, known_nodes={ursula}, start_learning_now=False, federated_only=True, learn_on_same_thread=True, ) arjun_config.initialize(password=passphrase) arjun_config.keyring.unlock(password=passphrase) arjun = arjun_config.produce() # We will save Alicia's config to a file for later use arjun_config_file = arjun_config.to_configuration_file() # Let's get to learn about the NuCypher network arjun.start_learning_loop(now=True) # 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. # Note: we add some random chars to create different policies, only for demonstration purposes label = "chat" + os.urandom(4).hex() label = label.encode() # Alicia can create the public key associated to the policy label, # even before creating any associated policy. policy_pubkey = arjun.get_policy_pubkey_from_label(label) print("The policy public key for "
class KMS: def __init__(self, ursula_url, dir_name, passphrase, ipfs_addr='', arweave_wallet_file_path='', federated_only=True, signer_uri='', checksum_address=None, client_password=None, provider_uri='', domain=TEMPORARY_DOMAIN): """ Args: ursula_url (str): ursula url e.g. localhost:11500 dir_name (str): dir_name where account files will be stored in tmp directory passphrase (str): passphrase for account ipfs_addr (str): ipfs addr (required only if you want to store data in ipfs) arweave_wallet_file_path (str): arweave wallet file path (required only if you want to store data in arweave) federated_only (bool): Whether federated mode should be used signer_uri (str): signer uri for ethereum transaction https://docs.nucypher.com/en/latest/guides/ethereum_node.html#external-transaction-signing checksum_address (str): Ethereum address client_password (str): Password for ethereum keystore. Required only if signer_uri is keystore://{path} provider_uri (str): geth or infura https uri domain (str): nucypher network name e.g. lynx for nucypher testnet and mainnet for nucypher mainnet """ self.__client_password = client_password self.federated_only = federated_only self.ursula_url = ursula_url self.ursula = Ursula.from_seed_and_stake_info( seed_uri=self.ursula_url, federated_only=self.federated_only, minimum_stake=0) self.arweave_wallet = None if arweave_wallet_file_path: self.arweave_wallet = arweave.Wallet(arweave_wallet_file_path) self.ipfs = None if ipfs_addr: self.ipfs = ipfshttpclient.connect(ipfs_addr) self.temp_dir = os.path.join('/', 'tmp', dir_name) self.alice_config = AliceConfiguration( provider_uri=provider_uri, checksum_address=checksum_address, signer_uri=signer_uri, config_root=os.path.join(self.temp_dir), domain=domain, known_nodes={self.ursula}, start_learning_now=False, federated_only=self.federated_only, learn_on_same_thread=True) try: if os.path.exists(os.path.join(self.temp_dir, "alice.json")): raise ExistingKeyringError() self.alice_config.initialize(password=passphrase) except ExistingKeyringError: self.alice_config = AliceConfiguration.from_configuration_file( filepath=os.path.join(self.temp_dir, "alice.json"), known_nodes={self.ursula}, start_learning_now=False) self.alice_config.attach_keyring() self.alice_config.keyring.unlock(password=passphrase) signer = Signer.from_signer_uri(signer_uri) if signer_uri else None if signer: signer.unlock_account(account=checksum_address, password=client_password) self.alice = self.alice_config.produce(signer=signer) try: self.alice_config_file = self.alice_config.to_configuration_file() except FileExistsError: pass self.alice.start_learning_loop(now=True) self.privkeys, self.pubkeys = fetch_keys(path=self.temp_dir) bob_enc_keypair = DecryptingKeypair(private_key=self.privkeys["enc"]) bob_sig_keypair = SigningKeypair(private_key=self.privkeys["sig"]) enc_power = DecryptingPower(keypair=bob_enc_keypair) sig_power = SigningPower(keypair=bob_sig_keypair) power_ups = [enc_power, sig_power] self.bob = Bob(domain=domain, federated_only=self.federated_only, crypto_power_ups=power_ups, start_learning_now=True, abort_on_learning_error=True, known_nodes=[self.ursula], save_metadata=False, network_middleware=RestMiddleware(), provider_uri=provider_uri) def encrypt_data(self, plaintext): """ Encrypt data Args: plaintext (str): plaintext that should be encrypted Returns: label, data_source_public_key, data (bytes, bytes, byes): tuple containing label for the policy, data source public_key & encrypted data """ label = ("policy️-" + os.urandom(8).hex()).encode() policy_pubkey = self.alice.get_policy_encrypting_key_from_label(label) data_source = Enrico(policy_encrypting_key=policy_pubkey) data_source_public_key = bytes(data_source.stamp) message, _signature = data_source.encrypt_message( plaintext.encode("utf-8")) data = message.to_bytes() return label, data_source_public_key, data def decrypt_data(self, data_source_public_key, data, policy_info): """ Decrypt data Args: data_source_public_key (bytes): data_source_public_key data (bytes): encrypted data policy_info (dict): dict containing policy_pubkey, alice_sig_pubkey and label keys Returns: retrieved_plaintexts (list): list of str """ policy_pubkey = UmbralPublicKey.from_bytes( bytes.fromhex(policy_info["policy_pubkey"])) alice_sig_pubkey = UmbralPublicKey.from_bytes( bytes.fromhex(policy_info["alice_sig_pubkey"])) label = policy_info["label"].encode() self.bob.join_policy(label, alice_sig_pubkey) message_kit = UmbralMessageKit.from_bytes(data) data_source = Enrico.from_public_keys( verifying_key=data_source_public_key, policy_encrypting_key=policy_pubkey) retrieved_plaintexts = self.bob.retrieve( message_kit, label=label, enrico=data_source, alice_verifying_key=alice_sig_pubkey) retrieved_plaintexts = [ x.decode('utf-8') for x in retrieved_plaintexts ] return retrieved_plaintexts def share_data_access(self, pubkeys, label, days=5, m=1, n=1, rate=Web3.toWei(50, 'gwei')): """ Share data access based on public keys Args: pubkeys (dict): public keys dict containing sig and enc keys label (bytes): label for the policy days (int): days for which the access should be granted m (int): Minimum number of kfrags needed to activate a Capsule n (int): Total number of kfrags to generate rate (int): rate in wei Returns: policy_info (dict): dict containing policy_pubkey, alice_sig_pubkey and label keys """ bob = Bob.from_public_keys(verifying_key=pubkeys['sig'], encrypting_key=pubkeys['enc'], federated_only=self.federated_only) # Policy expiration date policy_end_datetime = maya.now() + datetime.timedelta(days=days) power_ups = self.alice._crypto_power._CryptoPower__power_ups for key, power_up in power_ups.items(): self.alice._crypto_power.consume_power_up( power_up, password=self.__client_password) policy = self.alice.grant(bob=bob, label=label, m=m, n=n, expiration=policy_end_datetime, rate=rate) policy_info = { "policy_pubkey": policy.public_key.to_bytes().hex(), "alice_sig_pubkey": bytes(self.alice.stamp).hex(), "label": label.decode("utf-8"), } return policy_info def upload_data(self, plaintext, storage): """ Upload data to the selected storage Args: plaintext (str): plaintext storage (str): storage layer e.g. ipfs, arweave, skynet, etc. Returns: label, data_source_public_key, hash_key (bytes, bytes, str): tuple containing policy label, data source public key and hash_key """ label, data_source_public_key, data = self.encrypt_data( plaintext=plaintext) if storage == "ipfs": hash_key = self.ipfs.add_bytes(data) elif storage == "arweave": transaction = arweave.Transaction(self.arweave_wallet, data=data) transaction.sign() transaction.send() hash_key = transaction.id elif storage == "skynet": file_name = '/tmp/{}.txt'.format( random.randint(100000000000, 999999999999)) file = open(file_name, 'wb') file.write(data) file.close() skynet_client = skynet.SkynetClient() hash_key = skynet_client.upload_file(file_name) else: raise ValueError("invalid storage layer") return label, data_source_public_key, hash_key @staticmethod def get_shareable_code(hash_key, data_source_public_key, policy_info, storage): """ Get shareable code to fetch the secret which can be shared easily Args: hash_key (str): storage layer hash key data_source_public_key (bytes): data source public key policy_info (dict): dict containing policy_pubkey, alice_sig_pubkey and label keys storage (str): storage layer e.g. ipfs, arweave, skynet, etc. Returns: shareable_code (str): shareable code """ data = { "hash": hash_key, "data_source_public_key": data_source_public_key.hex(), "policy_info": policy_info, "storage": storage } return base64.b64encode( json.dumps(data, separators=(',', ':')).encode("utf-8")).decode('utf-8') def fetch_data(self, shareable_code, storage): """ Fetch data from the selected storage and decrypt it Args: shareable_code (str): shareable code storage (str): storage layer e.g. ipfs, arweave, skynet, etc. Returns: retrieved_plaintexts (list): list of str """ meta_data = json.loads( base64.b64decode(shareable_code.encode('utf-8')).decode('utf-8')) data_source_public_key = meta_data['data_source_public_key'] hash_key = meta_data['hash'] if storage == "ipfs": data = self.ipfs.cat(hash_key) elif storage == "arweave": transaction = arweave.Transaction(self.arweave_wallet, id=hash_key) transaction.get_data() data = transaction.data if data == b'': raise ValueError( "Transaction not found. Wait for some more time") elif storage == "skynet": file_name = '/tmp/{}.txt'.format( random.randint(100000000000, 999999999999)) skynet_client = skynet.SkynetClient() skynet_client.download_file(file_name, hash_key) file = open(file_name, 'rb') data = file.read() file.close() else: raise ValueError("invalid storage layer") data_source_public_key = bytes.fromhex(data_source_public_key) policy_info = meta_data["policy_info"] return self.decrypt_data(data_source_public_key=data_source_public_key, data=data, policy_info=policy_info)