def set_policy(id_as_hex): """ REST endpoint for setting a kFrag. TODO: Instead of taking a Request, use the apistar typing system to type a payload and validate / split it. TODO: Validate that the kfrag being saved is pursuant to an approved Policy (see #121). """ policy_message_kit = UmbralMessageKit.from_bytes(request.data) alices_verifying_key = policy_message_kit.sender_pubkey_sig alice = _alice_class.from_public_keys({SigningPower: alices_verifying_key}) try: cleartext = verifier(alice, policy_message_kit, decrypt=True) except InvalidSignature: # TODO: Perhaps we log this? return Response(status_code=400) kfrag = KFrag.from_bytes(cleartext) if not kfrag.verify(signing_pubkey=alices_verifying_key): raise InvalidSignature("{} is invalid".format(kfrag)) with ThreadedSession(db_engine) as session: datastore.attach_kfrag_to_saved_arrangement( alice, id_as_hex, kfrag, session=session) # TODO: Sign the arrangement here. #495 return "" # TODO: Return A 200, with whatever policy metadata.
def reencrypt_via_rest(id_as_hex): from nucypher.policy.models import WorkOrder # Avoid circular import arrangement_id = binascii.unhexlify(id_as_hex) work_order = WorkOrder.from_rest_payload(arrangement_id, request.data) log.info("Work Order from {}, signed {}".format(work_order.bob, work_order.receipt_signature)) with ThreadedSession(db_engine) as session: policy_arrangement = datastore.get_policy_arrangement(arrangement_id=id_as_hex.encode(), session=session) kfrag_bytes = policy_arrangement.kfrag # Careful! :-) verifying_key_bytes = policy_arrangement.alice_pubkey_sig.key_data # TODO: Push this to a lower level. kfrag = KFrag.from_bytes(kfrag_bytes) alices_verifying_key = UmbralPublicKey.from_bytes(verifying_key_bytes) cfrag_byte_stream = b"" for capsule, capsule_signature in zip(work_order.capsules, work_order.capsule_signatures): # This is the capsule signed by Bob capsule_signature = bytes(capsule_signature) # Ursula signs on top of it. Now both are committed to the same capsule. capsule_signed_by_both = bytes(stamp(capsule_signature)) capsule.set_correctness_keys(verifying=alices_verifying_key) cfrag = pre.reencrypt(kfrag, capsule, metadata=capsule_signed_by_both) log.info("Re-encrypting for {}, made {}.".format(capsule, cfrag)) signature = stamp(bytes(cfrag) + bytes(capsule)) cfrag_byte_stream += VariableLengthBytestring(cfrag) + signature # TODO: Put this in Ursula's datastore work_order_tracker.append(work_order) headers = {'Content-Type': 'application/octet-stream'} return Response(response=cfrag_byte_stream, headers=headers)
def create_keyfrag(): if not request.json or not 'id' in request.json or request.json['id'] in keyfrags.keys(): abort(400) k_id = request.json['id'] show_debug("Storing key fragment with id: " + str(k_id)) keyfrags[k_id] = { 'capsule': pre.Capsule.from_bytes(binascii.unhexlify(request.json['capsule'].encode()), params), 'keyfrag': KFrag.from_bytes(binascii.unhexlify(request.json['keyfrag'].encode()), SECP256K1), 'delegating': UmbralPublicKey.from_bytes(binascii.unhexlify(request.json['delegating'].encode()), params), 'receiving': UmbralPublicKey.from_bytes(binascii.unhexlify(request.json['receiving'].encode()), params), 'verifying': UmbralPublicKey.from_bytes(binascii.unhexlify(request.json['verifying'].encode()), params), 'rekeyfrag': None } show_debug('-- Delegating:' + request.json['delegating']) show_debug('-- Receiving:' + request.json['receiving']) now = time.time()*1000 keyfrags[k_id]['capsule'].set_correctness_keys(delegating=keyfrags[k_id]['delegating'], receiving=keyfrags[k_id]['receiving'], verifying=keyfrags[k_id]['verifying']) keyfrags[k_id]['rekeyfrag'] = pre.reencrypt(kfrag=keyfrags[k_id]['keyfrag'], capsule=keyfrags[k_id]['capsule']) end = time.time()*1000 enc_tot = end-now show_debug("-- Re-encrypted key fragment with id: " + str(k_id)) return jsonify({'time': enc_tot}), 201
def test_decentralized_grant(blockchain_alice, blockchain_bob, agency): # Setup the policy details n = 3 policy_end_datetime = maya.now() + datetime.timedelta(days=5) label = b"this_is_the_path_to_which_access_is_being_granted" # Create the Policy, Granting access to Bob policy = blockchain_alice.grant( bob=blockchain_bob, label=label, m=2, n=n, rate=int(1e18), # one ether expiration=policy_end_datetime) # Check the policy ID policy_id = keccak_digest(policy.label + bytes(policy.bob.stamp)) assert policy_id == policy.id # The number of accepted arrangements at least the number of Ursulas we're using (n) assert len(policy._accepted_arrangements) >= n # The number of actually enacted arrangements is exactly equal to n. assert len(policy._enacted_arrangements) == n # Let's look at the enacted arrangements. for kfrag in policy.kfrags: arrangement = policy._enacted_arrangements[kfrag] # Get the Arrangement from Ursula's datastore, looking up by the Arrangement ID. retrieved_policy = arrangement.ursula.datastore.get_policy_arrangement( arrangement.id.hex().encode()) retrieved_kfrag = KFrag.from_bytes(retrieved_policy.kfrag) assert kfrag == retrieved_kfrag # Test PolicyCredential w/o TreasureMap credential = policy.credential(with_treasure_map=False) assert credential.alice_verifying_key == policy.alice.stamp assert credential.label == policy.label assert credential.expiration == policy.expiration assert credential.policy_pubkey == policy.public_key assert credential.treasure_map is None cred_json = credential.to_json() deserialized_cred = PolicyCredential.from_json(cred_json) assert credential == deserialized_cred # Test PolicyCredential w/ TreasureMap credential = policy.credential() assert credential.alice_verifying_key == policy.alice.stamp assert credential.label == policy.label assert credential.expiration == policy.expiration assert credential.policy_pubkey == policy.public_key assert credential.treasure_map == policy.treasure_map cred_json = credential.to_json() deserialized_cred = PolicyCredential.from_json(cred_json) assert credential == deserialized_cred
def test_federated_grant(federated_alice, federated_bob): # Setup the policy details m, n = 2, 3 policy_end_datetime = maya.now() + datetime.timedelta(days=5) label = b"this_is_the_path_to_which_access_is_being_granted" # Create the Policy, granting access to Bob policy = federated_alice.grant(federated_bob, label, m=m, n=n, expiration=policy_end_datetime) # The number of accepted arrangements at least the number of Ursulas we're using (n) assert len(policy._accepted_arrangements) >= n # The number of actually enacted arrangements is exactly equal to n. assert len(policy._enacted_arrangements) == n # Let's look at the enacted arrangements. for kfrag in policy.kfrags: arrangement = policy._enacted_arrangements[kfrag] # Get the Arrangement from Ursula's datastore, looking up by hrac. # This will be changed in 180, when we use the Arrangement ID. proper_hrac = keccak_digest( bytes(federated_alice.stamp) + bytes(federated_bob.stamp) + label) retrieved_policy = arrangement.ursula.datastore.get_policy_arrangement( arrangement.id.hex().encode()) retrieved_kfrag = KFrag.from_bytes(retrieved_policy.kfrag) assert kfrag == retrieved_kfrag
def test_mocked_decentralized_grant(blockchain_alice, blockchain_bob, three_agents): # Monkey patch Policy Creation _token_agent, _miner_agent, policy_agent = three_agents policy_agent.blockchain.wait_for_receipt = MockPolicyCreation.wait_for_receipt policy_agent.contract.functions.createPolicy = MockPolicyCreation # Setup the policy details n = 3 policy_end_datetime = maya.now() + datetime.timedelta(days=5) label = b"this_is_the_path_to_which_access_is_being_granted" # Create the Policy, Granting access to Bob policy = blockchain_alice.grant(blockchain_bob, label, m=2, n=n, expiration=policy_end_datetime) # The number of accepted arrangements at least the number of Ursulas we're using (n) assert len(policy._accepted_arrangements) >= n # The number of actually enacted arrangements is exactly equal to n. assert len(policy._enacted_arrangements) == n # Let's look at the enacted arrangements. for kfrag in policy.kfrags: arrangement = policy._enacted_arrangements[kfrag] # Get the Arrangement from Ursula's datastore, looking up by the Arrangement ID. retrieved_policy = arrangement.ursula.datastore.get_policy_arrangement(arrangement.id.hex().encode()) retrieved_kfrag = KFrag.from_bytes(retrieved_policy.kfrag) assert kfrag == retrieved_kfrag
def set_policy(id_as_hex): """ REST endpoint for setting a kFrag. """ policy_message_kit = UmbralMessageKit.from_bytes(request.data) alices_verifying_key = policy_message_kit.sender_verifying_key alice = _alice_class.from_public_keys( verifying_key=alices_verifying_key) try: cleartext = this_node.verify_from(alice, policy_message_kit, decrypt=True) except InvalidSignature: # TODO: Perhaps we log this? Essentially 355. return Response(status_code=400) if not this_node.federated_only: # This splitter probably belongs somewhere canonical. transaction_splitter = BytestringSplitter(32) tx, kfrag_bytes = transaction_splitter(cleartext, return_remainder=True) try: # Get all of the arrangements and verify that we'll be paid. # TODO: We'd love for this part to be impossible to reduce the risk of collusion. #1274 arranged_addresses = this_node.policy_agent.fetch_arrangement_addresses_from_policy_txid( tx, timeout=this_node.synchronous_query_timeout) except TimeExhausted: # Alice didn't pay. Return response with that weird status code. this_node.suspicious_activities_witnessed['freeriders'].append( (alice, f"No transaction matching {tx}.")) return Response(status=402) this_node_has_been_arranged = this_node.checksum_address in arranged_addresses if not this_node_has_been_arranged: this_node.suspicious_activities_witnessed['freeriders'].append( (alice, f"The transaction {tx} does not list me as a Worker - it lists {arranged_addresses}." )) return Response(status=402) else: _tx = NO_BLOCKCHAIN_CONNECTION kfrag_bytes = cleartext kfrag = KFrag.from_bytes(kfrag_bytes) if not kfrag.verify(signing_pubkey=alices_verifying_key): raise InvalidSignature("{} is invalid".format(kfrag)) with datastore.describe(PolicyArrangement, id_as_hex, writeable=True) as policy_arrangement: if not policy_arrangement.alice_verifying_key == alice.stamp.as_umbral_pubkey( ): raise alice.SuspiciousActivity policy_arrangement.kfrag = kfrag # TODO: Sign the arrangement here. #495 return "" # TODO: Return A 200, with whatever policy metadata.
def test_kfrag_roundtrip(d, b0, p0, p1, sig_proxy, sig_bob): k = KFrag(identifier=d, bn_key=b0, point_commitment=p0, point_precursor=p1, signature_for_proxy=sig_proxy, signature_for_bob=sig_bob) assert_kfrag_eq(k, KFrag.from_bytes(k.to_bytes()))
def reencrypt_via_rest(id_as_hex): from nucypher.policy.models import WorkOrder # Avoid circular import arrangement_id = binascii.unhexlify(id_as_hex) work_order = WorkOrder.from_rest_payload(arrangement_id, request.data) log.info("Work Order from {}, signed {}".format( work_order.bob, work_order.receipt_signature)) with ThreadedSession(db_engine) as session: policy_arrangement = datastore.get_policy_arrangement( arrangement_id=id_as_hex.encode(), session=session) kfrag_bytes = policy_arrangement.kfrag # Careful! :-) verifying_key_bytes = policy_arrangement.alice_pubkey_sig.key_data # TODO: Push this to a lower level. Perhaps to Ursula character? #619 kfrag = KFrag.from_bytes(kfrag_bytes) alices_verifying_key = UmbralPublicKey.from_bytes(verifying_key_bytes) cfrag_byte_stream = b"" alices_address = canonical_address_from_umbral_key( alices_verifying_key) if not alices_address == work_order.alice_address: message = f"This Bob ({work_order.bob}) sent an Alice's ETH address " \ f"({work_order.alice_address}) that doesn't match " \ f"the one I have ({alices_address})." raise SuspiciousActivity(message) bob_pubkey = work_order.bob.stamp.as_umbral_pubkey() if not work_order.alice_address_signature.verify( message=alices_address, verifying_key=bob_pubkey): message = f"This Bob ({work_order.bob}) sent an invalid signature of Alice's ETH address" raise InvalidSignature(message) # This is Bob's signature of Alice's verifying key as ETH address. alice_address_signature = bytes(work_order.alice_address_signature) for capsule, capsule_signature in zip(work_order.capsules, work_order.capsule_signatures): # This is the capsule signed by Bob capsule_signature = bytes(capsule_signature) # Ursula signs on top of it. Now both are committed to the same capsule. # She signs Alice's address too. ursula_signature = stamp(capsule_signature + alice_address_signature) capsule.set_correctness_keys(verifying=alices_verifying_key) cfrag = pre.reencrypt(kfrag, capsule, metadata=bytes(ursula_signature)) log.info(f"Re-encrypting for {capsule}, made {cfrag}.") signature = stamp(bytes(cfrag) + bytes(capsule)) cfrag_byte_stream += VariableLengthBytestring(cfrag) + signature # TODO: Put this in Ursula's datastore work_order_tracker.append(work_order) headers = {'Content-Type': 'application/octet-stream'} return Response(response=cfrag_byte_stream, headers=headers)
def reencrypt_via_rest(id_as_hex): # TODO: How to pass Ursula's identity evidence to Bob? #962 # 'Identity evidence' is a signature of her stamp with the checksum address from nucypher.policy.models import WorkOrder # Avoid circular import arrangement_id = binascii.unhexlify(id_as_hex) with ThreadedSession(db_engine) as session: policy_arrangement = datastore.get_policy_arrangement( arrangement_id=id_as_hex.encode(), session=session) kfrag_bytes = policy_arrangement.kfrag # Careful! :-) verifying_key_bytes = policy_arrangement.alice_pubkey_sig.key_data # TODO: Push this to a lower level. Perhaps to Ursula character? #619 kfrag = KFrag.from_bytes(kfrag_bytes) alices_verifying_key = UmbralPublicKey.from_bytes(verifying_key_bytes) alices_address = canonical_address_from_umbral_key( alices_verifying_key) work_order = WorkOrder.from_rest_payload(arrangement_id=arrangement_id, rest_payload=request.data, ursula_pubkey_bytes=bytes( this_node.stamp), alice_address=alices_address) log.info( f"Work Order from {work_order.bob}, signed {work_order.receipt_signature}" ) cfrag_byte_stream = b"" for task in work_order.tasks: # Ursula signs on top of Bob's signature of each task. # Now both are committed to the same task. See #259. reencryption_metadata = bytes( this_node.stamp(bytes(task.signature))) capsule = task.capsule capsule.set_correctness_keys(verifying=alices_verifying_key) cfrag = pre.reencrypt(kfrag, capsule, metadata=reencryption_metadata) log.info(f"Re-encrypting for {capsule}, made {cfrag}.") # Finally, Ursula commits to her result reencryption_signature = this_node.stamp(bytes(cfrag)) cfrag_byte_stream += VariableLengthBytestring( cfrag) + reencryption_signature # TODO: Put this in Ursula's datastore this_node._work_orders.append(work_order) headers = {'Content-Type': 'application/octet-stream'} return Response(response=cfrag_byte_stream, headers=headers)
def reencrypt_via_rest(id_as_hex): # Get Policy Arrangement try: arrangement_id = binascii.unhexlify(id_as_hex) except (binascii.Error, TypeError): return Response(response=b'Invalid arrangement ID', status=405) try: with ThreadedSession(db_engine) as session: arrangement = datastore.get_policy_arrangement( arrangement_id=id_as_hex.encode(), session=session) except NotFound: return Response(response=arrangement_id, status=404) # Get KFrag # TODO: Yeah, well, what if this arrangement hasn't been enacted? 1702 kfrag = KFrag.from_bytes(arrangement.kfrag) # Get Work Order from nucypher.policy.collections import WorkOrder # Avoid circular import alice_verifying_key_bytes = arrangement.alice_verifying_key.key_data alice_verifying_key = UmbralPublicKey.from_bytes( alice_verifying_key_bytes) alice_address = canonical_address_from_umbral_key(alice_verifying_key) work_order_payload = request.data work_order = WorkOrder.from_rest_payload( arrangement_id=arrangement_id, rest_payload=work_order_payload, ursula=this_node, alice_address=alice_address) log.info( f"Work Order from {work_order.bob}, signed {work_order.receipt_signature}" ) # Re-encrypt response = this_node._reencrypt( kfrag=kfrag, work_order=work_order, alice_verifying_key=alice_verifying_key) # Now, Ursula saves this workorder to her database... with ThreadedSession(db_engine): this_node.datastore.save_workorder( bob_verifying_key=bytes(work_order.bob.stamp), bob_signature=bytes(work_order.receipt_signature), arrangement_id=work_order.arrangement_id) headers = {'Content-Type': 'application/octet-stream'} return Response(headers=headers, response=response)
def test_cfrags(): vector_file = os.path.join('vectors', 'vectors_cfrags.json') try: with open(vector_file) as f: vector_suite = json.load(f) except OSError: raise params = default_params() capsule = pre.Capsule.from_bytes(bytes.fromhex(vector_suite['capsule']), params=params) verifying_key = UmbralPublicKey.from_bytes( bytes.fromhex(vector_suite['verifying_key'])) delegating_key = UmbralPublicKey.from_bytes( bytes.fromhex(vector_suite['delegating_key'])) receiving_key = UmbralPublicKey.from_bytes( bytes.fromhex(vector_suite['receiving_key'])) kfrags_n_cfrags = [ (KFrag.from_bytes(bytes.fromhex(json_kfrag['kfrag'])), CapsuleFrag.from_bytes(bytes.fromhex(json_kfrag['cfrag']))) for json_kfrag in vector_suite['vectors'] ] capsule.set_correctness_keys(delegating=delegating_key, receiving=receiving_key, verifying=verifying_key) for kfrag, cfrag in kfrags_n_cfrags: assert kfrag.verify(signing_pubkey=verifying_key, delegating_pubkey=delegating_key, receiving_pubkey=receiving_key), \ 'Invalid KFrag {}'.format(kfrag.to_bytes().hex()) new_cfrag = pre.reencrypt(kfrag, capsule, provide_proof=False) assert new_cfrag.point_e1 == cfrag.point_e1 assert new_cfrag.point_v1 == cfrag.point_v1 assert new_cfrag.kfrag_id == cfrag.kfrag_id assert new_cfrag.point_precursor == cfrag.point_precursor assert new_cfrag.proof is None assert cfrag.to_bytes() == new_cfrag.to_bytes()
def reencrypt_data(alice_pub_key, bob_pub_key, alice_verify_key, capsule): kfrags_file = KFRAGS_FILE_FORMAT.format(bob_pub_key.to_bytes().hex()) try: with open(kfrags_file) as f: stored_kfrags = json.load(f) except FileNotFoundError as e: raise AccessError("Access Denied") kfrags = list() for kfrag_hex in stored_kfrags: kfrag = KFrag.from_bytes(bytes.fromhex(kfrag_hex)) kfrags.append(kfrag) capsule.set_correctness_keys(delegating=alice_pub_key, receiving=bob_pub_key, verifying=alice_verify_key) for kfrag in kfrags: cfrag = pre.reencrypt(kfrag=kfrag, capsule=capsule) capsule.attach_cfrag(cfrag)
def test_kfrags(): vector_file = os.path.join('vectors', 'vectors_kfrags.json') try: with open(vector_file) as f: vector_suite = json.load(f) except OSError: raise verifying_key = UmbralPublicKey.from_bytes( bytes.fromhex(vector_suite['verifying_key'])) delegating_key = UmbralPublicKey.from_bytes( bytes.fromhex(vector_suite['delegating_key'])) receiving_key = UmbralPublicKey.from_bytes( bytes.fromhex(vector_suite['receiving_key'])) for json_kfrag in vector_suite['vectors']: kfrag = KFrag.from_bytes(bytes.fromhex(json_kfrag['kfrag'])) assert kfrag.verify(signing_pubkey=verifying_key, delegating_pubkey=delegating_key, receiving_pubkey=receiving_key), \ 'Invalid KFrag {}'.format(kfrag.to_bytes().hex())
def test_federated_grant(federated_alice, federated_bob): # Setup the policy details m, n = 2, 3 policy_end_datetime = maya.now() + datetime.timedelta(days=5) label = b"this_is_the_path_to_which_access_is_being_granted" # Create the Policy, granting access to Bob policy = federated_alice.grant(federated_bob, label, m=m, n=n, expiration=policy_end_datetime) # Check the policy ID policy_id = keccak_digest(policy.label + bytes(policy.bob.stamp)) assert policy_id == policy.id # Check Alice's active policies assert policy_id in federated_alice.active_policies assert federated_alice.active_policies[policy_id] == policy # The number of accepted arrangements at least the number of Ursulas we're using (n) assert len(policy._accepted_arrangements) >= n # The number of actually enacted arrangements is exactly equal to n. assert len(policy._enacted_arrangements) == n # Let's look at the enacted arrangements. for kfrag in policy.kfrags: arrangement = policy._enacted_arrangements[kfrag] # Get the Arrangement from Ursula's datastore, looking up by the Arrangement ID. retrieved_policy = arrangement.ursula.datastore.get_policy_arrangement( arrangement.id.hex().encode()) retrieved_kfrag = KFrag.from_bytes(retrieved_policy.kfrag) assert kfrag == retrieved_kfrag
def test_kfrag_serialization(alices_keys, bobs_keys, kfrags): delegating_privkey, signing_privkey = alices_keys _receiving_privkey, receiving_pubkey = bobs_keys for kfrag in kfrags: kfrag_bytes = kfrag.to_bytes() assert len(kfrag_bytes) == KFrag.expected_bytes_length() new_kfrag = KFrag.from_bytes(kfrag_bytes) assert new_kfrag.id == kfrag.id assert new_kfrag.bn_key == kfrag.bn_key assert new_kfrag.point_precursor == kfrag.point_precursor assert new_kfrag.point_commitment == kfrag.point_commitment assert new_kfrag.keys_in_signature == kfrag.keys_in_signature assert new_kfrag.signature_for_proxy == kfrag.signature_for_proxy assert new_kfrag.signature_for_bob == kfrag.signature_for_bob assert new_kfrag.verify(signing_pubkey=signing_privkey.get_pubkey(), delegating_pubkey=delegating_privkey.get_pubkey(), receiving_pubkey=receiving_pubkey) assert new_kfrag == kfrag
def de_route(): if not request.json: abort(400) capsule_raw = request.json['capsule'] capsule = Capsule.from_bytes(bytes.fromhex(capsule_raw), params) alices_public_key = getUmbralPublicFromHex( request.json['alices_public_key']) alices_verifying_key = getUmbralPublicFromHex( request.json['alices_verifying_key']) # ? maybe without 03 ciphertext = bytes.fromhex(request.json['ciphertext']) bobs_private_key = getUmbralPrivateFromHex( request.json['bobs_private_key']) # kfrags serialized_kfrags = request.json['kfrags'] kfrags = [] for skfrag in serialized_kfrags: kfrags.append(KFrag.from_bytes(bytes.fromhex(skfrag))) responce = de(capsule, alices_public_key, alices_verifying_key, ciphertext, bobs_private_key, kfrags) print(responce) return responce, 200
def test_decentralized_grant(blockchain_alice, blockchain_bob, agency): # Setup the policy details n = 3 policy_end_datetime = maya.now() + datetime.timedelta(days=5) label = b"this_is_the_path_to_which_access_is_being_granted" # Create the Policy, Granting access to Bob policy = blockchain_alice.grant( bob=blockchain_bob, label=label, m=2, n=n, value=int(1e18), # one ether expiration=policy_end_datetime) # Check the policy ID policy_id = keccak_digest(policy.label + bytes(policy.bob.stamp)) assert policy_id == policy.id # The number of accepted arrangements at least the number of Ursulas we're using (n) assert len(policy._accepted_arrangements) >= n # The number of actually enacted arrangements is exactly equal to n. assert len(policy._enacted_arrangements) == n # Let's look at the enacted arrangements. for kfrag in policy.kfrags: arrangement = policy._enacted_arrangements[kfrag] # Get the Arrangement from Ursula's datastore, looking up by the Arrangement ID. retrieved_policy = arrangement.ursula.datastore.get_policy_arrangement( arrangement.id.hex().encode()) retrieved_kfrag = KFrag.from_bytes(retrieved_policy.kfrag) assert kfrag == retrieved_kfrag
def test_bob_can_issue_a_work_order_to_a_specific_ursula(enacted_federated_policy, federated_bob, federated_alice, federated_ursulas, capsule_side_channel): """ Now that Bob has his list of Ursulas, he can issue a WorkOrder to one. Upon receiving the WorkOrder, Ursula saves it and responds by re-encrypting and giving Bob a cFrag. This is a multipart test; it shows proper relations between the Characters Ursula and Bob and also proper interchange between a KFrag, Capsule, and CFrag object in the context of REST-driven proxy re-encryption. """ # We pick up our story with Bob already having followed the treasure map above, ie: hrac, treasure_map = enacted_federated_policy.hrac(), enacted_federated_policy.treasure_map map_id = treasure_map.public_id() federated_bob.treasure_maps[map_id] = treasure_map federated_bob.start_learning_loop() federated_bob.follow_treasure_map(map_id=map_id, block=True, timeout=1) assert len(federated_bob.known_nodes) == len(federated_ursulas) # Bob has no saved work orders yet, ever. assert len(federated_bob._saved_work_orders) == 0 # We'll test against just a single Ursula - here, we make a WorkOrder for just one. # We can pass any number of capsules as args; here we pass just one. capsule = capsule_side_channel[0].capsule capsule.set_correctness_keys(delegating=enacted_federated_policy.public_key, receiving=federated_bob.public_keys(DecryptingPower), verifying=federated_alice.stamp.as_umbral_pubkey()) work_orders = federated_bob.generate_work_orders(map_id, capsule, num_ursulas=1) # Again: one Ursula, one work_order. assert len(work_orders) == 1 # Bob saved the WorkOrder. assert len(federated_bob._saved_work_orders) == 1 # And the Ursula. assert len(federated_bob._saved_work_orders.ursulas) == 1 ursula_id, work_order = list(work_orders.items())[0] # The work order is not yet complete, of course. assert work_order.completed is False # **** RE-ENCRYPTION HAPPENS HERE! **** cfrags = federated_bob.get_reencrypted_cfrags(work_order) # We only gave one Capsule, so we only got one cFrag. assert len(cfrags) == 1 the_cfrag = cfrags[0] # ...and the work order is complete. assert work_order.completed # Attach the CFrag to the Capsule. capsule.attach_cfrag(the_cfrag) # Having received the cFrag, Bob also saved the WorkOrder as complete. assert len(federated_bob._saved_work_orders.by_ursula[ursula_id]) == 1 # OK, so cool - Bob has his cFrag! Let's make sure everything went properly. First, we'll show that it is in fact # the correct cFrag (ie, that Ursula performed re-encryption properly). for u in federated_ursulas: if u.rest_information()[0].port == work_order.ursula.rest_information()[0].port: ursula = u break else: raise RuntimeError("We've lost track of the Ursula that has the WorkOrder. Can't really proceed.") kfrag_bytes = ursula.datastore.get_policy_arrangement( work_order.arrangement_id.hex().encode()).kfrag the_kfrag = KFrag.from_bytes(kfrag_bytes) the_correct_cfrag = pre.reencrypt(the_kfrag, capsule) # The first CFRAG_LENGTH_WITHOUT_PROOF bytes (ie, the cfrag proper, not the proof material), are the same: assert bytes(the_cfrag)[:CapsuleFrag.expected_bytes_length()] == bytes( the_correct_cfrag)[:CapsuleFrag.expected_bytes_length()] # It's the correct cfrag! assert the_correct_cfrag.verify_correctness(capsule) # Now we'll show that Ursula saved the correct WorkOrder. work_orders_from_bob = ursula.work_orders(bob=federated_bob) assert len(work_orders_from_bob) == 1 assert work_orders_from_bob[0] == work_order
# file = open(os.getenv("CAPSULE"), 'rb') # The "rb" clause tells the open method to read the file as bytes # capsule_byte = file.read() # capsule = pre.Capsule.from_bytes(capsule_byte,params) public_key_byte= pickle.load(open(os.getenv("DELEGERPK"), 'rb')) public_key= keys.UmbralPublicKey.from_bytes(public_key_byte) verifying_key_byte= pickle.load(open(os.getenv("DELEGERVK"), 'rb')) verifying_key= keys.UmbralPublicKey.from_bytes(verifying_key_byte) Bob_public_key_byte= pickle.load(open(os.getenv("PK_PATH"), 'rb')) Bob_public_key= keys.UmbralPublicKey.from_bytes(Bob_public_key_byte) kfrags_byte= pickle.load(open('Ursulas/'+ os.getenv("FOR") +'/kfrag.cert', 'rb')) kfrags=[ KFrag.from_bytes(kfrag) for kfrag in kfrags_byte] kfrags_info= pickle.load(open('Ursulas/'+ os.getenv("FOR") +'/kfrags.info', 'rb')) kfrags = random.sample(kfrags, int(kfrags_info['N'])) correctness=capsule.set_correctness_keys(delegating=public_key,receiving=Bob_public_key,verifying=verifying_key) cfrags = list() if False in correctness: print ('Verification error') exit() else: for kfrag in kfrags: cfrag = pre.reencrypt(kfrag=kfrag, capsule=capsule ) cfrags.append(cfrag)
def reencrypt(): api = ipfsapi.connect('127.0.0.1', 5001) addrs = list() caddrs = list() res = {} if request.headers['Content-Type'] == 'application/json': account = request.json['account'] # 所有的传入参数都是hex key threshold = request.json['threshold'] capsulehex = request.json['capsule'] b_capsule = api.cat(capsulehex) capsule = Capsule.from_bytes(b_capsule, UmbralParameters(Curve(714))) addrs = request.json['addresses'] delegatinghex = request.json['delegating'] b_delegating = bytes.fromhex(delegatinghex) delegating = UmbralPublicKey.from_bytes(b_delegating) receivinghex = request.json['receiving'] b_receiving = bytes.fromhex(receivinghex) receiving = UmbralPublicKey.from_bytes(b_receiving) verifyinghex = request.json['verifying'] b_verifying = bytes.fromhex(verifyinghex) verifying = UmbralPublicKey.from_bytes(b_verifying) if threshold > len(addrs): return "Not enough addresses." capsule.set_correctness_keys(delegating=delegating, receiving=receiving, verifying=verifying) cfrags = list() # Receiver's cfrag collection # each kfrag is a rk segment for addr in addrs: rkseg = KFrag.from_bytes(api.cat(addr)) # cfrag = pre.reencrypt(kfrag=kfrag, capsule=capsule) cfrag = pre.reencrypt(kfrag=rkseg, capsule=capsule) cfrags.append(cfrag) # Receiver's collects a cfrag for cfrag in cfrags: caddrs.append(api.add_bytes(cfrag.to_bytes())) savedcap = capsule.to_bytes_all() # savedcap包括三块,basic为capsule,correctness为set的key,cfrag是append上去的东西,此时还为空 print(type(savedcap)) print(type(savedcap['basic'])) print(savedcap['correctness']) delegating_key = savedcap['correctness']['delegating'] receiving_key = savedcap['correctness']['receiving'] verifying_key = savedcap['correctness']['verifying'] b_delegating_key = delegating_key.to_bytes() b_receiving_key = receiving_key.to_bytes() b_verifying_key = verifying_key.to_bytes() print(b_delegating_key) print(b_receiving_key) print(b_verifying_key) sendbytes = savedcap[ 'basic'] + b'ZAtech' + b_delegating_key + b'ZBtech' + b_receiving_key + b'ZBtech' + b_verifying_key print(sendbytes) savedcapaddr = api.add_bytes(sendbytes) res = {"caddrs": caddrs, "capsule": savedcapaddr} return jsonify(res), {'Content-Type': 'application/json'} return
for kfrag_hex in kfrags: kfrag_hex = kfrag_hex.to_bytes().hex() kfrags_hex.append(kfrag_hex) # print("************************** random `kfrags_hex`") # print(kfrags_hex) # Bob collects the resulting `cfrags` from several Ursulas. # Bob must gather at least `threshold` `cfrags` in order to activate the capsule. bob_capsule.set_correctness_keys(delegating=alices_public_key, receiving=bobs_public_key, verifying=alices_verifying_key) cfrags = list() # Bob's cfrag collection cfrags_hex = list() for kfrag_h in kfrags_hex: kfrag_from_hex = KFrag.from_bytes(bytes.fromhex(kfrag_h)) cfrag = pre.reencrypt(kfrag=kfrag_from_hex, capsule=bob_capsule) cfrag_hex = cfrag.to_bytes().hex() cfrags_hex.append(cfrag_hex) cfrags.append(cfrag) # Bob collects a cfrag assert len(cfrags) == 10 # pprint("$$$$$$$$$$cfrags --------------------") ##pprint(cfrags_hex_from_file) # receive from server for cfrag in cfrags: # cfrags_from_hex = CapsuleFrag.from_bytes(bytes.fromhex(cfrag_hex_from_file)) ##pprint(cfrags_from_hex) bob_capsule.attach_cfrag(cfrag) #for cfrag in cfrags:
import base64 import sys from umbral import pre, keys from umbral.kfrags import KFrag from umbral.config import default_curve from umbral.params import UmbralParameters encoded_kfrags = sys.argv[1].split(',') for idx, row in enumerate(encoded_kfrags): encoded_kfrags[idx] = KFrag.from_bytes(base64.b64decode(row)) kfrags = tuple(encoded_kfrags) params = UmbralParameters(default_curve()) capsule = pre.Capsule.from_bytes(base64.b64decode(sys.argv[2]), params) ciphertext = base64.b64decode(sys.argv[3]) bobs_private_key = keys.UmbralPrivateKey.from_bytes( base64.b64decode(sys.argv[4])) bobs_public_key = keys.UmbralPublicKey.from_bytes(base64.b64decode( sys.argv[5])) alice_public_key = keys.UmbralPublicKey.from_bytes( base64.b64decode(sys.argv[6])) capsule.set_correctness_keys(alice_public_key, bobs_public_key, alice_public_key) for kfrag in kfrags: cfrag = pre.reencrypt(kfrag, capsule) capsule.attach_cfrag(cfrag) cleartext = pre.decrypt(ciphertext, capsule, bobs_private_key, alice_public_key)
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