Characters

class nucypher.characters.base.Character(domains: Set = None, is_me: bool = True, federated_only: bool = False, checksum_address: str = NO_BLOCKCHAIN_CONNECTION, network_middleware: nucypher.network.middleware.RestMiddleware = None, keyring: nucypher.config.keyring.NucypherKeyring = None, keyring_root: str = None, crypto_power: nucypher.crypto.powers.CryptoPower = None, crypto_power_ups: List[nucypher.crypto.powers.CryptoPowerUp] = None, provider_uri: str = None, registry: nucypher.blockchain.eth.registry.BaseContractRegistry = None, *args, **kwargs)[source]

A base-class for any character in our cryptography protocol narrative.

exception SuspiciousActivity

raised when an action appears to amount to malicious conduct.

encrypt_for(recipient: nucypher.characters.base.Character, plaintext: bytes, sign: bool = True, sign_plaintext=True) → tuple[source]

Encrypts plaintext for recipient actor. Optionally signs the message as well.

Parameters
  • recipient – The character whose public key will be used to encrypt cleartext.

  • plaintext – The secret to be encrypted.

  • sign – Whether or not to sign the message.

  • sign_plaintext – When signing, the cleartext is signed if this is True, Otherwise, the resulting ciphertext is signed.

Returns

A tuple, (ciphertext, signature). If sign==False, then signature will be NOT_SIGNED.

classmethod from_public_keys(powers_and_material: Dict = None, verifying_key: Union[bytes, umbral.keys.UmbralPublicKey] = None, encrypting_key: Union[bytes, umbral.keys.UmbralPublicKey] = None, federated_only: bool = True, *args, **kwargs) → nucypher.characters.base.Character[source]

Sometimes we discover a Character and, at the same moment, learn the public parts of more of their powers. Here, we take a Dict (powers_and_material) in the format {CryptoPowerUp class: material}, where material can be bytes or UmbralPublicKey.

Each item in the collection will have the CryptoPowerUp instantiated with the given material, and the resulting CryptoPowerUp instance consumed by the Character.

Alternatively, you can pass directly a verifying public key (for SigningPower) and/or an encrypting public key (for DecryptionPower).

# TODO: Need to be federated only until we figure out the best way to get the checksum_address in here.

public_keys(power_up_class: ClassVar)[source]

Pass a power_up_class, get the public material for this Character which corresponds to that class - whatever type of object that may be.

If the Character doesn’t have the power corresponding to that class, raises the appropriate PowerUpError (ie, NoSigningPower or NoDecryptingPower).

store_metadata(filepath: str) → str[source]

Save this node to the disk. :param filepath: Output filepath to save node metadata. :return: Output filepath

verify_from(stranger: nucypher.characters.base.Character, message_kit: Union[nucypher.crypto.kits.UmbralMessageKit, bytes], signature: umbral.signing.Signature = None, decrypt=False, label=None) → bytes[source]

Inverse of encrypt_for.

Parameters
  • stranger – A Character instance representing the actor whom the sender claims to be. We check the public key owned by this Character instance to verify.

  • message_kit – the message to be (perhaps decrypted and) verified.

  • signature – The signature to check.

  • decrypt – Whether or not to decrypt the messages.

  • label – A label used for decrypting messages encrypted under its associated policy encrypting key

Returns

Whether or not the signature is valid, the decrypted plaintext or NO_DECRYPTION_PERFORMED

class nucypher.characters.lawful.Alice(is_me: bool = True, federated_only: bool = False, checksum_address: str = None, client_password: str = None, m: int = None, n: int = None, rate: int = None, duration_periods: int = None, first_period_reward: int = 0, timeout: int = 10, network_middleware: nucypher.network.middleware.RestMiddleware = None, controller: bool = True, *args, **kwargs)[source]
add_active_policy(active_policy)[source]

Adds a Policy object that is active on the NuCypher network to Alice’s active_policies dictionary by the policy ID. The policy ID is a Keccak hash of the policy label and Bob’s stamp bytes

create_policy(bob: nucypher.characters.lawful.Bob, label: bytes, **policy_params)[source]

Create a Policy to share uri with bob. Generates KFrags and attaches them.

decrypt_message_kit(message_kit: nucypher.crypto.kits.UmbralMessageKit, data_source: nucypher.characters.base.Character, label: bytes) → List[bytes][source]

Decrypt this Alice’s own encrypted data.

I/O signatures match Bob’s retrieve interface.

generate_kfrags(bob: nucypher.characters.lawful.Bob, label: bytes, m: int = None, n: int = None) → List[source]

Generates re-encryption key frags (“KFrags”) and returns them.

These KFrags can be used by Ursula to re-encrypt a Capsule for Bob so that he can activate the Capsule.

Parameters
  • bob – Bob instance which will be able to decrypt messages re-encrypted with these kfrags.

  • m – Minimum number of kfrags needed to activate a Capsule.

  • n – Total number of kfrags to generate

generate_policy_parameters(m: int = None, n: int = None, duration_periods: int = None, expiration: maya.core.MayaDT = None, *args, **kwargs) → dict[source]

Construct policy creation from parameters or overrides.

revoke(policy) → Dict[source]

Parses the treasure map and revokes arrangements in it. If any arrangements can’t be revoked, then the node_id is added to a dict as a key, and the revocation and Ursula’s response is added as a value.

class nucypher.characters.lawful.Bob(controller: bool = True, *args, **kwargs)[source]
exception IncorrectCFragsReceived(evidence: List)[source]

Raised when Bob detects incorrect CFrags returned by some Ursulas

follow_treasure_map(treasure_map=None, map_id=None, block=False, new_thread=False, timeout=10, allow_missing=0)[source]

Follows a known TreasureMap, looking it up by map_id.

Determines which Ursulas are known and which are unknown.

If block, will block until either unknown nodes are discovered or until timeout seconds have elapsed. After timeout seconds, if more than allow_missing nodes are still unknown, raises NotEnoughUrsulas.

If block and new_thread, does the same thing but on a different thread, returning a Deferred which fires after the blocking has concluded.

Otherwise, returns (unknown_nodes, known_nodes).

# TODO: Check if nodes are up, declare them phantom if not.

get_treasure_map_from_known_ursulas(network_middleware, map_id)[source]

Iterate through the nodes we know, asking for the TreasureMap. Return the first one who has it.

peek_at_treasure_map(treasure_map=None, map_id=None)[source]

Take a quick gander at the TreasureMap matching map_id to see which nodes are already known to us.

Don’t do any learning, pinging, or anything other than just seeing whether we know or don’t know the nodes.

Return two sets: nodes that are unknown to us, nodes that are known to us.

class nucypher.characters.lawful.Enrico(policy_encrypting_key, controller: bool = True, *args, **kwargs)[source]

A Character that represents a Data Source that encrypts data for some policy’s public key

classmethod from_alice(alice: nucypher.characters.lawful.Alice, label: bytes)[source]
Parameters
  • alice – Not a stranger. This is your Alice who will derive the policy keypair, leaving Enrico with the public part.

  • label – The label with which to derive the key.

Returns

class nucypher.characters.lawful.StakeHolder(is_me: bool = True, initial_address: str = None, checksum_addresses: set = None, password: str = None, *args, **kwargs)[source]
property total_stake

The total number of staked tokens, either locked or unlocked in the current period.

class nucypher.characters.lawful.Ursula(rest_host: str, rest_port: int, domains: Set = None, certificate: cryptography.x509.base.Certificate = None, certificate_filepath: str = None, db_filepath: str = None, is_me: bool = True, interface_signature=None, timestamp=None, decentralized_identity_evidence: bytes = NOT_SIGNED, checksum_address: str = None, worker_address: str = None, work_tracker: nucypher.blockchain.eth.token.WorkTracker = None, client_password: str = None, abort_on_learning_error: bool = False, federated_only: bool = False, start_learning_now: bool = None, crypto_power=None, tls_curve: cryptography.hazmat.primitives.asymmetric.ec.EllipticCurve = None, known_nodes: Iterable = None, **character_kwargs)[source]
exception NotEnoughUrsulas[source]

All Characters depend on knowing about enough Ursulas to perform their role. This exception is raised when a piece of logic can’t proceed without more Ursulas.

exception NotFound[source]
classmethod from_seednode_metadata(seednode_metadata, *args, **kwargs)[source]

Essentially another deserialization method, but this one doesn’t reconstruct a complete node from bytes; instead it’s just enough to connect to and verify a node.

NOTE: This is a federated only method.

work_orders(bob=None)[source]

TODO: This is better written as a model method for Ursula’s datastore.