예제 #1
0
def test_split_two_signatures():
    """
    We make two random Signatures and concat them.  Then split them and show that we got the proper result.
    """
    sig1, sig2 = Signature(secure_random(65)), Signature(secure_random(65))
    sigs_concatted = sig1 + sig2
    two_signature_splitter = BytestringSplitter(Signature, Signature)
    rebuilt_sig1, rebuilt_sig2 = two_signature_splitter(sigs_concatted)
    assert (sig1, sig2) == (rebuilt_sig1, rebuilt_sig2)
예제 #2
0
def test_signature_rs_serialization():
    privkey = UmbralPrivateKey.gen_key()
    message = b"attack at dawn"
    der_sig_bytes = ecdsa_sign(message, privkey)

    signature_from_der = Signature.from_bytes(der_sig_bytes, der_encoded=True)
    rs_sig_bytes = bytes(signature_from_der)
    assert len(rs_sig_bytes) == 64

    signature_from_rs = Signature.from_bytes(rs_sig_bytes, der_encoded=False)

    assert signature_from_rs == signature_from_der
    assert signature_from_rs == der_sig_bytes
    assert signature_from_rs.verify(message, privkey.get_pubkey())
예제 #3
0
def test_split_signature_from_arbitrary_bytes():
    how_many_bytes = 10
    signature = Signature(secure_random(65))
    some_bytes = secure_random(how_many_bytes)
    splitter = BytestringSplitter(Signature, (bytes, how_many_bytes))

    rebuilt_signature, rebuilt_bytes = splitter(signature + some_bytes)
예제 #4
0
    def verify_from(self, actor_whom_sender_claims_to_be: "Character", message: bytes, signature: Signature = None,
                    decrypt=False,
                    signature_is_on_cleartext=False) -> tuple:
        """
        Inverse of encrypt_for.

        :param actor_that_sender_claims_to_be: A Character instance representing the actor whom the sender claims to be.  We check the public key owned by this Character instance to verify.
        :param messages: The messages to be verified.
        :param decrypt: Whether or not to decrypt the messages.
        :param signature_is_on_cleartext: True if we expect the signature to be on the cleartext.  Otherwise, we presume that the ciphertext is what is signed.
        :return: (Whether or not the signature is valid, the decrypted plaintext or NO_DECRYPTION_PERFORMED)
        """
        if not signature and not signature_is_on_cleartext:
            raise ValueError("You need to either provide the Signature or decrypt and find it on the cleartext.")

        cleartext = NO_DECRYPTION_PERFORMED

        if signature_is_on_cleartext:
            if decrypt:
                cleartext = self._crypto_power.decrypt(message)
                signature, message = BytestringSplitter(Signature)(cleartext, return_remainder=True)
            else:
                raise ValueError(
                    "Can't look for a signature on the cleartext if we're not decrypting.")

        actor = self._lookup_actor(actor_whom_sender_claims_to_be)

        return signature.verify(message, actor.seal), cleartext
예제 #5
0
    def verify_from(self,
                    actor_whom_sender_claims_to_be: "Character",
                    message_kit: Union[MessageKit, bytes],
                    signature: Signature=None,
                    decrypt=False,
                    signature_is_on_cleartext=False) -> tuple:
        """
        Inverse of encrypt_for.

        :param actor_that_sender_claims_to_be: A Character instance representing
            the actor whom the sender claims to be.  We check the public key
            owned by this Character instance to verify.
        :param messages: The messages to be verified.
        :param decrypt: Whether or not to decrypt the messages.
        :param signature_is_on_cleartext: True if we expect the signature to be
            on the cleartext. Otherwise, we presume that the ciphertext is what
            is signed.
        :return: Whether or not the signature is valid, the decrypted plaintext
            or NO_DECRYPTION_PERFORMED
        """
        # TODO: In this flow we now essentially have two copies of the public key.  See #174.
        # One from the actor (first arg) and one from the MessageKit.
        # Which do we use in which cases?

        # if not signature and not signature_is_on_cleartext:
        # TODO: Since a signature can now be in a MessageKit, this might not be accurate anymore.  See #174.
        # raise ValueError("You need to either provide the Signature or \
        #                   decrypt and find it on the cleartext.")

        cleartext = NO_DECRYPTION_PERFORMED

        if signature_is_on_cleartext:
            if decrypt:
                cleartext_with_sig = self.decrypt(message_kit)
                signature, cleartext = BytestringSplitter(Signature)(cleartext_with_sig,
                                                                     return_remainder=True)
                message_kit.signature = signature  # TODO: Obviously this is the wrong way to do this.  Let's make signature a property.
            else:
                raise ValueError(
                    "Can't look for a signature on the cleartext if we're not \
                     decrypting.")
            message = cleartext
            alice_pubkey = message_kit.alice_pubkey
        else:
            # The signature is on the ciphertext.  We might not even need to decrypt it.
            if decrypt:
                message = message_kit.ciphertext
                cleartext = self.decrypt(message_kit)
            else:
                message = bytes(message_kit)
            alice_pubkey = actor_whom_sender_claims_to_be.public_key(SigningPower)

        if signature:
            is_valid = signature.verify(message, alice_pubkey)
        else:
            # Meh, we didn't even get a signature.  Not much we can do.
            is_valid = False

        return is_valid, cleartext
예제 #6
0
def test_trying_to_extract_too_many_bytes_raises_typeerror():
    how_many_bytes = 10
    too_many_bytes = 11
    signature = Signature(secure_random(65))
    some_bytes = secure_random(how_many_bytes)
    splitter = BytestringSplitter(Signature, (bytes, too_many_bytes))

    with pytest.raises(ValueError):
        rebuilt_signature, rebuilt_bytes = splitter(signature + some_bytes, return_remainder=True)
예제 #7
0
    def sign(self, message: bytes) -> bytes:
        """
        Signs a hashed message and returns a signature.

        :param message: The message to sign

        :return: Signature in bytes
        """
        signature_der_bytes = API.ecdsa_sign(message, self._privkey)
        return Signature.from_bytes(signature_der_bytes, der_encoded=True)
예제 #8
0
    def sign(self, *messages):
        """
        Signs a message and returns a signature with the keccak hash.
        :param Iterable messages: Messages to sign in an iterable of bytes
        :rtype: bytestring
        :return: Signature of message
        """
        try:
            sig_keypair = self._power_ups[SigningPower]
        except KeyError as e:
            raise NoSigningPower(e)
        msg_digest = b"".join(API.keccak_digest(m) for m in messages)

        return Signature(sig_keypair.sign(msg_digest))
예제 #9
0
def test_signature_can_verify():
    privkey = UmbralPrivateKey.gen_key()
    message = b"attack at dawn"
    der_sig_bytes = ecdsa_sign(message, privkey)
    signature = Signature.from_bytes(der_sig_bytes, der_encoded=True)
    assert signature.verify(message, privkey.get_pubkey())