예제 #1
0
    def __init__(
        self,
        signature_bytes: bytes = None,
        vrs: Tuple[int, int, int] = None,
        backend:
        'Union[BaseECCBackend, Type[BaseECCBackend], str, None]' = None,
    ) -> None:
        if bool(signature_bytes) is bool(vrs):
            raise TypeError(
                "You must provide one of `signature_bytes` or `vrs`")
        elif signature_bytes:
            validate_recoverable_signature_bytes(signature_bytes)
            r = big_endian_to_int(signature_bytes[0:32])
            s = big_endian_to_int(signature_bytes[32:64])
            v = ord(signature_bytes[64:65])
        elif vrs:
            v, r, s, = vrs
        else:
            raise TypeError("Invariant: unreachable code path")

        super().__init__(rs=(r, s), backend=backend)
        try:
            self.v = v
        except ValidationError as error:
            raise BadSignature(str(error)) from error
예제 #2
0
def verify(public_key: str,
           signature: str,
           message: Optional[str] = None,
           message_hash: Optional[str] = None) -> bool:
    """
    Verify XinFin signature by public key.

    :param public_key: XinFin public key.
    :type public_key: str.
    :param signature: Signed message data.
    :type signature: str.
    :param message: Message data, default to ``None``.
    :type message: str.
    :param message_hash: Message data hash, default to ``None``.
    :type message_hash: str.

    :return: bool -- Verified signature.

    >>> from pyxdc.signature import verify
    >>> verify(public_key="03d8799336beacc6b2e7f86f46bce4ad5cabf1ec7a0d6241416985e3b29fe1cc85", message="meherett", signature="74ad07a84b87fa3efa2f0e825506fb8bbee41021ca77a30e8ffa2bd66d47d99917d4a0587185e78a051a9cb80ebf65c7d62dbeedb7f9a029f961d70b52a10dc001")
    True
    >>> verify(public_key="03d8799336beacc6b2e7f86f46bce4ad5cabf1ec7a0d6241416985e3b29fe1cc85", message_hash="4bbbfd0c33fea618f4a9aa75c02fe76e50fa59798af021bc34f7856f3259c685", signature="74ad07a84b87fa3efa2f0e825506fb8bbee41021ca77a30e8ffa2bd66d47d99917d4a0587185e78a051a9cb80ebf65c7d62dbeedb7f9a029f961d70b52a10dc001")
    True
    """

    if message:
        message_bytes = curried.to_bytes(primitive=None,
                                         hexstr=None,
                                         text=message)
        msg_length = str(len(message_bytes)).encode('utf-8')
        joined = b'\x19' + b'E' + b'thereum Signed Message:\n' + msg_length + message_bytes
        keccak_256_message = keccak_256()
        keccak_256_message.update(joined)
        message_hash = keccak_256_message.digest()
    elif message_hash:
        message_hash = unhexlify(message_hash)
    else:
        raise ValueError("Message data or hash is required to sign.")

    signature = unhexlify(signature)
    validate_recoverable_signature_bytes(signature)
    r = big_endian_to_int(signature[0:32])
    s = big_endian_to_int(signature[32:64])
    v = ord(signature[64:65])
    validate_compressed_public_key_bytes(unhexlify(public_key))
    uncompressed_public_key = decompress_public_key(unhexlify(public_key))

    return ecdsa_raw_verify(msg_hash=message_hash,
                            rs=(r, s),
                            public_key_bytes=uncompressed_public_key)