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()))
示例#2
0
    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)
示例#3
0
def reencrypt(kfrag: KFrag,
              capsule: Capsule,
              provide_proof: bool = True,
              metadata: Optional[bytes] = None,
              verify_kfrag: bool = True) -> CapsuleFrag:

    if not isinstance(capsule, Capsule) or not capsule.verify():
        raise Capsule.NotValid

    if verify_kfrag:
        if not isinstance(kfrag,
                          KFrag) or not kfrag.verify_for_capsule(capsule):
            raise KFrag.NotValid

    rk = kfrag.bn_key
    e1 = rk * capsule.point_e  # type: Any
    v1 = rk * capsule.point_v  # type: Any

    cfrag = CapsuleFrag(point_e1=e1,
                        point_v1=v1,
                        kfrag_id=kfrag.id,
                        point_precursor=kfrag.point_precursor)

    if provide_proof:
        cfrag.prove_correctness(capsule, kfrag, metadata)

    return cfrag
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
示例#5
0
    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_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?
            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.
示例#6
0
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
示例#8
0
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
示例#9
0
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
示例#10
0
    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.
示例#11
0
    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)
示例#13
0
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
示例#14
0
    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()
示例#16
0
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())
示例#18
0
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
示例#20
0
# 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)       
示例#21
0
class KeyStore(object):
    """
    A storage class of cryptographic keys.
    """
    kfrag_splitter = BytestringSplitter(Signature,
                                        (KFrag, KFrag.expected_bytes_length()))

    def __init__(self, sqlalchemy_engine=None) -> None:
        """
        Initalizes a KeyStore object.

        :param sqlalchemy_engine: SQLAlchemy engine object to create session
        """
        self.engine = sqlalchemy_engine
        Session = sessionmaker(bind=sqlalchemy_engine)

        # This will probably be on the reactor thread for most production configs.
        # Best to treat like hot lava.
        self._session_on_init_thread = Session()

    def add_key(self, key, is_signing=True, session=None) -> Key:
        """
        :param key: Keypair object to store in the keystore.

        :return: The newly added key object.
        """
        session = session or self._session_on_init_thread
        fingerprint = fingerprint_from_key(key)
        key_data = bytes(key)
        new_key = Key(fingerprint, key_data, is_signing)

        session.add(new_key)
        session.commit()

        return new_key

    def get_key(
        self,
        fingerprint: bytes,
        session=None
    ) -> Union[keypairs.DecryptingKeypair, keypairs.SigningKeypair]:
        """
        Returns a key from the KeyStore.

        :param fingerprint: Fingerprint, in bytes, of key to return

        :return: Keypair of the returned key.
        """
        session = session or self._session_on_init_thread

        key = session.query(Key).filter_by(fingerprint=fingerprint).first()

        if not key:
            raise NotFound(
                "No key with fingerprint {} found.".format(fingerprint))

        pubkey = UmbralPublicKey.from_bytes(key.key_data)
        return pubkey

    def del_key(self, fingerprint: bytes, session=None):
        """
        Deletes a key from the KeyStore.

        :param fingerprint: Fingerprint of key to delete
        """
        session = session or self._session_on_init_thread

        session.query(Key).filter_by(fingerprint=fingerprint).delete()
        session.commit()

    def add_policy_arrangement(self,
                               expiration,
                               id,
                               kfrag=None,
                               alice_pubkey_sig=None,
                               alice_signature=None,
                               session=None) -> PolicyArrangement:
        """
        Creates a PolicyArrangement to the Keystore.

        :return: The newly added PolicyArrangement object
        """
        session = session or self._session_on_init_thread

        alice_key_instance = session.query(Key).filter_by(
            key_data=bytes(alice_pubkey_sig)).first()
        if not alice_key_instance:
            alice_key_instance = Key.from_umbral_key(alice_pubkey_sig,
                                                     is_signing=True)

        new_policy_arrangement = PolicyArrangement(
            expiration,
            id,
            kfrag,
            alice_pubkey_sig=alice_key_instance,
            alice_signature=None,  # bob_pubkey_sig.id
        )

        session.add(new_policy_arrangement)
        session.commit()

        return new_policy_arrangement

    def get_policy_arrangement(self,
                               arrangement_id: bytes,
                               session=None) -> PolicyArrangement:
        """
        Returns the PolicyArrangement by its HRAC.

        :return: The PolicyArrangement object
        """
        session = session or self._session_on_init_thread

        policy_arrangement = session.query(PolicyArrangement).filter_by(
            id=arrangement_id).first()

        if not policy_arrangement:
            raise NotFound(
                "No PolicyArrangement {} found.".format(arrangement_id))
        return policy_arrangement

    def del_policy_arrangement(self, arrangement_id: bytes, session=None):
        """
        Deletes a PolicyArrangement from the Keystore.
        """
        session = session or self._session_on_init_thread

        session.query(PolicyArrangement).filter_by(id=arrangement_id).delete()
        session.commit()

    def attach_kfrag_to_saved_arrangement(self,
                                          alice,
                                          id_as_hex,
                                          kfrag,
                                          session=None):
        session = session or self._session_on_init_thread

        policy_arrangement = session.query(PolicyArrangement).filter_by(
            id=id_as_hex.encode()).first()

        if policy_arrangement is None:
            raise NotFound(
                "Can't attach a kfrag to non-existent Arrangement {}".format(
                    id_as_hex))

        if policy_arrangement.alice_pubkey_sig.key_data != alice.stamp:
            raise alice.SuspiciousActivity

        policy_arrangement.kfrag = bytes(kfrag)
        session.commit()

    def add_workorder(self,
                      bob_pubkey_sig,
                      bob_signature,
                      arrangement_id,
                      session=None) -> Workorder:
        """
        Adds a Workorder to the keystore.
        """
        session = session or self._session_on_init_thread
        bob_pubkey_sig = self.add_key(bob_pubkey_sig)
        new_workorder = Workorder(bob_pubkey_sig.id, bob_signature,
                                  arrangement_id)

        session.add(new_workorder)
        session.commit()

        return new_workorder

    def get_workorders(self, arrangement_id: bytes, session=None) -> Workorder:
        """
        Returns a list of Workorders by HRAC.
        """
        session = session or self._session_on_init_thread

        workorders = session.query(Workorder).filter_by(
            arrangement_id=arrangement_id)

        if not workorders:
            raise NotFound(
                "No Workorders with {} HRAC found.".format(arrangement_id))
        return workorders

    def del_workorders(self, arrangement_id: bytes, session=None):
        """
        Deletes a Workorder from the Keystore.
        """
        session = session or self._session_on_init_thread

        workorders = session.query(Workorder).filter_by(
            arrangement_id=arrangement_id)
        deleted = workorders.delete()
        session.commit()

        return deleted
示例#22
0
class Datastore:
    """
    A storage class of persistent cryptographic entities for use by Ursula.
    """
    kfrag_splitter = BytestringSplitter(Signature,
                                        (KFrag, KFrag.expected_bytes_length()))

    def __init__(self, sqlalchemy_engine=None) -> None:
        """
        Initializes a Datastore object.

        :param sqlalchemy_engine: SQLAlchemy engine object to create session
        """
        self.engine = sqlalchemy_engine
        Session = sessionmaker(bind=sqlalchemy_engine)

        # This will probably be on the reactor thread for most production configs.
        # Best to treat like hot lava.
        self._session_on_init_thread = Session()

    @staticmethod
    def __commit(session) -> None:
        try:
            session.commit()
        except OperationalError:
            session.rollback()
            raise

    #
    # Keys
    #

    def add_key(self,
                key: UmbralPublicKey,
                is_signing: bool = True,
                session=None) -> Key:
        """
        :param key: Keypair object to store in the keystore.

        :return: The newly added key object.
        """
        session = session or self._session_on_init_thread
        fingerprint = fingerprint_from_key(key)
        key_data = bytes(key)
        new_key = Key(fingerprint, key_data, is_signing)

        session.add(new_key)
        self.__commit(session=session)
        return new_key

    def get_key(self, fingerprint: bytes, session=None) -> UmbralPublicKey:
        """
        Returns a key from the Datastore.

        :param fingerprint: Fingerprint, in bytes, of key to return

        :return: Keypair of the returned key.
        """
        session = session or self._session_on_init_thread

        key = session.query(Key).filter_by(fingerprint=fingerprint).first()
        if not key:
            raise NotFound(
                "No key with fingerprint {} found.".format(fingerprint))

        pubkey = UmbralPublicKey.from_bytes(key.key_data)
        return pubkey

    def del_key(self, fingerprint: bytes, session=None):
        """
        Deletes a key from the Datastore.

        :param fingerprint: Fingerprint of key to delete
        """
        session = session or self._session_on_init_thread

        session.query(Key).filter_by(fingerprint=fingerprint).delete()
        self.__commit(session=session)

    #
    # Arrangements
    #

    def add_policy_arrangement(
            self,
            expiration: maya.MayaDT,
            arrangement_id: bytes,
            kfrag: KFrag = None,
            alice_verifying_key: UmbralPublicKey = None,
            alice_signature: Signature = None,  # TODO: Why is this unused?
            session=None) -> PolicyArrangement:
        """
        Creates a PolicyArrangement to the Keystore.

        :return: The newly added PolicyArrangement object
        """
        session = session or self._session_on_init_thread

        alice_key_instance = session.query(Key).filter_by(
            key_data=bytes(alice_verifying_key)).first()
        if not alice_key_instance:
            alice_key_instance = Key.from_umbral_key(alice_verifying_key,
                                                     is_signing=True)

        new_policy_arrangement = PolicyArrangement(
            expiration=expiration,
            id=arrangement_id,
            kfrag=kfrag,
            alice_verifying_key=alice_key_instance,
            alice_signature=None,
            # bob_verifying_key.id  # TODO: Is this needed?
        )

        session.add(new_policy_arrangement)
        self.__commit(session=session)
        return new_policy_arrangement

    def get_policy_arrangement(self,
                               arrangement_id: bytes,
                               session=None) -> PolicyArrangement:
        """
        Retrieves a PolicyArrangement by its HRAC.

        :return: The PolicyArrangement object
        """
        session = session or self._session_on_init_thread
        policy_arrangement = session.query(PolicyArrangement).filter_by(
            id=arrangement_id).first()
        if not policy_arrangement:
            raise NotFound(
                "No PolicyArrangement {} found.".format(arrangement_id))
        return policy_arrangement

    def get_all_policy_arrangements(self,
                                    session=None) -> List[PolicyArrangement]:
        """
        Returns all the PolicyArrangements

        :return: The list of PolicyArrangement objects
        """
        session = session or self._session_on_init_thread
        arrangements = session.query(PolicyArrangement).all()
        return arrangements

    def attach_kfrag_to_saved_arrangement(self,
                                          alice,
                                          id_as_hex,
                                          kfrag,
                                          session=None):
        session = session or self._session_on_init_thread
        policy_arrangement = session.query(PolicyArrangement).filter_by(
            id=id_as_hex.encode()).first()

        if policy_arrangement is None:
            raise NotFound(
                "Can't attach a kfrag to non-existent Arrangement {}".format(
                    id_as_hex))

        if policy_arrangement.alice_verifying_key.key_data != alice.stamp:
            raise alice.SuspiciousActivity

        policy_arrangement.kfrag = bytes(kfrag)
        self.__commit(session=session)

    def del_policy_arrangement(self,
                               arrangement_id: bytes,
                               session=None) -> int:
        """
        Deletes a PolicyArrangement from the Keystore.
        """
        session = session or self._session_on_init_thread
        deleted_records = session.query(PolicyArrangement).filter_by(
            id=arrangement_id).delete()

        self.__commit(session=session)
        return deleted_records

    def del_expired_policy_arrangements(self, session=None, now=None) -> int:
        """
        Deletes all expired PolicyArrangements from the Keystore.
        """
        session = session or self._session_on_init_thread
        now = now or datetime.now()
        result = session.query(PolicyArrangement).filter(
            PolicyArrangement.expiration <= now)

        deleted_records = 0
        if result.count() > 0:
            deleted_records = result.delete()
        self.__commit(session=session)
        return deleted_records

    #
    # Work Orders
    #

    def save_workorder(self,
                       bob_verifying_key: UmbralPublicKey,
                       bob_signature: Signature,
                       arrangement_id: bytes,
                       session=None) -> Workorder:
        """
        Adds a Workorder to the keystore.
        """
        session = session or self._session_on_init_thread

        # Get or Create Bob Verifying Key
        fingerprint = fingerprint_from_key(bob_verifying_key)
        key = session.query(Key).filter_by(fingerprint=fingerprint).first()
        if not key:
            key = self.add_key(key=bob_verifying_key)

        new_workorder = Workorder(bob_verifying_key_id=key.id,
                                  bob_signature=bob_signature,
                                  arrangement_id=arrangement_id)

        session.add(new_workorder)
        self.__commit(session=session)
        return new_workorder

    def get_workorders(self,
                       arrangement_id: bytes = None,
                       bob_verifying_key: bytes = None,
                       session=None) -> List[Workorder]:
        """
        Returns a list of Workorders by HRAC.
        """
        session = session or self._session_on_init_thread
        query = session.query(Workorder)

        if not arrangement_id and not bob_verifying_key:
            workorders = query.all()  # Return all records

        else:

            # Return arrangement records
            if arrangement_id:
                workorders = query.filter_by(arrangement_id=arrangement_id)

            # Return records for Bob
            else:
                fingerprint = fingerprint_from_key(bob_verifying_key)
                key = session.query(Key).filter_by(
                    fingerprint=fingerprint).first()
                workorders = query.filter_by(bob_verifying_key_id=key.id)

            if not workorders:
                raise NotFound

        return list(workorders)

    def del_workorders(self, arrangement_id: bytes, session=None) -> int:
        """
        Deletes a Workorder from the Keystore.
        """
        session = session or self._session_on_init_thread

        workorders = session.query(Workorder).filter_by(
            arrangement_id=arrangement_id)
        deleted = workorders.delete()
        self.__commit(session=session)
        return deleted
示例#23
0
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
示例#24
0
# kfrags_dict = {}
# kfrags_dict["kfrags"] = [ KFrag.to_bytes(kfrag)  for kfrag in kfrags]
# kfrags_dict["FOR"]= os.getenv("FOR")
# kfrags_dict["THRESHOLD"]= os.getenv("THRESHOLD")
# kfrags_dict["N"]= os.getenv("N")

kfrags_info = {}
kfrags_info["FOR"] = os.getenv("FOR")
kfrags_info["THRESHOLD"] = os.getenv("THRESHOLD")
kfrags_info["N"] = os.getenv("N")

outfile = open('Ursulas/' + os.getenv("FOR") + '/kfrags.info', 'wb')
pickle.dump(kfrags_info, outfile)
outfile.close()

kfrags = [KFrag.to_bytes(kfrag) for kfrag in kfrags]
outfile = open('Ursulas/' + os.getenv("FOR") + '/kfrag.cert', 'wb')
pickle.dump(kfrags, outfile)
outfile.close()

# s=json.dumps(variables)
# variables2=json.loads(s)
# assert(variables==variables2)

# outfile.write(str(kfrags))
# outfile.close()

# outfile = open('Ursulas/'+ os.getenv("FOR") +'/kfrag.cert','wb')
# kfrags_dict = {}
# kfrags_dict[os.getenv("FOR")] = kfrags
# # pickle.dump(kfrags_dict,outfile)
示例#25
0
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)
示例#26
0
def generate_kfrags(
    delegating_privkey: UmbralPrivateKey,
    receiving_pubkey: UmbralPublicKey,
    threshold: int,
    N: int,
    signer: Signer,
    sign_delegating_key: Optional[bool] = True,
    sign_receiving_key: Optional[bool] = True,
) -> List[KFrag]:
    """
    Creates a re-encryption key from Alice's delegating public key to Bob's
    receiving public key, and splits it in KFrags, using Shamir's Secret Sharing.
    Requires a threshold number of KFrags out of N.

    Returns a list of N KFrags
    """

    if threshold <= 0 or threshold > N:
        raise ValueError(
            'Arguments threshold and N must satisfy 0 < threshold <= N')

    if delegating_privkey.params != receiving_pubkey.params:
        raise ValueError("Keys must have the same parameter set.")

    params = delegating_privkey.params

    g = params.g

    delegating_pubkey = delegating_privkey.get_pubkey()

    bob_pubkey_point = receiving_pubkey.point_key

    # The precursor point is used as an ephemeral public key in a DH key exchange,
    # and the resulting shared secret 'dh_point' is used to derive other secret values
    private_precursor = CurveBN.gen_rand(params.curve)
    precursor = private_precursor * g  # type: Any

    dh_point = private_precursor * bob_pubkey_point

    # Secret value 'd' allows to make Umbral non-interactive
    d = hash_to_curvebn(precursor,
                        bob_pubkey_point,
                        dh_point,
                        bytes(constants.NON_INTERACTIVE),
                        params=params)

    # Coefficients of the generating polynomial
    coefficients = [delegating_privkey.bn_key * (~d)]
    coefficients += [
        CurveBN.gen_rand(params.curve) for _ in range(threshold - 1)
    ]

    bn_size = CurveBN.expected_bytes_length(params.curve)

    kfrags = list()
    for _ in range(N):
        kfrag_id = os.urandom(bn_size)

        # The index of the re-encryption key share (which in Shamir's Secret
        # Sharing corresponds to x in the tuple (x, f(x)), with f being the
        # generating polynomial), is used to prevent reconstruction of the
        # re-encryption key without Bob's intervention
        share_index = hash_to_curvebn(precursor,
                                      bob_pubkey_point,
                                      dh_point,
                                      bytes(constants.X_COORDINATE),
                                      kfrag_id,
                                      params=params)

        # The re-encryption key share is the result of evaluating the generating
        # polynomial for the index value
        rk = poly_eval(coefficients, share_index)

        commitment = rk * params.u  # type: Any

        validity_message_for_bob = (
            kfrag_id,
            delegating_pubkey,
            receiving_pubkey,
            commitment,
            precursor,
        )  # type: Any
        validity_message_for_bob = bytes().join(
            bytes(item) for item in validity_message_for_bob)
        signature_for_bob = signer(validity_message_for_bob)

        if sign_delegating_key and sign_receiving_key:
            mode = DELEGATING_AND_RECEIVING
        elif sign_delegating_key:
            mode = DELEGATING_ONLY
        elif sign_receiving_key:
            mode = RECEIVING_ONLY
        else:
            mode = NO_KEY

        validity_message_for_proxy = [kfrag_id, commitment, precursor,
                                      mode]  # type: Any

        if sign_delegating_key:
            validity_message_for_proxy.append(delegating_pubkey)
        if sign_receiving_key:
            validity_message_for_proxy.append(receiving_pubkey)

        validity_message_for_proxy = bytes().join(
            bytes(item) for item in validity_message_for_proxy)
        signature_for_proxy = signer(validity_message_for_proxy)

        kfrag = KFrag(
            identifier=kfrag_id,
            bn_key=rk,
            point_commitment=commitment,
            point_precursor=precursor,
            signature_for_proxy=signature_for_proxy,
            signature_for_bob=signature_for_bob,
            keys_in_signature=mode,
        )

        kfrags.append(kfrag)

    return kfrags
示例#27
0
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
示例#28
0
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:
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