from typing import Final


ENG_LCASE: Final = "abcdefghijklmnopqrstuvwxyz"
RUS_LCASE: Final = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя"

ALPHABET_TABLE: Final = {
    "russian": RUS_LCASE,
    "english": ENG_LCASE
}

IC_TABLE: Final = {
    "russian": 0.0553,
    "english": 0.0644
}

POLYBIUS_SQUARE_EN: Final = {
    (1, 1): ("A",), (2, 1): ("B",), (3, 1): ("C",), (4, 1): ("D",),     (5, 1): ("E",),
    (1, 2): ("F",), (2, 2): ("G",), (3, 2): ("H",), (4, 2): ("I", "J"), (5, 2): ("K",),
    (1, 3): ("L",), (2, 3): ("M",), (3, 3): ("N",), (4, 3): ("O",),     (5, 3): ("P",),
    (1, 4): ("Q",), (2, 4): ("R",), (3, 4): ("S",), (4, 4): ("T",),     (5, 4): ("U",),
    (1, 5): ("V",), (2, 5): ("W",), (3, 5): ("X",), (4, 5): ("Y",),     (5, 5): ("Z",)
}

POLYBIUS_SQUARE_RU: Final = {
    (1, 1): ("А",),     (2, 1): ("Б",),     (3, 1): ("В",),     (4, 1): ("Г",), (5, 1): ("Д",),
    (1, 2): ("Е", "Э"), (2, 2): ("Ж", "З"), (3, 2): ("И", "Й"), (4, 2): ("К",), (5, 2): ("Л",),
    (1, 3): ("М",),     (2, 3): ("Н",),     (3, 3): ("О",),     (4, 3): ("П",), (5, 3): ("Р", "С"),
    (1, 4): ("Т",),     (2, 4): ("У",),     (3, 4): ("Ф", "Х"), (4, 4): ("Ц",), (5, 4): ("Ч",),
    (1, 5): ("Ш", "Щ"), (2, 5): ("Ы",),     (3, 5): ("Ь",),     (4, 5): ("Ю",), (5, 5): ("Я",)
}

KOI8R_STOPBYTES = (
    0x0D,
)

ENG_LETTER_FREQ_COMMON: Final = {
    "a": 8.12,  "b": 1.49,  "c": 2.71,  "d": 4.32,  "e": 12.02, "f": 2.30,  "g": 2.03,
    "h": 5.92,  "i": 7.31,  "j": 0.10,  "k": 0.69,  "l": 3.98,  "m": 2.61,  "n": 6.95,
    "o": 7.68,  "p": 1.82,  "q": 0.11,  "r": 6.02,  "s": 6.28,  "t": 9.10,  "u": 2.88,
    "v": 1.11,  "w": 2.09,  "x": 0.17,  "y": 2.11,  "z": 0.07
}

ENG_LETTER_FREQ_MATH: Final = {
    "a": 7.8,   "b": 1.52,  "c": 3.59,  "d": 3.20,  "e": 12.20, "f": 2.65,  "g": 1.74,
    "h": 4.35,  "i": 7.96,  "j": 0.199, "k": 0.473, "l": 3.93,  "m": 2.61,  "n": 7.45,
    "o": 7.18,  "p": 2.17,  "q": 0.33,  "r": 6.12,  "s": 6.47,  "t": 9.46,  "u": 2.81,
    "v": 1.28,  "w": 1.446, "x": 1.08,  "y": 1.59,  'z': 0.33
}

ENG_LETTER_FREQ_LITERATURE: Final = {
    "a": 7.97,  "b": 1.55,  "c": 2.51,  "d": 4.41,  "e": 12.58, "f": 2.19,  "g": 2.01,
    "h": 6.13,  "i": 6.98,  "j": 0.15,  "k": 0.84,  "l": 4.01,  "m": 2.63,  "n": 6.86,
    "o": 7.68,  "p": 1.70,  "q": 0.09,  "r": 5.80,  "s": 6.25,  "t": 9.09,  "u": 2.88,
    "v": 0.99,  "w": 2.37,  "x": 0.17,  "y": 2.11,  "z": 0.06
}


RUS_LETTER_FREQ_COMMON: Final = {
    "а": 8.01,  "б": 1.59,  "в": 4.54,  "г": 1.70,  "д": 2.98,  "е": 8.45,  "ё": 0.04,
    "ж": 0.94,  "з": 1.65,  "и": 7.35,  "й": 1.21,  "к": 3.49,  "л": 4.40,  "м": 3.21,
    "н": 6.70,  "о": 10.96, "п": 2.81,  "р": 4.73,  "с": 5.47,  "т": 6.26,  "у": 2.62,
    "ф": 0.26,  "х": 0.97,  "ц": 0.48,  "ч": 1.44,  "ш": 0.73,  "щ": 0.36,  "ъ": 0.04,
    "ы": 1.90,  "ь": 1.74,  "э": 0.32,  "ю": 0.64,  "я": 2.01
}

RUS_LETTER_FREQ_MATH: Final = {
    "а": 6.98,  "б": 1.03,  "в": 4.16,  "г": 1.40,  "д": 2.99,  "е": 9.68,  "ё": 0.01,
    "ж": 0.77,  "з": 1.51,  "и": 8.14,  "й": 1.05,  "к": 2.92,  "л": 4.05,  "м": 3.43,
    "н": 7.61,  "о": 10.28, "п": 2.87,  "р": 5.29,  "с": 4.99,  "т": 6.53,  "у": 2.44,
    "ф": 0.71,  "х": 1.05,  "ц": 0.70,  "ч": 1.70,  "ш": 0.42,  "щ": 0.43,  "ъ": 0.02,
    "ы": 1.79,  "ь": 1.42,  "э": 0.44,  "ю": 0.71,  "я": 2.50
}

RUS_LETTER_FREQ_LITERATURE: Final = {
    "а": 7.74,  "б": 1.69,  "в": 4.79,  "г": 1.85,  "д": 3.07,  "е": 8.39,  "ё": 0.04,
    "ж": 0.89,  "з": 1.66,  "и": 7.06,  "й": 1.55,  "к": 3.65,  "л": 4.37,  "м": 3.21,
    "н": 6.44,  "о": 10.13, "п": 3.05,  "р": 4.76,  "с": 5.59,  "т": 6.25,  "у": 2.75,
    "ф": 0.29,  "х": 1.07,  "ц": 0.50,  "ч": 1.40,  "ш": 0.89,  "щ": 0.28,  "ъ": 0.02,
    "ы": 1.91,  "ь": 1.71,  "э": 0.26,  "ю": 0.73,  "я": 2.02,
}

FREQ_TABLES: Final = {
    "english": {
        "common": ENG_LETTER_FREQ_COMMON,
        "math": ENG_LETTER_FREQ_MATH,
        "literature": ENG_LETTER_FREQ_LITERATURE
    },
    "russian": {
        "common": RUS_LETTER_FREQ_COMMON,
        "math": RUS_LETTER_FREQ_MATH,
        "literature": RUS_LETTER_FREQ_LITERATURE
    }
}

DES_IP_TABLE = (58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
                62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
                57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
                61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7)

DES_SHIFT_TABLE = (1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1)

DES_PC_1_TABLE = (57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
                  10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
                  63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
                  14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4)

DES_PC_2_TABLE = (14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4,
                  26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40,
                  51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32)

DES_E_TABLE = (32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9,
               10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16,
               17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
               24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1)

DES_S_TABLE = (
    # s1
    ((14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7),
     (0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8),
     (4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0),
     (15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13)),

    # s2
    ((15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10),
     (3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5),
     (0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15),
     (13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9)),

    # s3
    ((10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8),
     (13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1),
     (13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7),
     (1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12)),

    # s4
    ((7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15),
     (13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9),
     (10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4),
     (3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14)),

    # s5
    ((2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9),
     (14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6),
     (4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14),
     (11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3)),

    # s6
    ((12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11),
     (10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8),
     (9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6),
     (4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13)),

    # s7
    ((4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1),
     (13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6),
     (1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2),
     (6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12)),

    # s8
    ((13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7),
     (1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2),
     (7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8),
     (2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11))
)

DES_P_TABLE = (16, 7, 20, 21, 29, 12, 28, 17,
               1, 15, 23, 26, 5, 18, 31, 10,
               2, 8, 24, 14, 32, 27, 3, 9,
               19, 13, 30, 6, 22, 11, 4, 25)

DES_IP_INV_TABLE = (40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
                    38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
                    36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
                    34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25)


GOST_ENC_INDICES = (0, 1, 2, 3, 4, 5, 6, 7,
                    0, 1, 2, 3, 4, 5, 6, 7,
                    0, 1, 2, 3, 4, 5, 6, 7,
                    7, 6, 5, 4, 3, 2, 1, 0)

GOST_DEC_INDICES = (0, 1, 2, 3, 4, 5, 6, 7,
                    7, 6, 5, 4, 3, 2, 1, 0,
                    7, 6, 5, 4, 3, 2, 1, 0,
                    7, 6, 5, 4, 3, 2, 1, 0)

GOST_SBLOCK = ((9, 6, 3, 2, 8, 11, 1, 7, 10, 4, 14, 15, 12, 0, 13, 5),
               (3, 7, 14, 9, 8, 10, 15, 0, 5, 2, 6, 12, 11, 4, 13, 1),
               (14, 4, 6, 2, 11, 3, 13, 8, 12, 15, 5, 10, 0, 7, 1, 9),
               (14, 7, 10, 12, 13, 1, 3, 9, 0, 2, 11, 4, 15, 8, 5, 6),
               (11, 5, 1, 9, 8, 13, 15, 0, 14, 4, 2, 3, 12, 7, 10, 6),
               (3, 10, 13, 12, 1, 2, 0, 11, 7, 5, 9, 4, 8, 15, 14, 6),
               (1, 13, 2, 9, 7, 10, 6, 0, 8, 12, 4, 5, 15, 3, 11, 14),
               (11, 10, 15, 5, 0, 12, 14, 8, 6, 2, 3, 9, 1, 7, 13, 4))

from typing import Final


ENG_LCASE: Final = "abcdefghijklmnopqrstuvwxyz"
RUS_LCASE: Final = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя"

ALPHABET_TABLE: Final = {
    "russian": RUS_LCASE,
    "english": ENG_LCASE
}

IC_TABLE: Final = {
    "russian": 0.0553,
    "english": 0.0644
}

POLYBIUS_SQUARE_EN: Final = {
    (1, 1): ("A",), (2, 1): ("B",), (3, 1): ("C",), (4, 1): ("D",),     (5, 1): ("E",),
    (1, 2): ("F",), (2, 2): ("G",), (3, 2): ("H",), (4, 2): ("I", "J"), (5, 2): ("K",),
    (1, 3): ("L",), (2, 3): ("M",), (3, 3): ("N",), (4, 3): ("O",),     (5, 3): ("P",),
    (1, 4): ("Q",), (2, 4): ("R",), (3, 4): ("S",), (4, 4): ("T",),     (5, 4): ("U",),
    (1, 5): ("V",), (2, 5): ("W",), (3, 5): ("X",), (4, 5): ("Y",),     (5, 5): ("Z",)
}

POLYBIUS_SQUARE_RU: Final = {
    (1, 1): ("А",),     (2, 1): ("Б",),     (3, 1): ("В",),     (4, 1): ("Г",), (5, 1): ("Д",),
    (1, 2): ("Е", "Э"), (2, 2): ("Ж", "З"), (3, 2): ("И", "Й"), (4, 2): ("К",), (5, 2): ("Л",),
    (1, 3): ("М",),     (2, 3): ("Н",),     (3, 3): ("О",),     (4, 3): ("П",), (5, 3): ("Р", "С"),
    (1, 4): ("Т",),     (2, 4): ("У",),     (3, 4): ("Ф", "Х"), (4, 4): ("Ц",), (5, 4): ("Ч",),
    (1, 5): ("Ш", "Щ"), (2, 5): ("Ы",),     (3, 5): ("Ь",),     (4, 5): ("Ю",), (5, 5): ("Я",)
}

KOI8R_STOPBYTES = (
    0x0D,
)

ENG_LETTER_FREQ_COMMON: Final = {
    "a": 8.12,  "b": 1.49,  "c": 2.71,  "d": 4.32,  "e": 12.02, "f": 2.30,  "g": 2.03,
    "h": 5.92,  "i": 7.31,  "j": 0.10,  "k": 0.69,  "l": 3.98,  "m": 2.61,  "n": 6.95,
    "o": 7.68,  "p": 1.82,  "q": 0.11,  "r": 6.02,  "s": 6.28,  "t": 9.10,  "u": 2.88,
    "v": 1.11,  "w": 2.09,  "x": 0.17,  "y": 2.11,  "z": 0.07
}

ENG_LETTER_FREQ_MATH: Final = {
    "a": 7.8,   "b": 1.52,  "c": 3.59,  "d": 3.20,  "e": 12.20, "f": 2.65,  "g": 1.74,
    "h": 4.35,  "i": 7.96,  "j": 0.199, "k": 0.473, "l": 3.93,  "m": 2.61,  "n": 7.45,
    "o": 7.18,  "p": 2.17,  "q": 0.33,  "r": 6.12,  "s": 6.47,  "t": 9.46,  "u": 2.81,
    "v": 1.28,  "w": 1.446, "x": 1.08,  "y": 1.59,  'z': 0.33
}

ENG_LETTER_FREQ_LITERATURE: Final = {
    "a": 7.97,  "b": 1.55,  "c": 2.51,  "d": 4.41,  "e": 12.58, "f": 2.19,  "g": 2.01,
    "h": 6.13,  "i": 6.98,  "j": 0.15,  "k": 0.84,  "l": 4.01,  "m": 2.63,  "n": 6.86,
    "o": 7.68,  "p": 1.70,  "q": 0.09,  "r": 5.80,  "s": 6.25,  "t": 9.09,  "u": 2.88,
    "v": 0.99,  "w": 2.37,  "x": 0.17,  "y": 2.11,  "z": 0.06
}


RUS_LETTER_FREQ_COMMON: Final = {
    "а": 8.01,  "б": 1.59,  "в": 4.54,  "г": 1.70,  "д": 2.98,  "е": 8.45,  "ё": 0.04,
    "ж": 0.94,  "з": 1.65,  "и": 7.35,  "й": 1.21,  "к": 3.49,  "л": 4.40,  "м": 3.21,
    "н": 6.70,  "о": 10.96, "п": 2.81,  "р": 4.73,  "с": 5.47,  "т": 6.26,  "у": 2.62,
    "ф": 0.26,  "х": 0.97,  "ц": 0.48,  "ч": 1.44,  "ш": 0.73,  "щ": 0.36,  "ъ": 0.04,
    "ы": 1.90,  "ь": 1.74,  "э": 0.32,  "ю": 0.64,  "я": 2.01
}

RUS_LETTER_FREQ_MATH: Final = {
    "а": 6.98,  "б": 1.03,  "в": 4.16,  "г": 1.40,  "д": 2.99,  "е": 9.68,  "ё": 0.01,
    "ж": 0.77,  "з": 1.51,  "и": 8.14,  "й": 1.05,  "к": 2.92,  "л": 4.05,  "м": 3.43,
    "н": 7.61,  "о": 10.28, "п": 2.87,  "р": 5.29,  "с": 4.99,  "т": 6.53,  "у": 2.44,
    "ф": 0.71,  "х": 1.05,  "ц": 0.70,  "ч": 1.70,  "ш": 0.42,  "щ": 0.43,  "ъ": 0.02,
    "ы": 1.79,  "ь": 1.42,  "э": 0.44,  "ю": 0.71,  "я": 2.50
}

RUS_LETTER_FREQ_LITERATURE: Final = {
    "а": 7.74,  "б": 1.69,  "в": 4.79,  "г": 1.85,  "д": 3.07,  "е": 8.39,  "ё": 0.04,
    "ж": 0.89,  "з": 1.66,  "и": 7.06,  "й": 1.55,  "к": 3.65,  "л": 4.37,  "м": 3.21,
    "н": 6.44,  "о": 10.13, "п": 3.05,  "р": 4.76,  "с": 5.59,  "т": 6.25,  "у": 2.75,
    "ф": 0.29,  "х": 1.07,  "ц": 0.50,  "ч": 1.40,  "ш": 0.89,  "щ": 0.28,  "ъ": 0.02,
    "ы": 1.91,  "ь": 1.71,  "э": 0.26,  "ю": 0.73,  "я": 2.02,
}

FREQ_TABLES: Final = {
    "english": {
        "common": ENG_LETTER_FREQ_COMMON,
        "math": ENG_LETTER_FREQ_MATH,
        "literature": ENG_LETTER_FREQ_LITERATURE
    },
    "russian": {
        "common": RUS_LETTER_FREQ_COMMON,
        "math": RUS_LETTER_FREQ_MATH,
        "literature": RUS_LETTER_FREQ_LITERATURE
    }
}

DES_IP_TABLE = (58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
                62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
                57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
                61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7)

DES_SHIFT_TABLE = (1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1)

DES_PC_1_TABLE = (57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
                  10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
                  63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
                  14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4)

DES_PC_2_TABLE = (14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4,
                  26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40,
                  51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32)

DES_E_TABLE = (32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9,
               10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16,
               17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
               24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1)

DES_S_TABLE = (
    # s1
    ((14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7),
     (0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8),
     (4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0),
     (15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13)),

    # s2
    ((15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10),
     (3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5),
     (0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15),
     (13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9)),

    # s3
    ((10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8),
     (13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1),
     (13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7),
     (1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12)),

    # s4
    ((7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15),
     (13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9),
     (10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4),
     (3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14)),

    # s5
    ((2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9),
     (14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6),
     (4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14),
     (11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3)),

    # s6
    ((12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11),
     (10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8),
     (9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6),
     (4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13)),

    # s7
    ((4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1),
     (13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6),
     (1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2),
     (6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12)),

    # s8
    ((13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7),
     (1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2),
     (7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8),
     (2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11))
)

DES_P_TABLE = (16, 7, 20, 21, 29, 12, 28, 17,
               1, 15, 23, 26, 5, 18, 31, 10,
               2, 8, 24, 14, 32, 27, 3, 9,
               19, 13, 30, 6, 22, 11, 4, 25)

DES_IP_INV_TABLE = (40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
                    38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
                    36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
                    34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25)


GOST_ENC_INDICES = (0, 1, 2, 3, 4, 5, 6, 7,
                    0, 1, 2, 3, 4, 5, 6, 7,
                    0, 1, 2, 3, 4, 5, 6, 7,
                    7, 6, 5, 4, 3, 2, 1, 0)

GOST_DEC_INDICES = (0, 1, 2, 3, 4, 5, 6, 7,
                    7, 6, 5, 4, 3, 2, 1, 0,
                    7, 6, 5, 4, 3, 2, 1, 0,
                    7, 6, 5, 4, 3, 2, 1, 0)

GOST_SBLOCK = ((9, 6, 3, 2, 8, 11, 1, 7, 10, 4, 14, 15, 12, 0, 13, 5),
               (3, 7, 14, 9, 8, 10, 15, 0, 5, 2, 6, 12, 11, 4, 13, 1),
               (14, 4, 6, 2, 11, 3, 13, 8, 12, 15, 5, 10, 0, 7, 1, 9),
               (14, 7, 10, 12, 13, 1, 3, 9, 0, 2, 11, 4, 15, 8, 5, 6),
               (11, 5, 1, 9, 8, 13, 15, 0, 14, 4, 2, 3, 12, 7, 10, 6),
               (3, 10, 13, 12, 1, 2, 0, 11, 7, 5, 9, 4, 8, 15, 14, 6),
               (1, 13, 2, 9, 7, 10, 6, 0, 8, 12, 4, 5, 15, 3, 11, 14),
               (11, 10, 15, 5, 0, 12, 14, 8, 6, 2, 3, 9, 1, 7, 13, 4))

# s1 # s2 # s3 # s4 # s5 # s6 # s7 # s8