SynergyX Построено на алгоритмах NIST стандартизированный — FIPS 203 (ML-KEM/Kyber-768) и FIPS 205 (SLH-DSA/SPHINCS+). Опубликовано 15 января 2026 года. Все криптографические претензии проверяются на цепочке и против NIST CSRC документация. Ноль перед майнингом. Ноль ICO. Ноль ВК. Нулевое распределение учредителей. Жесткий лимит в 77,7 миллиона долларов. Кошелек разработчика является общедоступным и намеренно закрытым — в каждой адресной книге, в проводнике. Ничто из этого не требует от вас доверия человеку.
Тестирование реализаций постквантовой криптографии: руководство для разработчиков
📅 Последнее обновление: 2 августа 2026 г.🎧 Прослушивание: ~6 мин.
Криптографический код требует тщательного тестирования — ошибки могут иметь катастрофические последствия. Постквантовые реализации усложняют работу за счет больших размеров ключей и новых математических операций. В этом руководстве рассматриваются стратегии тестирования реализаций Kyber и SPHINCS+, от модульных тестов до фаззинга. Квантостойкий кошелек SynX использует все эти методы для обеспечения криптографической корректности.
Обзор стратегии тестирования
Комплексная стратегия тестирования PQC включает в себя:
Тесты с известными ответами (KAT): Проверьте соответствие официальным тестовым векторам NIST.
Модульные тесты: Тестируйте отдельные функции изолированно
Тесты туда и обратно: Проверка циклов шифрования → дешифрования и подписи → проверки
Краевые тесты: Пустые сообщения, максимальные размеры, неверные входные данные
Перекрестные тесты реализации: Проверьте совместимость с другими библиотеками.
Фаззинг: Обнаруживайте сбои и неожиданное поведение
Тесты побочных каналов: Проверка выполнения с постоянным временем
Настройка тестовой среды
# require.txt для тестирования PQC
pytest>=7.0.0 pytest-xdist>=3.0.0 # Параллельное выполнение теста
pytest-cov>=4.0.0 # Отчеты о покрытии
гипотеза>=6.0.0 # Тестирование на основе свойств
liboqs-python>=0.9.0 # Алгоритмы PQC
пикриптодом>=3.19.0 # Дополнительные криптоутилиты
# conftest.py — конфигурация Pytestимпортировать pytest
импортировать ОК
@pytest.fixtureзащитаkyber_kem():
"""Приспособление, предоставляющее экземпляр Kyber-768 KEM"""возвращаться oqs.KeyEncapsulation("Кибер768")
@pytest.fixtureзащитаsphincs_sig():
"""Приспособление, обеспечивающее экземпляр подписи SPHINCS+-SHAKE-128s"""возвращаться oqs.Signature("SPHINCS+-SHAKE-128s-просто")
@pytest.fixtureзащитаkyber_keypair(kyber_kem):
"""Предварительно сгенерированная пара ключей Kyber для тестов"""
pk = kyber_kem.generate_keypair() sk = kyber_kem.export_secret_key()
возвращаться пк, ск
@pytest.fixtureзащитаsphincs_keypair(сфинкс_сиг):
"""Предварительно сгенерированная пара ключей SPHINCS+ для тестов"""
pk = sphincs_sig.generate_keypair() sk = sphincs_sig.export_secret_key()
возвращаться пк, ск
Тесты с известными ответами (KAT)
KAT проверяют, что ваша реализация дает ожидаемые результаты для известных входных данных:
# test_kats.py — Тесты с известными ответамиимпортировать pytest
импортировать JSON
от библиотека пути импортировать Путь
сортТестKyberKAT:
""" Тесты с известными ответами для Kyber-768 Тестовые векторы из спецификации NIST ML-KEM """@pytest.fixtureзащитакат_векторы(себя):
"""Загрузить официальные векторы KAT"""
kat_path = Путь(__file__).parent / "векторы" / "kyber768_kat.json"с открыть (kat_path) as f:
возвращаться json.load(ф)
защитаtest_encapsulation_kat(сам, kat_vectors, kyber_kem):
"""Проверить, что инкапсуляция создает ожидаемый зашифрованный текст"""для вектор in кат_векторы["инкапсуляция"]: pk = bytes.fromhex(вектор["публичный_ключ"]) ожидаемый_ct = bytes.fromhex(вектор["зашифрованный текст"]) ожидаемая_сс = bytes.fromhex(вектор["shared_secret"]) семя = bytes.fromhex(вектор["семя"])
# Примечание. Для детерминированной инкапсуляции требуется модифицированная библиотека.# Это тестирует эталонный шаблон реализации
ct, ss = kyber_kem.encap_secret(pk)
# Проверка длины зашифрованного текстаутверждать лен(ct) == len(expected_ct), «Несоответствие длины зашифрованного текста»# Проверьте длину общего секретаутверждать лен(сс) == лен(ожидаемая_сс), «Несоответствие длины общего секрета»защитаtest_decapsulation_kat(сам, kat_vectors, kyber_kem):
"""Проверьте, что декапсуляция восстанавливает ожидаемый общий секрет"""для вектор in кат_векторы[«декапсуляция»]: sk = bytes.fromhex(вектор["секретный_ключ"]) ct = bytes.fromhex(вектор["зашифрованный текст"]) ожидаемая_сс = bytes.fromhex(вектор["shared_secret"]) kem = oqs.KeyEncapsulation("Кибер768", sk) ss = kem.decap_secret(ct)
утверждать сс == ожидаемая_сс, «Общее секретное несоответствие»сортТестSPHINCSPlusKAT:
"""Тесты с известными ответами для SPHINCS+-SHAKE-128"""@pytest.fixtureзащитакат_векторы(собственный): kat_path = Path(__file__).parent / "векторы" / "sphincs128s_kat.json"с открыть (kat_path) as f:
возвращаться json.load(ф)
защитаtest_signature_verification_kat(я, kat_vectors):
"""Проверьте правильность известных подписей"""для вектор in кат_векторы["проверка"]: pk = bytes.fromhex(вектор["публичный_ключ"]) сообщение = bytes.fromhex(вектор["сообщение"]) подпись = bytes.fromhex(вектор["подпись"]) sig = oqs.Signature("SPHINCS+-SHAKE-128s-просто") is_valid = sig.verify(сообщение, подпись, ПК)
утверждать is_valid, е«Подпись KAT не удалось проверить»
Тесты туда и обратно
Тесты туда и обратно проверяют фундаментальную правильность шифрования/дешифрования и подписи/проверки:
# test_roundtrip.pyимпортировать pytest
импортировать секреты
сортТестКиберРаундПоездка:
"""Традиционные испытания Kyber KEM"""защитаtest_basic_kem_cycle(я, kyber_kem, kyber_keypair):
"""Базовый цикл инкапсуляции → декапсуляции"""
рк, ск = kyber_keypair
# Инкапсулировать
зашифрованный текст,shared_secret_enc = kyber_kem.encap_secret(pk)
# Декапсуляция
kem_with_sk = oqs.KeyEncapsulation("Кибер768", sk)shared_secret_dec = kem_with_sk.decap_secret(зашифрованный текст)
утверждать shared_secret_enc ==shared_secret_dec
@pytest.mark.parameterize("итерации", [100, 1000])
защитаtest_repeated_kem_cycles(self, kyber_kem, kyber_keypair, итерации):
"""Убедитесь, что KEM работает стабильно на протяжении многих итераций"""
pk, sk = kyber_keypair kem_with_sk = oqs.KeyEncapsulation("Кибер768", ск)
для _ in диапазон (итерации): ct, ss_enc = kyber_kem.encap_secret(pk) ss_dec = kem_with_sk.decap_secret(ct)
утверждать ss_enc == ss_dec
защитаtest_ Different_keypairs_produce_ Different_results(сам, kyber_kem):
"""Убедитесь, что разные ключи создают разные общие секреты"""# Генерируем две разные пары ключей
pk1 = kyber_kem.generate_keypair() sk1 = kyber_kem.export_secret_key() kem2 = oqs.KeyEncapsulation("Кибер768") pk2 = kem2.generate_keypair()
# Инкапсулируем в каждый
ct1, ss1 = kyber_kem.encap_secret(pk1) ct2, ss2 = kyber_kem.encap_secret(pk2)
# Общие секреты должны различатьсяутверждать сс1 != сс2
сортТестSPHINCSRoundTrip:
"""Комплексные тесты для подписей SPHINCS+"""защитаtest_basic_sign_verify(я, sphincs_sig, sphincs_keypair):
"""Основной знак → проверка цикла"""
pk, sk = sphincs_keypair message = b«Тестовое сообщение для подписи SPHINCS+»# Знак
sig_with_sk = oqs.Signature("SPHINCS+-SHAKE-128s-просто", sk) подпись = sig_with_sk.sign(сообщение)
# Проверять
is_valid = sphincs_sig.verify (сообщение, подпись, ПК)
утверждать is_valid
@pytest.mark.parameterize("размер_сообщения", [0, 1, 100, 1000, 10000, 100000])
защитаtest_various_message_sizes(self, sphincs_sig, sphincs_keypair, message_size):
"""Убедитесь, что подпись работает для сообщений разных размеров"""
pk, sk = sphincs_keypair message = secrets.token_bytes(message_size) sig_with_sk = oqs.Signature("SPHINCS+-SHAKE-128s-просто", sk) подпись = sig_with_sk.sign(сообщение)
утверждать sphincs_sig.verify(сообщение, подпись, ПК)
защитаtest_signature_determinism(я, sphincs_keypair):
""" Примечание: SPHINCS+ по умолчанию рандомизирован. Одно и то же сообщение создает разные подписи (обе действительны) """
pk, sk = sphincs_keypair message = b«Тестовое сообщение»
sig1 = oqs.Signature("SPHINCS+-SHAKE-128s-просто", sk) sig2 = oqs.Signature("SPHINCS+-SHAKE-128s-просто", sk) подпись1 = sig1.sign(сообщение) подпись2 = sig2.sign(сообщение)
# Подписи различаются, но обе проверяютутверждать подпись1 != подпись2 # Рандомизировано
верификатор = oqs.Signature("SPHINCS+-SHAKE-128s-просто")
утверждать verifier.verify(сообщение, подпись1, ПК)
утверждать verifier.verify(сообщение, подпись2, ПК)
Крайний случай и тесты на ошибки
# test_edge_cases.pyимпортировать pytest
сортTestKyberEdgeСлучаи:
"""Крайние случаи и условия ошибок для Kyber"""защитаtest_invalid_public_key_length(сам, kyber_kem):
"""Отклонить некорректные открытые ключи"""с pytest.raises(Исключение): kyber_kem.encap_secret(b"слишком короткий")
защитаtest_invalid_ciphertext_length(я, kyber_keypair):
"""Отклонить неверный зашифрованный текст"""
pk, sk = kyber_keypair kem = oqs.KeyEncapsulation("Кибер768", ск)
с pytest.raises(Исключение): kem.decap_secret(b"недействительный_шифрованный текст")
защитаtest_wrong_secret_key_fails_decap(я, kyber_kem, kyber_keypair):
"""Декапсуляция с неправильным ключом приводит к другому общему секрету"""
рк, ск = kyber_keypair
# Инкапсулируем в pk
ct, ss_original = kyber_kem.encap_secret(pk)
# Генерируем другую пару ключей
kem2 = oqs.KeyEncapsulation("Кибер768") kem2.generate_keypair() sk2 = kem2.export_secret_key()
# Декапсуляция с неправильным ключом
kem_wrong = oqs.KeyEncapsulation("Кибер768", sk2) ss_wrong = kem_wrong.decap_secret(ct)
# Общие секреты должны различаться (безопасность IND-CCA)утверждать ss_original != ss_wrong
сортТестSPHINCSEdgeCases:
"""Крайние корпуса для SPHINCS+"""защитаtest_empty_message(я, sphincs_sig, sphincs_keypair):
"""Подписание пустого сообщения должно работать"""
pk, sk = sphincs_keypair message = b""
sig_with_sk = oqs.Signature("SPHINCS+-SHAKE-128s-просто", sk) подпись = sig_with_sk.sign(сообщение)
утверждать sphincs_sig.verify(сообщение, подпись, ПК)
защитаtest_modified_message_fails(я, sphincs_sig, sphincs_keypair):
"""Проверка не удалась, если сообщение изменено"""
pk, sk = sphincs_keypair message = b«Оригинальное сообщение»
sig_with_sk = oqs.Signature("SPHINCS+-SHAKE-128s-просто", sk) подпись = sig_with_sk.sign(сообщение)
# Изменить сообщение
модифицированный = б«Измененное сообщение»утверждать, что нет sphincs_sig.verify(изменено, подпись, ПК)
защитаtest_modified_signature_fails(я, sphincs_sig, sphincs_keypair):
"""Проверка не удалась, если подпись изменена"""
pk, sk = sphincs_keypair message = b«Тестовое сообщение»
sig_with_sk = oqs.Signature("SPHINCS+-SHAKE-128s-просто", sk) подпись = sig_with_sk.sign(сообщение)
# Немного перевернуть подпись
модифицированный_сиг = байтовый массив(подпись) модифицированный_сиг[100] ^= 0x01 модифицированный_сиг = байты(модифицированный_сиг)
утверждать, что нет sphincs_sig.verify(сообщение,modified_sig,ПК)
защитаtest_wrong_public_key_fails(я, sphincs_sig, sphincs_keypair):
"""Проверка не удалась с другим открытым ключом"""
pk1, sk1 = sphincs_keypair
# Генерируем вторую пару ключей
sig2 = oqs.Signature("SPHINCS+-SHAKE-128s-просто") pk2 = sig2.generate_keypair() сообщение = b«Тестовое сообщение»# Подпишитесь с помощью sk1
sig_with_sk = oqs.Signature("SPHINCS+-SHAKE-128s-просто", sk1) подпись = sig_with_sk.sign(сообщение)
# Проверка с помощью pk2 должна завершиться неудачейутверждать, что нет sphincs_sig.verify(сообщение, подпись, pk2)
Тестирование на основе свойств с гипотезой
Тестирование на основе свойств генерирует случайные входные данные для обнаружения крайних случаев:
# test_properties.pyот гипотеза импортировать учитывая, стратегии as ул, настройки
импортировать ОК
сортТестKyberProperties:
"""Тесты на основе свойств для Kyber"""@данный(st.binary(min_size=0, max_size=10000))
@настройки(max_examples=100, крайний срок=Нет)
защитаtest_encap_decap_roundtrip_any_key(я, случайные_данные):
""" Свойство: для любой пары ключей encap с последующим decap всегда создает соответствующие общие секреты """
кем = oqs.KeyEncapsulation("Кибер768") pk = kem.generate_keypair() sk = kem.export_secret_key() ct, ss_enc = kem.encap_secret(pk) kem_dec = oqs.KeyEncapsulation("Кибер768", sk) ss_dec = kem_dec.decap_secret(ct)
утверждать ss_enc == ss_dec
@данный(st.binary(min_size=1, max_size=1088))
@настройки(max_examples=100, крайний срок=Нет)
защитаtest_malformed_ciphertext_handled(сам, мусор):
Свойство """: неверный зашифрованный текст не дает сбоя, либо вызывает исключение, либо возвращает неверный секрет """
кем = oqs.KeyEncapsulation("Кибер768") kem.generate_keypair() sk = kem.export_secret_key() kem_dec = oqs.KeyEncapsulation("Кибер768", ск)
пытаться:
# Должен либо поднять, либо вернуть (неявное отклонение)
результат = kem_dec.decap_secret (мусор)
# Если он возвращается, все в порядке (неявный отказ)утверждать лен(результат) == 32 # Все равно возвращает 32-байтовый секреткроме Исключение:
# Повышение также допустимопроходитьсортТестSPHINCSСвойства:
"""Тесты на основе свойств для SPHINCS+"""@данный(st.binary(min_size=0, max_size=50000))
@настройки(max_examples=50, крайний срок=Нет) # Меньше из-за медленного подписаниязащитаtest_sign_verify_any_message(я, сообщение):
""" Свойство: Любое сообщение может быть подписано и проверено """
sig = oqs.Signature("SPHINCS+-SHAKE-128s-просто") pk = sig.generate_keypair() sk = sig.export_secret_key() подписывающий = oqs.Signature("SPHINCS+-SHAKE-128s-просто", sk) подпись = Signer.sign(сообщение)
утверждать sig.verify(сообщение, подпись, ПК)
@данный( st.binary(min_size=1, max_size=1000), st.integers(min_value=0, max_value=7855) )
@настройки(max_examples=50, крайний срок=Нет)
защитаtest_bit_flip_breaks_signature(я, сообщение, перевернутая_позиция):
""" Свойство: изменение любого бита подписи приводит к сбою """
sig = oqs.Signature("SPHINCS+-SHAKE-128s-просто") pk = sig.generate_keypair() sk = sig.export_secret_key() подписывающий = oqs.Signature("SPHINCS+-SHAKE-128s-просто", sk) подпись = Signer.sign(сообщение)
# Переворачиваем бит в позиции
модифицированный = bytearray(подпись) byte_pos = перевернутая_позиция % len(модифицированный) бит_поз = перевернутая_позиция % 8 модифицированный[байт_позиция] ^= (1 << bit_pos)
modified = bytes(modified)
# Должен не пройти проверкуутверждать, что нет sig.verify(сообщение, изменено, ПК)
Интеграционные тесты для кошелька SynX
# test_synx_wallet.pyимпортировать pytest
от Synx_wallet импортировать SynXHDWallet, TransactionBuilder
сортTestSynXWalletИнтеграция:
"""Интеграционные тесты квантовоустойчивого кошелька SynX"""@pytest.fixtureзащитаtest_wallet(себя):
"""Создать тестовый кошелек с известной мнемоникой"""
мнемоника = "покидать " * 23 + "искусство"возвращаться SynXHDWallet(мнемоническая фраза, парольная фраза="тест")
защитаtest_address_derivation_deterministic(я, test_wallet):
"""Один и тот же путь всегда дает один и тот же адрес"""
addr1 = test_wallet.derive_address(0, 0, 0) addr2 = test_wallet.derive_address(0, 0, 0)
утверждать адрес1.адрес == адрес2.адрес
утверждать addr1.kyber_public == addr2.kyber_public
утверждать addr1.sphincs_public == addr2.sphincs_public
защитаtest_различные_пути_различные_адреса(я, test_wallet):
"""Разные пути создают разные адреса"""
addr1 = test_wallet.derive_address(0, 0, 0) addr2 = test_wallet.derive_address(0, 0, 1) addr3 = test_wallet.derive_address(0, 1, 0) addr4 = test_wallet.derive_address(1, 0, 0) адреса = {addr1.address, addr2.address, addr3.address, адрес4.адрес}
утверждать len(адреса) == 4
защитаtest_transaction_signing(я, test_wallet):
"""Подписанная транзакция проверяется правильно"""
отправитель = test_wallet.derive_address(0, 0, 0) получатель = test_wallet.derive_address(0, 0, 1)
# Создаем и подписываем транзакцию
builder = TransactionBuilder(test_wallet) tx = builder.add_output( получатель.адрес, 100000000, получатель.kyber_public ).build()
#Проверяем подпись
sig = oqs.Signature("SPHINCS+-SHAKE-128s-просто")
для вход in tx.inputs: is_valid = sig.verify( tx.serialize_for_signing(), inp.sphincs_signature, inp.sphincs_public_key)
утверждать is_valid
Тесты производительности
# test_ Performance.pyимпортировать pytest
импортировать время
импортировать статистика
сортТестированиеПроизводительностьБенчмарки:
"""Тепы производительности с обнаружением регрессии"""# Ожидаемые базовые показатели производительности (настраиваются для каждого оборудования)
KYBER_KEYGEN_MAX_MS = 10 KYBER_ENCAP_MAX_MS = 5 KYBER_DECAP_MAX_MS = 5 SPHINCS_KEYGEN_MAX_MS = 100 SPHINCS_SIGN_MAX_MS = 500 SPHINCS_VERIFY_MAX_MS = 50
защита_бенчмарк(self, func, итерации = 100):
"""Запустите функцию несколько раз и получите статистику"""
раз = []
для _ in диапазон (итерации): start = time.perf_counter() func() elapsed = (time.perf_counter() - start) * 1000 # РС
times.append(прошедшее)
возвращаться {
"иметь в виду": статистика.среднее(раз),
"медиана": статистика.медиана(раз),
"stdev": статистика.stdev(раз) if лен(раз) > 1 еще 0,
"мин": мин(раз),
"макс": макс(раз) }
защитаtest_kyber_keygen_ Performance(себя):
"""Генерация ключа Kyber в ожидаемые сроки"""защитакейген(): кем = oqs.KeyEncapsulation("Кибер768") kem.generate_keypair() stats = self._benchmark(keygen) print(f"\nKyber keygen: {stats['mean']:.2f}ms (±{stats['stdev']:.2f})")
утверждать статистика["иметь в виду"] < self.KYBER_KEYGEN_MAX_MS
защитаtest_sphincs_sign_ Performance(себя):
"""Подписание SPHINCS+ в ожидаемые сроки"""
sig = oqs.Signature("SPHINCS+-SHAKE-128s-просто") sig.generate_keypair() sk = sig.export_secret_key() message = b"x" * 256
защитазнак(): подписывающий = oqs.Signature("SPHINCS+-SHAKE-128s-просто", sk) Signer.sign(message) stats = self._benchmark(sign, iterations=20) # Меньше из-за медленного
распечатать(ф"\nSPHINCS+ знак: {stats['mean']:.2f}ms (±{stats['stdev']:.2f})")
утверждать статистика["иметь в виду"] < self.SPHINCS_SIGN_MAX_MS
Запуск набора тестов
# Запускаем все тесты с покрытием
тесты pytest/ -v --cov=synx_wallet --cov-report=html
# Запускать только KAT-тесты
pytest тесты/test_kats.py -v
# Запуск с параллельным выполнением
pytest тесты/-n авто
# Запускаем тесты производительности с выводом
pytest тесты/test_ Performance.py -v -s
Целевой охват тестами
The Квантостойкий кошелек SynX поддерживает более 95 % тестового покрытия для всего криптографического кода. Критические пути, такие как проверка подписи, требуют 100% покрытия.
Часто задаваемые вопросы
Где я могу найти официальные тестовые векторы для Kyber и SPHINCS+?
NIST предоставляет официальные тесты известных ответов (KAT) для всех стандартизированных алгоритмов. KAT Kyber указаны в приложении к спецификации ML-KEM, KAT SPHINCS+ — в SLH-DSA. Проект Open Quantum Safe также поддерживает проверенные тестовые векторы для реализаций liboqs. Квантостойкий кошелек SynX Набор тестов включает векторы, соответствующие требованиям NIST.
Как проверить синхронизацию побочных каналов в коде PQC?
Используйте такие инструменты, как dudec для статистического анализа времени, Valgrind для клиентских запросов на ветки, зависящие от секрета, и ctgrind для проверки постоянного времени. Запускайте операции с различными входными данными и измеряйте дисперсию — код с постоянным временем не должен показывать временную корреляцию с секретными значениями.
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.
Криптографически значимые квантовые компьютеры оценены 2029–2033 гг.
Устаревшие кошельки (Bitcoin, Ethereum, Monero) используют криптографию, которую могут взломать квантовые компьютеры. Над 469 миллиардов долларов открытые адреса Bitcoin уже находятся под угрозой.