Загрузка данных


def solve_gf2_linear(H_k, D):
    """
    Решает X * H_k = D в GF(2^128).
    Строит матрицу 128x128 и решает Гауссом.
    """
    # Столбцы: H_k * e_i для i=0..127
    # e_i = 1 << i
    cols = [gf128_mul(H_k, 1 << i) for i in range(128)]
    
    # Строим систему: для каждого бита j (0..127):
    # sum_i X_i * cols[i][j] = D[j]
    # где cols[i][j] = (cols[i] >> j) & 1
    
    # Матрица строк: row j = (биты cols[0..127][j], D[j])
    rows = []
    for j in range(128):
        row = 0
        for i in range(128):
            if (cols[i] >> j) & 1:
                row |= (1 << i)
        if (D >> j) & 1:
            row |= (1 << 128)
        rows.append(row)
    
    # Гаусс
    pivot_row = 0
    pivot_cols = []
    for col in range(128):
        pivot = -1
        for r in range(pivot_row, 128):
            if (rows[r] >> col) & 1:
                pivot = r
                break
        if pivot == -1:
            continue
        rows[pivot_row], rows[pivot] = rows[pivot], rows[pivot_row]
        for r in range(128):
            if r != pivot_row and ((rows[r] >> col) & 1):
                rows[r] ^= rows[pivot_row]
        pivot_cols.append(col)
        pivot_row += 1
    
    # Проверяем решение
    X = 0
    for r in range(pivot_row):
        for col in range(128):
            if (rows[r] >> col) & 1:
                if (rows[r] >> 128) & 1:
                    X |= (1 << col)
                break
    
    # Проверка
    check = 0
    for i in range(128):
        if (X >> i) & 1:
            check ^= cols[i]
    if check != D:
        return None
    return X