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() # So, our story is fairly simple: an everyman meets Alice. somebody = Character() somebody.learn_about_actor(alice) # Alice signs a message. message = b"A message for all my friends who can only verify and not sign." signature = alice.seal(message) # Our everyman can verify it. verification, cleartext = somebody.verify_from(alice, message, signature, decrypt=False) assert verification is True assert cleartext is NO_DECRYPTION_PERFORMED
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 == 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_character_with_encrypting_power_can_encrypt(): """ Now, a Character *with* EncryptingKeyPair can encrypt. """ can_sign_and_encrypt = Character(crypto_power_ups=[SigningPower, EncryptingPower]) ursula = Ursula() can_sign_and_encrypt.learn_about_actor(ursula) cleartext = b"This is Officer Rod Farva. Come in, Ursula! Come in Ursula!" # TODO: Make encrypt_for actually encrypt. ciphertext, signature = can_sign_and_encrypt.encrypt_for(ursula, cleartext, sign=False) assert signature == NOT_SIGNED assert ciphertext is not None # annnd fail.
def test_anybody_can_encrypt(): """ Similar to anybody_can_verify() above; we show that anybody can encrypt. """ can_sign_and_encrypt = Character( crypto_power_ups=[SigningPower, EncryptingPower]) ursula = Ursula() cleartext = b"This is Officer Rod Farva. Come in, Ursula! Come in Ursula!" ciphertext, signature = can_sign_and_encrypt.encrypt_for(ursula, cleartext, sign=False) assert signature == NOT_SIGNED assert ciphertext is not None
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]) seal_of_the_signer = signer.seal # We can use the signer's seal to sign a message... signature = seal_of_the_signer(message) # ...or to get the signer's public key for verification purposes. sig = api.ecdsa_load_sig(signature) verification = api.ecdsa_verify(*sig, api.keccak_digest(message), seal_of_the_signer) assert verification is True
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
def test_trying_to_find_unknown_actor_raises_not_found(): tony_clifton = Character() message = b"some_message" signature = ALICE.seal(message) # Tony can't reference Alice... with pytest.raises(Character.NotFound): verification = tony_clifton.verify_from(ALICE, signature, message) # ...before learning about Alice. tony_clifton.learn_about_actor(ALICE) verification, NO_DECRYPTION_PERFORMED = tony_clifton.verify_from(ALICE, signature, message) assert verification is True
def test_trying_to_find_unknown_actor_raises_not_found(alice): """ Tony the test character can't make reference to a character he doesn't know about yet. """ tony_clifton = Character() message = b"some_message" signature = alice.seal(message) # Tony can't reference Alice... with pytest.raises(Character.NotFound): verification = tony_clifton.verify_from(alice, signature, message) # ...before learning about Alice. tony_clifton.learn_about_actor(alice) verification, NO_DECRYPTION_PERFORMED = tony_clifton.verify_from(alice, message, signature) assert verification is True
def test_signing_only_power_cannot_encrypt(): """ Similar to the above with signing, here we show that a Character without the EncryptingKeypair PowerUp can't encrypt. """ # Here's somebody who can sign but not encrypt. can_sign_but_not_encrypt = Character(crypto_power_ups=[SigningPower]) # ..and here's Ursula, for whom our Character above wants to encrypt. ursula = Ursula() # They meet. can_sign_but_not_encrypt.learn_about_actor(ursula) # The Character has the message ready... cleartext = "This is Officer Rod Farva. Come in, Ursula! Come in Ursula!" # But without the proper PowerUp, no encryption happens. with pytest.raises(NoEncryptingPower) as e_info: can_sign_but_not_encrypt.encrypt_for(ursula, cleartext)