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
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)