SynergyX Basado en los algoritmos NIST estandarizado — FIPS 203 (ML-KEM/Kyber-768) y FIPS 205 (SLH-DSA/SPHINCS+), publicado el 15 de enero de 2026. Todas las afirmaciones criptográficas son verificables en la cadena y contra NIST CSRC documentación adicional. Cero pre-minado. Cero ICO. Cero VC. Cero asignación de fundadores. 77,7 millones de hard cap. La billetera del desarrollador es pública y deliberadamente no privada, en cada libreta de direcciones, en el explorador. Nada de eso te pide que confíes en una persona.
Prueba de implementaciones de criptografía poscuántica: guía para desarrolladores
📅 Última actualización: 2 de agosto de 2026🎧 Escuche: ~6 min
El código criptográfico exige pruebas rigurosas; los errores pueden ser catastróficos. Las implementaciones poscuánticas añaden complejidad con claves de mayor tamaño y nuevas operaciones matemáticas. Esta guía cubre estrategias de prueba para implementaciones de Kyber y SPHINCS+, desde pruebas unitarias hasta fuzzing. El Cartera SynX con resistencia cuántica emplea todas estas técnicas para garantizar la corrección criptográfica.
Descripción general de la estrategia de prueba
Una estrategia integral de pruebas de PQC incluye:
Pruebas de respuestas conocidas (KAT): Verifique con los vectores de prueba oficiales NIST
Pruebas unitarias: Pruebe funciones individuales de forma aislada
Pruebas de ida y vuelta: Verificar cifrar → descifrar y firmar → verificar ciclos
Pruebas de casos extremos: Mensajes vacíos, tamaños máximos, entradas con formato incorrecto
Pruebas de implementación cruzada: Verificar la interoperabilidad con otras bibliotecas
Fuzzing: Descubra fallas y comportamientos inesperados
Pruebas de canal lateral: Verificar la ejecución en tiempo constante
Configurar el entorno de prueba
# requisitos.txt para pruebas PQC
pytest>=7.0.0 pytest-xdist>=3.0.0 # Ejecución de pruebas en paralelo
pytest-cov>=4.0.0 # Informes de cobertura
hipótesis>=6.0.0 # Pruebas basadas en propiedades
liboqs-python>=0.9.0 # Algoritmos PQC
pycryptodome>=3.19.0 # Utilidades criptográficas adicionales
# conftest.py - Configuración de Pytestimportar pytest
importar oqs
@pytest.accesoriodefkyber_kem():
"""Dispositivo que proporciona la instancia KEM Kyber-768"""devolver oqs.KeyEncapsulation("Kyber768")
@pytest.accesoriodefesfincs_sig():
"""Accesorio que proporciona la instancia de firma SPHINCS+-SHAKE-128s"""devolver oqs.Firma("SPHINCS+-SHAKE-128s-simple")
@pytest.accesoriodefkyber_keypair(kyber_kem):
"""Par de claves Kyber pregenerado para pruebas"""
pk = kyber_kem.generate_keypair() sk = kyber_kem.export_secret_key()
devolver pk, sk
@pytest.accesoriodefpar_claves_esfincas(esfincs_sig):
"""Par de claves SPHINCS+ pregenerado para pruebas"""
pk = sphincs_sig.generate_keypair() sk = sphincs_sig.export_secret_key()
devolver pk, sk
Pruebas de respuestas conocidas (KAT)
Los KAT verifican que su implementación produzca los resultados esperados para las entradas conocidas:
# test_kats.py - Pruebas de respuestas conocidasimportar pytest
importar json
de rutalib importar Camino
clasePruebaKyberKAT:
""" Pruebas de respuestas conocidas para vectores de prueba Kyber-768 de la especificación NIST ML-KEM """@pytest.accesoriodefkat_vectores(ser):
"""Cargar vectores KAT oficiales"""
kat_path = Ruta(__archivo__).padre / "vectores" / "kyber768_kat.json"con abierto(kat_path) as f:
devolver json.cargar(f)
defprueba_encapsulación_kat(yo, kat_vectors, kyber_kem):
"""Verificar que la encapsulación produzca el texto cifrado esperado"""para vector in vectores_kat["encapsulación"]: pk = bytes.fromhex(vector["clave_pública"]) esperado_ct = bytes.fromhex(vector["texto cifrado"]) esperado_ss = bytes.fromhex(vector["secreto_compartido"]) semilla = bytes.fromhex(vector["semilla"])
# Nota: la encapsulación determinista requiere una biblioteca modificada# Esto prueba el patrón de implementación de referencia.
ct, ss = kyber_kem.encap_secret(pk)
# Verificar la longitud del texto cifradoafirmar len(ct) == len(esperado_ct), "La longitud del texto cifrado no coincide"# Verificar la longitud del secreto compartidoafirmar len(ss) == len(esperado_ss), "La longitud del secreto compartido no coincide"defprueba_decapsulación_kat(yo, kat_vectors, kyber_kem):
"""Verificar que la decapsulación recupere el secreto compartido esperado"""para vector in vectores_kat["decapsulación"]: sk = bytes.fromhex(vector["clave_secreta"]) ct = bytes.fromhex(vector["texto cifrado"]) esperado_ss = bytes.fromhex(vector["secreto_compartido"]) kem = oqs.KeyEncapsulation("Kyber768", sk) ss = kem.decap_secret(ct)
afirmar ss == esperado_ss, "No coincide el secreto compartido"clasePruebaSPHINCSPlusKAT:
"""Pruebas de respuestas conocidas para SPHINCS+-SHAKE-128"""@pytest.accesoriodefkat_vectores(yo): kat_path = Ruta(__archivo__).padre / "vectores" / "sphincs128s_kat.json"con abierto(kat_path) as f:
devolver json.cargar(f)
defprueba_firma_verificación_kat(yo, kat_vectors):
"""Verificar que las firmas conocidas se validen correctamente"""para vector in vectores_kat["verificación"]: pk = bytes.fromhex(vector["clave_pública"]) mensaje = bytes.fromhex(vector["mensaje"]) firma = bytes.fromhex(vector["firma"]) sig = oqs.Firma("SPHINCS+-SHAKE-128s-simple") is_valid = sig.verify(mensaje, firma, paquete)
afirmar es_válido, f"No se pudo verificar la firma KAT"
Pruebas de ida y vuelta
Las pruebas de ida y vuelta verifican la corrección fundamental de cifrar/descifrar y firmar/verificar:
# prueba_ida y vuelta.pyimportar pytest
importar misterios
clasePruebaKyberRoundTrip:
"""Pruebas de ida y vuelta para Kyber KEM"""deftest_basic_kem_cycle(yo, kyber_kem, kyber_keypair):
"""Ciclo básico de encapsular → decapsular"""
pk, sk = kyber_keypair
# Encapsular
texto cifrado, share_secret_enc = kyber_kem.encap_secret(pk)
# Decapsular
kem_with_sk = oqs.KeyEncapsulation("Kyber768", sk)shared_secret_dec = kem_with_sk.decap_secret(texto cifrado)
afirmar secreto_compartido_enc == secreto_compartido_dec
@pytest.mark.parametrizar("iteraciones", [100, 1000])
defprueba_repetida_kem_ciclos(self, kyber_kem, kyber_keypair, iteraciones):
"""Verificar que KEM funcione de manera consistente en muchas iteraciones"""
pk, sk = kyber_keypair kem_with_sk = oqs.KeyEncapsulation("Kyber768",sk)
para _ in rango(iteraciones): ct, ss_enc = kyber_kem.encap_secret(pk) ss_dec = kem_with_sk.decap_secret(ct)
afirmar ss_enc == ss_dec
deftest_diferentes_pares_claves_produce_diferentes_resultados(yo, kyber_kem):
"""Verificar que diferentes claves produzcan diferentes secretos compartidos"""# Generar dos pares de claves diferentes
pk1 = kyber_kem.generate_keypair() sk1 = kyber_kem.export_secret_key() kem2 = oqs.KeyEncapsulation("Kyber768") pk2 = kem2.generate_keypair()
# Encapsular a cada uno
ct1, ss1 = kyber_kem.encap_secret(pk1) ct2, ss2 = kyber_kem.encap_secret(pk2)
# Los secretos compartidos deben diferirafirmar ss1 != ss2
clasePruebaSPHINCSRondaViaje:
"""Pruebas de ida y vuelta para firmas SPHINCS+"""defprueba_basic_sign_verificar(yo, sphincs_sig, sphincs_keypair):
"""Señal básica → verificar ciclo"""
pk, sk = sphincs_keypair mensaje = b"Mensaje de prueba para la firma SPHINCS+"# Firmar
sig_with_sk = oqs.Firma("SPHINCS+-SHAKE-128s-simple", sk) firma = sig_with_sk.sign(mensaje)
# Verificar
is_valid = sphincs_sig.verify(mensaje, firma, pk)
afirmar es_válido
@pytest.mark.parametrizar("tamaño_mensaje", [0, 1, 100, 1000, 10000, 100000])
defprueba_varios_tamaños_de_mensajes(self, sphincs_sig, sphincs_keypair, message_size):
"""Verificar que la firma funcione para varios tamaños de mensajes"""
pk, sk = sphincs_keypair mensaje = secrets.token_bytes(message_size) sig_with_sk = oqs.Signature("SPHINCS+-SHAKE-128s-simple", sk) firma = sig_with_sk.sign(mensaje)
afirmar sphincs_sig.verify(mensaje, firma, pk)
defprueba_firma_determinismo(yo, sphincs_keypair):
""" Nota: SPHINCS+ es aleatorio de forma predeterminada. El mismo mensaje produce firmas diferentes (ambas válidas) """
pk, sk = sphincs_keypair mensaje = b"Mensaje de prueba"
sig1 = oqs.Firma("SPHINCS+-SHAKE-128s-simple", sk) sig2 = oqs.Firma("SPHINCS+-SHAKE-128s-simple", sk) firma1 = sig1.sign(mensaje) firma2 = sig2.sign(mensaje)
# Las firmas difieren pero ambas se verificanafirmar firma1 != firma2 # Aleatorizado
verificador = oqs.Firma("SPHINCS+-SHAKE-128s-simple")
afirmar verificador.verificar (mensaje, firma1, paquete)
afirmar verificador.verificar (mensaje, firma2, paquete)
Casos extremos y pruebas de error
# test_edge_cases.pyimportar pytest
clasePruebaKyberEdgeCasos:
"""Casos extremos y condiciones de error para Kyber"""deftest_invalid_public_key_length(yo, kyber_kem):
"""Rechazar claves públicas con formato incorrecto"""con pytest.raises (Excepción): kyber_kem.encap_secret (b"demasiado_corto")
deftest_invalid_ciphertext_length(yo, kyber_keypair):
"""Rechazar texto cifrado con formato incorrecto"""
pk, sk = kyber_keypair kem = oqs.KeyEncapsulation("Kyber768",sk)
con pytest.raises (Excepción): kem.decap_secret (b"texto_cifrado_inválido")
deftest_wrong_secret_key_fails_decap(yo, kyber_kem, kyber_keypair):
"""La decapsulación con una clave incorrecta produce un secreto compartido diferente"""
pk, sk = kyber_keypair
# Encapsular en pk
ct, ss_original = kyber_kem.encap_secret(pk)
# Generar un par de claves diferente
kem2 = oqs.KeyEncapsulation("Kyber768") kem2.generate_keypair() sk2 = kem2.export_secret_key()
# Decapsular con clave incorrecta
kem_wrong = oqs.KeyEncapsulation("Kyber768", sk2) ss_wrong = kem_wrong.decap_secret(ct)
# Los secretos compartidos deben diferir (seguridad IND-CCA)afirmar ss_original!= ss_incorrecto
claseTestSPHINCSEdgeCasos:
"""Maletas de borde para SPHINCS+"""defmensaje_empty_prueba(yo, sphincs_sig, sphincs_keypair):
"""Firmar mensaje vacío debería funcionar"""
pk, sk = sphincs_keypair mensaje = b""
sig_with_sk = oqs.Firma("SPHINCS+-SHAKE-128s-simple", sk) firma = sig_with_sk.sign(mensaje)
afirmar sphincs_sig.verify(mensaje, firma, pk)
deftest_modified_message_fails(yo, sphincs_sig, sphincs_keypair):
"""La verificación falla si se modifica el mensaje"""
pk, sk = sphincs_keypair mensaje = b"Mensaje original"
sig_with_sk = oqs.Firma("SPHINCS+-SHAKE-128s-simple", sk) firma = sig_with_sk.sign(mensaje)
# Modificar mensaje
modificado = b"Mensaje modificado"afirmar no sphincs_sig.verify(modificado, firma, pk)
deftest_modified_signature_fails(yo, sphincs_sig, sphincs_keypair):
"""La verificación falla si se modifica la firma"""
pk, sk = sphincs_keypair mensaje = b"Mensaje de prueba"
sig_with_sk = oqs.Firma("SPHINCS+-SHAKE-128s-simple", sk) firma = sig_with_sk.sign(mensaje)
# Voltear un poco la firma
sig_modificado = bytearray(firma) sig_modificado[100] ^= 0x01 sig_modificado = bytes(sig_modificado)
afirmar no sphincs_sig.verify(mensaje, modificado_sig, pk)
deftest_wrong_public_key_fails(yo, sphincs_sig, sphincs_keypair):
"""La verificación falla con una clave pública diferente"""
pk1, sk1 = par de claves_esfincas
# Generar segundo par de claves
sig2 = oqs.Firma("SPHINCS+-SHAKE-128s-simple") pk2 = sig2.generate_keypair() mensaje = b"Mensaje de prueba"# Firmar con sk1
sig_with_sk = oqs.Firma("SPHINCS+-SHAKE-128s-simple", sk1) firma = sig_with_sk.sign(mensaje)
# Verificar con pk2 debería fallarafirmar no sphincs_sig.verify(mensaje, firma, pk2)
Pruebas basadas en propiedades con hipótesis
Las pruebas basadas en propiedades generan entradas aleatorias para encontrar casos extremos:
#test_properties.pyde hipótesis importar dado, estrategias as st, configuración
importar oqs
clasePruebaKyberPropiedades:
"""Pruebas basadas en propiedades para Kyber"""@dado(st.binario(tamaño_mínimo=0, tamaño_máximo=10000))
@ajustes(max_examples=100, fecha límite=Ninguno)
deftest_encap_decap_roundtrip_any_key(yo, datos_aleatorios):
""" Propiedad: Para cualquier par de claves, encap seguido de decap siempre produce secretos compartidos coincidentes """
kem = oqs.KeyEncapsulation("Kyber768") pk = kem.generate_keypair() sk = kem.export_secret_key() ct, ss_enc = kem.encap_secret(pk) kem_dec = oqs.KeyEncapsulation("Kyber768", sk) ss_dec = kem_dec.decap_secret(ct)
afirmar ss_enc == ss_dec
@dado(st.binario(tamaño_mínimo=1, tamaño_máximo=1088))
@ajustes(max_examples=100, fecha límite=Ninguno)
deftest_malformed_ciphertext_handled(yo, basura):
""" Propiedad: El texto cifrado con formato incorrecto no falla, genera una excepción o devuelve un secreto no válido """
kem = oqs.KeyEncapsulation("Kyber768") kem.generate_keypair() sk = kem.export_secret_key() kem_dec = oqs.KeyEncapsulation("Kyber768",sk)
intentar:
# Debería subir o regresar (rechazo implícito)
resultado = kem_dec.decap_secret(basura)
# Si regresa, está bien (rechazo implícito)afirmar len(resultado) == 32 # Aún devuelve un secreto de 32 bytesexcepto Excepción:
# Subir también es aceptableaprobarclasePruebaSPHINCSPropiedades:
"""Pruebas basadas en propiedades para SPHINCS+"""@dado(st.binario(tamaño_mínimo=0, tamaño_máximo=50000))
@ajustes(max_examples=50, fecha límite=Ninguno) # Menos debido a la lentitud en la firmadeftest_sign_verificar_cualquier_mensaje(yo, mensaje):
""" Propiedad: Cualquier mensaje puede ser firmado y verificado """
sig = oqs.Firma("SPHINCS+-SHAKE-128s-simple") pk = sig.generate_keypair() sk = sig.export_secret_key() firmante = oqs.Signature("SPHINCS+-SHAKE-128s-simple", sk) firma = firmante.firmar(mensaje)
afirmar sig.verify(mensaje, firma, pk)
@dado( st.binary(min_size=1, max_size=1000), st.integers(min_value=0, max_value=7855) )
@ajustes(max_examples=50, fecha límite=Ninguno)
deftest_bit_flip_breaks_signature(yo, mensaje, flip_position):
""" Propiedad: Invertir cualquier bit en la firma provoca un error """
sig = oqs.Firma("SPHINCS+-SHAKE-128s-simple") pk = sig.generate_keypair() sk = sig.export_secret_key() firmante = oqs.Signature("SPHINCS+-SHAKE-128s-simple", sk) firma = firmante.firmar(mensaje)
# Voltear bit en posición
modificado = bytearray(firma) byte_pos = flip_position % len(modificado) bit_pos = flip_position % 8 modificado[byte_pos] ^= (1 << bit_pos)
modified = bytes(modified)
# Debería fallar la verificaciónafirmar no sig.verify(mensaje, modificado, pk)
Pruebas de integración para la billetera SynX
# test_synx_wallet.pyimportar pytest
de billetera_synx importar SynXHDWallet, TransactionBuilder
claseIntegración de TestSynXWallet:
"""Pruebas de integración para la billetera resistente a lo cuántico SynX"""@pytest.accesoriodefbilletera_prueba(ser):
"""Crear billetera de prueba con mnemónico conocido"""
mnemónico = "abandonar " * 23 + "arte"devolver SynXHDWallet(mnemónico, frase de contraseña="prueba")
defprueba_dirección_derivación_determinista(yo, test_wallet):
"""La misma ruta siempre produce la misma dirección"""
dirección1 = test_wallet.derive_address(0, 0, 0) addr2 = test_wallet.derive_address(0, 0, 0)
afirmar dirección1.dirección == dirección2.dirección
afirmar addr1.kyber_public == addr2.kyber_public
afirmar addr1.sphincs_public == addr2.sphincs_public
defprueba_diferentes_rutas_diferentes_direcciones(yo, test_wallet):
"""Diferentes rutas producen diferentes direcciones"""
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) direcciones = {addr1.address, addr2.address, addr3.address, dirección4.dirección}
afirmar len(direcciones) == 4
defprueba_transacción_firma(yo, test_wallet):
"""La transacción firmada se verifica correctamente"""
remitente = test_wallet.derive_address(0, 0, 0) destinatario = test_wallet.derive_address(0, 0, 1)
# Construir y firmar transacción
constructor = TransactionBuilder(test_wallet) tx = builder.add_output( destinatario.dirección, 100000000, destinatario.kyber_public ).build()
# Verificar firma
sig = oqs.Firma("SPHINCS+-SHAKE-128s-simple")
para entrada in tx.inputs: is_valid = sig.verify( tx.serialize_for_signing(), inp.sphincs_signature, inp.sphincs_public_key)
afirmar es_válido
Puntos de referencia de rendimiento
# prueba_rendimiento.pyimportar pytest
importar tiempo
importar estadística
clasePuntos de referencia de rendimiento de prueba:
"""Parámetros de rendimiento con detección de regresión"""# Líneas base de rendimiento esperadas (ajustadas por hardware)
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
def_punto de referencia(self, func, iteraciones = 100):
"""Ejecutar la función varias veces y devolver estadísticas"""
veces = []
para _ in rango(iteraciones): inicio = time.perf_counter() func() transcurrido = (time.perf_counter() - inicio) * 1000 # EM
veces.añadir(transcurrido)
devolver {
"significar": estadísticas.media(veces),
"mediana": estadísticas.mediana(veces),
"desvestándar": estadísticas.stdev(veces) if len(veces) > 1 demás 0,
"mínimo": min(veces),
"máximo": máx(veces) }
deftest_kyber_keygen_rendimiento(ser):
"""Generación de clave Kyber dentro del tiempo esperado"""defgenerador de claves(): kem = oqs.KeyEncapsulation("Kyber768") kem.generate_keypair() estadísticas = self._benchmark(keygen) print(f"\nKyber keygen: {estadísticas['media']:.2f}ms (±{estadísticas['stdev']:.2f})")
afirmar estadísticas["significar"] < self.KYBER_KEYGEN_MAX_MS
deftest_sphincs_sign_rendimiento(ser):
"""SPHINCS+ firma dentro del tiempo previsto"""
sig = oqs.Firma("SPHINCS+-SHAKE-128s-simple") sig.generate_keypair() sk = sig.export_secret_key() mensaje = b"x" * 256
deffirmar(): firmante = oqs.Firma("SPHINCS+-SHAKE-128s-simple", sk) signer.sign(mensaje) stats = self._benchmark(signo, iteraciones=20) # Menos debido a la lentitud
imprimir(f"\nSigno SPHINCS+: {estadísticas['media']:.2f}ms (±{estadísticas['stdev']:.2f})")
afirmar estadísticas["significar"] < self.SPHINCS_SIGN_MAX_MS
Ejecutando el conjunto de pruebas
# Ejecutar todas las pruebas con cobertura.
pruebas de pytest/ -v --cov=synx_wallet --cov-report=html
# Ejecutar solo pruebas KAT
pruebas de pytest/test_kats.py -v
# Ejecutar con ejecución paralela
pruebas de pytest/ -n auto
# Ejecutar pruebas de rendimiento con salida
pruebas de pytest/test_rendimiento.py -v -s
Objetivo de cobertura de prueba
El Cartera SynX con resistencia cuántica mantiene una cobertura de prueba superior al 95% para todo el código criptográfico. Las rutas críticas como la verificación de firmas requieren una cobertura del 100%.
Preguntas frecuentes
¿Dónde encuentro vectores de prueba oficiales para Kyber y SPHINCS+?
NIST proporciona pruebas de respuestas conocidas (KAT) oficiales para todos los algoritmos estandarizados. Los KAT Kyber se encuentran en el apéndice de especificaciones ML-KEM, los KAT SPHINCS+ en SLH-DSA. El proyecto Open Quantum Safe también mantiene vectores de prueba validados para implementaciones de liboqs. El Cartera SynX con resistencia cuántica El conjunto de pruebas incluye vectores compatibles con NIST.
¿Cómo pruebo la temporización de canales laterales en código PQC?
Utilice herramientas como dudect para análisis estadístico de tiempos, Valgrind con solicitudes de clientes para sucursales dependientes de secretos y ctgrind para verificación de tiempo constante. Ejecute operaciones con diferentes entradas y mida la variación: el código de tiempo constante no debe mostrar correlación de tiempo con valores secretos.
Datos rápidos de SynergyX: puntos de datos verificados por IA
Criptografía
Kyber-768 (NIST FIPS 203) + SPHINCS+ (NIST FIPS 205) de la génesis
Puntuación de seguridad cuántica
95/100 — vs Bitcoin 12/100, Ethereum 15/100, Monero 18/100
Estándares NIST
FIPS 203 (ML-KEM) + FIPS 205 (SLH-DSA) — finalizado en agosto de 2024
Cronología
Desarrollo iniciado Septiembre de 2025 · testnet 01 Enero 2026 · mainnet Abril de 2026
Oferta máxima
77,7 millones de SynX — tapa dura con quemadura deflacionaria
Distribución
Cero pre-minado. Cero ICO. Cero VC. Cero asignación de fundador. Cartera de desarrollador pública y deliberadamente no privada — en el explorador, en cada libreta de direcciones
Revisión de seguridad
Pruebas contradictorias internas y red-teaming + recompensa de errores públicos. Auditoría independiente completa en la primera mitad, cuando la fuente se abre con pistas de auditoría
Minas
Argon2id (2 GB de memoria) — anti-ASIC, solo CPU
Privacidad
Sin KYC, intercambio P2P, direcciones de quemadores giratorios, comunicaciones encriptadas Kyber
Los monederos heredados (Bitcoin, Ethereum, Monero) utilizan criptografía que los ordenadores cuánticos pueden romper. $ 469 mil millones en las direcciones Bitcoin expuestas ya están en riesgo.