def from_bytes(cls, record: bytes):
        """Build a TLSClientHelloSignature from a Client Hello TLS record.

        Parameters
        ----------
        record : bytes
            Raw over-the-wire content of the Client Hello TLS record.

        Returns
        -------
        sig : TLSClientHelloSignature
            Signature of the TLS record.
        """
        off = 0
        record_header = TLSRecordHeader._make(struct.unpack_from(
            TLS_RECORD_HEADER, record, off
        ))
        off += struct.calcsize(TLS_RECORD_HEADER)

        if record_header.type != 0x16:
            raise Exception(
                f"TLS record not of type Handshake (0x16). "
                f"Got 0x{record_header.type:02x}"
            )

        if not TLSVersion.has_value(record_header.version):
            raise Exception(
                f"Unknown TLS version 0x{record_header.version:04x}"
            )

        if len(record) - off != record_header.length:
            raise Exception("Corrupt record length")

        handshake_header = TLSHandshakeHeader._make(struct.unpack_from(
            TLS_HANDSHAKE_HEADER, record, off
        ))

        if handshake_header.type != 0x01:
            raise Exception(
                f"TLS handshake not of type Client Hello (0x01). "
                f"Got 0x{handshake_header.type:02x}"
           )

        if (len(record) - off - 4 != 
            (handshake_header.length_high << 16) + handshake_header.length_low):
            raise Exception("Corrupt handshake length")

        off += struct.calcsize(TLS_HANDSHAKE_HEADER)

        if not TLSVersion.has_value(handshake_header.version):
            raise Exception(
                f"Unknown TLS version 0x{handshake_header.version:04x}"
            )

        off += handshake_header.session_id_length

        ciphersuites, s = parse_tls_int_list(record[off:], entry_size=2)
        off += s

        comp_methods, s = parse_tls_int_list(
            record[off:], entry_size=1, header_size=1, replace_grease=False
        )
        off += s

        (extensions_length, ) = struct.unpack_from("!H", record, off)
        off += struct.calcsize("!H")

        if len(record) - off != extensions_length:
            raise Exception(f"Corrupt TLS extensions length")

        extensions = []
        while off < len(record):
            (ext_type, ext_len) = struct.unpack_from(
                TLS_EXTENSION_HEADER, record, off
            )
            ext_total_len = ext_len + struct.calcsize(TLS_EXTENSION_HEADER)
            extensions.append(TLSExtensionSignature.from_bytes(
                record[off:off + ext_total_len]
            ))
            off += ext_total_len

        return TLSClientHelloSignature(
            record_version=TLSVersion(record_header.version),
            handshake_version=TLSVersion(handshake_header.version),
            session_id_length=handshake_header.session_id_length,
            ciphersuites=ciphersuites,
            comp_methods=comp_methods,
            extensions=extensions
        )
Build a TLSClientHelloSignature from a Client Hello TLS record.

        Parameters
        ----------
        record : bytes
            Raw over-the-wire content of the Client Hello TLS record.

        Returns
        -------
        sig : TLSClientHelloSignature
            Signature of the TLS record.
        
tests/signature.py