Aller au contenu principal

Distribution quantique de clés

Pour ce module Qiskit en classe, les étudiants doivent disposer d'un environnement Python fonctionnel avec les packages suivants installés :

  • qiskit v2.1.0 ou plus récent
  • qiskit-ibm-runtime v0.40.1 ou plus récent
  • qiskit-aer v0.17.0 ou plus récent
  • qiskit.visualization
  • numpy
  • pylatexenc

Pour configurer et installer les packages ci-dessus, consulte le guide Installer Qiskit. Pour exécuter des jobs sur de vrais ordinateurs quantiques, les étudiants devront créer un compte IBM Quantum® en suivant les étapes du guide Configurer ton compte IBM Cloud.

Ce module a été testé et a utilisé 5 secondes de temps QPU. Il s'agit d'une estimation uniquement. Ton utilisation réelle peut varier.

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-aer qiskit-ibm-runtime
# Uncomment and modify this line as needed to install dependencies
#!pip install 'qiskit>=2.1.0' 'qiskit-ibm-runtime>=0.40.1' 'qiskit-aer>=0.17.0' 'numpy' 'pylatexenc'

Regarde la présentation du module par Dr. Katie McCormick ci-dessous, ou clique ici pour la visionner sur YouTube.


Introduction et motivation

Il existe une infinité de façons de chiffrer et de déchiffrer des informations, et littéralement des milliers de méthodes ont été bien étudiées. Ici, nous nous limiterons à une méthode de chiffrement très ancienne et très simple, appelée « substitution simple », afin de nous concentrer sur la partie quantique de ce protocole. La partie quantique pourrait être adaptée à de nombreux autres protocoles avec relativement peu de modifications.

Substitution simple

Un chiffrement par substitution simple est un chiffrement dans lequel une lettre ou un chiffre est remplacé par un autre, de telle sorte qu'il existe une correspondance 1:1 entre les lettres et les chiffres d'un message et les lettres et les chiffres utilisés dans la séquence chiffrée. Un exemple populaire de ce type de chiffrement est le puzzle cryptoquote ou cryptogramme, dans lequel une citation ou une phrase est chiffrée par substitution simple, et le joueur doit la déchiffrer. Ces puzzles sont faciles à résoudre s'ils sont suffisamment longs. Considère l'exemple suivant :

R WVXRWVW GSZG R'W YVGGVI NZPV GSRH KIVGGB OLMT. GSZG DZB, KVLKOV DROO SZEV ZM VZHRVI GRNV HLOERMT RG. R SLKV R NZWV RG HRNKOV VMLFTS.

Les personnes qui résolvent ces puzzles à la main utilisent principalement des astuces liées à leur familiarité avec la structure de la langue du message original. Par exemple, en anglais, les seuls mots d'une lettre comme le « R » chiffré sont « a » et « I ». Les lettres doubles chiffrées dans, par exemple, « KIVGGB » ne peuvent prendre que certaines valeurs. Il y a des choses plus subtiles qui donnent des indices, comme le fait que le mot le plus courant correspondant au motif « GSZG » est « that ». Les personnes qui utilisent du code pour résoudre ces puzzles disposent de bien plus d'options, notamment en parcourant les possibilités jusqu'à ce qu'un mot anglais soit trouvé, et en mettant à jour tout en conservant ce mot. Une méthode simple mais puissante consiste à utiliser la fréquence des lettres, surtout lorsque le message est suffisamment long pour constituer un échantillon représentatif de l'anglais.

Question de vérification

Essaie de déchiffrer ce message si tu le souhaites, bien que ce ne soit pas nécessaire pour le reste du module. Clique sur le triangle ci-dessous pour voir le message.

Réponse :

I decided that I'd better make this pretty long. That way, people will have an easier time solving it. I hope I made it simple enough.

L'exemple ci-dessus est associé à une « clé », une correspondance entre les lettres chiffrées et les lettres déchiffrées. Dans ce cas, la clé est :

  • A (non utilisé, appelons-le Z)
  • B->Y
  • C (non utilisé, appelons-le X)
  • D->W
  • E->V
  • F->U
  • ...

Et ainsi de suite. Pour le dire avec euphémisme, ce n'est pas une bonne clé. Les clés dans lesquelles les lettres chiffrées et déchiffrées sont simplement des versions décalées de l'alphabet (comme A->B et B->C) sont appelées chiffrements « César ».

Note que ces chiffrements sont très difficiles à casser s'ils sont courts. En fait, s'ils sont très courts, ils sont indéterminés. Considère :

URYYP

Il existe de nombreux déchiffrements possibles, avec des clés différentes : HELLO, PETTY, HAPPY, JIGGY, STOOL. Peux-tu en trouver d'autres ?

Mais si tu envoies de nombreux messages comme celui-ci, le chiffrement finira par être cassé. Tu ne devrais donc pas utiliser la même « clé » trop souvent. En fait, le mieux est d'utiliser une certaine substitution une seule fois. Pas dans un seul message, mais uniquement pour un seul caractère ! Par là, nous entendons que tu auras un schéma de chiffrement ou une clé pour chaque caractère utilisé dans le message, dans l'ordre. Si tu veux envoyer un message à un ami en utilisant ce schéma, toi et ton ami auriez besoin d'un bloc-notes (dans le bon vieux temps) sur lequel cette clé en perpétuel changement est écrite. Tu ne l'utiliseras qu'une seule fois. C'est ce qu'on appelle un « bloc-notes à usage unique ».

Le bloc-notes à usage unique

Voyons comment cela fonctionne avec un exemple. On pourrait le faire entièrement avec des lettres, mais il est courant de les convertir en chiffres, par exemple en assignant A=0, B=1, C=2… Supposons que nous soyons des amis impliqués dans des activités clandestines et que nous ayons partagé un bloc-notes. Idéalement, nous en partagerions plusieurs, mais celui d'aujourd'hui est :

EDGRPOJNCUWQZVMK…

Ou, en convertissant en chiffres par position dans l'alphabet :

4,3,6,17,15, 14, 9, 13, 2, 20, 22, 16, 25, 21, 12, 10…

Supposons que je veuille te partager le message :

"I love quantum!"

Ou, de façon équivalente :

8, 11, 14, 21, 4, 16, 20, 0, 13, 19, 20, 12

Nous ne voulons pas envoyer le code ci-dessus ; c'est une substitution simple, qui n'est pas du tout sécurisée. Nous voulons le combiner avec notre clé d'une certaine façon. Une méthode courante est l'addition modulo 26. Nous ajoutons la valeur du message à la valeur de la clé, mod 26, jusqu'à atteindre la fin du message. Nous enverrions donc :

8+4 (mod 26) = 12, 11+3 (mod 26) = 14, 14+6 (mod 26) = 20, 21+17 (mod 26) = 12…

= 12, 14, 20, 12, 19, 4, 3, 13, 15, 13, 16, 2

Note que si quelqu'un intercepte ceci et ne possède PAS la clé, le déchiffrer est totalement désespéré ! Même les deux « u » de « quantum » ne sont pas encodés avec le même chiffre ! Le premier est un 3, et le second est un 16… dans le même mot !

Donc, je t'envoie ceci, et tu as la même clé que moi. Tu annules l'addition modulo 26 que tu sais que j'ai effectuée :

12, 14, 20, 12, 19, 4, 3, 13, 15, 13, 16, 2

=(4+x1) (mod 26), (3+x2) (mod 26), (6+x3) (mod 26), (17+x4) (mod 26),…

De sorte que le message x1, x2, x3, x4… doit être :

8, 11, 14, 21…

Enfin, en convertissant ceci en texte, on obtient :

"I love quantum".

C'est un bloc-notes à usage unique.

Note que si la clé est plus courte que le message, nous commençons à répéter notre encodage. Ce serait encore un problème de déchiffrement difficile à résoudre, mais pas impossible si c'est répété suffisamment de fois. Tu as donc besoin d'une clé (ou d'un « bloc-notes ») longue.

remarque

Dans de nombreux contextes, les étudiants seront déjà familiers avec ce chiffrement, de sorte que cette activité peut être ignorée. Mais c'est une révision relativement rapide et simple.

Étape 1 : Trouve un partenaire, et partagez une séquence de 4 lettres à utiliser comme clé. Toute séquence de 4 lettres appropriée pour la classe fera l'affaire.
Étape 2 : Choisis un mot secret de 4 lettres que tu veux envoyer à ton partenaire (les deux partenaires font cela afin de s'envoyer des mots secrets différents).
Étape 3 : Convertis la clé/le bloc-notes de 4 lettres et chacun des mots secrets de 4 lettres en chiffres en utilisant A = 1, B = 2, et ainsi de suite.
Étape 4 : Combine ton mot de 4 lettres avec le bloc-notes à usage unique en utilisant l'addition modulo 26.
Étape 5 : Donne à ton partenaire la séquence de chiffres encodant ton mot secret, et ton partenaire te donnera la sienne.
Étape 6 : Décode les mots de l'autre en utilisant la soustraction modulo 26.
Étape 7 : Vérifie. Est-ce que ça a marché ?

Suite

Échange des mots chiffrés avec un autre groupe qui n'a pas accès à ton bloc-notes à usage unique. Peux-tu le déchiffrer ? Explique pourquoi ou pourquoi pas ?

Avec un peu de chance, l'activité ci-dessus montre clairement qu'un bloc-notes à usage unique est une forme de chiffrement incassable, sous réserve de quelques hypothèses, comme :

  • La clé est de la même longueur que le message envoyé, ou plus longue
  • La clé est véritablement aléatoire
  • La clé n'est utilisée qu'une seule fois, puis détruite

C'est donc formidable. Nous avons un chiffrement incassable… à moins que quelqu'un n'obtienne notre clé. Si quelqu'un obtient notre clé, tout est déchiffré. Cette différence entre un chiffrement incassable et l'exposition de tous nos secrets rend le partage d'une clé sécurisée extrêmement important. L'objectif de la distribution quantique de clés est d'exploiter les contraintes que la nature a imposées à l'information quantique pour sécuriser une clé partagée/un bloc-notes à usage unique.

Utiliser des états quantiques comme clé

Supposons que nous travaillions avec des qubits (en soulignant que les qubits ont deux états propres). On pourrait utiliser des systèmes quantiques avec un plus grand nombre d'états quantiques, mais les ordinateurs quantiques à la pointe de la technologie chez IBM® utilisent des qubits. Il n'y a aucun problème à encoder nos A, B, C en séquences de 0 et de 1. Il nous suffit donc de partager une clé de 0 et de 1 et d'effectuer une addition modulo 2 sur chaque bit stockant une lettre.

Vérifie ta compréhension

Lis la question ci-dessous, réfléchis à ta réponse, puis clique sur le triangle pour révéler la solution.

Si on ne s'intéresse qu'aux lettres anglaises, de combien de bits avons-nous besoin ?

Réponse :

24=1625=325 bits2^4=16\\ 2^5 = 32 \rightarrow 5 \text{ bits}

Nos amis, Alice et Bob, souhaitent partager une clé quantique de telle manière que personne d'autre ne puisse l'intercepter (du moins pas sans qu'ils le sachent). Ils ont besoin d'un moyen de s'envoyer des états quantiques. Le faire avec une haute fidélité et sans bruit ni erreurs n'est PAS trivial. Mais il existe deux approches que nous devrions être capables de comprendre à ce stade :

  1. Un câble à fibre optique te permet d'envoyer de la lumière… qui est très quantique. Des photons uniques peuvent être détectés avec une haute fidélité sur de nombreux kilomètres de câble à fibre optique. Ce n'est pas un canal quantique parfait et sans erreur, mais il pourrait être très bon.
  2. On pourrait utiliser la téléportation quantique, comme décrit dans un module précédent. C'est-à-dire qu'Alice et Bob pourraient partager des qubits intriqués et un état pourrait être envoyé d'Alice à Bob en utilisant le protocole de téléportation.

Pour ce module, nous ne voulons pas t'obliger à disposer de configurations optiques à haute fidélité pour partager des photons, nous utiliserons donc la deuxième méthode pour partager des états quantiques. Mais cela ne veut pas dire que c'est la plus réaliste pour le partage de clés quantiques sur de longues distances.

Nous allons maintenant explorer un protocole décrit pour la première fois par Charles Bennett et Gilles Brassard en 1984 pour partager des états mesurés dans différentes bases entre Alice et Bob. Nous utiliserons un régime de mesure astucieux pour construire une clé destinée à un chiffrement ultérieur. En d'autres termes, nous distribuons une clé quantique entre deux parties souhaitant communiquer, d'où le terme « distribution quantique de clés » (QKD, de l'anglais Quantum Key Distribution).

QKD étape 1 : les bits aléatoires et les bases aléatoires d'Alice

Alice commence par générer une séquence aléatoire de 0 et de 1. Elle choisit ensuite aléatoirement une base dans laquelle préparer un état quantique, en se basant sur chaque bit aléatoire, en utilisant le tableau ci-dessous (un tableau que Bob possède également) :

Basebit = 0bit = 1
Z0\vert 0\rangle1\vert 1\rangle
X+\vert +\rangle\vert -\rangle

Par exemple, supposons qu'Alice ait généré aléatoirement un 0 et qu'elle ait sélectionné aléatoirement la base X. Elle préparerait alors un état quantique ψ=+x=12(0+1)|\psi\rangle = |+\rangle_x = \frac{1}{\sqrt{2}}(|0\rangle+|1\rangle). On peut certainement exploiter l'aléatoire quantique pour générer un ensemble aléatoire de 0 et de 1, et un choix de base aléatoire. Pour l'instant, supposons simplement qu'un ensemble aléatoire a été généré, comme suit :

Bits d'Alice010011010...
Bases d'AliceXXZZZXZZX...
États d'Alice+\vert +\rangle\vert -\rangle0\vert 0\rangle0\vert 0\rangle1\vert 1\rangle\vert -\rangle0\vert 0\rangle1\vert 1\rangle+\vert +\rangle...

Cet ensemble de bits aléatoires, de bases et d'états résultants continuerait dans une longue séquence, pour donner une clé de longueur suffisante.

QKD étape 2 : les bases aléatoires de Bob

Bob fait également un choix aléatoire de bases. Cependant, alors qu'Alice utilisait le choix de base pour préparer son état, Bob effectuera réellement des mesures dans ces bases. Si Bob effectue une mesure dans la même base que celle dans laquelle Alice a préparé l'état, alors on peut prédire le résultat de la mesure de Bob. Lorsque Bob choisit par hasard une base différente de celle qu'Alice a utilisée pour la préparation, on ne peut pas connaître le résultat de la mesure de Bob.

Bits d'Alice010011010...
Bases d'AliceXXZZZXZZX...
États d'Alice+\vert +\rangle\vert -\rangle0\vert 0\rangle0\vert 0\rangle1\vert 1\rangle\vert -\rangle0\vert 0\rangle1\vert 1\rangle+\vert +\rangle...
Bases de BobXZXZXXZXX...
États de Bob (a priori)+\vert +\rangle??0\vert 0\rangle?\vert -\rangle0\vert 0\rangle?+\vert +\rangle...
États de Bob (mesurés)+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle+\vert +\rangle\vert -\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle...
Dans le tableau ci-dessous, considère la première colonne. Alice a préparé l'état +,\vert +\rangle, qui est un état propre de X. Puisque Bob a également choisi aléatoirement de mesurer dans la base X, il n'y a qu'un seul résultat possible pour l'état mesuré de Bob : +.\vert +\rangle. Dans la deuxième colonne, cependant, ils ont choisi des bases différentes. L'état envoyé par Alice est =12(01).\vert -\rangle = \frac{1}{\sqrt{2}}(\vert 0\rangle-\vert 1 \rangle). Celui-ci a 50 % de chances d'être mesuré par Bob dans l'état 0\vert 0\rangle, et 50 % de chances d'être mesuré dans 1.\vert 1\rangle. Donc la ligne montrant ce que nous savons, a priori, des mesures de Bob ne peut pas être remplie pour la colonne 2. Mais Bob effectuera une mesure et obtiendra un état propre de (dans cette colonne) Z. Dans la dernière ligne, nous indiquons ce que ces mesures ont donné.

QKD étape 3 : discussion publique des bases

Alice et Bob peuvent maintenant se communiquer la base qu'ils ont choisie dans chaque cas. Pour toutes les colonnes dans lesquelles ils ont choisi la même base, ils savent chacun avec certitude quel état l'autre avait. Bob peut convertir l'état et la base en un 0 ou un 1 selon la convention partagée par les deux parties. Nous pouvons réécrire le tableau ci-dessus pour ne montrer que les instances où les bases d'Alice et de Bob correspondent :

Bits d'Alice00100...
Bases d'AliceXZXZX...
États d'Alice+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle+\vert +\rangle...
Bases de BobXZXZXX
États de Bob (a priori)+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle+\vert +\rangle...
États de Bob (mesurés)+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle+\vert +\rangle...
Bits de Bob00100...

Alice a réussi à transmettre la chaîne de bits 00100… à Bob. Si les amis s'étaient mis d'accord au préalable pour utiliser des chaînes de 5 bits comme nombres dans leur bloc-notes à usage unique, ces cinq premiers bits leur donneraient le nombre 4=0×24+0×23+1×22+0×21+0×20.4 = 0\times2^4+0\times2^3+1\times2^2+0\times2^1+0\times2^0.

QKD étape 4 : vérification et envoi du secret

Avant qu'Alice et Bob n'aillent plus loin, ils devraient choisir un sous-ensemble de leurs bits classiques à comparer. Puisqu'ils n'ont conservé que les mesures de qubits qui ont été préparés et mesurés dans la même base, toutes les valeurs mesurées devraient concorder. Si un très faible pourcentage ne concordait pas, cela pourrait être attribué au bruit quantique ou à des erreurs. Mais si beaucoup ne concordent pas, quelque chose s'est mal passé !

Ici, nous ne traiterons pas de la fraction de la clé qui devrait être utilisée pour la vérification. Pour l'instant, nous supposerons que cette vérification se passe bien ; nous reviendrons sur ce point dans la section ci-dessous sur l'espionnage.

Les amis enverraient ensuite un message chiffré l'un à l'autre via des canaux classiques. Ils utiliseraient ensuite les nombres de leur bloc-notes à usage unique pour chiffrer/déchiffrer des messages secrets, sans jamais transmettre le bloc-notes à usage unique d'un endroit à un autre. Pour la prochaine section sur l'espionnage, garde à l'esprit que tout ce partage de la clé se produit avant la révélation du secret chiffré via des canaux classiques.

Alice et Bob ont communiqué leur choix de base via des canaux classiques, cela ne pourrait-il pas être intercepté ? Oui ! Mais connaître la base qu'ils ont utilisée pour la mesure ne te dit pas quel bit ils ont envoyé ou obtenu. C'est seulement possible si tu connais également les bits de départ d'Alice. Mais dans ce cas, tu serais dans l'ordinateur d'Alice, où les secrets sont stockés, et la communication secrète des secrets devient sans objet. Donc l'interception de la communication classique ne brise pas le chiffrement. Mais qu'en est-il de l'interception d'informations dans le canal quantique ?

Résistance de la QKD à l'espionnage

Alice et Bob ont une amie, Ève, connue pour espionner. Ève souhaite intercepter la clé quantique d'Alice et de Bob, afin de pouvoir l'utiliser pour déchiffrer les messages échangés entre les deux. Cela devrait nécessairement se produire entre la préparation des états par Alice et la mesure des états par Bob, puisque la mesure fait s'effondrer l'état quantique. En particulier, cela signifie que l'espionnage devrait avoir lieu avant qu'il y ait eu un quelconque partage ou comparaison de bases.

Ève doit deviner quelle base a été utilisée pour encoder chaque bit. Encore une fois, si elle n'est pas capable d'accéder à l'ordinateur d'Alice, elle n'a aucune base sur laquelle fonder cette supposition, et elle sera aléatoire. Supposons que le départ d'Alice soit le même qu'avant, et supposons également que le choix aléatoire de base de mesure de Bob soit le même qu'avant. Voyons ce qu'Ève obtient si elle effectue des mesures sur le canal quantique. Comme avant, si Ève choisit la même base qu'Alice, nous savons ce qu'elle obtiendra. Sinon, elle pourrait obtenir l'un ou l'autre des deux résultats, chacun avec une probabilité de 50 %.

Bits d'Alice010011010...
Bases d'AliceXXZZZXZZX...
États d'Alice+\vert +\rangle\vert -\rangle0\vert 0\rangle0\vert 0\rangle1\vert 1\rangle\vert -\rangle0\vert 0\rangle1\vert 1\rangle+\vert +\rangle...
Bases supposées d'ÈveZXXZXZZXX...
États d'Ève (a priori)?\vert -\rangle?0\vert 0\rangle??0\vert 0\rangle?+\vert +\rangle...
États d'Ève (mesurés)1\vert 1\rangle\vert -\rangle+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle...
Bases de BobXZXZXXZXX...

Maintenant, comme Ève ne sait pas si elle a correspondu ou non à la base d'Alice, elle ne sait pas quoi transmettre à Bob pour correspondre aux états originaux d'Alice. Lorsqu'Ève mesure, par exemple, 0,|0\rangle, tout ce qu'elle sait avec certitude, c'est qu'Alice n'a pas préparé l'état 1|1\rangle pour ce qubit. Mais Alice aurait pu préparer 0,|0\rangle, +,|+\rangle, ou .|-\rangle. Tous pourraient être compatibles avec la mesure d'Ève. Donc Ève doit faire un choix. Elle pourrait transmettre exactement l'état qu'elle a mesuré, ou elle pourrait essayer de deviner les cas dans lesquels sa mesure n'était pas l'état propre envoyé par Alice. Nous inclurons un mélange dans notre tableau :

Bits d'Alice010011010...
Bases d'AliceXXZZZXZZX...
États d'Alice+\vert +\rangle\vert -\rangle0\vert 0\rangle0\vert 0\rangle1\vert 1\rangle\vert -\rangle0\vert 0\rangle1\vert 1\rangle+\vert +\rangle...
Bases supposées d'ÈveZXXZXZZXX...
États d'Ève (a priori)?\vert -\rangle?0\vert 0\rangle??0\vert 0\rangle?+\vert +\rangle...
États d'Ève (mesurés)1\vert 1\rangle\vert -\rangle+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle...
États d'Ève (transmis)1\vert 1\rangle0\vert 0\rangle1\vert 1\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle...
Bases de BobXZXZXXZXX...
États de Bob (a priori)?0\vert 0\rangle?0\vert 0\rangle\vert -\rangle+\vert +\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle...
États de Bob (mesurés)\vert -\rangle0\vert 0\rangle+\vert +\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle...
Bits de Bob100010010...

À ce stade, il est raisonnable de se demander : « Pourquoi Ève ne fait-elle pas simplement une copie de l'état quantique d'Alice, en garde une pour la mesurer, et transmet l'autre à Bob ? » La réponse est le théorème de « non-clonage ». Informellement, il stipule qu'il n'existe pas d'opération unitaire (quantique mécanique) qui puisse faire une seconde copie d'un état quantique arbitraire, tout en préservant la première copie. La preuve est relativement simple, et est laissée comme exercice guidé. Mais pour l'instant, comprends que le fait pour Ève de faire des copies de l'état quantique est interdit par les lois fondamentales de la nature, et c'est un des principaux atouts de la QKD. Comme avant, Alice et Bob se téléphoneront et compareront leurs bases. Ils réduiront ce tableau aux cas où les deux amis ont sélectionné les mêmes bases :

Bits d'Alice00100...
Bases d'AliceXZXZX...
États d'Alice+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle+\vert +\rangle...
Bases supposées d'ÈveZZZZX...
États d'Ève (a priori)?0\vert 0\rangle?0\vert 0\rangle+\vert +\rangle...
États d'Ève (mesurés)1\vert 1\rangle0\vert 0\rangle0\vert 0\rangle0\vert 0\rangle+\vert +\rangle...
États d'Ève (transmis)1\vert 1\rangle0\vert 0\rangle+\vert +\rangle0\vert 0\rangle0\vert 0\rangle...
Bases de BobXZXZX...
États de Bob (a priori)?0\vert 0\rangle+\vert +\rangle0\vert 0\rangle+\vert +\rangle...
États de Bob (mesurés)\vert -\rangle0\vert 0\rangle+\vert +\rangle0\vert 0\rangle+\vert +\rangle...
Bits de Bob10000...

Alice et Bob ont une fois de plus communiqué une chaîne de bits… mais les chaînes ne correspondent pas. Le bit le plus à gauche et le bit du milieu sont inversés. En regardant le tableau précédent, tu peux retracer cette discordance à l'interférence d'Ève. Point crucial, note que nous pouvons faire des statistiques sur la correspondance entre nos chaînes de bits maintenant, pendant la mise en place de la clé, bien avant de partager notre secret chiffré. Alice et Bob sont libres d'utiliser autant de bits de leur bloc-notes à usage unique qu'ils le souhaitent pour vérifier la sécurité de leur canal. Si un seul bit, ou un très faible pourcentage de bits ne correspondait pas, cela pourrait être attribué au bruit ou à des erreurs. Mais une fraction substantielle de discordances indique un espionnage. La signification de « substantielle » dépend un peu du bruit dans la configuration utilisée ; ce que cela signifie pour les ordinateurs quantiques IBM® est discuté ci-dessous lorsque nous implémentons ce protocole. Si des erreurs excessives sont détectées, Alice et Bob ne partagent pas le secret, et ils peuvent commencer à chercher l'espion.

Mises en garde

Prouver la sécurité est extrêmement difficile. En fait, le protocole décrit ici de façon approximative a été proposé en 1984, et n'a été prouvé sécurisé que 16 ans plus tard Shor & Preskill, 2000. Il existe de nombreuses subtilités qui dépassent le cadre de cette introduction. Mais nous en énumérerons brièvement quelques-unes pour montrer que le sujet est plus complexe que ce qui est illustré ici.

  • Canaux sécurisés : Lorsqu'Alice envoie ses qubits à travers une configuration quantique (un canal), et en particulier lorsqu'elle reçoit des réponses classiques de quelqu'un, nous avons supposé que ce quelqu'un était vraiment Bob. Si Ève s'était infiltrée dans cette configuration de telle sorte que toutes les communications d'Alice se passaient en réalité avec Ève, et que toutes les communications de Bob se passaient en réalité avec Ève, alors Ève a effectivement obtenu une clé, et peut apprendre les secrets. Il faut d'abord assurer des « canaux sécurisés », un processus avec un ensemble différent de protocoles que nous n'avons pas abordé ici.
  • Hypothèses sur Ève : Pour vraiment prouver la sécurité, nous ne pouvons pas faire d'hypothèses sur le comportement d'Ève ; elle pourrait toujours déjouer nos attentes. Ici, pour donner des exemples concrets, nous faisons des hypothèses. Par exemple, nous pourrions supposer que les états qu'Ève transmet à Bob sont toujours exactement ceux qu'elle a obtenus lors de la mesure. Ou nous pourrions supposer qu'elle choisit aléatoirement un état expérimentalement compatible avec sa mesure. Plus fondamentalement, le langage utilisé ici suppose qu'Ève effectue réellement une mesure, par opposition au stockage de l'état sur un autre système quantique et à l'envoi d'un qubit aléatoire à Bob. Ces hypothèses sont suffisantes pour comprendre le protocole, mais elles signifient que nous ne prouvons rien dans toute sa généralité.
  • Amplification de la confidentialité : Alice et Bob ne sont pas obligés d'utiliser la clé quantique exactement telle qu'elle a été transmise. Ils peuvent, par exemple, appliquer une fonction de hachage à la clé partagée. Cela permettrait d'exploiter le fait que l'espion a une connaissance incomplète de la clé pour produire une clé partagée plus courte, mais sécurisée.

Expérience 1 : QKD sans espion

Implémentons le protocole ci-dessus en l'absence d'un espion. Nous commencerons avec un simulateur, simplement pour comprendre le flux de travail.

Quelques mots sur les simulateurs quantiques : la plupart des problèmes quantiques impliquant plus de ~30 qubits ne peuvent pas être simulés par la plupart des ordinateurs. Aucun ordinateur classique, supercalculateur ou GPU ne peut simuler l'ensemble du comportement d'un ordinateur quantique à 127 qubits. En général, la motivation pour utiliser de vrais ordinateurs quantiques est que les nombreux qubits intriqués ne peuvent pas être simulés. Dans ce cas, il n'y a pas d'intrication de qubits, à moins d'utiliser le schéma de téléportation pour déplacer l'information. Ici, la motivation pour utiliser de vrais ordinateurs quantiques est différente : c'est le théorème de non-clonage. Un ordinateur classique simulant un qubit pourrait envoyer des informations sur un état quantique d'Alice à Bob, mais si cette information classique était interceptée, elle pourrait facilement être dupliquée, et Eve pourrait en conserver une copie parfaite tout en en envoyant une autre à Bob. Cela n'est pas possible avec de vrais états quantiques.

IBM Quantum recommande d'aborder les problèmes de calcul quantique à l'aide d'un cadre que nous appelons les « Qiskit patterns ». Il se compose des étapes suivantes.

  • Étape 1 : Mapper ton problème sur un circuit quantique
  • Étape 2 : Optimiser ton circuit pour l'exécution sur du vrai matériel quantique
  • Étape 3 : Exécuter ton job sur les ordinateurs quantiques IBM en utilisant les primitives Runtime
  • Étape 4 : Post-traiter les résultats

Qiskit patterns étape 1 : Mapper ton problème sur un circuit quantique

Dans ce cas, le mappage de notre problème sur des circuits quantiques se réduit à préparer les états d'Alice, puis à inclure les mesures de Bob. Nous commençons par la sélection aléatoire des bits et des bases.

# Qiskit patterns step 1: Map your problem to quantum circuit
# Import some generic packages

import numpy as np
from qiskit import QuantumCircuit

# Set up a random number generator and a quantum circuit. We choose to start with 20 bits, though any number <30 should be fine.

rng = np.random.default_rng()
bit_num = 20
qc = QuantumCircuit(bit_num, bit_num)

# QKD step 1: Random bits and bases for Alice
# generate Alice's random bits

abits = np.round(rng.random(bit_num))

# generate Alice's random measurement bases. Here we will associate a "0" with the Z basis, and a "1" with the X basis.

abase = np.round(rng.random(bit_num))

# Alice's state preparation. Check that this creates states according to table 1

for n in range(bit_num):
if abits[n] == 0:
if abase[n] == 1:
qc.h(n)
if abits[n] == 1:
if abase[n] == 0:
qc.x(n)
if abase[n] == 1:
qc.x(n)
qc.h(n)

qc.barrier()

# QKD step 2: Random bases for Bob
# generate Bob's random measurement bases.

bbase = np.round(rng.random(bit_num))

# Note that if Bob measures in Z no gates are necessary, since IBM Quantum computers measure in Z by default.
# If Bob measures in the X basis, we implement a hadamard gate qc.h to facilitate the measurement.

for m in range(bit_num):
if bbase[m] == 1:
qc.h(m)
qc.measure(m, m)

Visualisons les bits, les bases et le circuit. Note que les bases concordent parfois, et parfois non.

print("Alice's bits are ", abits)
print("Alice's bases are ", abase)
print("Bob's bases are ", bbase)
qc.draw("mpl")
Alice's bits are  [1. 1. 0. 1. 0. 1. 1. 0. 0. 1. 0. 0. 1. 0. 0. 0. 1. 0. 0. 0.]
Alice's bases are [0. 0. 0. 1. 1. 0. 0. 0. 0. 1. 1. 1. 1. 1. 0. 1. 1. 0. 1. 0.]
Bob's bases are [0. 1. 1. 0. 1. 0. 1. 1. 0. 0. 1. 1. 0. 0. 1. 0. 1. 1. 0. 0.]

Sortie de la cellule de code précédente

Qiskit patterns étape 2 : Optimiser le problème pour l'exécution quantique

Cette étape prend les opérations que nous souhaitons effectuer et les exprime en termes des fonctionnalités d'un ordinateur quantique spécifique. Elle mappe également notre problème sur la topologie de l'ordinateur quantique.

Nous commencerons par charger plusieurs paquets nécessaires pour communiquer avec les ordinateurs quantiques IBM. Nous devons également sélectionner un backend sur lequel exécuter notre code. Nous pouvons soit choisir le backend le moins occupé, soit sélectionner un backend spécifique dont nous connaissons les propriétés. Bien que nous utilisions momentanément un simulateur, il est important d'utiliser un modèle de bruit réaliste lors de la simulation, et il vaut mieux maintenir le flux de travail aussi proche que possible de ce que nous utiliserons ensuite pour de vrais ordinateurs quantiques.

Le code ci-dessous te permet de sauvegarder tes identifiants lors de la première utilisation. Assure-toi de supprimer ces informations du notebook après les avoir enregistrées dans ton environnement, afin que tes identifiants ne soient pas accidentellement partagés lorsque tu partages le notebook. Consulte Configurer ton compte IBM Cloud et Initialiser le service dans un environnement non sécurisé pour plus d'informations.

# Load the Qiskit Runtime service
from qiskit_ibm_runtime import QiskitRuntimeService

# Load the Qiskit Runtime service

# Syntax for first saving your token. Delete these lines after saving your credentials.
# QiskitRuntimeService.save_account(channel='ibm_quantum_platform', instance = '<YOUR_IBM_INSTANCE_CRN>', token='<YOUR-API_KEY>', overwrite=True, set_as_default=True)
# service = QiskitRuntimeService(channel='ibm_quantum_platform')

# Load saved credentials
service = QiskitRuntimeService()

# Use the least busy backend, or uncomment the loading of a specific backend like "ibm_brisbane".
# backend = service.least_busy(operational=True, simulator=False, min_num_qubits = 127)
backend = service.backend("ibm_brisbane")
print(backend.name)
ibm_brisbane

Ci-dessous, nous sélectionnons un simulateur et un modèle de bruit.

# Load the backend sampler
from qiskit.primitives import BackendSamplerV2

# Load the Aer simulator and generate a noise model based on the currently-selected backend.
from qiskit_aer import AerSimulator
from qiskit_aer.noise import NoiseModel

# Load the qiskit runtime sampler
from qiskit_ibm_runtime import SamplerV2 as Sampler

noise_model = NoiseModel.from_backend(backend)

# Define a simulator using Aer, and use it in Sampler.
backend_sim = AerSimulator(noise_model=noise_model)
sampler_sim = BackendSamplerV2(backend=backend_sim)
# Qiskit patterns step 2: Transpile
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager

target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)

Qiskit patterns étape 3 : Exécuter

Utilise le sampler pour exécuter ton job, en passant le circuit en argument.

# This required 5 s to run on a Heron r2 processor on 10-28-24
sampler = Sampler(mode=backend)
job = sampler.run([qc_isa], shots=1)
# job = sampler_sim.run([qc], shots = 1)
counts = job.result()[0].data.c.get_counts()
countsint = job.result()[0].data.c.get_int_counts()

Qiskit patterns étape 4 : Post-traitement

Ici, nous interprétons nos résultats et en extrayons des informations utiles. Nous pourrions essayer de visualiser la sortie de notre sampler, mais nous l'avons utilisé de manière non conventionnelle. Plutôt que d'effectuer de nombreuses mesures de notre circuit et de développer des statistiques sur les états, nous n'avons effectué qu'une seule mesure (celle de Bob). Tout qubit dont l'état a été préparé et mesuré dans la même base devrait avoir un résultat déterministe, de sorte qu'une seule mesure est nécessaire. Les qubits dont les états ont été préparés et mesurés dans des bases différentes (qui auraient des résultats probabilistes et nécessiteraient de nombreuses mesures pour être interprétés) ne seront pas utilisés pour construire notre masque jetable/clé. Extrayons une liste de résultats de mesure à partir de cette chaîne de bits. Prends soin d'inverser l'ordre si tu compares avec le tableau de bits d'Alice que nous avons utilisé pour générer le circuit.

# Get an array of bits

keys = counts.keys()
key = list(keys)[0]
bmeas = list(key)
bmeas_ints = []
for n in range(bit_num):
bmeas_ints.append(int(bmeas[n]))

# Reverse the order to match our input. See "little endian" notation.

bbits = bmeas_ints[::-1]

print(bbits)
[1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0]

Comparons les bases de mesure choisies aléatoirement par Alice et Bob. C'était l'étape 3 de notre protocole QKD (discussion publique des bases). Chaque fois qu'ils ont choisi la même base pour un qubit, nous ajoutons les bits associés à ce qubit à une liste de bits pour générer des nombres dans un masque jetable. Lorsque les bases ne concordent pas, les résultats sont écartés. Vérifions également que les deux listes de bits concordent, ou s'il y a eu des pertes dues au bruit ou à d'autres facteurs.

# QKD step 3: Public discussion of bases

agoodbits = []
bgoodbits = []
match_count = 0
for n in range(bit_num):
# Check whether bases matched.
if abase[n] == bbase[n]:
agoodbits.append(int(abits[n]))
bgoodbits.append(bbits[n])
# If bits match when bases matched, increase count of matching bits
if int(abits[n]) == bbits[n]:
match_count += 1

print(agoodbits)
print(bgoodbits)
print("fidelity = ", match_count / len(agoodbits))
print("loss = ", 1 - match_count / len(agoodbits))
[1, 0, 1, 0, 0, 0, 1, 0]
[1, 0, 1, 0, 0, 0, 1, 0]
fidelity = 1.0
loss = 0.0

Alice et Bob disposent chacun d'une liste de bits, et elles concordent avec une fidélité de 100 %. Ils peuvent les utiliser pour générer des nombres dans un masque jetable, puis s'en servir à l'étape QKD 4 : envoyer et déchiffrer un secret. Le tableau de bits actuel est trop court pour déchiffrer quoi que ce soit de conséquent. Nous y reviendrons après avoir introduit l'écoute clandestine.

Vérifie ta compréhension

Lis la question ci-dessous, réfléchis à ta réponse, puis clique sur le triangle pour révéler la solution.

Suppose que tu aies besoin de chiffres suffisamment grands pour décaler des lettres de l'alphabet anglais d'au moins la longueur de cet alphabet, bien qu'il existe d'autres schémas d'encodage. (a) De combien de lettres pourrait être composé un message pouvant être déchiffré avec les bits de la clé ci-dessus ? (b) Ta réponse doit-elle nécessairement s'accorder avec celle de tes camarades ? Pourquoi ou pourquoi pas ?

Réponse :

(a) La réponse dépend du nombre de bases choisies aléatoirement qui concordent entre Alice et Bob. Puisqu'il y a environ 50 % de chance que les bases concordent pour un qubit donné, on s'attend à ce qu'environ 10 de nos bits soient utilisables. 9 ou 11 seront tout à fait courants. Même 4 ou 15 ne sont pas hors du domaine du possible. 5 bits sont nécessaires pour décaler d'un nombre supérieur ou égal à la longueur de l'alphabet anglais, ce qui signifie que tu peux appliquer le décalage à une lettre pour chaque tranche de 5 bits. Si tu as au moins 5 bits partagés entre Alice et Bob, tu peux encoder une seule lettre. Si tu en as au moins 10, tu peux en encoder 2, et ainsi de suite. (b) Elle n'a pas besoin de s'accorder, pour les raisons énoncées en (a).

Expérience 2 : QKD avec un espion

Nous allons implémenter exactement le même protocole qu'avant. Cette fois, nous allons insérer un ensemble supplémentaire de mesures, effectuées par Eve, entre Alice et Bob.

from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister

# Qiskit patterns step 1: Mapping your problem to a quantum circuit
# QKD step 1: Random bits and bases for Alice

bit_num = 20
qr = QuantumRegister(bit_num, "q")
cr = ClassicalRegister(bit_num, "c")
qc = QuantumCircuit(qr, cr)

# Alice's random bits and bases, as before

abits = np.round(rng.random(bit_num))
abase = np.round(rng.random(bit_num))

# Alice's state preparation, as before

for n in range(bit_num):
if abits[n] == 0:
if abase[n] == 1:
qc.h(n)
if abits[n] == 1:
if abase[n] == 0:
qc.x(n)
if abase[n] == 1:
qc.x(n)
qc.h(n)

qc.barrier()

# Eavesdropping happens here!
# Generate Eve's random measurement bases

ebase = np.round(rng.random(bit_num))

for m in range(bit_num):
if ebase[m] == 1:
qc.h(m)
qc.measure(qr[m], cr[m])
# Qiskit patterns step 2: Transpile
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager

target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)
# Qiskit patterns step 3: Execute
job = sampler_sim.run([qc_isa], shots=1)
counts = job.result()[0].data.c.get_counts()
countsint = job.result()[0].data.c.get_int_counts()

L'étape 4 des Qiskit patterns (post-traitement) est simple dans ce cas. Pas besoin de visualiser la distribution des mesures, puisque nous n'avons effectué qu'une seule mesure. Eve dispose des bits suivants :

keys = counts.keys()
key = list(keys)[0]
emeas = list(key)
emeas_ints = []
for n in range(bit_num):
emeas_ints.append(int(emeas[n]))
ebits = emeas_ints[::-1]

print(ebits)
[0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1]

Eve doit maintenant reconstruire des états à envoyer à Bob. Comme décrit dans l'introduction, elle n'a aucun moyen de savoir si elle a correctement deviné les bases d'encodage, et elle ne peut donc pas préparer exactement les mêmes états qui ont été envoyés. Elle pourrait supposer que chaque choix de base était correct et encoder exactement ce qu'elle a mesuré, ou supposer qu'elle a fait le mauvais choix de base et sélectionner l'un ou l'autre état propre de la base opposée. Ici, pour simplifier, nous supposons la première option. Nous y parvenons en construisant un nouveau circuit quantique et en répétant les étapes des Qiskit patterns comme précédemment.

from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager

# Qiskit patterns step 1: Mapping your problem onto a quantum circuit
# QKD step 1: Eve uses her measurements to prepare best guess states to send on to Bob

qr = QuantumRegister(bit_num, "q")
cr = ClassicalRegister(bit_num, "c")
qc = QuantumCircuit(qr, cr)

# Eve's state preparation

for n in range(bit_num):
if ebits[n] == 0:
if ebase[n] == 1:
qc.h(n)
if ebits[n] == 1:
if ebase[n] == 0:
qc.x(n)
if ebase[n] == 1:
qc.x(n)
qc.h(n)

qc.barrier()

# QKD step 2: Random bases for Bob

bbase = np.round(rng.random(bit_num))

for m in range(bit_num):
if bbase[m] == 1:
qc.h(m)
qc.measure(qr[m], cr[m])

# Qiskit patterns step 2: Transpile

target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)

# Qiskit patterns step 3: Execute

job = sampler_sim.run([qc_isa], shots=1)
counts = job.result()[0].data.c.get_counts()
countsint = job.result()[0].data.c.get_int_counts()

# Qiskit patterns step 4: Post-processing

keys = counts.keys()
key = list(keys)[0]
bmeas = list(key)
bmeas_ints = []
for n in range(bit_num):
bmeas_ints.append(int(bmeas[n]))
bbits = bmeas_ints[::-1]

print(bbits)
[0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1]

Comparons maintenant les bits d'Alice et de Bob :

agoodbits = []
bgoodbits = []
match_count = 0
for n in range(bit_num):
if abase[n] == bbase[n]:
agoodbits.append(int(abits[n]))
bgoodbits.append(bbits[n])
if int(abits[n]) == bbits[n]:
match_count += 1
print(agoodbits)
print(bgoodbits)
print("fidelity = ", match_count / len(agoodbits))
print("loss = ", 1 - match_count / len(agoodbits))
[1, 1, 0, 0, 0, 1, 1]
[1, 1, 0, 0, 0, 0, 1]
fidelity = 0.8571428571428571
loss = 0.1428571428571429

Auparavant, les bits des clés d'Alice et de Bob concordaient parfaitement. Maintenant, en raison de l'interférence d'Eve, nous constatons que les bits d'Alice et de Bob diffèrent dans 14 % des cas qui devraient concorder, puisqu'Alice et Bob ont sélectionné les mêmes bases. Alice et Bob devraient facilement détecter cette anomalie. Toutefois, s'appuyer sur un tel pourcentage d'erreurs signifie qu'il y a une limite à la quantité de bruit que nous pouvons tolérer dans le canal quantique.

Expérience 3 : Comparer la QKD avec et sans écoute sur un vrai ordinateur quantique

Exécutons cela sur un vrai ordinateur quantique. On peut ainsi tirer parti du théorème de non-clonage. En revanche, les vrais ordinateurs quantiques sont bruités et ont des taux d'erreur plus élevés que les ordinateurs classiques. Comparons donc la perte de fidélité de nos bits de clé avec et sans écoute, pour s'assurer que la différence est détectable sur un vrai ordinateur quantique. On commence sans écoute :

from qiskit_ibm_runtime import SamplerV2 as Sampler

# This calculation was run on an Eagle r3 processor on 11-7-24 and required 3 sec to run, with 127 qubits.
# Qiskit patterns step 1: Mapping your problem to a quantum circuit

bit_num = 127
qc = QuantumCircuit(bit_num, bit_num)

# QKD step 1: Generate Alice's random bits and bases

abits = np.round(rng.random(bit_num))
abase = np.round(rng.random(bit_num))

# Alice's state preparation

for n in range(bit_num):
if abits[n] == 0:
if abase[n] == 1:
qc.h(n)
if abits[n] == 1:
if abase[n] == 0:
qc.x(n)
if abase[n] == 1:
qc.x(n)
qc.h(n)

# QKD step 2: Random bases for Bob

bbase = np.round(rng.random(bit_num))

for m in range(bit_num):
if bbase[m] == 1:
qc.h(m)
qc.measure(m, m)

# Qiskit patterns step 2: Transpilation

target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)

# Load the Runtime primitive and session
sampler = Sampler(mode=backend)

# Qiskit patterns step 3: Execute

job = sampler.run([qc_isa], shots=1)
counts = job.result()[0].data.c.get_counts()
countsint = job.result()[0].data.c.get_int_counts()

# Qiskit patterns step 4: Post-processing
# Extract Bob's bits

keys = counts.keys()
key = list(keys)[0]
bmeas = list(key)
bmeas_ints = []
for n in range(bit_num):
bmeas_ints.append(int(bmeas[n]))
bbits = bmeas_ints[::-1]

# Compare Alice's and Bob's measurement bases and collect usable bits

agoodbits = []
bgoodbits = []
match_count = 0
for n in range(bit_num):
if abase[n] == bbase[n]:
agoodbits.append(int(abits[n]))
bgoodbits.append(bbits[n])
if int(abits[n]) == bbits[n]:
match_count += 1

# Print some results

print("Alice's bits = ", agoodbits)
print("Bob's bits = ", bgoodbits)
print("fidelity = ", match_count / len(agoodbits))
print("loss = ", 1 - match_count / len(agoodbits))
Alice's bits =  [0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1]
Bob's bits = [0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1]
fidelity = 0.9682539682539683
loss = 0.031746031746031744

Sans écoute, on a obtenu une fidélité de 100 % sur cet ensemble de 127 bits d'essai, avec 55 bases correspondantes et donc 55 bits de clé utilisables. Répétons maintenant cette expérience avec Ève qui écoute :

from qiskit_ibm_runtime import SamplerV2 as Sampler

# This calculation was run on an Eagle r3 processor on 11-7-24 and required 2 s to run, with 127 qubits.
# Qiskit patterns step 1: Mapping your problem to a quantum circuit

bit_num = 127
qr = QuantumRegister(bit_num, "q")
cr = ClassicalRegister(bit_num, "c")
qc = QuantumCircuit(qr, cr)

# QKD step 1: Generate Alice's random bits and bases

abits = np.round(rng.random(bit_num))
abase = np.round(rng.random(bit_num))

# Alice's state preparation

for n in range(bit_num):
if abits[n] == 0:
if abase[n] == 1:
qc.h(n)
if abits[n] == 1:
if abase[n] == 0:
qc.x(n)
if abase[n] == 1:
qc.x(n)
qc.h(n)

# Eavesdropping happens here!
# Generate Eve's random measurement bases

ebase = np.round(rng.random(bit_num))

for m in range(bit_num):
if ebase[m] == 1:
qc.h(m)
qc.measure(qr[m], cr[m])

# Qiskit patterns step 2: Transpile

target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)

sampler = Sampler(mode=backend)

# Qiskit patterns step 3: Execute

job = sampler.run([qc_isa], shots=1)
counts = job.result()[0].data.c.get_counts()
countsint = job.result()[0].data.c.get_int_counts()

# Qiskit patterns step 4: Post-processing
# Extract Eve's bits

keys = counts.keys()
key = list(keys)[0]
emeas = list(key)
emeas_ints = []
for n in range(bit_num):
emeas_ints.append(int(emeas[n]))
ebits = emeas_ints[::-1]

# print(ebits)

# Restart process
# Qiskit patterns step 1: Mapping your problem to a quantum circuit

# QKD step 1: Eve uses her measurements above to prepare best guess states to send on to Bob

qr = QuantumRegister(bit_num, "q")
cr = ClassicalRegister(bit_num, "c")
qc = QuantumCircuit(qr, cr)

# Eve's state preparation

for n in range(bit_num):
if ebits[n] == 0:
if ebase[n] == 1:
qc.h(n)
if ebits[n] == 1:
if ebase[n] == 0:
qc.x(n)
if ebase[n] == 1:
qc.x(n)
qc.h(n)

# QKD step 2: Random bases for Bob

bbase = np.round(rng.random(bit_num))

for m in range(bit_num):
if bbase[m] == 1:
qc.h(m)
qc.measure(qr[m], cr[m])

# Qiskit patterns step 2: Transpile

target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)

# Qiskit patterns step 3: Execute

job = sampler.run([qc_isa], shots=1)
counts = job.result()[0].data.c.get_counts()
countsint = job.result()[0].data.c.get_int_counts()

# Qiskit Patterns step 4: Post-processing
# Extract Bob's bits

keys = counts.keys()
key = list(keys)[0]
bmeas = list(key)
bmeas_ints = []
for n in range(bit_num):
bmeas_ints.append(int(bmeas[n]))
bbits = bmeas_ints[::-1]

# Compare Alice's and Bob's bases, when they are the same, keep the bits.

agoodbits = []
bgoodbits = []
match_count = 0
for n in range(bit_num):
if abase[n] == bbase[n]:
agoodbits.append(int(abits[n]))
bgoodbits.append(bbits[n])
if int(abits[n]) == bbits[n]:
match_count += 1

# Print some results

print("Alice's bits = ", agoodbits)
print("Bob's bits = ", bgoodbits)
print("fidelity = ", match_count / len(agoodbits))
print("loss = ", 1 - match_count / len(agoodbits))
Alice's bits =  [1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1]
Bob's bits = [1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1]
fidelity = 0.7619047619047619
loss = 0.23809523809523814

On constate ici une perte de fidélité de presque 23 % sur les bits partagés, due à l'écoute ! C'est très détectable ! À noter que la transmission d'information quantique sur de longues distances peut introduire du bruit et des erreurs supplémentaires. S'assurer que l'écoute reste détectable, même en présence de bruit et même quand Ève dispose de toutes les astuces possibles, est un domaine complexe qui dépasse le cadre de cette introduction.

Questions

Les enseignants peuvent demander des versions de ces carnets avec les corrigés et des conseils sur leur intégration dans les programmes courants en remplissant ce rapide sondage sur la façon dont les carnets sont utilisés.

Concepts clés

  • L'information quantique ne peut pas être copiée ni « clonée ».
  • On peut répéter le même processus de préparation pour créer un ensemble d'états quantiques tous identiques, ou presque.
  • Une clé de chiffrement/déchiffrement (un masque jetable) peut être partagée entre deux personnes à l'aide d'états quantiques.
  • Quand deux personnes choisissent aléatoirement une base de mesure, elles choisissent différemment la moitié du temps et doivent alors ignorer l'information de ces qubits.
  • Le choix aléatoire de la base de mesure garantit également qu'une espionne ne peut pas connaître l'état initial préparé et ne peut donc pas recréer l'état envoyé. Cela assure que l'écoute sera détectée.

Questions vrai/faux

  1. V/F Dans la distribution quantique de clés, les deux partenaires de communication mesurent chaque qubit dans la même base.
  2. V/F Une espionne qui intercepte de l'information quantique dans la QKD est empêchée par les lois de la nature de copier l'état quantique qu'elle intercepte.
  3. V/F Un masque jetable est une clé de chiffrement/déchiffrement de messages sécurisés dans laquelle un schéma de codage particulier n'est utilisé qu'une seule fois, pour une seule information (comme une seule lettre de l'alphabet).

Questions à choix multiple

  1. Sélectionne l'option qui complète le mieux la phrase suivante. Tel que décrit dans ce module, un masque jetable est un ensemble de clés de chiffrement/déchiffrement qui est utilisé...
  • a. Une seule fois pour une seule information, comme une seule lettre.
  • b. Une seule fois pour un seul message.
  • c. Une seule fois pour une période de temps définie, comme une journée.
  • d. Jusqu'à ce qu'il y ait une preuve d'écoute.
  1. Supposons qu'Alice et Bob choisissent leurs bases de mesure aléatoirement. Ils mesurent. Ensuite, ils partagent leurs bases de mesure et ne conservent que les bits d'information pour lesquels ils ont utilisé la même base. En dehors des fluctuations aléatoires, quel pourcentage approximatif de leurs qubits devrait produire des bits d'information utilisables ?
  • a. 100 %
  • b. 50 %
  • c. 25 %
  • d. 12,5 %
  • e. 0 %
  1. Après qu'Alice et Bob ont sélectionné les cas où ils ont utilisé les mêmes bases de mesure, quel pourcentage de ces bits d'information devrait correspondre, si le bruit quantique et les erreurs étaient négligeables ?
  • a. 100 %
  • b. 50 %
  • c. 25 %
  • d. 12,5 %
  • e. 0 %
  1. Supposons qu'Alice ait choisi ses bases de mesure aléatoirement. Ève choisit également ses bases aléatoirement et écoute (mesure). Elle envoie à Bob des états cohérents avec ses mesures. Alice et Bob comparent leurs choix de bases et ne conservent que les qubits mesurés/préparés par eux dans les mêmes bases. En dehors des fluctuations aléatoires, quel pourcentage approximatif de ces mesures de qubits conservées correspondront, selon Alice et Bob ?
  • a. 100 %
  • b. 75 %
  • c. 50 %
  • d. 25 %
  • e. 12,5 %
  • f. 0 %

Questions de discussion

  1. Supposons que tous les choix de bases soient aléatoires pour tous les participants : Alice, Bob et Ève. Supposons qu'après avoir écouté, Ève envoie à Bob un état préparé dans la même base que celle qu'elle a utilisée pour mesurer, et cohérent avec cette mesure. Convaincs tes partenaires que 12,5 % de tous les qubits initialisés par Alice produiront des désaccords de mesure entre Alice et Bob, indiquant une écoute (en ignorant les erreurs et le bruit quantiques). Indice 1 : Comme il n'y a pas de base privilégiée, si tu considères un seul choix initial pour Alice, le rapport pour ce choix devrait être le même que le rapport pour la somme de tous les choix. Indice 2 : Il peut ne pas suffire de compter le nombre de façons dont quelque chose peut se produire, car certains résultats peuvent survenir avec des probabilités différentes.