Saltar al contenido principal

Distribución cuántica de claves

Para este módulo de Qiskit en el aula, los estudiantes deben tener un entorno de Python funcional con los siguientes paquetes instalados:

  • qiskit v2.1.0 o más reciente
  • qiskit-ibm-runtime v0.40.1 o más reciente
  • qiskit-aer v0.17.0 o más reciente
  • qiskit.visualization
  • numpy
  • pylatexenc

Para configurar e instalar los paquetes anteriores, consulta la guía Instalar Qiskit. Para ejecutar trabajos en computadoras cuánticas reales, los estudiantes deberán crear una cuenta en IBM Quantum® siguiendo los pasos de la guía Configurar tu cuenta de IBM Cloud.

Este módulo fue probado y utilizó 5 segundos de tiempo de QPU. Esto es solo una estimación. Tu uso real puede variar.

# 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'

Mira el recorrido del módulo a cargo de la Dra. Katie McCormick a continuación, o haz clic aquí para verlo en YouTube.


Introducción y motivación

Existen infinitas formas de cifrar y descifrar información, y literalmente miles han sido ampliamente estudiadas. Aquí nos limitaremos a un método de cifrado muy antiguo y muy sencillo, llamado "sustitución simple", con el fin de centrarnos en la parte cuántica de este protocolo. La parte cuántica podría adaptarse a muchos otros protocolos con relativamente pocos cambios.

Sustitución simple

Un cifrado de sustitución simple es aquel en el que una letra o número se reemplaza por otro, de modo que existe una correspondencia 1:1 entre las letras y números de un mensaje y las letras y números utilizados en la secuencia cifrada. Un ejemplo de cultura popular de este tipo son los acertijos criptográficos (cryptoquote o cryptogram), en los que una frase o cita se cifra mediante sustitución simple y el jugador debe descifrarla. Son fáciles de resolver si son suficientemente largos. Considera el ejemplo:

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.

Las personas que los resuelven a mano utilizan principalmente trucos relacionados con el conocimiento de la estructura del idioma del mensaje original. Por ejemplo, en inglés, las únicas palabras de una sola letra como la "R" cifrada son "a" e "I". Las letras dobles cifradas en, por ejemplo, "KIVGGB" solo pueden tomar ciertos valores. Hay indicios más sutiles, como que la palabra más común que encaja con el patrón "GSZG" es "that". Quienes usan código para resolverlos tienen muchas más opciones, como simplemente explorar posibilidades hasta recuperar una palabra en inglés y actualizar el descifrado preservando esa palabra. Un método sencillo pero poderoso es el uso de la frecuencia de letras, especialmente cuando el mensaje es lo suficientemente largo como para constituir una muestra representativa del inglés.

Pregunta de verificación

Intenta descifrar esto si quieres, aunque no es necesario para el resto del módulo. Haz clic en el símbolo de abajo para ver el mensaje.

Respuesta:

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.

El ejemplo anterior está asociado a una "clave", es decir, una correspondencia entre las letras cifradas y las descifradas. En este caso, la clave es:

  • A (no utilizada, llamémosla Z)
  • B->Y
  • C (no utilizada, llamémosla X)
  • D->W
  • E->V
  • F->U
  • ...

Y así sucesivamente. En pocas palabras, esta no es una buena clave. Las claves en las que las letras cifradas y descifradas son simplemente versiones desplazadas del alfabeto (como A->B y B->C) se denominan cifrados "César" o "de desplazamiento".

Ten en cuenta que estos son muy difíciles de romper si son cortos. De hecho, si son muy cortos, son indeterminados. Considera:

URYYP

Hay muchas posibles decodificaciones con diferentes claves: HELLO, PETTY, HAPPY, JIGGY, STOOL. ¿Se te ocurren otras?

Pero si envías muchos mensajes de este tipo, eventualmente el cifrado será descifrado. Por eso no deberías usar la misma "clave" con demasiada frecuencia. De hecho, lo ideal es usar una sustitución determinada solo una vez. No en un solo mensaje, sino ¡únicamente para un único carácter! Con esto queremos decir que tendrás un esquema de cifrado o clave para cada carácter del mensaje, en orden. Si quieres enviar un mensaje a un amigo usando este método, tú y tu amigo necesitarían un bloc de papel (en los viejos tiempos) en el que esté escrita esta clave siempre cambiante. Lo usarás una sola vez. Esto se llama "bloc de uso único" (one-time pad).

El bloc de uso único

Veamos cómo funciona esto con un ejemplo. Se podría hacer todo con letras, pero es habitual convertir las letras a números, por ejemplo, asignando A=0, B=1, C=2… Supongamos que somos amigos involucrados en actividades clandestinas y hemos compartido un bloc. Idealmente compartiríamos muchos blocs, pero el de hoy es:

EDGRPOJNCUWQZVMK…

O, convirtiendo a números según la posición en el alfabeto:

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

Supongamos que quiero compartir contigo el mensaje:

"I love quantum!"

O, de forma equivalente:

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

No queremos enviar el código anterior; eso es una sustitución simple, que no es nada segura. Queremos combinarlo con nuestra clave de alguna manera. Una forma habitual es la adición módulo 26. Sumamos el valor del mensaje al valor de la clave, mod 26, hasta llegar al final del mensaje. Así que enviaríamos:

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

¡Ten en cuenta que si alguien intercepta esto y NO tiene la clave, descifrar es absolutamente imposible! ¡Ni siquiera las dos "u" de "quantum" están codificadas con el mismo número! La primera es un 3, y la segunda un 16… ¡en la misma palabra!

Entonces te envío esto, y tú tienes la misma clave que yo. Deshaces la adición módulo 26 que sabes que realicé:

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 tal forma que el mensaje x1, x2, x3, x4… debe ser

8, 11, 14, 21…

Finalmente, convirtiendo esto a texto, obtenemos

"I love quantum".

Esto es un bloc de uso único.

Ten en cuenta que si la clave es más corta que el mensaje, comenzamos a repetir nuestra codificación. Eso seguiría siendo un problema de descifrado difícil, pero no imposible si se repite suficientes veces. Por eso necesitas una clave (o "bloc") larga.

nota

En muchos contextos, los estudiantes ya estarán familiarizados con este cifrado, por lo que esta actividad puede omitirse. Pero es un repaso relativamente rápido y sencillo.

Paso 1: Consigue un compañero y compartan una secuencia de 4 letras para usar como clave. Cualquier secuencia de 4 letras apropiada para el aula sirve.
Paso 2: Elige una palabra secreta de 4 letras que quieras enviar a tu compañero (ambos hacen esto para que se envíen palabras secretas diferentes).
Paso 3: Convierte la clave/bloc de 4 letras y cada una de las palabras secretas de 4 letras a números usando A = 1, B = 2, y así sucesivamente.
Paso 4: Combina tu palabra de 4 letras con el bloc de uso único usando adición módulo 26.
Paso 5: Entrégale a tu compañero la secuencia de números que codifica tu palabra secreta, y tu compañero te entregará la suya.
Paso 6: Descifra las palabras del otro usando sustracción módulo 26.
Paso 7: Verifica. ¿Funciónó?

Seguimiento

Intercambia palabras cifradas con otro grupo que no tenga acceso a tu bloc de uso único. ¿Puedes descifrarlas? Explica por qué sí o por qué no.

Con suerte, la actividad anterior deja claro que un bloc de uso único es una forma de cifrado irrompible, dadas algunas suposiciones, como:

  • La clave tiene la misma longitud que el mensaje que se envía, o mayor
  • La clave es verdaderamente aleatoria
  • La clave se usa solo una vez y luego se descarta

Así que esto es genial. Tenemos un cifrado irrompible... a menos que alguien obtenga nuestra clave. Si alguien obtiene nuestra clave, todo queda descifrado. Esta diferencia entre un cifrado irrompible y tener todos nuestros secretos expuestos hace que compartir una clave segura sea extremadamente importante. El objetivo de la distribución cuántica de claves es aprovechar las restricciones que la naturaleza ha impuesto sobre la información cuántica para asegurar una clave compartida o bloc de uso único.

Usar estados cuánticos como clave

Supongamos que estamos trabajando con qubits (haciendo hincapié en que los qubits tienen dos autoestados). Se podrían usar sistemas cuánticos con mayor número de estados cuánticos, pero las computadoras cuánticas más avanzadas de IBM® usan qubits. No hay ningún problema en codificar nuestras letras A, B, C en secuencias de 0s y 1s. Por tanto, es suficiente con compartir una clave de 0s y 1s y realizar adición módulo 2 en cada bit que almacena una letra.

Comprueba tu comprensión

Lee la pregunta a continuación, piensa en tu respuesta y luego haz clic en el triángulo para ver la solución.

Si realmente solo nos interesan las letras del inglés, ¿cuántos bits necesitamos?

Respuesta:

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

Nuestros amigos, Alice y Bob, quieren compartir una clave cuántica de tal manera que nadie más pueda interceptarla (al menos no sin que ellos lo sepan). Necesitan una forma de enviarse estados cuánticos entre sí. Hacerlo con alta fidelidad y sin ruido ni errores NO es trivial. Pero hay dos enfoques que deberíamos poder entender en este punto:

  1. Un cable de fibra óptica te permite enviar luz... que es muy cuántica. Los fotones individuales pueden detectarse con alta fidelidad a lo largo de muchos kilómetros de cable de fibra óptica. Este no es un canal cuántico perfecto y sin errores, pero podría ser muy bueno.
  2. Podríamos usar teleportación cuántica, como se describe en un módulo anterior. Es decir, Alice y Bob podrían compartir qubits entrelazados y un estado podría enviarse de Alice a Bob usando el protocolo de teleportación.

Para este módulo, no queremos exigirte configuraciones ópticas de alta fidelidad para compartir fotones, por lo que usaremos el segundo método para compartir estados cuánticos. Pero esto no quiere decir que sea el más realista para el intercambio de claves cuánticas a larga distancia.

Exploraremos ahora un protocolo establecido por primera vez por Charles Bennett y Gilles Brassard en 1984 para compartir estados medidos en diferentes bases de Alice a Bob. Usaremos un régimen de medición ingenioso para construir una clave para uso en el cifrado posterior. En otras palabras, estamos distribuyendo una clave cuántica entre dos partes que desean comunicarse, de ahí "distribución cuántica de claves" (QKD, por sus siglas en inglés).

Paso 1 de QKD: los bits y bases aleatorios de Alice

Alice comenzará generando una secuencia aleatoria de 0s y 1s. Luego seleccionará aleatoriamente una base en la que preparar un estado cuántico, basándose en cada bit aleatorio, usando la tabla a continuación (una tabla que Bob también tiene):

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

Por ejemplo, supongamos que Alice generó aleatoriamente un 0 y selecciónó aleatoriamente la base X. Entonces prepararía un estado cuántico ψ=+x=12(0+1)|\psi\rangle = |+\rangle_x = \frac{1}{\sqrt{2}}(|0\rangle+|1\rangle). Ciertamente se puede aprovechar la aleatoriedad cuántica para generar un conjunto aleatorio de 0s y 1s, y una elección aleatoria de base. Por ahora, simplemente asumamos que se ha generado un conjunto aleatorio, como sigue:

Bits de Alice010011010...
Bases de AliceXXZZZXZZX...
Estados de Alice+\vert +\rangle\vert -\rangle0\vert 0\rangle0\vert 0\rangle1\vert 1\rangle\vert -\rangle0\vert 0\rangle1\vert 1\rangle+\vert +\rangle...

Este conjunto de bits aleatorios, bases y estados resultantes continuaría en una larga secuencia para proporcionar una clave de longitud suficiente.

Paso 2 de QKD: las bases aleatorias de Bob

Bob también hace una elección aleatoria de bases. Sin embargo, mientras que Alice usaba la elección de base para preparar su estado, Bob realizará mediciones en estas bases. Si Bob hace una medición en la misma base en la que Alice preparó el estado, entonces podemos predecir el resultado de la medición de Bob. Cuando Bob elige una base diferente a la que Alice usó en la preparación, no podemos conocer el resultado de la medición de Bob.

Bits de Alice010011010...
Bases de AliceXXZZZXZZX...
Estados de 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...
Estados de Bob (a priori)+\vert +\rangle??0\vert 0\rangle?\vert -\rangle0\vert 0\rangle?+\vert +\rangle...
Estados de Bob (medidos)+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle+\vert +\rangle\vert -\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle...
En la tabla anterior, considera la primera columna. Alice ha preparado el estado +,\vert +\rangle, que es un autoestado de X. Como Bob también eligió aleatoriamente medir en la base X, solo hay un resultado posible para el estado medido por Bob: +.\vert +\rangle. En la segunda columna, sin embargo, han elegido bases diferentes. El estado que Alice envió es =12(01).\vert -\rangle = \frac{1}{\sqrt{2}}(\vert 0\rangle-\vert 1 \rangle). Esto tiene un 50% de probabilidad de ser medido por Bob en el estado 0\vert 0\rangle, y un 50% de probabilidad de ser medido en 1.\vert 1\rangle. Por eso la fila que muestra lo que sabemos, a priori, sobre las mediciones de Bob no puede completarse para la columna 2. Pero Bob hará una medición y obtendrá un autoestado de (en esa columna) Z. En la fila inferior, completamos lo que esas mediciones resultaron ser.

Paso 3 de QKD: discusión pública de bases

Alice y Bob pueden ahora compartir entre sí qué base eligieron en cada caso. Para todas las columnas en las que eligieron la misma base, cada uno sabe con certeza qué estado tenía el otro. Bob puede convertir el estado y la base en un 0 o un 1 según la convención compartida por ambas partes. Podemos reescribir la tabla anterior para mostrar solo los casos en que las bases de Alice y Bob coincidieron:

Bits de Alice00100...
Bases de AliceXZXZX...
Estados de Alice+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle+\vert +\rangle...
Bases de BobXZXZXX
Estados de Bob (a priori)+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle+\vert +\rangle...
Estados de Bob (medidos)+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle+\vert +\rangle...
Bits de Bob00100...

Alice ha transmitido con éxito la cadena de bits 00100... a Bob. Si los amigos acordaron de antemano usar cadenas de 5 bits como números en su bloc de uso único, estos primeros cinco bits les darían el número 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.

Paso 4 de QKD: verificar y enviar el secreto

Antes de que Alice y Bob vayan más lejos, deben elegir un subconjunto de sus bits clásicos para comparar. Como solo han conservado las mediciones de qubits que fueron preparados y medidos usando la misma base, todos los valores medidos deberían coincidir. Si un porcentaje muy pequeño no coincidiera, podría atribuirse al ruido cuántico o a errores. ¡Pero si muchos no coinciden, algo ha salido mal!

Aquí no abordaremos qué fracción de la clave debe usarse para la verificación. Por ahora, asumiremos que esta comprobación sale bien; revisitaremos esto en la sección siguiente sobre espionaje.

Los amigos enviarían entonces un mensaje cifrado entre sí usando canales clásicos. Luego usarían los números de su bloc de uso único para cifrar y descifrar mensajes secretos, sin transmitir nunca el bloc de uso único de una ubicación a otra. Para la siguiente sección sobre espionaje, ten en cuenta que todo este intercambio de la clave ocurre antes de la revelación del secreto cifrado a través de canales clásicos.

Alice y Bob comunicaron su elección de base a través de canales clásicos, ¿no podría eso interceptarse? ¡Sí! Pero conocer la base que usaron para la medición no te dice qué bit enviaron u obtuvieron. Eso solo es posible si también conoces los bits iniciales de Alice. Pero entonces estarías en la computadora de Alice, donde se almacenan los secretos, y la comunicación secreta de los secretos se vuelve irrelevante. Por tanto, la interceptación de la comunicación clásica no rompe el cifrado. ¿Pero qué pasa con la interceptación de información en el canal cuántico?

Resistencia de QKD al espionaje

Alice y Bob tienen una amiga, Eve, que es conocida por espiar. Eve desea interceptar la clave cuántica de Alice y Bob para poder usarla y descifrar los mensajes enviados entre los dos. Esto necesariamente ocurriría entre la preparación de los estados por parte de Alice y la medición de los estados por parte de Bob, ya que la medición colapsa el estado cuántico. En particular, esto significa que el espionaje tendría que ocurrir antes de que haya habido cualquier intercambio o comparación de bases.

Eve debe adivinar qué base se usó para codificar cada bit. De nuevo, si no puede acceder a la computadora de Alice, no tiene ninguna base para esta suposición, y será aleatoria. Supongamos que el punto de partida de Alice es el mismo que antes, y supongamos además que la elección aleatoria de base de medición de Bob es la misma que antes. Completemos lo que Eve obtiene si realiza mediciones del canal cuántico. Como antes, si Eve elige la misma base que Alice, sabemos lo que obtendrá. Si no, podría obtener cualquiera de dos resultados, cada uno con un 50% de probabilidad.

Bits de Alice010011010...
Bases de AliceXXZZZXZZX...
Estados de 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 adivinadas por EveZXXZXZZXX...
Estados de Eve (a priori)?\vert -\rangle?0\vert 0\rangle??0\vert 0\rangle?+\vert +\rangle...
Estados de Eve (medidos)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...

Ahora, como Eve no sabe si coincidió con la base de Alice o no, no sabe qué transmitirle a Bob para que coincida con los estados originales de Alice. Cuando Eve mide, por ejemplo, 0,|0\rangle, todo lo que sabe con certeza es que Alice no preparó el estado 1|1\rangle para ese qubit. Pero Alice podría haber preparado 0,|0\rangle, +|+\rangle o .|-\rangle. Todos son consistentes con la medición de Eve. Así que Eve debe tomar una decisión. Podría reenviar exactamente el estado que midió, o podría intentar adivinar los casos en que su medición no fue el autoestado enviado por Alice. Incluiremos una mezcla en nuestra tabla:

Bits de Alice010011010...
Bases de AliceXXZZZXZZX...
Estados de 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 adivinadas por EveZXXZXZZXX...
Estados de Eve (a priori)?\vert -\rangle?0\vert 0\rangle??0\vert 0\rangle?+\vert +\rangle...
Estados de Eve (medidos)1\vert 1\rangle\vert -\rangle+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle...
Estados de Eve (reenviados)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...
Estados de Bob (a priori)?0\vert 0\rangle?0\vert 0\rangle\vert -\rangle+\vert +\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle...
Estados de Bob (medidos)\vert -\rangle0\vert 0\rangle+\vert +\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle...
Bits de Bob100010010...

En este punto, es razonable preguntarse: "¿Por qué Eve no hace simplemente una copia del estado cuántico de Alice, se queda con una para medir y reenvía la otra a Bob?" La respuesta es el teorema de no clonación. De forma informal, establece que no existe ninguna operación unitaria (mecánico-cuántica) que pueda hacer una segunda copia de un estado cuántico arbitrario preservando la primera copia. La demostración es relativamente sencilla y se deja como ejercicio guiado. Pero por ahora, comprende que el hecho de que Eve haga copias del estado cuántico está prohibido por las leyes fundamentales de la naturaleza, y este es un principio clave de la fortaleza de QKD. Como antes, Alice y Bob se llamarían y compararían bases. Reducirán esta tabla a los casos en que los dos amigos seleccionaron las mismas bases:

Bits de Alice00100...
Bases de AliceXZXZX...
Estados de Alice+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle+\vert +\rangle...
Bases adivinadas por EveZZZZX...
Estados de Eve (a priori)?0\vert 0\rangle?0\vert 0\rangle+\vert +\rangle...
Estados de Eve (medidos)1\vert 1\rangle0\vert 0\rangle0\vert 0\rangle0\vert 0\rangle+\vert +\rangle...
Estados de Eve (reenviados)1\vert 1\rangle0\vert 0\rangle+\vert +\rangle0\vert 0\rangle0\vert 0\rangle...
Bases de BobXZXZX...
Estados de Bob (a priori)?0\vert 0\rangle+\vert +\rangle0\vert 0\rangle+\vert +\rangle...
Estados de Bob (medidos)\vert -\rangle0\vert 0\rangle+\vert +\rangle0\vert 0\rangle+\vert +\rangle...
Bits de Bob10000...

Alice y Bob han comunicado de nuevo una cadena de bits... pero las cadenas no coinciden. Los bits del extremo izquierdo y el central están invertidos. Mirando la tabla anterior, puedes rastrear esta discrepancia hasta la interferencia de Eve. Es fundamental notar que ahora podemos hacer estadísticas sobre la coincidencia entre nuestras cadenas de bits, mientras configuramos la clave, mucho antes de compartir nuestro secreto cifrado. Alice y Bob pueden usar tantos bits de su bloc de uso único como deseen para comprobar la seguridad de su canal. Si un único bit, o un porcentaje muy pequeño de bits no coincidiera, podría atribuirse al ruido o a errores. Pero una fracción sustancial de discrepancias indica espionaje. El significado de "sustancial" depende un poco del ruido del sistema que se utilice; lo que significa para las computadoras cuánticas de IBM® se explica a continuación cuando implementamos este protocolo. Si se detectan errores en exceso, Alice y Bob no comparten el secreto y pueden empezar a buscar al espía.

Advertencias

Demostrar la seguridad es extremadamente difícil. De hecho, el protocolo descrito aquí de forma aproximada fue propuesto en 1984 y no fue demostrado seguro hasta 16 años después Shor & Preskill, 2000. Hay muchos matices que van más allá del alcance de esta introducción. Pero listaremos brevemente algunos para demostrar que el tema es más complejo de lo que aquí se ilustra.

  • Canales seguros: Cuando Alice envía sus qubits a través de algún sistema cuántico (un canal), y en particular cuando recibe respuestas clásicas de alguien, hemos asumido que ese alguien es realmente Bob. Si Eve se infiltrara en este sistema de tal manera que toda la comunicación de Alice ocurriera en realidad con Eve, y toda la comunicación de Bob ocurriera en realidad con Eve, entonces Eve habría obtenido efectivamente una clave y podría conocer los secretos. Primero hay que garantizar "canales seguros", un proceso con un conjunto diferente de protocolos que no hemos abordado aquí.
  • Suposiciones sobre Eve: Para demostrar realmente la seguridad, no podemos hacer suposiciones sobre el comportamiento de Eve; siempre podría confundir nuestras expectativas. Aquí, para dar ejemplos concretos, estamos haciendo suposiciones. Por ejemplo, podríamos suponer que los estados que Eve reenvía a Bob son siempre exactamente los que obtuvo tras la medición. O podríamos suponer que elige aleatoriamente un estado experimentalmente consistente con su medición. Más fundamentalmente, el lenguaje aquí asume que Eve realmente realiza una medición, en lugar de almacenar el estado en otro sistema cuántico y reenviar un qubit aleatorio a Bob. Estas suposiciones son útiles para entender el protocolo, pero significan que no estamos demostrando nada en total generalidad.
  • Amplificación de privacidad: Alice y Bob no están obligados a usar la clave cuántica exactamente como fue transmitida. Pueden, por ejemplo, aplicar una función hash a la clave compartida. Esto aprovecharía el hecho de que el espía tiene un conocimiento incompleto de la clave para producir una clave compartida más corta pero segura.

Experimento 1: QKD sin espía

Implementemos el protocolo anterior en ausencia de un espía. Lo haremos primero usando un simulador, simplemente para entender el flujo de trabajo.

Primero, una nota sobre los simuladores cuánticos: la mayoría de los problemas cuánticos que involucran más de ~30 qubits no pueden ser simulados por la mayoría de las computadoras. Ninguna computadora clásica, supercomputadora o GPU puede simular el rango completo de comportamiento de una computadora cuántica de 127 qubits. Normalmente, la motivación para usar computadoras cuánticas reales es que los muchos qubits entrelazados no pueden simularse. En este caso no hay entrelazamiento de qubits, a menos que usemos el esquema de teletransportación para mover información. En este caso, la motivación para usar computadoras cuánticas reales es diferente: es el teorema de no-clonación. Una computadora clásica que simule un qubit podría enviar información sobre un estado cuántico de Alice a Bob, pero si esta información clásica fuera interceptada, podría duplicarse fácilmente, y Eve podría quedarse con una copia perfecta mientras envía otra a Bob. Esto no es posible con estados cuánticos reales.

IBM Quantum recomienda abordar los problemas de computación cuántica usando un marco que llamamos "patrones de Qiskit". Consiste en los siguientes pasos:

  • Paso 1: Mapea tu problema a un circuito cuántico
  • Paso 2: Optimiza tu circuito para ejecutarlo en hardware cuántico real
  • Paso 3: Ejecuta tu trabajo en las computadoras cuánticas de IBM usando primitivas de Runtime
  • Paso 4: Posprocesa los resultados

Paso 1 de los patrones de Qiskit: Mapear tu problema a un circuito cuántico

En este caso, el mapeo de nuestro problema a circuitos cuánticos se reduce simplemente a preparar los estados de Alice e incluir las mediciones de Bob. Comenzamos con la selección aleatoria de bits y 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)

Visualicemos los bits, las bases y el circuito. Ten en cuenta que a veces las bases coinciden y a veces no.

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.]

Salida de la celda de código anterior

Paso 2 de los patrones de Qiskit: Optimizar el problema para la ejecución cuántica

Este paso toma las operaciones que queremos realizar y las expresa en términos de la funcionalidad de una computadora cuántica específica. También mapea nuestro problema sobre el diseño de la computadora cuántica.

Comenzaremos cargando varios paquetes necesarios para comunicarnos con las computadoras cuánticas de IBM. También debemos seleccionar un backend en el que ejecutar. Podemos elegir el backend menos ocupado o seleccionar uno específico cuyas propiedades conocemos. Aunque en un momento usaremos un simulador, es importante usar un modelo de ruido razonable en la simulación, y conviene mantener el flujo de trabajo lo más cercano posible a lo que usaremos más adelante en computadoras cuánticas reales.

Más abajo hay código para guardar tus credenciales en el primer uso. Asegúrate de eliminar esta información del cuaderno después de guardarla en tu entorno, para que tus credenciales no se compartan accidentalmente cuando compartas el cuaderno. Consulta Configura tu cuenta de IBM Cloud e Inicializa el servicio en un entorno no confiable para obtener más orientación.

# 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

A continuación seleccionamos un simulador y un modelo de ruido.

# 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)

Paso 3 de los patrones de Qiskit: Ejecutar

Usa el sampler para ejecutar tu trabajo, con el circuito como argumento.

# 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()

Paso 4 de los patrones de Qiskit: Posprocesamiento

Aquí interpretamos nuestros resultados y extraemos información útil. Podríamos intentar visualizar la salida de nuestro sampler, pero lo hemos usado de una manera no convencional. En lugar de hacer muchas mediciones de nuestro circuito y desarrollar estadísticas sobre los estados, hemos hecho solo una medición (la de Bob). Cualquier qubit cuyo estado fue preparado y medido en la misma base debería tener un resultado determinista, de modo que solo se necesita una medición. Los qubits con estados preparados y medidos en bases diferentes (que tendrían resultados probabilísticos y requerirían muchas mediciones para interpretarse) no se usarán para construir nuestro bloc de notas de un solo uso/clave. Extraigamos una lista de resultados de medición de esta cadena de bits. Ten cuidado de invertir el orden si lo comparas con el arreglo de bits de Alice que usamos para generar el circuito.

# 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]

Comparemos las bases de medición elegidas al azar por Alice y Bob. Este fue el paso 3 en nuestro protocolo QKD (discusión pública de bases). Cada vez que eligieron la misma base para un qubit, añadimos los bits asociados a ese qubit a una lista de bits para generar números en un bloc de notas de un solo uso. Cuando las bases no coinciden, los resultados se descartan. Verifiquemos también si las dos listas de bits coinciden o si hubo alguna pérdida debida al ruido u otros factores.

# 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 y Bob tienen cada uno una lista de bits, y coinciden con una fidelidad del 100%. Pueden usarlos para generar números en un bloc de notas de un solo uso. Luego pueden usar esto en el paso 4 del QKD: enviar y descifrar un secreto. El arreglo de bits actual es demasiado corto para descifrar gran cosa. Volveremos a esto después de incluir el espionaje.

Verifica tu comprensión

Lee la pregunta de abajo, piensa en tu respuesta y luego haz clic en el triángulo para ver la solución.

Supón que necesitas dígitos lo suficientemente grandes como para facilitar el desplazamiento de letras en el alfabeto inglés por toda la longitud de ese alfabeto, o más, aunque ciertamente existen otros esquemas de codificación. (a) ¿Cuántas letras de largo podría ser un mensaje para descifrarlo usando los bits de la clave anterior? (b) ¿Tu respuesta debe coincidir con la de tus compañeros? ¿Por qué o por qué no?

Respuesta:

(a) La respuesta depende de cuántas bases elegidas al azar coincidieron entre Alice y Bob. Dado que hay aproximadamente un 50-50 de probabilidades de que las bases coincidan para cualquier qubit dado, esperamos que cerca de 10 de nuestros bits sean útiles. 9 u 11 serán perfectamente comunes. Incluso 4 o 15 no están fuera del ámbito de posibilidad. Se necesitan 5 bits para desplazar por un número mayor o igual a la longitud del alfabeto inglés, lo que significa que puedes aplicar el desplazamiento a una letra por cada 5 bits que tengas. Si tienes al menos 5 bits compartidos entre Alice y Bob, puedes codificar una sola letra. Si tienes al menos 10, puedes codificar 2 letras, y así sucesivamente. (b) No tiene por qué coincidir, por las razones expuestas en (a).

Experimento 2: QKD con un espía

Implementaremos exactamente el mismo protocolo que antes. Esta vez, insertaremos otro conjunto de mediciones, las de Eve, entre Alice y 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()

El paso 4 de los patrones de Qiskit (posprocesamiento) es sencillo en este caso. No es necesario visualizar la distribución de mediciones, ya que solo hicimos una medición. Eve tiene los siguientes 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)
[0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1]

Ahora Eve debe reconstruir los estados para enviarlos a Bob. Como se describe en la introducción, no tiene manera de saber si adivinó correctamente las bases de codificación, por lo que no puede preparar exactamente los mismos estados que se enviaron. Podría asumir que cada elección de base fue correcta y codificar exactamente lo que midió, o podría asumir que eligió la base incorrectamente y elegir cualquiera de los estados propios de la base opuesta. Aquí asumimos lo primero, por simplicidad. Logramos esto construyendo un circuito cuántico completamente nuevo, repitiendo los pasos de los patrones de Qiskit como antes.

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]

Comparemos ahora los bits de Alice y 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

Anteriormente había una coincidencia perfecta entre los bits de las claves de Alice y Bob. Ahora, debido a la interferencia de Eve, vemos que los bits de Alice y Bob difieren en el 14% de los casos que deberían coincidir porque Alice y Bob seleccionaron las mismas bases. Esto debería ser fácil de detectar para Alice y Bob. Sin embargo, depender de un porcentaje de errores como este implica que hay un límite de cuánto ruido podemos tolerar en el canal cuántico.

Experimento 3: Comparar QKD con y sin espionaje en una computadora cuántica real

Ejecutemos esto en una computadora cuántica real. Así podemos aprovechar el teorema de no clonación. Al mismo tiempo, las computadoras cuánticas reales tienen ruido y tasas de error más altas que las computadoras clásicas. Así que comparemos la pérdida de fidelidad de nuestros bits de clave con y sin espionaje, para asegurarnos de que la diferencia sea detectable al usar una computadora cuántica real. Empezaremos sin espionaje:

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

Sin espionaje, obtuvimos un 100% de fidelidad sobre este conjunto de 127 bits de prueba, lo que resultó en 55 bases coincidentes y bits de clave utilizables. Ahora repitamos este experimento con Eva escuchando:

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

¡Aquí encontramos casi un 23% de pérdida de fidelidad en los bits compartidos debido al espionaje! ¡Esto es muy detectable! Ten en cuenta que transferir información cuántica a grandes distancias podría igualmente introducir ruido y errores adicionales. Asegurar que el espionaje pueda detectarse incluso en presencia de ruido, e incluso cuando Eva usa todos los trucos a su disposición, es un campo complejo que va más allá de esta introducción.

Preguntas

Los instructores pueden solicitar versiones de estos notebooks con claves de respuesta y orientación sobre su ubicación en planes de estudio comunes rellenando esta encuesta rápida sobre cómo se están usando los notebooks.

Conceptos clave

  • La información cuántica no puede copiarse ni "clonarse".
  • puedes repetir el mismo proceso de preparación para crear un conjunto de estados cuánticos que sean todos iguales, o casi iguales.
  • Una clave de cifrado/descifrado (un bloc de notas de un solo uso) puede compartirse entre dos amigos usando estados cuánticos.
  • Cuando dos amigos eligen aleatoriamente una base de medición, la mitad de las veces elegirán de forma diferente y tendrán que descartar la información de esos qubits.
  • La elección aleatoria de la base de medición también garantiza que un espía no pueda conocer el estado inicial preparado y, por tanto, no pueda recrear el estado enviado. Esto asegura que el espionaje sea detectado.

Preguntas de verdadero/falso

  1. V/F En la distribución de claves cuánticas, los dos socios de comunicación miden cada qubit en la misma base.
  2. V/F Las leyes de la naturaleza impiden que un espía que intercepta información cuántica en QKD copie el estado cuántico que intercepta.
  3. V/F Un bloc de notas de un solo uso es una clave para cifrar/descifrar mensajes seguros en la que un esquema de codificación particular se usa solo una vez, para un único fragmento de información (como una letra del alfabeto).

Preguntas de opción múltiple

  1. Selecciona la opción que mejor completa el enunciado. Tal como se describe en este módulo, un bloc de notas de un solo uso es un conjunto de claves de cifrado/descifrado que se usa...
  • a. Solo una vez para un único fragmento de información, como una sola letra.
  • b. Solo una vez para un único mensaje.
  • c. Solo una vez durante un período de tiempo determinado, como un día.
  • d. Hasta que haya evidencia de espionaje.
  1. Supón que Alicia y Bob eligen sus bases de medición al azar. Miden. Luego comparten sus bases de medición y conservan solo los bits de información de los casos en que usaron la misma base. Dejando a un lado las fluctuaciones aleatorias, ¿aproximadamente qué porcentaje de sus qubits debería producir bits de información utilizables?
  • a. 100%
  • b. 50%
  • c. 25%
  • d. 12,5%
  • e. 0%
  1. Después de que Alicia y Bob seleccionan los casos en los que usaron las mismas bases de medición, ¿qué porcentaje de esos bits de información debería coincidir, si el ruido y los errores cuánticos fueran despreciables?
  • a. 100%
  • b. 50%
  • c. 25%
  • d. 12,5%
  • e. 0%
  1. Supón que Alicia ha elegido sus bases de medición al azar. Eva también elige sus bases al azar y escucha (mide). Envía a Bob estados consistentes con sus mediciones. Alicia y Bob comparan sus elecciones de base y conservan solo los qubits medidos/preparados por ellos en las mismas bases. Dejando a un lado las fluctuaciones aleatorias, ¿aproximadamente qué porcentaje de las mediciones de esos qubits conservados coincidirá, según Alicia y Bob?
  • a. 100%
  • b. 75%
  • c. 50%
  • d. 25%
  • e. 12,5%
  • f. 0%

Preguntas de debate

  1. Supón que todas las elecciones de base son aleatorias para todos los participantes: Alicia, Bob y Eva. Supón que después de que Eva escucha, envía a Bob un estado preparado en la misma base en que midió, y que es consistente con esa medición. Convence a tus compañeros de que el 12,5% de todos los qubits inicializados por Alicia producirán desajustes de medición entre Alicia y Bob, lo que indica espionaje (ignorando errores cuánticos y ruido). Pista 1: Como no hay ninguna base preferente, si consideras solo una elección inicial de Alicia, la proporción para esa elección debería ser la misma que la proporción para la suma de todas las elecciones. Pista 2: Puede no ser suficiente contar el número de formas en que algo podría ocurrir, ya que algunos resultados pueden darse con diferentes probabilidades.