def test_lifecycle_with_serialization(N, M, signing_mode, curve=default_curve()): """ This test is a variant of test_simple_api, but with intermediate serialization/deserialization steps, modeling how pyUmbral artifacts (such as keys, ciphertexts, etc) will actually be used. These intermediate steps are in between the different 'usage domains' in NuCypher, namely, key generation, delegation, encryption, decryption by Alice, re-encryption by Ursula, and decryption by Bob. Manually injects UmbralParameters for multi-curve testing. """ # Convenience method to avoid replicating key generation code def new_keypair_bytes(): privkey = UmbralPrivateKey.gen_key(params=params) return privkey.to_bytes(), privkey.get_pubkey().to_bytes() ## SETUP params = UmbralParameters(curve=curve) delegating_privkey_bytes, delegating_pubkey_bytes = new_keypair_bytes() signing_privkey_bytes, signing_pubkey_bytes = new_keypair_bytes() receiving_privkey_bytes, receiving_pubkey_bytes = new_keypair_bytes() ## DELEGATION DOMAIN: ## Alice delegates decryption rights to some Bob by generating a set of ## KFrags, using her delegating private key and Bob's receiving public key delegating_privkey = UmbralPrivateKey.from_bytes(delegating_privkey_bytes, params=params) signing_privkey = UmbralPrivateKey.from_bytes(signing_privkey_bytes, params=params) receiving_pubkey = UmbralPublicKey.from_bytes(receiving_pubkey_bytes, params=params) signer = Signer(signing_privkey) sign_delegating_key, sign_receiving_key = signing_mode kfrags = pre.generate_kfrags(delegating_privkey=delegating_privkey, receiving_pubkey=receiving_pubkey, threshold=M, N=N, signer=signer, sign_delegating_key=sign_delegating_key, sign_receiving_key=sign_receiving_key) kfrags_bytes = tuple(map(bytes, kfrags)) del kfrags del signer del delegating_privkey del signing_privkey del receiving_pubkey del params ## ENCRYPTION DOMAIN ## params = UmbralParameters(curve=curve) delegating_pubkey = UmbralPublicKey.from_bytes(delegating_pubkey_bytes, params) plain_data = b'peace at dawn' ciphertext, capsule = pre.encrypt(delegating_pubkey, plain_data) capsule_bytes = bytes(capsule) del capsule del delegating_pubkey del params ## DECRYPTION BY ALICE ## params = UmbralParameters(curve=curve) delegating_privkey = UmbralPrivateKey.from_bytes(delegating_privkey_bytes, params=params) capsule = pre.Capsule.from_bytes(capsule_bytes, params) cleartext = pre.decrypt(ciphertext, capsule, delegating_privkey) assert cleartext == plain_data del delegating_privkey del capsule del params ## RE-ENCRYPTION DOMAIN (i.e., Ursula's side) cfrags_bytes = list() for kfrag_bytes in kfrags_bytes: params = UmbralParameters(curve=curve) delegating_pubkey = UmbralPublicKey.from_bytes(delegating_pubkey_bytes, params) signing_pubkey = UmbralPublicKey.from_bytes(signing_pubkey_bytes, params) receiving_pubkey = UmbralPublicKey.from_bytes(receiving_pubkey_bytes, params) capsule = pre.Capsule.from_bytes(capsule_bytes, params) capsule.set_correctness_keys(delegating=delegating_pubkey, receiving=receiving_pubkey, verifying=signing_pubkey) # TODO: use params instead of curve? kfrag = KFrag.from_bytes(kfrag_bytes, params.curve) assert kfrag.verify(signing_pubkey, delegating_pubkey, receiving_pubkey, params) cfrag_bytes = bytes(pre.reencrypt(kfrag, capsule)) cfrags_bytes.append(cfrag_bytes) del capsule del kfrag del params del delegating_pubkey del signing_pubkey del receiving_pubkey ## DECRYPTION DOMAIN (i.e., Bob's side) params = UmbralParameters(curve=curve) capsule = pre.Capsule.from_bytes(capsule_bytes, params) delegating_pubkey = UmbralPublicKey.from_bytes(delegating_pubkey_bytes, params) signing_pubkey = UmbralPublicKey.from_bytes(signing_pubkey_bytes, params) receiving_privkey = UmbralPrivateKey.from_bytes(receiving_privkey_bytes, params=params) receiving_pubkey = receiving_privkey.get_pubkey() capsule.set_correctness_keys(delegating=delegating_pubkey, receiving=receiving_pubkey, verifying=signing_pubkey) for cfrag_bytes in cfrags_bytes: # TODO: use params instead of curve? cfrag = CapsuleFrag.from_bytes(cfrag_bytes, params.curve) capsule.attach_cfrag(cfrag) reenc_cleartext = pre.decrypt(ciphertext, capsule, receiving_privkey) assert reenc_cleartext == plain_data
######################### enrico = Enrico(policy_encrypting_key=policy_pubkey) # 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. single_passage_ciphertext, _signature = enrico.encrypt_message(plaintext) data_source_public_key = bytes(enrico.stamp) del enrico ############### # Back to Bob # ############### enrico_as_understood_by_bob = Enrico.from_public_keys( {SigningPower: data_source_public_key}, policy_encrypting_key=policy_pubkey ) # Now Bob can retrieve the original message. alice_pubkey_restored_from_ancient_scroll = UmbralPublicKey.from_bytes(alices_pubkey_bytes_saved_for_posterity) delivered_cleartexts = BOB.retrieve(message_kit=single_passage_ciphertext, data_source=enrico_as_understood_by_bob, alice_verifying_key=alice_pubkey_restored_from_ancient_scroll, label=label) # We show that indeed this is the passage originally encrypted by Enrico. assert plaintext == delivered_cleartexts[0] print("Retrieved: {}".format(delivered_cleartexts[0]))
def _create_enrico(emitter, policy_encrypting_key) -> Enrico: policy_encrypting_key = UmbralPublicKey.from_bytes(bytes.fromhex(policy_encrypting_key)) ENRICO = Enrico(policy_encrypting_key=policy_encrypting_key) ENRICO.controller.emitter = emitter return ENRICO
def grant_others_access(self, username, password, cid, label, recp_enc_b58_key, recp_sig_b58_key): alice = self.act_as_alice(username, password) enc = UmbralPublicKey.from_bytes(base58.b58decode(recp_enc_b58_key)) sig = UmbralPublicKey.from_bytes(base58.b58decode(recp_sig_b58_key)) nucid = creat_nucid(alice, cid, enc, sig, label.encode("utf-8")) return nucid
federated_only=True, crypto_power_ups=power_ups, start_learning_now=True, abort_on_learning_error=True, known_nodes=[ursula], save_metadata=False, network_middleware=RestMiddleware(), ) print("Doctor = ", doctor) # Let's join the policy generated by Alicia. We just need some info about it. with open("policy-metadata.json", 'r') as f: policy_data = json.load(f) policy_pubkey = UmbralPublicKey.from_bytes( bytes.fromhex(policy_data["policy_pubkey"])) alices_sig_pubkey = UmbralPublicKey.from_bytes( bytes.fromhex(policy_data["alice_sig_pubkey"])) label = policy_data["label"].encode() print("The Doctor joins policy for label '{}'".format(label.decode("utf-8"))) doctor.join_policy(label, alices_sig_pubkey) # Now that the Doctor joined the policy in the NuCypher network, # he can retrieve encrypted data which he can decrypt with his private key. # But first we need some encrypted data! # Let's read the file produced by the heart monitor and unpack the MessageKits, # which are the individual ciphertexts. data = msgpack.load(open("heart_data.msgpack", "rb"), raw=False) message_kits = (UmbralMessageKit.from_bytes(k) for k in data['kits'])
def test_pubkey_roundtrip(p): k = UmbralPublicKey(p, params) assert (k == UmbralPublicKey.from_bytes(k.to_bytes(), params=params))
def canonical_address_from_umbral_key(public_key: UmbralPublicKey) -> bytes: pubkey_raw_bytes = public_key.to_bytes(is_compressed=False)[1:] eth_pubkey = EthKeyAPI.PublicKey(pubkey_raw_bytes) canonical_address = eth_pubkey.to_canonical_address() return canonical_address
def update_cached_decrypted_measurements_list(read_time, df_json_latest_measurements, bob_id): if int(read_time) == 0: # button never clicked but triggered by interval return None # Let's join the policy generated by Alicia. We just need some info about it. with open("policy-metadata.json", 'r') as f: policy_data = json.load(f) policy_pubkey = UmbralPublicKey.from_bytes( bytes.fromhex(policy_data["policy_pubkey"])) alices_sig_pubkey = UmbralPublicKey.from_bytes( bytes.fromhex(policy_data["alice_sig_pubkey"])) label = policy_data["label"].encode() source_metadata = msgpack.load(open("car_data.msgpack", "rb"), raw=False) # The bob also needs to create a view of the Data Source from its public keys data_source = DataSource.from_public_keys( policy_public_key=policy_pubkey, datasource_public_key=source_metadata['data_source'], label=label) if not joined: print("The Doctor joins policy for label '{}' " "and pubkey {}".format(policy_data["label"], policy_data["policy_pubkey"])) bob.join_policy(label, alices_sig_pubkey) joined.append(1) df = pd.DataFrame() last_timestamp = time.time() - 5 # last 5s if (df_json_latest_measurements is not None) and (df_json_latest_measurements != ACCESS_REVOKED): df = pd.read_json(df_json_latest_measurements, convert_dates=False) if len(df) > 0: # sort readings and order by timestamp df = df.sort_values(by='timestamp') # use last timestamp last_timestamp = df['timestamp'].iloc[-1] db_conn = sqlite3.connect(DB_FILE) encrypted_df_readings = pd.read_sql_query( 'SELECT Timestamp, EncryptedData ' 'FROM {} ' #'WHERE Timestamp > "{}" ' 'ORDER BY Timestamp ' 'LIMIT 30;'.format(DB_NAME), #, last_timestamp), db_conn) print("N READ", len(encrypted_df_readings)) for index, row in encrypted_df_readings.iterrows(): kit_bytes = bytes.fromhex(row['EncryptedData']) message_kit = UmbralMessageKit.from_bytes(kit_bytes) # Now he can ask the NuCypher network to get a re-encrypted version of each MessageKit. try: retrieved_plaintexts = bob.retrieve( message_kit=message_kit, data_source=data_source, alice_verifying_key=alices_sig_pubkey) plaintext = msgpack.loads(retrieved_plaintexts[0], raw=False) print(plaintext) except Exception as e: print(str(e)) continue readings = plaintext['carInfo'] readings['timestamp'] = row['Timestamp'] df = df.append(readings, ignore_index=True) # only cache last 30 readings rows_to_remove = len(df) - 30 if rows_to_remove > 0: df = df.iloc[rows_to_remove:] return df.to_json()
def enrico(click_config, action, policy_encrypting_key, dry_run, http_port, message): """ "Enrico the Encryptor" management commands. \b Actions ------------------------------------------------- \b run Start Enrico's controller. encrypt Encrypt a message under a given policy public key """ # # Validate # if not policy_encrypting_key: raise click.BadArgumentUsage( '--policy-encrypting-key is required to start Enrico.') # Banner emitter = click_config.emitter emitter.clear() emitter.banner(ENRICO_BANNER.format(policy_encrypting_key)) # # Make Enrico # policy_encrypting_key = UmbralPublicKey.from_bytes( bytes.fromhex(policy_encrypting_key)) ENRICO = Enrico(policy_encrypting_key=policy_encrypting_key) ENRICO.controller.emitter = emitter # TODO: set it on object creation? Or not set at all? # # Actions # if action == 'run': # RPC if click_config.json_ipc: rpc_controller = ENRICO.make_rpc_controller() _transport = rpc_controller.make_control_transport() rpc_controller.start() return ENRICO.log.info('Starting HTTP Character Web Controller') controller = ENRICO.make_web_controller() return controller.start(http_port=http_port, dry_run=dry_run) elif action == 'encrypt': # Validate if not message: raise click.BadArgumentUsage( '--message is a required flag to encrypt.') # Request encryption_request = {'message': message} response = ENRICO.controller.encrypt_message( request=encryption_request) return response else: raise click.BadArgumentUsage
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
parser.add_argument("function", help="Function name to be executed") parser.add_argument("--label", help="Policy label") parser.add_argument("--policypubkeyHex", help="Policy Pubkey") parser.add_argument("--dirPath", help="Path of tracks") parser.add_argument("--bobpubkeys", help="Listener Pubkeys") args = parser.parse_args() if args.function == 'initialize_alice': artist.initialize_alice() if args.function == 'get_policy_pubkey': policy_key = artist.get_policy_pubkey(args.label) print(policy_key.to_bytes().hex()) if args.function == 'encrypt_track_segments': policy_key = UmbralPublicKey.from_bytes(bytes.fromhex( args.policypubkeyHex)) track_encrypt.encrypt_track_segments(policy_key, args.dirPath) if args.function == 'encrypt_file': policy_key = UmbralPublicKey.from_bytes(bytes.fromhex( args.policypubkeyHex)) track_encrypt.encrypt_track(policy_key, args.dirPath) if args.function == 'grant_access_policy': bob_pub_keys = json.loads(args.bobpubkeys) bobpubkeys = {} bobpubkeys["enc"] = UmbralPublicKey.from_bytes( bytes.fromhex(bob_pub_keys["enc"])) bobpubkeys["sig"] = UmbralPublicKey.from_bytes( bytes.fromhex(bob_pub_keys["sig"]))
def from_public_keys(cls, policy_public_key, datasource_public_key, label): umbral_public_key = UmbralPublicKey.from_bytes(datasource_public_key) return cls(policy_public_key, signing_keypair=SigningKeypair(public_key=umbral_public_key), label=label, )
# b"\x03\\:\xd1\x0e\x16\xa6\xab\xcaj\x91\xe0\x82h\xb1J\xd6\x01+\x98uz'S"", " b'\xadj\x94\x06\x96\x9e\x8aJ*' # renove_alice_key = base64.b64decode(apb_64) # pprint(apb_64) # pprint("===========renove_alice_key") # pprint(renove_alice_key.decode("utf-8", errors="ignore")) apk_hex = alices_public_key.to_bytes().hex() bpk_hex = bobs_public_key.to_bytes().hex() vpk_hex = alices_verifying_key.to_bytes().hex() priv_hex = alices_private_key.to_bytes().hex() # pprint(apk_hex) # pprint("===========hex") # text = str( apb_64, 'utf-8' ) # pprint("===========pb_64") # pprint(text) verifying_key_fromBytes = UmbralPublicKey.from_bytes(bytes.fromhex(apk_hex)) # print(verifying_key_fromBytes) pprint(priv_hex) pprint("?????") # dict = [alices_public_key, bobs_public_key, alices_verifying_key] # print str (dict) t = json.dumps({ 'delegating': apk_hex, "receiving": bpk_hex, "verifying": vpk_hex }) # '[1, 2, [3, 4]]' pprint(t) pprint("!!!!") #return t
def encrypting_public_key(self): encrypting_pubkey_bytes = _read_keyfile(keypath=self.__root_pub_keypath, deserializer=None) encrypting_pubkey = UmbralPublicKey.from_bytes(encrypting_pubkey_bytes) return encrypting_pubkey
book = Book(author) first_buyer = Buyer( b"First Buyer's ETH account", Bob(known_nodes=(URSULA, ), federated_only=True, known_certificates_dir=CERTIFICATE_DIR)) book_store_delivery = BookStoreDelivery(book) book_store_contract = BookStoreEthContract( book, author, 10, book_store_delivery.deliver_purchase) author_public_key, policy_public_key, data_source_public_key, label, kit = first_buyer.send_eth_to( book_store_contract, 10) first_buyer.character.join_policy( label, # The label - he needs to know what data he's after. bytes(author.character.stamp ), # To verify the signature, he'll need Alice's public key. # He can also bootstrap himself onto the network more quickly # by providing a list of known nodes at this time. node_list=[("localhost", 3601)]) datasource_as_understood_by_bob = DataSource.from_public_keys( policy_public_key=policy_public_key, datasource_public_key=data_source_public_key, label=label) alice_pubkey_restored_from_ancient_scroll = UmbralPublicKey.from_bytes( author_public_key) delivered_cleartexts = first_buyer.character.retrieve( message_kit=kit, data_source=datasource_as_understood_by_bob, alice_verifying_key=alice_pubkey_restored_from_ancient_scroll) print(delivered_cleartexts)
def signing_public_key(self): signature_pubkey_bytes = _read_keyfile( keypath=self.__signing_pub_keypath, deserializer=None) signature_pubkey = UmbralPublicKey.from_bytes(signature_pubkey_bytes) return signature_pubkey
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()