Characters

class nucypher.characters.base.Character(domains: Set = (b'GLOBAL_DOMAIN', ), is_me: bool = True, federated_only: bool = False, blockchain: nucypher.blockchain.eth.chains.Blockchain = None, checksum_public_address: bytes = NO_BLOCKCHAIN_CONNECTION, network_middleware: nucypher.network.middleware.RestMiddleware = None, keyring_dir: str = None, crypto_power: nucypher.crypto.powers.CryptoPower = None, crypto_power_ups: List[nucypher.crypto.powers.CryptoPowerUp] = None, *args, **kwargs)[source]

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

exception InvalidSignature

Raised when a Signature is not valid.

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, federated_only=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_key_bytes) in the following format: {CryptoPowerUp class: public_material_bytes}

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

# TODO: Need to be federated only until we figure out the best way to get the checksum_public_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).

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.
Returns:

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

class nucypher.characters.lawful.Alice(is_me=True, federated_only=False, network_middleware=None, *args, **kwargs)[source]
create_policy(bob: nucypher.characters.lawful.Bob, label: bytes, m: int, n: int, federated=False)[source]

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

generate_kfrags(bob, label: bytes, m: int, n: int) → 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
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(*args, **kwargs)[source]
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 swarm, asking for the TreasureMap. Return the first one who has it. TODO: What if a node gives a bunk TreasureMap?

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 kwown 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, *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.Ursula(rest_host: str, rest_port: int, domains: Set = (b'GLOBAL_DOMAIN', ), certificate: cryptography.x509.base.Certificate = None, certificate_filepath: str = None, db_filepath: str = None, is_me: bool = True, interface_signature=None, timestamp=None, identity_evidence: bytes = NOT_SIGNED, checksum_public_address: str = None, 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.

work_orders(bob=None)[source]

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