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


import struct

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 ghash(H_bytes, aad, ct):
    H = int.from_bytes(H_bytes, "big")
    len_block = struct.pack(">QQ", len(aad) * 8, len(ct) * 8)
    data = aad + ct + len_block
    Y = 0
    for i in range(0, len(data), 16):
        block = data[i:i+16]
        if len(block) < 16:
            block = block + b"\x00" * (16 - len(block))
        X = int.from_bytes(block, "big")
        Y = gf128_mul(Y ^ X, H)
    return Y.to_bytes(16, "big")

# Данные из твоего вывода:
GLOBAL_H = bytes.fromhex("044419fccd60e5ce1b9f1659fb1831e9")
FLAG_CT  = bytes.fromhex("18930f5ebd9e497b1d511181817de1a7c05d54281447ee3c8f97f1d86a04606b1fe7ae2fc5")
known    = bytes.fromhex("3a49b67dcfd2e6afa091835adb1d8000")
G0_real  = bytes.fromhex("de97a6094a79f37f5d1779c242dc4dce")
AAD_PREFIX = b"user-aad-prefix:"

print(f"FLAG_CT len = {len(FLAG_CT)}")

# G0 через нашу функцию
G0 = ghash(GLOBAL_H, AAD_PREFIX + b"\x00" * 16, FLAG_CT)
print(f"G0 (локально) = {G0.hex()}")
print(f"G0 (с сервера) = {G0_real.hex()}")
print(f"G0 совпадает: {G0 == G0_real}")
print()

# Проверим разные X
def test_X(X):
    return ghash(GLOBAL_H, AAD_PREFIX + X, FLAG_CT)

G0 = test_X(b"\x00" * 16)
G1 = test_X(b"\x00" * 15 + b"\x01")
G2 = test_X(b"\x00" * 15 + b"\x02")
G3 = test_X(b"\x00" * 15 + b"\x03")

d1 = int.from_bytes(bytes(a ^ b for a, b in zip(G1, G0)), "big")
d2 = int.from_bytes(bytes(a ^ b for a, b in zip(G2, G0)), "big")
d3 = int.from_bytes(bytes(a ^ b for a, b in zip(G3, G0)), "big")

print(f"d1 = G1^G0 = {d1:032x}")
print(f"d2 = G2^G0 = {d2:032x}")
print(f"d3 = G3^G0 = {d3:032x}")
print(f"d2 == 2*d1: {d2 == gf128_mul(2, d1)}")
print(f"d3 == 3*d1: {d3 == gf128_mul(3, d1)}")
print()

# Ищем k: d1 == H^k
H = int.from_bytes(GLOBAL_H, "big")
H_k = 1
for k in range(0, 30):
    if H_k == d1:
        print(f"*** d1 == H^{k} ***")
        break
    H_k = gf128_mul(H_k, H)
else:
    print("d1 != H^k для k=0..29")