def test_anybody_can_encrypt():
    """
    Similar to anybody_can_verify() above; we show that anybody can encrypt.
    """
    someone = Character(always_be_learning=False, federated_only=True)
    bob = Bob(is_me=False, federated_only=True)

    cleartext = b"This is Officer Rod Farva. Come in, Ursula!  Come in Ursula!"

    ciphertext, signature = someone.encrypt_for(bob, cleartext, sign=False)

    assert signature == constants.NOT_SIGNED
    assert ciphertext is not None
def test_anybody_can_encrypt():
    """
    Similar to anybody_can_verify() above; we show that anybody can encrypt.
    """
    everyman = Character()
    ursula = Ursula(is_me=False)

    cleartext = b"This is Officer Rod Farva. Come in, Ursula!  Come in Ursula!"

    ciphertext, signature = everyman.encrypt_for(ursula, cleartext, sign=False)

    assert signature == constants.NOT_SIGNED
    assert ciphertext is not None
def test_actor_without_signing_power_cannot_sign():
    """
    We can create a Character with no real CryptoPower to speak of.
    This Character can't even sign a message.
    """
    cannot_sign = CryptoPower(power_ups=[])
    non_signer = Character(crypto_power=cannot_sign)

    # The non-signer's stamp doesn't work for signing...
    with pytest.raises(NoSigningPower) as e_info:
        non_signer.stamp("something")

    # ...or as a way to cast the (non-existent) public key to bytes.
    with pytest.raises(NoSigningPower) as e_info:
        bytes(non_signer.stamp)
def test_anybody_can_verify():
    """
    In the last example, we used the lower-level Crypto API to verify the signature.

    Here, we show that anybody can do it without needing to directly access Crypto.
    """
    # Alice can sign by default, by dint of her _default_crypto_powerups.
    alice = Alice(federated_only=True, always_be_learning=False)

    # So, our story is fairly simple: an everyman meets Alice.
    somebody = Character(always_be_learning=False, federated_only=True)

    # Alice signs a message.
    message = b"A message for all my friends who can only verify and not sign."
    signature = alice.stamp(message)

    # Our everyman can verify it.
    cleartext = somebody.verify_from(alice, message, signature, decrypt=False)
    assert cleartext is constants.NO_DECRYPTION_PERFORMED
def test_anybody_can_verify(nucypher_test_config, mock_policy_agent):
    """
    In the last example, we used the lower-level Crypto API to verify the signature.

    Here, we show that anybody can do it without needing to directly access Crypto.
    """

    # Alice can sign by default, by dint of her _default_crypto_powerups.
    alice = Alice(config=nucypher_test_config, policy_agent=mock_policy_agent)

    # So, our story is fairly simple: an everyman meets Alice.
    somebody = Character(config=nucypher_test_config)

    # Alice signs a message.
    message = b"A message for all my friends who can only verify and not sign."
    signature = alice.stamp(message)

    # Our everyman can verify it.
    verification, cleartext = somebody.verify_from(alice,
                                                   message,
                                                   signature,
                                                   decrypt=False)
    assert verification is True
    assert cleartext is constants.NO_DECRYPTION_PERFORMED
def test_character_blockchain_power(testerchain):

    # TODO: Handle multiple providers
    eth_address = testerchain.interface.w3.eth.accounts[0]
    sig_privkey = testerchain.interface.providers[
        0].ethereum_tester.backend._key_lookup[eth_utils.to_canonical_address(
            eth_address)]
    sig_pubkey = sig_privkey.public_key

    signer = Character(is_me=True, checksum_address=eth_address)
    signer._crypto_power.consume_power_up(
        BlockchainPower(testerchain, eth_address))

    # Due to testing backend, the account is already unlocked.
    power = signer._crypto_power.power_ups(BlockchainPower)
    power.is_unlocked = True
    # power.unlock_account('this-is-not-a-secure-password')

    data_to_sign = b'What does Ursula look like?!?'
    sig = power.sign_message(data_to_sign)

    is_verified = power.verify_message(eth_address, sig_pubkey.to_bytes(),
                                       data_to_sign, sig)
    assert is_verified == True

    # Test a bad message:
    with pytest.raises(PowerUpError):
        power.verify_message(eth_address, sig_pubkey.to_bytes(),
                             data_to_sign + b'bad', sig)

    # Test a bad address/pubkey pair
    with pytest.raises(ValueError):
        power.verify_message(testerchain.interface.w3.eth.accounts[1],
                             sig_pubkey.to_bytes(), data_to_sign, sig)

    # Test a signature without unlocking the account
    power.is_unlocked = False
    with pytest.raises(PowerUpError):
        power.sign_message(b'test')

    # Test lockAccount call
    del (power)
def test_actor_with_signing_power_can_sign():
    """
    However, simply giving that character a PowerUp bestows the power to sign.

    Instead of having a Character verify the signature, we'll use the lower level API.
    """
    message = b"Llamas."

    signer = Character(crypto_power_ups=[SigningPower], is_me=True)
    stamp_of_the_signer = signer.stamp

    # We can use the signer's stamp to sign a message (since the signer is_me)...
    signature = stamp_of_the_signer(message)

    # ...or to get the signer's public key for verification purposes.
    # (note: we use the private _der_encoded_bytes here to test directly against the API, instead of Character)
    verification = api.ecdsa_verify(message, signature._der_encoded_bytes(),
                                    stamp_of_the_signer.as_umbral_pubkey())

    assert verification is True