""" Tests pour la cryptographie post-quantique hybride. Valide les standards NIST FIPS 203/204/205. """ import pytest from src.crypto.pqc_hybrid import PostQuantumCryptography class TestPostQuantumCryptography: """Tests de la cryptographie post-quantique hybride""" def test_hybrid_keypair_generation(self): """Tester la génération de paires de clés hybrides""" keypair = PostQuantumCryptography.generate_hybrid_keypair() # Vérifier présence de toutes les clés assert "rsa_public_key" in keypair assert "rsa_private_key" in keypair assert "dilithium_public" in keypair assert "dilithium_secret" in keypair assert "kyber_public" in keypair assert "kyber_secret" in keypair assert "elgamal_public" in keypair assert "elgamal_secret" in keypair # Vérifier formats assert b"-----BEGIN PUBLIC KEY-----" in keypair["rsa_public_key"] assert b"-----BEGIN PRIVATE KEY-----" in keypair["rsa_private_key"] assert len(keypair["dilithium_public"]) > 0 assert len(keypair["kyber_public"]) > 0 def test_hybrid_sign_and_verify(self): """Tester les signatures hybrides RSA-PSS + Dilithium""" # Générer clés keypair = PostQuantumCryptography.generate_hybrid_keypair() # Message à signer message = b"Vote securise avec cryptographie post-quantique" # Signer signatures = PostQuantumCryptography.hybrid_sign( message, keypair["rsa_private_key"], keypair["dilithium_secret"] ) # Vérifier les signatures assert "rsa_signature" in signatures assert "dilithium_signature" in signatures assert len(signatures["rsa_signature"]) > 0 assert len(signatures["dilithium_signature"]) > 0 # Vérifier les deux signatures ensemble is_valid = PostQuantumCryptography.hybrid_verify( message, signatures, keypair["rsa_public_key"], keypair["dilithium_public"] ) assert is_valid def test_hybrid_sign_invalid_message(self): """Tester que les signatures invalides sont rejetées""" keypair = PostQuantumCryptography.generate_hybrid_keypair() message = b"Message original" signatures = PostQuantumCryptography.hybrid_sign( message, keypair["rsa_private_key"], keypair["dilithium_secret"] ) # Vérifier avec un message différent (doit échouer) modified_message = b"Message modifie" is_valid = PostQuantumCryptography.hybrid_verify( modified_message, signatures, keypair["rsa_public_key"], keypair["dilithium_public"] ) assert not is_valid def test_hybrid_encapsulate_decapsulate(self): """Tester l'encapsulation/décapsulation hybride""" keypair = PostQuantumCryptography.generate_hybrid_keypair() # Encapsuler un secret result = PostQuantumCryptography.hybrid_encapsulate( keypair["kyber_public"], keypair["elgamal_public"] ) assert "kyber_ciphertext" in result assert "elgamal_ciphertext" in result assert "combined_secret" in result assert len(result["combined_secret"]) == 32 # 256-bit # Décapsuler le secret decapsulated_secret = PostQuantumCryptography.hybrid_decapsulate( { "kyber_ciphertext": result["kyber_ciphertext"], "elgamal_ciphertext": result["elgamal_ciphertext"] }, keypair["kyber_secret"], keypair["elgamal_secret"] ) # Les secrets doivent correspondre assert decapsulated_secret == result["combined_secret"] def test_algorithm_info(self): """Tester que les infos d'algorithmes sont correctes""" info = PostQuantumCryptography.get_algorithm_info() assert "signatures" in info assert "encryption" in info assert "hashing" in info assert "ML-DSA-65" in info["signatures"] assert "ML-KEM-768" in info["encryption"] assert "SHA-256" in info["hashing"] assert "FIPS 203" in info["encryption_status"] assert "FIPS 204" in info["signatures_status"] def test_multiple_signatures_different_messages(self): """Tester plusieurs signatures sur des messages différents""" keypair = PostQuantumCryptography.generate_hybrid_keypair() messages = [ b"Vote pour Alice", b"Vote pour Bob", b"Vote pour Charlie", ] signatures_list = [] for msg in messages: sig = PostQuantumCryptography.hybrid_sign( msg, keypair["rsa_private_key"], keypair["dilithium_secret"] ) signatures_list.append(sig) # Vérifier chaque signature avec son message for msg, sig in zip(messages, signatures_list): is_valid = PostQuantumCryptography.hybrid_verify( msg, sig, keypair["rsa_public_key"], keypair["dilithium_public"] ) assert is_valid # Vérifier que les signatures ne sont pas valides avec d'autres messages for i, (msg, sig) in enumerate(zip(messages, signatures_list)): for j, other_msg in enumerate(messages): if i != j: is_valid = PostQuantumCryptography.hybrid_verify( other_msg, sig, keypair["rsa_public_key"], keypair["dilithium_public"] ) assert not is_valid def test_hybrid_encapsulate_multiple_times(self): """Tester que chaque encapsulation produit des ciphertexts différents""" keypair = PostQuantumCryptography.generate_hybrid_keypair() result1 = PostQuantumCryptography.hybrid_encapsulate( keypair["kyber_public"], keypair["elgamal_public"] ) result2 = PostQuantumCryptography.hybrid_encapsulate( keypair["kyber_public"], keypair["elgamal_public"] ) # Les ciphertexts doivent être différents (randomisés) assert result1["kyber_ciphertext"] != result2["kyber_ciphertext"] assert result1["combined_secret"] != result2["combined_secret"] # Mais les deux doivent se décapsuler correctement dec1 = PostQuantumCryptography.hybrid_decapsulate( { "kyber_ciphertext": result1["kyber_ciphertext"], "elgamal_ciphertext": result1["elgamal_ciphertext"] }, keypair["kyber_secret"], keypair["elgamal_secret"] ) dec2 = PostQuantumCryptography.hybrid_decapsulate( { "kyber_ciphertext": result2["kyber_ciphertext"], "elgamal_ciphertext": result2["elgamal_ciphertext"] }, keypair["kyber_secret"], keypair["elgamal_secret"] ) assert dec1 == result1["combined_secret"] assert dec2 == result2["combined_secret"]