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


R = 0xE1000000000000000000000000000000
MASK128 = (1 << 128) - 1

def gf128_mul(x, y):
    z = 0
    v = x & MASK128
    for i in range(128):
        if (y >> i) & 1:
            z ^= v
        msb = (v >> 127) & 1
        v = (v << 1) & MASK128
        if msb:
            v ^= R
    return z & MASK128

def rev128(y):
    r = 0
    for i in range(128):
        if (y >> i) & 1:
            r |= (1 << (127 - i))
    return r

def gf128_inv(x):
    if x == 0:
        raise ZeroDivisionError
    x_le = rev128(x)
    MOD = (1 << 128) | 0x87
    
    def deg(a):
        return a.bit_length() - 1 if a else -1
    
    def divmod_poly(a, b):
        q = 0
        while a and deg(a) >= deg(b):
            s = deg(a) - deg(b)
            q ^= (1 << s)
            a ^= (b << s)
        return q, a
    
    def mul_poly(a, b):
        r = 0
        while b:
            if b & 1:
                r ^= a
            a <<= 1
            b >>= 1
        return r
    
    def mod_poly(a, m):
        while a and deg(a) >= deg(m):
            s = deg(a) - deg(m)
            a ^= (m << s)
        return a
    
    r0, r1 = MOD, x_le
    s0, s1 = 0, 1
    steps = 0
    while r1:
        steps += 1
        if steps > 1000:
            raise RuntimeError("EGCD loop")
        q, r = divmod_poly(r0, r1)
        r0, r1 = r1, r
        s0, s1 = s1, s0 ^ mod_poly(mul_poly(q, s1), MOD)
    
    return rev128(s0 & MASK128)

print("=== Тесты gf128_mul ===")
print(f"1*1 = {gf128_mul(1,1):x}")
print(f"1*2 = {gf128_mul(1,2):x}")
print(f"2*2 = {gf128_mul(2,2):x}")
print(f"0x80*2 = {gf128_mul(0x80000000000000000000000000000000,2):x} (ожидается {R:x})")

print("\n=== Тесты gf128_inv (EGCD с разворотом) ===")
for t in [1, 2, 3, 0x80, 0x123456789abcdef0123456789abcdef0, MASK128]:
    try:
        inv_t = gf128_inv(t)
        p = gf128_mul(t, inv_t)
        print(f"inv({t:032x}) = {inv_t:032x}")
        print(f"   {t:032x} * inv = {p:032x} {'OK' if p == 1 else 'FAIL'}")
    except Exception as e:
        print(f"inv({t:032x}) -> ошибка: {e}")

print("\n=== Тест GF(2^4) для сравнения ===")
def gf4_mul(x, y, R=0x3, MASK=0xF):
    z = 0
    v = x & MASK
    for i in range(4):
        if (y >> i) & 1:
            z ^= v
        msb = (v >> 3) & 1
        v = (v << 1) & MASK
        if msb:
            v ^= R
    return z & MASK

def gf4_inv(x):
    result = 1
    base = x
    exp = (1 << 4) - 2
    while exp:
        if exp & 1:
            result = gf4_mul(result, base)
        base = gf4_mul(base, base)
        exp >>= 1
    return result

for t in [1, 2, 3, 4, 5, 6, 7]:
    inv_t = gf4_inv(t)
    p = gf4_mul(t, inv_t)
    print(f"inv({t}) = {inv_t}, {t} * inv = {p} {'OK' if p == 1 else 'FAIL'}")