from secrets import randbelow, randbits from core.prime_utils import is_prime class ParamGenerator: """ Генератор параметров протокола Диффи–Хеллмана. Возвращает тройку (p, q, g): - p = 2*q + 1, где p и q простые - g — корректный генератор для группы по модулю p """ @staticmethod def generate() -> tuple[int, int, int]: """ Случайным образом выбирает размерность (кол-во бит) для q, подбирает безопасное простое p и генератор g. Возвращает (p, q, g). """ # Размер числа выбираем случайно от 8 до 16 бит (от 256 до 65 535) bits = 8 + randbelow(9) # Генерация безопасного простого while True: q = randbits(bits - 1) | 1 # нечётное число if not is_prime(q): continue p = 2 * q + 1 if not is_prime(p): continue # Найдём генератор g = ParamGenerator._find_generator(p, q) return p, q, g @staticmethod def _find_generator(p: int, q: int) -> int: """ Ищет генератор g: минимальное число 2..p-2, для которого g^q mod p != 1. """ for g in range(2, p - 1): if pow(g, q, p) != 1: return g raise ValueError("Не удалось найти генератор для p")