from unittest import TestCase

from cryptography.hazmat.primitives.ciphers.algorithms import ARC4, AES, TripleDES, Camellia
from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305, AESGCM, AESCCM
from cryptography.hazmat.primitives.hashes import SHA1, SHA256, SHA384
from cryptography.hazmat.primitives.ciphers.modes import CBC, GCM

from tlexport.decryptor import Decryptor
from tlexport.tlsversion import TlsVersion

from tlexport.tlsrecord import TlsRecord

"""
implemented tests:
SSL 3.0: aes 128, aes 256, rc4, 3des, camellia
tls 1.0: covered by ssl 3.0


tls 1.3: all


"""


class TestTls13Decryptor(TestCase):
    def setUp(self) -> None:
        self.tls_1_3_chacha20_poly1305_decryptor = Decryptor(ChaCha20Poly1305, ChaCha20Poly1305, SHA256, {
            'client_handshake_traffic_secret': b'-SH\xf5\xe3\xfd\xe2\xa9Fz\x08q\xc2\xc1\x0e\x9c~\xbbI\xbd\xb8ix\xbf\xa7\xe9VM\x83\x00\xae\xf0',
            'server_handshake_traffic_secret': b'\x90\xfe\x89\xcc\xb5@\x86e\xd7\r"\xdb\xd9\xe6\xba\xc83\xc7\xe4O\x14\x9f\x92\xe31;\xbf\xea~\xc0\xbc\x07',
            'client_application_traffic_secret_0': b'\xecY\xdd{)\x01\xdb(f-\x91!\xc7NG\xa9b\xaafc+!\xff\x1d\xd5\xb9\xf3B\x13(CT',
            'server_application_traffic_secret_0': b"\x10\x87c\xa4\x18c*\xa4\x1a\x99\xb4\x0bM\x82\xcc\xe2'wh\xc3\xba\x9d\xde\x9e\xc6\x9f3\xd3\x92\xbe\xd1\xd0",
            'client_handshake_iv': b';\xd7\xf1\xd4\xde\xc1\x87\xce\x06\xba\xd5w',
            'server_handshake_iv': b'\x87_\x89g\x1fm\x89?j\x19\x9b\x0b',
            'client_application_iv': b'\x1c\xa0\xf3F\xa042 \x83\xa1\xeaS',
            'server_application_iv': b'\x03\xe2:\x8e\xb1\x0e\x18\x80<\xda\x89\x85'},
                                                             TlsVersion.TLS13, 16, 32, 8, 128,
                                                             {b'\x00+': bytearray(b'\x03\x04'), b'\x003': bytearray(
                                                                 b"\x00\x1d\x00 a\xb0\xb1\xf7\x83:\x85PR\x11^\xa7\xc6\x8bA\xa2\x82\xa3\xd0\'\xdd\x9cM\xdbDn\xdbL\xf2.\xfb3")}, 0)

        self.tls_1_3_aes_128_gcm_decryptor = Decryptor(AESGCM, AESGCM, SHA256, {
            'client_handshake_traffic_secret': b'?\x9c\xe1\x0c\xa7Q`\xa6\xddR\x9efx`\x14\x86',
            'server_handshake_traffic_secret': b'XCy\x82!\x93\x180\\\xab\x0b\xb5\xd7\xeb\x1e\xe1',
            'client_application_traffic_secret_0': b'\xcd*\x93\xb6\xf0\xa5\xad \x8d\x0f\x0c\x1a\x1e\x8d\xce\xee',
            'server_application_traffic_secret_0': b'T\xd6\x98\x98\xee\xd4\x1c\xc9~\x9cD\np\x13\xa4\xf4',
            'client_handshake_iv': b'\xdcl\x84\xf4\x84/\xd2\xd8\xc8\xd1\xc7\x87',
            'server_handshake_iv': b't*\x1aQ%\xc3\x96\x99Ips\x89',
            'client_application_iv': b'?P\xabB>\xc0\x851\xf9\xa5p\x96',
            'server_application_iv': b'hY\x0e\xb2\xc7\xce4\xf4\x0e\x9bL\r'}, TlsVersion.TLS13, 16, 32, 8, 128,
                                                       {b'\x00+': bytearray(b'\x03\x04'), b'\x003': bytearray(
                                                           b"\x00\x1d\x00 a\xb0\xb1\xf7\x83:\x85PR\x11^\xa7\xc6\x8bA\xa2\x82\xa3\xd0\'\xdd\x9cM\xdbDn\xdbL\xf2.\xfb3")},0)

        self.tls_1_3_aes_256_gcm_decryptor = Decryptor(AESGCM, AESGCM, SHA384, {
            'client_handshake_traffic_secret': b'\xadf\x06\x01h\x9bra\x11PAJ\x02q\xccb\xa7\xb1\xd0\xd1Tq\xbev\x1a\xac!9B";\xf8',
            'server_handshake_traffic_secret': b'&D\xcb\xa3\xda\xa7\xd2\x0ee\xcbuX\xb6\n~F\x06\x83\xb0\xe4#Up\x1f\xc3c\xd5h,\xbc\xf5\xad',
            'client_application_traffic_secret_0': b'\xe6\x1c\xf1\xbf\xae\xb2\x84\x14:\x88A\xd5\xe2.\xa8%\xc7TX\xf6\x862\x1b\x83?\x9cT\xb6\xe8}\xe7|',
            'server_application_traffic_secret_0': b'\xfa\xbb\xeeP\xd8T\xda\xe7U\x1b\xb3-\xa2\xb1\xe5\xe0\x94[&\x0f\xd2\x8d\xda:\xb5\xcaU4\x80\xa0tT',
            'client_handshake_iv': b'*\xd5\xca\t\xe6iU"S\xf4\xbe\x88',
            'server_handshake_iv': b'\xaf\xa7A\xac[\xbe\xc8Eu\xd91^',
            'client_application_iv': b'\xc8p\x1e\xfc\x8b0\xabK\xcf\xa0\xcap',
            'server_application_iv': b'\xa7\xff\xc3\xf4\xed\xc4Q\x8d\xd9\x05\xfb='},
                                                       TlsVersion.TLS13, 32, 48, 8, 128,
                                                       {b'\x00+': bytearray(b'\x03\x04'), b'\x003': bytearray(
                                                           b'\x00\x1d\x00 \xf8n\x01\xda\x8d\xdd\xb9\x0b\x1ak\xdb\xe0\x13c\x8f@\xe5\xa0\x1c\x04\x0e\x04e\x14w\xce\x89U\x9c{\xbfj')},0)

        self.tls_1_3_aes_128_ccm_decryptor = Decryptor(AESCCM, AESCCM, SHA256, {
            'client_handshake_traffic_secret': b'\xa4\xa1p\xee!\xd7\xe2Ky\x91B|\xcd\xfb3\t',
            'server_handshake_traffic_secret': b'\x84u\xeb\xb3\x97!\xc2O<\xddw@P\xd9\xa10',
            'client_application_traffic_secret_0': b'W\x1a\x99\x95U\x16\x02E2\xf8\x13p\x0e\\\x9f\x03',
            'server_application_traffic_secret_0': b'\xc8\xa7X\x0e\xed=J\x1a)\xb3\x88\xb3o\x0c\x95\xda',
            'client_handshake_iv': b'\xe5\xfb-\xb8\xea\xa4\n?j\x96\xa2\xdc',
            'server_handshake_iv': b'\xed\x04\xf9\xd7\xf9\x8f\x8cc[B>\xf3',
            'client_application_iv': b'\x08&\xab\xbf,5\xb2\xc2T\xfd3u',
            'server_application_iv': b'\x91\x1e\xb0\xa0\xa3s]\xd6\x02;:\xc5'},
                                                       TlsVersion.TLS13, 16, 32, 16, 128,
                                                       {b'\x003': bytearray(b'\x00\x17\x00A\x04\x19U\xfeBc:q\xa8q\xf6\x930\xda\xd0\x82\x14Z\xb6\xc9\xe2\x95\xea\x1a\xef<\xf7\xaa\xebL\x91Q\x0c\xf4\x08dEI\xf9\t\xd0f\x9e]\xf2\xd0\xd4\xc6\x92\xcaL:\x1c\xae\xcf\x8f\xad\xc1\xaa^\x11d\xc2\x8fo'),
                                                           b'\x00+': bytearray(
                                                               b'\x03\x04')},0)

        self.tls_1_3_aes_128_ccm_8_decryptor = Decryptor(AESCCM, AESCCM, SHA256, {
            'client_handshake_traffic_secret': b'`\xd1&s.q\xda\x9a\xe2@\xf5\xe5\xa8\xca\xcd\xf3',
            'server_handshake_traffic_secret': b'\x99xl*1A\x91U\n\x85\x8f\xe3\xe6\xd0\x16\x02',
            'client_application_traffic_secret_0': b'\ry4q\xe3\xab\xe7\xad\xb06\xd0\x95\xd5bEe',
            'server_application_traffic_secret_0': b'\x92\\\x1a\x14.=\xb4\x12\x0f\xb2N\\\x1b\x12\x9f=',
            'client_handshake_iv': b'\x9b\xf8\xde\xf8\xd4\xdb>"\xe0?\x92\xbd',
            'server_handshake_iv': b'\x1f\x07w[\r\xe1\x0f\xfd: /$',
            'client_application_iv': b'\xb9\xd1\x80\x19\xa4\xb6R}\xa9\x10\xef\x98',
            'server_application_iv': b'\xfc\xd9Y\xb3\x86T\x19\xfe\xe7\x0fv\xd4'},
                                                         TlsVersion.TLS13, 16, 32, 8, 128,
                                                         {b'\x003': bytearray(b'\x00\x17\x00A\x04(a4\x9b+\x15\x1c\x99i\x12\x84\x88\xb9q\x98\x90\xe8/\xd9\x115\xaaAM\xac\xceW\x9bSz \xe9|\x99\xa5\x13\xf38>\xb2\xe9\xef\xf5\xf1\xc5\xbaz\xf9\xc7\x0ez\x1aAq\x0b\xaa\xe6\r\xc0\x0c\xe7\x03\xbd\xff'),
                                                             b'\x00+': bytearray(
                                                                 b'\x03\x04')},0)

    def test_aes_128_ccm_8(self):
        server_1 = TlsRecord(bytearray(
            b'\x17\x03\x03\x00\x15\xb0\x94\x8d\xf7\x99\x94\xbd\x81b\xda\x93\xaa\xda\xf3{c\xdf\x13\xf2\x17\x03'), [],
            True)
        server_2 = TlsRecord(bytearray(
            b'\x17\x03\x03\x00:\xf4 \xf5\xc2Ahu6\x85^>\xcc\xe6\xd5\xb7w\xc8M\x92\x9b?\xc3\xdd\xa7 \x92G_A\x95IC|h\xe5\x99\xdf\xbf\xb5{?u[#D\xca\xc0TR\xaa)\xdcj\xd1w\x8c\x88\xf0'),
            [], True)
        server_3 = TlsRecord(bytearray(
            b'\x17\x03\x03\x05\xad\\#o4\xce\xef"\x9f\xd1s\x9a\x82O\xec{\x06\x1cl\xfdo\xfeAaG\x0es\xcc\x93S\xca\x03\xac\xcf$\xeb\x12g`\x07% \\.m\xd8\x08,\xc4>\xc1z^\xf8\xedb\x94\x18\xf1P\x89\xdevnA\x93wO}\xe2\xec\x8eM\xba\x99f\xaa3\xba\x12y\x1aF(\t\x8e\xd1\x16\x19\xcb\x12\xb0A\xa2\xc9"\t\x1c\xe1C\x1cF\x03t3\xc3\n\x1e;a\x02\xadG\xb0\x7f\nu\x83\x9b\xdb\xc0\xce\x08\rA\xea\xf1\xd7\xd9\x88E$\x84\x1a\xbc\xa9q\x84\xbf\xf51\xbbYWi_@\xb9\xab\xbc{\xc5D\x9d\xb3\x0c\xb0\xe1\xf6M\xdf\xfdD\n\xb0:\xb2\xa5z]\xd26\xb4\xbb\x98:2uf\xb0\xa7N\xb8\x90\xcf\xff\x12\xbd\x90\xee\xf3pv9\r\xcf\xc0\xbc\xd0\xe7\xeboe9\xca\xd6u\x9eM\x0e\xc2A\xdfP\xcd@\xb3|\xaa-\x14^3]~\xe6n!\x8a\x9a`\x19n\xd3\xcbh1/\xa8\xe0M\xbe\xc3\xf1\xb6N\x91\x93\xe8x<\x92\x05\xd7r\x94\x8a\x88W\xe9!\x95*\xe1\xd5\x0f\xcd\x90$K\xd1\xda\xbdf\x9bsR9\xf5\x07\x83\x8e\xb3z\xb7o\xc8\x8c\x97\xbf*i\x08\x9c\xa6\x9d+{\x99\xf4v\xfc\x8b\xb4_8\xd2\xb6L\x9f\t\xd0\x8c\x87\xee\xf2\x14\x8f\xbf\xe5\xfbQ\'\x91~\x86\xd1b\xc9\xb7\x1b\xcd\xc6l\xa3\x0c2\x01|\xcf2+\x8e\xf60\xc3}\xf4@C\x99\x9a\xd7\xfe\xc5\xc0\xfb{\xa6\x98.;\xde\x96y\xa8\x04\x8aV>\x1a\x19[\xf1\x9c\xf2\x13A\xbf\xde\xb5d<\xe1\xae\xfe&b\xd9\x1e\n\xb4\x87t\xa7\xe0@\x0eP\x0b\xd1\xc4\xb6\xff\xc4\x8dzX\xa9I\xd9\x1a\xbd\xba\xb0\x91\x92\xb9x\t\t\xa8\x9d\x0e\xe9\x96y\xcc\xd4c\x98\xbejUL\x7fZ[m\xf9\xe6\x07\xd55]\xa3\xf9\x80\x1f\x03[6\x01\xf0\xe75\x1b\xa5\xf0\xe2$\xf3g\xd13\xf6\xcaX^\xc2:\xdd\x134\x05Q\x96I\xe9\xe6\xf7\xf5\xa0\xef\xe80\xde\xc9@jq\xe9\x02\xb0uT\xfd\xa5\xed\x04\x90\xf7\x92k\xfbz\xa3\x93\x0643$\xcb\'\xf4\xb6\xd8\xa0@\x1f\xb3z\x98\xc6\xd5\x1e\xdeF\xb4\x86\x9d1\xee)1y/v\xa8PN\x0bi\xc0\xff\xa4L\xec\xa6U\x16La\xd9\xc6\xed\x90G\xc1\xc9\x16\xd4j:mu\x00\x16\x7f\x00d\x05\xdc.\xc2fe\x00I\xfcZG\xa5j2H\xa7\xc2\x13\xaa\xbe\x01\xd3=7\xb3\x83\xbd\xcb\xd1\xc7^\x98\xa3\x18\xa1\x16\x17\xc0N6X\xba\xe5\xb6\xdb\xdd\xc4\xcf\xdd\xf1\xd5u\x8d\xbb\xef!\xaf\xc4]\xbd\xd2E\xdd@\x86[\x869\x8d\x8eu\x8e\xc5\xf3\x18B]\xb5D\xd4\xff,\xf0\xa9\x16\x92\x1a\xa4\x87\xe51-\xbab\xa5\xc6yk:S\x1e\xe5\xfd?\xb8q\x9a/y_\x04\xf8\x95\xc4\x13^J\xe1""\xb4*H`=\x06\x87q\x90\x03 e\xa5\x97\x1a\xc3\xe3=\x95m\x18\xdc-\xb0\xb6\x12\xd9;\xe2\xb5\xa4\xf7#\xc4\xfeS\xc2\xc9\x03r\xea\xfcl\x82\xda\xaa\xa2\x83\xe2\xfd\x7fM\xa2Xf\xfb^\x17"\x88+J\xed\xf5\x1f\xd6 \x06\x89q\x97\x07qy\x89)\x04Nn\x8b\x1d\xb5\x95K\x9e%\x8f1\x91\xc4\x99P\x97\xa2W\'\xc9n\x1a\x03\xd2\xb7\xcc\xceB-\xb2\xa8\xfe\xcf|\xd7\x0b\x1c\x8e\xe3\x11\x15\t:\xd0\x8az>\x99Iwur\xae#\xd6\xb5\x8b\xc1\x10\xfb\x83\xff\x04\xe5Oi#\xe4G\x05N#;M{\xcd\x077Tow\xd0\xb3\xd5\xf8\xc7\x14K\xdc\x13\x94\x7f=\xbdM\x93M\x90<3\xc2q\xd1\xbf5\xb3\xa6^w,C6A\x8a\x072u\x9a\x8f0\x9ezVD\x0e\x1dr\x94\x98\xc1\x91\xddI\xae\\.\x91\xa7D\nQx"\xa4\xc4\xa5\xd5\x00fH;\x1d\x84"S\xca\xf8\xd0Mt\x12y8\xd3\x99\x81\xea\x16Q\x97!\xa6\xa1\xa4Y\xc5\xd7@\x9b\x97\x9e\x1f\x1e\x14\x827\xf9X m\xe5o\x19\xc8\xab\xd0\xd0\xdfC0#~\xd02\xa4\xbfF\x81\xe5\x8d\t6\xbc\x82\xed\xa2ti\xbf\xbe\xf1\x02\x11A\x80\xcc\xe3\x0e\xe3-\\\x03(\xdem\xcd\xf47\x1c\x97RF\x8fX\xd7\xf3\xd0\xf9\n\xc7F\xab\x90\xb2\x13\x89c\x1axo1\xcd\x9e\xc8\xc3\x90\xd4\xba\x93\xdc\xa8\xac\xcc\x06\xf5\xdd\xc3\xb1\x8a\xe5s\x93\xd4\xef\x88\x9e\x17\xc5\xf9<&\xe4nI#XF\xb4\xd9\xb5\x0b\xd5\x920L$\x00{\xad\x08yN\xcaQCpJl\x90\x9c\xcf\x9e\x80\xe8D\x16@1<o\x9f\xb7w\x98\x190\xfbv\xcf\xcb\x03\xa6\xca\xcb\x19\x97\xd1q8X\xe6a\xf5\xeb?\x8b\x9f2\x7fYV\xb8\x85l\xb0\xc3=\xe4t\xe4o\xbf]\xbf3\xb9\xed\xe8\xbe\x08\x93\xf0V\x13\xd7\x8a\xf3\xd7\xcb\x028\x9f$*\xdbi\xf8\x1b:\xbe,\x8d\xea\xc9\xe5\x16\x95:\xcd:"Gen\x9e=^R\x18\x82+\xd9PC\xd0\x1a?\x1f\xa0|\x08\xf3\x05B\xfc\x9c\xdc\xa6\x95\x8e7X\xe7\xc8\xbf\xda&\xcd\x17a{D\xff\xdf\x15q\x14CQ6.a\xe9\x91 D\xf9\x07\xffeF\x01\xca\x07\xbaK\x9b\x8d\x83\x0b\x9eQg\x15*\x99\xd5\x05T\x10\x82K\x99\n\x1b\x1e%|Y\x8d\xabG\x94\xf6\xdb\xaf\x0c\x99F9\x9fb\x8a\xe6N\x80\xaa\xc1\x0b\xdc\x01\xe9\x01$\x16=:\xe5\xec:Q\x117\xa6\xa5\xa4#Z7\x11\x88\xfe\xa0S\x07\xb2\'{\xb3\x842\x12\xe2_\xd2Q\xfe\x81i\x7f\x96\xd5j\x85n\xc1\x90\xc9\xfc\x8a\xf9\x197\x07E\xc9JS\xbb\x07oh}@Z)\xae\xf1\xefPe%J\xe2WR?\xd6\xdbC\x94\x05\x877k\'\xad\x0b\xf1=\x0b\x82\xe0^K\xd1KFr\xcd\x8f\x1e\x98\x89z\xad\xd0U\xcbGt@\xf1\xdfz2\xa0\xb2\xbb\xfe\xac\x1d\x8f\x94\xb1\xca\x04\xb9e\x0eT\xd8\xe7\x10\xde\\1\xb3`\x99W\x0b\x98sJ\x83\xde\xfe\\\xa4\xb7\x83\xd7\x16BL\xfb+)\xcbGaY\x88\x89$'),
            [], True)
        server_4 = TlsRecord(bytearray(
            b'\x17\x03\x03\x02\x11\xfb)O\xcfC\xbe\x01\x18pR\xe1x\xe6;\x00\x92\xafL\xearOD\':\xb7\xb5i\xddQ\n]z\x0c-\xc8\xaf\x1d\t\x85Z\xef \xed\xf3\xba\xfbc\xd3\xea\xae\xbf\xb3\xbbp^\xa9\xae\x84\xee\xdd+\xe0\x96\xe9\x00\xb3\x86\x04\xcbA\xb7\x18F\xdb\xa7\xba\x15t\xd9\x16\xa1#\xbb\xab\xdf\x0f\x94\nz\x8el\xa5\xc0W\xb4\xa6w\x00\xac\x91\xe0\xb7N}\xd9\x03s\x9cC\xfa \x8eUp\xeek1F\x0em\xd5\xb2\xa9Q\xab\xca\x01\xb5\xd5Qr\x1bQ\x14\xf6iz\xac}\xd2\x99\x18Q\xd70\xee\x08po\xb4\xcb\x81O3\xe9\xc1\xe3W\xfd\xd9\xdb.\xa1\xf0RU\xd5\x8d\xb1\xfeE\x87\xf1\x11\nA*`\x8cw\nk\xf0\xa7\x81g\xe0\xe3\xdd\xea:\x15\x87\xa0"N\xf7\xf28\xa1\x88Y\xd6J\xe5\xb8\xd6_\x9bI\xaej:\xfa\xd9\x81>\xcfU\x98\xb3\xfe\xfd\xcd\x1c\xfdf\x14\xc0\xd3\x7f\xd9;g\xdbZ\xbe\x00B\xa2-\xd5\xbf\x86\x1c\xa7\xd0\xb3\xb8 \xef\x11\x15j\x02\xf6\x99:-K\x1e5\x15\xb7\xedWS9\xa4\x16\xb5\x87\xcfzy\r\xe8\x80\xd7g\xa4\xcd!Z\xedWKf *+\xa9P\xfe3%\xb2\x8a\xcd3i\xc1\xc9|w\xa8\x9b&,\x7f\xb7\xfb&/0\x13\xa8\x83\xc1+\xb9\x08#EO\xb4*|\x92\xd8\xa8\x19\x0e\xfd\xaf/\x03\x9c_vu\x8dzb\xb6\xfel\t\x81$\x95>\xd7\xad\x1c\xc0\x02A\xab\xcb\x99\xe7A\xbcJ\x1c\x19\xa0\xcd\xda\x15\xd5\x0c4u\xd5\x14\xbc\xdf\xa5\xa3\x9a\xea^\xba5\xcf\xe3\xa6\x9b;\xfe\xcf51N\x8b\xa8\x80|d!\x87\xbc\xd4\xc0\tL\xf97\xac\x00\xd8\xc6(\x00/\x04v\xb6#\xca\x06q\x0c\x07\xc3\xac\x1e\x92\xf4Y\xdf\x84\x1b\x03P\n\xc3x\xa8Y\xee\x91\xf3\xaa\x8f\x8b{\xc0\xbf{{^\xa1\xa4:{\x0b\xd6QQ\x1d\xf0\xfeQ;\xe1<\x95\xc9\x1a\xf0\x93y\xf4G\xe5&]Y\x17\xae\xf0\xf1\xe5\r\xe8\x92!e\xa4\xa6+h\xa4\x8fk\xcc\xc3\xedKS^\\\xb06\xc2\x9e\xd4\x89\x82OO\xfc6\xd7\xbd%3ku\x02\xcam\xb7\x04\x19\x93'),
            [], True)
        server_5 = TlsRecord(bytearray(
            b'\x17\x03\x03\x00-\xa0\x13\x1e\x1a>\t\x84\x10BP\xc6\x9b\xec\x8f!\x9b\xb7\x0c\xf5\xba\\\xbf:1s!\xe6\r\xf3G{f\x10\x17\xc1\x9c\xb4\x82\x93\xa9\xd3\xc3\xa7kk'),
            [], True)

        client_1 = TlsRecord(bytearray(b'\x17\x03\x03\x00\x11\x05\xfc\xce\x9aR\xd8\n\x11Y\xd5x\xd6}\xc9\xfb\xccH'), [],
                             False)
        client_2 = TlsRecord(bytearray(
            b'\x17\x03\x03\x00-&\xaes\x9c\x90\xd8\x0bS\xed\xb0\x1c\xc0F\xc5e(\x82lT\xb1\x11x\xc2\x10\xbd\x12\x0c\x0b\xb5\xbf*\xd6F\xb7\x89\x98\xe3\x844\x98q\xd0\x07\xd2\x97'),
            [], False)

        server_app_1 = TlsRecord(bytearray(
            b'\x17\x03\x03\x01\x04\xb5D\x00\xe2_>\xb4.\xfb\xe6\x8d\x0c+\xdd\xab\r \xef\xa8\xfe\xf0\xf5\x03\xba\xcc$K:\x00$\xf1\xca\x12\x8e\x1f\xc2\xcd\xdc\nz(\xc2\xf9\x92{5\x93\x92\x13V\xe07O-\n\x1f\x04L2\xe8Q\x8d\xe5\xa7@\xcbR\xa5X=\xd1HQ&l\x85Pw\xee\xd0\xc4\x15\x89]\xf4\xb96\xbcF\n\x99\x1b\x89\xba\x1d\x98\xed\xc8\xd1\xc4\xc0\xe3\x9f\xc3\xd7\xa2\xad.\xab\xfbT\xcf\x8a\xd4\x05\x83\xa3\x0fm\x07\x03\x83\x06/\xab\xa4\xd0\xab\x95?Ai3S\x15\xc9\x15\xect\x06w\x88\xc7p\xf4\x9fr\x938c~\x80\xc9z|Au[\x81\xb3\x7f"\x04\x89\xb4\x1f\x8a\x16"\xfb\x96\x0bz\xb8\xfb\xb2,\xafT\\$\xff\x1c+\xc3\x96\xad\xd4@\xb6\xa9L\xfa\xbf\xfc\x07,p\x0c\x1e\x13\xa7<_TN\x19>A\xc6\xd9\x1e}\x9d~kgT\xccH.\xde?#\xaf\xed\xb4\x84\xf8w\'\x14 \xc5\xbf\tW\x00@\xa0\x17A\xf2N\xa4&=\xacdF\xd6\xc0=\xd8Y$0=\xb5<'),
            [], True)
        server_app_2 = TlsRecord(bytearray(
            b'\x17\x03\x03\x01\x04\x887\x07\xe0\xcaU\x96:\xe8\xf9\n\x9b\x06\n\xb2\x8d\xe7\x93\xb6\x19\x87\xbdE\xbd\x03\x06\xc3\x0c\x96\x99\x11\xe6\x80\x95\x97\xe8\x9a\x02\x8b\x9c]o\xb7o I\xa3k\x98\xe9\xe4\xc8\xbe\x0c\x8ae\x99\x19\xacRn4(=>\xc1\xf5\x83\x17\x10\x8e_\x10\x87\x1b\x07\xab\xde\x93\xdaYY4\x04\x06Ss\xfe[\xa2T\x93t\xc6\xdfk\x16X\xb0\xd1\xf7\x05\x9c\xaeX\x1b\x17\x14\xe9\x84\xf9%\xc8\xf9\x83\xbfM\xee?\xe5G\x9d\x88\x0b\x88x[\xf3\xa5u1\x8e\xe3\xf6-\x03\xde\x95\xc2XS\xf0\x88Q\xfe\xb3\x0c\x8f?\x07\x8dX\xdc\xcb\xf8R\xf1\xe3+\xdex\x99~\xb1m\xe1X\x86y\xed.h}\x9dX\xa4\xa6\xb6V}E\xf2\t\x9e\xac\xfctuH8s\xfeu\xeb\xf9\xa7\x981\xb3\x8cQ_\x9e\x08\xdaU\xd4\xc5\xb2\xf17\xaa\x8a\xcf$j\xbek\xec\x9cyUqjW\xfa\x0b\x8f\x10\x93\x83~\x88\x8a.\xf9\xfb\xf9\xf6\xd53\xce)m\x19\xd4\x89\x9c9\xfa\xe4Gg\x94\x86\xbc\xe1?\xfc\x05'),
            [], True)

        client_app_1 = TlsRecord(bytearray(b'\x17\x03\x03\x00\x0f\xb5\x8a\xed,*\xf9B\xf0\xe8\x11(\x99\xd0\x8a\x13'), [],
                                 False)
        server_app_3 = TlsRecord(bytearray(b'\x17\x03\x03\x00\x0f\x01\x80\xf6_^h\xb5ar5\x98\xe4\xfay,'), [], True)

        self.assertEqual(self.tls_1_3_aes_128_ccm_8_decryptor.decrypt(server_1, True),
                         b'\x08\x00\x00\x08\x00\x06\x00\x1c\x00\x02@\x01\x16')
        self.assertEqual(self.tls_1_3_aes_128_ccm_8_decryptor.decrypt(server_2, True),
                         b'\r\x00\x00-\x00\x00*\x00\r\x00"\x00 \x04\x01\x08\t\x08\x04\x04\x03\x08\x07\x05\x01\x08\n\x08\x05\x05\x03\x08\x08\x06\x01\x08\x0b\x08\x06\x06\x03\x02\x01\x02\x03\x00\x05\x00\x00\x16')
        self.assertEqual(self.tls_1_3_aes_128_ccm_8_decryptor.decrypt(server_3, True),
                         b'\x0b\x00\x05\xa0\x00\x00\x05\x9c\x00\x05\x970\x82\x05\x930\x82\x03{\xa0\x03\x02\x01\x02\x02\x14\x1aY\xdfW$L\x97V\xf9\xe8\\3\xaa\xf5\x81\xbf\xc08\xf3E0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\x000Y1\x0b0\t\x06\x03U\x04\x06\x13\x02AU1\x130\x11\x06\x03U\x04\x08\x0c\nSome-State1!0\x1f\x06\x03U\x04\n\x0c\x18Internet Widgits Pty Ltd1\x120\x10\x06\x03U\x04\x03\x0c\tlocalhost0\x1e\x17\r230926104549Z\x17\r240925104549Z0Y1\x0b0\t\x06\x03U\x04\x06\x13\x02AU1\x130\x11\x06\x03U\x04\x08\x0c\nSome-State1!0\x1f\x06\x03U\x04\n\x0c\x18Internet Widgits Pty Ltd1\x120\x10\x06\x03U\x04\x03\x0c\tlocalhost0\x82\x02"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\x00\x03\x82\x02\x0f\x000\x82\x02\n\x02\x82\x02\x01\x00\xe1\xd5\x88\x9e\xcbhEC\xbf\xe2x\xc4\xef\xd9\xb6A\x08>\xe2\xe4A\xb94\xd3\x06#\xd9\xf6~\x95\x1a9h-j\x8d\xd3_\xef\xb1\x19l\xbfO\xa3\xc8\xf5t2\\+\xee$\xbb\xb8EF\xc9\xf5`\xaeJhF-\xbd\r\xa9E\t\xceS\t\xf9\xc6By?eT\x9420\xd5\xfd\x19\x12~\xa8\x8a\x92\xaf\xf2U\xba\x1b!F\x81\tM\\\xfd|\xc6\x7f\xfb\xb2\xe3\xf1\xfcB\x1frn:8\xf6\x15\x1e\xba\x0e2\xfe\xd0\x95u=\x83\x1f\x1dx\xe7\x1a\xce\xe8\xf8<\x90\x92e\xd5B\xbeo\xfc\x9f;\xfe\x97\x19\xc5\x04\xe5\xf77@\x94\xbd\x08\x7f\xbe\x9e\x11\xc5\x96\xe6\xb0\xfa\\l\xd6\xf2\\.\x03f\x7f\x19\x1b\xaf1\xef\xcc\xba}\x10aL3 \xef\xde\xf2\xcaij\xc0\xa5\x15\x8ci6\xe7\xaa\xea!\xf8q)\x9c\x9ea\x0fuj\x07\xe2$\xb4R\xf0\x00:\xf0\x1b\x15\x1c;\x81\xc6/\'\xca\xfc\x97*7\xcb\x16*\xfc\xbeJ\xfc\xec\xe7\xf6\x14ej\x0582v6\xf3\x0b1\xdb\xad#\x91^\xa9\xf1q\x03\x16\xaf\xfc\xca\x88\xcc4\xe2\x862\xb6\x80\x1b)\x858\x16\t\x145\x8c\xa6\xb7\x85\xfa`\xd9\x8d\xf9\\\xfdx\xfbA\xb8Z\x9c\xaa\xb0\x9b\x85\x80\xf9$z\xa4\x8f\xa0\xd7\x94\x94\xa5<\xa7\xb6\xac\xde\xa8n\x99\xa5\xa6w\x0e+$G=DY\x98/\x0c\xa6:\xd5:em\\\xb2"\x97\xbe6\x96\x04P\n\xb3\xe0&?\x97\xe7\x03\xa2J\x97\x87qo(pHsu\x18\x88\xf1\x89]\x04\xb0\xa3\xb51\x1fa{\x030\xe3\xc3\xe88\xc4\xcch\x81\x9d\x0c\x15\x96\x93ynx}\xbd\xbdM\xfa3\xdd\xc9\x0f\x00\xc7pxIrs\xa9U\xc0.\x81C\xb2\t\xd4\xab\xbf\xde\xbeo\xee\x8a\xa73\x97\xa0_\xe1\xadreN\xf0\xd4]\xee\xc0\x0c\x06\xbaB%:I\x96\x92~\xbb\xf0B7\xd1\x16$FS\xc1\xc1kT\xd4V\xb1\xe1\xe6\xffs\xf5\xad\xa7;D\xae\xb5\xa44\x1e\xf5V \xd5q\xe3\xcfj\xca%\xe8\xd1\x9ev_{\rCW\x02\x03\x01\x00\x01\xa3S0Q0\x1d\x06\x03U\x1d\x0e\x04\x16\x04\x14j\\\xd67\x97r`\xf0\xc2|\xb5|\xf5y\xa1Qy\x03E\x180\x1f\x06\x03U\x1d#\x04\x180\x16\x80\x14j\\\xd67\x97r`\xf0\xc2|\xb5|\xf5y\xa1Qy\x03E\x180\x0f\x06\x03U\x1d\x13\x01\x01\xff\x04\x050\x03\x01\x01\xff0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\x00\x03\x82\x02\x01\x00s\xe7\xbc\xec\xd7\xbf\x96_r\x94\xdd\xf0\x1f\xea\x9d\xbe%\x1dn\xeb3\xce\xb9}+\xe5\xadk\xe1\x99\x10\x95\xc65\x9f]\xb2\x19O\x86u{\x191"\x90/ \x88\xa70\x13\xe3\x1a\x92 \xf8\x9b\xf7\x88g\x89\xd6\xdc5\xb6C~\x91\xbdO\xe6&\xbb\xec\xab#\xf8\xce8\xb6n\x9f\xe0\xf4\xb2\xd0\xfa\xb7T4\r\xf0\xd8\x8c\x13\xe8\x199\xd0a\xbb#\n\xfe\xb1/\xe5\xb0\x9dT`\xfa\x94#~\xbe3~B\x04@o.R\xba\x91<\xd0\xbc\xae,\x0b`ZN{\x06\x04\xce\x11Kb\x95\x8a>\xd4\xd1$\xde\xba\x8dA\tV\xb5M\xc8\xaa\x98\x03\x0er\x02\x07\x8fF\xa7\xd1=\xc7\x85g9\x82\xba\xfaJ\xe9m\xd6\xff\xa8F\nYO\nng*\x84\xebKz\xb67\x8c@u\xebC \x96L\xc9Lv\xb1:z\xa8\xe9pN\x98\xf8\xab\x11?\x96\x86A2\x90\xb5\xf5\x9e\x88A87>\xbb\xd1H\xc13P\xa8\xd0H\x8b8P-sK\xf08\x8132\xdc_\xca\x92\xbd\x9f\xdc\x8d\x84o\xc7\x19\xd2\xfbG\xbe\x16_\x96Ev\xba\x82\xcb\xe2\xe8\xc6+9\x1b$ \xb3\xc2bFD\x8a\xce\xd2\xb83t\x1c\xbe^\xa3\xfc\x83\xb7\t\xbe\xda\x81\x81g6(v\xd7\xdfU\x98\xfd@fL\xdb\xe7\xdc\xaf\xbb\xac\xe0yM\xe5\\\'d\xb8x\xf6\xf3\x14\xcet^\xf5\x19t\xa5~\xa5\xc2+I\xfc\x0ec\xd8:/\xb6\x02\xe4\xa3\x13\xa1\x7fbo\xba\xa6m\xb3\xe5\x87YS\xea\xcb\x9b\x0fa\xf4\xd1\x93^t\x06\x9fLJ\x9b%\x0c\x93G\xbcz\x89\x1e\x08\x02\xb5\x99\xe8\xfb\xfc[\xcb\xb0\x1eA<\x80\xb6\xcd\xb2\x02\xbf\xb1ig\xa4\xf0\x82\xac\x82\xba\x85e\xd9-\r\x9d\xeb\x12@p\xa6v\xc5\x94\xf3}\xafV\x1e*\x9c\x99\xbdy\xa2{\xcc\xdb\xc0\x85\xdd\x00\xda\xb4\x8c1\xb5s\x03\x11qk\xcf\xa8\x06\xbf\xda&b\x03R\xde\xaf\xadK\xb9\x1f\xc8F\xcc\xbb\xd3\xf5\x10\x90n\t\x0e)\xc3\xa9V\x9f\xd5\xf8*\xfc\x9fv\xb5\xf7\x18\x90w\xae\xcfc\x1a\x00\x00\x16')
        self.assertEqual(self.tls_1_3_aes_128_ccm_8_decryptor.decrypt(server_4, True),
                         b"\x0f\x00\x02\x04\x08\x04\x02\x00\x9e\x97\xc3g$\xba\t\x1eu'\xe9{\xc9\xb0A\xfb(\xf6D6\x9f\x9d\x0c\x05\x8c\x96\x9c:\xddA4@\x17P\xf2[\x17w\xa2\xe3B\x93\x01\xa8j\x06{p\x02Y\x84 u\xcb'\x1a-9)\x84 +\xe6\rs\x9e\xa5\xdb\\\ti\xb9\xb0\xc6y\x06\x9f\xe7|\x99x$\x8c\xce\xab\xbf6\x99\xcf\xb5\x1fZL\xab\xcf\x88\ri\xf8\xc4\xb6[\xcf\xbf\xf9{\x0f\xe2\xf7BL\x8a\xaa\xd5\x08\tt\xed\x8fr\x00\xceO\xad\xbb\x92*\xd9\xfa\xfeny\xa0<!\x1c\xa8\xcd\x1a\x9b\xb1\xb6X\xc6*\xca\xb9?G\xed\xb6\xf6\x1a\x83\x15\xc2\x07\xfb<e\x80c\x0f\x97ZR\xa4x\xb2G\x04\xd4\xebIF\xafL\xccWNx(\x1f\xc3y\x89G~Y}EYQ\xdf\x99V\xc0\xe3\x12\xe4\x84\x1f\x90\xba\x9d\xd1\xdfwu\xcehvs\x96E!\xfb\xe9I;\xd0z\xd0\xbc\x02\x97\xca\xcf\xc9\xbe\xe2\xbdW\x00=\x12\xbf\x01\xdd\x1b:\x04\x1b\xa6r\xb0&xGh\x1bM.\xbb\x01\xcb\xfcr`\x9d\xb5-\xae\x18\xdb\xab\xa3\xf4\x93\xd2b:c\xc8zb\xad\x990&\xf2\xa2\x7f\xe8&G\xdd\xc5*\xb5#C\x85\xfe\xf2h\x88\xaf\x0e\xa9L:?\x1d\x90\x1a\xfd\xed\x16\xcf\xf3\x8a\\\xd3\xbf\xa6\x03>,;\x18\xe3\x13\xea\xe7\xd1\xfe\xa8\xca\xc7#\x07\xa8\xe3\x85H\x01\x17)\xcfu\xb9\xc7\x03\x88_>\x8f\xfb\xdf\xb5\xceIF\xb2Y\xd6]\xd6\x0c\x13vo]\xad\x90<\xa6\x8ei\x87\xc7\x10\xea\xda\x02\x10p\x948\x08Fc\x8d\xb1\x0f\xf4\xe1\x96\x8fM\xaeE\xf6\x91\xc1\x90^Q\x9ay\xd0\x00~`\x98\x98\x06\x0f<\x04sQ\xd2\xdd\x85\x1b\xeeD>#\xd5>\xc2WB`\x9cw\xbc}\xc3\xd3\xf1q\xf4{RZ\xdd\xd2\x13\x17\xa6hin\xf2N\xc0\xac\x08l\xdc~\xc2\xfaK\xf7\x81W[\xa3\xb3\x9cd\x94\x99\x17\xd0\xd7Ab\xd9\r\xbf\xbf\x8f\x00q.W\r\xd2\xce\x12\t\x19\xb7\xcf\x82\xc0\xaf\x94\x89\x1b\x00xL\x90\x96\xdaH\xa1#\xdf\xf4`\xfcA\x8bi\x16")
        self.assertEqual(self.tls_1_3_aes_128_ccm_8_decryptor.decrypt(server_5, True),
                         b'\x14\x00\x00 \xd7\x8b\x1b;\x7f\xd6\xff\xa4\\|H\x8cO.:\x8a\xf3\xb7z\xcc\x04\xfd\x96D\xea\xe23\xa9+\x88S\x9c\x16')

        self.tls_1_3_aes_128_ccm_8_decryptor.update_keys(True)

        self.assertEqual(self.tls_1_3_aes_128_ccm_8_decryptor.decrypt(client_1, False),
                         b'\x0b\x00\x00\x04\x00\x00\x00\x00\x16')
        self.assertEqual(self.tls_1_3_aes_128_ccm_8_decryptor.decrypt(client_2, False),
                         b'\x14\x00\x00 \x9b\xa5\xea\xc6\xa3\x0e8Q\x86+\xa1?Y\x89\x84D\xb2*\xdc\xfa\xd5Vb&\x9c\xbb\x13\x07`\x94\xad\x15\x16')

        self.tls_1_3_aes_128_ccm_8_decryptor.update_keys(False)

        self.assertEqual(self.tls_1_3_aes_128_ccm_8_decryptor.decrypt(server_app_1, True),
                         b'\x04\x00\x00\xf7\x00\x00T`\x9b1\x16\x82\x04\x08\xdb$\xf7\x00\xe6U\x91Q*\xf4\x039\xe6\x89\x92T\xc5\xb2\x0f\t\x7f\xce\xfe\xc7\x91\xf7\xf5h/\x9c\xd8-\xf8\xb2\x9fu\x97\x00\xb0l\x91+7\xab\xa6\x0b\x1d$\xa9)\x82C]\xfe\x04\x89\n\x05\x9b\x16$\xc6S\xa9\x93\x91b\xe0\x8a\x90\xc9\xa7\xab\xd6\x01\xbd(-\xdeg\xedo\xfa:\xb8`L\xb82\xe6~\xaa\x80\x95\xf2\xdd\xcd\x9d\xcc@\x00o\x80\x08<\xba9\xca\x14\xead\xdfet.c\xa4\x8f\x82,\xc1\xf8\xf0v\xc9\x855\xd4\x89\xfc\xfc\x8e\xe2\x85\xaaX7\xb6h$\x90\xdc\xe7ReA\xe0\xdb&h\x05\x88,\x8a\xfdA\x94\n8\xc0\xc1J~M\x81\x1cK\ne\xbf\x7f\x825l1\xcf\x8a9\xf5y\xe6u-5\xe2\xdd\xce< Y0\xc2\xad"\x8c\x99\x84W*\x87\xae\xbe\xd2\xbf\xf7\xc3\xf1\x8bP\x89p\xc2Em\xa1\x8a9\x14W\x94\x83\xc4\x95\xe6\xfa\xc1\xf2\xf5\xdf\xbd\xee\tr\n\xc7\x00\x00\x16')
        self.assertEqual(self.tls_1_3_aes_128_ccm_8_decryptor.decrypt(server_app_2, True),
                         b'\x04\x00\x00\xf7\x00\x00T`r@\x13C\x04b_\xc0\xf4\x00\xe6U\x91Q*\xf4\x039\xe6\x89\x92T\xc5\xb2\x0f\t\x7f\xc3c`\xe6\xf5\xf6".\xe8\x95\x8f\xb2^X\xa1\xb4\x00\xb0\x13\xe5\xf5\xfd\xdb\xc2[\x97\xc8\x93\xba`G6<\n\xa6\xaa\xa1\xd17\x19r\x0e\x02,\xf0AF\xde\xb7\xbd\n\xb2\x19z\x98\x0e\xdbIJ\x8d\xd5U1\x1f\xd0_U\xcb\xdb\xc8\x10j\x06\x945\xc7\xf1\xb6\x84\xf5]\xce?Nh\xa4!\x1d9\x84\xa7\x97>@\xaeV\x99\xae\xf7^\x9d\xad`\xcf\x8c\x01\\\x0fK\xd5\x16\x99\x9da\xdff\xc2\xe7\xb2M>:\xe3\x1c\xf1\x00\x8eM\xc8\x00\\$\xc7\xc8\xb2\x18erQ\x93)\xeaF\xe0\xb7\x1c\x9c\xf8\xdc\x029\xae:\x19\xf7gp?\xac\xaa\xb1\xf9\xa7\xde\x03\x18\x17M\xaf\xaf,Gy\xd5\x99y\x16\xe6p\xee\xb9\xab85Eu\xee\x1e\xdc\xb5\xa8-Y^\xa4\xac\xc8,\xc1y\xd9\x05(\xce\xf6\xeb\x17\x10!\x90\xad\x990\x84\x00\x00\x16')
        self.assertEqual(self.tls_1_3_aes_128_ccm_8_decryptor.decrypt(client_app_1, False), b'Lorem\n\x17')
        self.assertEqual(self.tls_1_3_aes_128_ccm_8_decryptor.decrypt(server_app_3, True), b'Lorem\n\x17')

    def test_aes_128_ccm(self):
        server_1 = TlsRecord(bytearray(
            b'\x17\x03\x03\x00\x1d\xbf\xc5\xc1Q\xa6}v"\x04x\xc7Q\x85\x01\x8b|\xe3\xf7\x8fY\x16\xbc$Lw\x8a\xa8Uz'), [],
            True)
        server_2 = TlsRecord(bytearray(
            b'\x17\x03\x03\x00B\xe5SEW\xb0W\xe3\x01\x9e\xe4\xd4\xf6\xef\x14\x1d\xaf\x03\xa2\xd6\x91\xfb\xdd\xcc\xe0LF\xf8\xff\x99\x84\xb4"\x02\xa5\x03\x8a%\xb0\x05?\x05\xfbY>|\xa9\x9e53\xc1\x03 Bu\xb9\xd3\x02\x03\xf0\xcfi\'\xf0-_\x9f'),
            [], True)
        server_3 = TlsRecord(bytearray(
            b'\x17\x03\x03\x05\xb5,\x05\xfa\x0f\xcb\x0f/\x91\xbeG\x0e\xca\xc9\x8c\xceQ\xca\xfaV\xd0^\xc6\x7fQ\x989\x98\x04Yb-\xd3\xd2P\xbc^\x11\xb4,*k\xb1t\xa1\xca$\x1aE\x98\x0c\xa2\x8a#T\xd7\xf9\x96\xf0\xd8\xcc\t\xc8;Q\x84\xb59\x1e!\xcc\xe9\x05\xf0\xa6\xbd\xd9q|[\xa9n\x9d\xa4M\xe1hU\xb7\'\x0ci1\xdf\xb6D\xbfX\xa0\xe8\xff.\x9cp\xf0\x96]\x8d\x8f\xc1ib\xa1\xe2\x0f\x8d\x8f\xb96\xe1\xcc\n\xb1\xa5\xa8\x0e\xc6)\xb7\x08\xb4m\n\xca\xa9\xa2,\xd0\xbf\xb9a\x97\x12`[\\\xf4\x91\x1e\x9a\xf2Pa?G:ek\x96#nvG+\x06\xa8\xdcf\x86vr\xe1\x0f\xf2\xeab\xe3Y\xf7\xf8\xcdE\xf3U>\xdb\x9dv\x89\xcb\xe7\xc2\x17L\xebp]C\xcf\x9eTX\xc3\x7f\xfb\xc0-\xf5\x8d\xe8\xdb\x92nY\xf5pD9\x82\xc0\xdb|Q2\xfe\xdf\xef\xa1\xd1\xd4J\xf6\x00T\xe4\xfb\x84\x8bT\x1bV\xb4\xae\x8a\x045$7\x82&\xe9]\xb92\xe3\xad\xaa\x94\x1c\xbc5\x04\xed\xe2\x9fGUV\xbe\x1c\x8b\x00\x95W\xc2\xd6=I\x8e\xef\xfb\xc6\x06wP\xffL\xad\x8f\xe6\x12\xc1(\xf1(&\x8f\xfb\xf2\xdf\x1c\x91\xe8;^\xc6\x97Bw\xd9\xe2{_\x04W\x1e\x01\xc8\xaa#*\xbftt~\x82\x076\x9bX\xbd^o"G\x87[\x0f\xa4\xbfc\x87\xf6Od\x94\xea\'J@\x82\x1e\x05\xedz\x98S]\x0f\xae$\x94\x04\xfa\xef\xf2\x99\xfe\xe5\xf0\x10`\x9bn\xc6\xb7\x8ct\xf9mt\xd0$*r\xb6f\xdd\xba\xcc\x07\n\xe2\x0c_\xa7E\xc913\xf2$)\x87\xd4f\xe89U\xce.\xa5\xf0d]{\xb3\x97\x89\xd8\x00\xd8\xb3#\x18\xd5\xd06\xa0\x81\'\x17xf\x9c\xa4.\xd8\x03\x9fY\xa8\xa4U\x15XT\x85\xf2\x9b\xfb\x18j8\x1d\xec\xd1u\xb1\xadb"\xbe\xdb\xde;\xad\xf6qS\xe7B\xf71\xc3\xaaN.EaT\x1a\xc0p\xca\xe0\x9fv\x9a \x95;\x84,2\xfc}\xa6\xb7\xd7N\x87l\x04\xe6\xf7O\x13\xa9.m\xd0;hHO\xb07\xd6\x18\xd3q;\xd3\x830\xeb\xe0\x94`\xa8|\x0b\x85\xf9\x84\xfbd\x00\xae\x1d\x8b\xed\x04/D\x7f\x04\xe1\xdd\xcfx[\xca\xd7\xac\x04\xf7\xeev\xd5B13\x01\x03_u\x83\x08\xcbSn}\xf2y\xe7\x81\xc6\x07.\x9a\x9ar\xa0\xff\x07[\xae\x04\x93\xda#6\xe77\xe6U\x1a\x1c+\xbd$\xc2{hd\x86\xacn\xd9=\xe3b=q\x19o\x8c\xfb\xa5H\x18p\xb9%Z\x0b\xe6/\xb2\x9b|`:\xe5\xbb0\xc4\x99\x05\xa3\x16\x13\x99\xf4\x8a\x03\xc4\xcd\xb2\xd6\x96\xda\xd7$\x9a\xb86:\xccs\x1b\xfb\xa1\x1b\xde\x90V&\xe0W\x83Icd\xee0\x8e}\xc9\xfd\xd5\x8fs\x86\x01\xef\tg8\x1e\xca?\x14`\xdc\x14\x07P\xe3\xedo3.\xfc\xa6\xbf\x89\xd4\xe0\xa4r\xd0M\xf6\xe0\xdc<7\x1b\xfb\x1f\xac\x80\xcc\x9dpQf\x1a\xbcP\xea\x18L\x1d\xd4\n8\xd1\x01\x84\x9f\xd9Qm\xba<v\x0f\x1fE\xf0\xc6\xbde$\xb2sb\xdc\x93\xc6_\xbf\xd5\x01\xe2\xcb\xa82\xf8\xc5\x99\'\x9fO\xbd\xe7\xcb\xb7\x12C\xeb\xa8Xi\x89\x01\x88\xf0\xec\xaf\x8d\xec\x0e\x01\x0c\xf9\xf9\xb1\xb8\x11\xb0\xff\xa3N\x1dB\xf66\xcc\x9f\xb3L\xaf\x01\x82\xd2\xe2\xc1\r&g\xb8\nI\x9d\xcdY\x98\x88\xffs\xf6%\xbb@\xd7s\x1aV%\xd6Q\xc6\xbc\xa5d\x8e\x0c\x9b(i\xf4\x84\xb4\xabr\xcfq\x0e>\xb4\xd7/\xbe6\xc9\x84\xd3\xec\x9c\x99\x99\x84\x81\xf3\x90\xb7\x18\x82\xad*\xb7\xaag\x85\x92\\\xb5\x9d\xbc\xd0\x0cf\xaft\x08y\xcc\x95\xc9\x87%\xfdF\xbe+\x87\x91]\x86\xf6h\xe9\xec\xf3\x07\xf1)\xb7\xb2\xf4\xdf1\x83\xa9G\x1f\xd3D\xcd\xe9\xc2\xe2DI_!:B\xf2\x0clgOyXA\xb9\xb7\xc4/\xbc\xd5>O\xc3\xf1\x05\xe1a\x8fv\x12S,q\xa0\xdd\x0c\xcf\xe0\x84\x84\x88\xa6\\\x06\xb7\xe3\x1a\xaf\x10\x83\x87\x0eIX\xec\xd88H\x964Q\xbd\x81eTt\xe3O\r\xa8R\x94\xe7wZ\xd6}\x8fG\xa4\xc5\xf6\xd8\rf\xcb\xe9s(\x91\x0bH7\x1b$q\x89\xe7A\x00,\xb43\xad]\xa3\xf9\x82\xb4)A\xdcp\xfb\xae\x935\xf5e\xc9\x90\xa4:\xeb\x18\xab\xf0\xc7\x95\x121\xe1"\xa7J\x14\xd5\x8b\x99g\x87"\xf8j\x9dE\xb5\xe7Z\r\xed\xa0b#\x98\xce\x95z\xb6\xb1\x15\x16Y\xe0\x1b(\xd3\xbf_x1-PMA\x8c\xee|\xdb\xd6q(_\xc5vR\x87\x94\xa7\xa5\xe4\x9aLnb\xc6\x0e%\xea\x8e\x83*\xb5\x0bC E\xf7i\xd5\x1e4\xea\xfbV\xc0\xdf|@\x9a\xbe\xa8@\xf9\x89\xe7rB\xfb\xff\x1fs\xe9xH\xc6\x1c\xbc!3~1\xd5\x8f/~\x1d\x86i\xc7]K\xd8\x02m0R\x92\xc7\xb5O\x992\xaf\xabz\xff5\xb8\xd7mHT\xf9\x99\xdc\xf1\x13\x1fo\x92E*N]\xff\x04C\xc2\xb0\xf6\xb6\xba4\xe5n\xc4W\x11\xbd\xb3:\xd7\xa0\x95"*}\xbd(\xd5\xf1p,@}\x1b\xee\xe5A\xe2\xe0x \x9a\x01\xff+\x12}$\x88%N\xf0a\xda\x8b<\x13\xe6\xa7\xc6E\xddW^\xeaLa \xd0\xa1\ru\x15w\xe2\xba\xc19.\x87j\x03c\xc0\x84|\xf5M@\xcd\xce\xd0\x92\xae\x0fy9^\x89v5\x89k,\x01\x99\xc4\xfaA!(\xc0\xe4\x19O\xec\xdb\xe2\x87\x8a>D\'d\xe2\xd2\x90\xdcB\x0f^\xd0\x05EV\xb8\x1d~\xab\x04\xbb\x8f\x8cvQ\xd8\xdc\xd7<\xb7\xfe\xe4\x86G\x90\x9f0\xf8\xce\xfe.\x1e+\x98\x9a@\x83\xf9\xeb/\xee\xf79\x17\x8b\xaen\x11\xe6\xec\xdd\x13\xd6\x19u\xf3\xc8\x1e\x08\xf5"\xb7/\x80\x0e\xc8w\xf3f\x0f\xd8\xc9\xf2\xbb?\xad\xf7\x1fM1+^\x8d\nDU\xb2^R\x97\x17.e\xe1\xa6,@\x11\x14\x9c6\xb4V\xa2\x98\xe9\x1f\xcf\x98\xfe|\x8e'),
            [], True)
        server_4 = TlsRecord(bytearray(
            b'\x17\x03\x03\x02\x19\xe3\x9b\xf4\xbe\x8aJ\x86\xc8S\x9d\x07Y84\x1cP\xa4\x9f\xa1\xc7\x99\xcf\x90\x03\x04\xbc\xa1\xc4\xfc\x02\xd9*>\xf29\x80\xcc\xf6\x9f}\xa3"QB\xa6eY\xfbSZ\x1d\xf7}\x8bWX`\xa7\xaf\r(\x99\xcc\xe5\xb5/\xfe\xcf\x96\x91\x1e\xb5\xc0-T\xed\xbf\xa4\x86\xd6\xac)U\xaa\xb36H\xf05}\xc6A\xe9<\x93#O:\x12\xdb\x11\r\x08_\xeaL\xa2\xea*\xff\x12% 5\x92\xba\xad\x15\xe4Q\x8d\xc7b5\x08\x9c\xa3\xb7HIf9~\xdby\xc7\x96P\x1aq\x8et^\xb2@\xcb\xa3\x02\x12\xfb\x8d]\xfel\x1cF\xea\xab+\xa3\x0c\x94\x96\x93\x85\x84+\xbb4\x92\xd0\n\xd3q;\x9b\xde"\x1b\x98\x10\xfa\xbb\xcd.%0\xdb\x1e\x1a4\x150\xb5\x88\xe1\xbeh\xa1\xa6\xd5U\x9e\xeb\xa9\xaf\x11[\x97\xad\xb2\\9\xd8\x90\xfe\x80\x81\xad\xfd\x00\xaa\x8f\x07F\xb5\x15f\xfc\x9a\xf4\x10z\\\x1e& \x88\xfb\x1a\xcd\x16\xf0\x97\t\x82L;\xa9\xddc6\xf5*\x82h\x9c4\x90\xda\x8fG\xcf\xb4\xdc\xb0=\xcd\xce\x8aDR\xb5\xe3\xa3\x00\x08$q\xd9\xb6\xa17+@\'\xc2\x91\x96\x17v[6\xe6A\xb2\xc4^\xd1VG\xa9;Y\x94Ig\xa1\xd90;\r<i^\xbc\x10\xbbW\x8c-\xbd(%i\x1cc\xa2\x1c\xb9\x04g\xa9\x15\xd3ud\x0354\xde\xb9Q+,\x811UU_X\x91\xdb\xfd\xd9\x90\xe1plT\xec\xc8\x820\xfa:|\xa60\x9e\xe4\x9f\xfb\x15F\x7f\xbd\xe8|_S\xecG\x12\xf9\xa2\xf6B\xe7\xd7"\xa7\xb7\x1fT\x8eU\x86\xf4\xa7hqA\xea/\xed\xcd\xbc\xa29\xe2\xd9SG\x99\x8cn\x91Z\x9a\xbb3\x08\xaf)\xb9K\x15\x14\xc0\x00\xe3\n\xa4\xd9\x06Y\xd3IJl-\x04\xf5\xa2MOe\x96z!ho\xa4\x04YdO?\xbf\xc8\xa5\xeb\xd8"\xb2\xb5E\xf1\x18\xbc\x02\xd7}W\x83N\xa5\xde\xfes\xca\x1e\x18sZ="\xf6\x13\x13\x02K\x8c\xa5\xa3jxkF\xa1\xc0i\xa9$LQ+\xdao+\xaflsP,\xad5\x0b@U\xcb\xca\xa0\xa1xl\xbc_\xc6\x95\x8c.{\x1a0\xc1'),
            [], True)
        server_5 = TlsRecord(bytearray(
            b'\x17\x03\x03\x0057|\x86\xde\x07\xbc\xc1\xffX\x93NJ\xf1=V\xe0\xe7\x98}\x87\xb9Hv\x8c\x1a\x1f\xe7W\xb0\xfe\xab<\xd6NiR\x06\xa0\x1a\xb9\xbce\x95\x0c\x1e\xaaO\xdcj\xe0T\xb5\x1f'),
            [], True)

        client_1 = TlsRecord(bytearray(b"\x17\x03\x03\x00\x19\x05M@\xa1\xc0b>\xdfdv?C\x02\xf4\x0cY\xf21b\x1e\x92^Dd\'"),
                             [], False)
        client_2 = TlsRecord(bytearray(
            b'\x17\x03\x03\x005\x1fH\x12\x0b\xb1\xfc\xb8\t\xbb\x11=\xea\xbaE\x92\xfc~!\x80`B\xa3(\xd0I\x84i\x19\xaeK\x89\x83y`\x89bF_\xd8_\x93(\xbcs\xfb\xcf\xff\xc4\t\x98p\xe3\xf4'),
            [], False)

        server_app_1 = TlsRecord(bytearray(
            b'\x17\x03\x03\x01\x0c\xba\x8a\xc0Y\xd6\xa2\x9c\t\xe5\x9f\xc0\xef\xe1\xf8Ef\xac\xc6f\\>_\xc4\xfc\xb1\x8c\xd7g\x97[C\x9d\xfe.t\xece\xce\xb0\xed(\xf3%kc\x17r\xe4@d\x0e]\x81\xba"\x99q\x8d\xd0\x15>p\xfd\xc6\xf3\x8a\x1b\x17!\x8el\xe0\xaf+m\x1bW\x0c-G2ix\x00\xc1\x96 C.\x91\x17%#:\xa4\x08>\x1fU\xb9\xde\xdbJF,\xe6\xfd\x80\xc2\x1e\x88K\x9e\xfe\xd6\xfbS\xcf\xf7\xaa}\x1e\x1a\x00\xc0\xe8*\xaf\xea\x9d&\xe7\x11:\x95\x86-=P_\x14\xc6\xfe\xd0\xcb6\x9a\x80\xfb\x04\xd9\xbe\x08\xfa\xd3f\x9c\xe8\xf9\x9d\x08{\xdc!S@\x079\x88^\x89\xa9/\xe1sA`\x92\xcf\x9f\xde\xbe\xc9;2t\x85\xf8\xe0,\xc3yB \x7f\x12\xc6|\xffF\x14\\OE\xf1\xeb\xd3\xef\xb4KQ\x0b\xf2"\x9e\xd8\xc5\xaf+w\x1c\x9b\xaf6_+\x9c\xee\xf16\x9d\xc2w\x14\xd62M\x1dY\xf9\x01\x0bQ\xa5\n\x88\xbc\xa5\x8f\t\xe3\xf5\x83\xb0\xee\x97\xb6\xa3Xh\t?!\xa3\x1ePr\xe3'),
            [], True)
        server_app_2 = TlsRecord(bytearray(
            b"\x17\x03\x03\x01\x0c\xbe\x0e\x9a\xbc\x19\xda\xad\xf7\x11\xc3\x1c\xdb\x18\r6\x9ep\x9a6&Z\x84U\xbe&c_\x99\xce\xb0\x84\xcf\xce\xe4\xd9Xz\xad\xb4\x80\x9bL\xc4\xcd\xb9\x8d^\xaeaR\x04\x17\xbf)=I\x83&o\x08!\\\x18\x97>\x0eF9F@D\x01\x12\xdfX\xb9\x06CR\x8d\x02!x\xc9X!\'*\xc6\xd0\xfe^\x95\xe4\x02\x9a\xb3F(xNM\xf5\xddUh\x11\x85O\xf7|<y\xef\xe3\xfd\x83\xc9\xcf\x90{\x9a\x98\xee\x14\xfa\xcd\xdb\xb9\xccr\xc31wFb\xc9\x04p\xdf\xd0g[qn\x11\x88\xf9c\xaa\xc4\x9d\xe3\x83\xa6db\xfe\xe1\xf4\xd6U\xb5\x7f\xab\xa5\xb4u\xe5r}.&\x08d\x0e#c\xdd\xc3s\x84:mj\xa9\xae\xd3\xaf\xab\xa8n{U\xd4Q\x83\xe9`\xd5d\x9ew\x12\xf3\rSUP\xfc\xea\xc5\xe6aa\\G\xd30)\xfd_H\xdahc\xab\xf7\x1f|\x93\x89i\xb0\xee\xa7tsr^\xab\xda\xa8\x88\xad\xc2u\xae\xa0\x1c-)(\x18\xa7eu\\\x12@\t\x08Km\xfbH\xb1\xef"),
            [], True)

        client_app_1 = TlsRecord(
            bytearray(b'\x17\x03\x03\x00\x17\x98\x7f|\x1f\xc5I\xa9\x99N\x8c\xb7\xf2/\x9c[Lz\xfa\x82Wn`\xc0'), [], False)
        server_app_3 = TlsRecord(
            bytearray(b'\x17\x03\x03\x00\x17P|_u\x9d\xf3\xadoD\xcf)3\xe9\x1e .\xf8\x88\\c\xda:\x85'), [], True)

        self.assertEqual(self.tls_1_3_aes_128_ccm_decryptor.decrypt(server_1, True),
                         b'\x08\x00\x00\x08\x00\x06\x00\x1c\x00\x02@\x01\x16')
        self.assertEqual(self.tls_1_3_aes_128_ccm_decryptor.decrypt(server_2, True),
                         b'\r\x00\x00-\x00\x00*\x00\r\x00"\x00 \x04\x01\x08\t\x08\x04\x04\x03\x08\x07\x05\x01\x08\n\x08\x05\x05\x03\x08\x08\x06\x01\x08\x0b\x08\x06\x06\x03\x02\x01\x02\x03\x00\x05\x00\x00\x16')
        self.assertEqual(self.tls_1_3_aes_128_ccm_decryptor.decrypt(server_3, True),
                         b'\x0b\x00\x05\xa0\x00\x00\x05\x9c\x00\x05\x970\x82\x05\x930\x82\x03{\xa0\x03\x02\x01\x02\x02\x14\x1aY\xdfW$L\x97V\xf9\xe8\\3\xaa\xf5\x81\xbf\xc08\xf3E0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\x000Y1\x0b0\t\x06\x03U\x04\x06\x13\x02AU1\x130\x11\x06\x03U\x04\x08\x0c\nSome-State1!0\x1f\x06\x03U\x04\n\x0c\x18Internet Widgits Pty Ltd1\x120\x10\x06\x03U\x04\x03\x0c\tlocalhost0\x1e\x17\r230926104549Z\x17\r240925104549Z0Y1\x0b0\t\x06\x03U\x04\x06\x13\x02AU1\x130\x11\x06\x03U\x04\x08\x0c\nSome-State1!0\x1f\x06\x03U\x04\n\x0c\x18Internet Widgits Pty Ltd1\x120\x10\x06\x03U\x04\x03\x0c\tlocalhost0\x82\x02"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\x00\x03\x82\x02\x0f\x000\x82\x02\n\x02\x82\x02\x01\x00\xe1\xd5\x88\x9e\xcbhEC\xbf\xe2x\xc4\xef\xd9\xb6A\x08>\xe2\xe4A\xb94\xd3\x06#\xd9\xf6~\x95\x1a9h-j\x8d\xd3_\xef\xb1\x19l\xbfO\xa3\xc8\xf5t2\\+\xee$\xbb\xb8EF\xc9\xf5`\xaeJhF-\xbd\r\xa9E\t\xceS\t\xf9\xc6By?eT\x9420\xd5\xfd\x19\x12~\xa8\x8a\x92\xaf\xf2U\xba\x1b!F\x81\tM\\\xfd|\xc6\x7f\xfb\xb2\xe3\xf1\xfcB\x1frn:8\xf6\x15\x1e\xba\x0e2\xfe\xd0\x95u=\x83\x1f\x1dx\xe7\x1a\xce\xe8\xf8<\x90\x92e\xd5B\xbeo\xfc\x9f;\xfe\x97\x19\xc5\x04\xe5\xf77@\x94\xbd\x08\x7f\xbe\x9e\x11\xc5\x96\xe6\xb0\xfa\\l\xd6\xf2\\.\x03f\x7f\x19\x1b\xaf1\xef\xcc\xba}\x10aL3 \xef\xde\xf2\xcaij\xc0\xa5\x15\x8ci6\xe7\xaa\xea!\xf8q)\x9c\x9ea\x0fuj\x07\xe2$\xb4R\xf0\x00:\xf0\x1b\x15\x1c;\x81\xc6/\'\xca\xfc\x97*7\xcb\x16*\xfc\xbeJ\xfc\xec\xe7\xf6\x14ej\x0582v6\xf3\x0b1\xdb\xad#\x91^\xa9\xf1q\x03\x16\xaf\xfc\xca\x88\xcc4\xe2\x862\xb6\x80\x1b)\x858\x16\t\x145\x8c\xa6\xb7\x85\xfa`\xd9\x8d\xf9\\\xfdx\xfbA\xb8Z\x9c\xaa\xb0\x9b\x85\x80\xf9$z\xa4\x8f\xa0\xd7\x94\x94\xa5<\xa7\xb6\xac\xde\xa8n\x99\xa5\xa6w\x0e+$G=DY\x98/\x0c\xa6:\xd5:em\\\xb2"\x97\xbe6\x96\x04P\n\xb3\xe0&?\x97\xe7\x03\xa2J\x97\x87qo(pHsu\x18\x88\xf1\x89]\x04\xb0\xa3\xb51\x1fa{\x030\xe3\xc3\xe88\xc4\xcch\x81\x9d\x0c\x15\x96\x93ynx}\xbd\xbdM\xfa3\xdd\xc9\x0f\x00\xc7pxIrs\xa9U\xc0.\x81C\xb2\t\xd4\xab\xbf\xde\xbeo\xee\x8a\xa73\x97\xa0_\xe1\xadreN\xf0\xd4]\xee\xc0\x0c\x06\xbaB%:I\x96\x92~\xbb\xf0B7\xd1\x16$FS\xc1\xc1kT\xd4V\xb1\xe1\xe6\xffs\xf5\xad\xa7;D\xae\xb5\xa44\x1e\xf5V \xd5q\xe3\xcfj\xca%\xe8\xd1\x9ev_{\rCW\x02\x03\x01\x00\x01\xa3S0Q0\x1d\x06\x03U\x1d\x0e\x04\x16\x04\x14j\\\xd67\x97r`\xf0\xc2|\xb5|\xf5y\xa1Qy\x03E\x180\x1f\x06\x03U\x1d#\x04\x180\x16\x80\x14j\\\xd67\x97r`\xf0\xc2|\xb5|\xf5y\xa1Qy\x03E\x180\x0f\x06\x03U\x1d\x13\x01\x01\xff\x04\x050\x03\x01\x01\xff0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\x00\x03\x82\x02\x01\x00s\xe7\xbc\xec\xd7\xbf\x96_r\x94\xdd\xf0\x1f\xea\x9d\xbe%\x1dn\xeb3\xce\xb9}+\xe5\xadk\xe1\x99\x10\x95\xc65\x9f]\xb2\x19O\x86u{\x191"\x90/ \x88\xa70\x13\xe3\x1a\x92 \xf8\x9b\xf7\x88g\x89\xd6\xdc5\xb6C~\x91\xbdO\xe6&\xbb\xec\xab#\xf8\xce8\xb6n\x9f\xe0\xf4\xb2\xd0\xfa\xb7T4\r\xf0\xd8\x8c\x13\xe8\x199\xd0a\xbb#\n\xfe\xb1/\xe5\xb0\x9dT`\xfa\x94#~\xbe3~B\x04@o.R\xba\x91<\xd0\xbc\xae,\x0b`ZN{\x06\x04\xce\x11Kb\x95\x8a>\xd4\xd1$\xde\xba\x8dA\tV\xb5M\xc8\xaa\x98\x03\x0er\x02\x07\x8fF\xa7\xd1=\xc7\x85g9\x82\xba\xfaJ\xe9m\xd6\xff\xa8F\nYO\nng*\x84\xebKz\xb67\x8c@u\xebC \x96L\xc9Lv\xb1:z\xa8\xe9pN\x98\xf8\xab\x11?\x96\x86A2\x90\xb5\xf5\x9e\x88A87>\xbb\xd1H\xc13P\xa8\xd0H\x8b8P-sK\xf08\x8132\xdc_\xca\x92\xbd\x9f\xdc\x8d\x84o\xc7\x19\xd2\xfbG\xbe\x16_\x96Ev\xba\x82\xcb\xe2\xe8\xc6+9\x1b$ \xb3\xc2bFD\x8a\xce\xd2\xb83t\x1c\xbe^\xa3\xfc\x83\xb7\t\xbe\xda\x81\x81g6(v\xd7\xdfU\x98\xfd@fL\xdb\xe7\xdc\xaf\xbb\xac\xe0yM\xe5\\\'d\xb8x\xf6\xf3\x14\xcet^\xf5\x19t\xa5~\xa5\xc2+I\xfc\x0ec\xd8:/\xb6\x02\xe4\xa3\x13\xa1\x7fbo\xba\xa6m\xb3\xe5\x87YS\xea\xcb\x9b\x0fa\xf4\xd1\x93^t\x06\x9fLJ\x9b%\x0c\x93G\xbcz\x89\x1e\x08\x02\xb5\x99\xe8\xfb\xfc[\xcb\xb0\x1eA<\x80\xb6\xcd\xb2\x02\xbf\xb1ig\xa4\xf0\x82\xac\x82\xba\x85e\xd9-\r\x9d\xeb\x12@p\xa6v\xc5\x94\xf3}\xafV\x1e*\x9c\x99\xbdy\xa2{\xcc\xdb\xc0\x85\xdd\x00\xda\xb4\x8c1\xb5s\x03\x11qk\xcf\xa8\x06\xbf\xda&b\x03R\xde\xaf\xadK\xb9\x1f\xc8F\xcc\xbb\xd3\xf5\x10\x90n\t\x0e)\xc3\xa9V\x9f\xd5\xf8*\xfc\x9fv\xb5\xf7\x18\x90w\xae\xcfc\x1a\x00\x00\x16')
        self.assertEqual(self.tls_1_3_aes_128_ccm_decryptor.decrypt(server_4, True),
                         b'\x0f\x00\x02\x04\x08\x04\x02\x003l\xe4\x84\t\xb5Z\x07\x18\xb9\xce\x92\xa1]D\xcc\x0e\xab\x94\x93\xb8\xb4\xc3\xba\x83\x86\x82\xac\xc5\xcc\x90\xe8\xaa\xa9\xc4\xb3\x85\xac\xa0\xe2\xf5\n\xdb\x97d\x9a\xa7\x02.\xad \xb2F\xd6^\xdb.Lz1\xf9\x83=C\x04:G\xea[\xcf9\xc53:\x8a\x81{\xd1j\xfc_\x01\x1c\xd3(\x01\x9b\xa90j\xe0s\xf6\x0fT\x150\xc0\xda\x7f\xaa\xf1\x05::\x0b\xf9\xdf\xcapF\xe5\xf3\xe6\xe5\x89@]\xa4o\x1d\x88}\xee\xc9\xf5\xde\x19\xf8:\xfa\x82\x99\xee\r\xd5\xa0\xc5\x87\x9c\xbcr\xe1\xa6\xc8R{*\xdf\xaf\x0c\x04\x0b\xd0\r\x01;\xdbx\xc6\x8b\x05\x96\xb4^\xe8\xe0_\x8cT\t\x9es\np\xce-\xdf&\xa0\xed<t\x9b\xcc\xb3\x1f\xe2\xeb\xe9.\xb2k\xfcU\xde\xd2\xab\xb1\xb79\xde\x80p\x1c\x06\xae\xdeh\x88\x8c\xdc\x0f\x82M\x85\x05\xb0\xba\x02+j\x84_\x1b\x9bS\t\x9c\x88!E\xb3\x84\re\x864\xaeY\xc8e>\xdb\xda\xbfB]\xce\xdf\xd2.\xa6#g\xba\xe2\xf4\xc8\xe4\n$\xb5\x9e\x90\x97\xff\xea\x90\x02\xc6\x81\x14\xcaS\xad\xfd\xd7PC\x8b\x96\xb1\x9a\x9c\xf9\x8eX\xa7\xd6\xb4\xed\x97\xb0\xab\xf2\xe9#\x95\xf1\xc1\xbd\xbeVj\x8ef\x1f\x0f\x9a\xd9$\xf5p\xea\xab\xfc%\x9f\x94V\xc6\xb7<p\x19\x8f\x87.\x92\xdeJ\x8bl\xaf\xd1\xf7\x1bW\xa7\xac!"\xab\xec!\xe9D\xe3\x8d\xba\xdbPB^J\x17\xc5\xca=\x0c\x82|bJ\x05\xb2\x91\xd8\x82\x8f!no\xeb\t\xc5\xee#\xde\xbaYc\xf1X\xc7\xcc\xf6\xdf7\xf5\x0b.\x8a\xdb\xe6\xd0\x05\x7f26\xb9\xa9\xdf\x13K\xafaW\xc30m3\xe1\xb2\x07\xb28}\xe6*-yc&\x8e\x82\x8b4\xbcq\xa0\x90G\x10\x06\xcc\xc6\xf9\xff\x12\xed\x9c\x14j\x119\xddb\xb2\xbc\xe3B\x0b\x12w\x95\\\x17\xfb\x86+\x97\xbcE\x19\xac{\'\xdfjO\xca\x19dg"`5k\xab\x05\x16@\x9fy4\\\xa5\x96\x11\xbd?\x87\x90\x9eN\n\x92\xc5\x84\xb6:\'\xb2l\x0c\x8e\xe1\xed\x19\xe3\x16')
        self.assertEqual(self.tls_1_3_aes_128_ccm_decryptor.decrypt(server_5, True),
                         b'\x14\x00\x00 T\x1b\x1bz\xd1\xd5\x8e\x15\x8e\t\x12\x8cx\x06\x86\xecz\x89\x109\x86\xe4L8#$\x9fo\xce@\x85y\x16')

        self.tls_1_3_aes_128_ccm_decryptor.update_keys(True)

        self.assertEqual(self.tls_1_3_aes_128_ccm_decryptor.decrypt(client_1, False),
                         b'\x0b\x00\x00\x04\x00\x00\x00\x00\x16')
        self.assertEqual(self.tls_1_3_aes_128_ccm_decryptor.decrypt(client_2, False),
                         b'\x14\x00\x00 \xdcOO\xecsjj\x0fq\xe9\n\x9eSh\xdd\xcd\xc1\xfb\xa7P2\xf9\xa6\xe6\x80\x12\xf5\x9f\xf0[\xfa\xa9\x16')

        self.tls_1_3_aes_128_ccm_decryptor.update_keys(False)

        self.assertEqual(self.tls_1_3_aes_128_ccm_decryptor.decrypt(server_app_1, True),
                         b'\x04\x00\x00\xf7\x00\x00T`\xe4nX,\x04}\xdd3\x86\x00\xe6\x81\xb1\x0c\xe4Cs\xed\x82\x04\x95\xcc]\xb1K<k$Zl\xe2\xdff\xb8\xc0\xbd .\xae\x9c\xd2\xd4]\x00\xb0W\xdd\x06\xed\x8b\x8a\x9b\x80/&\x97\xa96\xa4\xa9/hG\xe1\xe9-\x7f1\x85\x9bG\x9cJ\xcd\xe8\xf0\x85){f\x85\xab;[\x00Q \xfc\x17\xd2\x00\x02\xa0\xe4\xfe\x9d\xad*r\xec\x1a\xac\x03\xadD\xf6O\xd9h[\xd4\x8b\x03[@\xaa\xa9\xb3\x0bK\xa8h\x15\x8c\x9e\xa5\x10@\x8f\xedV&\xb4\xc3\x00\x96j+\xe5\x16|\xfe=\x87\xb2LlB\xbe\xa7\xf8\xf3\xf8\xc8f\x1c\xac"\xb5\x80\xf0/\xf6FH\xf3\x8c\xbe\xab\x97\xf1\x80\x9a\xbb\xe7t\x0f9s\x98v\x8b\x05\xe0[\xe4\xc5\xb5\xbd\xcfz\xe3\xd4\x84d\xef\xdd\'Nc\xf2\x18\xe8z\xc9#\xe87\x82m\xdf\xa1!9h\xe35;\xd5+\x8a\xdc\xe0\xf3\xabs~c\x8c\x18w\xc3\xab#_H\x17m\x04\x161\x00\x00\x16')
        self.assertEqual(self.tls_1_3_aes_128_ccm_decryptor.decrypt(server_app_2, True),
                         b'\x04\x00\x00\xf7\x00\x00T`\x9d]}\xbd\x04\xcbS\xc6\xb2\x00\xe6\x81\xb1\x0c\xe4Cs\xed\x82\x04\x95\xcc]\xb1K<k\xc9XC\xf1\x19\\\x14\xc4\xfa{\xf1\x85\xb6\xe7\x80\x07\x00\xb0\xb8\x0c\x8a^+\x96\xc1\x1az\xcd\xff\xda\xe1x\xb6[\x80\xa9\x93\xe1\xd7\x8d\tG\xa7%\xc7\xbe\xbc\x064\x10\xeb\xd1\xfb\xc7\xdc\xde\xb6|\xdan\xb9\xaf\x06\x9cv\x93F\xe7\xe1\xc0\xdf6\xc8O\xbd\xee\t\xacQ\x8e\xb5\x99\x89\xefm\x83,\xf8\xbfi\x8f]\x18\x011\x9bS\x12\xad:\x87;M{\x88\xd5\xdf!EM\x82\xf6\x1e\x82\x11\xa3\x89\xc2\xdd\xa5]\xd6\xe1\x0bg\x91\x1b`P(\xf4\xe4j\xc3\xdenj\xc1\xf8\xff\x13?\xfc\xf1\xd3\xfd"\xf8X\x90\x80\xf4\x9a7\xb9\x0c\xe6\xe4\xc4/\x11\xf7\xa9\x15f\x08\x89B\x8a\x80=<l\xfaOh\xe2=\x1a\x9c\x14\x0cXa\xaf\xa8\xddVUP\x8f\x1a9P\x16\xb37ZGya\x1b\x15\xd5`\r\xc9\x8d\xf8L\xa9\x19\xbc)\x00\x00\x16')

        self.assertEqual(self.tls_1_3_aes_128_ccm_decryptor.decrypt(client_app_1, False), b'Lorem\n\x17')
        self.assertEqual(self.tls_1_3_aes_128_ccm_decryptor.decrypt(server_app_3, True), b'Lorem\n\x17')

    def test_aes_256_gcm(self):
        server_1 = TlsRecord(
            bytearray(b'\x17\x03\x03\x00\x17\xd199O\xbe\xee\xb5\xaf(\x82#%3\xbd\x9a\xc0\xfe\x822\xdb@\x1du'), [], True)
        server_2 = TlsRecord(bytearray(
            b'\x17\x03\x03\x03\x8dF5w\xd9\xb2\x19\x91\x08\x07XoI\xd8:s0_\xb7\\\xa8\x9b,Xe\xda!\x105R\\\xf9\xe6W\xc3m{e\xac\xaa-\xc1\x80;\x88r\xa3{L\xeeX\'\x1b\xfe\xff\x1c<\xfeaC\xd1\xaa\x1dp\xdc\x90*\xf23\x90\x1b\xf7\xb0\x08L\xb3\xfc\xc6\xb4QS\x11b\x8c(\xd24#\xc06\x93\x0f8c\xca\x1b\xdc\xc6\\\xdfuoC\x0b\xab\xf2)\xaa@h\xf4\xd4\x8b\x04N2\xd3\xd6\x1f\xa6%\x14\xc0\xa1\xc6\xf2\xe8-\x0c?\x19N\x8b\xcb\xa5\x1b@\x99H\xd4\x15\xc9\xb9Mf\xa6\xc1\xe1\xb25\xd8L\x93\x17x\xe5\x19\x85\xd7\xadQZ\x13B\x12*ga\xc4\x90&\x1a\xec\x0f\x96\xf6\xb2\x8f\t\xd3n>\xfd-\xf1\xc5\x93\xf2\xb7\xeb\x0c\xe7\xc7f\x880\x82\xfa\\\x12\xb4&\xa0\xeb\xa5\xb6\x9a\x1c\xa66\xa8e#y\x11\x92>\t\x06Z\xc9\xd3sA\x84y\x16\x80\xcf\xb2<a\xb1d\xdc\xb9}@\xa4\xdcQ2I\x03&}\x94\xcf&N\x02\x166\t\xe9*\x8f#\xdb#\xbd@mq\xe1*\xe4\x15\xc6\x8c?N\\%$.\xbe\xdc\xab\x10\xc8\x1d\xe1\x7fN\xda8L\xb9a\xa9\x12\x8a{s7\xef\xc9{J:\xd8\xb0Lj\xd8\x93\xfa\xd7\xea\xa4\x00\xb6\xa2\xad\xb1\x18\xda\xc1Lq\x07j\x11\xbd\x1f=e\xc3\xd5/\xa0\xcc\xf2\xa0\xb0\xc5\x99\x08.\x06\x9e\x89\x8d\xd6\x8dO\xd9\xe6*e1\xa1\xd4\x8c~\xf7\xad\x15\xf8\x0e+\x06>\xc3\x8d=\xb7\xc6\xd2\xa4\x05\xc5\xa3%\x17K\xc7\xbb\x8e\x823\xe3\'WZ\xe7A\xf3Dh<\xf8\xdc\x99\xb9\x0e\x9e\xac\xd6\xed\xa3]\xc7\xec\x0b\xc2y\xb3(\x94z\xafI\xe3\x82\xd9L:h\x8f\xa2\x0c/n\x98\xa2!<\x8f\xed\x1dVs"m\xd3\xd6\xa5kUy:\x10\x01\xd4\x95\x1b\xce\xcb\x80b\xa5\x19*}\xd2\xf3\x9a^Zh:|\xafx%F\xee\xaf)\xb9\t\x9ci\x93\xc0q\x8edv\x96\x18\xb7g\xa96.\x88/|3@\x02\xe6\xfc\xb3g\xbe\xb7\xa0\x02b\xa0\x848\xe2{\x81\xd0\x80\xf9vC\x86{[\x10\x1d6H\xc5\x12\x9bR\xab\xfe\x07\xc2\xbd\x94(\xc1\x10\x059C=x\x1d\xac(\x90\xe0E\xb8\xad\xa1H\xc1h\xef/\xa2.\x00\xc3\xf6K\x01\x06\x94\x9b=\xdf\xdc\x9f9\xefq\xdc\xa7\x820S\xc86XS\x01\xd9\xc0\xe2\x95\xd32#\x1b3}\xff\xeb\xd4"\x02;4\x8b\x10\x8e\x1f\xa2\x9b\x7fI\xc3S\xd7`\xe3\xc3\xb1\xe6\xef\x13\xb2/\xd3\x99;\xe4\xd4y\x7f\x1f\xa6o\xae\xf5\xc9\xf8\xbcs\xda:\x1a\xe0`\x8b\xba\x8b\xac\x03?;\x88\xd4D\x8e\x02\xe4\xfc2\xdc\xdbOk\tPuZ(`Y\n\xbe\x05\x9d\x1e\x01\x9a(\xb3\x07\x9a(X\xa5\x1e\x82eX\x19yPACQcyCAR\xa6\xb9%\xc46\xa7\x10\xd8\x81*ml\n\xdc,0Um*`\xb0\xdb\xd7\xd4\xca\x1b\x8f>b\xf2\\r\xf5#\xa7g|\xa6e\xbf\xd6\xaeLL\xcfv\xe4;\xe1^3r\xae\xdb\xc7\xdab\xc8\x04\xe2\x8eY\x00\t\xe6\x87|#RZ\x86\xa7k\xfep$\xe3\xce\xe7\x85K\xa56fQ\x1b\x83\xf8\x05\xb8\xe1\xc7\x91\xc7+\xfe\xfd\xcc^J\xe3\x8d#\x9a\t\xee<\x1e\xb5\xde\xec\xbd\xd6\xf2\xdc\x95\x8bF\xackq\x9dX7n\xf2g\x82*\x1fp|\r\xd7}\x87\xc1b\x14\x95\xb8c\xd4Lh\xe5\x13\x02\x92d\x91\xce\x86>\x19\x18\xce}\x92\xc7\xd8\xa8\xea\xfc\x1c\xdd\xec\x12-L\x19\x9bk\x8dH\xda*\xb5\xf7\xf7P\x9a\xd6\xf7\x89\x963\x17\xb9\x1f\xd2r\xe5Ca\xc7\x1aa\xe9\x97*D\x0ct\x90\x95\xdf\x81\xee)\\\xb2\x88= !F'),
            [], True)
        server_3 = TlsRecord(bytearray(
            b'\x17\x03\x03\x01\x19\x85\xbb\xaa\xbc\xb8\x04"\xb7\xbc \xdd;\x01\x08\xb4\xdd\x1c\xaa4\xe4R\x05u\xa6:\xcc\xc9\x06\xa7\xed\xff\xd4\xfe\xc9\xa2\xd2\r\xb4I\xe9\xc1\x15\xd2q\xed2\x89\x89\xe2\xa8\x0e\x7f\xe2\x9d\x8fxD\xe8{\x98\xf8\xf2\x99\xa5\xa0\xd6q\xa6|#\xd7v>\x84\x95\xbdN\x83Fp\xa3\x11&\x9e\xf9\xe0/\xa8\r\xa4.\xf3\xc0\x94o\x86o\xc4%\xf7y$\tP\x86\x8b\xef\xa3\xc5\xba\xe7\x13\xe4\xbb\x86\xfbaE.\xb2\xea\xf8\xdf\x85\x1e`+\xaa\x83\xff)d\x1b\xe6(\x82hd\x9e\x0b\xc3\x8b\x81\xda\xa7\x83J\xf7\xda\xb5\x11\x00\xbe6\x7f\xd7\xd4C\xec\x11\x9c\x9bjW\x186\xe1\xd6\xb48}\x91k\x9d]20r\xa1\xb9\x89\xe4wU\xa9\x06\xaf\x93\x9cC;\xdf_\xbd\x1aENza"\xc2\xe9\x824Z\x1a\xce\xf8\xc4_f6\xb2\xd7\x81\xeaVS\x92\xf2Sa\xf9+\x04y\xcf\xb6KJB*\xf0\xd3\xfe\xfdc\xfb\xb7\xc3\xd7\xed\xba\x84%\xbc\xf0\x8b3\xaa;p6k\xe5W\x932\x9cRR\xf6\x1a\xd3O\xd9\xb7\x90x\x11\x85\xab^\xe8Vj\x0et\xd5`e'),
            [], True)
        server_4 = TlsRecord(bytearray(
            b"\x17\x03\x03\x00E\x19DBp\xaaE\xe1\xb6\xf9\x8f\xe4\xb5m\x1e\xb5\x0cG\xaacn\x17\x9bK\xfe\xdbx\xb6Z\x97ZU!\x80\xc7^Y\xb4\x19\xabd\xd4g\xa4\xc3\'_\xc4\x17V$N\xf6\xb2\xa0\xbf\x14g+\xa1\xcaX\xd0\x86I\xa6\xf5\xbb\xbf\xc5"),
            [], True)

        self.tls_1_3_aes_128_gcm_decryptor.update_keys(True)

        client_1 = TlsRecord(bytearray(
            b'\x17\x03\x03\x00E\xe2$\xd8\x90~2\xb7\xfbI\t)\x97=\xda\x9f\x96\x13\xbe\x8e\x04\x07\xed\x00\x0e>\xd6v5\x9b\xc2\xd3r\x9f\x00\xc3\xe5I2\xdbS\x98\xa1HbFb\xfe$\x8b\xc8b\x8f\xdf\xe7\xc3\xfe\xfa"D\x14\x92\xad!\xcd@\xa94\x0c\x1f'),
            [], False)

        self.tls_1_3_aes_128_gcm_decryptor.update_keys(False)

        server_app_1 = TlsRecord(bytearray(
            b'\x17\x03\x03\x00\xfa=\xect^\xbb\x9c\x12\xa7|\xd0\x9f\x13\x17~\xbd\xda#\xf1i\x92iX\x89\xb0\xfaBr4\xaa\xe6\x90\x04\xc3_\xb0\xbfF\xb12{\x9d\xcb\x0c5\xb5\x88\x13\xb5\x0b\x12"\x8c\xa69\x1fq9\xab\x01\xf61\xea\x8a\xaf\\\x98\xe1\x12\x16\xb28*\xd4\\\x08J\xd9<\x04K\xbbG\x1f\xec\xbev\x1cv\x17g\xd2\xf3\xb5C@\x80\x8d(\xee\x17\t\x84X\x1b\x91u\x91{^5{l\xbfL\x9d\xed\x9e\xae\xc0\xc5rp#R\x92\xf7\xd7\xf8\xd2\x11\xb0\xb7x\x97\x8a\x99\x1aq\xccNAg\x06|\xda\t\x12t\xf7\xcf\xbeg\xb6\xde\x9eK{\xca\x0e\x9c\xa1\x80/\xb4H\x98&\xe3\xc2\x884):]JUF@\x01\xd2mI\x06\xe3\xcd\x95X30\x0f\x95\x98\xa7\xc3\xa8\x82S\xaa\xa2\xeadvUL\x93\xe9=\t\x9e\x19S\xfe*C\\\x89\x87\x06d\xf1\xb6w\x90\\\xc0\xce\xdb\x95\xb8\x14\x04\xda\xdc\x0f\\\t\x98K%\xb3\xe6\xf9\xfe\x05G>\xe8\x1a\'\x19'),
            [], True)
        server_app_2 = TlsRecord(bytearray(
            b'\x17\x03\x03\x00\xfa]Xu\x1aJ|\x1a)0\xaa\x90\xfc\xb6`\x15h\xac\xdb1\xa1\xed:t^\xa3\xe5\xefA\xfc\x9b\x01\xeed\x0bE\xde\xe4\xf5\xdb\xd5\x16\xfd\xd4x{\x88\x95\xba\xb0\xd3Lo\xa3|\xf3\x9ceS\x1a\xd8s\xb7\xc9\xd6"\x0e\x9a8P/\xf4Z\x1b\xb1\xb8\xc2&!T\x9dS\xe7f\x9f!\xb8B\xda\x01\xf2\x9d-\t\xbf\xd3\xab~U\'c&\x81\xdb\x8c\x81(\x93>J4i\xc8B/\xc1 \x83\x883\x12\x99\xa5=\x9b\xc4\x11kU\x9fw\xa4\x7fhH\xae\xb8p\xc2\xb3\x8c\xb3\xbe\xd1]\x8dR#\\M(6\x8b\xca\xf5\xed\x1b\x9a\xbfv\xbe\x98\x98\xcbIP\xb8\xcf\xcc\xccr\xdd\x12x\xf2\x88\x8c\x87\x13\xa0\x06\x01\xec\x91\xf1|\\0\xe2\xad\xc9\xc5\r=\xb3C\x83\x1f\xf0\x8d\xab#r\xa0\xe4s\xaa/\xa5zQ\xfd\xb4\x8f\xf1:a\xb6n\x16\xaf(\x04%+UR_\x82\xdf\xce\x04\x92\x8bhD\xd7\x91M0\x03\x92\x11\x00\xb2m\x92\xfc\xcd\x00\x01'),
            [], True)

        client_app_1 = TlsRecord(bytearray(
            b'\x17\x03\x03\x00\x17\xcb\x1a\xad1n\x08\x94\xd7\xcaJ\x9e\xe4\x10X\x16\xe3%H\x83\xd3\xa6\x02\xff'), [],
            False)
        server_app_3 = TlsRecord(
            bytearray(b'\x17\x03\x03\x00\x17\xf1X\xa83.\x15\xaa\xfd\x146\x8d]\r\x18TA}\xb7X\xb1!\xd6V'), [], True)

        self.assertEqual(self.tls_1_3_aes_256_gcm_decryptor.decrypt(server_1, True), b'\x08\x00\x00\x02\x00\x00\x16')
        self.assertEqual(self.tls_1_3_aes_256_gcm_decryptor.decrypt(server_2, True),
                         b'\x0b\x00\x03x\x00\x00\x03t\x00\x03o0\x82\x03k0\x82\x02S\xa0\x03\x02\x01\x02\x02\x14zC\xc1\xae\xee\x84$\xbc\xe2\x95\xd9h\xc5\x15V\xcc\xd3\xf8\x1e\x130\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\x000E1\x0b0\t\x06\x03U\x04\x06\x13\x02AU1\x130\x11\x06\x03U\x04\x08\x0c\nSome-State1!0\x1f\x06\x03U\x04\n\x0c\x18Internet Widgits Pty Ltd0\x1e\x17\r230926081013Z\x17\r240925081013Z0E1\x0b0\t\x06\x03U\x04\x06\x13\x02AU1\x130\x11\x06\x03U\x04\x08\x0c\nSome-State1!0\x1f\x06\x03U\x04\n\x0c\x18Internet Widgits Pty Ltd0\x82\x01"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x000\x82\x01\n\x02\x82\x01\x01\x00\xdb\x85\xeb2^\xa7\x02y5\xf1}=\xad\xdf\x0c\xf6\xcd\xbc\x1e\xfe\x01\x195A~wI;1\xbe\xc11?\x06\xca\xb2\xac\xc7\xa1\xba\xb6\xe0\xd5\xb0+_\xa2i\xc4y\x97\x17\xcc&\xa4\x0cv\x8c\xb8\xb1\xbc\x89\x1e\xf1f_Z\xa1\x00\x0c\x01Hm\xae\xe6\x00K\xa2\xabj:6\xa7\x02`\xef\xeb\x95C\xc4\xa0\x1eH~]\xf6\xf9\xc5{\xbc\xa3\x9c\xd6\x9e\xf6\x88G\xbd\xa5\xa1\\\xa5\xdd>\xec\xc6\x03\x86\x101\x12\x1e)\xb7\xbdc\xdc(\xfe\xc4%\x14i3u\xe1\x93\xa4<G\x11\xf0\xe1\xd5\xe6\xdd\x14)\xf8\xc8\xa6\xd6S\xa0\xf5<\x1ep~\x1cD\x8c] P\xd8%t.\x85I\x9b\xd2\xdb\x14%wb\xfa\xd3\xd9\xdd\xcf\x05\'(\x90\xbdY\x02\x1c\x18\x7f\xdfr\xc1dYr\x15\xe4\n\xd4\xdb\x1c\xc9G\xc7\xea\xe4\x1a\xc9\x12L\xeav.\xcb&z\t$\xa1\xbf\xc8t\xdbM\xc6+\xd26pC\xbey\xe6\x16rVn\xe9\x97\x9d[#dT\xa4\x91XR\xd8\xd5$E\x02\x03\x01\x00\x01\xa3S0Q0\x1d\x06\x03U\x1d\x0e\x04\x16\x04\x14\xdf3\xd5\xd9\xec\xd6\xab\xb0Fc\xd6t\\\xbdl\xb4l\x00\xf6x0\x1f\x06\x03U\x1d#\x04\x180\x16\x80\x14\xdf3\xd5\xd9\xec\xd6\xab\xb0Fc\xd6t\\\xbdl\xb4l\x00\xf6x0\x0f\x06\x03U\x1d\x13\x01\x01\xff\x04\x050\x03\x01\x01\xff0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x002IA\xe21\x9a\xcaY\xc4\xba\xf4\xd6\xbe><\xcf\x81f\xac\x03\x03\xba\n<\xcc\xd0e\xf2\x07\xd4\xe3\x11u\x02*\x02\xf6u\x14n\xd7qz\xcd\x0ck\xbf;O\x8cA\xb0R\x8a\x86\xceg3hv.\x12\xa1\xb7\xfa{\xcf\x01qz\x95rn\xbb\x83B[~\x1110\xe7\xa9Z-\x9b\xbdR\x12\xa0mt\xf8iHL\xaa\x05jI\xc6\n\x84\xc9\xfbK\x8c\xd2\xe1\xe2s\xa1L\xe4J\x9d\xe6\xfeM\x82_\xcd\xe4s\'I\xd9\xf7\xca0\x84\xaa\xef&\xd5\xd6\x82\xe3,\x8bp\xedH\x95\xfc\x15\xeaB\xaa\xac0\xa9\x84\x92\xed}\xb9\xc6\x8dg\x02Q\xf5k\x89\x04\xe1A\xc7\x99\x9b\xef;O2\x12\xa1u\x0eX\xfaz\x01\x1a\xe6+\x08w\x04\xb2\x0cja(\x13!\x19\x0ct\xf7\x05\xc5\xd1\n.\xbc\xc4\x83i9!\\\x89\x14\xd0XGM)\xeb+t\xfd\x00\x17\x89\xc4\x97{\x05U\x88\x8d\xec\x9a\x89\x96\xeb\xc7U%0NJ\xfd5\xb2\x0e\x94\xa9\xbf\xd7\xb6 #|\x00\x00\x16')
        self.assertEqual(self.tls_1_3_aes_256_gcm_decryptor.decrypt(server_3, True),
                         b'\x0f\x00\x01\x04\x08\x04\x01\x002\xa0\xe7i\xa7u\x8bP\rML)cp\xe5{?\xdbB\xbdI0\xf1\xff]h\xc5\xbcN\xe5$F#/Y\x86i\x8bVX\xb3\x0c\xd1lvP{Op +\x1aW\x16Y\x08\x8b?\xc0\xd0\x9d\xa9\xb20^\xf1 \x07\x876N,\xb0\x1e\x94\xaa,\x9c%$\xecY\xfc\xca\xed\x1c\xe7\xad\x86\xc2\x9e\xf6\xf7W\x93\t\x87g\xa1\xe96"\xa7]H\xed\xbb<\t\x99\xbe\x1b}T\xf8\xafQNN$\x8cP(\xb2\xd0\xc9l\xde\xda\xef\x7f\x94[\xe9\xedm\xacSg\xb9\xfa\x91\xf7c,\x8f\xcd\xb4\xf4>\xa4\x8er\xc0\x02Z|\xf1T9B\x87\xea\x8e\x89(#,\xc1N9\xb6\xc2"\x077\xb3\xe1\x03K3x\xa5\xc1\xffK\xc7\xec\x8d:]\xfd_\x11\x87\x95\x03\x82\x94\xb5\x1a\x10X\xa3\xe1\xfc\x13\xcbJ!\xa7\xb2{!z\x10]\x8d\x03Hu\x0f}\xd0W\xf9d\x98G\xbcc\x8e\xb4y\xe4\xd4\x18\xef\xf4\x90\xf1\x8a\xa8N\xf9D\xff\x9c%\x98]\xadk\xad\xa5\x96\x16')
        self.assertEqual(self.tls_1_3_aes_256_gcm_decryptor.decrypt(server_4, True),
                         b'\x14\x00\x000\xcdyGhz\x12\xcb\x96\x1eJ\x8e\x83\xa5\xcbj\x1f\x11\xc3\x9c%\xbc\xf0\xd8^\x87H\x14o\xb5sx?\x07\x9e\xb7\xd7Fc\xed9\x99$`\xd4Fxes\x16')

        self.tls_1_3_aes_256_gcm_decryptor.update_keys(True)

        self.assertEqual(self.tls_1_3_aes_256_gcm_decryptor.decrypt(client_1, False),
                         b'\x14\x00\x000)\xc9\xf0\xbd\x12\x1eU\xcd2\xfd\xad7{nP\xa5\xb1!4;+\xfa\x9d\xe0\xe9\x9ekp/\x0ce\x84\x01\x86\x11C \x1dS\xec\xaa\xe0\x94Mzl\x82\xc8\x16')
        self.tls_1_3_aes_256_gcm_decryptor.update_keys(False)

        self.assertEqual(self.tls_1_3_aes_256_gcm_decryptor.decrypt(server_app_1, True),
                         b'\x04\x00\x00\xe5\x00\x00\x1c \xce\xe8r\xa1\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0uk\xd0\x9e\x82\xb1\xabF_\xd1\xac\x17n\x8b\xca\x10\x16\xa9Ewf\xee\x89\xec\x97\xa6\xf3\x84\x18\x80\xcb\x0f\xd0\x882\xf8\x0fwae\xe7?\xeb\xfdH\x13\x13\xbc\x8f\xf2\r\x80\xf1\n!r#\xb4o\xb4\xd3\x82\x11\x02T\xea.\xeb\xc5\x8e\xe1B\xda\x7f\x82\xdfr\xbd\x0b\x00\x0e?\x81\xe5=\xbeL\xbev\xdc(\x94\xd8{\r\xcd\xd8\x1b]\xf8\x98O\xe7\xe4\xbdF\x00\xeeP\x03e\xcd\x07\xdd\x90\x97\xbb%\xa0^\xe9$\x8f\xf2`\xbd\x9ci?\x8b\xf2\xb7\xfb\xf0\x84A\x96l\x0b\x11o\xdf\x9e\xcd\xe1\xd0qj\x03\xc0 d\xf8\xb5\xd8?Q\xce\xdaq\xb6\x81_\x8bc\xd6\xf2E\xbd\x81X\x1a\x13\xefu\xed\xb6l\xbed\x0f\xa7\x06<W\x01\xac\xf9\xa8\x872\xb4We\n\x98e\x9b\xc4u\xf5D\xf9F\x81\xaa\x9f\xc6\x00\x00\x16')
        self.assertEqual(self.tls_1_3_aes_256_gcm_decryptor.decrypt(server_app_2, True),
                         b'\x04\x00\x00\xe5\x00\x00\x1c k\xa2\xa08\x08\x00\x00\x00\x00\x00\x00\x00\x01\x00\xd0uk\xd0\x9e\x82\xb1\xabF_\xd1\xac\x17n\x8b\xca\x10#\x84\xe6\x01>\xc4&\x912\xcf\xb4awd\xc3q\xf2\x85\x036(\x00\x8b\x93\x12\xb15\xf8\x97\xcb\xc8\xc0H\xb3jw\xae \xe7\xf9H\xc0{\xc1\x06\x8b\x85\x0c\x90\xba\xe5\xae\xaa\xcaI\x8b\xba\xca\xb7\x8a\x0b\x19\xac\x0c\x94\xfc=\x8e\xf71\x87I\\\x82\x16\xdd&X^\x89\x03Y\xae\xa6ON\xb7\xb8@r-?\x83"\x0b\xf3DD|\x06Pa\x94\'\x9a\xcd~\xd2o\x1dN\xa0\xca\x95\x06\xc78%\xb1\xcb\xb7h\xa7&\xcb\x95\x932Md\x95~\x9b\x07]!\x98\xacj$\x14\xafol\xf5(\xf1(\xde\xc6\x1f\xfaM\xa3\xcb{\r]\x05\x83\'\xea\xa2\x93\x0fyOC\x90\xd9\xb3\xb5ZS\xe0\x06svq\r\xc5\xa8\'\x7f\xf6nX\x8d\x97\x06\xcb~\x00\x00\x16')

        self.assertEqual(self.tls_1_3_aes_256_gcm_decryptor.decrypt(client_app_1, False), b'Lorem\n\x17')
        self.assertEqual(self.tls_1_3_aes_256_gcm_decryptor.decrypt(server_app_3, True), b'Lorem\n\x17')

    def test_aes_128_gcm(self):
        server_1 = TlsRecord(
            bytearray(b'\x17\x03\x03\x00\x17\x1a\x9fM\xe5L\xc8\xcax\x97\x9eq\xd0\x92\xc8\xfd\rm\xc0A\xed\xe3}\xa1'), [],
            True)
        server_2 = TlsRecord(bytearray(
            b'\x17\x03\x03\x03\x8d\xbe\x108\xb2\xcaI6\xa4\x1ew\x01\xef\x94\x8d3\xce6\xa6\x8fS\x01\x8am\xf0\xb0\x14i\xffJ\x9b\xc1\x98\xb2\x11\xeeH{/\xca\xe8\xab\xd0\x140|,\xfe\xf8\x83\x1c7md\x13\xaf\x9c\xbe}\xf8\x84\xcf\x88\xd4\xfc\x89\xb2\xc7\x0c\xfeY\xb5\xc3K`0[?Tl\x96A&T\xc1\xc5\xfd\xef5\x9b\xf4\xa6\xfaBI\x87\xd6\xfb\'\xc8\x02~\xda\x97\t\x91\'H\xfd\x03J\xadZ\xb5\xadE\xcd\xb7u\xcd[C\x0f\x7f\x07\xefa\xf9\x07\xbd\x95\xa0\x84\xf2b\xe1\xa9/\xd0H\xbf\x15\x01\xe9\xe7z\x8a\x08\xc66l\x12@@\x16\x1d9\x82O\xd0\xa0\x0b?w)\xdd\xb33\xcb{\x936\x08\x97_\xf7]\xa1\x9a\xaf\xb3\xfeRI\x87\x1b\x03\x8f\xeb\xe2(\x90Y\xb8\xd5w\xd3\xad\xa6L\x7f\xf1wS\xe8SU\xdb\x05\x95\xe6\xb8\xbe\xaf ~\x08\xbd\xe7)\xc3\xa0\xa2E*V\xc4<\x1fPa\x83\x92/\x90\xf6\xe1\x03\x10\x86\xf5\xfe\x9a\x14\xa5V\x03W\x7f_9\x10\x9c$\xe9YnS\xcf\xa0E\x9a\xb8\xba\x14\xd1A.\x8e\xc8\xc5\x9e|-c\xfcZM"\xdf\x92W\x08\x9fNlUA\xa6\x16F\xb8\xb84\x90\xf6\xb4\xd0r\xd9\xc9\xd9\x0c\xd8\xedV\x1a\x87\xf6\x17x\x88|\xadZ\x80\x03\xbb\xc4\xbcB^\n\x11(\xb2\x12)\xf1>\xbdU#\xeb\xb3\xa9>\xa7\xa8\x9f\xe8[\xde\xa1\xa2\xa1:\x93\x05\x06\x18\xeb\xfc0\xb0\xfc\xf6\xbb\xe0\xa8\xb9`\xf9\x91Vz\x83Z\xe6&\xf9\xf7\xads\x82i[)\xa0\xa0\x84\xa5U\x1d\xb4\xbc\x89\xae\xbf\x8e\xd7\xa0\xe9\x1c\xecP\x868\xbf\xcb\xd2\xa8\xa3\xb7\x9b@=\xd1\x92\x87\xff(\x8f\xda\xde\xc3\x1a{I\x8feN\xc3m\x96o\x06l\xe9?`\xd8pPc\xc7B\xb3\xd7vYT\x84\xc8\x82`\x84d\xa8\xed\xa8k_\x1f\tG\x99M\xf9(\xbe\x8e<\n\xa2A\x9f\xdc:p\x8fkA\x83\xa9\xcc\x9b}KDq\xa1`Y\x166Q6\x96\x05\xa3js"\xf4\xc9w\xd0\xafn\x0e\x8am\x06\x03\xc7\x8d\xe5\x1aT\xf9\xc2\xc4\xa5d63\xa5wD\xf8\x97\xee\xbf\xc0\xc7?\xceZ\x19\x16>\xdf\x1a\xc9\x02;\xcb\xb8\xcb_\xa00\xa6\xa9\xdd\xd6E\t#L\xd2\xfe\xc9\x86P\x82\xbb.sa\xf5TA\xb6w\x1aW\x05\xf2?+|\xc6\x1a\x8a\x9f\x90\x18\x84\xf0bZ\xbd\xe3\x9a\x08\x9a\x8c\xe8\xe0\xd3\xa2\xca%\xed\xba\xbei W\x0bxGCo\xc5\xb8\xf8\x1e\x9eGn\xb4j\x9er\x84\x12\xee^6;N\x0e\xb7\xeeSW\xc3\x19\\22\xe7\x84&\xbd\x95\xaf0\xed \x11\x9a\xa2\x15\x84\xb0\x1b\x0f\xd3Wx\xab\x11\xf3\xbf\x85\xb4\x9c:F\xd2S\xd5\x81Za\xf7!\xa4v*\xdb\xa7\xcf\x05\xc1\x05\x15t\xd6\x05N\x18d\xec\xc7\xd8D\xce\x8d\x07#\x9e\x95?\xb7\xdb\x16b@\x0c\xc2\xbb\x1a)\xd2\xfe]\xe4$\xc7\xa7\xdf\xf9\x81\xa0\xc6\xde3\xf3\xa6E\x06\xed\xe5\x93c\xc6q\xbf\x08/\xd9J%\xaa\x9c#\xcc\xc1\x04\xbfq\xdf\xc3\xa7\xc5\x16|r\xfac\xa0\x96\x8bh\xc6`i,\xcc\xfc_\xe0&\x88l\xb3\x03i\xd6a\x7fF\xdc\xbdN\r5^\xb7w`\xe9,\xf0\xe9j\xc6\x04\xf9\x0e[S\xcdb\xe4\x05\x00\xd5\x9f\x83@\xf2Y\xc0P\xa7wU\xc9VLox\xcb+Af\x00?\xea(7\xa8\xfc\xfeM\xf4\x95D\xea4h\xaf\n\x9a\xc8\xe6q\xaf\xd7\xbb:\xa0\xe0\xc0\x05\r\x8a%\xe1>\xa8\x12r\x96J\x82\xda&\xacDu7"\x8d\xb7-\xb6\x10\xc5X\xec\x02\xa0HU\x987&]\xe7Z\xfbV\x18\x97I\xcdMb\xca\xa4w\xe7R\x89J\xa1>Y\x92\xcf\x9f\\\x7f'),
            [], True)
        server_3 = TlsRecord(bytearray(
            b"\x17\x03\x03\x01\x19\x9f\x00\xf1+\xa5\xdbK\xdb\x15\t\xc7n\xdc\xf1\x02\xd8n\xbf\xdaQ=\xc5q\xdccg\x9b\xd2\xee\xbc\xbe?\xa7\xd9M\xa6j\x9d\xdc\xf51\xdc\xa1o0Y)\xda\x829\x03\xd7~\x98\x10\x08\xde\x7fu+I\xd0\x99+\xf9\xe9+\xe8\xeb0V\x99\xd3\xd3%)4kRg\x84\xe4\xe6\xae\xfdm9\xf5\x13\xc1O\xafT\xacr\xcf\xb9X\xf6\xe8\xdf\x04\x97\r\xed\xc2\xb6B\xc8?\xec\xaa\xfcY\x8a\x94\xc0\xbf\xb5HH\xe4?V\x8d\xd4\xcc\xb2Bo\xee35\xa5\x12\x9d\x13O\xcb*.\xcf\x0b\x80\xb5r\xd96\x84\xd9\r&\x8cxmI\x12\xd6\xe2\xca\xfbJ\x13\xee\xedT(\xfe1\xae\xa8\xc0;,\xdb6\n\x16,\xcb\x14\xafn\xed\xc8-\xb0\xe8r\xab\xaa\xcei\x85\x8aM\xe6@APm:\xc7\xd7\x05)\xd6S\xc96s?\x99j\'=z\x05[\x94W\xca|\\\xa0\xe4wP\xa6\x1e]\x0f\x87l\x91\x98\x19\x82P\x89m\xf9\xdd|\x80\xba\xa3\xfa\x83\x06\x95\xb2\xdf\xb0\xd1\xfa\xb1K\xd8\xeb\xd2=\xc3f\n\x98\xa1\x143RSK~-[\xfc\\\xcct\xba\x9d"),
            [], True)
        server_4 = TlsRecord(bytearray(
            b'\x17\x03\x03\x005I\x90\x9a\x9e\x84h[w>0[=xq.\xa0\xc9\x12\x80q\xf8>\xb1\xee\x87\xdb\xa6e\xfc\xbb\xe5\xb0sZe\xc2Dc\x92tY\x00"\x0f\xf00\xc6y)\xc2\xb6\x01\x1a'),
            [], True)

        client_1 = TlsRecord(bytearray(
            b"\x17\x03\x03\x005#\x90E\xb6\xc2\xb4\x1dW\xfa\xe7\xcf\xb5_U3\xf7\x8c\xce\x13jr=\x12\xaf\'\xec10\x05i\x92h#\x80\xaf\xe7\x1e$V\xe3/<\xc55P\x16)3\xd2\xbc\x18\r\xea"),
            [], False)

        server_app_1 = TlsRecord(bytearray(
            b'\x17\x03\x03\x00\xea\x0e\xfbPgg\x15\x16<\xbf\x88f\xe2\xbbp\xe7\xf7\x86P\x05\x18[&\xcc3\xba\xdeR\xa3\x17F\x1eU\xf3#yj0\x00\xa2\xbd\x8f\x07v\xdc\x10\xa3\xbc\xcc\xe8A\xe7\xb9*\x98\xf6\xfd\xb6\xcc\xc5\xc6M\x91\x97K\x8d\x1c]puAh\xd9\x8d\xc2[@4\x9b\xc2\x08A;\x96t\xf98\xd6\x18A\x1c\xcd\x83\x13\xe9\xeb<\x91\xb1j#\xd6\x86t\xe0\t),\x83.\xac\xabz/\x04\x91\xad\xfdr\x91\xbf\x1a\x1e\xa7\xad\xac\xca)\x15S\x05l\x97\x06\xd9\xea4O\xf8T\x1e\xf7[\xb0\xfa\xe7{\xf2\x15\x81\x8d\x12k*7\xd4\x1f7a\xfa\xc6\xdb\xe3\xc0\x06\xc2\xf9\xf1NV/\x15\x97N\xe0\x98\x89\xcd,;\xfe\xfa\xb4D\xd1\xfb\xeaj\x81\x8c\xd1W\x01r+q\xdb\xf4ww[\x8f\xb0\xc6E\x9a{@p\xdcr\xe1S\xf2\xde\x8f\xb8rdt\xb2B?\x12\x05\xd2&\xbb\x08\xa0x\x829\x81\xe3'),
            [], True)
        server_app_2 = TlsRecord(bytearray(
            b'\x17\x03\x03\x00\xea"_\xc9\x90\xc5P}Ft(\x8eD\xb9R\xa48<\xed=+\x81=\x82r|\x83\x131-\x95\xa2,#pc\xbe\xf4Jiga\xc5\xe7\xb8\xc1\xf6A\x94[7\x91w\xce\xa4);\xae\x02%S\xd9\xdae\x16^\xf1\x8e\x95\x14T\xc6\xa9K\x86h\xbc\xe3S\x89\xaa\x7f{\xb3P\x9d\xf9\xf2\xc1=+#\xf5\xa1\xd9\xf9A\xd6\xb1^\x8e^\x07\xa9=\x98{\xb8\xd2\x80\xc7\xea\xdb\x0b\xf1\xa9x^\xeal9-c7\xcf\xa8\xc0T\x03\x04\xccL\xb6\x05\xcbj\xd1\x9d\xdc\xf3 #\xc1\xb0\x88\x14C\xc2\xfaD3\x87lkEb#*\xf1\'`\xf1|KM\xbc\xa9\xa3\x91\x85\xbeo0f\x06\x1e]J\x91\x7fh\x0e\xed\xc2\xea\xfa\xe0e\xab]\x0c\xa6\x97\xae5\xda\x88pQ\xd3\xf3\x88\x88\xec%\\\xb3\xe1\x15\x8e\xc5K\xd4\x95\xac=\xe3\x0f9y4P\x92\x88\xb6\xb4\xdb\xc18\xb9\xc8\xd3\x92\xd8\xa9'),
            [], True)

        client_app_1 = TlsRecord(
            bytearray(b'\x17\x03\x03\x00\x17\xd5#\x99c&A\xc2a|7\x8ce\xe6\xf1\xc4i2\x92\x8a\xd2\x06Q\xfc'), [], False)
        server_app_3 = TlsRecord(
            bytearray(b'\x17\x03\x03\x00\x17L\xdfo\xc5S\x17\xfd\x0e^\xe0\n\x14\xbe/\xa6\xdc[\xc2\x0c\xfa\xad@\xca'), [],
            True)

        self.assertEqual(self.tls_1_3_aes_128_gcm_decryptor.decrypt(server_1, True), b'\x08\x00\x00\x02\x00\x00\x16')
        self.assertEqual(self.tls_1_3_aes_128_gcm_decryptor.decrypt(server_2, True),
                         b'\x0b\x00\x03x\x00\x00\x03t\x00\x03o0\x82\x03k0\x82\x02S\xa0\x03\x02\x01\x02\x02\x14zC\xc1\xae\xee\x84$\xbc\xe2\x95\xd9h\xc5\x15V\xcc\xd3\xf8\x1e\x130\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\x000E1\x0b0\t\x06\x03U\x04\x06\x13\x02AU1\x130\x11\x06\x03U\x04\x08\x0c\nSome-State1!0\x1f\x06\x03U\x04\n\x0c\x18Internet Widgits Pty Ltd0\x1e\x17\r230926081013Z\x17\r240925081013Z0E1\x0b0\t\x06\x03U\x04\x06\x13\x02AU1\x130\x11\x06\x03U\x04\x08\x0c\nSome-State1!0\x1f\x06\x03U\x04\n\x0c\x18Internet Widgits Pty Ltd0\x82\x01"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x000\x82\x01\n\x02\x82\x01\x01\x00\xdb\x85\xeb2^\xa7\x02y5\xf1}=\xad\xdf\x0c\xf6\xcd\xbc\x1e\xfe\x01\x195A~wI;1\xbe\xc11?\x06\xca\xb2\xac\xc7\xa1\xba\xb6\xe0\xd5\xb0+_\xa2i\xc4y\x97\x17\xcc&\xa4\x0cv\x8c\xb8\xb1\xbc\x89\x1e\xf1f_Z\xa1\x00\x0c\x01Hm\xae\xe6\x00K\xa2\xabj:6\xa7\x02`\xef\xeb\x95C\xc4\xa0\x1eH~]\xf6\xf9\xc5{\xbc\xa3\x9c\xd6\x9e\xf6\x88G\xbd\xa5\xa1\\\xa5\xdd>\xec\xc6\x03\x86\x101\x12\x1e)\xb7\xbdc\xdc(\xfe\xc4%\x14i3u\xe1\x93\xa4<G\x11\xf0\xe1\xd5\xe6\xdd\x14)\xf8\xc8\xa6\xd6S\xa0\xf5<\x1ep~\x1cD\x8c] P\xd8%t.\x85I\x9b\xd2\xdb\x14%wb\xfa\xd3\xd9\xdd\xcf\x05\'(\x90\xbdY\x02\x1c\x18\x7f\xdfr\xc1dYr\x15\xe4\n\xd4\xdb\x1c\xc9G\xc7\xea\xe4\x1a\xc9\x12L\xeav.\xcb&z\t$\xa1\xbf\xc8t\xdbM\xc6+\xd26pC\xbey\xe6\x16rVn\xe9\x97\x9d[#dT\xa4\x91XR\xd8\xd5$E\x02\x03\x01\x00\x01\xa3S0Q0\x1d\x06\x03U\x1d\x0e\x04\x16\x04\x14\xdf3\xd5\xd9\xec\xd6\xab\xb0Fc\xd6t\\\xbdl\xb4l\x00\xf6x0\x1f\x06\x03U\x1d#\x04\x180\x16\x80\x14\xdf3\xd5\xd9\xec\xd6\xab\xb0Fc\xd6t\\\xbdl\xb4l\x00\xf6x0\x0f\x06\x03U\x1d\x13\x01\x01\xff\x04\x050\x03\x01\x01\xff0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x002IA\xe21\x9a\xcaY\xc4\xba\xf4\xd6\xbe><\xcf\x81f\xac\x03\x03\xba\n<\xcc\xd0e\xf2\x07\xd4\xe3\x11u\x02*\x02\xf6u\x14n\xd7qz\xcd\x0ck\xbf;O\x8cA\xb0R\x8a\x86\xceg3hv.\x12\xa1\xb7\xfa{\xcf\x01qz\x95rn\xbb\x83B[~\x1110\xe7\xa9Z-\x9b\xbdR\x12\xa0mt\xf8iHL\xaa\x05jI\xc6\n\x84\xc9\xfbK\x8c\xd2\xe1\xe2s\xa1L\xe4J\x9d\xe6\xfeM\x82_\xcd\xe4s\'I\xd9\xf7\xca0\x84\xaa\xef&\xd5\xd6\x82\xe3,\x8bp\xedH\x95\xfc\x15\xeaB\xaa\xac0\xa9\x84\x92\xed}\xb9\xc6\x8dg\x02Q\xf5k\x89\x04\xe1A\xc7\x99\x9b\xef;O2\x12\xa1u\x0eX\xfaz\x01\x1a\xe6+\x08w\x04\xb2\x0cja(\x13!\x19\x0ct\xf7\x05\xc5\xd1\n.\xbc\xc4\x83i9!\\\x89\x14\xd0XGM)\xeb+t\xfd\x00\x17\x89\xc4\x97{\x05U\x88\x8d\xec\x9a\x89\x96\xeb\xc7U%0NJ\xfd5\xb2\x0e\x94\xa9\xbf\xd7\xb6 #|\x00\x00\x16')
        self.assertEqual(self.tls_1_3_aes_128_gcm_decryptor.decrypt(server_3, True),
                         b'\x0f\x00\x01\x04\x08\x04\x01\x00\x1b\xbf\x82\x1c\xa0\x89\xa1Day\xa1\xc5\xf1I7?\xb5\xf3\xe9";\xc1\xc3\xbb\x80\xde_p\x96\xf6*\xdb\x86\xfc\r\x12Z\x08d\xa1\xaf\x14\r\x18g\x00\xbaM\xb7\'\x9a\xb55\xa6=6\x97\xc6\x11\x9e\xf0=\xb37\xe9\xb6\xbdo\x0e\xc8\\\xc3x1e\xd0\x13\x96{\xc8}\x1d\xf6\xbf$T\x834\x13\x81eS\xd9@\xb0\x87\xdb\xb6y\x94\xf3\x96\xf4\x81\xdd\x04\x8faDZW":\x15\xea\xd2^\x13q\xb0\xd1[k\x04g3\x7f\xb3Jt\xb7\x8c\x8b\x83(\xb9\xc1\x94{\xe0Tlbo\xdd\x95\xdb\xe2w\xbaln2]*\xb0\xc24h\xf0j\x01\xd0\x81\xfe\x02\x95\x9b\xd9\xf7\xee{\xff\x05\xba\xd0\x03{\xa6\xa8\xcb\x13\xd4\x94z\x9a\x82\xff\x9d\xb7pL\xc7\x18+\te\\\xe7-\xe7\'\x8c(\xc8\xa4\x84\xa6\xd3\\\xe5X\xffg~\x1d\x16\xe1p\x88(\xa8j\x12;,\x8f\x0b\xdf<\x00T\x1dw\xad\xb2\xa4~\x1f]\rk\xb4\xfe\x93\x05lcL\x8b\x80\xc1\x94+\xe3\xfe\x16')
        self.assertEqual(self.tls_1_3_aes_128_gcm_decryptor.decrypt(server_4, True),
                         b'\x14\x00\x00 o>L\r6\xcfp\xab\x10\xc9\x95\xac\xb9A\xacp\x7f\xbb2&\xd7"Q>\xf9\xd8?\xf7`\x04\xa3\xe5\x16')

        self.tls_1_3_aes_128_gcm_decryptor.update_keys(True)

        self.assertEqual(self.tls_1_3_aes_128_gcm_decryptor.decrypt(client_1, False),
                         b'\x14\x00\x00 \r\xbd\xa8\xb8 \x10\x85\x9dV\xc1\xaa\xa4\x14\xb5\x0e\n_\x13\x94\x84\x9f\xc5\xb9\xe7\xdbtry\xd7\x9c\x103\x16')

        self.tls_1_3_aes_128_gcm_decryptor.update_keys(False)

        self.assertEqual(self.tls_1_3_aes_128_gcm_decryptor.decrypt(server_app_1, True),
                         b"\x04\x00\x00\xd5\x00\x00\x1c \xd3\xb3\xda\xcf\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0uk\xd0\x9e\x82\xb1\xabF_\xd1\xac\x17n\x8b\xca\x10\xdav\x9f\x04}\xec\xdbA\x932\xa4\x93\x82\xcf\xc92\x00\x95\xf2\xd23\xe7^\xe0j\x1a=(*\xd1\xac\x03\xca\xcaAKD\x99\x12\x8cQW\x8a\xab\x89\r\xc3\xe2 \xa6L\xd0?\xbe\x03\x03H/\xb0P\xc6\xdc\xf9\xbc/3\xaaV\x91?b\xcb\x1e)\xc0\xa2\x04\x93\xf7\x96\x1f~\xceK\xca\x8f\xdf4\xdb\x7f\xc5\xc7k!s\x8d\x1al\xd8\xa6\x8fH\x03\x83\x92[n\xb8\te\x9b\x8a\x1eG\xf4\xd2\xf0\xcde\x1b\xf4\xa3u\xbb\xd2\xe7+\xb4\x0b\xed\xbb\xe9\r\xa8\r\xe1\xc8=\x8d\xa1;\x87\xe4\x12\x9b\xb0Hu\xd9f\x91\xc6GL\x1a'-db)\xcb\xc9\x02\xda\r\xa7\x86\xc0\xeab\x0b2\x05x\x02\xce\x00\x00\x16")
        self.assertEqual(self.tls_1_3_aes_128_gcm_decryptor.decrypt(server_app_2, True),
                         b"\x04\x00\x00\xd5\x00\x00\x1c X\x14\xf6A\x08\x00\x00\x00\x00\x00\x00\x00\x01\x00\xc0uk\xd0\x9e\x82\xb1\xabF_\xd1\xac\x17n\x8b\xca\x10\xdb\xa3\xa7i\xfa\xecD~_\xc4m\xa5\xba^\x97e\x87Y,\xe0\xf5\x16&\xf9\x98\x00\x95\xf9\xc7\xad\xee\xde\xe8\xc0ZJW\x9c\n+\xc4\x98\xa50=$\xa9\xe8^;r\xf7\xa1m\xe6o_\xbb\xb85\x9f\xb9\xcd\xf6\xf2vC\x1c\xc5\x8b\xf8Z\xaf\x811~\xd8\xed\n\xd1\xde\xa6\x89\x80\xf0S9\xc3 \x97\xe7?-\x85\xaa\xf3ES\x10\x96\x95\xc0&\x19\x90\x8d\xf3QA\xbe\x9a\x03\x85\x82\x01\x8a\xff\x0eH\xd0\x95\x1b\x19\x02%\x95\x036'FP\x9c\xb6x\xf8\x89\xef\x91s\xb0\xe6\xae\xeeD\xf2\xcdH\xcb\x8e\x18\x9c\x12\xe2\xe1h\xdc \x8f\xbc\xf3\x86e]5uL\xfcb\x03r#\xd59-K\xa1\x00\x00\x16")

        self.assertEqual(self.tls_1_3_aes_128_gcm_decryptor.decrypt(client_app_1, False), b'Lorem\n\x17')
        self.assertEqual(self.tls_1_3_aes_128_gcm_decryptor.decrypt(server_app_3, True), b'Lorem\n\x17')

    def test_chacha20_decrypt(self):
        server_1 = TlsRecord(
            bytearray(b'\x17\x03\x03\x00\x17y\xaf\xe4&6\xe0&\xf9\xd11: {\xe7\xac\x16;\xc7\xe5\xa6\xd7\xc8\xe4'), [],
            True)
        server_2 = TlsRecord(bytearray(
            b'\x17\x03\x03\x03\x8d\xf7\xdb\xa3\'\xb7\x80RK\x08\x03\x99:Pj\x87\xec\x8d\xc7\xb6\xffp\xfb\xc2+\x1a\xee\x01\xb7J\xde8A\x96\x85Q\xc3n\x98\xb8\xc1\xbf\x91?\x0fC\x1d\xe5#\x01\x9e\x87\xce\xe29\xbb\xd3J0V\x82\xda\\\x80\x0bK?\x9c\xd6\xactQ)\xad \x1e\x91\x0e.\x1a\x00\x1c\xef\x84\x0e\xeb5\xc0J\x1e\xc9\x9b^T\xcdG\x07\x15Ii`\xf7+x\x92;\x84U\xba\x92V8\r\x89c\xd2\xb4\xd3\xe2q\xe2\x00\x86o\xfa\xcd\xfc\xfbyN\'\x0e\x9bj\x05\x1d\x96\xc0P\x92!\xf9\xachvV@oZ\xc5\xa5p\xddQ\x08\xe7\xba\x18\xf5\xccvM\x03\x86\xc4\xe6\xec\xea\x91\xea\xbb.\xb6\x10L35\x10\x94\xc6\x04\x12\x1f\xd3\x8e\xec\xdf\xa0At\x8c8\xcb\x88\'o\xbf\xe64\xe3\xd0C\xd7\xf2\x9f\xe7\xa4\xe9\xc0n.w\xec\x1e\xe3\xc2\xba\xcd}\xca\xbb5\xb4\xfa"\x91\x87\x10\xb9\xea\x15\x9e\x9e\n\xe6)\x19$g\xf2X\x1b\xce$f\xe9\x8d\xdd\xa0\xed\x17\\u\xd2&(I\xa7&`\x90a<\xaa\'\x05\x0c\x81p\x0c\xcb\x16\xa5\xff\x1b\x0ea\xbd\xc3\xb1\xbd(\xaeGY\xcc>b\x85\xac\xa9\x10\'\xf1\x8d\x12\xd1blb\xca{!X\x86\x8a\x81\x8d\xfd1\xda\xc6\xd2\xa2\r:#p=\x868\xce6\xfb\xdd\xe8\xf5fUZ\xb0f|\xe6\xf6E\xa1\xdd\xfc\xa6],\x9cD`\x01T\xc3SR\xdc\xe7In\x9d8\xae\x80\x18\x18\x9dO\xf0\xcc+g=\xbe_\xb4\xfd\x98\xae\x1bS17H\xe6e\x91)\x80}\xbf,\xff\xab\x06\x052\x94\xae\xeaBE\xa7q\x1dT\x8b\xfe\xd0nu\xec\xef\xaa\xc4\xe3\x16\x0c\xf2\x04\xf24P\x90\xd5$\xdcA\x0c\x00\xbf\xb6I\xb3m\xa3Z\x0c\'\xbdK\xa9v\xe1\xba%\xb9\xdc\xec\xb3\xe3d\xe6\xacc\x9d\x03\xed\xdf]\xcc\xefm9\xdfn)\x88\xdb \x0c\xc9(\xcb\xc5yrC\x97rLQ\xbajPs\xeaM\x82`o\x13!\xdd\xc61\x8bAX\xc8\x86h\xf2Xq\x82(\xb7\x17Q\xf7f*a\x07k\x1d\xf6\xaa\xb1\x97\xf4X\xad*PF7\xae)\xc7}\x8b\xd7\x98PF\x19\xf2\xa60o#c\xca\xfd<\x15\xd5\xbeJ\x9b\xe2K\xea\x87NHaj\xed\x15\xf3&\x85H\x8b(\xa1\x8de\x0eE:\xea;\x05\xbe\x9a&d\xb5\xe3"Y>g\xd3\xcdBT\x17\x8a\x11\xd0\x16\xd0\x89}\xd8\x1a\xcfR\xfa\xab]6\xff\xa8\x864\xa6\x83\xfe\xf0\x91\xb0?\x9do5\xdf\xe5\x1b(\xe6\xd3\x0c\xd22\x8e8\xd3C\xd2Y7\xad\xa0\x12in\x89\xea\x01\xbf\xa0?~z\x9f\xe4\xbe\xb1?\xee{,\x9e\x03\xcb\xd2:\xdd3\xd3\xef\x83Zm\x1e\x8b\x86\xfc\x19\x92f\t\xbc:\x84^\x9b\xeb\xd8\xbd\xb5I>q)\xf9\x0eh\x85b\xcdQ\xc4\xf1{\x11\xc1T\xcf\x89\x9b\xa1\x1b\x18u\xebG$\x87\x15\xc9\x055qf\x1axu\xbb8\xa6\'m\xdc\xeb-}\x14\xc1\x8b\x03\x83R\x9b>\x95n\xec\xe9Q\x90\xccfs\xc6\xb6\xc2(\x98\x14I1\xb7\xf3\x10\xf7S\xab\x8e\xc4\x17\xc0\x18\xf6\x14\x0e.\xa3e(\xb1\xc4\xb8pl\xd0<C\xb1\xdf\xbch\x18\xae\x9f\x0f\xdf-"\x8c[\xf7\xf9\xfa\xcc\x12\x9c\xf4\xef\x97\x01m\xc7\xb5\x1f\xe4\xa7\x0e}>\x1a\xfe\x8e\x8fC\xe6\x0c\x98j.NyIY\xf5a\x18\x08\xa0\x84\x1a\x1e\xa5\x0f\xc9\xa1:\xcb\x93V\xff\xe0\xd2\x86(\x0e\xae/\xc8\\{~\x16\x90\xe6h\x0c?\xbd\xd7]\x8ax\x91\xec\\\t\xf7\xa6-kRTb\xea\x87\x83;\xa3\xeaI\xb3\x97\xe3V\x84\x0e&/\x83\x92\x04\xaa\x94\xfe\x98\xba\x87>\xab?\xebo\x19\xba.\xfa\x08c.'),
            [], True)
        server_3 = TlsRecord(bytearray(
            b'\x17\x03\x03\x01\x19@\xe2C\xe0\x0ct\x1a\x91\x81\x92q\x83?\n\xd1\xfc\xb8\xa6%\xae>P\x90\x00%\xda\x89\xad\x8e\xab\xbc\x18U\x04\x0f\xecF\x10\xf5i\x1arn\xac\xe7\x8euS\xc7\xdcI?\xb2<+\xb1\x8d\x88n\x8b\xa6\x02\xf3\xcd\xf1\xba1\x8e\\-\xc6\x8b>=\xedn\xde\x98\x92u\xd6\x15D\x97\x93E\xc5\x95m\xed\x82\xcd\xd6\xcc\xa6\xdc\xf1Yu-\xc0p\xad\x1d\x13Q\xf1\xe1\xbb\xc8\x12\xae E\xedE\x999\x82\xac\x11(zwm(2\x12\xcf,\x19\xdfd\x9f\xc3M\xa0\xe5}\xe3\xed\xdaa\xd1\xfcq\xa7\xd5\xc2I\xdbP\x85\xb2r\x1eJH\xfa\x80L\x8a\xbc\xe5\x14F\xa4>\xe2\xf4>&\xd8\xd7-T\x01?\xf4\xfea~\xb5!%\x86P\xb8yT\xfd\x87\x08\xd0\x06N\xa5zF.\xec\x1b\xcfH\x91\x96\x90\n\xcb3\xb5\xf4<Kv\xadg\xd0\x0c\x1c\xb1\xf2\xa2UT\t\r\xe3\x06\x11\x8b\xcc\x84\x86d\t({\xad\xee\xb3C\xcf\x8a\xd4\xa9\xe6\xd0\xff\x05\xb4\x9a\xc1\x19\x85\xf1<\x95{\xb8\n\x0b\x9bU6\xba\xe1\x0c\xdchG\x8b\xbfJ\rP\xcd\x03\x9c\x1b\x00'),
            [], True)
        server_4 = TlsRecord(bytearray(
            b'\x17\x03\x03\x005\xf0\xdd\x85\x9a=\xed\x99r\xd3\xf5\xed\x9b\xc8\xde\xa8T\xd7\xf8q\xf4\x1f \xc4\xe6r]\x14`om\xed\xc2<\xd2\x9fS,lV\x00q\x87\nUxl\xb1\xe3\xe3\t\xfa04'),
            [], True)
        # cipher change server
        clint_1 = TlsRecord(bytearray(
            b"\x17\x03\x03\x005|\xe2\x06\xbc\xc4$\xf3\xaa\x0bh\xcb\x95\x15f\xb0\xac5K\xb9\xbe\xcd%\xdaQ\xfdS:\x81\xb8\xba^\xc0|\xd4SC\xba\xc8\xde\xa9\x1f)\xf0\xa8\'\x88\xc9\'\xcbr\x0b\xab\xa9"),
            [], False)

        server_app_1 = TlsRecord(bytearray(
            b"\x17\x03\x03\x00\xea\xd7\x05\xb8\xb8\xb9\x9c\xa3e\xe1\x97%/\xe8\xfe\xbf(P\xd4z\xba\x96\xaew\x81qd\x10FQ\x0e\x80!\x15*\xcfs&vE\xac\xf4$\xa3.\xd5\xf35U\xf5\xa1\x04\x8ag\ng\xf8\x97qh\xb5\x1f\xe6!\x87Th\xf5\x04\xf2>A\xbd\xf9&\xbd3\xbb0D\xf7\xde3\x1e\xbb\xc9\xe8Qo\xbd\xe1\xaa\xbduu\x84g\xe63\xebZ\x86\x03,%\xfa3\x13jK\x1e\xbd\x04\x8d\xec\x12l\x87\xf8\x14v\xabf4\xedN5:\xbc5\xa5\x9d\t\xc5(\xb5\xec\x16\xb8\xf9\xf3\x19\xe2#\x12\xd5\xb3\xc1h\x93\xa1\xd7\x95\x01\x0e\x97\x8b\xd4\xb5\x16\xe9\xe2\xb9lU@(\x86\x0eU\x01\xe4c\x8c\xe6\xf8z\xddlC&\xfeao\'\x85\x92\x98\x88S\xf4\x85\xad8\xf9\xaaq\x12\x01n\xf3wh\xc0\xdb\x9a\x07\x0eB<\x93\x08\x83\xbb\x03R\xac\xa1\xb9W\x9c\xd9*\xf5\xd4\xbe\x00J\xe0:\xab\x9e\x9e\xa3\xf9"),
            [], True)
        server_app_2 = TlsRecord(bytearray(
            b'\x17\x03\x03\x00\xea\x1e??_G\x88\xb3I\x08\x11\xda\x0b\xe4\xa0\xcc\xb9\xbb\xdb-U\xbbc[\x9d\xae\xe7\xb3N{\x1f\xe9\x86:\xff+\xda\x9a`\xa0Q\x1e~\xee\x8a\xd6\x9fVh\xf2\xed\xc3b\xb4\x95\xda\xf7\xe5-\x1b.&WV\xfd\xb4\xb3\xbb-\xc0\x9f\x9b\xe5w9*\x1e\x89\xff\xa3\xdcC\x1e\x96u\xd4{\x94A\xc4l\xf8>?M\x9f\x1b\xc1\xd4K\xec\nAx\xf3\xa7\xc5o\\\xf6\xf9\xef\x82$\x1e\xde\xe3~\x96\xc3D\x92\x96\x92F\xf1h7\x12!o\x12-\xcam0\xd0\x8dFoO\x11 \xc9J7)\xdc\xfa\xb7\x9ax\xf6\x03\xa1\xc86H![\xbd\xf6\xd4}J:\xa6\xc6\xc9\xd6O\xbat\x0c\xbd\x9bd`\xaf\xb8\xfb\x12}L!\x8c\x85/\x8dM\xd1\xd1@3x\x80\xa9yYjn\x00\xe1J\x93\xb0*\xf3\\\x80Yn\xaa\xfbVzr\xa8\x1a\xb1\xd3{_\x9b\x938\xb5\x8e\x0b=\xb2\xec\x0f\xaf\x92'),
            [], True)

        clint_app_1 = TlsRecord(
            bytearray(b'\x17\x03\x03\x00\x170?\xb8\x05\xff\x94\x1e\xd6\xff;\x88hR/~p\xfd\xbf\xb4\xd6\x08p\n'), [],
            False)
        server_app_3 = TlsRecord(
            bytearray(b'\x17\x03\x03\x00\x17X\xacv\xe6\xe9\xe6\xbd\xaf~\x08\xa3v\xba9S\xd8\xb3}JF\x13K\x0e'), [],
            True)

        self.assertEqual(self.tls_1_3_chacha20_poly1305_decryptor.decrypt(server_1, True),
                         b'\x08\x00\x00\x02\x00\x00\x16')
        self.assertEqual(self.tls_1_3_chacha20_poly1305_decryptor.decrypt(server_2, True),
                         b'\x0b\x00\x03x\x00\x00\x03t\x00\x03o0\x82\x03k0\x82\x02S\xa0\x03\x02\x01\x02\x02\x14zC\xc1\xae\xee\x84$\xbc\xe2\x95\xd9h\xc5\x15V\xcc\xd3\xf8\x1e\x130\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\x000E1\x0b0\t\x06\x03U\x04\x06\x13\x02AU1\x130\x11\x06\x03U\x04\x08\x0c\nSome-State1!0\x1f\x06\x03U\x04\n\x0c\x18Internet Widgits Pty Ltd0\x1e\x17\r230926081013Z\x17\r240925081013Z0E1\x0b0\t\x06\x03U\x04\x06\x13\x02AU1\x130\x11\x06\x03U\x04\x08\x0c\nSome-State1!0\x1f\x06\x03U\x04\n\x0c\x18Internet Widgits Pty Ltd0\x82\x01"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x000\x82\x01\n\x02\x82\x01\x01\x00\xdb\x85\xeb2^\xa7\x02y5\xf1}=\xad\xdf\x0c\xf6\xcd\xbc\x1e\xfe\x01\x195A~wI;1\xbe\xc11?\x06\xca\xb2\xac\xc7\xa1\xba\xb6\xe0\xd5\xb0+_\xa2i\xc4y\x97\x17\xcc&\xa4\x0cv\x8c\xb8\xb1\xbc\x89\x1e\xf1f_Z\xa1\x00\x0c\x01Hm\xae\xe6\x00K\xa2\xabj:6\xa7\x02`\xef\xeb\x95C\xc4\xa0\x1eH~]\xf6\xf9\xc5{\xbc\xa3\x9c\xd6\x9e\xf6\x88G\xbd\xa5\xa1\\\xa5\xdd>\xec\xc6\x03\x86\x101\x12\x1e)\xb7\xbdc\xdc(\xfe\xc4%\x14i3u\xe1\x93\xa4<G\x11\xf0\xe1\xd5\xe6\xdd\x14)\xf8\xc8\xa6\xd6S\xa0\xf5<\x1ep~\x1cD\x8c] P\xd8%t.\x85I\x9b\xd2\xdb\x14%wb\xfa\xd3\xd9\xdd\xcf\x05\'(\x90\xbdY\x02\x1c\x18\x7f\xdfr\xc1dYr\x15\xe4\n\xd4\xdb\x1c\xc9G\xc7\xea\xe4\x1a\xc9\x12L\xeav.\xcb&z\t$\xa1\xbf\xc8t\xdbM\xc6+\xd26pC\xbey\xe6\x16rVn\xe9\x97\x9d[#dT\xa4\x91XR\xd8\xd5$E\x02\x03\x01\x00\x01\xa3S0Q0\x1d\x06\x03U\x1d\x0e\x04\x16\x04\x14\xdf3\xd5\xd9\xec\xd6\xab\xb0Fc\xd6t\\\xbdl\xb4l\x00\xf6x0\x1f\x06\x03U\x1d#\x04\x180\x16\x80\x14\xdf3\xd5\xd9\xec\xd6\xab\xb0Fc\xd6t\\\xbdl\xb4l\x00\xf6x0\x0f\x06\x03U\x1d\x13\x01\x01\xff\x04\x050\x03\x01\x01\xff0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x002IA\xe21\x9a\xcaY\xc4\xba\xf4\xd6\xbe><\xcf\x81f\xac\x03\x03\xba\n<\xcc\xd0e\xf2\x07\xd4\xe3\x11u\x02*\x02\xf6u\x14n\xd7qz\xcd\x0ck\xbf;O\x8cA\xb0R\x8a\x86\xceg3hv.\x12\xa1\xb7\xfa{\xcf\x01qz\x95rn\xbb\x83B[~\x1110\xe7\xa9Z-\x9b\xbdR\x12\xa0mt\xf8iHL\xaa\x05jI\xc6\n\x84\xc9\xfbK\x8c\xd2\xe1\xe2s\xa1L\xe4J\x9d\xe6\xfeM\x82_\xcd\xe4s\'I\xd9\xf7\xca0\x84\xaa\xef&\xd5\xd6\x82\xe3,\x8bp\xedH\x95\xfc\x15\xeaB\xaa\xac0\xa9\x84\x92\xed}\xb9\xc6\x8dg\x02Q\xf5k\x89\x04\xe1A\xc7\x99\x9b\xef;O2\x12\xa1u\x0eX\xfaz\x01\x1a\xe6+\x08w\x04\xb2\x0cja(\x13!\x19\x0ct\xf7\x05\xc5\xd1\n.\xbc\xc4\x83i9!\\\x89\x14\xd0XGM)\xeb+t\xfd\x00\x17\x89\xc4\x97{\x05U\x88\x8d\xec\x9a\x89\x96\xeb\xc7U%0NJ\xfd5\xb2\x0e\x94\xa9\xbf\xd7\xb6 #|\x00\x00\x16')
        self.assertEqual(self.tls_1_3_chacha20_poly1305_decryptor.decrypt(server_3, True),
                         b'\x0f\x00\x01\x04\x08\x04\x01\x00#\xe6\xd9\xba\xef\xea\xe0\xca\\\xecA\xba/@\xf8\xe0+\x1cP\xc2\x99U&W\xb9\x00^\x87H\x83<\xe2G\xa4%\xd6\x8e\xb3K7\x90Vo\x99bf\x866\x8b\xd0)\xe3\x8c}\x01\xd5D-\xd6\x8c\x9d\xb9\xcc\xb7>\xd7\x9c\x82\xa4\xee&\xf7z\x83\xd9\xf9_7\x92\xe7\x85a\xe0\x82|\xe1b\x86\xc2\xc2]~~\n<\xd3h;7\xc6\x01(\xa1\xb2V\x91k\xf0~\x02\xe9\xb7\xb8/\x13\x0e\xaf\xbf\n\xca\xb1=\xf3\x99t\xba\xdd$^\x18\x97Cg\xefo\xadCl\xc0\x87\x9d\x91n\xd5S\xfa\x11\xd3\xe9\xa1\xde\xb4.\xd6\xc6\xa4mgZ\x1cL6]\xea\xc2M\x7f\t\x03\xb1\xbb\x9a\xba\xa0\xaf\xd0\xa3\x1d\xd0m\xf5\x1b\x9cf\xd4T\xa2\xebb\t\xf8G\x042\xfb-\x1c\xd8*\xc1#x\xdd\xd43\xcaK\xae\x8e\xbf\x05\xca\xe3\xb9v((Ts\xe3\xb8D!A\xa5\x86\xc1\x8fB\x05\xea\x15O6\x95\xa7\xa4\xa1\n\x03Rs6\x05\x1a8\r\x15T\xda\xea\xa1\xb7\xbe\\\x0e\x16')
        self.assertEqual(self.tls_1_3_chacha20_poly1305_decryptor.decrypt(server_4, True),
                         b'\x14\x00\x00 \xc5\x02:S~{c\xd9\xe9`*\xa8\xf7L\xa7\xd5\x8al\xed&\xd4\x07\x85a\xb7\ns\xd8\xb1;.w\x16')

        self.tls_1_3_chacha20_poly1305_decryptor.update_keys(True)

        self.assertEqual(self.tls_1_3_chacha20_poly1305_decryptor.decrypt(clint_1, False),
                         b'\x14\x00\x00 #\x9e&\xac\xe1\x10v\xcflJ\xf5o\xe4\xc7\xb0\xd7\x83\xea\xdc\xdc\xaa\x87H\x1b\xf2i\x1ba0\xf2\x85\x82\x16')

        self.tls_1_3_chacha20_poly1305_decryptor.update_keys(False)

        self.assertEqual(self.tls_1_3_chacha20_poly1305_decryptor.decrypt(server_app_1, True),
                         b'\x04\x00\x00\xd5\x00\x00\x1c \xd9\xa7\xc1\xeb\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0uk\xd0\x9e\x82\xb1\xabF_\xd1\xac\x17n\x8b\xca\x10f^\xad\xf2tCQh$\x7f&\x17o\xc9\xa0T\t\xcc\x84*\xdc\x01\x95\x1c\x85\x0ck\x05\xcbE-g\xcc+\x8a\xf9\xcd\t&\xc4\x08\x17@i\\\xa7\x8c[\x89\x1eZ\xebW)\xed\xb6m\xa0\xf9\xd40F\x7f\xa6\xbc\xc5\x9f\xd1\x84v;9O\xacZ\x19\xcd&,\x02\xc5%\xe4HW\xd3\x0f7\x00\xff_3\xfad;\xc2~E\xa8\xe3f?E\x86\xc9\xeb\x80,\xb4\xfbI\xee\xf9\xb4=-i\xbdx\xe9\xa6\x004\x91\xb0PM`Z\x87\xce\x84\xf7\xbe\x16\x03\xc2\x93\xd9\xa6\xc18\xb5\xec\xddW\x90\x9dZ.\x9a\xee-_\xb5-u7\x06f\xff\x9f\x053\x7f7\x99\x04\x8di\xd7t\xce\x9a\xb7L\x00\x00\x16')
        self.assertEqual(self.tls_1_3_chacha20_poly1305_decryptor.decrypt(server_app_2, True),
                         b'\x04\x00\x00\xd5\x00\x00\x1c \x82\x83\x9a\xc3\x08\x00\x00\x00\x00\x00\x00\x00\x01\x00\xc0uk\xd0\x9e\x82\xb1\xabF_\xd1\xac\x17n\x8b\xca\x107\xb9"\x16\x87\xc0\xba\xed\xe3\xf3\x93bj\x14\xe8?\xf3IK4,bE\xdf\xd4\x13\x02R\xa6\xd2]1\xe17\xbd4N\x96\x15\x13\xe0\x06\xc4\xcc\xd9\xe0B\xa1\xa7p\xe0\xfc\xf1\xe6I%g\x8aQ\x81l\xc8\xceY\x15l^ucw\xa38g\xb9V\xf6\xa7\x06\x8b3\xd3"\xb0\xba\xb1\xef-\xf4)x\xe1\x8d+\x1a\xd1V\x14hr\x90\xe7SL\xbcW\xc19\x95\xc8\xf7\xb6O\x9fW\xde\xf3\xb4v\xcf\xb2\xb4\x8a16\xd6\x9cs\xa2\x06\xcc\xbd\xd7^;41\xc9\xbd\x08\xb9\xcf\xff\xf7\xa1\xb2\xacL\xb3\x82\xab\xc3\x10>\x16\xae\xa2\xb8\x98\xe3U\xa1\x8a\xf9\xe1x\xf2\x93\xe0@\xaf\xbdTg\xba\xabS\x00\x00\x16')

        self.assertEqual(self.tls_1_3_chacha20_poly1305_decryptor.decrypt(clint_app_1, False), b'Lorem\n\x17')
        self.assertEqual(self.tls_1_3_chacha20_poly1305_decryptor.decrypt(server_app_3, True), b'Lorem\n\x17')


class TestSsl30Decryptor(TestCase):
    def setUp(self) -> None:
        self.ssl_3_0_rc4_decryptor = Decryptor(ARC4, None, SHA1, {
            'client_write_MAC_secret': b'p\xd6]cl\x04\x81\xec\x1a\xb7\xe4\xc3\x03\\\xcf2\xb5\xe9\xc1W',
            'server_write_MAC_secret': b'<\x97\x9e\x1ei\xd8\xbd\x850\xeb\x17\x96\x9d\xd0\x0e\xb9\xe0\xebGD',
            'client_write_key': b'\xe5\xd6R\xf1\x07\x82\xe4\x17i%\x15\x97\x15\x86;\x8a',
            'server_write_key': b'c\xa7\x93\x98D\xf0\xa9\xb2N\xac\x90\xb3\xaa#\xfc-',
            'client_write_IV': b' \x1d\x8a\xfc', 'server_write_IV': b'\xf3\x9f\t|'}, TlsVersion.SSL30, 16, 20, 8, 0,
                                               {b'\x00#': bytearray(b''), b'\xff\x01': bytearray(b'\x00'),
                                                b'\x00\x1c': bytearray(b'@\x00')},0)
        self.ssl_3_0_aes_128_decryptor = Decryptor(AES, CBC, SHA1, {
            'client_write_MAC_secret': b"l\xa8\x9a\xfe\x0bj\x87\x0c\xdc\xe6&\xca\xd0!\x11\xd1']\x1e\x03",
            'server_write_MAC_secret': b'\xc1\xef4YR\xce\xd3|\xec\xa1 \x89\xa8\xbc:a\x82\x9d\x10_',
            'client_write_key': b'x\x9b:\x13\xea:\xd0!\xb3\xfd\xa71\xec\x91\xca\xff',
            'server_write_key': b'\x88\xa1\xc3\xf3\xafNs\xe8\xd4\xb8\xf1\xcf\\\x1e\xb5\x8b',
            'client_write_IV': b'\x97\xed\x01\x90\x08\x1a\x0fUv\x86Gx\x92\xa9\xd1)',
            'server_write_IV': b'\x06d\xefLg\xc6;\xdb\x80\x96\x94R\xd1b[['}, TlsVersion.SSL30, 16, 20, 8, 128,
                                                   {b'\x00\x16': bytearray(b''), b'\x00#': bytearray(b''),
                                                    b'\xff\x01': bytearray(b'\x00'), b'\x00\x1c': bytearray(b'@\x00')},0)
        self.ssl_3_0_aes_256_decryptor = Decryptor(AES, CBC, SHA1, {
            'client_write_MAC_secret': b'a\xba\xdf\xb6g\x9f\xe8\x9d)S\xd5O\x9c\xb8\xa0\xd9\x03\x84\xad4',
            'server_write_MAC_secret': b'\x89\xb5\xe0j\x06\x90\x1b\xfa]&\xcb\x8ed\xf7\xbf<\xbf\x16b\x1d',
            'client_write_key': b"\xc2\xffK\xd9xs\x88\xe1\xc6\xbe\xf7\xabW\xc7\xba)I\xc8\xf4\x9d\x13\xbf'O\x99l*\xde\xa8V\xfb\xc5",
            'server_write_key': b'%\xf8Os\xa2\xa6p\xd5\xbb\xc8\x11\xday\x91\xe0\x8fr\xc1\x00(\xcb\x85\xc2\xcf\xc3%\xa0\xdc\x08\x01*0',
            'client_write_IV': b'\xb6\xf3\xc2\x1fB\xe4\xd9\x8f\xbfN\x96.]\xd7\x8d\xfb',
            'server_write_IV': b'3\xf3\xedsE\x8a\xd4O\x01\x01\\/I~\x1f\x88'}, TlsVersion.SSL30, 32, 20, 16, 128,
                                                   {b'\x00\x16': bytearray(b''), b'\x00#': bytearray(b''),
                                                    b'\xff\x01': bytearray(b'\x00'), b'\x00\x1c': bytearray(b'@\x00')},0)
        self.ssl_3_0_3des_ebe_cbc_decryptor = Decryptor(TripleDES, CBC, SHA1, {
            'client_write_MAC_secret': b'\xaaZ\xc7\xbd\xa1=\xb1\x8aBT2\xa3X\xe2\xef\x03\xd3NiB',
            'server_write_MAC_secret': b'\xac\x98 _w\xb8bqK\x85-\x06\xc4l\xa4\xf0\x1f\xdb\rO',
            'client_write_key': b'P\x12ji\xeb\xdc\xff\x10\xf5\xe29\r\xba\x07p\x19\x14&\x17\xe2\xf9\xa0\x11V',
            'server_write_key': b'\x1a@\x01o\x1f\x15*t\xdb\x18A\x8a\\\x82[?p\x97\xaf}c\x16\xd3\xb0',
            'client_write_IV': b'\xd1\xa5\x01\x03\x93\x90\xc1\x8a', 'server_write_IV': b'\xbbmG\xcb\x9f\xccx\xb5'},
                                                        TlsVersion.SSL30, 24, 20, 16, 64,
                                                        {b'\x00\x16': bytearray(b''), b'\x00#': bytearray(b''),
                                                         b'\xff\x01': bytearray(b'\x00'),
                                                         b'\x00\x1c': bytearray(b'@\x00')},0)

        self.ssl_3_0_camellia_128_decryptor = Decryptor(Camellia, CBC, SHA1, {
            'client_write_MAC_secret': b'\xb5\xeb\xa5\xed\xae:\xc8\xe0\\\xf8!\x80\xe4G\x1d\xe4g\xd3\xa6"',
            'server_write_MAC_secret': b'\xe7\xdb\x18P\x00\xa7CZ9\xfc\xcd\xcb?\x1a\x06\xbe\xd6o\xa2e',
            'client_write_key': b'K\xe6D[df\xdf\x87mOw\xac\xa4\xdc\xffX',
            'server_write_key': b'\xb1\xd3X\x06\xca3AZ\xf95\xdck\x94T\x92\xf0',
            'client_write_IV': b'\\\x0f\\Z\n\xeey\xefg\x1a&\xb2zx\x97`',
            'server_write_IV': b'\x83\x80\xf1\x04\x97\xae\xf5\xc9\xdf\x05{l\xf0\xee\xcd\xe8'},
                                                        TlsVersion.SSL30, 16, 20, 16, 128,
                                                        {b'\x00\x16': bytearray(b''), b'\x00#': bytearray(b''),
                                                         b'\xff\x01': bytearray(b'\x00'),
                                                         b'\x00\x1c': bytearray(b'@\x00')},0)

        self.ssl_3_0_camellia_256_decryptor = Decryptor(Camellia, CBC, SHA1, {
            'client_write_MAC_secret': b'\x93\x04\x9cm\xca\x92\x9a\xb4u\xfd6\xc0\xa3\xa9v\xee\x80QX4',
            'server_write_MAC_secret': b'HQX\x8d\xdfd\x9aR\x1f\x16X\xf7,gVI$\x82%\x9b',
            'client_write_key': b'\xec\xdf\xfb\xd5cb\x101\xab\xcb\xc8 \xd3\x86\xaa\x85#\x04\xd6\xc99X\xba\xf0\xaa\xabG\xbeC:\x89\x15',
            'server_write_key': b'e\xe4\xcf\xb7<\x18$\x15\xc0\x8fa\x06J\x17\xb0\xb1\xbdUR\x9cWQk\x11\xc4\xef(\x91Q\x91\x95\x80',
            'client_write_IV': b'%\x17\xb9\xf4\xfe\xc6\x18\x1f\xf4\xe5I\x97\xab\x8eQ\xea',
            'server_write_IV': b'E\xe9u\x9cr\t\x1b\x8a\xa6\n9\xa02"\x1b%'},
                                                        TlsVersion.SSL30, 32, 20, 16, 128,
                                                        {b'\x00\x16': bytearray(b''), b'\x00#': bytearray(b''),
                                                         b'\xff\x01': bytearray(b'\x00'),
                                                         b'\x00\x1c': bytearray(b'@\x00')},0)

    def test_rc4_decrypt(self):
        client_1 = TlsRecord(bytearray(
            b'\x16\x03\x00\x00<(\xb8("\x186j\xf2\xdf\xf4u\x92\x9e~p\x9fL\x1c\x96\xf8\xdc{%\xd6T\x0b\x82\xc7\xb0\xec\xb1a\x88\xe2%\x05\x15\xa17d\x08{\xf1)\xda\xbc\x84\x08\xc2\xb1\xba\xb3(\xc4\xd9\xc8\xc8\xf1)K'),
            [], False)
        server_1 = TlsRecord(bytearray(
            b'\x16\x03\x00\x00<\xd4T\xbb\xe4LU\xf3\xac\xf1\x96\x91\xb6Y\xf3\x96\xa3~\xa6tU\xbd\xe5\xf4h\x9e0\xde\x1bB]\xb8%qC\xe82)\x11\xb1\x04\xea\xf9\xc2\x92\xae\x13ZB{\n-\x0f\xb5c\xd2\x98\x1c\xf2C '),
            [], True)
        client_2 = TlsRecord(bytearray(
            b'\x17\x03\x00\x00\x1a\xf5\xbaBE\x11\xef\x13\xf8n\xbd\xfe\xe5.\x8d!W\xe03r\xb3\xeb\r:\xd9\x16\x11'), [],
            False)
        server_2 = TlsRecord(bytearray(
            b'\x17\x03\x00\x00\x1a\x04\xb89\xf3\xe2\xc4\xe8|\xfc\xe7b\xb7g\x81\x16\x07\x9d\x8eb\x97\x84\xa9\x89\x19\x11K'),
            [], True)
        client_3 = TlsRecord(bytearray(
            b'\x17\x03\x00\x03\x8d\xd6\x04IN\xfb\xac\x0f\x8cJr^\xac\xe3@\xb9I4Xvf\xa1\xff\xd0\xb2\xbez\x9a\xc0M\xd6P\x9b\xbf\x87W\x90\x13\xd7v.\x89\x0e\x05\xc7\xbev\xfe\xad\xbb=?\x03kj\xe0-\xdc\xe9\xf6Q\xcb\xbd\xad\x1e,\x02(\xb6i\xfe\xec\x11\x1e\xf3C7\x99\x9a\xdc\xf0\xd4\xbc\x0b5\xb3\x9a\x14\xa6\x13\xcf\xdb`@A\xf2H\xb9n_\xda\xdd\xf3\x1ff:\xb0\x13\xde\x12\x83\xd3W\xbd\x91U\x91Kil\n}/\x0e\xd3\x8d\xc0\x1b\xa3I\xea\xdb\x08\xcd\xd5\xec\xcc\xa3\xd0\xfa\xa9\xd6\x05w\\\'\xa3-\x0c\xead\xce\x18\xcd\xddd#\x1d\x99D\xdc}\x82\xe3Bq\x1f\xf0\x07\xfa\x06\xe3\xb2\x9a)wT.r\x05\xe27\xab\xab\xc7Mc\xd2\xf9[\x96\xa8F\xb3\xd8\x81\xebp\t\xed\x15C\xf3n\x98\x9e;\xa5o-\x1b"\x94\xe6\xfd\x98\xed\xbf&g\x00\x02\xa9\xc3c\xac,\x8d\xf0\xdfq^\x1ac\xb3\x7f\xc4\xac\xb02\xef\xc7\x8eS`\xd7\x98\x83~\xe4\xcd \xbf\xd4.\xc4\xb9\xb7\x9f>\xb9Xh\xb8\xa0%\xd3T:\x90\x9c\xf6\x0e6\xd4\x9c\x11\xbemB\xfd\xa6\x8c\xb1\x8f\xc3\x8f\x07\x9e\xefD?C\t\xb9_w\xda]\x9a\x01\x9a\xf7\xd1\x1a90_\x8a8\xaf\xe8\xafp\x0c\xbe\x94bN\xf7P\x11\x89\x10Y:\x8c\x85YF\x02\x1f\xd4\x02\xd7\x89_&Q\xb1a\x07\x9bUog\xcf\x90"\xeeV"\xa7\x84\x94\x03\xe0\xc8\xd5\x88\xd6\xa9\xfa\xfc\'\x89(>\xd55\xae\xd4$~\xb5)\xb5\'\x07\xa0\xe7\x9ec\xfb\xfd\xdfL{\xbd\xfaK\xee\xc4K\xfe\xd9\x88\x8d\xe7\xbf\xea\'&\xac\x97\x1b\xbes\xdeO\x8c\xa54G\xa2\xa6\x96\xfa\x9d%\x19\x07\x99\xd7\xb0\xf5\x8c\x05\'\xa8.\x18\x1e\xe3\xe2d\xf4m$\xab\xc8~i?\xaf\xd3F]\xe9K`\xe5i>s\xc3=uj\xe8\xa6\x18\x13\xd7\xfa\xd7\xff\xdc\x99h>\xab\xf3;]\xc6!\xf2\xc9\xe4\xde\x19 \x17\x99\x1a\xd2\xd2<\xc9\r/\xc8\xd0\x0f+\\\xb4\xe0X\xce\xa4\xa8\x17;\xac\xfcKZ\xbb\xf7\xcd8\x80\xb3P{\x90e\x7f\xfdo\x03\xa1[i\x07\xab\x9eG\xa0\xa9P\x00;\x08\xa3\xe7\xc6\x1a,JQ\\l \xb2B(\xb1\x01E\xa0\xf5U\xdb\xb1\x06j\xbcjW\xcdu:\xcfd\x95*\x9f\xfa\x9c\xf7\xc8:h\x8d(\xdc\xd3\x1c\x99v\x81\xe68\x01=S5a)\xd4\xe5\x1dF\xd3\xba7]\xe9\xda4G\xd2|\x8d\xf6\xbf\x9e\xad3\x92I\xe8\x95\xba\xe6\x9c\x0f\xa5?Bv\xb9l\xb9\x18&\x90\xfa\xa2\xc3\x8f3\xb9\xf3\xf2\xc5\x03\x12z\xf8\xae\xdf\xee\x0ez\x1f\\\x08l~\x90AS\x93\xeb\x04t9\x12q"\x01m\x1b\x11\x8d\xfe\xa6~\xc6wD\x1a\x02\x84\xc9v,8\xbf \x8a\xae\xcf\x8el\xaf\xfa\xf4\x15\xe8f\x95\xb4\x91\x8d\x9ena9\xd3\x04\x83dZ\xa3\xc8#\x9fx\xd0\xa1,0v\x94\xb5\xf2\xb1\x1by\x0b\xe6\x9c\xb0iku\xad/+\x19b\xa2\xec\xf4)bL\xadS%\x16\x03\xc7q\xe9\x15&\x05`\x8c-.\x17\xb7c\x177q\x88\xbe\x98\xdb\xf1\xaa=\xe8\xa4\x18&\x00\xdb\xcd\xfb~%f\xce\x80\xb3Q+\'\xb0\x94H\xab\x9dy-;\xbb\xb7\x0c\x9fx\xc5&]m\xb1\x04\xf7Q\xa0P\xbd\xd3d\x03\x86T\xd6s\xfd\xb2\xfe\x05\xa5\xcd9%O\x9e\x82ky\x17\xfbBK\x0e@>C\xaa\x8c\x13^\x12\x9f\x9aM\x9e\xcd\xdf\x91\xe0{\xbb\xa72\x849\xbe8\xf2\xdcj\x1a\xd8:\x04B\x0fK\x1dB\xbb\xc8 O|\xed\xa2\x9f\xf4\xfc\xf0\x97\xe1^\t\xe8f\xbe\x96mje\xa4#B\x91!\xc9\xae\xa1\xd6\xbbi\x043\xca\xbc\xc7'),
            [], False)
        server_3 = TlsRecord(bytearray(
            b'\x17\x03\x00\x03\x8d\xfa|\x8f\t6\x03\xdb\x81`\xf9\xb0U\xdf\x85\xb2,\xf0\xd6k\xce\xcd\x05\xdd\xbdCoC\xad6\xe1l\xe3\xbe\xf1\x1af:M8\x82\xcb3tOi%w\xc8\x0c\x00\xeb\xf4\xa8\x10W.\x18\x11[^4Y?G\xf8\xfa\x9d\x84\xc8$:a\x1dR\xd7\xc5\x0bdE\x0b2$2\x19\xb9\xcd\x10!\x8a^lcs\x87s\xc1il\xe9\x8e8\x98\xfco\xd0U\xb1\x7f\x18\xda\xdc\xc8g\x0e]\xb7D\x98D#\xc4\x15\xb6\x9b`\xbc/D\x04\xaf3\xc0\x1d)\x98S\x8f\xaa\x04\xb1\xebv\xe38C\x1e\xc9K@J\x95\xba$\xb8\\\r\xe8\x9b\xf3\xec\rP\x9c\x8d$\xe5S\xae_\xba{\x12\x89I\x8d#\xfb\x81\xa86\x01\x1c\xe0-5\x15u\x89\x99x}\x10\xd3\x9d\xa4\x9d\xd8z\xb17>~\xf9\xb3\xbas!\x84\xbf\xf7\x8e\xd2\xc2\xe79\x8c\x8bb\xc1\x94\xf7\xef\n_pv\x94)\x0b@\x17\xaaz\x0e\xc0B\\yq\xee\n\xae\xd9\xa3\xae\xf7D\x00h\xe8un\x97|Q8\xcd\x958\x874\xc1\x03\x8dh!\xc0\xe6\x92>\xb0GCBO\xc2\x0f\xf9!`\x97\x0e\xa9<0]\x99\xfb\xbd\xc2H\x87\xd8\x1c\xa8\xf9&Xx\xaes1\x15\x8bN\x07yqrl\x94\xb4\x8bI{\x0e\no\xae:\x937s\xa9\xca\xea\x02\xc7\xa0/\xbf\xf7\x84\xb53\x95\xadG\x03\xa6]"o\\\xfe=\xe8M\x8e\x9e\xcfw\t.\xc7gv\x14I\xf2\xd7g-\xcas:\xd8_0:B\x07Nsc\xe0\xb4A\xbc\x10t\x15\xb6\xbc\x0e\xb6e\xee\xdb\x17r\xce\x94\x9d\xf7\x17x\xa9\xb8\xc9\x07+B\x9c\xfb\x89\xd4:\xa7\xa3G\x88\xe2\xb6"\xb5\xfft\x9d\x05e\x83`\xc3\x15\xc8HF\x07N\x92\xd5\x8a\xcdL\xcf\x9e\x18\xfe\xd8\x9b\xf0n\xeeo.\xfd\xef\xd2\xdfZ\x87o\x96\x87?\xc0\xa9\xd3\xf1p\x80S\x84\xa9\xd1Y4}\xa0\xd9tU`|X\xbc:6\\\x0e\xa1\xc8 v\xf2\x8f\xf7\x10W\x85\xa28\rAb\xf0S\xbd\x19:\r"\x9c\xcbvx\x93\x1f[\x14#\xbeGu\x15\xec\xa8\xa5\xec\xf1\xe0\x0f\x86\x14\x8fD\xfa\x8a\xc1\xd2\x9c\x05\xf5\xa1+\xc6\xc1\x1d\x88\x9e\xab7\x90:\x12\xdbc\xc5\x13\xe3\x90\xce\xd0\x95ig8\x91\xcf\x87r<\xde4\x10\xb2\x9c\n\xb5Nb\xbf\xbc#r\xaf\xce\xa1h9\xdd\xf8\x07\x06\x7ff\x94*}\xb1\x1dW?\x15\xd4X \x8f E?\x8d;\x03B\x91\x10(m\xd0\x1c\xb8n\xfd\x7f\xf0U\x0e\xedd\x88,6grM\x18\x03 3\xdd\xd6\x80\xe09\xf2\xba\x87\xabc#b\x1d\xfd/5Q\xd7\x97\x88\xf1\xd4\xf6\x82\x8fWJ\x80MH\xd7V\x98\xd1\xec1.$.\x15S\x89\x8auY\xdf\xc2\x87\xca\n\xf8a\xc5\\\xdc1\xd0e\x05\x11\x88\xa1\x93\xf2M\xe6\x12\x89\xd2\xa4\x94\xd9\x98V\xbb\x82\x1a\xce\xc7\x01[\xee\xff\x0e\xd0\x9f\xcc\xf0u<\xe2\x0cY`\xdd\xd0\xa3+n\x0b\xfe\xed\xb7Mp\xf0\x02\x8dG,sEiqiF!%6\x19/z\xd7&H-\xa5\xe9\xbd\xe9\xe4+_\xbdn\xc11\x07H\xbf\xfel\xdb\x9f"_{\x0e}o\xfc\xaa3M\xdcH(\x97\xf5\x0c\x88\x06\xc7uW\xeb\xe9\xed\x13[\x18\xb5\x9a*\xa4 H\r\x96I\x92\xb7\x1a\xdf\x18H\x9b\x99i\x1cz[\x01C\xb4\xf7\xbd&\xdc,xo\n\t\xc2\x89\to*\xf8r\n^-L\x81\xd5\xaeJ\xb8\x1fX@\xc9\xfc\xf8\xa0\x03\xe5 \xd8\xec\x96\xd7\xcc\x06\xec\xb2_+\xfe\x9f\x85D\ne\x1e\xf0G\xc7V\x92\xa1\x1b\xaf\xb9\x80\xdd>x\xb5\xc1\xf4\xc1\x0c9\xe8\xbbS\xd5\xe9\x11\x8f\xfc\xe9\x98\x92\xe3'),
            [], True)

        self.assertEqual(self.ssl_3_0_rc4_decryptor.decrypt(client_1, False),
                         b'\x14\x00\x00$x-\xbc\x7f\xa9\xd6b~U;;\xfbQ2t\xf9\xf3\x94\xa9\x9f\xfc\x1fGj\xd5\xe1w\x98\xe7\x17\xbaX\xfc\xbd\xac\x9e')
        self.assertEqual(self.ssl_3_0_rc4_decryptor.decrypt(server_1, True),
                         b'\x14\x00\x00$\x81\xb8{\x8b^\xb4F\xb0&NGe\xd61\x13\xdd\r9\xccY|-a,}\xb6~\xce\xcb\xfd3\xe8\xf1\x9aM\xea')
        self.assertEqual(self.ssl_3_0_rc4_decryptor.decrypt(client_2, False), b'Lorem\n')
        self.assertEqual(self.ssl_3_0_rc4_decryptor.decrypt(server_2, True), b'Lorem\n')
        self.assertEqual(self.ssl_3_0_rc4_decryptor.decrypt(client_3, False),
                         b'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. \n')
        self.assertEqual(self.ssl_3_0_rc4_decryptor.decrypt(server_3, True),
                         b'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. \n')

    def test_aes_128_decrypt(self):
        client_1 = TlsRecord(bytearray(
            b'\x16\x03\x00\x00D\x0e\xc5,\xe1\x0c\xa4\xba\x87!Mn\xd9H\x93c\xbf\xc7\x01\x91\xcd\x95w<M\xf5*\xfcr\xbfQR\xf7\xb7\x7f\x9f\x18Zi\x8a\x7f\xefs\xa9\x8f\x97\xa4\x85L\xa6+\xcb\x0b\xbcM\xff_G\xbf&9jG\x8d\x1aVW\x86\x87'),
            [], False)
        server_1 = TlsRecord(bytearray(
            b'\x16\x03\x00\x00D+\xed\x10\\l\xf8\x84\xbf\xe2\xc6Hk\x929\xb3\x852F\x81\x87\x0b\xae\x11\x1f|s\xdd\xf1\xe0\x15\xc3;\x84\x9f\xd2\xc9\x9f*\r\xfc@!{*93\xf1D\x14\xa7\x8dKQ\xa6\xa5\xb11s\xb8:\x99\xe2\x07GX\x04\xb7\x9c'),
            [], True)
        client_2 = TlsRecord(bytearray(
            b'\x17\x03\x00\x00$e\xabX\xd3#T\x89\x0e\x843\x1c\xf9\x99D\xfbL\x10\xb0\x89\x10\x99_\xddA2X\xda7\xc4\xec\xc1\x94\x12\x8dDv'),
            [], False)
        server_2 = TlsRecord(bytearray(
            b'\x17\x03\x00\x00$\x99\xe7\x8d\xa7\x9ct\x88\x05\x0c\xa9\xbe4[A\x91EfM\xde\xce.\xbc\xa8\xb0}\x82.\xad\xb2T[\x14"\xfd\'\xe0'),
            [], True)

        self.assertEqual(self.ssl_3_0_aes_128_decryptor.decrypt(client_1, False),
                         b'\x14\x00\x00$\xb8\xd6\xf9J\xaayR\xbd\xf4TY_\xe3N\xb7\x9ai\x85\x0f\x16\xb4s\x0c\xef\xc4\x88V\xe7VI\xa4\x04*L\xef#')
        self.assertEqual(self.ssl_3_0_aes_128_decryptor.decrypt(server_1, True),
                         b'\x14\x00\x00$\xb1nYG\xb8\xc6\x97\x00t\xee\xbf\xd0\xae\xfc\x0fLci\xf6z\xb5D\x85\xddgD\xbc\xa7\x1a\x88\xfc.\x10\xf1r{')
        self.assertEqual(self.ssl_3_0_aes_128_decryptor.decrypt(client_2, False), b'Lorem\n')
        self.assertEqual(self.ssl_3_0_aes_128_decryptor.decrypt(server_2, True), b'Lorem\n')

    def test_aes_256_decrypt(self):
        client_1 = TlsRecord(bytearray(
            b'\x16\x03\x00\x00D\xa0\n\xecv\x83,\xe3\xcaI\x18\xf5\x1f\x1c\xfc8]\xbd\xe2 \x0b\xb5dS\xbf\x8e\xb4#\xe4\x1cPB\xf4\x80l\x87y\x98\x8d\x89,\x80\xbe\x04\xd2\xdb\xae\x94\x0c\xf2\x80\xe6%\xf3\xca\xaa5\x0f\xe1#\xa1Joy\xfbJ\x8b\xae\xb7'),
            [], False)
        server_1 = TlsRecord(bytearray(
            b'\x16\x03\x00\x00D\xfc\x12`)\xb1\nD\xf8U< \xf6/\x938\x1d\xc0I\x85{\x1b.,\xe8\x92\xf6m$\x94N%*=Y\x96"\xf3\x8f\x02\x10\xca\xdd\xb0\x85uN6M\x86\xf1L\xa7\xa4Xq\xcd\xb0\xdb\xa5k*\x07`\xaf\xd0\x08\x16r'),
            [], True)
        client_2 = TlsRecord(bytearray(
            b'\x17\x03\x00\x00$L\x96\xa9W\x1bU\xba\n\x07\xc1\x1d>\rIT\x93\x89\xe2\xd6\xd9\x9d\xa5\xe4\xd9Y\xa2\x83\xea\x06\xdd\xa1-\xd9\xc9\x89Q'),
            [], False)
        server_2 = TlsRecord(bytearray(
            b"\x17\x03\x00\x00$4\x9aCspN\xc0\xbce\'y\'\x00\x11\x99z]\x8d\x93\x82\xf5\xd8~\x87\xc8\x9a\xd8\xbe\xa1\xabz\x96\xd2\\\x08|"),
            [], True)

        self.assertEqual(self.ssl_3_0_aes_256_decryptor.decrypt(client_1, False),
                         b'\x14\x00\x00$\xeaJ\xda\xe2\xb6{=\x13\xf0Sjo\xb1D\xc6\x95&p\x14\xee\xdeK\xa3\x84f2v\xc9\xb4\xa1\xd7\xb0\xdc\x13_\xda')
        self.assertEqual(self.ssl_3_0_aes_256_decryptor.decrypt(server_1, True),
                         b'\x14\x00\x00$\x84\xc7\xec"\x16_\x18\x18\x11\x93\xfa\r1\xa4\x90-\xcca\xd3\x0e\xb8:\xeb\xfdx\xa6O\xa9#\xd2`<\xfd\x87\xa9\x12')
        self.assertEqual(self.ssl_3_0_aes_256_decryptor.decrypt(client_2, False), b'Lorem\n')
        self.assertEqual(self.ssl_3_0_aes_256_decryptor.decrypt(server_2, True), b'Lorem\n')

    def test_3des_decrypt(self):
        client_1 = TlsRecord(bytearray(
            b'\x16\x03\x00\x00D\xa2\x8a<p|\x13\xa6\xd0\x83\xb9\xb8\xf2\xffw5\xa3\x10\'\x07\x8cR\xc3\xa3\xc1\x18\x8a\x1d\x8c]s\x95b\xe7\x97\x1d\xd7y\x17lo\x12i\x91\xd0r\x85\xea\xb1\xfd\xcd\xc6\xa15\xe3\xd7\xfc\x95\xab\x04<\xd7\xe0\xd0?"\x0b\x19\xcd'),
            [], False)
        server_1 = TlsRecord(bytearray(
            b'\x16\x03\x00\x00D\xf5\x83\xa3\x03\x98\xd2\xf9\xec\xa3x\xecP\x14\x82\xd1\xc4s14\x0b&\xb5Z\x93\x98\x0eU\xd3\xaf\xe5\x0eU\x03\x8e\xf6\x87\xfcBh\xb5D\xb1\x93\x02Zq\xe4\xa3fR\xe8\xc3\xe7\xe0\x99\x8a\x0bH\xb7\xa3\xbc\xaf<!\x00\xf6c\xa8'),
            [], True)
        client_2 = TlsRecord(
            bytearray(b'\x17\x03\x00\x00\x1c\xdaE\x89\xf8w\x12\xef|\xd1\\?tG\xb9\xddb(&\x93\xbb\tY\x1e\x19\xd4{\xc1*'),
            [], False)
        server_2 = TlsRecord(
            bytearray(b'\x17\x03\x00\x00\x1c\xd1\xcau8\x1ek\xdfuK\xd2\xd3\xe6[Y-\xe3=\xa0Mb\x1fSWYty\n\x01'),
            [], True)

        self.assertEqual(self.ssl_3_0_3des_ebe_cbc_decryptor.decrypt(client_1, False),
                         b'\x14\x00\x00$\xea\x89\xf2,\xdd,\xd3\xf5\xcdS\xd9\xff\xb5"6\x7f\x8e\xf2\xb1a\xbe{\xb7T9O]\xed~}\xffO|\x9eZ\xb0')
        self.assertEqual(self.ssl_3_0_3des_ebe_cbc_decryptor.decrypt(server_1, True),
                         b'\x14\x00\x00$2\n\xa5\xfc\x96\x8c\x05\xf3\xd9^w8\xc9\x85R\x95|\xba#\xc2zX\xcd\xaf\xe5\xf4":/\xba\x0e\xcf\x08)\xee\xdf')
        self.assertEqual(self.ssl_3_0_3des_ebe_cbc_decryptor.decrypt(client_2, False), b'Lorem\n')
        self.assertEqual(self.ssl_3_0_3des_ebe_cbc_decryptor.decrypt(server_2, True), b'Lorem\n')

    def test_camellia_128_decrypt(self):
        client_1 = TlsRecord(bytearray(
            b'\x16\x03\x00\x00D\x0c\xc0\xb7p\xc2\xf6S\xb5F2\xb2VN\xa3\xe7\x9a\\\xb6\xa0fD\xa8I\xf8\xcc\x93QP5\xd7w\nN\x18\xfe\x13n\xa3\x1f\x15\xd8QwM4N-\x9bV,\xe8)/)\x89\x11(\xe58\xeb\xdc\x9e\x82\xba\x89(+r'),
            [], False)
        server_1 = TlsRecord(bytearray(
            b"\x16\x03\x00\x00D\xa7\xf2IP\xc1\xb8\xf7\x1f\x8ec\xe9Y\xc5\x86\x9bLK\x81h\x84\x87\x1d\xc96\xcb~\xbc\'}\xbf\x85*\x8f\xb5]\x88\xa5C\xb1c\xaf\x96e5\xf9\xfb\x87qzn\x8a=\xc38\x06B\xeb7\xf3\x99\x8c\x92\xd1V\xf1\xf2\xa8t"),
            [], True)
        client_2 = TlsRecord(
            bytearray(
                b'\x17\x03\x00\x00$\x14Y=$W\xd5\x9a^\x16\x01\xd9\x8a\xce\xcc\xb1\xfe\x0fb\xc6z\x11`\xfdb\x06Y\xdfcg\x93\x98\xad\x13\xfe0$'),
            [], False)
        server_2 = TlsRecord(
            bytearray(
                b'\x17\x03\x00\x00$L\x03w\x13\xb1w$\x050\x8d\x8d\xd5w0\t\x92oJ}\x93\xb1\xba0R\xf0\x99VV`NB\x02\xe4b\x8c\xac'),
            [], True)

        self.assertEqual(self.ssl_3_0_camellia_128_decryptor.decrypt(client_1, False),
                         b'\x14\x00\x00$\xff\x0c\xc5C\x18\xbd\xa7\xa0\xc4\xc4\xe1\xbf\xe6$\xaeGz\x93\xb0\xcdA\x92\x8d3l\xbdFu\xf6}\xac$T\xb8%\x0e')
        self.assertEqual(self.ssl_3_0_camellia_128_decryptor.decrypt(server_1, True),
                         b"\x14\x00\x00$\x03urquaE\x05\x04\xbe'\xcc\xc0\x1fz\x06\x8b@5\xfaK\xb8x\xf6\xdf\xf6\xeej\x85+\x88\x81h\x9d\xa1>")
        self.assertEqual(self.ssl_3_0_camellia_128_decryptor.decrypt(client_2, False), b'Lorem\n')
        self.assertEqual(self.ssl_3_0_camellia_128_decryptor.decrypt(server_2, True), b'Lorem\n')

    def test_camellia_256_decrypt(self):
        client_1 = TlsRecord(bytearray(
            b"\x16\x03\x00\x00D\x9f6\x81\xdc^\xa3~\xff7\xcck=d\xdd\'\xd7\x0fJxi\xbe\xf4&\x11\xb4\xfb\x86\x9e\x90Ya\x7f\x13\xb0\x89\xcdD\xfeJ^\xf3KhS\xb6-:1\x03rF\xb6o\xa5K+\xc0\x8f{\xdd\x03\x02\xe0!\xef\x1f4\xda"),
            [], False)
        server_1 = TlsRecord(bytearray(
            b'\x16\x03\x00\x00D\x95\x1b\xb1\xe8Z\xd8\x05\xbfRm\xf8O\xdf\x063?G\xb7\xec\xe2\xd2\x82\xc0\x9e\x1e\xa6\x87\x86d\x98m\xa8\x19\x12\n\x8c06\xa1u,\xba\x89\x07\x03\x06;!\x83`\xc3p\x0fNh\x86\x90\xdf\xf3d\x8fh\xdc\x1d^DFz'),
            [], True)
        client_2 = TlsRecord(bytearray(
            b'\x17\x03\x00\x00$\\\xcc\xbc\xc1\xba:\xaf6%\x8a\xceC\xe0\x7f\x04\xbb\x92\xc9 \xac\xef\xfaf\x9c\xaaj\x8eY\x8d\xb3\x07a\xfe\x86\xc8P'),
            [], False)
        server_2 = TlsRecord(bytearray(
            b'\x17\x03\x00\x00$\xbb\x03Z\x15:\tb\xf4\xcct5\xd6%W\xd7\xd0Og\x9a\xb97\x85\xc3\xdf\x91p2\xfb\x8f\xc2\xeb\x90\xa9\xc1\x9c\xf0'),
            [], True)

        self.assertEqual(self.ssl_3_0_camellia_256_decryptor.decrypt(client_1, False),
                         b"\x14\x00\x00$'<&\xd6\xbc\x98\xd5\x1a\x07K\x96\xdde\x98\x91\xb7\xf4\xea5\x8f]x>\x9a\x14<\x82\xf4\xd8U\xfb\xd7\x08k\xe9&")
        self.assertEqual(self.ssl_3_0_camellia_256_decryptor.decrypt(server_1, True),
                         b'\x14\x00\x00$\xc0]\xac."K\x1e\xd9p\x9d9\x97H\xdc%\x87\x80\x1f\x1e\x19\xe9\xd2\x80\xb3d\xd9\xb2\x95\xb7m\xe1\xec\xbca\xfb\xa3')
        self.assertEqual(self.ssl_3_0_camellia_256_decryptor.decrypt(client_2, False), b'Lorem\n')
        self.assertEqual(self.ssl_3_0_camellia_256_decryptor.decrypt(server_2, True), b'Lorem\n')


class TestTls12Decryptor(TestCase):
    def setUp(self) -> None:
        self.tls_1_2_3des_ebe_cbc_decryptor = Decryptor(TripleDES, CBC, SHA1, {
            'client_write_MAC_secret': b'|-\x06+\xf4\xbb\xe3ej\x9dZ\xa8\x96s\xa1\xccB\xb0\xc3\x8e',
            'server_write_MAC_secret': b'_\\\xa7\xa2_\xd1\xab\x1dp,\x94\xfb#\xeas\xe3\xf6\xee\x7f\xe2',
            'client_write_key': b'f\x15\xe3\'\xc4\xd9\xa9\xe4\xe2+t*\x11mT\x9cj\xb4\x8cQ\xd0"\xda\x08',
            'server_write_key': b'\xf9$a<\xd1\xe4\xf0q\xbb<%_\x0b\x0e\n4a\x9a4\x0e\xbaB\xac\xa1',
            'client_write_IV': b"@\xdf'\xfc", 'server_write_IV': b'yE\x7f3'}, TlsVersion.TLS12, 24, 20, 16, 64,
                                                        {b'\x00\x0b': bytearray(b'\x01\x00'),
                                                         b'\x00\x16': bytearray(b''), b'\x00\x17': bytearray(b''),
                                                         b'\x00#': bytearray(b''), b'\xff\x01': bytearray(b'\x00'),
                                                         b'\x00\x1c': bytearray(b'@\x00')},0)

        self.tls_1_2_aes_128_ccm_decryptor = Decryptor(AESCCM, AESCCM, SHA256,
                                                       {'client_write_MAC_secret': b'', 'server_write_MAC_secret': b'',
                                                        'client_write_key': b'E\x8e\x9b\x1d_\x89\xd7g!\x83\xd7\xdc\xda\x99QC',
                                                        'server_write_key': b"\xc4\x8a-\xc1'2\xf9\x1d\xb6\x94CjT\xe7\x8de",
                                                        'client_write_IV': b'\xabV7\xca',
                                                        'server_write_IV': b'\xe0\x1b\xe6o'},
                                                       TlsVersion.TLS12, 16, 32, 16, 128,
                                                       {b'\x00\x17': bytearray(b''), b'\x00#': bytearray(b''),
                                                        b'\xff\x01': bytearray(b'\x00'),
                                                        b'\x00\x1c': bytearray(b'@\x00')},0)

        self.tls_1_2_aes_256_ccm_8_decryptor = Decryptor(AESCCM, AESCCM, SHA256, {'client_write_MAC_secret': b'',
                                                                                  'server_write_MAC_secret': b'',
                                                                                  'client_write_key': b'D\x04\xe1\xb0\x1d8(\x91\xd12-w\n\x16S\x12',
                                                                                  'server_write_key': b'7\xf92M\xbe`\xf4\xcf\xfe\x12\x91\xe9%N\xf8\xb5',
                                                                                  'client_write_IV': b'\x19;Fr',
                                                                                  'server_write_IV': b'\x0b\x98\xd2-'},
                                                         TlsVersion.TLS12, 16, 32, 8, 128,
                                                         {b'\x00\x17': bytearray(b''), b'\x00#': bytearray(b''),
                                                          b'\xff\x01': bytearray(b'\x00'),
                                                          b'\x00\x1c': bytearray(b'@\x00')},0)

        self.tls_1_2_aes_256_cbc_decryptor = Decryptor(AES, CBC, SHA1, {
            'client_write_MAC_secret': b'j\xd0\x15\xe6\xd9#\x8d\x8e\xdaTg\xe6\xd2\x7f)\xd8N\xc1\xb3\xfb',
            'server_write_MAC_secret': b'X{\xef[S\x06k\x98\xe9>\xa9\xfaF\x8c\x02k\x8d\xc1\x0c%',
            'client_write_key': b'S\xde\x00\xac\x15\xae\x06`\x14\x9d\x0e\xb9\x97\xa0\xff\xdc\xaf\xf6;\x945O\x8d\x03\x01\x15\xb0\xd8\xa9\x18\xaa7',
            'server_write_key': b's\xe2H\xc0K-\xb4\xea\xcdS\x8c\\4\xc1C.{\x0c\xfc\x1a\xe4G.\xf3l[\xc3oo\xc6u\xac',
            'client_write_IV': b'\xc219$.\x8f\x1d\x1c\x0e\x1d\xfa\xce\x98H1\xb7',
            'server_write_IV': b'%{\xcb\x8aW\x97\x93\xc28\xb7\x16F\xff\xa7\x1f\xc9'},
                                                       TlsVersion.TLS12, 32, 20, 16, 128,
                                                       {b'\x00\x0b': bytearray(b'\x01\x00'),
                                                        b'\x00\x16': bytearray(b''), b'\x00\x17': bytearray(b''),
                                                        b'\x00#': bytearray(b''), b'\xff\x01': bytearray(b'\x00'),
                                                        b'\x00\x1c': bytearray(b'@\x00')},0)

        self.tls_1_2_aes_256_gcm_decryptor = Decryptor(AESGCM, GCM, SHA384,
                                                       {'client_write_MAC_secret': b'', 'server_write_MAC_secret': b'',
                                                        'client_write_key': b'\xde\xf7\xaa\xc7\xdb\x01\xf8T\xdd~i\xc7\x04\x18\xff\x01\xbc<\x119I\xe4\x1al\xdc\x80\xcbU\xd4\x16w\x17',
                                                        'server_write_key': b'\xcez\xc2B\xb2|\xb1\x15\x99\x1b\x8fx^\xb2}\xb3L\x81\xa5\x91\x1f\nI~>\xdfk\xc1\xe2\x9e\xeb\x1b',
                                                        'client_write_IV': b'p\xe9\x12\xea',
                                                        'server_write_IV': b'ic\x9d\x9f'},
                                                       TlsVersion.TLS12, 32, 48, 16, 128,
                                                       {b'\x00\x0b': bytearray(b'\x01\x00'),
                                                        b'\x00\x17': bytearray(b''), b'\x00#': bytearray(b''),
                                                        b'\xff\x01': bytearray(b'\x00'),
                                                        b'\x00\x1c': bytearray(b'@\x00')},0)

        self.tls_1_2_chacha20_poly1305_decryptor = Decryptor(ChaCha20Poly1305, ChaCha20Poly1305, SHA256,
                                                             {'client_write_MAC_secret': b'',
                                                              'server_write_MAC_secret': b'',
                                                              'client_write_key': b'qq\xb4\x82\x97\x80\x04\xae\xa3R\x1fY\xe61\x80\xc8)]Y\xe3U7o;\xa2\xd04\x94\x80\x8c\xf6-',
                                                              'server_write_key': b"\x9b73\xc0\xf3\xa0\x08\x82\xb5\xb6< \x89&\xa9\xbaB'f\x08v\xbbi\xbak\xff]\t\xa8\xe9\x18c",
                                                              'client_write_IV': b'e\x88\x83\x8d\x1fn\x16\xd8\xda \xc7\x18',
                                                              'server_write_IV': b'\x1d\x8f\xa6\xccJ\xa74J\x1a\xa3\xa9\x8c'},
                                                             TlsVersion.TLS12, 32, 32, 16, 0,
                                                             {b'\x00\x0b': bytearray(b'\x01\x00'),
                                                              b'\x00\x17': bytearray(b''), b'\x00#': bytearray(b''),
                                                              b'\xff\x01': bytearray(b'\x00'),
                                                              b'\x00\x1c': bytearray(b'@\x00')},0)

        self.tls_1_2_rc4_128_decryptor = Decryptor(ARC4, None, SHA1, {
            'client_write_MAC_secret': b"{t\xc2'm\xec\x99\xf9(r\xfa\x92I\xc2\xab\x08._\x9a@",
            'server_write_MAC_secret': b'1\xbf\xb6r\x8fA0\n\x1e\xf7\xf0\xfd"I\xf3\xb3SyC^',
            'client_write_key': b'\r\xb9W-\xea\x89\xa9\xb9\xc8I\xf6\x06\xb0\x05s+',
            'server_write_key': b'\xc8\xea\x0b7\xb4\xfa10uQu\x03\x1e>\xa0\x1d', 'client_write_IV': b'\xb0\xc7&\xa5',
            'server_write_IV': b' \x9a]\xa9'},
                                                   TlsVersion.TLS12, 16, 20, 16, 0,
                                                   {b'\x00\x0b': bytearray(b'\x01\x00'), b'\x00\x17': bytearray(b''),
                                                    b'\x00#': bytearray(b''), b'\xff\x01': bytearray(b'\x00'),
                                                    b'\x00\x1c': bytearray(b'@\x00')},0)

        self.tls_1_2_camellia_128_decryptor = Decryptor(Camellia, CBC, SHA1, {
            'client_write_MAC_secret': b'lM\x04{|\xc0\xcc(nQ\x90x\xdfK\xe2\xc3\x00\xba\xcf\xd8',
            'server_write_MAC_secret': b'\xf6\xca\xb3\xbb\x97\xd0b\x13F\x00LL\xf0\x91\xf6\xdfA\xe8p\xb9',
            'client_write_key': b'\xf8\r-\xa5K\xb9u\x93$\x8eF*\xd4h\x12\x08',
            'server_write_key': b'\xd4\x80\x9e\x8c\xad\x12;\xfe\xf7\x88s]\x919\x8f{',
            'client_write_IV': b'\xf9\xccX\xb6D\r~\x94\x8e{\xc5u\x02\xf9\xc5v',
            'server_write_IV': b'\x0b\xe6\xc2\xb1LKBd\x95}\xf8\x86\xd9\xad1X'},
                                                        TlsVersion.TLS12, 16, 20, 16, 128,
                                                        {b'\x00\x16': bytearray(b''), b'\x00\x17': bytearray(b''),
                                                         b'\x00#': bytearray(b''), b'\xff\x01': bytearray(b'\x00'),
                                                         b'\x00\x1c': bytearray(b'@\x00')},0)

    def test_3des_decrypt(self):
        client_1 = TlsRecord(bytearray(
            b'\x16\x03\x03\x004CB\xde~\x01sd\x82\x1b\xc4\xf2\xfc\x98\x026\x8bZ\x11L\x1a\x93L\xe6&\xa3\xf6\x1e(\x000h\x9a_1o\x98\xe4\xdd\xd0\x9a1\x96\xcd^-X\x0c%\xe1\xae\xb3\xb4'),
            [], False)
        server_1 = TlsRecord(bytearray(
            b'\x16\x03\x03\x004\xe9s\xe3+\xab\x16S\xfe$On\x81\x14\xaf]\x92\x1e\xbcB\xb9(@\x97=n\xa3O6Q\x9b\x93\x81\x80\x1a\\k\xbb\x11\xa5c\x0b?w\xe0\xbb1\xef\xe8\xc2\xe5\xcaG'),
            [], True)
        client_2 = TlsRecord(bytearray(
            b'\x17\x03\x03\x00$\xe1\xfe\xf1\x12\x05D\x05\x11\x00LZ\xd5\x90\xa8W\xa7\xb7\xc8\xba\xe0"\x88\xe9\xa1\xe4\xba\xba\xf0M\xd8\x07\x8db\xae\xc2\xed'),
            [], False)
        server_2 = TlsRecord(bytearray(
            b'\x17\x03\x03\x00$\x96\xc1\x1e\xab\xa8Y\xf5\xfa\xe3\x87\\\x8b\xd7a\xc0\x81\x17y\x07iQxr+\x8b\xa3\x13<\xdf\x0c6\x9d\x83\xa6\xe2\xea'),
            [], True)

        self.assertEqual(self.tls_1_2_3des_ebe_cbc_decryptor.decrypt(client_1, False),
                         b'\x14\x00\x00\x0cO_y6f\x91{\xb4m\x04\x00\xd0')
        self.assertEqual(self.tls_1_2_3des_ebe_cbc_decryptor.decrypt(server_1, True),
                         b'\x14\x00\x00\x0c\x06Y\x94jpU\xb9\xadC\xbalW')
        self.assertEqual(self.tls_1_2_3des_ebe_cbc_decryptor.decrypt(client_2, False), b'Lorem\n')
        self.assertEqual(self.tls_1_2_3des_ebe_cbc_decryptor.decrypt(server_2, True), b'Lorem\n')

    def test_aes_128_ccm_decrypt(self):
        client_1 = TlsRecord(bytearray(
            b'\x16\x03\x03\x00(\x00\x00\x00\x00\x00\x00\x00\x00\xb7\x9d\x8cP\x00\xc4\x87\xda\x97\xda\xdd\x80-\xd8\xcb\xc2\xdd\xed\x87\xc1;\xdd\t\x0c\xa0\xe5C\x0fu\xa1\xceC'),
            [], False)
        server_1 = TlsRecord(bytearray(
            b'\x16\x03\x03\x00(\x00\x00\x00\x00\x00\x00\x00\x00\x81\x8e\x06\x04\t\r%8\xe7Z\xbeg?$\x88=4\xfe*\x91\x10\xday^1\xc8\xa5\rB\xe8\x8b#'),
            [], True)
        client_2 = TlsRecord(bytearray(
            b'\x17\x03\x03\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x01_bh\x10\xb5a\x08\x11\xce\xd7\xb6A\xb9\xab\x1f5\x1b|\x1d7\x89\x8a'),
            [], False)
        server_2 = TlsRecord(bytearray(
            b'\x17\x03\x03\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x01\xca\xdb\xa6\xab\xc2\xe8\xc8\xa2\xf9\xf2\x186\x12\xaa\xa4\x15\x05\xd9\xbc\x1fY\x0f'),
            [], True)

        self.assertEqual(self.tls_1_2_aes_128_ccm_decryptor.decrypt(client_1, False),
                         b'\x14\x00\x00\x0cr1-L\xd1\x81\xe8\xe4\xe3\xd8\x1f\x06')
        self.assertEqual(self.tls_1_2_aes_128_ccm_decryptor.decrypt(server_1, True),
                         b'\x14\x00\x00\x0cp\xbd2\xe2\xbb\xeb1P\xdd\xbf\xa4\xb0')
        self.assertEqual(self.tls_1_2_aes_128_ccm_decryptor.decrypt(client_2, False), b'Lorem\n')
        self.assertEqual(self.tls_1_2_aes_128_ccm_decryptor.decrypt(server_2, True), b'Lorem\n')

    def test_aes_256_ccm_8_decrypt(self):
        client_1 = TlsRecord(bytearray(
            b'\x16\x03\x03\x00 \x00\x00\x00\x00\x00\x00\x00\x00`]\x05\xb1\x80\x1d\xb6\x90Z0\xf9\x0bvZr\xc9\xb3qi\x1c\x0f\xab\xd9\xe6'),
            [], False)
        server_1 = TlsRecord(bytearray(
            b'\x16\x03\x03\x00 \x00\x00\x00\x00\x00\x00\x00\x00g/O,\xf2\xd1\xce\xf4[\x93\x8a\xdfa \x10\x1f@_\xe3\xa2\xb3\xe2\xe8\xf5'),
            [], True)
        client_2 = TlsRecord(
            bytearray(b'\x17\x03\x03\x00\x16\x00\x00\x00\x00\x00\x00\x00\x01\xfc\xba\x17++\xcd1\x8d\xb53@n\xa1\\'), [],
            False)
        server_2 = TlsRecord(
            bytearray(b'\x17\x03\x03\x00\x16\x00\x00\x00\x00\x00\x00\x00\x01PRm\x92\x81^FD\x8f\xe1\xb1\xbaT\xab'), [],
            True)

        self.assertEqual(self.tls_1_2_aes_256_ccm_8_decryptor.decrypt(client_1, False),
                         b'\x14\x00\x00\x0cP\x88_\xec\x89\x88g\xb1\x99P\x1bW')
        self.assertEqual(self.tls_1_2_aes_256_ccm_8_decryptor.decrypt(server_1, True),
                         b'\x14\x00\x00\x0c\xc3T\x05\xda\x9dH\xfe\x9b\xcc\xf3\xf3\x84')
        self.assertEqual(self.tls_1_2_aes_256_ccm_8_decryptor.decrypt(client_2, False), b'Lorem\n')
        self.assertEqual(self.tls_1_2_aes_256_ccm_8_decryptor.decrypt(server_2, True), b'Lorem\n')

    def test_aes_256_cbc_decrypt(self):
        client_1 = TlsRecord(bytearray(
            b"\x16\x03\x03\x00D\x89@(\x87\x0f\x91\x9a.9\xc9 hxKS\xcf\x96@\xb4\x13\x82\x1f\x9c\xef\xb1\xe2w\xaf\'v\x8dl{]\xa0A\xb1\xb1\x06\x89\x00\xf2\x9b\xbf\xa6\x0fe\xd67\x99\xa6\x14\x803\xaf\x8d\xb3\xf5\x16\xdb\xbeIN\xfe9\xf4F~"),
            [], False)
        server_1 = TlsRecord(bytearray(
            b'\x16\x03\x03\x00D\xeb\x9e\x8fw\xf8\xc0\xb0\xe5\xc0\n\xa7\x02Y~\xec\x06Cu\xf0\x91(\xca\x98qdX+\xe4\xf7\xf9E\xf4\xb9\x94\x02\xdf\x9c\x05\xe5AlD\xaa.\x18\xc4\xd6\xb5\x8c\xb2/\x17\x19\xe3[\xb2\x91@\x18O.\xba\xab\xf0\xe66q\x16'),
            [], True)
        client_2 = TlsRecord(bytearray(
            b'\x17\x03\x03\x004\xee\x90\xd5\x93\xb0d\xa8)\x81\x12Y\xf0\x8b/\xf1\xc8b\xa6\xbb\xfb\x19%\xb0:\xad\x06\x0c\xb1\xb4\xaey\\\xf9]$`\xb5\xdf\n,*\xb5\x99\xf5\xcc\xbcq\xf1\x8b\x1e\x0c\xc2'),
            [], False)
        server_2 = TlsRecord(bytearray(
            b'\x17\x03\x03\x0040\xc6p\xe7m\xf0T|aA\xb7P\xac\xa5\tO\xf0\x15T\x1c\x8b\xe3y\x9c\x1e\x9c\xa2$3\xa7\xed\xb8\xeeq\x94\x8d\xa99\x8fT\x83\x02S\x88\xea \x95\x06\xfen\x9bQ'),
            [], True)

        self.assertEqual(self.tls_1_2_aes_256_cbc_decryptor.decrypt(client_1, False),
                         b'\x14\x00\x00\x0c\xf8\xd2\xe3\x86\xde&7?\xd0\xdd-\x80')
        self.assertEqual(self.tls_1_2_aes_256_cbc_decryptor.decrypt(server_1, True),
                         b'\x14\x00\x00\x0c\x13\xa1\xb0\xa4\xd91\xcf\xac\x87\x1e\xe3\xce')
        self.assertEqual(self.tls_1_2_aes_256_cbc_decryptor.decrypt(client_2, False), b'Lorem\n')
        self.assertEqual(self.tls_1_2_aes_256_cbc_decryptor.decrypt(server_2, True), b'Lorem\n')

    def test_aes_256_gcm_decrypt(self):
        client_1 = TlsRecord(bytearray(
            b'\x16\x03\x03\x00(\x00\x00\x00\x00\x00\x00\x00\x00\xa9\xc9\xa3\xd3E\xf88\xff]\xc8\x86\x80cL\xfc\n#\r-\xef\xa0\x10\xa6\xb4\xcdx\xc9\xccW>\x8b\x99'),
            [], False)
        server_1 = TlsRecord(bytearray(
            b'\x16\x03\x03\x00(\x00\x00\x00\x00\x00\x00\x00\x00_\xf1\xe2=\x12K\x92i$\xbd|\xb7\x1fv=u\xd4t\xfd\xa6l~\xa4\x9c!d\xab\xfc\x8a\x83Q9'),
            [], True)
        client_2 = TlsRecord(bytearray(
            b'\x17\x03\x03\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x01^\x96Bw\xfe(\xc2\xf2\x90\x8c\x08\xa9\x9e\xba\xc2\xd8\x8f\xbe\xb9q\xd4\x01'),
            [], False)
        server_2 = TlsRecord(bytearray(
            b'\x17\x03\x03\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x01|]b\x1an\xf5\xc6|-\xa5\x00\xa3W\xf3\x03I\xc6_g\\\x1e\xfd'),
            [], True)

        self.assertEqual(self.tls_1_2_aes_256_gcm_decryptor.decrypt(client_1, False),
                         b'\x14\x00\x00\x0c\xe2~t\x85W\x10\x99\xcf\xfd\x1e\xa06')
        self.assertEqual(self.tls_1_2_aes_256_gcm_decryptor.decrypt(server_1, True),
                         b'\x14\x00\x00\x0c\xbf\x93"G\xbf\x9e\x96\xeb\xab]\t\xa0')
        self.assertEqual(self.tls_1_2_aes_256_gcm_decryptor.decrypt(client_2, False), b'Lorem\n')
        self.assertEqual(self.tls_1_2_aes_256_gcm_decryptor.decrypt(server_2, True), b'Lorem\n')

    def test_chacha20_poly1305_decrypt(self):
        client_1 = TlsRecord(bytearray(
            b'\x16\x03\x03\x00 \xd3\xe5\xe2\xa7\xd2zJ\xc0\x8e\xdd\x19\xea\xbf\xa4\xda\xbad\x05Pm\x0fh\xdc\xebA\xec\xdf\xb3\x84\x1e^_'),
            [], False)
        server_1 = TlsRecord(bytearray(
            b'\x16\x03\x03\x00 \xfb\xed\xae#\xc9\xca/\xdb\xe7\xb6oUI\xb2\rbO\xc6\x7f\x83\xfa\xf2\xb4\xf9\xa7\xe2\xd8\x99V\xb5\x1at'),
            [], True)
        client_2 = TlsRecord(bytearray(
            b'\x17\x03\x03\x00\x16\xdc\xcd\x02\xe5\xc2\xd2\x82\x8c\x869\xe6\xca~\xe9\x93\xdf\x8e\x8b\xe6I\xba\x8f'), [],
            False)
        server_2 = TlsRecord(bytearray(b'\x17\x03\x03\x00\x16\xe24Gl"?*\xbb\xd4o\x8fN\xa2\xd7Z\x85w-\xb5\x1aU\xce'), [],
                             True)

        self.assertEqual(self.tls_1_2_chacha20_poly1305_decryptor.decrypt(client_1, False),
                         b'\x14\x00\x00\x0c\xde\xbf\xc5_\xf27\xc2\x16c\x89\x8a\xf9')
        self.assertEqual(self.tls_1_2_chacha20_poly1305_decryptor.decrypt(server_1, True),
                         b'\x14\x00\x00\x0c\xc8\xf7\xd2\xda,F\xd05q.\xb2\xe4')
        self.assertEqual(self.tls_1_2_chacha20_poly1305_decryptor.decrypt(client_2, False), b'Lorem\n')
        self.assertEqual(self.tls_1_2_chacha20_poly1305_decryptor.decrypt(server_2, True), b'Lorem\n')

    def test_rc4_128_decrypt(self):
        client_1 = TlsRecord(bytearray(
            b'\x16\x03\x03\x00$.\xff5\xd4A\x01\x1e\x89HS\xa6\xb4\x06\xb1\x1fKK\x98~\x9e\x13\xc8x\xc1\xf9\x98\x12\xb4\x930\x86\xca\xfcZ\x97\x1c'),
            [], False)
        server_1 = TlsRecord(bytearray(
            b'\x16\x03\x03\x00$\x1c\x95|H\xf6\xbeHE\xb9\xc8c!b\x9aT\x0c\xd2\x1c\xc4n(Z\x9b\xefc\xfd\xe5Z\x1ae\xd5\x08\xfc\x85\x98O'),
            [], True)
        client_2 = TlsRecord(
            bytearray(b'\x17\x03\x03\x00\x1a\x9d?\xb7\xa4+wh=\xb3Z\xd7\x96\x96[\x97\xb5%\xf4,\x17=\x1d\xfcf<\xf1'), [],
            False)
        server_2 = TlsRecord(
            bytearray(b'\x17\x03\x03\x00\x1aF\xd7ys\x9d\x0f!\xfa\xb8u\x92\xbdQ\xe3\x9eT\xe5\x8bC%3mtz\xad\x1d'), [],
            True)

        self.assertEqual(self.tls_1_2_rc4_128_decryptor.decrypt(client_1, False),
                         b'\x14\x00\x00\x0c\xb2@\t\xa8\x8dQE\xbf$S/h')
        self.assertEqual(self.tls_1_2_rc4_128_decryptor.decrypt(server_1, True),
                         b'\x14\x00\x00\x0c\xae\x9d\x98\xf8.\xb8\x12\xa0\xc2\x12\xba\xae')
        self.assertEqual(self.tls_1_2_rc4_128_decryptor.decrypt(client_2, False), b'Lorem\n')
        self.assertEqual(self.tls_1_2_rc4_128_decryptor.decrypt(server_2, True), b'Lorem\n')

    def test_camellia_128_cbc_decrypt(self):
        client_1 = TlsRecord(bytearray(
            b'\x16\x03\x03\x00D\x0f\xad\xe3\x03\x81\x8b\xa6J\x87\xa1\xaa\x9d\x916\x81+\xa1z\x10}rol\xa1\xf56yGE\xae\xd3\xb8\x95b&\xb7\x88\xc5\r%\x8f\x9a%@\xe8\x1d\xf5\xd5\xef\xf9\x9c\x9e\xb1h\x1b\x1c\xc4\xf4\xb5\xa6\xd4p\xc4\x0c;\x0c\x9c`'),
                             [], False)
        server_1 = TlsRecord(bytearray(
            b"\x16\x03\x03\x00D\x1c\xb7\xf3\xd3\xb3\xbcSS\x10\'\x14_\xce{\x19\x84\xf0U7\xa2\xa8^\x9a\xb0\xf9\xd7YiS\x92\x92\x1d\x0b\xc6\xb3\x85\x86\x1d-\x90X\rH\xf5E\x97\xc0\xa8\xa4=\xb2`O\xdb\x84\r\xdb\xda\xca\x9b\xf9\x98p\xe0\xd7m!\x1e"),
                             [], True)
        client_2 = TlsRecord(bytearray(
            b'\x17\x03\x03\x004S\x98\x00\xe9\xfeG\xd6\xc37\xf6\x9e\xcc\x16\xe7\x1cH\x94\x15\xe7\xc5\xf6\xf7M\xb9G\xf3\x90\xcd]}Q}\xf1M\xceWF\xff\xd4\x15\xa0\x952\xce=\x8b\xb8%o\x0eL\x04'),
                             [], False)
        server_2 = TlsRecord(bytearray(
            b'\x17\x03\x03\x004\xb5\x1e\x8e\x9dM\xc7\xfer_p\xfb\xf7&.c\x9cA]\xf7\xf3`\xf9\xfc\x9c\x17d\xadY\xf8\xf1I5\xd7\xaf\xf6\xbc\x18\x85|\x02\xee!\xf6\x18\xbf0k\xd7\x10\x06\xd0Z'),
                             [], True)

        self.assertEqual(self.tls_1_2_camellia_128_decryptor.decrypt(client_1, False),
                         b'\x14\x00\x00\x0c9\xb6\x95W\xc8\xc7K\xfd\x91\x11\xd8)')
        self.assertEqual(self.tls_1_2_camellia_128_decryptor.decrypt(server_1, True),
                         b'\x14\x00\x00\x0c+dn\x1f,\xb0T\x933\xcf\xf1\x1a')
        self.assertEqual(self.tls_1_2_camellia_128_decryptor.decrypt(client_2, False), b'Lorem\n')
        self.assertEqual(self.tls_1_2_camellia_128_decryptor.decrypt(server_2, True), b'Lorem\n')


class TestTls10Decryptor(TestCase):
    def setUp(self) -> None:
        self.tls_1_0_3des_ebe_cbc_decryptor = Decryptor(TripleDES, CBC, SHA1, {
            'client_write_MAC_secret': bytearray(b'\xd3\xc1"\x82\x0f\xb2&\xabg\x9ei\x13\xe5\'\x14\xaa"\x93\xc5\xc2'),
            'server_write_MAC_secret': bytearray(b'\x1f\xb0\xd8N\xeb\xe0\x04\x9ai\xd1=o\xcd\xc6\xe3\xf4\xbbP\x16g'),
            'client_write_key': bytearray(b'-z\xfb\x02lA\xe2O\x98yE\xb7\x9c1{;\x9a\xdb\xc7\xe2C\xfa_Q'),
            'server_write_key': bytearray(b'W\xd6],\x1cX\xd6\x92p\xff\x1d\x8a\xf37L\t\x17\xee^a\x8f\xb3\x03\xf6'),
            'client_write_IV': bytearray(b'\xa6\x88\xa9\x9d\xb4\xfaw='),
            'server_write_IV': bytearray(b'\x00m\x9f>X\xe9yD')},
                                                        TlsVersion.TLS10, 24, 20, 16, 64,
                                                        {b'\x00\x16': bytearray(b''), b'\x00\x17': bytearray(b''),
                                                         b'\x00#': bytearray(b''), b'\xff\x01': bytearray(b'\x00'),
                                                         b'\x00\x1c': bytearray(b'@\x00')},0)
        self.tls_1_0_aes_128_cbc_decryptor = Decryptor(AES, CBC, SHA1, {
            'client_write_MAC_secret': bytearray(b'az\xb4O\xad}\xe9(\xcf~\x8c@\xe1\x86\xc3H\xa2_)\x0b'),
            'server_write_MAC_secret': bytearray(b'y\xcb\x03\r\xf0n\xf5`\xc7bc\xcd\x15\xc5\xe7y\xbd2\xadh'),
            'client_write_key': bytearray(b'\xc4x?\xce\x86\xcd\xde4$\x84g\x13\xe3\xdfUq'),
            'server_write_key': bytearray(b'\x90\n\x14}1\xa6P\x03E\xd5n\xa9\x8d\x1e|p'),
            'client_write_IV': bytearray(b'\xc1N\xcbW\x85\xee\xc1r\xed\x80\xaf\\\x16\x93\xa1d'),
            'server_write_IV': bytearray(b'\x8d\xb1\xacT\xe6UT\xf4-\x7f\xad\x9e\xc6I\xac\xb4')},
                                                       TlsVersion.TLS10, 16, 20, 16, 128,
                                                       {b'\x00\x16': bytearray(b''), b'\x00\x17': bytearray(b''),
                                                        b'\x00#': bytearray(b''), b'\xff\x01': bytearray(b'\x00'),
                                                        b'\x00\x1c': bytearray(b'@\x00')},0)

        self.tls_1_0_camellia_cbc_decryptor = Decryptor(Camellia, CBC, SHA1, {
            'client_write_MAC_secret': bytearray(b'\xd8wH\x9cE!\xf9\x1d\x01\x93O\x0eH\xf9)\xf7\x17>`\x01'),
            'server_write_MAC_secret': bytearray(b'\xa7Pk9X\xbe:\xe7\tQ\xa2yc\xa5\x97C\xc7\xd6s*'),
            'client_write_key': bytearray(b'{\x12\x9d\xc5\x17\xa9\xa0\n\x10\xd8\x9d\xb9L\t\x94='),
            'server_write_key': bytearray(b'\xa3\x1a\xc6H\xaa\xaa\x99\xf6w\xbcr=\x1c\xbeK\xfd'),
            'client_write_IV': bytearray(b"\xca,\xc5\xad\xe0\x11EVPSk\xd8\xbf\x86\x02\'"),
            'server_write_IV': bytearray(b'iS \xbd\xea6QCEz\x1f\x05\x97qS-')},
                                                        TlsVersion.TLS10, 16, 20, 16, 128,
                                                        {b'\x00\x16': bytearray(b''), b'\x00\x17': bytearray(b''),
                                                         b'\x00#': bytearray(b''), b'\xff\x01': bytearray(b'\x00'),
                                                         b'\x00\x1c': bytearray(b'@\x00')},0)

        self.tls_1_0_rc4_128_decryptor = Decryptor(ARC4, None, SHA1, {
            'client_write_MAC_secret': bytearray(b'\xa1x[Gn\x91\xa7\xb6w\x97pCZ\xc6\xf8\xa3\xa5\xc3J\xcb'),
            'server_write_MAC_secret': bytearray(b'\xbb\xa3\xe4ncQ\x05\x8d\xa3\x1e0\x87\xf2\x00\x06\x89y\xb5T`'),
            'client_write_key': bytearray(b'\xfe\x0c\x16:\xf4la.+\xa4\xad\xe5\xaf\x99v\xce'),
            'server_write_key': bytearray(b'\xaa\xc3\xefa\xc0\x86\x0fEB\xc3\x95\x82\x81\x11\xb7\xa6'),
            'client_write_IV': bytearray(b'\xdbj\xe5\x99'), 'server_write_IV': bytearray(b'\x82\xbf\xd9\xd4')},
                                                   TlsVersion.TLS10, 16, 20, 16, 0,
                                                   {b'\x00\x17': bytearray(b''), b'\x00#': bytearray(b''),
                                                    b'\xff\x01': bytearray(b'\x00'), b'\x00\x1c': bytearray(b'@\x00')},0)

    def test_3des_decrypt(self):
        client_1 = TlsRecord(bytearray(
            b'\x16\x03\x01\x00,[\x98+^\xae\xd7h\xb0\xdf\xd1\xb6\x08\x8a\x8a\xfam~\xa7\xac\x01PC\xb6-\xc6\xa6\xc2G\x16\x92wUX/\x06u\x05\x98\x1cz\xa9NrC'),
            [], False)
        server_1 = TlsRecord(bytearray(
            b'\x16\x03\x01\x00,\\@\xa1?\x1cNm\x8e\t\xef\x16\x99\xf4\x17\xdemJ\xcf0,|uv\xed\xf2\xf6]=\xdc\xd5d\x17\x8aUcz\x0bF\xa5y\xcae\xe16'),
            [], True)
        client_2 = TlsRecord(bytearray(
            b'\x17\x03\x01\x00\x1c\xdb\x1cj\xbb\xc9\xbc\t\x1e\\\xba\xb6\\\xa5{1k\xc1\x92\x1f\x18\x1eL\xab\xdd\x9aqJ\xc8'),
            [], False)
        server_2 = TlsRecord(
            bytearray(b'\x17\x03\x01\x00\x1c\xcb;qn115\x17Jd.\xd1i\xee\xfa\x03*\n\xd7\x8a)r<\x8d\x83\xe6\xc2a'), [],
            True)

        self.assertEqual(self.tls_1_0_3des_ebe_cbc_decryptor.decrypt(client_1, False),
                         b'\x14\x00\x00\x0cQ-\xf5\xe1\x01~\xe5\xc0\xcd\xe69^')
        self.assertEqual(self.tls_1_0_3des_ebe_cbc_decryptor.decrypt(server_1, True),
                         b'\x14\x00\x00\x0c3Q\xe8\xb9&hb\x0b\x9dX\xa7n')
        self.assertEqual(self.tls_1_0_3des_ebe_cbc_decryptor.decrypt(client_2, False), b'Lorem\n')
        self.assertEqual(self.tls_1_0_3des_ebe_cbc_decryptor.decrypt(server_2, True), b'Lorem\n')

    def test_aes_128_decrypt(self):
        client_1 = TlsRecord(bytearray(
            b"\x16\x03\x01\x004\x01\x94\xd7\xfc(\xe6\x08\x1d\xaf\xa7\x04\x1e\xe2\xa81\xf1Zh\xe1nxF\x90O\x03\xcc\xcb\xcc\xbc\x80N\x04\xfe\x9eI~\x92\xce\x97\x10\xd5Jr\x12\xe4\xa2\xc8\xdb!\xdb\'}"),
            [], False)
        server_1 = TlsRecord(bytearray(
            b'\x16\x03\x01\x004p\xe5c\x81IB\xb6b^\x1b\xe6{\xae\xd3\xf8(\xec-\xfb\x83\x96\xb6\xe9\x18\xb3\xf2y\xea\x9b\xe5\xd0^~zk9\xb0\x14\xc0\xb4\xa0\x89(\x87\x05\xb6\xa3\x93\x14l\x8d}'),
            [], True)
        client_2 = TlsRecord(bytearray(
            b'\x17\x03\x01\x00$\xb8/\x9fl\xb1cy9\xe6\x02\x8f\x03\xef\n\xba\xcf\xc9L8\x1d\x8e8~\xd9\xb1\x83\x8eP\xfe#x\xa1\xba\xb8/z'),
            [], False)
        server_2 = TlsRecord(bytearray(
            b'\x17\x03\x01\x00$\x02\x1aB\xc7\x129\x8c\xc1\x05\xf2\xdf\xa2@\xe9\x8a\xc1\xc9\xef\xee\x8e\x8f\xa5\x1fi\xe2q\xaby\t\x8f\x15\xe6S3\x8aG'),
            [], True)

        self.assertEqual(self.tls_1_0_aes_128_cbc_decryptor.decrypt(client_1, False),
                         b'\x14\x00\x00\x0c+Y\xeb\xb6N\xa8^|\xb8\x7fc`')
        self.assertEqual(self.tls_1_0_aes_128_cbc_decryptor.decrypt(server_1, True),
                         b'\x14\x00\x00\x0c2\xe5\xb7\x01\xb1X\x97*\xaa^\xf7\xdb')
        self.assertEqual(self.tls_1_0_aes_128_cbc_decryptor.decrypt(client_2, False), b'Lorem\n')
        self.assertEqual(self.tls_1_0_aes_128_cbc_decryptor.decrypt(server_2, True), b'Lorem\n')

    def test_camellia_128_decrypt(self):
        client_1 = TlsRecord(bytearray(
            b"\x16\x03\x01\x004\x98\xb2i\x84\xca\x8d\x83\x12\xf9\x9et~\x12\xd3`\xe11\xd2\x8c\x12\'rL_\x06GmK\xb0\x10\xad\x96\x91\x13\xb1^\x1a\xc6|U\xaa\xfa\'B#\r\xf1~\xf3\x19\x897"),
            [], False)
        server_1 = TlsRecord(bytearray(
            b'\x16\x03\x01\x004\x11\xb5?\xed\xb7\x12\x91\x13r\xe3d\xa0G\xca\x009\xdc/\xb4\xb4\xd4\x9e\x17\x87\x01\xbeaf\xfc\x04\xde\xecY\xf6\xcdJ\x8b\xb1\xb4\x04\x06\xfa\xcfh\xcb\xfa\xf0\xcb\xa3W\xf2G'),
            [], True)
        client_2 = TlsRecord(bytearray(
            b'\x17\x03\x01\x00${\xed\x9dN\x0f\x0b\x18\x84\x83\xd3\xd2\xdf\xf9\x0e6\x8bM\xabB\xba\xdb+\x17\xc4\x7f\x18\xabz7\xe4\x9a\x98\x04\x03FV'),
            [], False)
        server_2 = TlsRecord(bytearray(
            b'\x17\x03\x01\x00$\x8d?\xbbz,\x83\xad5\xac@\xfcq\xff\x13\xe5\xb7\x94\x83\xa7\x90\xa3WE7=k\xd3\xc0\xd3 \xb0$\xb9M+\x8f'),
            [], True)

        self.assertEqual(self.tls_1_0_camellia_cbc_decryptor.decrypt(client_1, False),
                         b'\x14\x00\x00\x0cb\xb1k\xb7\x98u\xfe\xc30^\x16\xc6')
        self.assertEqual(self.tls_1_0_camellia_cbc_decryptor.decrypt(server_1, True),
                         b'\x14\x00\x00\x0cmsb\x1a\xd3\xe2\xdf\xc4s@\x1d\xd0')
        self.assertEqual(self.tls_1_0_camellia_cbc_decryptor.decrypt(client_2, False), b'Lorem\n')
        self.assertEqual(self.tls_1_0_camellia_cbc_decryptor.decrypt(server_2, True), b'Lorem\n')

    def test_rc4_128_decrypt(self):
        client_1 = TlsRecord(bytearray(
            b'\x16\x03\x01\x00$\xb2\x06\x8eL\xc8\xf3\xee\x97r\xd4j\x92\xbbS\x19I\xdb\x81\xf9\xca\x7f-\xce\x80\x9a\xd8#\x19\x13f\n\xfe\x9e)\x8d\t'),
            [], False)
        server_1 = TlsRecord(bytearray(
            b'\x16\x03\x01\x00$1\xab#y\x01\x01g\x03\xb78~j0\xbe\xa9\x9a\xedB\x95 {p\t\x0f\x00\xe2\xb9\xeb/%B\xb8\xf4o\xa9\n'),
            [], True)
        client_2 = TlsRecord(bytearray(
            b'\x17\x03\x01\x00\x1a\x06\xaec\x82\x82\xda\x91m\xf5\xa4\xf8z2\xbc\xf9\x8a]\x86\x05\x924\xdb\x0c\xea\x87,'),
            [], False)
        server_2 = TlsRecord(
            bytearray(b"\x17\x03\x01\x00\x1a\x96\x11qBn:\x91\x08/Z\x14\xce\'\xaf\xe7\xd2s\x88\x9e\x1e\x046{uwy"), [],
            True)

        self.assertEqual(self.tls_1_0_rc4_128_decryptor.decrypt(client_1, False),
                         b'\x14\x00\x00\x0c\xb9\xae\xf9\xc8\x1f\x8d\xa2\xb5U\xf5\x15\x07')
        self.assertEqual(self.tls_1_0_rc4_128_decryptor.decrypt(server_1, True),
                         b'\x14\x00\x00\x0c\x84\xff\x0c\x1f\xff\xd5\xe7\xa4\x12\x1f_\xc3')
        self.assertEqual(self.tls_1_0_rc4_128_decryptor.decrypt(client_2, False), b'Lorem\n')
        self.assertEqual(self.tls_1_0_rc4_128_decryptor.decrypt(server_2, True), b'Lorem\n')


class TestTls11Decryptor(TestCase):
    def setUp(self) -> None:
        self.tls_1_1_3des_ebe_cbc_decryptor = Decryptor(TripleDES, CBC, SHA1, {
            'client_write_MAC_secret': bytearray(bytes.fromhex("39616b365fff3df25f8f780cc6f793548d83e730")),
            'server_write_MAC_secret': bytearray(bytes.fromhex("30eb4e4b4329d46eec9f623aa19dec93eaca783c")),
            'client_write_key': bytearray(bytes.fromhex("6423cd5561a7925d2e726277f970477d57161676b94662dc")),
            'server_write_key': bytearray(bytes.fromhex("1e3401fe31c007ea808c4aac7638792e8089ee02b31a6f30")),
            'client_write_IV': bytearray(bytes.fromhex("b3099059c15ba57f")),
            'server_write_IV': bytearray(bytes.fromhex("1ccaf207c85f8a5e"))},
                                                        TlsVersion.TLS11, 24, 20, 16, 64,
                                                        {b'\x00\x16': bytearray(b''), b'\x00\x17': bytearray(b''),
                                                         b'\x00#': bytearray(b''), b'\xff\x01': bytearray(b'\x00'),
                                                         b'\x00\x1c': bytearray(b'@\x00')},0)

        self.tls_1_1_aes_128_cbc_decryptor = Decryptor(AES, CBC, SHA1, {
            'client_write_MAC_secret': bytearray(bytes.fromhex("15289ce0eee45cef881e4e2603ab0df03a3a02a4")),
            'server_write_MAC_secret': bytearray(bytes.fromhex("d0bfbdcd64aa4b74c9099cbcb53a0d4ef526789b")),
            'client_write_key': bytearray(bytes.fromhex("a8f26e8c819162f0f0bc2643d5a7e6aa")),
            'server_write_key': bytearray(bytes.fromhex("70bf9b08939e5de976bf7db9b8af8085")),
            'client_write_IV': bytearray(bytes.fromhex("636f460016cfe020d69bee980568b5dc")),
            'server_write_IV': bytearray(bytes.fromhex("1d4882d8f369e0dfa182dc9b1aaeede0"))},
                                                       TlsVersion.TLS11, 16, 20, 16, 128,
                                                       {b'\x00\x16': bytearray(b''), b'\x00\x17': bytearray(b''),
                                                        b'\x00#': bytearray(b''), b'\xff\x01': bytearray(b'\x00'),
                                                        b'\x00\x1c': bytearray(b'@\x00')},0)

        self.tls_1_1_rc4_128_decryptor = Decryptor(ARC4, None, SHA1, {
            'client_write_MAC_secret': bytearray(bytes.fromhex("eef331005352271862a248691f7ca93f3266059c")),
            'server_write_MAC_secret': bytearray(bytes.fromhex("0e8d276e707c2acd0f9997560c029e12b4dbc45d")),
            'client_write_key': bytearray(bytes.fromhex("ba47c191eb1a1fe244fec9047deca488")),
            'server_write_key': bytearray(bytes.fromhex("68c18974503f4745d9bdb3d22391ed40")),
            'client_write_IV': bytearray(bytes.fromhex("ac8038aa")),
            'server_write_IV': bytearray(bytes.fromhex("ea02a772"))},
                                                   TlsVersion.TLS11, 16, 20, 16, 0,
                                                   {b'\x00\x17': bytearray(b''), b'\x00#': bytearray(b''),
                                                    b'\xff\x01': bytearray(b'\x00'), b'\x00\x1c': bytearray(b'@\x00')},0)

        self.tls_1_1_camellia_128_decryptor = Decryptor(Camellia, CBC, SHA1, {
            'client_write_MAC_secret': bytearray(b'\x0c0\xf2\x86\xff\xc4\xd0\xb2F\x1c\xd0\xad@a^\x88\xa7\xee\xebQ'),
            'server_write_MAC_secret': bytearray(b'T\x9fZ\x10\xe7\x99J\xcc\x98\xf6\xf6\xfdGD\x7f\xc1\xcdE\xe1\xec'),
            'client_write_key': bytearray(b'\x1b\xa41\xb7<\xa5\x05d\x12\x8f\x104\xe4\x18?&'),
            'server_write_key': bytearray(b'\xa6H\xca\xbadV\xc9\xa0\xc8\x05\x81\x8a%\x9c\x1a,'),
            'client_write_IV': bytearray(b"\xcd\x99\x91%\xd0\x97\xf7\'\x00\xdb\x15\x97\xe4\xe52\xa6"),
            'server_write_IV': bytearray(b'\x0e\xa5\xc7<\xa8\xfdh\xa03\xe9\x9d^\xf3ZS]')},
                                                        TlsVersion.TLS11, 16, 20, 16, 128,
                                                        {b'\x00\x16': bytearray(b''), b'\x00\x17': bytearray(b''),
                                                         b'\x00#': bytearray(b''), b'\xff\x01': bytearray(b'\x00'),
                                                         b'\x00\x1c': bytearray(b'@\x00')},0)

    def test_rc4_128_decrypt(self):
        client_1 = TlsRecord(bytearray(
            bytes.fromhex("16030200249e4df38e2b00e80a8efbb44ae81371380f303da75ebb2be8aeeb76c6d1cfb8b096990c5d")),
            [], False)
        server_1 = TlsRecord(bytearray(
            bytes.fromhex("16030200241efef13ad248bddc7ef95b37cf489f4b7f9b65cb67022f6bddf1f126ccc065cd299a075e")),
            [], True)
        client_2 = TlsRecord(bytearray(
            bytes.fromhex("170302001a8edd0a0cb37e21d33469fb15d4bc465981641c83d65499838a60")),
            [], False)
        server_2 = TlsRecord(
            bytearray(bytes.fromhex("170302001a495dc65bf43568edaac343d46324ffd410f28c67e1dac86b0cc3")), [],
            True)

        self.assertEqual(self.tls_1_1_rc4_128_decryptor.decrypt(client_1, False),
                         bytes.fromhex("1400000c2e688145acfbf3300dac5a74"))
        self.assertEqual(self.tls_1_1_rc4_128_decryptor.decrypt(server_1, True),
                         bytes.fromhex("1400000ca8f7bd029d49e9891812987f"))
        self.assertEqual(self.tls_1_1_rc4_128_decryptor.decrypt(client_2, False), b'Lorem\n')
        self.assertEqual(self.tls_1_1_rc4_128_decryptor.decrypt(server_2, True), b'Lorem\n')

    def test_3des_cbc(self):
        client_1 = TlsRecord(bytearray(
            bytes.fromhex(
                "160302003486ef14b9d210d261a0a0ac4a859ae37b77186c84050810e35d37f330a0d76ad0de49841d1f08b29ad12a47adf7a0acf83a4eccb2")),
            [], False)
        server_1 = TlsRecord(bytearray(
            bytes.fromhex(
                "1603020034c4594ef59609cf9db8e437c138dc357c8e861fb26d9e2e9710cb08da464535f6b68196989aa17f6041da0134a8859900717af323")),
            [], True)
        client_2 = TlsRecord(bytearray(
            bytes.fromhex("1703020024da3fb743b8462144de44c121fa7e692a5ff9a3d6eb6abaac9b973c0e4dac2d04bd0ff75f")),
            [], False)
        server_2 = TlsRecord(
            bytearray(
                bytes.fromhex("170302002446ab01db8d781804ae56806ea5be325ac727a2bd87e2372af9eb0435f5c4fdb2e24d91ef")),
            [],
            True)

        self.assertEqual(self.tls_1_1_3des_ebe_cbc_decryptor.decrypt(client_1, False),
                         bytes.fromhex("1400000c0fd63ad3c6a6c4f43d623664"))
        self.assertEqual(self.tls_1_1_3des_ebe_cbc_decryptor.decrypt(server_1, True),
                         bytes.fromhex("1400000c1a23892cbec6a18449cafc17"))
        self.assertEqual(self.tls_1_1_3des_ebe_cbc_decryptor.decrypt(client_2, False), b'Lorem\n')
        self.assertEqual(self.tls_1_1_3des_ebe_cbc_decryptor.decrypt(server_2, True), b'Lorem\n')

    def test_aes_128_cbc(self):
        client_1 = TlsRecord(bytearray(
            bytes.fromhex(
                "16030200441e7e502a9310ff30125f844bb840a551df9dec330b1b8a4d2dee2bb342e7b64041172431bd52817169341d50ccb44e55b97833562d2e5f455a228ab87061e002acc2f828")
        ),
            [], False)
        server_1 = TlsRecord(bytearray(
            bytes.fromhex(
                "1603020044f7adcfe1b4c63295960384acd12de56fc25515b1548e367ff4895a9bb8b2f6d095e5739b94f4017a93a076a119f691d47712ad59341235e9c876f0f42e0ead9a01bb2a98")),
            [], True)
        client_2 = TlsRecord(bytearray(
            bytes.fromhex(
                "1703020034391e5ec29ff11a3977f1cc120a6da502874b8ba1cc9b8eee5149b3f62f04ebaa6f7fc885cd3b04c8ea83c1622f8c8e7fae2d1c4b")),
            [], False)
        server_2 = TlsRecord(
            bytearray(
                bytes.fromhex(
                    "1703020034198c059377b6a2f4d0c52decf8a28fbd3836f723a02069dee47698663452e9f9ba0b79a88385aaa48e1b56dbe0c3e8a96d0adc06")),
            [],
            True)

        self.assertEqual(self.tls_1_1_aes_128_cbc_decryptor.decrypt(client_1, False),
                         bytes.fromhex("1400000c7292f2e28646aee41df6a6ab"))
        self.assertEqual(self.tls_1_1_aes_128_cbc_decryptor.decrypt(server_1, True),
                         bytes.fromhex("1400000c1c3dd463abb7d5654e24b23a"))
        self.assertEqual(self.tls_1_1_aes_128_cbc_decryptor.decrypt(client_2, False), b'Lorem\n')
        self.assertEqual(self.tls_1_1_aes_128_cbc_decryptor.decrypt(server_2, True), b'Lorem\n')

    def test_camellia_128_cbc(self):
        client_1 = TlsRecord(bytearray(
            b'\x16\x03\x02\x00D\xc5I}=Y\r\x9e\x84\xb3Y"\x8e}\x97\xc1\x15\xe7\x88XK%f\x9bU\x93\x1dL\x8e\x89\x8b\xeet\xbbu5\x16{\xc7\x82\x0e\x05\xbc\x08m\x10\xa8\x00\x9c\x06\xb7|\xe37\xc4\'TQ`.\x82P\x03\x88\xa5t\t\x1dg'),
                             [],
                             False)

        server_1 = TlsRecord(bytearray(
            b'\x16\x03\x02\x00D\xdf\xde\xb2Ij\x99\x84\xb7\xe0NtpGEjj5N`G\xe2(\xe8d\x12\xdf \x9b0]\xf6\x83\xcba\r*uU\xaa8K\x7f\xb5\xcbV*\x1a[\xc8\xa7\xd1\xc1\xa8K\xe1\x9f9\x9e8\x02%\x82\x8dV+\xab\xd3\x9f'),
                             [], True)

        client_2 = TlsRecord(bytearray(
            b"\x17\x03\x02\x004?7vn\x0b\xf6\xd8\x9a\x11\t\xf5\x03\x89A\x93\'B#\x96_\xf9\x8a\xaf1\xfb\x8b\xc4\x1b\xf3y/.\xd0,4_\xb1\x8b\xe6\xebZZ\x1c\xbe\xd5T\x8b\xd4e\x0e\xec\x19"),
                             [], False)

        server_2 = TlsRecord(bytearray(
            b'\x17\x03\x02\x004\xbcV#\xfcmz.g\xe0\xe8\xc1R6\xf2\xec*\xfav\x10>\xech\x81\xf2:,@\x96`\xd5GX6\x1b\x9aj}{O\x0e:\x9et\n\x1e\xb2\x15\xd5V\xb5e\x08'),
                             [], True)

        self.assertEqual(self.tls_1_1_camellia_128_decryptor.decrypt(client_1, False),
                         b'\x14\x00\x00\x0c\xa3\t\xb1\x9d\x1e\x18\x87r\xc3\x12}\xc9')
        self.assertEqual(self.tls_1_1_camellia_128_decryptor.decrypt(server_1, True),
                         b'\x14\x00\x00\x0c\xa4!\x7f\xce\x90m\xaf\xd3gD\x10\xa3')
        self.assertEqual(self.tls_1_1_camellia_128_decryptor.decrypt(client_2, False), b'Lorem\n')
        self.assertEqual(self.tls_1_1_camellia_128_decryptor.decrypt(server_2, True), b'Lorem\n')
