Beispiel #1
0
    def record_fleet_state(self, additional_nodes_to_track=None):
        if additional_nodes_to_track:
            self.additional_nodes_to_track.extend(additional_nodes_to_track)
        if not self._nodes:
            # No news here.
            return
        sorted_nodes = self.sorted()

        sorted_nodes_joined = b"".join(bytes(n) for n in sorted_nodes)
        checksum = keccak_digest(sorted_nodes_joined).hex()
        if checksum not in self.states:
            self.checksum = keccak_digest(b"".join(
                bytes(n) for n in self.sorted())).hex()
            self.updated = maya.now()
            # For now we store the sorted node list.  Someday we probably spin this out into
            # its own class, FleetState, and use it as the basis for partial updates.
            new_state = self.state_template(
                nickname=self.nickname,
                metadata=self.nickname_metadata,
                nodes=sorted_nodes,
                icon=self.icon,
                updated=self.updated,
            )
            self.states[checksum] = new_state
            return checksum, new_state
Beispiel #2
0
    def test_keccak_digest(self):
        data = b'this is a test'

        digest1 = sha3.keccak_256(data).digest()
        digest2 = api.keccak_digest(data)

        self.assertEqual(digest1, digest2)

        # Test iterables
        data = data.split()

        digest1 = sha3.keccak_256(b''.join(data)).digest()
        digest2 = api.keccak_digest(*data)

        self.assertEqual(digest1, digest2)
Beispiel #3
0
def test_upgrade_user_escrow_proxy(session_testerchain, session_agency,
                                   user_escrow_proxy_deployer):
    testerchain = session_testerchain
    agency = session_agency
    old_secret = USER_ESCROW_PROXY_DEPLOYMENT_SECRET.encode()
    new_secret = 'new' + USER_ESCROW_PROXY_DEPLOYMENT_SECRET
    new_secret_hash = keccak_digest(new_secret.encode())

    linker_deployer = LibraryLinkerDeployer(
        blockchain=testerchain,
        deployer_address=user_escrow_proxy_deployer.deployer_address,
        target_contract=user_escrow_proxy_deployer.contract,
        bare=True)
    linker_address = linker_deployer.contract_address

    target = linker_deployer.contract.functions.target().call()
    assert target == UserEscrowProxyDeployer.get_latest_version(
        blockchain=testerchain).address

    receipts = user_escrow_proxy_deployer.upgrade(
        existing_secret_plaintext=old_secret, new_secret_hash=new_secret_hash)

    assert len(receipts) == 2

    for title, receipt in receipts.items():
        assert receipt['status'] == 1

    for user_escrow_contract in user_escrow_contracts:
        linker = user_escrow_contract.functions.linker().call()
        assert linker == linker_address

    new_target = linker_deployer.contract.functions.target().call()
    assert new_target == UserEscrowProxyDeployer.get_latest_version(
        blockchain=testerchain).address
    assert new_target != target
Beispiel #4
0
def test_grant(alice, bob, nucypher_test_config):
    policy_end_datetime = maya.now() + datetime.timedelta(days=5)
    n = 5
    uri = b"this_is_the_path_to_which_access_is_being_granted"
    policy = alice.grant(bob, uri, m=3, n=n, expiration=policy_end_datetime)

    # The number of policies is equal to the number of Ursulas we're using (n)
    assert len(policy._accepted_arrangements) == n

    # Let's look at the first Ursula.
    ursula = list(policy._accepted_arrangements.values())[0].ursula

    # Get the Policy from Ursula's datastore, looking up by hrac.
    proper_hrac = keccak_digest(bytes(alice.stamp) + bytes(bob.stamp) + uri)
    retrieved_policy = ursula.datastore.get_policy_arrangement(
        proper_hrac.hex().encode())

    # TODO: Make this a legit KFrag, not bytes.
    retrieved_k_frag = KFrag.from_bytes(retrieved_policy.k_frag)

    # TODO: Implement KFrag.__eq__
    found = False
    for k_frag in policy.kfrags:
        if bytes(k_frag) == bytes(retrieved_k_frag):
            found = True
    assert found
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
Beispiel #6
0
    def receive_treasure_map(treasure_map_id):
        from nucypher.policy.models import TreasureMap

        try:
            treasure_map = TreasureMap.from_bytes(
                bytes_representation=request.data, verify=True)
        except TreasureMap.InvalidSignature:
            do_store = False
        else:
            do_store = treasure_map.public_id() == treasure_map_id

        if do_store:
            log.info("{} storing TreasureMap {}".format(
                stamp, treasure_map_id))

            # # # #
            # TODO: Now that the DHT is retired, let's do this another way.
            # self.dht_server.set_now(binascii.unhexlify(treasure_map_id),
            #                         constants.BYTESTRING_IS_TREASURE_MAP + bytes(treasure_map))
            # # # #

            # TODO 341 - what if we already have this TreasureMap?
            treasure_map_tracker[keccak_digest(
                binascii.unhexlify(treasure_map_id))] = treasure_map
            return Response(bytes(treasure_map), status=202)
        else:
            # TODO: Make this a proper 500 or whatever.
            log.info(
                "Bad TreasureMap ID; not storing {}".format(treasure_map_id))
            assert False
Beispiel #7
0
    def prepare_for_publication(self,
                                bob_encrypting_key,
                                bob_verifying_key,
                                alice_stamp,
                                label):

        plaintext = self._m.to_bytes(1, "big") + self.nodes_as_bytes()

        self.message_kit, _signature_for_bob = encrypt_and_sign(bob_encrypting_key,
                                                                plaintext=plaintext,
                                                                signer=alice_stamp,
                                                                )
        """
        Here's our "hashed resource access code".

        A hash of:
        * Alice's public key
        * Bob's public key
        * the label

        Alice and Bob have all the information they need to construct this.
        Ursula does not, so we share it with her.

        This way, Bob can generate it and use it to find the TreasureMap.
        """
        self._hrac = keccak_digest(bytes(alice_stamp) + bytes(bob_verifying_key) + label)
        self._public_signature = alice_stamp(bytes(alice_stamp) + self._hrac)
        self._set_payload()
Beispiel #8
0
 def learn_about_nodes(self, address, port):
     """
     Sends a request to node_url to find out about known nodes.
     """
     response = self.network_middleware.get_nodes_via_rest(address, port)
     signature, nodes = signature_splitter(response.content,
                                           return_remainder=True)
     # TODO: Although not treasure map-related, this has a whiff of #172.
     ursula_interface_splitter = dht_value_splitter + BytestringSplitter(
         (bytes, 17))
     split_nodes = ursula_interface_splitter.repeat(nodes)
     new_nodes = {}
     for node_meta in split_nodes:
         header, sig, pubkey, interface_info = node_meta
         if not pubkey in self.known_nodes:
             if sig.verify(keccak_digest(interface_info), pubkey):
                 address, dht_port, rest_port = msgpack.loads(
                     interface_info)
                 new_nodes[pubkey] = \
                     Ursula.as_discovered_on_network(
                         rest_port=rest_port,
                         dht_port=dht_port,
                         ip_address=address.decode("utf-8"),
                         powers_and_keys=({SigningPower: pubkey})
                     )
             else:
                 message = "Suspicious Activity: Discovered node with bad signature: {}.  Propagated by: {}:{}".format(
                     node_meta, address, port)
                 self.log.warn(message)
     return new_nodes
Beispiel #9
0
    def construct_by_bob(cls, arrangement_id, alice_verifying, capsules,
                         ursula, bob):
        ursula.mature()
        alice_address = canonical_address_from_umbral_key(alice_verifying)

        # TODO: Bob's input to prove freshness for this work order
        blockhash = b'\x00' * 32

        ursula_identity_evidence = b''
        if ursula._stamp_has_valid_signature_by_worker():
            ursula_identity_evidence = ursula.decentralized_identity_evidence

        tasks = OrderedDict()
        for capsule in capsules:
            task = cls.PRETask(capsule, signature=None)
            specification = task.get_specification(ursula.stamp, alice_address,
                                                   blockhash,
                                                   ursula_identity_evidence)
            task.signature = bob.stamp(specification)
            tasks[capsule] = task

        # TODO: What's the goal of the receipt? Should it include only the capsules?
        receipt_bytes = b"wo:" + bytes(ursula.stamp) + keccak_digest(
            *[bytes(task.capsule) for task in tasks.values()])
        receipt_signature = bob.stamp(receipt_bytes)

        return cls(bob=bob,
                   arrangement_id=arrangement_id,
                   tasks=tasks,
                   receipt_signature=receipt_signature,
                   alice_address=alice_address,
                   ursula=ursula,
                   blockhash=blockhash)
Beispiel #10
0
 def public_id(self):
     """
     We need an ID that Bob can glean from knowledge he already has *and* which Ursula can verify came from Alice.
     Ursula will refuse to propagate this if it she can't prove the payload is signed by Alice's public key,
     which is included in it,
     """
     return keccak_digest(bytes(self._verifying_key) + bytes(self._hrac)).hex()
def test_manual_proxy_retargeting(testerchain, test_registry, token_economics):

    deployer = StakingEscrowDeployer(
        registry=test_registry,
        deployer_address=testerchain.etherbase_account,
        economics=token_economics)

    # Get Proxy-Direct
    proxy_deployer = deployer.get_proxy_deployer(
        registry=test_registry, provider_uri=TEST_PROVIDER_URI)

    # Re-Deploy Staking Escrow
    old_target = proxy_deployer.target_contract.address

    old_secret = bytes("...maybe not.", encoding='utf-8')
    new_secret = keccak_digest(bytes('thistimeforsure', encoding='utf-8'))

    # Get the latest un-targeted contract from the registry
    latest_deployment = deployer.get_latest_enrollment(registry=test_registry)
    receipt = deployer.retarget(target_address=latest_deployment.address,
                                existing_secret_plaintext=old_secret,
                                new_secret_hash=new_secret)

    assert receipt['status'] == 1

    # Check proxy targets
    new_target = proxy_deployer.contract.functions.target().call()
    assert old_target != new_target
    assert new_target == latest_deployment.address

    # Check address consistency
    new_bare_contract = deployer.get_principal_contract(
        registry=test_registry, provider_uri=TEST_PROVIDER_URI)
    assert new_bare_contract.address == latest_deployment.address == new_target
Beispiel #12
0
    def fingerprint(self):
        """
        Hashes the key using keccak-256 and returns the hexdigest in bytes.

        :return: Hexdigest fingerprint of key (keccak-256) in bytes
        """
        return keccak_digest(bytes(self)).hex().encode()
Beispiel #13
0
def test_decentralized_grant(blockchain_alice, blockchain_bob,
                             blockchain_ursulas):
    # Setup the policy details
    n = 3
    policy_end_datetime = maya.now() + datetime.timedelta(days=35)
    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(label + bytes(blockchain_bob.stamp))
    assert policy_id == policy.id

    # The number of actually enacted arrangements is exactly equal to n.
    assert len(policy.treasure_map.destinations) == n

    # Let's look at the enacted arrangements.
    for ursula in blockchain_ursulas:
        if ursula.checksum_address in policy.treasure_map.destinations:
            arrangement_id = policy.treasure_map.destinations[
                ursula.checksum_address]

            # Get the Arrangement from Ursula's datastore, looking up by the Arrangement ID.
            with ursula.datastore.describe(
                    PolicyArrangement,
                    arrangement_id.hex()) as policy_arrangement:
                retrieved_kfrag = policy_arrangement.kfrag
            assert bool(retrieved_kfrag)  # TODO: try to assemble them back?
Beispiel #14
0
def test_grant(alice, bob, three_agents):
    # Monkey patch KFrag repr for better debugging.
    KFrag.__repr__ = lambda kfrag: "KFrag: {}".format(bytes(kfrag)[:10].hex())

    policy_end_datetime = maya.now() + datetime.timedelta(days=5)
    n = 3
    label = b"this_is_the_path_to_which_access_is_being_granted"
    _token_agent, _miner_agent, policy_agent = three_agents

    policy_agent.blockchain.wait_for_receipt = MockPolicyCreation.wait_for_receipt
    policy_agent.contract.functions.createPolicy = MockPolicyCreation

    policy = alice.grant(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]
        ursula = _TEST_KNOWN_URSULAS_CACHE[
            arrangement.ursula.rest_interface.port]

        # 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(alice.stamp) + bytes(bob.stamp) + label)
        retrieved_policy = ursula.datastore.get_policy_arrangement(
            arrangement.id.hex().encode())
        retrieved_kfrag = KFrag.from_bytes(retrieved_policy.k_frag)

        assert kfrag == retrieved_kfrag
Beispiel #15
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
Beispiel #16
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, Grating 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 hrac.
        # This will be changed in 180, when we use the Arrangement ID.
        proper_hrac = keccak_digest(bytes(blockchain_alice.stamp) + bytes(blockchain_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_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
Beispiel #18
0
    def retrieve(self, message_kit, data_source, alice_pubkey_sig):
        hrac = keccak_digest(
            bytes(alice_pubkey_sig) + self.stamp + data_source.label)
        treasure_map = self.treasure_maps[hrac]

        # First, a quick sanity check to make sure we know about at least m nodes.
        known_nodes_as_bytes = set([bytes(n) for n in self.known_nodes.keys()])
        intersection = treasure_map.ids.intersection(known_nodes_as_bytes)

        if len(intersection) < treasure_map.m:
            raise RuntimeError(
                "Not enough known nodes.  Try following the TreasureMap again."
            )

        work_orders = self.generate_work_orders(hrac, message_kit.capsule)
        for node_id in self.treasure_maps[hrac]:
            node = self.known_nodes[UmbralPublicKey.from_bytes(node_id)]
            cfrags = self.get_reencrypted_c_frags(work_orders[bytes(
                node.stamp)])
            message_kit.capsule.attach_cfrag(cfrags[0])
        verified, delivered_cleartext = self.verify_from(data_source,
                                                         message_kit,
                                                         decrypt=True)

        if verified:
            return delivered_cleartext
        else:
            raise RuntimeError(
                "Not verified - replace this with real message.")
Beispiel #19
0
def test_alice_creates_policy_with_correct_hrac(federated_alice, federated_bob,
                                                idle_federated_policy):
    """
    Alice creates a Policy.  It has the proper HRAC, unique per her, Bob, and the label
    """
    assert idle_federated_policy.hrac == keccak_digest(
        bytes(federated_alice.stamp) + bytes(federated_bob.stamp) +
        idle_federated_policy.label)[:16]
Beispiel #20
0
 def new(cls, this_node: Optional['Ursula'] = None) -> 'FleetState':
     this_node_ref = weakref.ref(this_node) if this_node is not None else None
     # Using empty checksum so that JSON library is not confused.
     # Plus, we do need some checksum anyway. It's a legitimate state after all.
     return cls(checksum=keccak_digest(b"").hex(),
                nodes={},
                this_node_ref=this_node_ref,
                this_node_metadata=None)
Beispiel #21
0
def test_alice_creates_policy_with_correct_hrac(idle_federated_policy):
    """
    Alice creates a Policy.  It has the proper HRAC, unique per her, Bob, and the uri (resource_id).
    """
    alice = idle_federated_policy.alice
    bob = idle_federated_policy.bob

    assert idle_federated_policy.hrac() == keccak_digest(
        bytes(alice.stamp) + bytes(bob.stamp) + idle_federated_policy.label)
Beispiel #22
0
def test_alice_sets_treasure_map(enacted_federated_policy, federated_ursulas):
    """
    Having enacted all the policies of a PolicyGroup, Alice creates a TreasureMap and ...... TODO
    """

    enacted_federated_policy.publish_treasure_map(network_middleware=MockRestMiddleware())

    treasure_map_as_set_on_network = list(federated_ursulas)[0].treasure_maps[
        keccak_digest(unhexlify(enacted_federated_policy.treasure_map.public_id()))]
    assert treasure_map_as_set_on_network == enacted_federated_policy.treasure_map
Beispiel #23
0
 def public_id(self) -> str:
     """
     We need an ID that Bob can glean from knowledge he already has *and* which Ursula can verify came from Alice.
     Ursula will refuse to propagate this if it she can't prove the payload is signed by Alice's public key,
     which is included in it,
     """
     # TODO: No reason to keccak this over and over again.  Turn into set-once property pattern.
     _id = keccak_digest(bytes(self._verifying_key) +
                         bytes(self._hrac)).hex()
     return _id
Beispiel #24
0
def test_address(testerchain, signature_verifier):
    # Generate Umbral key and extract "address" from the public key
    umbral_privkey = UmbralPrivateKey.gen_key()
    umbral_pubkey = umbral_privkey.get_pubkey()
    umbral_pubkey_bytes = umbral_pubkey.to_bytes(is_compressed=False)[1:]
    signer_address = keccak_digest(umbral_pubkey_bytes)
    signer_address = to_normalized_address(signer_address[12:])

    # Check extracting address in library
    result_address = signature_verifier.functions.toAddress(umbral_pubkey_bytes).call()
    assert signer_address == to_normalized_address(result_address)
Beispiel #25
0
def test_treasure_map_stored_by_ursula_is_the_correct_one_for_bob(federated_alice, federated_bob, federated_ursulas, enacted_federated_policy):
    """
    The TreasureMap given by Alice to Ursula is the correct one for Bob; he can decrypt and read it.
    """
    treasure_map_as_set_on_network = list(federated_ursulas)[0].treasure_maps[
        keccak_digest(unhexlify(enacted_federated_policy.treasure_map.public_id()))]

    hrac_by_bob = federated_bob.construct_policy_hrac(federated_alice.stamp, enacted_federated_policy.label)
    assert enacted_federated_policy.hrac() == hrac_by_bob

    hrac, map_id_by_bob = federated_bob.construct_hrac_and_map_id(federated_alice.stamp, enacted_federated_policy.label)
    assert map_id_by_bob == treasure_map_as_set_on_network.public_id()
Beispiel #26
0
    def with_updated_nodes(
        self,
        nodes_to_add: Iterable['Ursula'],
        nodes_to_remove: Iterable[ChecksumAddress],
        skip_this_node: bool = False,
    ) -> 'FleetState':

        if self._this_node_ref is not None and not skip_this_node:
            this_node = self._this_node_ref()
            this_node_metadata = bytes(this_node)
            this_node_updated = self._this_node_metadata != this_node_metadata
            this_node_list = [this_node]
        else:
            this_node_metadata = self._this_node_metadata
            this_node_updated = False
            this_node_list = []

        diff = self._calculate_diff(this_node_updated, nodes_to_add,
                                    nodes_to_remove)

        if not diff.empty():
            # TODO: if nodes were kept in a Merkle tree,
            # we'd have to only recalculate log(N) checksums.
            # Is it worth it?
            nodes = dict(self._nodes)
            nodes_to_add_dict = {
                node.checksum_address: node
                for node in nodes_to_add
            }
            for checksum_address in diff.nodes_updated:
                new_node = nodes_to_add_dict[checksum_address]
                new_node.mature()
                nodes[checksum_address] = new_node
            for checksum_address in diff.nodes_removed:
                del nodes[checksum_address]

            all_nodes_sorted = sorted(itertools.chain(this_node_list,
                                                      nodes.values()),
                                      key=lambda node: node.checksum_address)
            joined_metadata = b"".join(
                bytes(node) for node in all_nodes_sorted)
            checksum = keccak_digest(joined_metadata).hex()
        else:
            nodes = self._nodes
            checksum = self.checksum

        new_state = FleetState(checksum=checksum,
                               nodes=nodes,
                               this_node_ref=self._this_node_ref,
                               this_node_metadata=this_node_metadata)

        return new_state, diff
Beispiel #27
0
    def provide_treasure_map(treasure_map_id):
        headers = {'Content-Type': 'application/octet-stream'}

        try:
            treasure_map = treasure_map_tracker[keccak_digest(binascii.unhexlify(treasure_map_id))]
            response = Response(bytes(treasure_map), headers=headers)
            log.info("{} providing TreasureMap {}".format(node_bytes_caster(),
                                                          treasure_map_id))
        except KeyError:
            log.info("{} doesn't have requested TreasureMap {}".format(stamp, treasure_map_id))
            response = Response("No Treasure Map with ID {}".format(treasure_map_id),
                                status=404, headers=headers)

        return response
Beispiel #28
0
def test_recover(testerchain, signature_verifier):
    message = os.urandom(100)

    # Prepare message hash
    hash_ctx = hashes.Hash(hashes.SHA256(), backend=backend)
    hash_ctx.update(message)
    message_hash = hash_ctx.finalize()

    # Generate Umbral key and extract "address" from the public key
    umbral_privkey = UmbralPrivateKey.gen_key()
    umbral_pubkey = umbral_privkey.get_pubkey()
    umbral_pubkey_bytes = umbral_privkey.get_pubkey().to_bytes(
        is_compressed=False)
    signer_address = keccak_digest(umbral_pubkey_bytes[1:])
    signer_address = to_normalized_address(signer_address[12:])

    # Sign message
    signer = Signer(umbral_privkey)
    signature = signer(message)

    # Get recovery id (v) before using contract
    # If we don't have recovery id while signing then we should try to recover public key with different v
    # Only the correct v will match the correct public key
    v = get_signature_recovery_value(message, signature, umbral_pubkey)
    recoverable_signature = bytes(signature) + v

    # Check recovery method in the contract
    assert signer_address == to_normalized_address(
        signature_verifier.functions.recover(message_hash,
                                             recoverable_signature).call())

    # Also numbers 27 and 28 can be used for v
    recoverable_signature = recoverable_signature[:-1] + bytes(
        [recoverable_signature[-1] + 27])
    assert signer_address == to_normalized_address(
        signature_verifier.functions.recover(message_hash,
                                             recoverable_signature).call())

    # Only number 0,1,27,28 are supported for v
    recoverable_signature = bytes(signature) + bytes([2])
    with pytest.raises((TransactionFailed, ValueError)):
        signature_verifier.functions.recover(message_hash,
                                             recoverable_signature).call()

    # Signature must include r, s and v
    recoverable_signature = bytes(signature)
    with pytest.raises((TransactionFailed, ValueError)):
        signature_verifier.functions.recover(message_hash,
                                             recoverable_signature).call()
Beispiel #29
0
    def hrac(self) -> bytes:
        """
        # TODO: #180 - This function is hanging on for dear life.  After 180 is closed, it can be completely deprecated.

        The "hashed resource authentication code".

        A hash of:
        * Alice's public key
        * Bob's public key
        * the label

        Alice and Bob have all the information they need to construct this.
        Ursula does not, so we share it with her.
        """
        return keccak_digest(bytes(self.alice.stamp) + bytes(self.bob.stamp) + self.label)
Beispiel #30
0
 def join_policy(self,
                 label,
                 alice_pubkey_sig,
                 using_dht=False,
                 node_list=None,
                 verify_sig=True):
     hrac = keccak_digest(
         bytes(alice_pubkey_sig) + bytes(self.stamp) + label)
     if node_list:
         self.network_bootstrap(node_list)
     self.get_treasure_map(alice_pubkey_sig,
                           hrac,
                           using_dht=using_dht,
                           verify_sig=verify_sig)
     self.follow_treasure_map(hrac, using_dht=using_dht)