R = 0xE1000000000000000000000000000000
MASK = (1 << 128) - 1
def gf_mul(x, y):
z = 0
v = x & MASK
for i in range(128):
if (y >> i) & 1:
z ^= v
msb = (v >> 127) & 1
v = (v << 1) & MASK
if msb:
v ^= R
return z & MASK
def invert_matrix_gf2(H_k):
"""Строит обратную матрицу для умножения на H_k над GF(2)."""
cols = [gf_mul(H_k, 1 << i) for i in range(128)]
rows = []
for j in range(128):
row = 0
for i in range(128):
if (cols[i] >> j) & 1:
row |= (1 << i)
row |= (1 << (128 + j))
rows.append(row)
for col in range(128):
pivot = -1
for r in range(col, 128):
if (rows[r] >> col) & 1:
pivot = r
break
if pivot == -1:
return None
rows[col], rows[pivot] = rows[pivot], rows[col]
for r in range(128):
if r != col and ((rows[r] >> col) & 1):
rows[r] ^= rows[col]
inv_cols = [rows[i] >> 128 for i in range(128)]
def apply(D):
X = 0
for i in range(128):
if (D >> i) & 1:
X ^= inv_cols[i]
return X
return apply
# H_k из твоего реального запуска
H_k = 0x6483f1ed6ad11f379d4e92ad1f96a1e9
print("=== Тест матрицы ===")
apply_inv = invert_matrix_gf2(H_k)
if apply_inv is None:
print("Матрица не обратима!")
else:
for test_X in [0x123456789abcdef0123456789abcdef0, 1, 2, 0x80]:
D = gf_mul(test_X, H_k)
X = apply_inv(D)
print(f"test_X = {test_X:032x}")
print(f" X*H^5 = {D:032x}")
print(f" apply(D) = {X:032x}")
print(f" совпадает: {X == test_X}")
print()
inv_H_k = apply_inv(1)
print(f"inv(H^5) = {inv_H_k:032x}")
print(f"H^5 * inv(H^5) = {gf_mul(H_k, inv_H_k):032x} (должно быть 1)")
if gf_mul(H_k, inv_H_k) == 1:
print("*** УСПЕХ! ***")