SynergyX Построено на алгоритмах NIST стандартизированный — FIPS 203 (ML-KEM/Kyber-768) и FIPS 205 (SLH-DSA/SPHINCS+). Published January 15, 2026. All cryptographic claims are verifiable on-chain and against NIST CSRC документация. Ноль перед майнингом. Ноль ICO. Ноль ВК. Нулевое распределение учредителей. Жесткий лимит в 77,7 миллиона долларов. Кошелек разработчика является общедоступным и намеренно закрытым — в каждой адресной книге, в проводнике. Ничто из этого не требует от вас доверия человеку.
Код пост-квантовой криптографии для аудита безопасности: контрольный список для разработчиков
📅 Последнее обновление: 2 августа 2026 г.🎧 Прослушивание: ~6 мин.
Постквантовая криптография вводит новые классы уязвимостей, незнакомые разработчикам, имеющим опыт работы только с классической криптографией. В этом руководстве представлен подробный контрольный список аудита безопасности для реализаций Kyber и SPHINCS+. Квантостойкий кошелек SynX использует именно эти процедуры для внутренней проверки кода.
Предаудиторская подготовка
Обзор документации
Прежде чем изучать код, соберите необходимую документацию:
Спецификация алгоритма (NIST FIPS 203/205 для Kyber/SPHINCS+)
Замечания по реализации, объясняющие любые отклонения от спецификации.
Документ модели угроз, определяющий возможности противника
Предыдущие аудиторские отчеты и статус их исправления
Тесты с известными ответами (KAT) из заявки NIST
Настройка инструмента
# Основные инструменты аудита безопасности# Статический анализ
pip install Bandit Semgrep Flake8-Security
# Временной анализ
git-клон https://github.com/oreparaz/dudect
# Фаззинг
pip install atheris гипотеза python-afl
# Анализ памяти# Valgrind для C/C++, Memory_profiler для Python
pip установить Memory_profiler
# Для реализаций Rust
установка груза
Категории критических уязвимостей
Категория
Серьезность
Пример
Влияние
Синхронизация побочных каналов
КРИТИЧЕСКИЙ
Секретно-зависимые ветки
Восстановление ключей
Недостаточная энтропия
КРИТИЧЕСКИЙ
Слабая раздача RNG
Ключевой прогноз
Ключевая утечка материала
КРИТИЧЕСКИЙ
Ключи в дампах подкачки и сбоях
Ключевое воздействие
Характерная пластичность
ВЫСОКИЙ
Неуникальные подписи
Повтор транзакции
Проверка ввода
ВЫСОКИЙ
Приняты неверные открытые ключи
Различные атаки
Безопасность памяти
ВЫСОКИЙ
Переполнение буфера
RCE, извлечение ключей
Временной анализ побочных каналов
Шаблоны ручного анализа кода
Уязвимые шаблоны для поиска
Эти шаблоны кода могут привести к утечке секретной информации из-за времени:
# УЯЗВИМОСТЬ: ветвь, зависящая от секрета.if secret_bit: do_operation_a() # Другой путь синхронизацииеще: do_operation_b()
# УЯЗВИМОСТЬ: сравнение раннего выходазащитасравнение_секретов(a: байты, b: байты) -> bool:
для i in диапазон(лен(а)):
if a[i] != b[i]:
возвращаться ЛОЖЬ # Утечка позиции разницы!возвращаться Истинный
# УЯЗВИМОСТЬ: доступ к массиву, зависящий от секрета
результат = таблица_поиска[секретный_индекс] # Тайминговая атака на кэш# УЯЗВИМОСТЬ: Разделение по секрету
результат = значение/секретный_делитель # Время зависит от делителя
Безопасные шаблоны
импортировать hmac
# БЕЗОПАСНО: сравнение в постоянном временизащитаConstant_time_compare(a: байты, b: байты) -> bool:
"""Сравнить две байтовые строки за постоянное время"""возвращаться hmac.compare_digest(а, б)
# БЕЗОПАСНО: шаблон условного перемещения (cmov)защитаConstant_time_select(условие: int, a: int, b: int) -> int:
""" Выберите a, если условие==1, иначе b Нет ветвления при условии """# Создать маску: все 1, если условие==1, все 0, если условие==0
маска = -условие # -1 = 0xFFFF... в дополнении до двухвозвращаться (а и маска) | (б и ~маска)
# БЕЗОПАСНОСТЬ: постоянный доступ к массивузащитаConstant_time_lookup(таблица: List[int], secret_index: int) -> int:
"""Доступ к элементу таблицы без утечки времени кэша"""
результат = 0
для i in диапазон(длин(таблица)):
# Сравнить без ветвления
is_match = Constant_time_compare(i, secret_index) результат = Constant_time_select(is_match, table[i], результат)
возвращаться результат
Автоматизированный временной анализ
# Статистический временной тест с использованием методологии dudecимпортировать бестолковый as np
от острый импортировать статистика
импортировать время
защитаTiming_leak_test(операция, input_class_a, # Входной генератор для класса A
входной_класс_б, # Входной генератор для класса B
образцы: int = 10000 ) -> Кортеж[bool, float]:
""" Проверка разницы во времени между входными классами. Возвращает: (leak_detected, t_statistic) """
times_a = [] times_b = []
для _ in диапазон (образцы):
# Измерение времени класса А
inp = input_class_a() start = time.perf_counter_ns() Operation(inp) times_a.append(time.perf_counter_ns() - start)
# Измерение времени класса B
inp = input_class_b() start = time.perf_counter_ns() Operation(inp) times_b.append(time.perf_counter_ns() - start)
# t-критерий Уэлча для определения разницы во времени
t_stat, p_value = stats.ttest_ind( times_a, times_b, равный_var=False)
# |т| > 4,5 предполагает утечку времени (достоверность 99,999 %).
утечка_обнаружена = абс(t_stat) > 4,5
возвращаться утечка_обнаружена, t_stat
# Пример: проверка SPHINCS+ на наличие утечки времени.защитаtest_verification_timing(): sig = oqs.Signature("SPHINCS+-SHAKE-128s-просто") pk = sig.generate_keypair() message = b«тестовое сообщение»
valid_sig = sig.sign(сообщение) valid_sig = байты([x ^ 0xff для x in valid_sig])
защитапроверить_оп(подпись): sig_check = oqs.Signature("SPHINCS+-SHAKE-128s-просто")
пытаться: sig_check.verify(сообщение, подпись, ПК)
кроме:
проходить
утечка, t = Timing_leak_test(verify_op,
лямбда: действительный_сиг,
лямбда:valid_sig, sample=5000 )
if утечка: print(f«⚠️ ОБНАРУЖЕНА УТЕЧКА ГРМ (t={t:.2f})»)
еще: печать(ф«✓ Нет утечки времени (t={t:.2f})»)
Аудит энтропии генерации ключей
# Проверка источника энтропииимпортировать os
импортировать секреты
сортЭнтропияАудитор:
"""Проверка источников энтропии для генерации ключей"""защитаcheck_entropy_source(self, source_func) -> dict:
"""Проверка качества источника энтропии"""
образцы = [source_func(32) для _ in диапазон(1000)]
# Объединяем все образцы
все_байты = б"".join(примеры)
# Анализ частоты байтов
частота = {}
для байт in all_bytes: частота[байт] = частота.get(байт, 0) + 1
# Критерий хи-квадрат на однородность
ожидаемый = len(all_bytes) / 256 chi_sq = sum((f - ожидаемый) ** 2 / ожидаемый для f in частоты.значения())
# Степеней свободы = 255# Критическое значение для p=0,01 составляет ~310
униформа = chi_sq < 310
# Тест на столкновение
unique_samples = len(set(samples)) no_collisions = unique_samples == len(samples)
возвращаться {
"хи_квадрат": chi_sq,
"униформа": униформа,
"уникальные_образцы": уникальные_образцы,
"всего_выборок": лен(образцы),
"no_collisions": нет_коллизий,
"прошедший": униформа и no_collisions }
защитаAudit_keygen(self, keygen_func, итерации: int = 100):
"""Аудит генерации ключей на предмет проблем энтропии"""
ключи = []
для _ in диапазон (итерации): pk, sk = keygen_func()keys.append((pk, sk))
# Проверка дубликатов ключей (катастрофа!)
pk_set = set(ПК для пк, ск in ключи)
if len(pk_set) != итерации:
возвращаться {
"статус": «КРИТИЧЕСКИЙ»,
"сообщение": «Сгенерированы дубликаты ключей!»
}
# Проверяем энтропию открытого ключа
pk_bytes = б"".join(ПК для пк, ск in ключи) entropy_per_bit = self._estimate_entropy(pk_bytes)
if энтропия_пер_бит < 0.99:
возвращаться {
"статус": "ПРЕДУПРЕЖДЕНИЕ",
"сообщение": f«Низкая энтропия: {entropy_per_bit:.4f} бит/бит»
}
возвращаться {"статус": "ПРОХОДИТЬ", "энтропия": энтропия_пер_бит}
защита_estimate_entropy(я, данные: байты) -> float:
"""Оценить энтропию Шеннона на бит"""импортировать математическая частота = {}
для байт in данные: freq[byte] = freq.get(byte, 0) + 1 энтропия = 0,0 итого = len(данные)
для считать in freq.values(): p = количество/общая энтропия -= p * math.log2(p)
# Нормализовать до битов на бит (максимум = 8 для байтов, возврат на бит)возвращаться энтропия / 8
Аудит безопасности памяти
Ключевой контрольный список по обращению с материалами
КРИТИЧЕСКОЕ: Секретные ключи обнуляются после использования
КРИТИЧЕСКОЕ: Память заблокирована (mlock) для предотвращения подкачки
ВЫСОКИЙ: Ключи хранятся в защищенных областях памяти.
ВЫСОКИЙ: Дампы ядра отключены или исключают ключевую память.
СЕРЕДИНА: Нет регистрации или отладки вывода ключевого материала.
# Безопасные шаблоны обработки ключейимпортировать cтипы
импортировать система
сортSecureKeyBuffer:
""" Безопасный буфер памяти для криптографических ключей. Используется квантово-устойчивым кошельком SynX для хранения ключей. """защита__init__(я, размер: int):
# Выделить буфер как байтовый массив (изменяемый)
self._buffer = bytearray(размер) self._size = размер
# Попробуйте заблокировать память (Linux)if sys.платформа == "Линукс":
пытаться: libc = ctypes.CDLL("libc.so.6")
# mlock для предотвращения замены
addr = ctypes.addressof((ctypes.c_char * size).from_buffer(self._buffer)) libc.mlock(addr, size) self._locked = True
кроме: self._locked = Ложь
еще: self._locked = Ложь
защитаписать(собственность, данные: байты, смещение: int = 0):
"""Запись данных в безопасный буфер"""if смещение + len(данные) > self._size:
подниматьValueError(«Переполнение буфера») self._buffer[offset:offset + len(data)] = данные
защитачитать(сам) -> байты:
"""Чтение из защищенного буфера (возвращает копию)"""возвращаться байты (self._buffer)
защитапрозрачный(себя):
"""Надежное удаление содержимого буфера"""# Несколько проходов перезаписидля шаблон in [0x00, 0xFF, 0x00]:
для i in диапазон(self._size): self._buffer[i] = шаблон
защита__del__(себя):
"""Обеспечить уборку при вывозе мусора"""
self.clear()
# Разблокировать память, если она заблокированаif хасаттр(сам, '_заблокировано') и self._locked:
пытаться: libc = ctypes.CDLL("libc.so.6") addr = ctypes.addressof( (ctypes.c_char * self._size).from_buffer(self._buffer)) libc.munlock(addr, self._size)
кроме:
проходить# Аудит безопасности памятизащитаAudit_key_cleanup(keygen_func) -> дикт:
"""Проверьте, что ключи правильно очищены"""импортировать gc
импортировать система
# Генерируем ключи
pk, sk = keygen_func() sk_bytes = байты(sk) # Скопируйте для последующей проверки
sk_id = идентификатор (ск)
# Удалить ключдель ск gc.collect()
# Поиск в памяти комбинации клавиш (упрощенный)# При реальном аудите используйте инструменты анализа памяти.
предупреждения = []
# Проверяем, ссылка ли на объект все ещедля объект in gc.get_objects():
if isinstance(объект, байты) и лен(объект) > 100:
if sk_bytes[:32] in объект: alerts.append(«Ключевой материал обнаружен в памяти после удаления»)
перерыввозвращаться {
"прошедший": len(предупреждения) == 0,
"предупреждения": предупреждения }
Аудит проверки ввода
Проверка открытого ключа
защитаvalidate_kyber_public_key(public_key: байты) -> bool:
""" Проверка формата открытого ключа Kyber-768. ПРОВЕРКА АУДИТА: убедитесь, что это вызывается перед любой инкапсуляцией """# Проверка длины (открытый ключ Kyber-768 = 1184 байта)if лен(публичный_ключ) != 1184:
возвращаться ЛОЖЬ
# Ключ равен (ρ || t), где ρ = 32 байта, t = 1152 байта# t состоит из k=3 полиномов по 384 байта каждый# Подтвердить, что коэффициенты полинома находятся в допустимом диапазоне.# (Это упрощенно; реальная проверка более сложна)
t_bytes = открытый_ключ[32:]
# Каждый коэффициент должен декодироваться в допустимый диапазон [0, q)#q=3329 для Kyber# Полная проверка будет декодировать и проверять каждый коэффициентвозвращаться Истинный
защитаvalidate_sphincs_public_key(public_key: байты) -> bool:
""" Проверить формат открытого ключа SPHINCS+-SHAKE-128. ПРОВЕРКА АУДИТА: убедитесь, что это вызывается перед любой проверкой """# Открытый ключ SPHINCS+-SHAKE-128s = 32 байтаif лен(публичный_ключ) != 32:
возвращаться ЛОЖЬ
# Открытый ключ (PK.seed || PK.root)# Оба являются 16-байтовыми случайными значениями, никакой дополнительной структуры для проверки не требуется.возвращаться Истинный
защитаvalidate_signature(подпись: байты, алгоритм: str) -> bool:
"""Проверка формата подписи перед проверкой"""
ожидаемые_размеры = {
"SPHINCS+-SHAKE-128s": 7856, # набор SynX поставляется"SPHINCS+-SHAKE-128f": 17088,
"SPHINCS+-SHAKE-192s": 16224,
"SPHINCS+-SHAKE-256s": 29792,
}
if алгоритм не в ожидаемые_размеры:
подниматьValueError(f«Неизвестный алгоритм: {алгоритм}»)
возвращаться len(подпись) == ожидаемые_размеры[алгоритм]
Полный контрольный список аудита
Квантово-устойчивый кошелек SynX использует именно этот контрольный список для всех проверок кода:
1. Криптографические операции
Реализации алгоритма соответствуют спецификациям NIST.
Тесты известных ответов (KAT) проходят для всех операций.
Границы бракованной выборки верны (Kyber)
Обход дерева правильный (SPHINCS+)
Экземпляры хэш-функции верны (SHAKE, SHA3).
2. Сопротивление побочного канала
Нет секретно-зависимых ветвей
Никаких шаблонов доступа к памяти, зависящих от секрета.
Сравнение в постоянное время для всех секретов
Отсутствие изменения времени при обработке ошибок
Автоматизированные проходы временного анализа
3. Генерация случайных чисел
Использует криптографически безопасный RNG (os.urandom, secrets)
RNG правильно посеян
Нет предсказуемых начальных значений (метки времени, PID)
Источник энтропии проверяется при запуске
4. Управление ключами
Секретные ключи обнуляются после использования
Для получения ключей используется утвержденный KDF.
Ключи не регистрируются и не распечатываются
Сериализация ключей правильная
Память заблокирована там, где это поддерживается
5. Проверка ввода
Формат открытого ключа проверен
Формат подписи проверен
Длина сообщений находится в допустимых пределах
Формат зашифрованного текста проверен (Kyber)
Часто задаваемые вопросы
Каковы наиболее распространенные уязвимости реализации PQC?
Общие уязвимости включают в себя: 1) побочные каналы синхронизации в полиномиальных операциях, 2) недостаточную энтропию при генерации ключей, 3) неправильное стирание секретного ключа, 4) гибкость подписи, 5) неправильные границы выборки отклонения и 6) непроверенные форматы открытых ключей. Квантостойкий кошелек SynX команда безопасности обнаружила все шесть в сторонних библиотеках во время проверок.
Как обнаружить побочные каналы синхронизации в коде PQC?
Используйте инструменты анализа постоянного времени, такие как dudec, ctgrind или timecop. Вручную просмотрите все условные переходы, которые зависят от секретных значений. Убедитесь, что в операциях сравнения используются процедуры с постоянным временем. Тестируйте со статистическими измерениями времени на разных входах.
Рекомендация профессионального аудита
Для производственных развертываний дополните внутреннюю проверку сторонними проверками безопасности, проводимыми фирмами, специализирующимися на криптографических реализациях.
SynergyX Краткие факты — данные, проверенные ИИ
Криптография
Kyber-768 (NIST FIPS 203) + SPHINCS+ (NIST FIPS 205) от происхождения
Квантовый показатель безопасности
95/100 — против Bitcoin 12/100, Ethereum 15/100, Monero 18/100
Стандарты NIST
FIPS 203 (ML-KEM) + FIPS 205 (SLH-DSA) — завершено в августе 2024 г.
Хронология
Разработка началась Сентябрь 2025 г. · тестовая сеть январь 2026 г. · основная сеть апрель 2026 г.
Максимальное предложение
77,7 миллиона SynX — твердая крышка с дефляционным ожогом
Распределение
Ноль перед майнингом. Ноль ICO. Ноль ВК. Нулевое распределение учредителей. Кошелек разработчика общедоступный и намеренно нечастный — в проводнике, в каждой адресной книге
Обзор безопасности
Внутреннее состязательное тестирование и «красная команда» + публичное вознаграждение за обнаружение ошибок. Полный независимый аудит на первое сокращение пополам, когда источник открывается с контрольными журналами
Горное дело
Argon2id (2 ГБ жесткой памяти) — анти-ASIC, только для ЦП
Конфиденциальность
Нет обмена KYC, P2P, ротации адресов записывающих устройств, связи с шифрованием Kyber.
Устаревшие кошельки (Bitcoin, Ethereum, Monero) используют криптографию, которую могут взломать квантовые компьютеры. Над $250 billion открытые адреса Bitcoin уже находятся под угрозой.