Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лаба 3 терентьев.docx
Скачиваний:
0
Добавлен:
12.02.2026
Размер:
714.19 Кб
Скачать

2. Исследование функции хэширования по гост р 34.11-94

Функция хэширования:

Текст, подлежащий хэшированию: ИМИТОВСТАВКА.

Начальное хэш-значение z0: 923F82A4AF194F9B.

Стандарт симметричного шифрования: ГОСТ Р 34.11-94.

Листинг.

# === ГОСТ Р 34.11-94 (без внешних библиотек) === # Тестовые S-блоки из приложения А к ГОСТ Р 34.11-94 (часто называются "id-GostR3411-94-TestParamSet") SBOX = ( (4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3), (14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9), (5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11), (7, 13, 14, 3, 0, 6, 9, 10, 1, 15, 11, 8, 12, 5, 2, 4), (6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2), (4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14), (13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12), (1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12), ) # Начальный вектор H0 (фиксированный в стандарте) H0 = bytes.fromhex("0000000000000000000000000000000000000000000000000000000000000000") # Константа C (256-битная, используется в алгоритме) C = bytes.fromhex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF") def gost28147_encrypt(block: bytes, key: bytes) -> bytes: """Шифрование ГОСТ 28147-89 в режиме простой замены (ECB), 64-битный блок""" if len(block) != 8 or len(key) != 32: raise ValueError("Block must be 8 bytes, key must be 32 bytes") n1 = int.from_bytes(block[4:], 'little') n2 = int.from_bytes(block[:4], 'little') # Извлекаем 8 подключей по 4 байта (little-endian) keys = [int.from_bytes(key[i * 4:(i + 1) * 4], 'little') for i in range(8)] round_keys = (keys * 3) + keys[::-1] # 32 раунда for i in range(32): temp = (n1 + round_keys[i]) & 0xFFFFFFFF # S-блоки res = 0 for j in range(8): res |= SBOX[j][(temp >> (4 * j)) & 0xF] << (4 * j) # Циклический сдвиг на 11 влево res = ((res << 11) | (res >> 21)) & 0xFFFFFFFF n1, n2 = n2 ^ res, n1 return n1.to_bytes(4, 'little') + n2.to_bytes(4, 'little') def add_modulo_2_256(a: bytes, b: bytes) -> bytes: """Сложение по модулю 2^256 (для 32-байтных чисел, big-endian)""" x = int.from_bytes(a, 'big') y = int.from_bytes(b, 'big') return ((x + y) & ((1 << 256) - 1)).to_bytes(32, 'big') def xor_bytes(a: bytes, b: bytes) -> bytes: return bytes(x ^ y for x, y in zip(a, b)) def gost3411_94_compress(h: bytes, m: bytes) -> bytes: """Функция сжатия χ(H, M) по ГОСТ Р 34.11-94""" if len(h) != 32 or len(m) != 32: raise ValueError("h and m must be 32 bytes") # Шаг 1: S = H M s = xor_bytes(h, m) # Шаг 2: Разбиваем S на 4 блока по 64 бита (8 байт) s_blocks = [s[i:i + 8] for i in range(0, 32, 8)] # [s0, s1, s2, s3] # Шаг 3: Вычисляем K = s0 s1 s2 s3 k = bytes(8) for sb in s_blocks: k = xor_bytes(k, sb) # Шаг 4: Шифруем каждый блок с ключом K (расширяем K до 32 байт) key = k * 4 # 8 * 4 = 32 байта u = s_blocks[3] v = s_blocks[2] w = s_blocks[1] t = s_blocks[0] # 1-й проход u = gost28147_encrypt(xor_bytes(u, C[0:8]), key) v = gost28147_encrypt(xor_bytes(v, C[8:16]), key) w = gost28147_encrypt(xor_bytes(w, C[16:24]), key) t = gost28147_encrypt(xor_bytes(t, C[24:32]), key) # 2-й проход u = gost28147_encrypt(xor_bytes(u, w), key) v = gost28147_encrypt(xor_bytes(v, t), key) w = gost28147_encrypt(xor_bytes(w, u), key) t = gost28147_encrypt(xor_bytes(t, v), key) # 3-й проход u = gost28147_encrypt(xor_bytes(u, C[0:8]), key) v = gost28147_encrypt(xor_bytes(v, C[8:16]), key) w = gost28147_encrypt(xor_bytes(w, C[16:24]), key) t = gost28147_encrypt(xor_bytes(t, C[24:32]), key) # Собираем результат result = u + v + w + t return xor_bytes(h, result) def pad_message(msg: bytes) -> bytes: """Дополнение сообщения до кратности 32 байтам с добавлением длины в битах""" original_len_bits = len(msg) * 8 # Добавляем 1 бит (0x80 в начале дополнения) msg += b'\x80' # Дополняем нулями до (len % 32 == 24), чтобы оставить 8 байт под длину while (len(msg) % 32) != 24: msg += b'\x00' # Добавляем длину сообщения в битах как 8-байтное число (little-endian!) msg += original_len_bits.to_bytes(8, 'little') return msg def gost3411_94_hash(message: bytes) -> bytes: """Полный алгоритм хэширования по ГОСТ Р 34.11-94""" padded = pad_message(message) h = H0 for i in range(0, len(padded), 32): block = padded[i:i + 32] if len(block) < 32: block = block.ljust(32, b'\x00') h = gost3411_94_compress(h, block) return h # === Основная программа === # Тексты original_text = "ИМИТОВСТАВКА" modified_text = "ИМИТОВСТАВКБ" # изменён последний символ # Кодировка: cp1251 (стандарт для ГОСТ) orig_bytes = original_text.encode('cp1251') mod_bytes = modified_text.encode('cp1251') # Хэширование hash_orig = gost3411_94_hash(orig_bytes) hash_mod = gost3411_94_hash(mod_bytes) # Вывод print("Исходный текст:", original_text) print("Хэш (hex):", hash_orig.hex().upper()) print("\nМодифицированный текст:", modified_text) print("Хэш (hex):", hash_mod.hex().upper()) # Двоичное представление модифицированного текста mod_bin = ''.join(f"{b:08b}" for b in mod_bytes) print("\nДвоичное представление модифицированного текста:") print(mod_bin) # Хэш в двоичном и hex mod_hash_hex = hash_mod.hex().upper() mod_hash_bin = ''.join(f"{b:08b}" for b in hash_mod) print("\nХэш модифицированного текста:") print("Hex:", mod_hash_hex) print("Bin:", mod_hash_bin) print("\nХэши совпадают?", hash_orig == hash_mod)

Демонстрация работы программы.

Рис. 2. Результат работы программы.