Expert Chapitre 63-64 / 33

Qiskit en profondeur & Cryptographie post-quantique

Maîtriser la transpilation, les primitives Sampler/Estimator de Qiskit Runtime v2, et comprendre les standards NIST de cryptographie post-quantique — sans prérequis mathématiques, avec du code Qiskit et C#.

Qiskit en profondeur

Transpilation : du circuit logique au circuit physique

Analogie développeur : la transpilation est à un circuit quantique ce qu’un compilateur C# est à votre code LINQ — elle traduit du haut niveau (portes arbitraires, connectivité totale) en instructions natives de la machine cible (portes physiques, connectivité limitée).

La transpilation se décompose en passes successives :

  • Décomposition de portes — chaque porte logique (H, T, SWAP…) est traduite en combinaisons de basis gates du backend.
  • Routage des qubits — insertion de portes SWAP pour respecter la connectivité physique du processeur.
  • Optimisation — réduction du nombre de portes et de la profondeur du circuit.
  • Mise en correspondance finale — vérification que tout est exprimé en basis gates.

Niveaux d’optimisation (0 à 3)

Qiskit propose 4 niveaux d’optimisation lors de la transpilation. Plus le niveau est élevé, plus le compilateur investit de temps pour réduire la profondeur du circuit et le nombre de portes 2-qubits (les plus coûteuses en fidélité).

NiveauComportementUsage typique
0Décomposition minimale, pas d’optimisationDebugging, circuits déjà optimisés
1Optimisation légère (suppression de portes identité, fusion triviale)Défaut — bon compromis vitesse/qualité
2Optimisation agressive (commutation de portes, réduction de profondeur)Circuits de taille moyenne
3Optimisation maximale (resynthèse de blocs unitaires, exploration de routages alternatifs)Production sur vrai matériel
# Transpiler un circuit avec différents niveaux
from qiskit import QuantumCircuit, transpile
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke

backend = FakeSherbrooke()  # Simulateur fidèle d'un processeur 127 qubits

qc = QuantumCircuit(3)
qc.h(0)
qc.cx(0, 1)
qc.cx(1, 2)

# Niveau 0 : rapide mais non optimisé
t0 = transpile(qc, backend=backend, optimization_level=0)
print(f"Niveau 0 : profondeur={t0.depth()}, ops={t0.count_ops()}")

# Niveau 3 : optimisation maximale
t3 = transpile(qc, backend=backend, optimization_level=3)
print(f"Niveau 3 : profondeur={t3.depth()}, ops={t3.count_ops()}")
# → Le niveau 3 produit généralement un circuit moins profond

Basis gates et portes natives

Chaque processeur quantique ne supporte qu’un jeu limité de portes physiques appelées basis gates. Par exemple, les processeurs IBM Eagle/Heron utilisent typiquement {ECR, ID, RZ, SX, X}. Toutes vos portes logiques sont décomposées en combinaisons de ces portes natives par le transpileur.

# Voir les basis gates d'un backend
print(backend.configuration().basis_gates)
# → ['ecr', 'id', 'rz', 'sx', 'x']

# La porte Hadamard (H) se décompose en : RZ(π) · SX · RZ(π)
# Le transpileur fait cette conversion automatiquement

Primitives Sampler et Estimator (Runtime v2)

Depuis Qiskit Runtime v2, on n’utilise plus directement backend.run(). Deux primitives standardisent l’interface :

PrimitiveRôleSortie
SamplerV2Échantillonne le circuit (exécution + mesure)Distribution de probabilités (comptages par bitstring)
EstimatorV2Calcule la valeur attendue ⟨O⟩ d’un observableValeur numérique + écart-type

Sampler remplace backend.run(qc) pour obtenir des comptages. Estimator est indispensable pour les algorithmes variationnels (VQE, QAOA) où l’on mesure des observables comme des hamiltoniens, sans avoir à décomposer les mesures manuellement.

# Utilisation de SamplerV2 (Qiskit Runtime v2)
from qiskit import QuantumCircuit, transpile
from qiskit_ibm_runtime import SamplerV2 as Sampler

backend = FakeSherbrooke()
sampler = Sampler(mode=backend)

qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
qc.measure_all()

# IMPORTANT : transpiler AVANT de soumettre aux primitives
transpiled = transpile(qc, backend)
job = sampler.run([transpiled], shots=4096)
result = job.result()
# result[0].data.meas → les comptages par bitstring

Piège courant : avec Qiskit Runtime v2, il faut toujours transpiler le circuit avant de le passer à une primitive. Les primitives n’effectuent plus la transpilation automatiquement — contrairement à l’ancien backend.run(). Oublier cette étape provoque une erreur ou un résultat incohérent.


Cryptographie post-quantique

Ce que menace l’ordinateur quantique

L’algorithme de Shor casse en temps polynomial les problèmes de factorisation (RSA) et de logarithme discret (ECC, Diffie-Hellman). Un ordinateur quantique suffisamment puissant rendrait obsolètes la majorité des systèmes à clé publique actuels.

L’algorithme de Grover offre une accélération quadratique sur la recherche exhaustive. Il ne « casse » pas AES, mais divise par deux la sécurité en bits : AES-128 passe de 2^128 à ~2^64 opérations quantiques. Parade simple : doubler la taille de clé (AES-256 reste sûr).

Algorithme classiqueMenace quantiqueImpact
RSA (2048, 4096)ShorCassé complètement
ECDSA / ECDHShorCassé complètement
Diffie-HellmanShorCassé complètement
AES-128GroverSécurité réduite à ~64 bits — insuffisant
AES-256GroverSécurité réduite à ~128 bits — toujours sûr
SHA-256GroverRésistance préimage : ~128 bits — acceptable

Les standards NIST de cryptographie post-quantique

Le NIST a finalisé en 2024 les premiers standards conçus pour résister aux attaques quantiques. La plupart reposent sur les réseaux euclidiens (lattice-based) :

Standard NISTAncien nomTypeProblème sous-jacent
ML-KEM (FIPS 203)CRYSTALS-KyberÉchange de clés (KEM)Module Learning With Errors (MLWE)
ML-DSA (FIPS 204)CRYSTALS-DilithiumSignature numériqueModule Learning With Errors (MLWE)
SLH-DSA (FIPS 205)SPHINCS+Signature numériqueFonctions de hachage (stateless)

Analogie réseaux euclidiens : imaginez un immense espace à des milliers de dimensions, rempli de points régulièrement espacés (le réseau). Trouver le point le plus proche d’une cible donnée dans cet espace est un problème que ni un ordinateur classique ni un ordinateur quantique ne sait résoudre efficacement. C’est ce qui rend ML-KEM et ML-DSA résistants.

Implications pratiques pour développeurs

# Python — échange de clés ML-KEM avec liboqs
# pip install liboqs-python
import oqs

# Alice génère une paire de clés ML-KEM-768
kem = oqs.KeyEncapsulation("ML-KEM-768")
public_key = kem.generate_keypair()

# Bob encapsule un secret partagé avec la clé publique d'Alice
ciphertext, shared_secret_bob = kem.encap_secret(public_key)

# Alice décapsule pour retrouver le même secret
shared_secret_alice = kem.decap_secret(ciphertext)

assert shared_secret_alice == shared_secret_bob
# → Les deux parties partagent un secret résistant aux attaques quantiques
// C# / .NET — signature ML-DSA avec BouncyCastle
// NuGet: BouncyCastle.Cryptography >= 2.3
using Org.BouncyCastle.Pqc.Crypto.MLDsa;
using Org.BouncyCastle.Security;

var random = new SecureRandom();
var keyGenParams = new MLDsaKeyGenerationParameters(
    random, MLDsaParameters.ML_DSA_65);
var keyGen = new MLDsaKeyPairGenerator();
keyGen.Init(keyGenParams);
var keyPair = keyGen.GenerateKeyPair();

// Signer un message
var signer = new MLDsaSigner();
signer.Init(true, keyPair.Private);
byte[] message = System.Text.Encoding.UTF8.GetBytes("Données sensibles");
byte[] signature = signer.GenerateSignature(message);

// Vérifier la signature
signer.Init(false, keyPair.Public);
bool valid = signer.VerifySignature(message, signature);
// valid == true → signature post-quantique vérifiée !

« Harvest now, decrypt later » : des attaquants peuvent intercepter et stocker dès aujourd’hui des communications chiffrées (RSA, ECC), en attendant de disposer d’un ordinateur quantique pour les déchiffrer plus tard. C’est pourquoi la migration vers la crypto post-quantique est urgente — même sans ordinateur quantique disponible actuellement.


Quiz — teste tes connaissances
Expert 7 questions Objectif : 5/7 minimum
0/7
bonnes reponses
Objectif non atteint (minimum 5/7 requis).
Remonte relire la fiche memo ci-dessus en pretant attention aux points rates, puis clique sur « Recommencer » pour retenter.