Théorème de non-clonage & Téléportation quantique
Non-clonage quantique et téléportation : pourquoi copier un état est impossible et comment le transférer — avec du code Q# et Qiskit.
Théorème de non-clonage
L’idée centrale
Il est physiquement impossible de copier un état quantique inconnu. Il n’existe aucune opération universelle qui prend un qubit dans un état arbitraire |ψ⟩ et produit deux qubits dans le même état |ψ⟩|ψ⟩.
Analogie : imagine un post-it sur lequel quelqu’un a écrit un message à l’encre invisible. Tu ne sais pas ce qui est écrit. Le théorème de non-clonage dit que tu ne peux pas photocopier ce post-it pour obtenir deux exemplaires identiques du message caché — toute tentative de lecture modifie le message original (c’est la mesure). C’est très différent du monde classique où File.Copy() fonctionne toujours.
Pourquoi c’est impossible ?
L’argument repose sur la linéarité de la mécanique quantique. Les opérations quantiques (portes) sont des transformations linéaires. Si une machine pouvait cloner |0⟩ et |1⟩ séparément, alors par linéarité, appliquée à une superposition α|0⟩ + β|1⟩, elle produirait quelque chose de différent de la copie souhaitée. La machine ne peut pas “deviner” les amplitudes α et β sans mesurer, et mesurer détruit la superposition.
En résumé : cloner = mesurer sans mesurer. C’est contradictoire. On peut copier des bits classiques (0 ou 1 connus), mais pas un qubit dans un état de superposition inconnu.
Conséquences pour le développeur
- Pas de copie défensive : en C#, on fait souvent
var backup = myObject.Clone()avant une opération risquée. En quantique, c’est interdit. Si tu passes un qubit à une fonction, l’état original est consommé ou modifié. - Pas de débogage par inspection : tu ne peux pas “print” l’état d’un qubit sans le mesurer (et donc le perturber). Les simulateurs contournent ça avec
DumpMachine()(Q#) ouStatevector(Qiskit), mais sur un vrai ordinateur quantique, c’est impossible. - Sécurité quantique : le non-clonage est la base de la cryptographie quantique (QKD). Un espion ne peut pas copier les qubits échangés sans se faire détecter.
| Concept | Classique | Quantique |
|---|---|---|
| Copier un état connu | Toujours possible | Possible (ex: copier |0⟩ connu) |
| Copier un état inconnu | Toujours possible | Interdit (non-clonage) |
| Inspecter sans modifier | Lecture non destructive | Mesure = effondrement |
| Sauvegarde / rollback | Snapshots, copies | Pas de snapshot d’un qubit |
En code : ce qui marche et ce qui ne marche pas
En Q#, on ne peut pas écrire une opération Clone universelle. Mais on peut préparer un deuxième qubit dans le même état si on connaît la procédure de préparation :
// Q# — Ceci ne clone PAS un état inconnu !
// On prépare deux qubits dans le même état CONNU
operation PrepareTwoHadamards() : (Result, Result) {
use (q1, q2) = (Qubit(), Qubit());
H(q1); // q1 → |+⟩
H(q2); // q2 → |+⟩ (même recette, pas un clonage)
let r1 = M(q1);
let r2 = M(q2);
return (r1, r2); // Résultats indépendants !
}
// ⚠️ Impossible d'écrire :
// operation Clone(source : Qubit, target : Qubit) : Unit {
// // Aucune suite de portes ne peut faire ça pour tout |ψ⟩
// }
# Qiskit — Tentative naïve de "clonage" avec CNOT
from qiskit import QuantumCircuit
from qiskit.quantum_info import Statevector
qc = QuantumCircuit(2)
qc.h(0) # q0 → |+⟩ = (|0⟩+|1⟩)/√2
qc.cx(0, 1) # CNOT : on espère "copier" q0 dans q1
# Résultat : état intriqué (|00⟩+|11⟩)/√2, PAS |+⟩|+⟩
sv = Statevector.from_instruction(qc)
print(sv) # [0.707+0j, 0+0j, 0+0j, 0.707+0j]
# → C'est un état de Bell, pas deux copies de |+⟩ !
⚠️ Piège fréquent : CNOT ne clone pas un qubit. Si le qubit source est en superposition, CNOT crée de l’intrication, pas une copie. CNOT ne “copie” que les états de base
|0⟩et|1⟩(états classiques). C’est exactement la subtilité du théorème de non-clonage.
Téléportation quantique
L’idée centrale
La téléportation quantique transfère l’état d’un qubit vers un autre qubit distant, sans violer le non-clonage. L’état original est détruit au passage — c’est un transfert, pas une copie. Rien ne voyage plus vite que la lumière : 2 bits classiques doivent être transmis pour compléter le protocole.
Analogie : imagine que tu as un origami unique (l’état quantique). Tu ne peux pas le photocopier. Mais tu peux le “faxer” : tu le déplies complètement (mesure → destruction de l’original), tu envoies les instructions de pliage par courrier classique (2 bits), et ton correspondant reconstruit l’origami identique de son côté grâce à du papier spécial qu’il avait préparé en avance (la paire de Bell partagée).
Les ingrédients
- 3 qubits : le qubit à téléporter (appelé |ψ⟩, détenu par Alice), et une paire de Bell partagée entre Alice et Bob (un qubit chacun).
- Mesure par Alice : Alice applique CNOT puis H sur ses deux qubits, puis les mesure. Cela donne 2 bits classiques (00, 01, 10, ou 11).
- Correction par Bob : Bob reçoit les 2 bits classiques et applique des corrections (portes X et/ou Z) sur son qubit. Après correction, le qubit de Bob est dans l’état |ψ⟩ original.
Le circuit étape par étape
Les qubits sont : q0 = état à téléporter, q1 = moitié Alice de la paire de Bell, q2 = moitié Bob.
| Étape | Action | Qui ? |
|---|---|---|
| 1. Partage de la paire | H + CNOT → état de Bell | Préparation commune |
| 2. Circuit d’Alice | CNOT(ψ, a) puis H(ψ) | Alice |
| 3. Mesure | Mesurer ψ et a → 2 bits | Alice |
| 4. Envoi classique | Transmettre m0, m1 | Alice → Bob |
| 5. Corrections | X si m1=1, Z si m0=1 | Bob |
Pourquoi ça ne viole pas le non-clonage : l’état original |ψ⟩ est détruit par la mesure d’Alice. À la fin, seul le qubit de Bob porte l’état. Il n’y a jamais eu deux copies simultanées.
Pourquoi ça ne va pas plus vite que la lumière : sans les 2 bits classiques envoyés par Alice (canal classique, limité par la vitesse de la lumière), le qubit de Bob est dans un état aléatoire inutilisable. Les corrections sont indispensables.
Implémentation Q#
// Q# — Téléportation quantique complète
operation Teleport(source : Qubit, target : Qubit) : Unit {
use auxiliary = Qubit();
// 1. Préparer la paire de Bell (auxiliary ↔ target)
H(auxiliary);
CNOT(auxiliary, target);
// 2. Circuit de téléportation côté Alice
CNOT(source, auxiliary);
H(source);
// 3. Mesurer les qubits d'Alice
let m0 = M(source); // bit classique m0
let m1 = M(auxiliary); // bit classique m1
// 4. Corrections de Bob
if m1 == One { X(target); }
if m0 == One { Z(target); }
Reset(source);
Reset(auxiliary);
// target contient maintenant l'état original de source !
}
Implémentation Qiskit
# Qiskit — Téléportation quantique
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
qr = QuantumRegister(3, 'q') # q0=source, q1=alice, q2=bob
cr = ClassicalRegister(2, 'c') # 2 bits classiques
qc = QuantumCircuit(qr, cr)
# Préparer un état à téléporter (exemple : |+⟩)
qc.h(qr[0])
qc.barrier()
# 1. Paire de Bell entre q1 (Alice) et q2 (Bob)
qc.h(qr[1])
qc.cx(qr[1], qr[2])
qc.barrier()
# 2. Circuit d'Alice
qc.cx(qr[0], qr[1])
qc.h(qr[0])
qc.barrier()
# 3. Mesure d'Alice
qc.measure(qr[0], cr[0]) # m0
qc.measure(qr[1], cr[1]) # m1
# 4. Corrections conditionnelles de Bob
qc.x(qr[2]).c_if(cr[1], 1) # X si m1=1
qc.z(qr[2]).c_if(cr[0], 1) # Z si m0=1
# q2 contient maintenant l'état initial de q0 !
⚠️ Piège fréquent : dans Qiskit, l’ordre des bits classiques dans
c_ifpeut surprendre. Vérifie bien quel bit classique correspond à quelle mesure. Aussi,c_ifest une API « legacy » — dans les versions récentes de Qiskit, on utiliseif_testou le moduleqiskit.circuit.classical, maisc_ifreste fonctionnel et plus lisible pour l’apprentissage.