Exercices - Chapitre 4: Cryptographie quantique
Mettez en pratique vos connaissances sur les principes de la cryptographie quantique
Exercice 4.1 : Simulation du protocole BB84
Le protocole BB84, développé par Charles Bennett et Gilles Brassard en 1984, est le premier protocole de distribution quantique de clés. Dans cet exercice, vous allez simuler son fonctionnement.
Partie A : Mise en œuvre du protocole
Complétez le code Python suivant qui simule le protocole BB84 :
import random
import numpy as np
def bb84_simulation(n_qubits, error_rate=0, eavesdropping=False):
"""
Simule le protocole BB84 pour la distribution quantique de clés.
Args:
n_qubits (int): Nombre de qubits à transmettre
error_rate (float): Taux d'erreur du canal (0-1)
eavesdropping (bool): Si True, simule la présence d'un espion (Eve)
Returns:
tuple: (clé secrète partagée, taux d'erreur estimé, taille de la clé finale)
"""
# Bases possibles: 0 pour base rectiligne (+), 1 pour base diagonale (×)
# États possibles: 0 et 1 dans la base choisie
# 1. Alice prépare des qubits aléatoires dans des bases aléatoires
alice_bits = [random.randint(0, 1) for _ in range(n_qubits)]
alice_bases = [random.randint(0, 1) for _ in range(n_qubits)]
# 2. Alice envoie les qubits à Bob
transmitted_qubits = alice_bits.copy()
# 3. Simulation de l'espionnage par Eve (si activé)
if eavesdropping:
eve_bases = [random.randint(0, 1) for _ in range(n_qubits)]
for i in range(n_qubits):
# Eve mesure dans une base aléatoire
if eve_bases[i] != alice_bases[i]:
# Si Eve utilise la mauvaise base, la mesure perturbe l'état
transmitted_qubits[i] = random.randint(0, 1)
# 4. Simulation d'erreurs de transmission
for i in range(n_qubits):
if random.random() < error_rate:
transmitted_qubits[i] = 1 - transmitted_qubits[i] # Inversion du bit
# 5. Bob choisit des bases aléatoires pour mesurer
bob_bases = [random.randint(0, 1) for _ in range(n_qubits)]
# 6. Bob mesure les qubits reçus
bob_measurements = []
for i in range(n_qubits):
if bob_bases[i] == alice_bases[i]:
# Si Bob utilise la même base qu'Alice, il obtient le même résultat
# (sauf en cas d'erreur de transmission ou d'espionnage)
bob_measurements.append(transmitted_qubits[i])
else:
# Si Bob utilise une base différente, il obtient un résultat aléatoire
bob_measurements.append(random.randint(0, 1))
# 7. Alice et Bob échangent leurs bases (canal public)
matching_bases_indices = [i for i in range(n_qubits) if alice_bases[i] == bob_bases[i]]
# 8. Alice et Bob gardent uniquement les bits où ils ont utilisé la même base
alice_key = [alice_bits[i] for i in matching_bases_indices]
bob_key = [bob_measurements[i] for i in matching_bases_indices]
# 9. Estimation du taux d'erreur (QBER)
# Dans une implémentation réelle, ils sacrifieraient une partie de la clé pour cela
errors = sum(a != b for a, b in zip(alice_key, bob_key))
error_estimation = errors / len(alice_key) if alice_key else 0
# 10. En pratique, ils effectueraient ensuite:
# - Réconciliation d'erreurs (correction d'erreurs)
# - Amplification de confidentialité (réduction des informations d'Eve)
# Mais pour cette simulation, nous simplifions en supposant ces étapes parfaites
return alice_key, error_estimation, len(alice_key)
# Test du protocole sans espionnage
key, error_rate, key_length = bb84_simulation(1000)
print(f"Sans espionnage:")
print(f"Clé d'Alice (premiers 20 bits): {key[:20]}")
print(f"Longueur de la clé: {key_length} bits")
print(f"Taux d'erreur estimé: {error_rate:.2%}")
# Test du protocole avec espionnage
key, error_rate, key_length = bb84_simulation(1000, eavesdropping=True)
print(f"\nAvec espionnage:")
print(f"Clé d'Alice (premiers 20 bits): {key[:20]}")
print(f"Longueur de la clé: {key_length} bits")
print(f"Taux d'erreur estimé: {error_rate:.2%}")
Partie B : Analyse de sécurité
En exécutant le code ci-dessus plusieurs fois, analysez comment le taux d'erreur est affecté par la présence d'un espion. Expliquez pourquoi et comment Alice et Bob peuvent détecter la présence d'Eve.
Partie C : Questions théoriques
Répondez aux questions suivantes :
- Pourquoi est-il impossible pour Eve de copier parfaitement un qubit sans le perturber ? Quel principe physique garantit cette sécurité ?
- Quelle est la différence fondamentale entre la sécurité du protocole BB84 et celle des cryptosystèmes classiques comme RSA ?
- Quelles sont les limitations pratiques qui rendent difficile l'implémentation réelle des systèmes QKD sur de longues distances ?
Exercice 4.2 : Impact de l'algorithme de Shor
L'algorithme de Shor représente une menace majeure pour la cryptographie à clé publique classique. Cet exercice vous aidera à comprendre son fonctionnement et ses implications.
Partie A : Analyse de l'algorithme
L'algorithme de Shor permet de factoriser efficacement de grands nombres sur un ordinateur quantique. Expliquez brièvement :
- Pourquoi la factorisation rapide de grands nombres est problématique pour RSA.
- Quels autres systèmes cryptographiques seraient menacés par l'algorithme de Shor et pourquoi.
- Comment l'algorithme de Shor utilise la transformée de Fourier quantique pour trouver la période d'une fonction.
Partie B : Évaluation de la menace
On considère des clés RSA de différentes tailles : 1024 bits, 2048 bits et 4096 bits.
- Combien de qubits logiques seraient théoriquement nécessaires pour casser chacune de ces clés avec l'algorithme de Shor ?
- Quel est l'état actuel du développement des ordinateurs quantiques en termes de nombre de qubits et de taux d'erreur ?
- Dans combien de temps estimez-vous que les cryptosystèmes RSA actuels pourraient être compromis par des ordinateurs quantiques ? Justifiez votre réponse.
Partie C : Étude de cas
Vous êtes responsable de la sécurité des données d'une entreprise qui doit être protégée pendant au moins 25 ans. Proposez une stratégie détaillée pour faire face à la menace quantique, en précisant :
- Quels algorithmes et quelles tailles de clés utiliser à court terme
- Quand et comment planifier la transition vers la cryptographie post-quantique
- Comment gérer la rétrocompatibilité pendant la période de transition
Exercice 4.3 : Cryptographie post-quantique
La cryptographie post-quantique développe des algorithmes résistants aux attaques quantiques. Cet exercice vous permettra d'explorer ce domaine émergent.
Partie A : Familles d'algorithmes
Pour chacune des familles d'algorithmes post-quantiques suivantes, décrivez brièvement le problème mathématique sous-jacent et évaluez leurs avantages et inconvénients :
- Cryptographie basée sur les réseaux (ex: CRYSTALS-Kyber)
- Cryptographie basée sur les codes (ex: Classic McEliece)
- Cryptographie multivariate (ex: Rainbow)
- Cryptographie basée sur les isogénies (ex: SIKE)
- Cryptographie basée sur les fonctions de hachage (ex: SPHINCS+)
Partie B : Analyse comparative
Comparez les algorithmes post-quantiques sélectionnés par le NIST (National Institute of Standards and Technology) avec RSA et les courbes elliptiques en termes de :
- Taille des clés et des signatures/chiffrements
- Performance (vitesse d'exécution)
- Maturité et confiance dans la sécurité
- Facilité d'implémentation et résistance aux attaques par canaux auxiliaires
Partie C : Implémentation expérimentale
On vous fournit le code Python suivant qui utilise la bibliothèque PyPQC pour expérimenter avec CRYSTALS-Kyber. Analysez ce code, expliquez son fonctionnement et répondez aux questions :
# Note: Ce code est conceptuel, PyPQC n'est pas une bibliothèque réelle
# En pratique, on utiliserait liboqs, PQClean ou des bibliothèques similaires
from pypqc import kyber
import time
import os
def benchmark_kyber():
# Tester les différents niveaux de sécurité de Kyber
security_levels = [1, 3, 5] # Correspond à Kyber512, Kyber768, Kyber1024
results = {}
for level in security_levels:
print(f"Testing Kyber at security level {level}")
start_time = time.time()
# Générer une paire de clés
key_gen_start = time.time()
public_key, secret_key = kyber.keygen(level)
key_gen_time = time.time() - key_gen_start
# Message à chiffrer
message = os.urandom(32) # 256 bits
# Chiffrer le message
encrypt_start = time.time()
ciphertext = kyber.encrypt(public_key, message, level)
encrypt_time = time.time() - encrypt_start
# Déchiffrer le message
decrypt_start = time.time()
decrypted = kyber.decrypt(secret_key, ciphertext, level)
decrypt_time = time.time() - decrypt_start
# Vérifier que le déchiffrement fonctionne
assert message == decrypted, "Decryption failed!"
total_time = time.time() - start_time
# Collecter les résultats
results[level] = {
'public_key_size': len(public_key),
'secret_key_size': len(secret_key),
'ciphertext_size': len(ciphertext),
'key_gen_time': key_gen_time,
'encrypt_time': encrypt_time,
'decrypt_time': decrypt_time,
'total_time': total_time
}
# Afficher les résultats
print("\nPerformance Comparison:")
print("-" * 80)
print(f"{'Security Level':<15} {'PK Size':<10} {'SK Size':<10} {'CT Size':<10} {'KeyGen (ms)':<12} {'Encrypt (ms)':<12} {'Decrypt (ms)':<12}")
print("-" * 80)
for level, data in results.items():
print(f"Kyber-{512 * (2 if level == 5 else level)}".ljust(15), end="")
print(f"{data['public_key_size']:<10}", end="")
print(f"{data['secret_key_size']:<10}", end="")
print(f"{data['ciphertext_size']:<10}", end="")
print(f"{data['key_gen_time']*1000:<12.2f}", end="")
print(f"{data['encrypt_time']*1000:<12.2f}", end="")
print(f"{data['decrypt_time']*1000:<12.2f}")
# Exécuter le benchmark
benchmark_kyber()
Questions :
- Quelles sont les différences de taille et de performance entre les différents niveaux de sécurité de Kyber ?
- Quels seraient les défis d'intégration de Kyber dans des applications existantes comme TLS ?
- Comment pourriez-vous modifier ce code pour implémenter une approche hybride combinant Kyber avec un échange de clés classique comme ECDH ?
Exercices du chapitre 4
Ressources complémentaires
- NIST Post-Quantum Cryptography
- Protocole BB84 (Wikipedia)
- CRYSTALS-Kyber
- "Post-Quantum Cryptography" de D. J. Bernstein et al.
Conseils de réussite
Pour l'exercice 4.1, essayez de tracer manuellement l'exécution du protocole BB84 avec un petit nombre de qubits pour mieux comprendre son fonctionnement.
Pour l'exercice 4.3, consultez la documentation du NIST sur les candidats post-quantiques pour approfondir votre compréhension des différentes approches.