Distribuția cuantică a cheilor
Pentru acest modul Qiskit in Classrooms, studenții trebuie să aibă un mediu Python funcțional cu următoarele pachete instalate:
qiskitv2.1.0 sau mai nouqiskit-ibm-runtimev0.40.1 sau mai nouqiskit-aerv0.17.0 sau mai nouqiskit.visualizationnumpypylatexenc
Pentru a configura și instala pachetele de mai sus, consultați ghidul Instalează Qiskit. Pentru a rula joburi pe calculatoare cuantice reale, studenții vor trebui să-și creeze un cont la IBM Quantum® urmând pașii din ghidul Configurează-ți contul IBM Cloud.
Acest modul a fost testat și a utilizat 5 secunde de timp QPU. Aceasta este doar o estimare. Utilizarea ta reală poate varia.
# 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'
Urmărește prezentarea modulului de Dr. Katie McCormick mai jos sau apasă aici pentru a o viziona pe YouTube.
Introducere și motivație
Există infinit de multe moduri de a cripta și decripta informații, și literalmente mii de metode au fost studiate în detaliu. Aici, ne vom limita la o metodă de criptare foarte veche și foarte simplă, numită „substituție simplă", pentru a ne putea concentra pe partea cuantică a acestui protocol. Partea cuantică ar putea fi adaptată la multe alte protocoale cu relativ puține modificări.
Substituția simplă
O criptare prin substituție simplă este una în care o literă sau un număr este înlocuit cu altul, astfel încât există o mapare 1:1 de la literele și numerele dintr-un mesaj la literele și numerele folosite într-o secvență criptată. Un exemplu din cultura populară îl reprezintă puzzle-ul cryptoquote sau cryptogram, în care un citat sau o frază este criptat prin substituție simplă, iar jucătorul are sarcina de a-l decripta. Acestea sunt ușor de rezolvat dacă sunt suficient de lungi. Consideră exemplul:
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.
Persoanele care rezolvă aceste puzzle-uri manual folosesc în principal trucuri bazate pe familiaritatea cu structura limbii mesajului original. De exemplu, în engleză, singurele cuvinte formate dintr-o singură literă, cum ar fi „R" criptat, sunt „a" și „I". Literele duble criptate din, de exemplu, „KIVGGB" pot lua doar anumite valori. Există indicii mai subtile, cum ar fi faptul că cel mai frecvent cuvânt care se potrivește tipărului „GSZG" este „that". Persoanele care folosesc cod pentru a rezolva aceste puzzle-uri au mult mai multe opțiuni, inclusiv simpla parcurgere a posibilităților până când se recuperează un cuvânt în engleză, și actualizarea păstrând acel cuvânt. O metodă simplă dar puternică este utilizarea frecvenței literelor, mai ales când mesajul este suficient de lung pentru a constitui un eșantion reprezentativ al limbii engleze.
Întrebare de verificare
Încearcă să decriptezi mesajul dacă dorești, deși nu este necesar pentru restul modulului. Apasă pe triunghi pentru a vedea mesajul.
Răspuns:
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.
Exemplul de mai sus este asociat cu o „cheie", o mapare de la literele criptate la literele decriptate. În acest caz, cheia este:
- A (nefolosit, să-l numim Z)
- B->Y
- C (nefolosit, să-l numim X)
- D->W
- E->V
- F->U
- ...
Și așa mai departe. Ca să spunem ușor, aceasta nu este o cheie bună. Cheile în care literele criptate și decriptate sunt pur și simplu versiuni decalate ale alfabetului (cum ar fi A->B și B->C) se numesc cifruri „Caesar shift".
Reține că acestea sunt foarte dificil de spart dacă sunt scurte. De fapt, dacă sunt foarte scurte, sunt nedeterminate. Consideră:
URYYP
Există multe decriptări posibile, folosind chei diferite: HELLO, PETTY, HAPPY, JIGGY, STOOL. Te poți gândi la altele?
Dar dacă trimiți multe mesaje de acest fel, în cele din urmă, criptarea va fi spartă. Deci, nu ar trebui să folosești aceeași „cheie" prea des. De fapt, cel mai bine este să folosești o anumită substituție o singură dată. Nu doar într-un singur mesaj, ci doar pentru un singur caracter! Prin aceasta, înțelegem că vei avea o schemă de criptare sau cheie pentru fiecare caracter folosit în mesaj, în ordine. Dacă vrei să trimiți un mesaj unui prieten folosind această schemă, tu și prietenul tău ați avea nevoie de un carnet de hârtie (în vremurile vechi) pe care această cheie în continuă schimbare este scrisă. O vei folosi o singură dată. Aceasta se numește „pad de unică folosință" (one-time pad).
Pad-ul de unică folosință
Să vedem cum funcționează asta cu un exemplu. S-ar putea face asta în întregime cu litere, dar este obișnuit să convertim de la litere la numere, să zicem, atribuind A=0, B=1, C=2…. Să presupunem că suntem prieteni implicați în activități clandestine și am partajat un carnet. În mod ideal, am partaja mai multe carnete, dar cel de astăzi este:
EDGRPOJNCUWQZVMK…
Sau, convertind la numere după poziția în alfabet:
4,3,6,17,15, 14, 9, 13, 2, 20, 22, 16, 25, 21, 12, 10…
Să presupunem că vreau să-ți transmit mesajul:
„I love quantum!"
Sau, echivalent:
8, 11, 14, 21, 4, 16, 20, 0, 13, 19, 20, 12
Nu vrem să trimitem codul de mai sus; aceea este o substituție simplă, care nu este deloc sigură. Vrem să combinăm asta cu cheia noastră într-un fel. O metodă obișnuită este adunarea modulo 26. Adunăm valoarea mesajului la valoarea cheii, mod 26, până la sfârșitul mesajului. Deci, am trimite
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
Reține că dacă cineva interceptează asta și NU are cheia, decriptarea este cu totul fără speranță! Nici măcar cele două „u"-uri din „quantum" nu sunt codificate cu același număr! Primul este un 3, iar al doilea este un 16… în același cuvânt!
Deci, îți trimit asta, și tu ai aceeași cheie ca mine. Anulezi adunarea modulo 26 pe care știi că am efectuat-o:
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),…
Astfel încât mesajul x1, x2, x3, x4… trebuie să fie
8, 11, 14, 21…
În final, convertind asta în text, avem
„I love quantum".
Acesta este un pad de unică folosință.
Reține că dacă cheia este mai scurtă decât mesajul, începem să repetăm codificarea. Ar fi totuși o problemă de decriptare dificilă de rezolvat, dar nu imposibilă dacă se repetă suficient de des. Deci, ai nevoie de o cheie lungă (sau „pad").
În multe contexte, studenții vor fi deja familiari cu această criptare, astfel încât această activitate poate fi omisă. Dar este o recapitulare relativ rapidă și simplă.
Pasul 1: Găsește-ți un partener și partajați o secvență de 4 litere ca cheie. Orice secvență de 4 litere adecvată clasei va fi bună.
Pasul 2: Alege un cuvânt secret de 4 litere pe care vrei să-l trimiți partenerului tău (ambii parteneri fac asta, astfel încât să vă trimiteți reciproc cuvinte secrete diferite)
Pasul 3: Convertește cheia/pad-ul de 4 litere și fiecare dintre cuvintele secrete de 4 litere în numere folosind A = 1, B = 2 și așa mai departe.
Pasul 4: Combină cuvântul tău de 4 litere cu pad-ul de unică folosință folosind adunarea modulo 26.
Pasul 5: Înmânează-i partenerului tău secvența de numere care codifică cuvântul tău secret, iar partenerul tău îți va înmâna pe a sa.
Pasul 6: Decriptați cuvintele celuilalt folosind scăderea modulo 26.
Pasul 7: Verificați. A funcționat?
Continuare
Schimbați cuvinte criptate cu un alt grup, care nu are acces la pad-ul vostru de unică folosință. Puteți să-l decriptați? Explicați de ce sau de ce nu?
Sperăm că activitatea de mai sus face clar că un pad de unică folosință este o formă de criptare de neîntrerupt, dată câteva ipoteze, cum ar fi:
- Cheia are aceeași lungime ca mesajul care urmează să fie trimis, sau mai lungă
- Cheia este cu adevărat aleatorie
- Cheia este folosită o singură dată și apoi aruncată
Deci, asta e grozav. Avem criptare de neîntrerupt... dacă nimeni nu obține cheia noastră. Dacă cineva obține cheia noastră, totul este decriptat. Această diferență între criptarea de neîntrerupt și a avea toate secretele expuse face ca partajarea unei chei securizate să fie extrem de importantă. Scopul distribuției cuantice a cheilor este de a folosi constrângerile pe care natura le-a impus informației cuantice pentru a securiza o cheie partajată/pad de unică folosință.
Folosirea stărilor cuantice ca cheie
Să presupunem că lucrăm cu qubiți (subliniind că qubiții au două stări proprii). S-ar putea folosi sisteme cuantice cu un număr mai mare de stări cuantice, dar calculatoarele cuantice de ultimă generație de la IBM® folosesc qubiți. Nu este nicio problemă să codificăm A, B, C în secvențe de 0 și 1. Deci, este suficient să partajăm o cheie de 0 și 1 și să facem adunare modulo 2 pe fiecare bit care stochează o literă.
Verifică-ți înțelegerea
Citește întrebarea de mai jos, gândește-te la răspunsul tău, apoi apasă pe triunghi pentru a dezvălui soluția.
Dacă ne interesează doar literele în engleză, de câți biți avem nevoie?
Răspuns:
Prietenii noștri, Alice și Bob, doresc să partajeze o cheie cuantică astfel încât nimeni altcineva să nu o poată intercepta (cel puțin nu fără ca ei să știe). Ei trebuie să aibă o modalitate de a-și trimite stări cuantice. A face asta cu fidelitate ridicată și fără zgomot/erori NU este trivial. Dar există două abordări pe care ar trebui să le putem înțelege în acest moment:
- Un cablu de fibră optică îți permite să trimiți lumină... care este foarte cuantică. Fotooni individuali pot fi detectați cu fidelitate ridicată pe mulți kilometri de cablu de fibră optică. Acesta nu este un canal cuantic perfect, fără erori, dar ar putea fi foarte bun.
- Am putea folosi teleportarea cuantică, descrisă într-un modul anterior. Adică, Alice și Bob ar putea partaja qubiți entangliați și o stare ar putea fi trimisă de la Alice la Bob folosind protocolul de teleportare.
Pentru acest modul, nu dorim să vă cerem să aveți configurații optice de înaltă fidelitate pentru partajarea fotooniloruri, așa că vom folosi a doua metodă pentru partajarea stărilor cuantice. Dar asta nu înseamnă că este cea mai realistă pentru partajarea pe distanțe lungi a cheilor cuantice.
Vom explora acum un protocol stabilit pentru prima dată de Charles Bennett și Gilles Brassard în 1984 pentru partajarea stărilor măsurate în baze diferite de la Alice la Bob. Vom folosi un regim de măsurare inteligent pentru a construi o cheie care să fie folosită în criptarea ulterioară. Cu alte cuvinte, distribuim o cheie cuantică între două părți care doresc să comunice, de unde și „distribuția cuantică a cheilor" (QKD).
QKD pasul 1: Biții aleatori și bazele aleatorii ale lui Alice
Alice va începe prin generarea unei secvențe aleatorii de 0 și 1. Ea va selecta aleator o bază în care să pregătească o stare cuantică, pe baza fiecărui bit aleator, folosind tabelul de mai jos (un tabel pe care îl are și Bob):
| Bază | bit = 0 | bit = 1 |
|---|---|---|
| Z | ||
| X |
De exemplu, să presupunem că Alice a generat aleator un 0 și a selectat aleator baza X. Atunci ar pregăti o stare cuantică . Cu siguranță se poate folosi aleatorismul cuantic pentru a genera un set aleator de 0 și 1 și o alegere aleatorie a bazei. Deocamdată, să presupunem pur și simplu că un set aleator a fost generat, după cum urmează:
| Biții lui Alice | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | ... |
|---|---|---|---|---|---|---|---|---|---|---|
| Bazele lui Alice | X | X | Z | Z | Z | X | Z | Z | X | ... |
| Stările lui Alice | ... |
Acest set de biți aleatori, baze și stări rezultante ar continua într-o secvență lungă, pentru a da o cheie de lungime suficientă.
QKD pasul 2: Bazele aleatorii ale lui Bob
Bob face și el o alegere aleatorie a bazelor. Cu toate acestea, în timp ce Alice folosea alegerea bazei pentru a-și pregăti starea, Bob va face de fapt măsurători în aceste baze. Dacă Bob face o măsurătoare în aceeași bază în care Alice și-a pregătit starea, atunci putem prezice rezultatul măsurătorii lui Bob. Când Bob alege din întâmplare o bază diferită față de baza pe care Alice a folosit-o în pregătire, nu putem cunoaște rezultatul măsurătorii lui Bob.
| Biții lui Alice | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | ... |
|---|---|---|---|---|---|---|---|---|---|---|
| Bazele lui Alice | X | X | Z | Z | Z | X | Z | Z | X | ... |
| Stările lui Alice | ... | |||||||||
| Bazele lui Bob | X | Z | X | Z | X | X | Z | X | X | ... |
| Stările lui Bob (a priori) | ? | ? | ? | ? | ... | |||||
| Stările lui Bob (măsurate) | ... | |||||||||
| În tabelul de mai jos, consideră prima coloană. Alice a pregătit starea care este o stare proprie a lui X. Deoarece Bob a ales și el aleator să măsoare în baza X, există un singur rezultat posibil pentru starea măsurată de Bob: În a doua coloană, totuși, ei au ales baze diferite. Starea trimisă de Alice este Aceasta are o șansă de 50% de a fi măsurată de Bob în starea și o șansă de 50% de a fi măsurată în Deci, rândul care arată ce știm, a priori, despre măsurătorile lui Bob nu poate fi completat pentru coloana 2. Dar Bob va face o măsurătoare și va obține o stare proprie a lui (în acea coloană) Z. În rândul de jos, completăm ce au produs aceste măsurători. |
QKD pasul 3: Discuția publică despre baze
Alice și Bob pot acum să-și comunice reciproc ce bază au ales în fiecare caz. Pentru toate coloanele în care s-au întâmplat să aleagă aceeași bază, fiecare știe cu certitudine ce stare a avut celălalt. Bob poate converti starea și baza într-un 0 sau 1 conform convenției partajate de ambele părți. Putem rescrie tabelul de mai sus pentru a arăta doar cazurile în care bazele lui Alice și Bob s-au potrivit:
| Biții lui Alice | 0 | 0 | 1 | 0 | 0 | ... |
|---|---|---|---|---|---|---|
| Bazele lui Alice | X | Z | X | Z | X | ... |
| Stările lui Alice | ... | |||||
| Bazele lui Bob | X | Z | X | Z | X | X |
| Stările lui Bob (a priori) | ... | |||||
| Stările lui Bob (măsurate) | ... | |||||
| Biții lui Bob | 0 | 0 | 1 | 0 | 0 | ... |
Alice a transmis cu succes șirul de biți 00100... lui Bob. Dacă prietenii au convenit dinainte să folosească șiruri de 5 biți ca numere în pad-ul lor de unică folosință, acești primii cinci biți le-ar da numărul
QKD pasul 4: Verifică și trimite secretul
Înainte ca Alice și Bob să meargă mai departe, ar trebui să aleagă un subset al biților lor clasici pentru a-i compara. Deoarece au păstrat doar măsurătorile qubiților care au fost pregătiți și măsurați folosind aceeași bază, toate valorile măsurate ar trebui să coincidă. Dacă există un procent foarte mic care nu coincide, acesta ar putea fi atribuit zgomotului sau erorilor cuantice. Dar dacă multe nu coincid, ceva a mers prost!
Aici nu vom aborda ce fracțiune din cheie ar trebui să fie folosită pentru verificare. Deocamdată, vom presupune că această verificare merge bine; vom reveni la aceasta în secțiunea de mai jos despre interceptare.
Prietenii ar trimite apoi un mesaj criptat unul altuia folosind canale clasice. Ei ar folosi apoi numerele din pad-ul lor de unică folosință pentru a cripta/decripta mesaje secrete, fără a transmite niciodată pad-ul de unică folosință de la o locație la alta. Pentru secțiunea următoare despre interceptare, reține că toate aceste partajări ale cheii au loc înainte de dezvăluirea secretului criptat prin canale clasice.
Alice și Bob și-au comunicat alegerea bazei prin canale clasice, deci nu ar putea fi asta interceptat? Da! Dar cunoașterea bazei pe care au folosit-o pentru măsurătoare nu îți spune ce bit au trimis sau obținut. Asta este posibil doar dacă știi și biții de start ai lui Alice. Dar atunci ai fi în calculatorul lui Alice, unde sunt stocate secretele, iar comunicarea secretă a secretelor devine inutilă. Deci interceptarea comunicării clasice nu sparge criptarea. Dar ce se întâmplă cu interceptarea informațiilor în canalul cuantic?
Rezistența QKD la interceptare
Alice și Bob au o prietenă, Eve, care este notorie pentru interceptarea comunicațiilor. Eve dorește să intercepteze cheia cuantică a lui Alice și Bob, astfel încât să o poată folosi pentru a decripta mesajele trimise între cei doi. Asta s-ar întâmpla în mod necesar între pregătirea stărilor de către Alice și măsurarea stărilor de către Bob, deoarece măsurarea prăbușește starea cuantică. În special, asta înseamnă că interceptarea ar trebui să aibă loc înainte ca bazele să fi fost partajate sau comparate.
Eve trebuie să ghicească ce bază a fost folosită în codificarea fiecărui bit. Din nou, dacă nu poate accesa calculatorul lui Alice, nu are nimic pe care să-și bazeze această ghicire, și va fi aleatorie. Să presupunem că startul lui Alice este același ca înainte, și să presupunem că alegerea aleatorie a bazei de măsurare a lui Bob este aceeași ca înainte. Să completăm ce obține Eve dacă face măsurători ale canalului cuantic. Ca înainte, dacă Eve alege din întâmplare aceeași bază ca Alice, știm ce va obține. Dacă nu, ar putea obține oricare dintre cele două rezultate, fiecare cu o probabilitate de 50%.
| Biții lui Alice | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | ... |
|---|---|---|---|---|---|---|---|---|---|---|
| Bazele lui Alice | X | X | Z | Z | Z | X | Z | Z | X | ... |
| Stările lui Alice | ... | |||||||||
| Bazele ghicite de Eve | Z | X | X | Z | X | Z | Z | X | X | ... |
| Stările lui Eve (a priori) | ? | ? | ? | ? | ? | ... | ||||
| Stările lui Eve (măsurate) | ... | |||||||||
| Bazele lui Bob | X | Z | X | Z | X | X | Z | X | X | ... |
Acum, deoarece Eve nu știe dacă s-a potrivit cu baza lui Alice sau nu, nu știe ce să transmită mai departe lui Bob pentru a se potrivi cu stările originale ale lui Alice. Când Eve măsoară, de exemplu, tot ce știe cu certitudine este că Alice nu a pregătit starea pentru acel qubit. Dar Alice ar fi putut pregăti sau Toate ar putea fi consistente cu măsurătoarea lui Eve. Deci Eve trebuie să facă o alegere. Ar putea transmite exact starea pe care a măsurat-o, sau ar putea încerca să ghicească instanțele în care măsurătoarea sa nu a fost starea proprie trimisă de Alice. Vom include o combinație în tabelul nostru:
| Biții lui Alice | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | ... |
|---|---|---|---|---|---|---|---|---|---|---|
| Bazele lui Alice | X | X | Z | Z | Z | X | Z | Z | X | ... |
| Stările lui Alice | ... | |||||||||
| Bazele ghicite de Eve | Z | X | X | Z | X | Z | Z | X | X | ... |
| Stările lui Eve (a priori) | ? | ? | ? | ? | ? | ... | ||||
| Stările lui Eve (măsurate) | ... | |||||||||
| Stările lui Eve (transmise mai departe) | ... | |||||||||
| Bazele lui Bob | X | Z | X | Z | X | X | Z | X | X | ... |
| Stările lui Bob (a priori) | ? | ? | ... | |||||||
| Stările lui Bob (măsurate) | ... | |||||||||
| Biții lui Bob | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | ... |
În acest moment, este rezonabil să întrebi: „De ce Eve nu face pur și simplu o copie a stării cuantice a lui Alice, păstrează una pentru a o măsura și o transmite pe cealaltă lui Bob?" Răspunsul este teorema „no-cloning". Informal, spune că nu există nicio operație unitară (mecanică cuantică) care să poată face o a doua copie a unei stări cuantice arbitrare, păstrând în același timp prima copie. Demonstrația este relativ simplă și este lăsată ca exercițiu ghidat. Dar deocamdată, înțelege că Eve să facă copii ale stării cuantice este interzis de legile fundamentale ale naturii, și acesta este un punct forte principal al QKD. Cum a fost înainte, Alice și Bob s-ar suna și ar compara bazele. Vor reduce acest tabel la cazurile în care cei doi prieteni au selectat aceleași baze:
| Biții lui Alice | 0 | 0 | 1 | 0 | 0 | ... |
|---|---|---|---|---|---|---|
| Bazele lui Alice | X | Z | X | Z | X | ... |
| Stările lui Alice | ... | |||||
| Bazele ghicite de Eve | Z | Z | Z | Z | X | ... |
| Stările lui Eve (a priori) | ? | ? | ... | |||
| Stările lui Eve (măsurate) | ... | |||||
| Stările lui Eve (transmise mai departe) | ... | |||||
| Bazele lui Bob | X | Z | X | Z | X | ... |
| Stările lui Bob (a priori) | ? | ... | ||||
| Stările lui Bob (măsurate) | ... | |||||
| Biții lui Bob | 1 | 0 | 0 | 0 | 0 | ... |
Alice și Bob au comunicat din nou un șir de biți... dar șirurile nu se potrivesc. Cel mai din stânga și bitul din mijloc sunt inversate. Uitându-te la tabelul anterior, poți urmări această nepotrivire până la interferența din partea lui Eve. Important de reținut, că putem face statistici pe potrivirea dintre șirurile noastre de biți acum, în timp ce configurăm cheia, cu mult înainte de a partaja secretul nostru criptat. Alice și Bob sunt liberi să folosească câți dintre biții pad-ului lor de unică folosință doresc pentru a verifica securitatea canalului lor. Dacă un singur bit, sau un procent foarte mic de biți, nu s-au potrivit, acest lucru ar putea fi atribuit zgomotului sau erorilor. Dar o fracție substanțială de nepotriviri indică interceptarea. Înțelesul „substanțial" depinde puțin de zgomotul din configurația utilizată; ce înseamnă asta pentru calculatoarele cuantice IBM® este discutat mai jos când implementăm acest protocol. Dacă sunt detectate erori excesive, Alice și Bob nu partajează secretul și pot începe să caute interceptatorul.
Avertismente
Demonstrarea securității este extrem de dificilă. De fapt, protocolul descris vag aici a fost propus în 1984 și nu a fost dovedit sigur până la 16 ani mai târziu Shor & Preskill, 2000. Există multe subtilități care depășesc sfera acestei introduceri. Dar vom lista pe scurt câteva pentru a demonstra că subiectul este mai complex decât este ilustrat aici.
- Canale securizate: Când Alice trimite qubiții săi printr-o configurație cuantică (un canal), și în particular când primește răspunsuri clasice de la cineva, am presupus că acel cineva este de fapt Bob. Dacă Eve ar infiltra această configurație astfel încât toată comunicarea lui Alice să se desfășoare de fapt cu Eve, și toată comunicarea lui Bob să se desfășoare de fapt cu Eve, atunci Eve a obținut efectiv o cheie și poate afla secretele. Mai întâi trebuie să se asigure „canalele securizate", un proces cu un set diferit de protocoale pe care nu le-am abordat aici.
- Ipoteze despre Eve: Pentru a dovedi cu adevărat securitatea, nu putem face ipoteze despre comportamentul lui Eve; ea ar putea întotdeauna să ne contrazică așteptările. Aici, pentru a da exemple concrete, facem ipoteze. De exemplu, am putea presupune că stările pe care Eve le transmite mai departe lui Bob sunt întotdeauna exact cele pe care le-a obținut la măsurătoare. Sau am putea presupune că alege aleator o stare experimental consistentă cu măsurătoarea sa. Mai fundamental, limbajul de aici presupune că Eve face de fapt o măsurătoare, spre deosebire de stocarea stării pe un alt sistem cuantic și trimiterea unui qubit aleator lui Bob. Aceste ipoteze sunt bune pentru a înțelege protocolul, dar ele înseamnă că nu dovedim nimic în deplină generalitate.
- Amplificarea confidențialității: Alice și Bob nu sunt obligați să folosească cheia cuantică exact ca transmisă. Ei pot, de exemplu, să aplice o funcție hash cheii partajate. Aceasta ar exploata faptul că interceptatoarea are cunoștință incompletă a cheii pentru a produce o cheie partajată mai scurtă, dar sigură.
Experimentul 1: QKD fără interceptor
Să implementăm protocolul de mai sus în absența unui interceptor. Vom face asta mai întâi folosind un simulator, pur și simplu pentru a înțelege fluxul de lucru.
Mai întâi, o notă despre simulatoarele cuantice: Cele mai multe probleme cuantice care implică mai mult de ~30 de qubiți nu pot fi simulate de majoritatea calculatoarelor. Niciun calculator clasic, supercomputer sau GPU nu poate simula întreaga gamă de comportamente ale unui calculator cuantic cu 127 de qubiți. De obicei, motivația pentru utilizarea calculatoarelor cuantice reale este că mulți qubiți încâlciți nu pot fi simulați. În acest caz, nu există încâlcire a qubiților, cu excepția cazului în care folosim schema de teleportare pentru a muta informațiile. În acest caz, motivația pentru utilizarea calculatoarelor cuantice reale este diferită: este teorema non-clonării. Un calculator clasic care simulează un qubit ar putea trimite informații despre o stare cuantică de la Alice la Bob, dar dacă aceste informații clasice ar fi interceptate, ar putea fi ușor duplicate, iar Eve ar putea păstra o copie perfectă, trimițând una lui Bob. Acest lucru nu este posibil cu stări cuantice reale.
IBM Quantum recomandă abordarea problemelor de calcul cuantic folosind un cadru pe care îl numim „tipare Qiskit". Acesta constă din următorii pași.
- Pasul 1: Mapează problema ta într-un circuit cuantic
- Pasul 2: Optimizează circuitul pentru rularea pe hardware cuantic real
- Pasul 3: Execută jobul pe calculatoarele cuantice IBM folosind primitive Runtime
- Pasul 4: Post-procesează rezultatele
Tipare Qiskit pasul 1: Mapează problema ta într-un circuit cuantic
În acest caz, maparea problemei noastre în circuite cuantice se reduce pur și simplu la pregătirea stărilor lui Alice, urmată de măsurătorile lui Bob. Începem cu selectarea aleatorie a bitului și a bazei.
# 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)
Să vizualizăm biții, bazele și circuitul. Observă că uneori bazele coincid, iar alteori nu.
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.]
Tipare Qiskit pasul 2: Optimizează problema pentru execuție cuantică
Acest pas preia operațiile pe care dorim să le efectuăm și le exprimă în termenii funcționalității unui calculator cuantic specific. De asemenea, mapează problema noastră pe topologia calculatorului cuantic.
Vom începe prin a încărca mai multe pachete necesare pentru comunicarea cu calculatoarele cuantice IBM. Trebuie, de asemenea, să selectăm un backend pe care să rulăm. Putem alege fie backend-ul cel mai puțin ocupat, fie un backend specific ale cărui proprietăți le cunoaștem. Deși vom folosi momentan un simulator, este important să utilizăm un model de zgomot rezonabil în simulare și este bine să păstrăm fluxul de lucru cât mai aproape de ceea ce vom folosi ulterior pentru calculatoarele cuantice reale.
Mai jos există cod pentru salvarea acreditivelor la prima utilizare. Asigură-te că ștergi aceste informații din notebook după ce le-ai salvat în mediul tău, astfel încât acreditivele tale să nu fie accidental partajate când distribui notebook-ul. Consultă Configurează contul tău IBM Cloud și Inițializează serviciul într-un mediu neîncrezut pentru mai multe îndrumări.
# 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
Mai jos selectăm un simulator și un model de zgomot.
# 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)
Tipare Qiskit pasul 3: Execută
Folosește sampler-ul pentru a rula jobul, cu circuitul ca argument.
# This required 5 s to run on a Heron r2 processor on 10-28-24
sampler = Sampler(mode=backend)
job = sampler.run([qc_isa], shots=1)
# job = sampler_sim.run([qc], shots = 1)
counts = job.result()[0].data.c.get_counts()
countsint = job.result()[0].data.c.get_int_counts()
Tipare Qiskit pasul 4: Post-procesare
Aici interpretăm rezultatele și extragem informații utile. Am putea încerca să vizualizăm rezultatul sampler-ului, dar l-am folosit într-un mod neconvențional. În loc să facem multe măsurători ale circuitului și să dezvoltăm statistici despre stări, am făcut o singură măsurătoare (a lui Bob). Orice qubit cu o stare care a fost pregătită și măsurată în aceeași bază ar trebui să aibă un rezultat determinist, astfel că este necesară o singură măsurătoare. Qubiții cu stări pregătite și măsurate în baze diferite (care ar avea rezultate probabilistice și ar necesita multe măsurători pentru a fi interpretați) nu vor fi folosiți pentru a construi pad-ul/cheia noastră de unică folosință. Să extragem o listă de rezultate ale măsurătorilor din acest șir de biți. Ai grijă să inversezi ordinea dacă compari cu tabloul de biți al lui Alice pe care l-am folosit pentru a genera circuitul.
# 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]
Să comparăm bazele de măsurare alese aleatoriu de Alice și Bob. Acesta a fost pasul 3 din protocolul nostru QKD (discuția publică despre baze). De fiecare dată când au ales aceeași bază pentru un qubit, adăugăm biții asociați acelui qubit la o listă de biți pentru generarea numerelor într-un pad de unică folosință. Când bazele nu coincid, rezultatele sunt aruncate. Să verificăm, de asemenea, dacă cele două liste de biți sunt de acord sau dacă au existat pierderi din cauza zgomotului sau a altor factori.
# 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 și Bob au fiecare o listă de biți care se potrivesc cu 100% fidelitate. Aceștia pot folosi acești biți pentru a genera numere într-un pad de unică folosință. Pot folosi apoi această cheie în pasul 4 al QKD: trimiterea și decriptarea unui secret. Tabloul actual de biți este prea scurt pentru a decripta mare lucru. Vom reveni la aceasta după ce includem interceptarea.
Verifică-ți înțelegerea
Citește întrebarea de mai jos, gândește-te la răspuns, apoi apasă pe triunghi pentru a dezvălui soluția.
Presupune că ai nevoie de cifre suficient de mari pentru a facilita deplasarea literelor din alfabetul englez cu întreaga lungime a acelui alfabet sau mai mult, deși există cu siguranță și alte scheme de codificare.
(a) Câte litere poate fi un mesaj pentru a putea fi decriptat folosind biții din cheia de mai sus? (b) Trebuie răspunsul tău să coincidă cu cel al colegilor tăi? De ce sau de ce nu?
Răspuns:
(a) Răspunsul depinde de câte baze alese aleatoriu s-au potrivit între Alice și Bob. Deoarece există o șansă de aproximativ 50-50 ca bazele să coincidă pentru orice qubit dat, ne așteptăm ca aproape 10 dintre biții noștri să fie utili. 9 sau 11 sunt destul de comune. Chiar și 4 sau 15 nu sunt în afara domeniului posibilului. 5 biți sunt necesari pentru a deplasa cu un număr mai mare sau egal cu lungimea alfabetului englez, ceea ce înseamnă că poți aplica deplasarea unei singure litere pentru fiecare 5 biți pe care îi ai. Dacă ai cel puțin 5 biți partajați de Alice și Bob, poți codifica o singură literă. Dacă ai cel puțin 10, poți codifica 2 litere și așa mai departe. (b) Nu trebuie să coincidă, din motivele prezentate la (a).
Experimentul 2: QKD cu un interceptor
Vom implementa exact același protocol ca înainte. De data aceasta, vom insera un alt set de măsurători, ale lui Eve, între Alice și 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()
Pasul 4 al tiparelor Qiskit (post-procesare) este simplu în acest caz. Nu este nevoie să vizualizăm distribuția măsurătorilor, deoarece am efectuat o singură măsurătoare. Eve are următorii biți:
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]
Acum Eve trebuie să reconstruiască stările pentru a le trimite lui Bob. Așa cum s-a descris în introducere, ea nu are cum să știe dacă a ghicit corect bazele de codificare, deci nu poate pregăti exact aceleași stări care au fost trimise. Ar putea presupune că fiecare alegere a bazei a fost corectă și să codifice exact ceea ce a măsurat, sau ar putea presupune că a ales baza greșit și să aleagă fie oricare stare proprie a bazei opuse. Aici, pentru simplitate, presupunem primul caz. Realizăm acest lucru construind un circuit cuantic complet nou, repetând pașii tiparelor Qiskit ca înainte.
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]
Să comparăm acum biții lui Alice și ai lui 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
Anterior, exista o potrivire perfectă între biții din cheile lui Alice și Bob. Acum, din cauza interferenței lui Eve, vedem că biții lui Alice și ai lui Bob diferă în 14% din cazurile care ar trebui să coincidă, deoarece Alice și Bob au selectat aceleași baze. Acest lucru ar trebui să fie ușor de detectat de Alice și Bob. Cu toate acestea, bazarea pe un procentaj de erori ca acesta înseamnă că există o limită a cantității de zgomot pe care o putem tolera în canalul cuantic.
Experiment 3: Compare QKD with and without eavesdropping on a real quantum computer
Hai să rulăm acest experiment pe un calculator cuantic real. Astfel, putem valorifica teorema non-clonării. În același timp, calculatoarele cuantice reale au zgomot și rate de eroare mai mari decât calculatoarele clasice. Deci, hai să comparăm pierderea de fidelitate a biților cheii cu și fără interceptare, pentru a ne asigura că diferența este detectabilă atunci când folosim un calculator cuantic real. Vom începe fără interceptare:
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
Fără interceptare, am obținut 100% fidelitate pe acest set de 127 biți de test, rezultând 55 de baze potrivite și biți de cheie utilizabili. Acum, hai să repetăm acest experiment cu Eve ascultând:
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
Aici am găsit o pierdere de aproape 23% a fidelității biților partajați din cauza interceptării! Aceasta este foarte ușor de detectat! Rețineți că transferul informațiilor cuantice pe distanțe lungi ar putea introduce totuși zgomot și erori suplimentare. Asigurarea că interceptarea poate fi detectată, chiar în prezența zgomotului, și chiar atunci când Eve folosește toate trucurile la dispoziția sa, este un domeniu complex care depășește scopul acestei introduceri.
Questions
Instructorii pot solicita versiuni ale acestor notebook-uri cu chei de răspuns și îndrumare privind plasarea în curricule comune, completând acest sondaj rapid despre modul în care sunt folosite notebook-urile.
Critical concepts
- Informația cuantică nu poate fi copiată sau „clonată".
- Poți repeta același proces de preparare pentru a crea un ansamblu de stări cuantice care sunt toate la fel, sau aproape la fel.
- O cheie de criptare/decriptare (un bloc de unică folosință) poate fi partajată între doi prieteni folosind stări cuantice.
- Atunci când doi prieteni aleg aleatoriu o bază de măsurare, jumătate din timp vor alege diferit și vor trebui să renunțe la informațiile de pe acei qubiți.
- Alegerea aleatorie a bazei de măsurare asigură, de asemenea, că un interceptor nu poate cunoaște starea inițială preparată și, prin urmare, nu poate recrea starea trimisă. Aceasta garantează că interceptarea va fi detectată.
T/F questions
- A/F În distribuția cuantică de chei, cei doi parteneri de comunicare măsoară fiecare qubit în aceeași bază.
- A/F Un interceptor care captează informații cuantice în QKD este împiedicat de legile naturii să copieze starea cuantică interceptată.
- A/F Un bloc de unică folosință este o cheie pentru criptarea/decriptarea mesajelor securizate în care o anumită schemă de codificare este folosită o singură dată, pentru o singură informație (cum ar fi o singură literă a alfabetului).
MC questions
- Selectează opțiunea care completează cel mai bine afirmația. Așa cum este descris în acest modul, un bloc de unică folosință este un set de chei de criptare/decriptare care este folosit...
- a. O singură dată pentru o singură informație, cum ar fi o singură literă.
- b. O singură dată pentru un singur mesaj.
- c. O singură dată pentru o perioadă de timp stabilită, cum ar fi o zi.
- d. Până când există dovezi de interceptare.
- Presupune că Alice și Bob aleg bazele de măsurare aleatoriu. Ei măsoară. Apoi își împărtășesc bazele de măsurare și păstrează doar biții de informație din cazurile în care au folosit aceeași bază. Neglijând fluctuațiile aleatoare, aproximativ ce procent din qubiții lor ar trebui să producă biți de informație utilizabili?
- a. 100%
- b. 50%
- c. 25%
- d. 12,5%
- e. 0%
- După ce Alice și Bob selectează cazurile în care au folosit aceleași baze de măsurare, ce procent din acei biți de informație ar trebui să se potrivească, dacă zgomotul cuantic și erorile ar fi neglijabile?
- a. 100%
- b. 50%
- c. 25%
- d. 12,5%
- e. 0%
- Presupune că Alice și-a ales bazele de măsurare aleatoriu. Eve alege de asemenea bazele aleatoriu și ascultă (măsoară). Ea trimite mai departe lui Bob stări care sunt consistente cu măsurătorile ei. Alice și Bob compară alegerile de baze și păstrează doar qubiții măsurați/preparați de ei în aceleași baze. Neglijând fluctuațiile aleatoare, aproximativ ce procent din măsurătorile qubiților păstrați se vor potrivi, conform Alice și Bob?
- a. 100%
- b. 75%
- c. 50%
- d. 25%
- e. 12,5%
- f. 0%
Discussion questions
-
Presupune că toate alegerile de baze sunt aleatorii pentru toți participanții — Alice, Bob și Eve. Presupune că după ce Eve ascultă, ea trimite lui Bob o stare preparată în aceeași bază în care a măsurat și care este consistentă cu acea măsurătoare. Convinge-ți partenerii că 12,5% din toți qubiții inițializați de Alice vor produce nepotriviri de măsurătoare între Alice și Bob, indicând interceptarea (ignorând erorile cuantice și zgomotul). Indiciu 1: Deoarece nu există o bază preferată, dacă iei în considerare o singură alegere inițială pentru Alice, raportul pentru acea alegere ar trebui să fie același cu raportul pentru suma tuturor alegerilor. Indiciu 2: Poate că nu este suficient să numeri numărul de moduri în care ceva ar putea să se întâmple, deoarece unele rezultate pot apărea cu probabilități diferite.
-
Presupune din nou că toate alegerile de baze sunt aleatorii pentru toți participanții — Alice, Bob și Eve. Dar acum, ia în considerare că Eve este liberă să trimită orice stare dorește după măsurătoarea sa. Ea ar putea chiar să încerce să trimită stări care sunt inconsistente cu propriile ei măsurători. Discută cu partenerii/vecinii tăi dacă crezi că există vreo alegere de baze care ar putea reduce procentul mediu de qubiți care indică interceptarea pentru Alice și Bob.