Skip to main content
IBM Quantum Platform

Distribuzione quantistica delle chiavi

Per questo modulo Qiskit in Classrooms, gli studenti devono avere un ambiente Python funzionante con i seguenti pacchetti installati:

  • qiskit v2.1.0 o più recente
  • qiskit-ibm-runtime v0.40.1 o più recente
  • qiskit-aer v0.17.0 o più recente
  • qiskit.visualization
  • numpy
  • pylatexenc

Per configurare e installare i pacchetti di cui sopra, consultare la guida Installare Qiskit. Per poter eseguire lavori su veri computer quantistici, gli studenti dovranno creare un account con IBM Quantum® seguendo i passaggi della guida Set up your IBM Cloud account.

Questo modulo è stato testato e ha utilizzato 5 secondi di tempo della QPU. Si tratta solo di una stima. L'utilizzo effettivo può variare.

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

Guardate la spiegazione del modulo da parte della dottoressa Katie McCormick qui sotto, oppure fate clic qui per guardarla su YouTube.



Introduzione e motivazione

Esistono infiniti modi per criptare e decriptare le informazioni e migliaia di modi sono stati studiati a fondo. In questa sede ci limiteremo a un metodo di crittografia molto precoce e molto semplice, chiamato "sostituzione semplice", per concentrarci sulla parte quantistica di questo protocollo. La parte quantistica potrebbe essere adattata a molti altri protocolli con relativamente poche modifiche.

Semplice sostituzione

Una crittografia sostitutiva semplice è quella in cui una lettera o un numero viene sostituito con un altro, in modo tale che vi sia una corrispondenza 1:1 tra le lettere e i numeri presenti in un messaggio e le lettere e i numeri utilizzati in una sequenza crittografata. Un esempio di cultura pop è il criptoquote o criptogramma, in cui una citazione o una frase viene criptata con una semplice sostituzione e il giocatore ha il compito di decriptarla. Sono facili da risolvere se sono abbastanza lunghi. Consideriamo un esempio:

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.

Le persone che li risolvono a mano utilizzano per lo più trucchi che implicano una certa familiarità con la struttura del linguaggio del messaggio originale. Ad esempio, in inglese, le uniche parole di una lettera come la "R" criptata sono "a" e "I". Le lettere doppie criptate, ad esempio, in "KIVGGB" possono assumere solo determinati valori. Ci sono cose più sottili che danno indizi, come la parola più comune che si adatta al modello "GSZG" è "che". Chi usa il codice per risolvere questo problema ha molte più opzioni, tra cui la semplice scansione delle possibilità finché non viene recuperata una parola inglese, e l'aggiornamento mantenendo quella parola. Un metodo semplice ma efficace è l'utilizzo della frequenza delle lettere, soprattutto quando il messaggio è abbastanza lungo da costituire un campione rappresentativo della lingua inglese.

Domanda di check-in

Se vuoi, prova a decifrarlo, anche se non è necessario per il resto del modulo. Clicca su "Rispondi" qui sotto per visualizzare il messaggio.

  • Ho deciso che avrei fatto meglio a farla lunga. In questo modo, sarà più facile risolverlo. Spero di essere stato abbastanza semplice.

L'esempio precedente è associato a una "chiave", una mappatura dalle lettere criptate a quelle decriptate. In questo caso, la chiave è:

  • A (non utilizzato, chiamiamolo Z)
  • B->Y
  • C (non utilizzato, chiamiamolo X)
  • D->W
  • E->V
  • F->U
  • ...

E così via. Per usare un eufemismo, questa non è una buona chiave. Le chiavi in cui le lettere criptate e decriptate sono semplicemente versioni spostate dell'alfabeto (come A->B e B->C) sono chiamate cifrari "Caesar shift".

Si noti che questi sono molto difficili se sono corti. Infatti, se sono molto corti, sono indeterminati. Considerate:

URYYP

Esistono molte decrittazioni possibili, che utilizzano chiavi diverse: HELLO, PETTY, HAPPY, JIGGY, STOOL. Vi vengono in mente altri?

Ma se si inviano molti messaggi di questo tipo, alla fine la crittografia verrà violata. Quindi, non si dovrebbe usare la stessa "chiave" troppo spesso. In effetti, la cosa migliore è utilizzare una determinata sostituzione solo una volta. Non in un solo messaggio, ma solo per un singolo personaggio! Ciò significa che avrete uno schema o una chiave di crittografia per ogni carattere utilizzato nel messaggio, in ordine. Se volete inviare un messaggio a un amico utilizzando questo messaggio, voi e il vostro amico avrete bisogno di un blocchetto di carta (come si faceva una volta) su cui è scritta questa chiave sempre diversa. Lo userete una sola volta. Si tratta del cosiddetto "one-time pad".

Il blocco monouso

Vediamo come funziona con un esempio. Si potrebbe fare tutto questo con le lettere, ma è comune convertire le lettere in numeri, ad esempio assegnando A=0, B=1, C=2…. Supponiamo di essere amici coinvolti in attività clandestine e di aver condiviso un blocco. L'ideale sarebbe condividere molti pad, ma quello di oggi lo è:

EDGRPOJNCUWQZVMK.

Oppure, la conversione in numeri in base alla posizione nell'alfabeto:

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

Supponiamo di voler condividere con voi il messaggio:

"Amo il quantum!"

Oppure, in modo equivalente:

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

Non vogliamo inviare il codice di cui sopra; si tratta di una semplice sostituzione, che non è affatto sicura. Vogliamo combinarlo con la nostra chiave in qualche modo. Un modo comune è l'addizione modulo 26. Aggiungiamo il valore del messaggio al valore della chiave, mod 26, fino a raggiungere la fine del messaggio. Quindi, invieremo

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

Si noti che se qualcuno intercetta questo messaggio e NON ha la chiave, la decrittazione è del tutto inutile! Nemmeno le due "u" di "quantum" sono codificate con lo stesso numero! Il primo è un 3 e il secondo è un 16... nella stessa parola!

Quindi, vi mando questo, e voi avete la mia stessa chiave. Annullate l'addizione modulo 26 che sapete che ho eseguito:

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),.

Tale che il messaggio x1, x2, x3, x4… deve essere

8, 11, 14, 21.

Infine, convertendo il tutto in testo, abbiamo

"Amo i quanti".

Si tratta di un blocco unico.

Si noti che se la chiave è più corta del messaggio, si inizia a ripetere la codifica. Si tratterebbe comunque di un problema di decrittazione difficile da risolvere, ma non impossibile se ripetuto un numero sufficiente di volte. È quindi necessario un tasto lungo (o "pad").

Note

In molti contesti, gli studenti avranno già familiarità con questa crittografia, tanto che questa attività può essere saltata. Ma è un aggiornamento semplice e relativamente veloce.

Fase 1: prendete un compagno e condividete una sequenza di 4 lettere da usare come chiave. Va bene qualsiasi sequenza di 4 lettere appropriata alla classe. \ Fase 2: selezionare una parola segreta di 4 lettere da inviare al partner (entrambi i partner devono farlo, in modo da inviarsi parole segrete diverse) \ Fase 3: convertire la chiave/pad di 4 lettere e ciascuna delle parole segrete di 4 lettere in numeri utilizzando A = 1, B = 2 e così via. \ Fase 4: combinare la parola di 4 lettere con il one-time pad utilizzando l'addizione modulo 26. \ Fase 5: consegnate al vostro compagno la sequenza di numeri che codifica la vostra parola segreta e il vostro compagno vi consegnerà la sua. \ Fase 6: Decodificare le parole dell'altro usando la sottrazione modulo 26. \ Fase 7: verifica. Ha funzionato?

Traccia messaggio

Scambiate le parole criptate con un altro gruppo che non ha accesso al vostro one-time pad. Puoi decifrarlo? Spiegare perché o perché no?

Si spera che l'attività di cui sopra chiarisca che un one-time pad è una forma di crittografia infrangibile, date alcune ipotesi, come ad esempio:

  • La chiave è della stessa lunghezza del messaggio da inviare, o più lunga
  • La chiave è veramente casuale
  • La chiave viene utilizzata una sola volta e poi scartata

Quindi è fantastico. Abbiamo una crittografia infrangibile... a meno che qualcuno non prenda la nostra chiave. Se qualcuno ottiene la nostra chiave, tutto viene decriptato. Questa differenza tra una crittografia infrangibile e l'esposizione di tutti i nostri segreti rende estremamente importante la condivisione di una chiave sicura. L'obiettivo della distribuzione quantistica delle chiavi è quello di sfruttare i vincoli che la natura ha imposto alle informazioni quantistiche per proteggere una chiave condivisa/un time pad.


Utilizzo degli stati quantistici come chiave

Supponiamo di lavorare con i qubit (sottolineando che i qubit hanno due autostati). Si potrebbero usare sistemi quantistici con un numero maggiore di stati quantici, ma i computer quantistici all'avanguardia di IBM® usano i qubit. Non è un problema codificare i nostri A, B, C in sequenze di 0’s e 1’s. È quindi sufficiente condividere una chiave di 0’s e 1’s e fare l'addizione modulo 2 su ogni bit che contiene una lettera.

Verifica la tua comprensione

Se ci interessano solo le lettere inglesi, di quanti bit abbiamo bisogno?

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

I nostri amici Alice e Bob vorrebbero condividere una chiave quantistica in modo tale che nessun altro possa intercettarla (almeno non a loro insaputa). Devono avere un modo per inviarsi reciprocamente gli stati quantici. Fare questo con alta fedeltà e senza rumori/errori non è banale. Ma ci sono due approcci che dovremmo essere in grado di capire a questo punto:

  1. Un cavo a fibre ottiche permette di inviare luce... che è molto quantomeccanica. I singoli fotoni possono essere rilevati con alta fedeltà su molti chilometri di cavo in fibra ottica. Non si tratta di un canale quantistico perfetto e privo di errori, ma potrebbe essere molto buono.
  2. Potremmo usare il teletrasporto quantistico, come descritto in un modulo precedente. Cioè, Alice e Bob potrebbero condividere qubit entangled e uno stato potrebbe essere inviato da Alice a Bob utilizzando il protocollo di teletrasporto.

Per questo modulo, non vogliamo richiedere una configurazione ottica ad alta fedeltà per la condivisione dei fotoni, quindi utilizzeremo il secondo metodo per la condivisione degli stati quantistici. Ma questo non significa che sia il più realistico per la condivisione a distanza di chiavi quantistiche.

Ora analizzeremo un protocollo, elaborato per la prima volta da Charles Bennett e Gilles Brassard nel 1984, per la condivisione di stati misurati in basi diverse da Alice a Bob. Utilizzeremo un sistema di misurazione intelligente per costruire una chiave da utilizzare per la crittografia successiva. In altre parole, stiamo distribuendo una chiave quantistica tra due parti che desiderano comunicare, da cui "distribuzione di chiavi quantistiche" (QKD).

QKD fase 1: bit casuali e basi casuali di Alice

Alice comincerà generando una sequenza casuale di 0 e 1. Quindi sceglierà a caso una base in cui preparare uno stato quantistico, basato su ogni bit casuale, utilizzando la tabella sottostante (una tabella che ha anche Bob):

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

Ad esempio, supponiamo che Alice abbia generato a caso uno 0 e che abbia selezionato a caso la base X. Poi preparerebbe uno stato quantico ψ=+x=12(0+1)|\psi\rangle = |+\rangle_x = \frac{1}{\sqrt{2}}(|0\rangle+|1\rangle). Si può certamente sfruttare la casualità quantistica per generare un insieme casuale di 0 e 1 e una scelta casuale di basi. Per ora, supponiamo semplicemente che sia stato generato un insieme casuale, come segue:

I pezzi di Alice
0
1
0
0
1
1
0
1
0
...
Le basi di AliceXXZZZXZZX...
Gli stati di Alice+\vert +\rangle\vert -\rangle0\vert 0\rangle0\vert 0\rangle1\vert 1\rangle\vert -\rangle0\vert 0\rangle1\vert 1\rangle+\vert +\rangle...

Questa serie di bit casuali, basi e stati risultanti continuerebbe in una lunga sequenza, per dare una chiave di lunghezza sufficiente.

QKD fase 2: basi casuali di Bob

Bob effettua anche una scelta casuale delle basi. Tuttavia, mentre Alice utilizzava la scelta delle basi per preparare il suo stato, Bob effettuerà effettivamente delle misure in queste basi. Se Bob effettua una misurazione nella stessa base in cui Alice ha preparato lo stato, possiamo prevedere il risultato della misurazione di Bob. Se Bob sceglie una base diversa da quella utilizzata da Alice per la preparazione, non possiamo conoscere il risultato della misurazione di Bob.

I pezzi di Alice
0
1
0
0
1
1
0
1
0
...
Le basi di AliceXXZZZXZZX...
Gli stati di Alice+\vert +\rangle\vert -\rangle0\vert 0\rangle0\vert 0\rangle1\vert 1\rangle\vert -\rangle0\vert 0\rangle1\vert 1\rangle+\vert +\rangle...
Basi di BobXZXZXXZXX...
Stati di Bob (a priori)+\vert +\rangle??0\vert 0\rangle?\vert -\rangle0\vert 0\rangle?+\vert +\rangle...
Stati di Bob (misurati)+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle+\vert +\rangle\vert -\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle...

Nella tabella sottostante, considerate la prima colonna. Alice ha preparato lo stato +,\vert +\rangle, che è un autostato di X. Poiché anche Bob ha scelto casualmente di misurare nella base X, c'è un solo risultato possibile per lo stato misurato da Bob: +.\vert +\rangle. Nella seconda colonna, invece, i due hanno scelto basi diverse. Lo stato che Alice ha inviato è =12(01).\vert -\rangle = \frac{1}{\sqrt{2}}(\vert 0\rangle-\vert 1 \rangle). Questo ha il 50% di probabilità di essere misurato da Bob nello stato 0\vert 0\rangle e il 50% di probabilità di essere misurato in 1.\vert 1\rangle. Quindi la riga che mostra ciò che sappiamo, a priori, sulle misurazioni di Bob non può essere riempita per la colonna 2. Ma Bob effettuerà una misurazione e otterrà un autostato di Z (in quella colonna). Nella riga inferiore, inseriamo i risultati di queste misurazioni.

QKD fase 3: Discussione pubblica delle basi

Alice e Bob possono ora condividere tra loro la base che hanno scelto in ciascun caso. Per tutte le colonne in cui hanno scelto la stessa base, ciascuno sa con certezza quale stato aveva l'altro. Bob può convertire lo stato e la base in 0 o 1 secondo la convenzione condivisa da entrambe le parti. Possiamo riscrivere la tabella precedente per mostrare solo i casi in cui le basi di Alice e Bob coincidono:

I pezzi di Alice
0
0
1
0
0
...
Le basi di AliceXZXZX...
Gli stati di Alice+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle+\vert +\rangle...
Basi di BobXZXZXX...
Stati di Bob (a priori)+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle+\vert +\rangle...
Stati di Bob (misurati)+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle+\vert +\rangle...
I bit di Bob00100...

Alice ha trasmesso con successo la stringa di bit 00100... a Bob. Se gli amici hanno concordato in anticipo di utilizzare stringhe di 5 bit come numeri nel loro one-time pad, questi primi cinque bit darebbero loro il numero 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 fase 4: Verifica e invio del segreto

Prima di procedere, Alice e Bob devono scegliere un sottoinsieme dei loro bit classici da confrontare. Poiché sono state effettuate solo misure di qubit che sono stati preparati e misurati utilizzando la stessa base, tutti i valori misurati dovrebbero concordare. Se c'è una piccolissima percentuale che non concorda, ciò potrebbe essere attribuibile a rumore quantistico o a errori. Ma se molti non sono d'accordo, qualcosa è andato storto!

In questa sede non ci occuperemo di quale frazione della chiave debba essere utilizzata per la verifica. Per ora supponiamo che questo controllo vada bene; lo rivedremo nella sezione successiva sulle intercettazioni.

Gli amici si inviano quindi un messaggio criptato utilizzando i canali classici. In questo modo, i numeri del loro one-time pad verrebbero utilizzati per criptare/decriptare messaggi segreti, senza mai trasmettere il one-time pad da una postazione all'altra. Per la prossima sezione sulle intercettazioni, si tenga presente che tutta questa condivisione della chiave avviene prima della rivelazione del segreto criptato attraverso i canali classici.

Alice e Bob comunicano la loro base di scelta attraverso canali classici, quindi non potrebbero essere intercettati? Sì! Ma conoscere la base utilizzata per la misurazione non ci dice quale bit hanno inviato o ottenuto. Questo è possibile solo se si conoscono anche i bit di partenza di Alice. Ma allora sareste nel computer di Alice, dove sono memorizzati i segreti, e la comunicazione segreta dei segreti diventa inutile. Quindi l'intercettazione della comunicazione classica non rompe la crittografia. Ma che dire dell'intercettazione di informazioni nel canale quantistico?


Resistenza della QKD alle intercettazioni

Alice e Bob hanno un'amica, Eve, che è nota per le sue intercettazioni. Eve vuole intercettare la chiave quantistica di Alice e Bob, in modo da poterla utilizzare per decifrare i messaggi inviati tra i due. Ciò avverrebbe necessariamente tra la preparazione degli stati da parte di Alice e la misurazione degli stati da parte di Bob, poiché la misurazione fa collassare lo stato quantistico. In particolare, ciò significa che l'intercettazione dovrebbe avvenire prima di qualsiasi condivisione o confronto di basi.

Eve deve indovinare quale base è stata utilizzata per codificare ciascun bit. Anche in questo caso, se non è in grado di accedere al computer di Alice, non ha nulla su cui basare questa ipotesi e sarà casuale. Supponiamo che la partenza di Alice sia la stessa di prima e che la scelta casuale della base di misura da parte di Bob sia la stessa di prima. Vediamo cosa ottiene Eve se effettua misure del canale quantistico. Come in precedenza, se Eva sceglie la stessa base di Alice, sappiamo cosa otterrà. In caso contrario, potrebbe ottenere uno dei due risultati, ciascuno con una probabilità del 50%.

I pezzi di Alice
0
1
0
0
1
1
0
1
0
...
Le basi di AliceXXZZZXZZX...
Gli stati di Alice+\vert +\rangle\vert -\rangle0\vert 0\rangle0\vert 0\rangle1\vert 1\rangle\vert -\rangle0\vert 0\rangle1\vert 1\rangle+\vert +\rangle...
Basi di ipotesi di EveZXXZXZZXX...
Stati di Eva (a priori)?\vert -\rangle?0\vert 0\rangle??0\vert 0\rangle?+\vert +\rangle...
Stati di Eva (misurati)1\vert 1\rangle\vert -\rangle+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle...
Basi di BobXZXZXXZXX...

Ora, poiché Eve non ha idea se abbia o meno trovato una corrispondenza con la base di Alice, non sa cosa trasmettere a Bob per ottenere una corrispondenza con gli stati originali di Alice. Quando Eve misura, ad esempio, 0,|0\rangle, sa con certezza che Alice non ha preparato lo stato 1|1\rangle per quel qubit. Ma Alice potrebbe aver preparato 0,|0\rangle, +,|+\rangle, o .|-\rangle. Tutto potrebbe essere coerente con la misurazione di Eva. Eva deve quindi fare una scelta. Potrebbe inviare esattamente lo stato che ha misurato, oppure potrebbe cercare di indovinare i casi in cui la sua misurazione non è l'autostato inviato da Alice. Includeremo una miscela nella nostra tavola:

I pezzi di Alice
0
1
0
0
1
1
0
1
0
...
Le basi di AliceXXZZZXZZX...
Gli stati di Alice+\vert +\rangle\vert -\rangle0\vert 0\rangle0\vert 0\rangle1\vert 1\rangle\vert -\rangle0\vert 0\rangle1\vert 1\rangle+\vert +\rangle...
Basi di ipotesi di EveZXXZXZZXX...
Stati di Eva (a priori)?\vert -\rangle?0\vert 0\rangle??0\vert 0\rangle?+\vert +\rangle...
Stati di Eva (misurati)1\vert 1\rangle\vert -\rangle+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle...
Stati di Eva (inviati)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...
Basi di BobXZXZXXZXX...
Stati di Bob (a priori)?0\vert 0\rangle?0\vert 0\rangle\vert -\rangle+\vert +\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle...
Stati di Bob (misurati)\vert -\rangle0\vert 0\rangle+\vert +\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle...
I bit di Bob100010010...

A questo punto, è ragionevole chiedersi: "Perché Eve non fa una copia dello stato quantico di Alice, ne conserva una per misurarla e trasmette l'altra a Bob?" La risposta è il teorema di non clonazione. Informalmente, dice che non esiste un'operazione unitaria (meccanica quantistica) che possa creare una seconda copia di uno stato quantistico arbitrario, preservando la prima copia. La prova è relativamente semplice e viene lasciata come esercizio guidato. Per il momento, però, è bene capire che la creazione di copie dello stato quantistico da parte di Eve è proibita dalle leggi fondamentali della natura, e questo è un principio di forza del QKD.

Come in precedenza, Alice e Bob si chiamano a vicenda e confrontano le basi. Ridurranno questa tabella ai casi in cui i due amici hanno selezionato le stesse basi:

I pezzi di Alice
0
0
1
0
0
...
Le basi di AliceXZXZX...
Gli stati di Alice+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle+\vert +\rangle...
Basi di ipotesi di EveZZZZX...
Stati di Eva (a priori)?0\vert 0\rangle?0\vert 0\rangle+\vert +\rangle...
Stati di Eva (misurati)1\vert 1\rangle0\vert 0\rangle0\vert 0\rangle0\vert 0\rangle+\vert +\rangle...
Stati di Eva (inviati)1\vert 1\rangle0\vert 0\rangle+\vert +\rangle0\vert 0\rangle0\vert 0\rangle...
Basi di BobXZXZX...
Stati di Bob (a priori)?0\vert 0\rangle+\vert +\rangle0\vert 0\rangle+\vert +\rangle...
Stati di Bob (misurati)\vert -\rangle0\vert 0\rangle+\vert +\rangle0\vert 0\rangle+\vert +\rangle...
I bit di Bob10000...

Alice e Bob hanno comunicato ancora una volta una stringa di bit... ma le stringhe non corrispondono. I bit all'estrema sinistra e al centro sono invertiti. Osservando la tabella precedente, è possibile risalire a questa mancata corrispondenza con le interferenze di Eve. È importante notare che possiamo effettuare statistiche sulla corrispondenza tra le nostre stringhe di bit ora, mentre impostiamo la chiave, molto prima di condividere il nostro segreto crittografato. Alice e Bob sono liberi di utilizzare tutti i bit del loro one-time pad che desiderano per verificare la sicurezza del loro canale. Se un singolo bit, o una percentuale molto piccola di bit, non corrisponde, ciò potrebbe essere attribuibile a rumore o errori. Tuttavia, una frazione sostanziale di errori di corrispondenza indica la presenza di intercettazioni. Il significato di "sostanziale" in questo caso dipende un po' dal rumore della configurazione utilizzata; cosa significhi per i computer quantistici di IBM® verrà discusso più avanti, quando implementeremo questo protocollo. Se vengono rilevati errori in eccesso, Alice e Bob non condividono il segreto e possono iniziare a dare la caccia all'intercettatore.

Avvertenze

Dimostrare la sicurezza è estremamente difficile. In effetti, il protocollo vagamente descritto in questa sede è stato proposto nel 1984 e si è dimostrato sicuro solo 16 anni più tardi Shor & Preskill, 2000. Ci sono molte sottigliezze che esulano dallo scopo di questa introduzione. Ma ne elencheremo brevemente alcuni per dimostrare che l'argomento è più complesso di quanto illustrato in questa sede.

  • Canali sicuri: Quando Alice invia i suoi qubit attraverso una qualche configurazione quantistica (un canale), e in particolare quando riceve risposte classiche da qualcuno, abbiamo assunto che quel qualcuno sia in realtà Bob. Se Eve si è infiltrata in questa configurazione in modo tale che tutte le comunicazioni di Alice avvengano con Eve e che tutte le comunicazioni di Bob avvengano con Eve, allora Eve ha effettivamente ottenuto una chiave e può imparare i segreti. Bisogna innanzitutto garantire la sicurezza dei "canali", un processo che prevede una serie di protocolli diversi che non abbiamo affrontato in questa sede.
  • Ipotesi su Eve: Per dimostrare veramente la sicurezza, non possiamo fare ipotesi sul comportamento di Eva; potrebbe sempre confondere le nostre aspettative. Qui, per fare degli esempi concreti, stiamo facendo delle ipotesi. Ad esempio, si potrebbe ipotizzare che gli stati che Eve invia a Bob siano sempre esattamente quelli ottenuti al momento della misurazione. Oppure potremmo ipotizzare che scelga a caso uno stato sperimentalmente coerente con la sua misurazione. Più fondamentalmente, il linguaggio qui utilizzato presuppone che Eve effettui effettivamente una misurazione, invece di memorizzare lo stato su un altro sistema quantistico e inviare un qubit casuale a Bob. Queste assunzioni vanno bene per comprendere il protocollo, ma significano che non stiamo dimostrando nulla in tutta generalità.
  • Amplificazione della privacy: Alice e Bob non sono tenuti a utilizzare la chiave quantistica esattamente come è stata trasmessa. Possono, ad esempio, applicare una funzione di hash alla chiave condivisa. In questo modo si sfrutterebbe il fatto che l'intercettatore ha una conoscenza incompleta della chiave per produrre una chiave condivisa più breve, ma sicura.

Esperimento 1: QKD senza intercettazioni

Implementiamo il protocollo di cui sopra in assenza di un eavesdropper. Lo faremo prima utilizzando un simulatore, semplicemente per capire il flusso di lavoro.

Innanzitutto, una nota sui simulatori quantistici: La maggior parte dei problemi quantistici che coinvolgono più di 30 qubit non può essere simulata dalla maggior parte dei computer. Nessun computer classico, supercomputer o GPU può simulare l'intera gamma di comportamenti di un computer quantistico a 127 qubit. Di solito, la motivazione per l'utilizzo di computer quantistici reali è che i molti qubit entangled non possono essere simulati. In questo caso, non c'è entanglement dei qubit, a meno che non si utilizzi lo schema del teletrasporto per spostare le informazioni. In questo caso, la motivazione per l'utilizzo di veri computer quantistici è diversa: si tratta del teorema di non clonazione. Un computer classico che simula un qubit potrebbe inviare informazioni su uno stato quantistico da Alice a Bob, ma se queste informazioni classiche venissero intercettate, potrebbero essere facilmente duplicate ed Eva potrebbe conservarne una copia perfetta, inviandone un'altra a Bob. Questo non è possibile con gli stati quantistici reali.

IBM Quantum raccomanda di affrontare i problemi di calcolo quantistico utilizzando un quadro che chiamiamo "modelli Qiskit". Si compone delle seguenti fasi.

  • Fase 1: mappare il problema in un circuito quantistico
  • Fase 2: Ottimizzazione del circuito per l'esecuzione su hardware quantistico reale
  • Passo 3: Eseguire il lavoro sui computer quantistici di IBM utilizzando le primitive di Runtime
  • Fase 4: Postelaborazione dei risultati

Modelli Qiskit fase 1: mappare il problema su un circuito quantistico

In questo caso, la mappatura del nostro problema sui circuiti quantistici si riduce alla semplice preparazione degli stati di Alice e all'inclusione delle misure di Bob. Iniziamo con la selezione casuale dei bit e delle basi.

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

Visualizziamo i bit, le basi e il circuito. Si noti che a volte le basi corrispondono e a volte no.

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

Output:

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.]
Output of the previous code cell

Modelli Qiskit fase 2: ottimizzazione del problema per l'esecuzione quantistica

Questa fase prende le operazioni che vogliamo eseguire e le esprime in termini di funzionalità di uno specifico computer quantistico. Inoltre, il nostro problema è stato tracciato sul layout del computer quantistico.

Inizieremo caricando diversi pacchetti che sono necessari per comunicare con i computer quantistici di IBM. Dobbiamo anche selezionare un backend su cui eseguire l'operazione. Possiamo scegliere il backend meno trafficato, oppure selezionare un backend specifico di cui conosciamo le proprietà. Anche se utilizzeremo momentaneamente un simulatore, è importante utilizzare un modello di rumore ragionevole nella simulazione ed è bene mantenere il flusso di lavoro il più vicino possibile a quello che utilizzeremo in seguito per i computer quantistici reali.

Di seguito è riportato un codice per salvare le credenziali al primo utilizzo. Assicurarsi di eliminare queste informazioni dal blocco note dopo averlo salvato nel proprio ambiente, in modo che le credenziali non vengano accidentalmente condivise quando si condivide il blocco note. Per ulteriori informazioni, vedere Configurazione dell'account IBM Cloud e Inizializzazione del servizio in un ambiente non attendibile.

# Load IBM Quantum Compute Service
from qiskit_ibm_runtime import QiskitRuntimeService

# Load IBM Quantum Compute 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)

Output:

ibm_brisbane

Di seguito selezioniamo un simulatore e un modello di rumore.

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

Modelli Qiskit fase 3: Esecuzione

Utilizzare il campionatore per eseguire il lavoro, con il circuito come argomento.

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

Modelli Qiskit fase 4: Post-elaborazione

Qui interpretiamo i nostri risultati ed estraiamo informazioni utili. Potremmo provare a visualizzare l'output del nostro campionatore, ma abbiamo usato il campionatore in modo non convenzionale. Invece di effettuare molte misure del nostro circuito e sviluppare statistiche sugli stati, abbiamo effettuato una sola misura (quella di Bob). Qualsiasi qubit con uno stato preparato e misurato con la stessa base dovrebbe avere un risultato deterministico, tale da richiedere una sola misurazione. Quei qubit con stati preparati e misurati in basi diverse (che avrebbero esiti probabilistici e richiederebbero molte misure per essere interpretati) non saranno utilizzati per costruire il nostro one-time pad/chiave.

Estraiamo da questa stringa di bit un elenco di risultati di misura. Fare attenzione a invertire l'ordine se si confronta con la matrice di bit di Alice che abbiamo usato per generare il 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)

Output:

[1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0]

Confrontiamo le basi di misura scelte a caso da Alice e Bob. Questa era la fase 3 del nostro protocollo QKD (discussione pubblica delle basi). Ogni volta che scelgono la stessa base per un qubit, aggiungiamo i bit associati a quel qubit a un elenco di bit per la generazione di numeri in un one-time pad. Se le basi non coincidono, i risultati vengono scartati. Controlliamo anche se i due elenchi di bit sono in accordo o se ci sono state perdite dovute al rumore o ad altri fattori.

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

Output:

[1, 0, 1, 0, 0, 0, 1, 0]
[1, 0, 1, 0, 0, 0, 1, 0]
fidelity =  1.0
loss =  0.0

Alice e Bob hanno ciascuno un elenco di bit, che corrispondono con una fedeltà del 100%. Possono usarli per generare numeri in un one-time pad. Possono quindi utilizzarlo nella fase 4 del QKD: invio e decrittazione di un segreto. L'attuale serie di bit è troppo corta per decriptare qualcosa. Torneremo su questo argomento dopo aver incluso le intercettazioni.

Verifica la tua comprensione

Si suppone che occorrano cifre abbastanza grandi da facilitare lo spostamento delle lettere dell'alfabeto inglese per l'intera lunghezza dell'alfabeto, o anche di più, anche se esistono sicuramente altri schemi di codifica. (a) Quante lettere può avere un messaggio per essere decifrato usando i bit della chiave di cui sopra? (b) La vostra risposta deve essere in accordo con quella dei vostri compagni di classe? Perché o perché no?

  • (a) La risposta dipende dal numero di basi, scelte a caso, che coincidono tra Alice e Bob. Dato che per ogni singolo qubit la probabilità che le basi coincidano è all’incirca del 50%, ci aspettiamo che circa 10 dei nostri bit siano utilizzabili. 9 o 11 saranno del tutto normali. Anche 4 o 15 non sono da escludere. Sono necessari 5 bit per effettuare uno spostamento pari o superiore alla lunghezza dell'alfabeto inglese, il che significa che è possibile applicare lo spostamento a una lettera ogni 5 bit disponibili. Se Alice e Bob condividono almeno 5 bit, è possibile codificare una singola lettera. Se ne hai almeno 10, puoi codificare 2 lettere, e così via.

    (b) Non è necessario che sia d’accordo, per i motivi esposti al punto (a).


Esperimento 2: QKD con un intercettatore

Implementeremo esattamente lo stesso protocollo di prima. Questa volta, inseriremo un'altra serie di misurazioni, effettuate da Eve, tra Alice e 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()

Il passo 4 dei modelli Qiskit (post-elaborazione) è semplice in questo caso. Non è necessario visualizzare la distribuzione delle misure, poiché abbiamo effettuato una sola misurazione. Eve ha i seguenti bit:

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)

Output:

[0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1]

Ora Eve deve ricostruire gli stati da inviare a Bob. Come descritto nell'introduzione, non ha modo di sapere se ha indovinato correttamente le basi di codifica, quindi non è in grado di preparare esattamente gli stessi stati che sono stati inviati. Potrebbe supporre che ogni scelta di base sia corretta e codificare esattamente ciò che ha misurato, oppure potrebbe supporre di aver scelto la base in modo errato e scegliere uno dei due autostati della base opposta. In questa sede, per semplicità, assumiamo la prima ipotesi. A questo scopo costruiamo un circuito quantistico completamente nuovo, ripetendo i passaggi dello schema Qiskit come in precedenza.

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)

Output:

[0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1]

Confrontiamo ora i bit di Alice e 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))

Output:

[1, 1, 0, 0, 0, 1, 1]
[1, 1, 0, 0, 0, 0, 1]
fidelity =  0.8571428571428571
loss =  0.1428571428571429

In precedenza, vi era una perfetta corrispondenza tra i bit delle chiavi di Alice e di Bob. Ora, dall'interferenza di Eve, vediamo che i bit di Alice e Bob sono diversi nel 14% dei casi che dovrebbero coincidere, perché Alice e Bob hanno selezionato le stesse basi. Questo dovrebbe essere facile da rilevare per Alice e Bob. Tuttavia, affidarsi a una percentuale di errori come questa significa che c'è un limite alla quantità di rumore che possiamo tollerare nel canale quantistico.


Esperimento 3: Confronto tra QKD con e senza intercettazione su un vero computer quantistico

Eseguiamolo su un vero computer quantistico. In questo modo possiamo sfruttare il teorema di non clonazione. Allo stesso tempo, i computer quantistici reali sono affetti da rumore e presentano tassi di errore più elevati rispetto ai computer classici. Confrontiamo quindi la perdita di fedeltà dei nostri bit chiave con e senza intercettazioni, per assicurarci che la differenza sia rilevabile quando si utilizza un vero computer quantistico. Inizieremo in assenza di intercettazioni:

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

Output:

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

Senza intercettazioni, abbiamo ottenuto il 100% di fedeltà su questa serie di 127 bit di prova, ottenendo 55 basi corrispondenti e bit di chiave utilizzabili. Ora ripetiamo questo esperimento con Eve in ascolto:

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

Output:

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

In questo caso abbiamo riscontrato una perdita di fedeltà di quasi il 23% nei bit condivisi a causa delle intercettazioni! Questo è molto rilevabile! Si noti che il trasferimento di informazioni quantistiche su lunghe distanze potrebbe comunque introdurre rumore ed errori aggiuntivi. Garantire che le intercettazioni possano essere rilevate, anche in presenza di rumore e anche quando Eve utilizza tutti i trucchi a sua disposizione, è un campo complesso che esula da questa introduzione.


Domande

Gli insegnanti possono richiedere le versioni di questi quaderni con le chiavi di risposta e le indicazioni per l'inserimento nei curricula comuni compilando questo rapido sondaggio sull'utilizzo dei quaderni.

Concetti fondamentali

  • Le informazioni quantistiche non possono essere copiate o "clonate".
  • È possibile ripetere lo stesso processo di preparazione per ottenere un insieme di stati quantici tutti uguali o quasi.
  • Una chiave di crittografia/decrittografia (un one-time pad) può essere condivisa tra due amici utilizzando gli stati quantici.
  • Due amici che scelgono a caso una base di misura significa che per metà del tempo sceglieranno in modo diverso e dovranno buttare via le informazioni su quei qubit.
  • La scelta casuale della base di misura garantisce inoltre che un intercettatore non possa conoscere lo stato iniziale preparato e quindi non possa ricreare lo stato inviato. In questo modo si garantisce che l'intercettazione venga rilevata.

Domande vero/falso

  1. T/F Nella distribuzione quantistica delle chiavi, i due partner comunicanti misurano ogni qubit nella stessa base.
  2. T/F Un intercettatore che intercetta informazioni quantistiche in QKD è impossibilitato dalle leggi della natura a copiare lo stato quantistico che intercetta.
  3. T/F Un one-time pad è una chiave per criptare/decriptare messaggi sicuri in cui un particolare schema di codifica viene utilizzato una sola volta, per una singola informazione (come una lettera dell'alfabeto).

Domande del presentatore

  1. Selezionare l'opzione che meglio completa l'affermazione. Come descritto in questo modulo, un one-time pad è un insieme di chiavi di crittografia/decrittografia che viene utilizzato...
  • a. Solo una volta per una singola informazione, come una singola lettera.
  • b. Solo una volta per un singolo messaggio.
  • c. Solo una volta per un periodo di tempo prestabilito, ad esempio un giorno.
  • d. Finché non ci sono prove di intercettazioni.
  1. Supponiamo che Alice e Bob scelgano le loro basi di misura in modo casuale. Misurano. Poi condividono le loro basi di misura e conservano solo le informazioni dei casi in cui hanno usato la stessa base. Fino a una certa fluttuazione casuale, approssimativamente quale percentuale dei loro qubit dovrebbe produrre bit di informazione utilizzabili?
  • a. 100%
  • b. Il 50%
  • c. 25%
  • d. 12.5%
  • e. 0%
  1. Dopo che Alice e Bob hanno selezionato i casi in cui hanno usato le stesse basi di misura, quale percentuale di quei bit di informazione dovrebbe corrispondere, se il rumore quantistico e gli errori sono trascurabili?
  • a. 100%
  • b. Il 50%
  • c. 25%
  • d. 12.5%
  • e. 0%
  1. Supponiamo che Alice abbia scelto le sue basi di misura in modo casuale. Anche Eve sceglie le sue basi in modo casuale e ascolta (misure). Invia a Bob gli stati che sono coerenti con le sue misure. Alice e Bob confrontano le scelte delle basi e mantengono solo i qubit da loro misurati/preparati nelle stesse basi. Fino a una certa fluttuazione casuale, approssimativamente quale percentuale di queste misure di qubit mantenute corrisponderà, secondo Alice e Bob?
  • a. 100%
  • b. il 75%
  • c. Il 50%
  • d. 25%
  • e. 12.5%
  • f. 0%

Domande di discussione

  1. Si supponga che tutte le scelte di base siano casuali per tutti i partecipanti, Alice, Bob ed Eve. Supponiamo che Eve, dopo aver ascoltato, invii a Bob uno stato preparato nella stessa base in cui ha effettuato la misurazione e che sia coerente con la misurazione stessa. Convincete i vostri interlocutori che 12.5 % di tutti i qubit inizializzati da Alice produrrà delle discrepanze di misura tra Alice e Bob, indicando un'intercettazione (ignorando gli errori quantistici e il rumore). Suggerimento 1: Poiché non esiste una base preferita, se si considera una sola scelta iniziale per Alice, il rapporto per quella scelta dovrebbe essere uguale al rapporto per la somma di tutte le scelte. Suggerimento 2: Potrebbe non essere sufficiente contare il numero di modi in cui qualcosa potrebbe accadere, poiché alcuni risultati possono verificarsi con probabilità diverse.

  2. Supponiamo ancora una volta che tutte le scelte di base siano casuali per tutti i partecipanti, Alice, Bob ed Eve. Ma ora, considerate che Eva è libera di mandare con sé qualsiasi stato che desideri dopo la sua misurazione. Potrebbe anche provare a inviare stati che non sono coerenti con le sue misure. Discutete con i vostri compagni/vicini se ritenete che esista una scelta di basi che possa ridurre la percentuale media di qubit che indicano l'intercettazione ad Alice e Bob.

Questa pagina è stata utile?
Segnala un bug, un errore di battitura o richiedi contenuti su GitHub.