def test_pay_a_flunky_instead_of_the_arranged_ursula( blockchain_alice, blockchain_bob, blockchain_ursulas, ursula_decentralized_test_config, testerchain): amonia = Amonia.from_lawful_alice(blockchain_alice) target_ursulas = blockchain_ursulas[0], blockchain_ursulas[ 1], blockchain_ursulas[2] flunkies = [ blockchain_ursulas[5], blockchain_ursulas[6], blockchain_ursulas[7] ] # Setup the policy details shares = 3 policy_end_datetime = maya.now() + datetime.timedelta(days=35) label = b"back_and_forth_forever" bupkiss_policy = amonia.grant_while_paying_the_wrong_nodes( ursulas_to_trick_into_working_for_free=target_ursulas, ursulas_to_pay_instead=flunkies, bob=blockchain_bob, label=label, threshold=2, shares=shares, rate=int(1e18), # one ether expiration=policy_end_datetime) # Enrico becomes enrico = Enrico(policy_encrypting_key=bupkiss_policy.public_key) plaintext = b"A crafty campaign" message_kit = enrico.encrypt_message(plaintext) with pytest.raises(Ursula.NotEnoughUrsulas): blockchain_bob.retrieve_and_decrypt( [message_kit], alice_verifying_key=amonia.stamp.as_umbral_pubkey(), encrypted_treasure_map=bupkiss_policy.treasure_map)
def test_try_to_post_free_service_by_hacking_enact(blockchain_ursulas, blockchain_alice, blockchain_bob, agency, testerchain): """ This time we won't rely on the tabulation in Alice's enact() to catch the problem. """ amonia = Amonia.from_lawful_alice(blockchain_alice) # Setup the policy details shares = 3 policy_end_datetime = maya.now() + datetime.timedelta(days=35) label = b"another_path" bupkiss_policy = amonia.circumvent_safegaurds_and_grant_without_paying( bob=blockchain_bob, label=label, threshold=2, shares=shares, expiration=policy_end_datetime) # Enrico becomes enrico = Enrico(policy_encrypting_key=bupkiss_policy.public_key) plaintext = b"A crafty campaign" message_kit = enrico.encrypt_message(plaintext) with pytest.raises(Ursula.NotEnoughUrsulas ): # Return a more descriptive request error? blockchain_bob.retrieve_and_decrypt( [message_kit], alice_verifying_key=amonia.stamp.as_umbral_pubkey(), encrypted_treasure_map=bupkiss_policy.treasure_map)
def test_policy_simple_sinpa(blockchain_ursulas, blockchain_alice, blockchain_bob, agency, testerchain): """ Making a Policy without paying. """ amonia = Amonia.from_lawful_alice(blockchain_alice) # Setup the policy details shares = 3 policy_end_datetime = maya.now() + datetime.timedelta(days=35) label = b"this_is_the_path_to_which_access_is_being_granted" bupkiss_policy = amonia.grant_without_paying( bob=blockchain_bob, label=label, threshold=2, shares=shares, rate=int(1e18), # one ether expiration=policy_end_datetime) # Enrico becomes enrico = Enrico(policy_encrypting_key=bupkiss_policy.public_key) plaintext = b"A crafty campaign" message_kit = enrico.encrypt_message(plaintext) with pytest.raises(Ursula.NotEnoughUrsulas ): # Return a more descriptive request error? blockchain_bob.retrieve_and_decrypt( [message_kit], alice_verifying_key=amonia.stamp.as_umbral_pubkey(), encrypted_treasure_map=bupkiss_policy.treasure_map)
def add_contents(self, alicia, my_label, contents): """ cid = client.add_contents( policy_pubkey=policy_pub_key ) """ print("add_contents") policy_pubkey = alicia.get_policy_encrypting_key_from_label(my_label) data_source = Enrico(policy_encrypting_key=policy_pubkey) data_source_public_key = bytes(data_source.stamp) heart_rate = 80 now = time.time() kits = list() heart_rate = contents now += 3 heart_rate_data = { 'heart_rate': heart_rate, 'timestamp': now, } plaintext = msgpack.dumps(heart_rate_data, use_bin_type=True) message_kit, _signature = data_source.encrypt_message(plaintext) kit_bytes = message_kit.to_bytes() kits.append(kit_bytes) data = { 'data_source': data_source_public_key, 'kits': kits, } print("🚀 ADDING TO IPFS D-STORAGE NETWORK 🚀") d = msgpack.dumps(data, use_bin_type=True) ### NETWORK ERROR OUT ON FALLBACK # print(dir(self.ipfs_gateway_api)) cid = self.ipfs_gateway_api.add_bytes(d) print("File Address:\t%s" % cid) return cid
def uploadData(self, label, file): policy_pubkey = self.Alice.get_policy_encrypting_key_from_label(label.encode("utf-8")) data_source = Enrico(policy_encrypting_key=policy_pubkey) data_source_public_key = bytes(data_source.stamp) now = time.time() kits = list() now += 5 data_representation = { 'data': file, 'timestamp': now, } plaintext = msgpack.dumps(data_representation, use_bin_type=True) message_kit, _signature = data_source.encrypt_message(plaintext) kit_bytes = message_kit.to_bytes() kits.append(kit_bytes) data = { 'data_source': data_source_public_key, 'kits': kits, } d = msgpack.dumps(data, use_bin_type=True) ipfs_hash = self.ipfs_gateway_api.add_bytes(d) receipt = { "data_source_public_key" : data_source_public_key.hex(), "hash_key" : ipfs_hash } return receipt
def put_password(policy_pubkey, username, password, save_as_file: bool = False): data_source = Enrico(policy_encrypting_key=policy_pubkey) data_source_public_key = bytes(data_source.stamp) kits = list() actual_data = { 'username': username, 'password': password, } plaintext = msgpack.dumps(actual_data, use_bin_type=True) message_kit, _signature = data_source.encrypt_message(plaintext) kit_bytes = message_kit.to_bytes() kits.append(kit_bytes) data = { 'data_source': data_source_public_key, 'kits': kits, } if save_as_file: with open(HEART_DATA_FILENAME, "wb") as file: msgpack.dump(data, file, use_bin_type=True) return data
def encrypt_track_segments(policy_pubkey, dir_path): data_source = Enrico(policy_encrypting_key=policy_pubkey) data_source_public_key = bytes(data_source.stamp) print(dir_path) target_path = "/".join(dir_path.split('/')[:-1]) target_path = os.path.join(target_path, 'segments_encrypted') if not os.path.exists(target_path): try: os.makedirs(target_path) except OSError as exc: # Guard against race condition if exc.errno != errno.EEXIST: raise track_files = os.scandir(dir_path) for track_segment in track_files: with open(track_segment, "rb") as f: plaintext = f.read() ciphertext, signature = data_source.encrypt_message(plaintext) print("Signature", signature) data = { 'track_segment_data': ciphertext.to_bytes(), 'data_source': data_source_public_key } with open(os.path.join(target_path, track_segment.name), "wb") as f: msgpack.dump(data, f, use_bin_type=True) return True
def __call__(self): enrico = Enrico( policy_encrypting_key=enacted_blockchain_policy.public_key) message = "Welcome to flippering number {}.".format( len(self.messages)).encode() message_kit, _signature = enrico.encrypt_message(message) self.messages.append((message_kit, enrico)) return message_kit, enrico
def post(self): policy_key = request.json['policy_pubkey'] data = request.json['data'] enrico = Enrico(policy_encrypting_key=UmbralPublicKey.from_bytes( bytes.fromhex(policy_key))) message_kit, _signature = enrico.encrypt_message(data.encode()) result = {} result["ciphertext"] = message_kit.to_bytes().hex() result["enrico"] = bytes(enrico.stamp).hex() return json.dumps(result)
def _make_message_kits(policy_pubkey): messages = [b"plaintext1", b"plaintext2", b"plaintext3"] message_kits = [] for message in messages: # Using different Enricos, because why not. enrico = Enrico(policy_encrypting_key=policy_pubkey) message_kit = enrico.encrypt_message(message) message_kits.append(message_kit) return messages, message_kits
def test_alice_can_decrypt(federated_alice): label = b"boring test label" policy_pubkey = federated_alice.get_policy_encrypting_key_from_label(label) enrico = Enrico(policy_encrypting_key=policy_pubkey) message = b"boring test message" message_kit = enrico.encrypt_message(plaintext=message) # Interesting thing: if Alice wants to decrypt, she needs to provide the label directly. cleartexts = federated_alice.decrypt_message_kit(label=label, message_kit=message_kit) assert cleartexts == [message]
def encrypt_data(plain_text, datasource_filename): POLICY_FILENAME = "policy-metadata.json" POLICY_FILE = os.path.join( settings.BASE_DIR, 'nucypher_utils', 'nucypher_data', POLICY_FILENAME, ) with open(POLICY_FILE, 'rb') as fp: policy_pubkey_data = json.load(fp) policy_pubkey_string = policy_pubkey_data['policy_pubkey'] policy_pubkey_bytes = unhexlify(policy_pubkey_string) policy_pubkey = keys.UmbralPublicKey.from_bytes(policy_pubkey_bytes) data_source = Enrico(policy_encrypting_key=policy_pubkey) data_source_public_key = bytes(data_source.stamp) plain_text = bytes(plain_text, 'utf-8') message_kit, _signature = data_source.encrypt_message(plain_text) kit_bytes = message_kit.to_bytes() kit = kit_bytes data = { 'data_source_public_key': data_source_public_key, 'kits': kit, } # data souce pub key naming convention: # author_name-article_title-article_id-datasource-pubkey.msgpack DATA_SOURCE_DIR = os.path.join( settings.BASE_DIR, 'nucypher_utils', 'nucypher_data', ) DATA_SOURCE_FILE_NAME = datasource_filename with open(os.path.join(DATA_SOURCE_DIR, DATA_SOURCE_FILE_NAME), "wb") as file: msgpack.dump(data, file, use_bin_type=True) return kit_bytes
def test_alice_can_decrypt(federated_alice): label = b"boring test label" policy_pubkey = federated_alice.get_policy_pubkey_from_label(label) enrico = Enrico(policy_encrypting_key=policy_pubkey) message = b"boring test message" message_kit, signature = enrico.encrypt_message(message=message) # Interesting thing: if Alice wants to decrypt, she needs to provide the label directly. cleartext = federated_alice.verify_from(stranger=enrico, message_kit=message_kit, signature=signature, decrypt=True, label=label) assert cleartext == message
def mario_box_cli(plaintext_dir, alice_config, label, outfile): # Derive Policy Encrypting Key alice_configuration = AliceConfiguration.from_configuration_file( filepath=alice_config) alice = make_cli_character(character_config=alice_configuration) alice_signing_key = alice.public_keys(SigningPower) policy_encrypting_key = alice.get_policy_encrypting_key_from_label( label=label.encode()) policy_encrypting_key_hex = bytes(policy_encrypting_key).hex() output = list() paths = list(plaintext_dir.iterdir()) click.secho( f"Encrypting {len(paths)} files for policy {policy_encrypting_key_hex}", fg='blue') with click.progressbar(paths) as bar: for path in bar: filepath = Path(plaintext_dir, path) with open(filepath, 'rb') as file: plaintext = file.read() encoded_plaintext = base64.b64encode(plaintext) enrico = Enrico(policy_encrypting_key=policy_encrypting_key) message_kit = enrico.encrypt_message( plaintext=encoded_plaintext) base64_message_kit = base64.b64encode( bytes(message_kit)).decode() # Collect Bob Retrieve JSON Requests retrieve_payload = { 'label': label, 'policy-encrypting-key': policy_encrypting_key_hex, 'alice-verifying-key': bytes(alice_signing_key).hex(), 'message-kit': base64_message_kit } output.append(retrieve_payload) if not outfile: outfile = f'{policy_encrypting_key_hex}.json' with open(outfile, 'w') as file: file.write(json.dumps(output, indent=2)) click.secho(f"Successfully wrote output to {outfile}", fg='green')
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 encrypt_track(policy_pubkey, file_path): data_source = Enrico(policy_encrypting_key=policy_pubkey) data_source_public_key = bytes(data_source.stamp) print(file_path) with open(file_path, "rb") as f: plaintext = f.read() ciphertext, signature = data_source.encrypt_message(plaintext) print("Signature", signature) data = { 'track_segment_data': ciphertext.to_bytes(), 'data_source': data_source_public_key } with open(file_path + '_encrypted', "wb") as f: msgpack.dump(data, f, use_bin_type=True) return True
def from_channel(cls, channel: Channel, data: bytes) -> object: ''' Create EncryptedDataPackage from Channel & data. In other words it encrypts data usign Channel settings :param channel: Channel instance :param data: data to be encrypted :return: EncryptedDataPackage instance ''' label_bytes = channel.label_bytes policy_pub_key_object = UmbralPublicKey.from_bytes( channel.policy_pubkey_bytes) data_source = Enrico(policy_encrypting_key=policy_pub_key_object) data_source_pubkey_bytes = bytes(data_source.stamp) message_kit, _signature = data_source.encrypt_message(data) kit_bytes = message_kit.to_bytes() return EncryptedDataPackage( alice_pubkey_bytes=channel.alice_pubkey_bytes, data_source_pubkey_bytes=data_source_pubkey_bytes, kit_bytes=kit_bytes, label_bytes=label_bytes, policy_pubkey_bytes=channel.policy_pubkey_bytes)
def generate_heart_rate_samples(policy_pubkey, samples: int = 500, save_as_file: bool = False): data_source = Enrico(policy_encrypting_key=policy_pubkey) data_source_public_key = bytes(data_source.stamp) heart_rate = 80 now = time.time() kits = list() for _ in range(samples): # Simulated heart rate data # Normal resting heart rate for adults: between 60 to 100 BPM heart_rate = random.randint(max(60, heart_rate - 5), min(100, heart_rate + 5)) now += 3 heart_rate_data = { 'heart_rate': heart_rate, 'timestamp': now, } plaintext = msgpack.dumps(heart_rate_data, use_bin_type=True) message_kit = data_source.encrypt_message(plaintext) kit_bytes = bytes(message_kit) kits.append(kit_bytes) data = { 'data_source': data_source_public_key, 'kits': kits, } if save_as_file: with open(HEART_DATA_FILENAME, "wb") as file: msgpack.dump(data, file, use_bin_type=True) return data
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 generateEncDataUsingEnrico(pub_policy_key, dataToEnc, sender, uuid, save_as_file: bool = False): data_source = Enrico(policy_encrypting_key=pub_policy_key) now = time.time() data_source_public_key = bytes(data_source.stamp) # create json formatted data of the location for specific user location_data = {'data_enc': dataToEnc, 'timestamp': now, 'sender': sender} plaintext = msgpack.dumps(location_data, use_bin_type=True) message_kit, _signature = data_source.encrypt_message(plaintext) location_bytes = message_kit.to_bytes() data = {'data_source': data_source_public_key, 'data': location_bytes} enc_data_alicia = uuid + '.msgpack' if save_as_file: with open(enc_data_alicia, "wb") as file: msgpack.dump(data, file, use_bin_type=True) return data
def test_collect_rewards_integration( click_runner, testerchain, agency_local_registry, stakeholder_configuration_file_location, blockchain_alice, blockchain_bob, random_policy_label, manual_staker, manual_worker, token_economics, mock_transacting_power_activation, policy_value, policy_rate): half_stake_time = token_economics.minimum_locked_periods // 2 # Test setup logger = Logger("Test-CLI") # Enter the Teacher's Logger, and current_period = 0 # State the initial period for incrementing staker_address = manual_staker worker_address = manual_worker staker = Staker(is_me=True, checksum_address=staker_address, registry=agency_local_registry) staker.refresh_stakes() # The staker is staking. assert staker.is_staking assert staker.stakes assert staker.worker_address == worker_address ursula_port = select_test_port() ursula = Ursula(is_me=True, checksum_address=staker_address, worker_address=worker_address, registry=agency_local_registry, rest_host='127.0.0.1', rest_port=ursula_port, network_middleware=MockRestMiddleware(), db_filepath=tempfile.mkdtemp(), domain=TEMPORARY_DOMAIN) MOCK_KNOWN_URSULAS_CACHE[ursula_port] = ursula assert ursula.worker_address == worker_address assert ursula.checksum_address == staker_address mock_transacting_power_activation(account=worker_address, password=INSECURE_DEVELOPMENT_PASSWORD) # Make a commitment for half the first stake duration for _ in range(half_stake_time): logger.debug( f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") ursula.commit_to_next_period() testerchain.time_travel(periods=1) current_period += 1 # Alice creates a policy and grants Bob access blockchain_alice.selection_buffer = 1 M, N = 1, 1 days = 3 now = testerchain.w3.eth.getBlock('latest').timestamp expiration = maya.MayaDT(now).add(days=days - 1) blockchain_policy = blockchain_alice.grant(bob=blockchain_bob, label=random_policy_label, m=M, n=N, value=policy_value, expiration=expiration, handpicked_ursulas={ursula}) # Ensure that the handpicked Ursula was selected for the policy arrangement = list(blockchain_policy._accepted_arrangements)[0] assert arrangement.ursula == ursula # Bob learns about the new staker and joins the policy blockchain_bob.start_learning_loop() blockchain_bob.remember_node(node=ursula) blockchain_bob.join_policy(random_policy_label, bytes(blockchain_alice.stamp)) # Enrico Encrypts (of course) enrico = Enrico(policy_encrypting_key=blockchain_policy.public_key, network_middleware=MockRestMiddleware()) verifying_key = blockchain_alice.stamp.as_umbral_pubkey() for index in range(half_stake_time - 5): logger.debug( f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") ursula.commit_to_next_period() # Encrypt random_data = os.urandom(random.randrange(20, 100)) ciphertext, signature = enrico.encrypt_message(plaintext=random_data) # Decrypt cleartexts = blockchain_bob.retrieve(ciphertext, enrico=enrico, alice_verifying_key=verifying_key, label=random_policy_label) assert random_data == cleartexts[0] # Ursula Staying online and the clock advancing testerchain.time_travel(periods=1) current_period += 1 # Finish the passage of time for the first Stake for _ in range(5): # plus the extended periods from stake division logger.debug( f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") ursula.commit_to_next_period() testerchain.time_travel(periods=1) current_period += 1 # # WHERES THE MONEY URSULA?? - Collecting Rewards # # The address the client wants Ursula to send rewards to burner_wallet = testerchain.w3.eth.account.create( INSECURE_DEVELOPMENT_PASSWORD) # The rewards wallet is initially empty, because it is freshly created assert testerchain.client.get_balance(burner_wallet.address) == 0 # Rewards will be unlocked after the # final committed period has passed (+1). logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") testerchain.time_travel(periods=1) current_period += 1 logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") # At least half of the tokens are unlocked (restaking was enabled for some prior periods) assert staker.locked_tokens() >= token_economics.minimum_allowed_locked # Since we are mocking the blockchain connection, manually consume the transacting power of the Staker. mock_transacting_power_activation(account=staker_address, password=INSECURE_DEVELOPMENT_PASSWORD) # Collect Policy Fee collection_args = ('stake', 'collect-reward', '--config-file', stakeholder_configuration_file_location, '--policy-fee', '--no-staking-reward', '--staking-address', staker_address, '--withdraw-address', burner_wallet.address) result = click_runner.invoke(nucypher_cli, collection_args, input=INSECURE_DEVELOPMENT_PASSWORD, catch_exceptions=False) assert result.exit_code == 0 # Policy Fee collected_policy_fee = testerchain.client.get_balance( burner_wallet.address) expected_collection = policy_rate * 30 assert collected_policy_fee == expected_collection # Finish the passage of time... once and for all # Extended periods from stake division for _ in range(9): ursula.commit_to_next_period() current_period += 1 logger.debug( f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") testerchain.time_travel(periods=1) # # Collect Staking Reward # balance_before_collecting = staker.token_agent.get_balance( address=staker_address) collection_args = ('stake', 'collect-reward', '--config-file', stakeholder_configuration_file_location, '--no-policy-fee', '--staking-reward', '--staking-address', staker_address, '--force') result = click_runner.invoke(nucypher_cli, collection_args, input=INSECURE_DEVELOPMENT_PASSWORD, catch_exceptions=False) assert result.exit_code == 0 # The staker has withdrawn her staking rewards assert staker.token_agent.get_balance( address=staker_address) > balance_before_collecting
def test_bob_joins_policy_and_retrieves(federated_alice, federated_ursulas, certificates_tempdir, ): # Let's partition Ursulas in two parts a_couple_of_ursulas = list(federated_ursulas)[:2] rest_of_ursulas = list(federated_ursulas)[2:] # Bob becomes bob = Bob(federated_only=True, start_learning_now=True, network_middleware=MockRestMiddleware(), abort_on_learning_error=True, known_nodes=a_couple_of_ursulas, ) # Bob only knows a couple of Ursulas initially assert len(bob.known_nodes) == 2 # Alice creates a policy granting access to Bob # Just for fun, let's assume she distributes KFrags among Ursulas unknown to Bob n = NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK - 2 label = b'label://' + os.urandom(32) contract_end_datetime = maya.now() + datetime.timedelta(days=5) policy = federated_alice.grant(bob=bob, label=label, m=3, n=n, expiration=contract_end_datetime, handpicked_ursulas=set(rest_of_ursulas), ) assert bob == policy.bob assert label == policy.label # Now, Bob joins the policy bob.join_policy(label=label, alice_pubkey_sig=federated_alice.stamp, block=True) # In the end, Bob should know all the Ursulas assert len(bob.known_nodes) == len(federated_ursulas) # Enrico becomes enrico = Enrico(policy_encrypting_key=policy.public_key) plaintext = b"What's your approach? Mississippis or what?" message_kit, _signature = enrico.encrypt_message(plaintext) alices_verifying_key = federated_alice.stamp.as_umbral_pubkey() # Bob takes the message_kit and retrieves the message within delivered_cleartexts = bob.retrieve(message_kit=message_kit, data_source=enrico, alice_verifying_key=alices_verifying_key, label=policy.label) assert plaintext == delivered_cleartexts[0] # FIXME: Bob tries to retrieve again # delivered_cleartexts = bob.retrieve(message_kit=message_kit, # data_source=enrico, # alice_verifying_key=alices_verifying_key, # label=policy.label) # # assert plaintext == delivered_cleartexts[0] # # Let's try retrieve again, but Alice revoked the policy. failed_revocations = federated_alice.revoke(policy) assert len(failed_revocations) == 0 with pytest.raises(Ursula.NotEnoughUrsulas): _cleartexts = bob.retrieve(message_kit=message_kit, data_source=enrico, alice_verifying_key=alices_verifying_key, label=policy.label)
def capsule_side_channel(enacted_federated_policy): enrico = Enrico(policy_encrypting_key=enacted_federated_policy.public_key) message_kit, _signature = enrico.encrypt_message(b"Welcome to the flippering.") return message_kit, enrico
def test_collect_rewards_integration(click_runner, testerchain, stakeholder_configuration_file_location, blockchain_alice, blockchain_bob, random_policy_label, manual_staker, manual_worker, token_economics, policy_value, policy_rate): half_stake_time = token_economics.minimum_locked_periods // 2 # Test setup logger = Logger("Test-CLI") # Enter the Teacher's Logger, and current_period = 0 # State the initial period for incrementing staker_address = manual_staker worker_address = manual_worker staker = Staker(is_me=True, checksum_address=staker_address, blockchain=testerchain) # The staker is staking. assert staker.stakes assert staker.is_staking assert staker.worker_address == worker_address ursula_port = select_test_port() ursula = Ursula(is_me=True, checksum_address=staker_address, worker_address=worker_address, blockchain=testerchain, rest_host='127.0.0.1', rest_port=ursula_port, network_middleware=MockRestMiddleware()) MOCK_KNOWN_URSULAS_CACHE[ursula_port] = ursula assert ursula.worker_address == worker_address assert ursula.checksum_address == staker_address # Mock TransactingPower consumption (Worker-Ursula) ursula.blockchain.transacting_power = TransactingPower( account=worker_address, password=INSECURE_DEVELOPMENT_PASSWORD, blockchain=testerchain) ursula.blockchain.transacting_power.activate() # Confirm for half the first stake duration for _ in range(half_stake_time): logger.debug( f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") ursula.confirm_activity() testerchain.time_travel(periods=1) current_period += 1 # Alice creates a policy and grants Bob access blockchain_alice.selection_buffer = 1 M, N = 1, 1 expiration = maya.now() + datetime.timedelta(days=3) blockchain_policy = blockchain_alice.grant(bob=blockchain_bob, label=random_policy_label, m=M, n=N, value=policy_value, expiration=expiration, handpicked_ursulas={ursula}) # Ensure that the handpicked Ursula was selected for the policy arrangement = list(blockchain_policy._accepted_arrangements)[0] assert arrangement.ursula == ursula # Bob learns about the new staker and joins the policy blockchain_bob.start_learning_loop() blockchain_bob.remember_node(node=ursula) blockchain_bob.join_policy(random_policy_label, bytes(blockchain_alice.stamp)) # Enrico Encrypts (of course) enrico = Enrico(policy_encrypting_key=blockchain_policy.public_key, network_middleware=MockRestMiddleware()) verifying_key = blockchain_alice.stamp.as_umbral_pubkey() for index in range(half_stake_time - 5): ursula.confirm_activity() logger.debug( f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") # Encrypt random_data = os.urandom(random.randrange(20, 100)) ciphertext, signature = enrico.encrypt_message(message=random_data) # Decrypt cleartexts = blockchain_bob.retrieve(message_kit=ciphertext, data_source=enrico, alice_verifying_key=verifying_key, label=random_policy_label) assert random_data == cleartexts[0] # Ursula Staying online and the clock advancing testerchain.time_travel(periods=1) current_period += 1 # Finish the passage of time for the first Stake for _ in range(5): # plus the extended periods from stake division ursula.confirm_activity() current_period += 1 logger.debug( f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") testerchain.time_travel(periods=1) # # WHERES THE MONEY URSULA?? - Collecting Rewards # # The address the client wants Ursula to send rewards to burner_wallet = testerchain.w3.eth.account.create( INSECURE_DEVELOPMENT_PASSWORD) # The rewards wallet is initially empty, because it is freshly created assert testerchain.client.get_balance(burner_wallet.address) == 0 # Rewards will be unlocked after the # final confirmed period has passed (+1). testerchain.time_travel(periods=1) current_period += 1 logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") # Half of the tokens are unlocked. assert staker.locked_tokens() == token_economics.minimum_allowed_locked # Simulate "Reconnection" within the CLI process to the testerchain def connect(self, *args, **kwargs): self._attach_provider(testerchain.provider) self.w3 = self.Web3(provider=self._provider) self.client = Web3Client.from_w3(w3=self.w3) BlockchainInterface.connect = connect # Since we are mocking the blockchain connection, manually consume the transacting power of the Staker. testerchain.transacting_power = TransactingPower( account=staker_address, password=INSECURE_DEVELOPMENT_PASSWORD, blockchain=testerchain) testerchain.transacting_power.activate() # Collect Policy Reward collection_args = ('stake', 'collect-reward', '--mock-networking', '--config-file', stakeholder_configuration_file_location, '--policy-reward', '--no-staking-reward', '--staking-address', staker_address, '--withdraw-address', burner_wallet.address, '--force') result = click_runner.invoke(nucypher_cli, collection_args, input=INSECURE_DEVELOPMENT_PASSWORD, catch_exceptions=False) assert result.exit_code == 0 # Policy Reward collected_policy_reward = testerchain.client.get_balance( burner_wallet.address) expected_collection = policy_rate * 30 assert collected_policy_reward == expected_collection # Finish the passage of time... once and for all # Extended periods from stake division for _ in range(9): ursula.confirm_activity() current_period += 1 logger.debug( f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") testerchain.time_travel(periods=1) # Collect Inflation Reward collection_args = ('stake', 'collect-reward', '--mock-networking', '--config-file', stakeholder_configuration_file_location, '--no-policy-reward', '--staking-reward', '--staking-address', staker_address, '--withdraw-address', burner_wallet.address, '--force') result = click_runner.invoke(nucypher_cli, collection_args, input=INSECURE_DEVELOPMENT_PASSWORD, catch_exceptions=False) assert result.exit_code == 0 # The burner wallet has the reward ethers assert staker.token_agent.get_balance(address=staker_address)
def test_bob_joins_policy_and_retrieves(federated_alice, federated_ursulas, certificates_tempdir, ): # Let's partition Ursulas in two parts a_couple_of_ursulas = list(federated_ursulas)[:2] rest_of_ursulas = list(federated_ursulas)[2:] # Bob becomes bob = Bob(federated_only=True, domains={TEMPORARY_DOMAIN}, start_learning_now=True, network_middleware=MockRestMiddleware(), abort_on_learning_error=True, known_nodes=a_couple_of_ursulas, ) # Bob only knows a couple of Ursulas initially assert len(bob.known_nodes) == 2 # Alice creates a policy granting access to Bob # Just for fun, let's assume she distributes KFrags among Ursulas unknown to Bob n = NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK - 2 label = b'label://' + os.urandom(32) contract_end_datetime = maya.now() + datetime.timedelta(days=5) policy = federated_alice.grant(bob=bob, label=label, m=3, n=n, expiration=contract_end_datetime, handpicked_ursulas=set(rest_of_ursulas), ) assert bob == policy.bob assert label == policy.label # Now, Bob joins the policy bob.join_policy(label=label, alice_verifying_key=federated_alice.stamp, block=True) # In the end, Bob should know all the Ursulas assert len(bob.known_nodes) == len(federated_ursulas) # Enrico becomes enrico = Enrico(policy_encrypting_key=policy.public_key) plaintext = b"What's your approach? Mississippis or what?" message_kit, _signature = enrico.encrypt_message(plaintext) alices_verifying_key = federated_alice.stamp.as_umbral_pubkey() # Bob takes the message_kit and retrieves the message within delivered_cleartexts = bob.retrieve(message_kit, enrico=enrico, alice_verifying_key=alices_verifying_key, label=policy.label, retain_cfrags=True) assert plaintext == delivered_cleartexts[0] # Bob tries to retrieve again, but without using the cached CFrags, it fails. with pytest.raises(TypeError): delivered_cleartexts = bob.retrieve(message_kit, enrico=enrico, alice_verifying_key=alices_verifying_key, label=policy.label) cleartexts_delivered_a_second_time = bob.retrieve(message_kit, enrico=enrico, alice_verifying_key=alices_verifying_key, label=policy.label, use_attached_cfrags=True) # Indeed, they're the same cleartexts. assert delivered_cleartexts == cleartexts_delivered_a_second_time # Let's try retrieve again, but Alice revoked the policy. failed_revocations = federated_alice.revoke(policy) assert len(failed_revocations) == 0 # One thing to note here is that Bob *can* still retrieve with the cached CFrags, even though this Policy has been revoked. #892 _cleartexts = bob.retrieve(message_kit, enrico=enrico, alice_verifying_key=alices_verifying_key, label=policy.label, use_precedent_work_orders=True, ) assert _cleartexts == delivered_cleartexts # TODO: 892 # OK, but we imagine that the message_kit is fresh here. message_kit.capsule.clear_cfrags() with pytest.raises(Ursula.NotEnoughUrsulas): _cleartexts = bob.retrieve(message_kit, enrico=enrico, alice_verifying_key=alices_verifying_key, label=policy.label, )
def test_collect_rewards_integration(click_runner, testerchain, agency_local_registry, stakeholder_configuration_file_location, blockchain_alice, blockchain_bob, random_policy_label, beneficiary, preallocation_escrow_agent, mock_allocation_registry, manual_worker, token_economics, mock_transacting_power_activation, stake_value, policy_value, policy_rate): # Disable re-staking restake_args = ('stake', 'restake', '--disable', '--config-file', stakeholder_configuration_file_location, '--allocation-filepath', MOCK_INDIVIDUAL_ALLOCATION_FILEPATH, '--force') result = click_runner.invoke(nucypher_cli, restake_args, input=INSECURE_DEVELOPMENT_PASSWORD, catch_exceptions=False) assert result.exit_code == 0 half_stake_time = token_economics.minimum_locked_periods // 2 # Test setup logger = Logger("Test-CLI") # Enter the Teacher's Logger, and current_period = 0 # State the initial period for incrementing staker_address = preallocation_escrow_agent.principal_contract.address worker_address = manual_worker # The staker is staking. stakes = StakeList(registry=agency_local_registry, checksum_address=staker_address) stakes.refresh() assert stakes staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=agency_local_registry) assert worker_address == staking_agent.get_worker_from_staker(staker_address=staker_address) ursula_port = select_test_port() ursula = Ursula(is_me=True, checksum_address=staker_address, worker_address=worker_address, registry=agency_local_registry, rest_host='127.0.0.1', rest_port=ursula_port, start_working_now=False, network_middleware=MockRestMiddleware()) MOCK_KNOWN_URSULAS_CACHE[ursula_port] = ursula assert ursula.worker_address == worker_address assert ursula.checksum_address == staker_address mock_transacting_power_activation(account=worker_address, password=INSECURE_DEVELOPMENT_PASSWORD) # Confirm for half the first stake duration for _ in range(half_stake_time): logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") ursula.confirm_activity() testerchain.time_travel(periods=1) current_period += 1 # Alice creates a policy and grants Bob access blockchain_alice.selection_buffer = 1 M, N = 1, 1 days = 3 now = testerchain.w3.eth.getBlock(block_identifier='latest').timestamp expiration = maya.MayaDT(now).add(days=days-1) blockchain_policy = blockchain_alice.grant(bob=blockchain_bob, label=random_policy_label, m=M, n=N, value=policy_value, expiration=expiration, handpicked_ursulas={ursula}) # Ensure that the handpicked Ursula was selected for the policy arrangement = list(blockchain_policy._accepted_arrangements)[0] assert arrangement.ursula == ursula # Bob learns about the new staker and joins the policy blockchain_bob.start_learning_loop() blockchain_bob.remember_node(node=ursula) blockchain_bob.join_policy(random_policy_label, bytes(blockchain_alice.stamp)) # Enrico Encrypts (of course) enrico = Enrico(policy_encrypting_key=blockchain_policy.public_key, network_middleware=MockRestMiddleware()) verifying_key = blockchain_alice.stamp.as_umbral_pubkey() for index in range(half_stake_time - 5): logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") ursula.confirm_activity() # Encrypt random_data = os.urandom(random.randrange(20, 100)) message_kit, signature = enrico.encrypt_message(message=random_data) # Decrypt cleartexts = blockchain_bob.retrieve(message_kit, enrico=enrico, alice_verifying_key=verifying_key, label=random_policy_label) assert random_data == cleartexts[0] # Ursula Staying online and the clock advancing testerchain.time_travel(periods=1) current_period += 1 # Finish the passage of time for _ in range(5 - 1): # minus 1 because the first period was already confirmed in test_ursula_run logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") ursula.confirm_activity() current_period += 1 testerchain.time_travel(periods=1) # # WHERES THE MONEY URSULA?? - Collecting Rewards # balance = testerchain.client.get_balance(beneficiary) # Rewards will be unlocked after the # final confirmed period has passed (+1). logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") testerchain.time_travel(periods=1) current_period += 1 logger.debug(f">>>>>>>>>>> TEST PERIOD {current_period} <<<<<<<<<<<<<<<<") # Since we are mocking the blockchain connection, manually consume the transacting power of the Beneficiary. mock_transacting_power_activation(account=beneficiary, password=INSECURE_DEVELOPMENT_PASSWORD) # Collect Policy Reward collection_args = ('stake', 'collect-reward', '--config-file', stakeholder_configuration_file_location, '--policy-reward', '--no-staking-reward', '--withdraw-address', beneficiary, '--allocation-filepath', MOCK_INDIVIDUAL_ALLOCATION_FILEPATH, '--force') result = click_runner.invoke(nucypher_cli, collection_args, input=INSECURE_DEVELOPMENT_PASSWORD, catch_exceptions=False) assert result.exit_code == 0 # Policy Reward collected_policy_reward = testerchain.client.get_balance(beneficiary) assert collected_policy_reward > balance # # Collect Staking Reward # token_agent = ContractAgency.get_agent(agent_class=NucypherTokenAgent, registry=agency_local_registry) balance_before_collecting = token_agent.get_balance(address=staker_address) collection_args = ('stake', 'collect-reward', '--config-file', stakeholder_configuration_file_location, '--no-policy-reward', '--staking-reward', '--allocation-filepath', MOCK_INDIVIDUAL_ALLOCATION_FILEPATH, '--force') result = click_runner.invoke(nucypher_cli, collection_args, input=INSECURE_DEVELOPMENT_PASSWORD, catch_exceptions=False) assert result.exit_code == 0 # The beneficiary has withdrawn her staking rewards, which are now in the staking contract assert token_agent.get_balance(address=staker_address) >= balance_before_collecting
def encryptData(): # { the object received in the request # "fileFieldCount": 2, # "textFieldCount": 2, # "0": "1st File", # "1": "2nd File", # "fileNames (stringified)": { # "0": "blood", # "1": "2nd File Name" # }, # "textFields (stringified)": { # "age": "18", # "name": "arvind" # } # # "username": "******", # "password": "******", # "hash": "", # "alice": "/home/arvind/Documents/ethDenver/umbral/alice/arvind/alice.config", # "label": "1stlabel" # # } json_data = request.form.to_dict() fileFieldCount= int(json_data['fileFieldCount']) # object that contains the files file_obj={} # object that contains all the other form fields form_field_obj ={} print("requetssss ------") print(request.files.to_dict()) print(request.form.to_dict()) print('json_data') print(json_data) fileNames = json.loads(json_data['fileNames']) textFields = json.loads(json_data['textFields']) for i in range(0, fileFieldCount): file_obj[fileNames[str(i)]] = request.files[str(i)].read() textFieldsKeys = list(textFields.keys()) for key in textFieldsKeys: form_field_obj[key] = textFields[key] data_obj = {} data_obj['file_obj'] = file_obj data_obj['form_field_obj'] = form_field_obj label = json_data['label'] aliceFile = json_data['alice'] password = json_data['password'] file_url = '/tmp/' + label + '.json' label = label.encode() hash = data_obj obj_to_be_stored = createDataObject(hash, json_data['label']) f = open(file_url, 'w') f.write(json.dumps(obj_to_be_stored)) f.close() alice_config = AliceConfiguration.from_configuration_file( filepath=aliceFile, known_nodes={ursula}, start_learning_now=False, ) alice_config.keyring.unlock(password=password) alicia = alice_config(domains={'TEMPORARY_DOMAIN'}) alicia.start_learning_loop(now=True) policy_pubkey = alicia.get_policy_pubkey_from_label(label) # Initialise Enrico enrico = Enrico(policy_encrypting_key=policy_pubkey) print ("Done upto 111") hash = msgpack.dumps(hash, use_bin_type=True) message_kit, _signature = enrico.encrypt_message(hash) message_kit_bytes = message_kit.to_bytes() newMsg = UmbralMessageKit.from_bytes(message_kit_bytes) print ("\n\ncheck") print (message_kit_bytes == newMsg.to_bytes()) print (message_kit) print (newMsg) data = {} data['message'] = message_kit_bytes.hex() data['label'] = label.decode('utf-8') data['policy_public_key'] = policy_pubkey.to_bytes().hex() data['alice_sig_pubkey'] = bytes(alicia.stamp).hex() data['data_source'] = bytes(enrico.stamp).hex() print ('result\n') print (data) print ('#####\n') return json.dumps(data)
def test_collect_rewards_integration( click_runner, funded_blockchain, configuration_file_location, alice_blockchain_test_config, bob_blockchain_test_config, charlie_blockchain_test_config, random_policy_label, blockchain_ursulas, staking_participant): blockchain = staking_participant.blockchain # Alice creates a policy and grants Bob access alice = alice_blockchain_test_config.produce( blockchain=funded_blockchain, network_middleware=MockRestMiddleware(), known_nodes=blockchain_ursulas) bob = bob_blockchain_test_config.produce( blockchain=blockchain, network_middleware=MockRestMiddleware(), known_nodes=blockchain_ursulas) # # Back to the Ursulas... # half_stake_time = MIN_LOCKED_PERIODS // 2 # Test setup logger = staking_participant.log # Enter the Teacher's Logger, and current_period = 1 # State the initial period for incrementing miner = Miner(checksum_address=staking_participant.checksum_public_address, blockchain=blockchain, is_me=True) pre_stake_eth_balance = miner.eth_balance # Finish the passage of time... once and for all for _ in range(half_stake_time): current_period += 1 logger.debug(f"period {current_period}") blockchain.time_travel(periods=1) miner.confirm_activity() M, N = 1, 1 expiration = maya.now() + datetime.timedelta(days=3) blockchain_policy = alice.grant(bob=bob, label=random_policy_label, m=M, n=1, value=POLICY_VALUE, expiration=expiration, handpicked_ursulas={staking_participant}) # Bob joins the policy bob.join_policy(random_policy_label, bytes(alice.stamp)) # Enrico Encrypts (of course) enrico = Enrico(policy_encrypting_key=blockchain_policy.public_key, network_middleware=MockRestMiddleware()) for index, _period in enumerate(range(half_stake_time - 5)): logger.debug(f"period {current_period}") alphabet = string.ascii_letters + string.digits # Random Request Periods if not random.choice((True, False)): continue # maybe re-encrypt max_reencryptions_per_period = 5 quantity = random.choice(range(max_reencryptions_per_period + 1)) quantity *= index # factorial or 0 verifying_key = UmbralPublicKey.from_bytes(bytes(alice.stamp)) # Random Re-encryptions for _i in range(quantity): # Encrypt random_data = ''.join( secrets.choice(alphabet) for i in range(secrets.choice(range(20, 100)))) ciphertext, signature = enrico.encrypt_message( message=bytes(random_data, encoding='utf-8')) # Retrieve payload = dict(message_kit=ciphertext, data_source=enrico, alice_verifying_key=verifying_key, label=random_policy_label) _cleartext = bob.retrieve(**payload) # Ursula Staying online and the clock advancing blockchain.time_travel(periods=1) miner.confirm_activity() current_period += 1 # Finish the passage of time... once and for all for _ in range(5): current_period += 1 logger.debug(f"period {current_period}") blockchain.time_travel(periods=1) miner.confirm_activity() # # WHERES THE MONEY URSULA?? - Collecting Rewards # # The address the client wants Ursula to send rewards to burner_wallet = blockchain.interface.w3.eth.account.create( INSECURE_DEVELOPMENT_PASSWORD) assert blockchain.interface.w3.eth.getBalance(burner_wallet.address) == 0 # Snag a random teacher from the fleet random_teacher = list(blockchain_ursulas).pop() collection_args = ('--mock-networking', 'ursula', 'collect-reward', '--teacher-uri', random_teacher.rest_interface, '--config-file', configuration_file_location, '--withdraw-address', burner_wallet.address, '--poa', '--force') result = click_runner.invoke(nucypher_cli, collection_args, input=INSECURE_DEVELOPMENT_PASSWORD, catch_exceptions=False) assert result.exit_code == 0 collected_reward = blockchain.interface.w3.eth.getBalance( burner_wallet.address) assert collected_reward != 0 expected_reward = Web3.toWei(21, 'gwei') * 30 * M assert collected_reward == expected_reward assert miner.eth_balance == pre_stake_eth_balance
finnegans_wake = file.readlines() print("\n************** Encrypt and Retrieve **************\n") for counter, plaintext in enumerate(finnegans_wake): # 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. # This demonstrates how many individual encryptors may encrypt for a single policy. # In other words -- Many data sources (Enricos) can encrypt for the policy's public key. enrico = Enrico(policy_encrypting_key=policy_public_key) # 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 = enrico.encrypt_message(plaintext) enrico_public_key = bytes(enrico.stamp) del enrico ############### # Back to Bob # ############### # Now Bob can retrieve the original message by requesting re-encryption from nodes. cleartexts = bob.retrieve_and_decrypt( [message_kit], alice_verifying_key=alice_verifying_key, encrypted_treasure_map=policy.treasure_map) # We show that indeed this is the passage originally encrypted by Enrico. assert plaintext == cleartexts[0]
print("") print("") ################################# # Retrieving Alice's public key # ################################# alice_pubkey_restored_from_ancient_scroll = UmbralPublicKey.from_bytes( alices_pubkey_bytes_saved_for_posterity) ####################################### # Encrypting and decrypting for bob A # ####################################### try: cipherdata_A, _signature_A = enrico_A.encrypt_message(ipfs_bytes) print("Enrico_A encrypted data for Bob_A") data_source_public_key_A = bytes(enrico_A.stamp) enrico_as_understood_by_bob_A = Enrico.from_public_keys( verifying_key=data_source_public_key_A, policy_encrypting_key=policy_pubkey_A) print("Honest researcher is attempting to decrypted") decrypted_data_A = BOB_A.retrieve( message_kit=cipherdata_A, data_source=enrico_as_understood_by_bob_A, alice_verifying_key=alice_pubkey_restored_from_ancient_scroll, label=label_A) decrypted_data_A_0 = decrypted_data_A[0].decode('utf8').replace('\\"', '"')