การกระจายกุญแจเชิงควอนตัม
สำหรับโมดูล Qiskit in Classrooms นี้ นักเรียนต้องมีสภาพแวดล้อม Python ที่ใช้งานได้พร้อมแพ็คเกจต่อไปนี้ติดตั้งไว้:
qiskitv2.1.0 หรือใหม่กว่าqiskit-ibm-runtimev0.40.1 หรือใหม่กว่าqiskit-aerv0.17.0 หรือใหม่กว่าqiskit.visualizationnumpypylatexenc
สำหรับการตั้งค่าและติดตั้งแพ็คเกจข้างต้น ดูคู่มือ ติดตั้ง Qiskit เพื่อรันงานบนคอมพิวเตอร์ควอนตัมจริง นักเรียนต้องสมัครบัญชีกับ IBM Quantum® โดยทำตามขั้นตอนในคู่มือ ตั้งค่าบัญชี IBM Cloud
โมดูลนี้ผ่านการทดสอบและใช้เวลา QPU 5 วินาที นี่เป็นเพียงการประมาณการ การใช้งานจริงของคุณอาจแตกต่างกัน
# 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'
ดูวิดีโอแนะนำโมดูลโดย Dr. Katie McCormick ด้านล่าง หรือคลิก ที่นี่ เพื่อดูบน YouTube
บทนำและแรงจูงใจ
มีวิธีการเข้ารหัสและถอดรหัสข้อมูลอยู่มากมายนับไม่ถ้วน และมีวิธีที่ได้รับการศึกษาอย่างละเอียดแล้วนับพัน ในที่นี้เราจะจำกัดตัวเองให้อยู่กับวิธีการเข้ารหัสที่เก่าแก่และเรียบง่ายมาก เรียกว่า "การแทนที่แบบง่าย" เพื่อมุ่งความสนใจไปที่ส่วนที่เป็นควอนตัมของโปรโตคอลนี้ ส่วนที่เป็นควอนตัมสามารถนำไปปรับใช้กับโปรโตคอลอื่น ๆ ได้โดยมีการเปลี่ยนแปลงน้อยมาก
การแทนที่แบบง่าย
การเข้ารหัสด้วยการแทนที่แบบง่ายคือการที่ตัวอักษรหรือ ตัวเลขหนึ่งถูกแทนที่ด้วยอีกตัวหนึ่ง โดยมีการแมปแบบ 1:1 จากตัวอักษรและตัวเลขในข้อความ ไปยังตัวอักษรและตัวเลขที่ใช้ในลำดับที่เข้ารหัส ตัวอย่างในวัฒนธรรมป๊อปคือปริศนา cryptoquote หรือ cryptogram ซึ่งคำพูดหรือวลีถูกเข้ารหัสด้วยการแทนที่แบบง่าย และผู้เล่นต้องถอดรหัสมัน ปริศนาเหล่านี้แก้ได้ง่ายหากยาวพอ ลองพิจารณาตัวอย่าง:
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.
คนที่แก้ปริศนาเหล่านี้ด้วยมือส่วนใหญ่ใช้เทคนิคที่อาศัยความคุ้นเคยกับโครงสร้างของภาษาต้นฉบับ ตัวอย่างเช่น ในภาษาอังกฤษ คำที่มีตัวอักษรเดียวอย่าง "R" ที่เข้ารหัสนั้น มีได้แค่ "a" หรือ "I" เท่านั้น ตัวอักษรซ้ำที่เข้ารหัสอยู่ในคำเช่น "KIVGGB" มีค่าได้แค่บางอย่าง ยังมีสิ่งที่ซับซ้อนกว่านั้นที่ให้เบาะแส เช่น คำที่พบบ่อยที่สุดที่ตรงกับรูปแบบ "GSZG" คือ "that" คนที่ใช้โปรแกรมในการแก้ปริศนามีตัวเลือกมากกว่า รวมถึงการสแกนผ่านความเป็นไปได้จนกว่าจะได้คำภาษาอังกฤษ และอัปเดตโดยรักษาคำนั้นไว้ วิธีที่ง่ายแต่ทรงพลังคือการใช้ความถี่ของตัวอักษร โดยเฉพาะเมื่อข้อความยาวพอที่จะเป็นตัวอย่างที่เป็นตัวแทนของภาษาอังกฤษ
คำถามตรวจสอบความเข้าใจ
ลองถอดรหัสด้วยตัวเองถ้าอยากลอง แต่ไม่จำเป็นสำหรับส่วนที่เหลือของโมดูล คลิกที่เครื่องหมายด้านล่างเพื่อดูข้อความ
คำตอบ:
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.
ตัวอย่างข้างต้นเชื่อมโยงกับ "กุญแจ" ซึ่งเป็นการแมปจาก ตัวอักษรที่เข้ารหัสไปยังตัวอักษรที่ถอดรหัส ในกรณีนี้ กุญแจคือ:
- A (ไม่ได้ใช้ เรียกว่า Z)
- B->Y
- C (ไม่ได้ใช้ เรียกว่า X)
- D->W
- E->V
- F->U
- ...
และอื่น ๆ พูดง่าย ๆ ว่านี่ไม่ใช่กุญแจที่ดีเลย กุญแจที่ตัวอักษรที่เข้ารหัสและถอดรหัสเพียงแค่เลื่อนตำแหน่งในตัวอักษร (เช่น A->B และ B->C) เรียกว่ารหัส "Caesar shift"
โปรดทราบว่าสิ่งเหล่านี้ยากมากหากสั้น อันที่จริง ถ้าสั้นมาก มันก็จะไม่มีคำตอบที่ชัดเจน ลองพิจารณา:
URYYP
มีการถอดรหัสที่เป็นไปได้มากมายโดยใช้กุญแจต่าง ๆ: HELLO, PETTY, HAPPY, JIGGY, STOOL คุณคิดออกไหมว่ามีอีกแบบไหนบ้าง?
แต่ถ้าคุณส่งข้อความหลายครั้งแบบนี้ ในที่สุดการเข้ารหัสก็จะถูกถอดรหัสได้ ดังนั้น คุณไม่ควรใช้ "กุญแจ" เดิมบ่อยเกินไป อันที่จริง ดีที่สุดคือใช้การแทนที่แบบหนึ่งเพียงครั้งเดียว ไม่ใช่แค่ในข ้อความเดียว แต่ เพียงสำหรับตัวอักษรเดียวเท่านั้น! หมายความว่าคุณจะมีรูปแบบการเข้ารหัสหรือกุญแจสำหรับแต่ละตัวอักษรที่ใช้ในข้อความตามลำดับ ถ้าต้องการส่งข้อความถึงเพื่อนโดยใช้วิธีนี้ คุณและเพื่อนจะต้องมีกระดาษแผ่นหนึ่ง (ในยุคเก่า) ที่กุญแจที่เปลี่ยนแปลงตลอดเวลานี้เขียนไว้ คุณจะใช้มันเพียงครั้งเดียวเท่านั้น นี่เรียกว่า "one-time pad"
One-time pad
มาดูวิธีการทำงานด้วยตัวอย่าง อาจทำได้ทั้งหมดด้วยตัวอักษร แต่เป็นเรื่องปกติที่จะแปลงจากตัวอักษรเป็นตัวเลข เช่น กำหนด A=0, B=1, C=2…. สมมติว่าเราเป็นเพื่อนที่เกี่ยวข้องกับกิจกรรมลับและเราได้แบ่งปัน pad กัน ในอุดมคติ เราควรแบ่งปัน pad หลายแผ่น แต่วันนี้คือ:
EDGRPOJNCUWQZVMK…
หรือแปลงเป็นตัวเลขตามตำแหน่งในตัวอักษร:
4,3,6,17,15, 14, 9, 13, 2, 20, 22, 16, 25, 21, 12, 10…
สมมติว่าฉันต้องการแบ่งปันกับคุณ ข้อความ:
"I love quantum!"
หรือเทียบเท่า:
8, 11, 14, 21, 4, 16, 20, 0, 13, 19, 20, 12
เราไม่ต้องการส่งรหัสข้างต้น นั่นเป็นการแทนที่แบบง่าย ซึ่งไม่ปลอดภัยเลย เราต้องการรวมสิ่งนี้กับกุญแจของเราด้วยวิธีใดวิธีหนึ่ง วิธีทั่วไปคือการบวก modulo 26 เราบวกค่าของข้อความกับค่าของกุญแจ mod 26 จนถึงท้ายข้อความ ดังนั้น เราจะส่ง
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
โปรดทราบว่าถ้าใครดักจับข้อความนี้และไม่มีกุญแจ การถอดรหัสมันเป็นเรื่องที่หวังไม่ได้เลย! แม้แต่ตัว "u" สองตัวใน "quantum" ก็ไม่ได้เข้ารหัสด้วยตัวเลขเดียวกัน! ตัวแรกเป็น 3 และตัวที่สองเป็น 16… ในคำเดียวกัน!
ดังนั้น ฉันส่งสิ่งนี้ให้คุณ และคุณมีกุญแจเดียวกับฉัน คุณยกเลิกการบวก modulo 26 ที่คุณรู้ว่าฉันทำ:
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),…
ทำให้ข้อความ x1, x2, x3, x4… ต้องเป็น
8, 11, 14, 21…
สุดท้าย แปลงสิ่งนี้เป็นข้อความ เราได้
"I love quantum".
นี่คือ one-time pad
โปรดทราบว่าถ้ากุญแจสั้นกว่าข้อความ เราจะเริ่มทำซ้ำการเข้ารหัส นั่นยังเป็นปัญหาการถอดรหัสที่ยาก แต่ไม่ใช่เรื่องเป็นไปไม่ได้ถ้าทำซ้ำมากพอ ดังนั้น คุณต้องการกุญแจที่ยาว (หรือ "pad")
ในหลายบริบท นักเรียนจะคุ้นเคยกับการเข้ารหัสนี้แล้ว จนสามารถข้ามกิจกรรมนี้ได้ แต่มันเป็นการทบทวนที่ค่อนข้าง รวดเร็วและเรียบง่าย
ขั้นตอนที่ 1: หาคู่ และแบ่งปันลำดับตัวอักษร 4 ตัวเพื่อใช้เป็นกุญแจ ลำดับ 4 ตัวที่เหมาะสมในชั้นเรียนจะได้ผล
ขั้นตอนที่ 2: เลือกคำลับ 4 ตัวอักษรที่ต้องการส่งให้คู่ของคุณ (ทั้งคู่ทำสิ่งนี้เพื่อส่งคำลับที่แตกต่างกันให้กัน)
ขั้นตอนที่ 3: แปลงกุญแจ/pad 4 ตัวอักษรและคำลับ 4 ตัวอักษรแต่ละคำเป็นตัวเลขโดยใช้ A = 1, B = 2 และต่อไป
ขั้นตอนที่ 4: รวมคำ 4 ตัวอักษรของคุณกับ one-time pad โดยใช้การบวก modulo 26
ขั้นตอนที่ 5: ส่งลำดับตัวเลขที่เข้ารหัสคำลับของคุณให้คู่ และคู่จะส่งของเขา/เธอให้คุณ
ขั้นตอนที่ 6: ถอดรหัสคำของกันและกันโดยใช้การลบ modulo 26
ขั้นตอนที่ 7: ตรวจสอบ มันได้ผลไหม?
ติดตามผล
แลกเปลี่ยนคำที่เข้ารหัสกับกลุ่ มอื่นที่ไม่มีสิทธิ์เข้าถึง one-time pad ของคุณ คุณถอดรหัสได้ไหม อธิบายว่าทำไมหรือทำไมไม่?
หวังว่ากิจกรรมข้างต้นจะทำให้เห็นชัดเจนว่า one-time pad เป็นรูปแบบการเข้ารหัสที่ทำลายไม่ได้ ภายใต้สมมติฐานบางประการ เช่น:
- กุญแจมีความยาวเท่ากับข้อความที่ส่ง หรือยาวกว่า
- กุญแจเป็นแบบสุ่มอย่างแท้จริง
- กุญแจถูกใช้เพียงครั้งเดียวแล้วทิ้ง
ดังนั้นนี่มันยอดเยี่ยมมาก เรามีการเข้ารหัสที่ทำลายไม่ได้... ยกเว้นว่าจะมีใครได้กุญแจเรา ถ้าใครได้กุญแจเรา ทุกอย่างก็ถูกถอดรหัสได้ ความแตกต่างระหว่างการเข้ารหัสที่ทำลายไม่ได้กับการเปิดเผยความลับทั้งหมดทำให้การแบ่งปันกุญแจที่ปลอดภัยมีความสำคัญอย่างยิ่ง เป้าหมายของการกระจายกุญแจเชิงควอนตัมคือการใช้ข้อจำกัดที่ธรรมชาติกำหนดให้กับข้อมูลควอนตัม เพื่อรักษาความปลอดภัยขอ งกุญแจที่แบ่งปัน/one-time pad
การใช้สถานะควอนตัมเป็นกุญแจ
สมมติว่าเราทำงานกับ Qubit (เน้นว่า Qubit มีสองสถานะ eigenstates) อาจใช้ระบบควอนตัมที่มีจำนวนสถานะควอนตัมมากกว่านั้นได้ แต่คอมพิวเตอร์ควอนตัมล้ำสมัยของ IBM® ใช้ Qubit การเข้ารหัส A, B, C ของเราเป็นลำดับ 0 และ 1 ไม่ใช่ปัญหา ดังนั้น เราแค่ต้องแบ่งปันกุญแจ 0 และ 1 และทำการบวก modulo 2 กับแต่ละบิตที่เก็บตัวอักษร
ตรวจสอบความเข้าใจ
อ่านคำถามด้านล่าง คิดคำตอบของคุณ จากนั้นคลิกสามเหลี่ยมเพื่อดูคำตอบ
ถ้าเราสนใจแค่ตัวอักษรภาษาอังกฤษ เราต้องการกี่บิต?
คำตอบ:
เพื่อน ๆ ของเรา Alice และ Bob ต้องการแบ่งปันกุญแจควอนตัมในลักษณะที่ไม่มีใครอื่นสามารถดักจับได้ (อย่างน้อยก็ไม่โดยที่พวกเขาไม่รู้) พวกเขาต้องมีวิธีส่งสถานะควอนตัมให้กัน การทำเช่นนี้ด้วยความแม่นยำสูงและไม่มีสัญญาณรบกวน/ข้อผิดพลาดไม่ใช่เรื่องง่าย แต่มีสองวิธีที่เราน่าจะเข้าใจได้ตอนนี้:
- สายใยแก้วนำแสงช่วยให้คุณส่งแสงได้... ซึ่งมีธรรมชาติควอนตัมมาก โฟตอนเดี่ยวสามารถตรวจจับได้ด้วยความแม่นยำสูงผ่านสายใยแก้วนำแสงหลายกิโลเมตร นี่ไม่ใช่ช่องสัญญาณควอนตัมที่สมบูรณ์แบบและปราศจากข้อผิดพลาด แต่มันอาจดีมาก
- เราอาจใช้กา รส่งต่อควอนตัม ตามที่อธิบายไว้ในโมดูลก่อนหน้า นั่นคือ Alice และ Bob สามารถแบ่งปัน Qubit ที่พัวพันกันและส่งสถานะจาก Alice ถึง Bob โดยใช้โปรโตคอลการส่งต่อ
สำหรับโมดูลนี้ เราไม่ต้องการให้คุณมีการตั้งค่าออปติกที่มีความแม่นยำสูงสำหรับการแบ่งปันโฟตอน ดังนั้นเราจะใช้วิธีที่สองสำหรับการแบ่งปันสถานะควอนตัม แต่นี่ไม่ได้หมายความว่ามันสมจริงที่สุดสำหรับการแบ่งปันกุญแจควอนตัมระยะไกล
ต่อไปเราจะสำรวจโปรโตคอลที่ Charles Bennett และ Gilles Brassard วางรากฐานไว้ในปี 1984 สำหรับการแบ่งปันสถานะที่วัดในฐาน (basis) ต่างกันจาก Alice ถึง Bob เราจะใช้กระบวนการวัดที่ชาญฉลาดเพื่อสร้างกุญแจสำหรับใช้ในการเข้ารหัสในภายหลัง กล่าวอีกนัยหนึ่ง เราจะกระจายกุญแจควอนตัมระหว่างสองฝ่ายที่ต้องการสื่อสาร ดังนั้นจึงเรียกว่า "กา รกระจายกุญแจเชิงควอนตัม" (QKD)
QKD ขั้นตอนที่ 1: บิตสุ่มและฐานสุ่มของ Alice
Alice จะเริ่มต้นด้วยการสร้างลำดับ 0 และ 1 แบบสุ่ม จากนั้นเธอจะสุ่มเลือกฐาน (basis) ในการเตรียมสถานะควอนตัม โดยอิงจากบิตสุ่มแต่ละบิต โดยใช้ตารางด้านล่าง (ตารางที่ Bob ก็มีเช่นกัน):
| ฐาน | bit = 0 | bit = 1 |
|---|---|---|
| Z | ||
| X |
ตัวอย่างเช่น สมมติว่า Alice สร้าง 0 แบบสุ่มและสุ่มเลือกฐาน X เธอก็จะเตรียมสถานะควอนตัม แน่นอนว่าสามารถใช้ความสุ่มเชิงควอนตัมเพื่อสร้างชุด 0 และ 1 แบบสุ่ม และการเลือกฐานแบบสุ่ม สำหรับตอนนี้ สมมติว่าชุดสุ่มถูกสร้างขึ้นแล้วดังนี้:
| บิตของ Alice | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | ... |
|---|---|---|---|---|---|---|---|---|---|---|
| ฐานของ Alice | X | X | Z | Z | Z | X | Z | Z | X | ... |
| สถานะของ Alice | ... |
ชุดบิตสุ่ม ฐาน และสถานะที่ได้นี้จะดำเนินต่อไปในลำดับที่ยาว เพื่อให้ได้กุญแจที่มีความยาวเพียงพอ
QKD ขั้นตอนที่ 2: ฐานสุ่มของ Bob
Bob ก็สุ่มเลือกฐานเช่นกัน อย่างไรก็ตาม ในขณะที่ Alice ใช้การเลือกฐานเพื่อเตรียมสถานะของเธอ Bob จะทำการวัดในฐานเหล่านี้จริง ๆ ถ้า Bob วัดในฐานเดียวกับที่ Alice เตรียมสถานะ เราสามารถทำนายผลลัพธ์ของการวัด Bob ได้ เมื่อ Bob เลือกฐานที่แตกต่างจากฐานที่ Alice ใช้ในการเตรียม เราไม่สามารถรู้ผลลัพธ์ของการวัด Bob ได้
| บิตของ Alice | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | ... |
|---|---|---|---|---|---|---|---|---|---|---|
| ฐานของ Alice | X | X | Z | Z | Z | X | Z | Z | X | ... |
| สถานะของ Alice | ... | |||||||||
| ฐานของ Bob | X | Z | X | Z | X | X | Z | X | X | ... |
| สถานะของ Bob (a priori) | ? | ? | ? | ? | ... | |||||
| สถานะของ Bob (วัดแล้ว) | ... | |||||||||
| ในตารางด้านล่าง พิจารณาคอลัมน์แรก Alice เตรียมสถานะ ซึ่งเป็น eigenstate ของ X เนื่องจาก Bob ก็สุ่มเลือกวัดในฐาน X เช่นกัน มีผลลัพธ์ที่เป็นไปได้เพียงหนึ่งเดียวสำหรับสถานะที่วัดของ Bob: อย่างไรก็ตาม ในคอลัมน์ที่สอง พวกเขาเลือกฐานต่างกัน สถานะที่ Alice ส่งคือ มีโอกาส 50% ที่ Bob จะวัดในสถานะ และโอกาส 50% ที่จะวัดใน ดังนั้นแถวที่แสดงสิ่งที่เรารู้ a priori เกี่ยวกับกา รวัด Bob ไม่สามารถกรอกสำหรับคอลัมน์ที่ 2 ได้ แต่ Bob จะทำการวัดและได้รับ eigenstate ของ (ในคอลัมน์นั้น) Z ในแถวล่างสุด เราใส่ผลลัพธ์ที่การวัดเหล่านั้นเกิดขึ้นจริง |
QKD ขั้นตอนที่ 3: การพูดคุยสาธารณะเกี่ยวกับฐาน
ตอนนี้ Alice และ Bob สามารถบอกกันได้ว่าพวกเขาเลือกฐานใดในแต่ละกรณี สำหรับคอลัมน์ทั้งหมดที่พวกเขาเลือกฐานเดียวกัน แต่ละคนรู้แน่ชัดว่าอีกฝ่ายมีสถานะใด Bob สามารถแปลงสถานะและฐานเป็น 0 หรือ 1 ตามแบบแผนที่ทั้งสองฝ่ายแบ่งปันกัน เราสามารถเขียนตารางข้างต้นใหม่เพื่อแสดงเฉพาะกรณีที่ฐานของ Alice และ Bob ตรงกัน:
| บิตของ Alice | 0 | 0 | 1 | 0 | 0 | ... |
|---|---|---|---|---|---|---|
| ฐานของ Alice | X | Z | X | Z | X | ... |
| สถานะของ Alice | ... | |||||
| ฐานของ Bob | X | Z | X | Z | X | X |
| สถานะของ Bob (a priori) | ... | |||||
| สถานะของ Bob (วัดแล้ว) | ... | |||||
| บิตของ Bob | 0 | 0 | 1 | 0 | 0 | ... |
Alice ส่งสตริงบิต 00100... ให้ Bob ได้สำเร็จ ถ้าเพื่อน ๆ ตกลงล่วงหน้าว่าจะใช้สตริง 5 บิตเป็นตัวเลขใน one-time pad ห้าบิตแรกจะให้ตัวเลข แก่พวกเขา
QKD ขั้นตอนที่ 4: ยืนยันและส่งความลับ
ก่อนที่ Alice และ Bob จะดำเนินการต่อ พวกเขาควรเลือกกลุ่มย่อยของบิตคลาสสิกของพวกเขาเพื่อเปรียบเทียบ เนื่องจากพวกเขาเก็บการวัด Qubit ที่เตรียมและวัดโดยใช้ฐานเดียวกันเท่านั้น ค่าที่วัดทั้งหมดควรตรงกัน ถ้ามีเปอร์เซ็นต์เล็กน้อยที่ไม่ตรงกัน อาจเกิดจากสัญญาณรบกวนหรือข้อผิดพลาดเชิงควอนตัม แต่ถ้าหลายค่าไม่ตรงกัน มีบางอย่างผิดปกติ!
ที่นี่เราจะไม่พูดถึงว่าควรใช้กุญแจสัดส่วนเท่าไรสำหรับการยืนยัน สำหรับตอนนี้เราจะสมมติว่าการตรวจสอบผ่านไปด้วยดี เราจะกลับมาดูในส่วนด้านล่างเกี่ยวกับการดักฟัง
จากนั้นเพื่อน ๆ จะส่งข้อความที่เข้ารหัสถึงกันผ่านช่องทางคลาสสิก พวกเขาจะใช้ตัวเลขใน one-time pad เพื่อเข้ารหัส/ถอดรหั สข้อความลับ โดยไม่ต้องส่ง one-time pad จากที่หนึ่งไปยังอีกที่หนึ่ง สำหรับส่วนถัดไปเกี่ยวกับการดักฟัง โปรดจำไว้ว่าการแบ่งปันกุญแจทั้งหมดนี้เกิดขึ้นก่อนการเปิดเผยความลับที่เข้ารหัสผ่านช่องทางคลาสสิก
Alice และ Bob สื่อสารฐานที่พวกเขาเลือกผ่านช่องทางคลาสสิก ดังนั้นสิ่งนั้นอาจถูกดักจับได้ใช่ไหม? ใช่! แต่การรู้ว่าพวกเขาใช้ฐานใดสำหรับการวัดไม่ได้บอกคุณว่าพวกเขาส่งหรือได้รับบิตอะไร นั่นเป็นไปได้เฉพาะถ้าคุณรู้บิตเริ่มต้นของ Alice ด้วย แต่ถ้าอย่างนั้นคุณก็อยู่ในคอมพิวเตอร์ของ Alice ที่ความลับถูกเก็บไว้ และการสื่อสารความลับอย่างลับ ๆ ก็ไม่มีความหมาย ดังนั้นการดักจับการสื่อสารคลาสสิกไม่ได้ทำลายการเข้ารหัส แต่การดักจับข้อมูลในช่องสัญญาณควอนตัมล่ะ?
การต้านทาน QKD ต่อการดักฟัง
Alice และ Bob มีเพื่อนชื่อ Eve ที่ขึ้นชื่อเรื่องชอบดักฟัง Eve ต้องการดักจับกุญแจควอนตัมของ Alice และ Bob เพื่อที่เธอจะได้ใช้ถอดรหัสข้อความที่ส่งระหว่างสองคน สิ่งนี้จำเป็นต้องเกิดขึ้นระหว่างการเตรียมสถานะของ Alice และการวัดสถานะของ Bob เนื่องจากการวัดจะทำให้สถานะควอนตัมยุบตัว โดยเฉพาะอย่างยิ่ง หมายความว่าการดักฟังต้องเกิดขึ้น ก่อน ที่จะมีการแบ่งปันหรือเปรียบเทียบฐานใด ๆ
Eve ต้องเดาว่าฐานใดถูกใช้ในการเข้ารหัสแต่ละบิต อีกครั้ง ถ้าเธอไม่สามารถเข้าถึงคอมพิวเตอร์ของ Alice เธอก็ไม่มีหลักฐานอะไรที่จะใช้ในการเดา และมันจะเป็นแบบสุ่ม สมมติว่าการเริ่มต้นของ Alice เหมือนเดิม และสมมติเพิ่มเติมว่าการเลือกฐานการวัดแบบสุ่มของ Bob เหมือนเดิม มาใส่ข ้อมูลที่ Eve ได้รับถ้าเธอทำการวัดของช่องสัญญาณควอนตัม เหมือนเดิม ถ้า Eve เลือกฐานเดียวกับ Alice เราก็รู้ว่าเธอจะได้อะไร ถ้าไม่ เธออาจได้ผลลัพธ์หนึ่งในสองแบบ แต่ละแบบมีความน่าจะเป็น 50%
| บิตของ Alice | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | ... |
|---|---|---|---|---|---|---|---|---|---|---|
| ฐานของ Alice | X | X | Z | Z | Z | X | Z | Z | X | ... |
| สถานะของ Alice | ... | |||||||||
| ฐานที่ Eve เดา | Z | X | X | Z | X | Z | Z | X | X | ... |
| สถานะของ Eve (a priori) | ? | ? | ? | ? | ? | ... | ||||
| สถานะของ Eve (วัดแล้ว) | ... | |||||||||
| ฐานของ Bob | X | Z | X | Z | X | X | Z | X | X | ... |
ตอนนี้เนื่องจาก Eve ไม่รู้ว่าเธอตรงกับฐานของ Alice หรือไม่ เธอไม่รู้ว่าจะส่งต่ออะไรให้ Bob เพื่อให้ตรงกับสถานะเดิมของ Alice เมื่อ Eve วัด ตัวอย่างเช่น สิ่งที่เธอรู้แน่ชัดคือ Alice ไม่ได้ เตรียมสถานะ สำหรับ Qubit นั้น แต่ Alice อาจเตรียม , , หรือ ก็ได้ ทั้งหมดอาจสอดคล้องกับการวัดของ Eve ดังนั้น Eve ต้องเลือก เธออาจส่งต่อสถานะที่เธอวัดได้โดยตรง หรืออาจพยายามเดาว่ากรณีใดที่การวัดของเธอไม่ใช่ eigenstate ที่ Alice ส่ง เราจะรวมทั้งสองแบบในตารางของเรา:
| บิตของ Alice | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | ... |
|---|---|---|---|---|---|---|---|---|---|---|
| ฐานของ Alice | X | X | Z | Z | Z | X | Z | Z | X | ... |
| สถานะของ Alice | ... | |||||||||
| ฐานที่ Eve เดา | Z | X | X | Z | X | Z | Z | X | X | ... |
| สถานะของ Eve (a priori) | ? | ? | ? | ? | ? | ... | ||||
| สถานะของ Eve (วัดแล้ว) | ... | |||||||||
| สถานะของ Eve (ส่งต่อ) | ... | |||||||||
| ฐานของ Bob | X | Z | X | Z | X | X | Z | X | X | ... |
| สถานะของ Bob (a priori) | ? | ? | ... | |||||||
| สถานะของ Bob (วัดแล้ว) | ... | |||||||||
| บิตของ Bob | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | ... |
ตอนนี้สมเหตุสมผลที่จะถามว่า "ทำไม Eve ไม่ทำสำเนาสถานะควอนตัมของ Alice ไว้วัดหนึ่งชุด และส่งอีกชุดให้ Bob?" คำตอบคือ ทฤษฎีบท "no-cloning" โดยไม่เป็นทางกา ร มันบอกว่าไม่มีการดำเนินการยูนิทารี (เชิงกลควอนตัม) ที่สามารถสร้างสำเนาที่สองของสถานะควอนตัมโดยพลการ ในขณะที่รักษาสำเนาแรกไว้ การพิสูจน์นั้นค่อนข้างง่าย และถูกทิ้งไว้เป็นแบบฝึกหัดแบบมีแนวทาง แต่สำหรับตอนนี้ ทำความเข้าใจว่าการที่ Eve ทำสำเนาสถานะควอนตัมถูกห้ามโดยกฎพื้นฐานของธรรมชาติ และนี่คือจุดแข็งหลักของ QKD เหมือนเดิม Alice และ Bob จะโทรหากันและเปรียบเทียบฐาน พวกเขาจะลดตารางนี้เหลือเฉพาะกรณีที่เพื่อนทั้งสองเลือกฐานเดียวกัน:
| บิตของ Alice | 0 | 0 | 1 | 0 | 0 | ... |
|---|---|---|---|---|---|---|
| ฐานของ Alice | X | Z | X | Z | X | ... |
| สถานะของ Alice | ... | |||||
| ฐานที่ Eve เดา | Z | Z | Z | Z | X | ... |
| สถานะของ Eve (a priori) | ? | ? | ... | |||
| สถานะของ Eve (วัดแล้ว) | ... | |||||
| สถานะของ Eve (ส่งต่อ) | ... | |||||
| ฐานของ Bob | X | Z | X | Z | X | ... |
| สถานะของ Bob (a priori) | ? | ... | ||||
| สถานะของ Bob (วัดแล้ว) | ... | |||||
| บิตของ Bob | 1 | 0 | 0 | 0 | 0 | ... |
Alice และ Bob สื่อสารสตริงบิตอีกครั้ง... แต่สตริงไม่ตรงกัน บิตซ้ายสุดและตรงกลางถูกกลับ เมื่อดูตารางก่อนหน้า คุณสามารถติดตามความไม่ตรงกันนี้ไปยังการรบกวนจาก Eve ที่สำคัญ โปรดทราบว่าเราสามารถทำสถิติเกี่ยวกับความตรงกันระหว่างสตริงบิตได้ตอนนี้ ในขณะที่ตั้งค่ากุญแจ นานก่อนที่จะแบ่งปันความลับที่เข้ารหัส Alice และ Bob สามารถใช้บิต one-time pad ของพวกเขาได้มากเท่าที่ต้องการเพื่อตรวจสอบความปลอดภัยของช่องสัญญาณ ถ้าบิตเดียวหรือเปอร์เซ็นต์เล็กน้อยมากที่ไม่ตรงกัน อาจเกิดจากสัญญาณรบกวนหรือข้อผิดพลาด แต่เปอร์เซ็นต์ความไม่ตรงกันที่มากพอสมควรบ่งชี้ถึงการดักฟัง ความหมายของ "มากพอสมควร" ขึ้นอยู่กับสัญญาณรบกวนในการตั้งค่าที่ใช้อยู่บ้าง สำหรับคอมพิวเตอร์ควอนตัม IBM® นั้นหมายความอะไรจะถูกอธิบายด้านล่างเมื่อเราใช้งานโปรโตคอลนี้ ถ้าตรวจพบข้อผิดพลาดมากเกินไป Alice และ Bob จะไม่แบ่งปันความลับ และพวกเขาสามารถเริ่มตามหาผู้ดักฟัง
ข้อจำกัด
การพิสูจน์ความปลอดภัยนั้นยากมาก อันที่จริง โปรโตคอลที่อธิบายไว้อย่างคร่าว ๆ ที่นี่ถูกเสนอในปี 1984 และไม่ได้รับการพิสูจน์ว่าปลอดภัยจนกระทั่ง 16 ปีต่อมา Shor & Preskill, 2000 มีความละเอียดอ่อนหลายอย่างที่อยู่นอกขอบเขตของการแนะนำนี้ แต่เราจะแสดงรายการสั้น ๆ เพื่อแสดงให้เห็นว่าหัวข้อนี้ซับซ้อนกว่าที่แสดงไว้ที่นี่
- ช่องสัญญาณที่ปลอดภัย: เมื่อ Alice ส่ง Qubit ผ่านการตั้งค่าควอนตัมบางอย่าง (ช่องสัญญาณ) และโดยเฉพาะเมื่อเธอได้ยินการตอบสนองคลาสสิกจากใครบางคน เราสมมติว่าคนนั้นคือ Bob จริง ๆ ถ้า Eve แทรกซึมการตั้งค่านี้ในลักษณะที่การสื่อสาร ทั้งหมด ของ Alice เกิดขึ้นกับ Eve จริง ๆ และการสื่อสาร ทั้งหมด ของ Bob เกิดขึ้นกับ Eve จริง ๆ Eve ก็ได้รับกุญแจอย่างมีประสิทธิภาพ และสามารถเรียนรู้ความลับได้ ต้องตรวจสอบ "ช่องสัญญาณที่ปลอดภัย" ก่อน ซึ่งเป็นกระบวนการที่มีโปรโตคอลต่างกันที่เราไม่ได้พูดถึงที่นี่
- สมมติฐานเกี่ยวกับ Eve: เพื่อพิสูจน์ความปลอดภัยอย่างแท้จริง เราไม่สามารถสมมติพฤติกรรมของ Eve ได้ เธออาจทำให้การคาดเดาของเราผิดพลาดเสมอ ที่นี่ เพื่อให้ตัวอย่างที่เป็นรูปธรรม เราตั้งสมมติฐาน ตัวอย่างเช่น เราอาจสมมติว่าสถานะที่ Eve ส่งต่อให้ Bob คือสิ่งที่เธอวัดได้เสมอ หรืออาจสมมติว่าเธอสุ่มเลือกสถานะที่สอดคล้องกับการวัดของเธอ พื้นฐานกว่านั้น ภาษาที่นี่สมมติว่า Eve วัดจริง ๆ เทียบกับการเก็บสถานะไว้ในระบบควอนตัมอื่นและส่ง Qubit แบบสุ่มให้ Bob สมมติฐานเหล่านี้ใช้ได้ดีในการทำความเข้าใจโปรโตคอล แต ่หมายความว่าเราไม่ได้พิสูจน์อะไรในความทั่วไปอย่างเต็มที่
- Privacy amplification: Alice และ Bob ไม่จำเป็นต้องใช้กุญแจควอนตัมตามที่ส่งมาโดยตรง พวกเขาสามารถนำ hash function มาใช้กับกุญแจที่แบ่งปัน เป็นต้น ซึ่งจะใช้ประโยชน์จากข้อเท็จจริงที่ว่าผู้ดักฟังมีความรู้ไม่สมบูรณ์เกี่ยวกับกุญแจ เพื่อสร้างกุญแจที่แบ่งปันที่สั้นกว่าแต่ปลอดภัย
การทดลองที่ 1: QKD โดยไม่มีผู้ดักฟัง
มาใช้งานโปรโตคอลข้างต้นในกรณีที่ไม่มีผู้ดักฟัง เราจะทำสิ่งนี้โดยใช้ simulator ก่อน เพื่อทำความเข้าใจขั้นตอนการทำงาน
ก่อนอื่น หมายเหตุเกี่ยวกับ quantum simulators: ปัญหาควอนตัมส่วนใหญ่ที่มีมากกว่า ~30 Qubit ไม่สามารถจำลองโดยคอมพิวเตอร์ส่วนใหญ่ได้ ไม่มีคอมพิวเตอร์คลาสสิก ซูเปอร์คอมพิวเตอร์ หรือ GPU ใดที่สามารถจำลองพฤติกรรมทั้งหมดของคอมพิวเตอร์ควอนตัม 127 Qubit ได้ ปกติแล้ว แรงจูงใจในการใช้คอมพิวเตอร์ควอนตัมจริงคือ Qubit จำนวนมากที่พัวพันกันไม่สามารถจำลองได้ ในกรณีนี้ ไม่มีการพัวพันของ Qubit เว้นแต่เราจะใช้โครงการส่งต่อเพื่อย้ายข้อมูล ในกรณีนี้ แรงจูงใจในการใช้คอมพิวเตอร์ควอนตัมจริงแตกต่างออกไป: คือทฤษฎีบท no-cloning คอมพิวเตอร์คลาสสิกที่จำลอง Qubit สามารถส่งข้อมูลเกี่ยวกับสถานะควอนตัมจาก Alice ถึง Bob ได้ แต่ถ้าข้อมูลคลาสสิกนี้ถูกดักจับ มันสามารถทำซ้ำได้ง่าย และ Eve สามารถเก็บสำเนาที่สมบูรณ์ ในขณะที่ส่งอีกชุดให้ Bob สิ่งนี้เป็นไปไม่ได้กับสถานะควอนตัมจริง
IBM Quantum แนะนำให้แก้ปัญหาคอมพิวเตอร์ควอนตัมโดยใช้กรอบการทำงานที่เราเรียกว่า "Qiskit patterns" ประกอบด้วยขั้นตอนต่อไปนี้
- ขั้นตอนที่ 1: แมปปัญหาของคุณไปยัง Circuit ควอนตัม
- ขั้นตอนที่ 2: ปรับ Circuit ของคุณให้เหมาะสมสำหรับการรันบนฮาร์ดแวร์ควอนตัมจริง
- ขั้นตอนที่ 3: รันงานบนคอมพิวเตอร์ควอนตัม IBM โดยใช้ Runtime primitives
- ขั้นตอนที่ 4: ประมวลผลผลลัพธ์หลังการทดลอง
Qiskit patterns ขั้นตอนที่ 1: แมปปัญหาของคุณไปยัง Circuit ควอนตัม
ในกรณีนี้ การแมปปัญหาของเราไปยัง Circuit ควอนตัมลดเหลือแค่การเตรียมสถานะของ Alice และรวมการวัดของ Bob เราเริ่มต้นด้วยการเลือกบิตสุ่มและฐานสุ่ม
# 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)
มาแสดงบิต ฐาน และ Circuit ให้เห็น โปรดทราบว่าบางครั้งฐานตรงกัน และบางครั้งไม่ตรงกัน
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.]
Qiskit patterns ขั้นตอนที่ 2: ปรับปัญหาให้เหมาะสมสำหรับการประมวลผลควอนตัม
ขั้นตอนนี้นำการดำเนินการที่ต้องการทำและแสดงออกมาในรูปแบบของฟังก์ชันการทำงานของคอมพิวเตอร์ควอนตัมเฉพาะ มันยังแมปปัญหาของเราไปยังเลย์เอาต์ของคอมพิวเตอร์ควอนตัมด้วย
เราจะเริ่มต้นด้วยการโหลดแพ็คเกจหลายตัวที่จำเป็นสำหรับการสื่อสารกับคอมพิวเตอร์ควอนตัม IBM เราต้องเลือก Backend ที่จะรันด้วย เราสามารถเลือก Backend ที่ไม่ยุ่งที่สุด หรือเลือก Backend เฉพาะที่เรารู้จักคุณสมบัติ แม้ว่าเราจะใช้ simulator ชั่วครา ว แต่สำคัญที่จะใช้โมเดลสัญญาณรบกวนที่สมเหตุสมผลในการจำลอง และดีที่จะรักษาขั้นตอนการทำงานให้ใกล้เคียงกับที่เราจะใช้ในภายหลังสำหรับคอมพิวเตอร์ควอนตัมจริงมากที่สุด
มีโค้ดด้านล่างสำหรับบันทึกข้อมูลรับรองเมื่อใช้ครั้งแรก อย่าลืมลบข้อมูลนี้ออกจาก notebook หลังจากบันทึกลงในสภาพแวดล้อมของคุณ เพื่อที่ข้อมูลรับรองของคุณจะไม่ถูกแบ่งปันโดยไม่ตั้งใจเมื่อคุณแบ่งปัน notebook ดู ตั้งค่าบัญชี IBM Cloud และ เริ่มต้นบริการในสภาพแวดล้อมที่ไม่น่าเชื่อถือ สำหรับคำแนะนำเพิ่มเติม
# 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
ด้านล่างเราเลือก simulator และโมเดลสัญญาณรบกวน
# Load the backend sampler
from qiskit.primitives import BackendSamplerV2
# Load the Aer simulator and generate a noise model based on the currently-selected backend.
from qiskit_aer import AerSimulator
from qiskit_aer.noise import NoiseModel
# Load the qiskit runtime sampler
from qiskit_ibm_runtime import SamplerV2 as Sampler
noise_model = NoiseModel.from_backend(backend)
# Define a simulator using Aer, and use it in Sampler.
backend_sim = AerSimulator(noise_model=noise_model)
sampler_sim = BackendSamplerV2(backend=backend_sim)
# Qiskit patterns step 2: Transpile
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)
Qiskit patterns ขั้นตอนที่ 3: รัน
ใช้ Sampler เพื่อรันงานของคุณ โดยมี Circuit เป็น argument
# This required 5 s to run on a Heron r2 processor on 10-28-24
sampler = Sampler(mode=backend)
job = sampler.run([qc_isa], shots=1)
# job = sampler_sim.run([qc], shots = 1)
counts = job.result()[0].data.c.get_counts()
countsint = job.result()[0].data.c.get_int_counts()
Qiskit patterns ขั้นตอนที่ 4: การประมวลผลหลังการทดลอง
ที่นี่เราตีความผลลัพธ์และดึงข้อมูลที่เป็นประโยชน์ เราอาจลองแสดงผลลัพธ์จาก Sampler ของเรา แต่เราใช้ Sampler ในลักษณะที่ไม่ปกติ แทนที่จะวัด Circuit หลายครั้งและพัฒนาสถิติเกี่ยวกับสถานะ เราวัดเพียงครั้งเดียว (ของ Bob) Qubit ใด ๆ ที่มีสถานะที่เตรียมและวัดในฐานเดียวกันควรมีผลลัพธ์ที่กำหนดได้แน่นอน จนต้องการการวัดเพียงครั้งเดียว Qubit ที่มีสถานะที่เตรียมและวัดในฐานต่างกัน (ซึ่งจะมีผลลัพธ์ที่น่าจะเป็นและต้องการการวัดหลายครั้งในการตีความ) จะไม่ถูกใช้ในการสร้าง one-time pad/กุญแจ มาดึงรายการผลลัพธ์การวัดจากสตริงบิตนี้ ระวังการกลับลำดับถ้าเปรียบเทียบกับ array บิตของ Alice ที่เราใช้สร้าง Circuit
# Get an array of bits
keys = counts.keys()
key = list(keys)[0]
bmeas = list(key)
bmeas_ints = []
for n in range(bit_num):
bmeas_ints.append(int(bmeas[n]))
# Reverse the order to match our input. See "little endian" notation.
bbits = bmeas_ints[::-1]
print(bbits)
[1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0]
มาเปรียบเทียบฐานการวัดที่ Alice และ Bob เลือกแบบสุ่ม นี่คือขั้นตอนที่ 3 ในโปรโตคอล QKD (การพูดคุยสาธารณะเกี่ยวกับฐาน) ทุกครั้งที่พวกเขาเลือกฐานเดียวกันสำหรับ Qubit เราจะเพิ่มบิตที่เกี่ยวข้องกับ Qubit นั้นเข้าไปในรายการบิตสำหรับสร้างตัวเลขใน one-time pad เมื่อฐานไม่ตรงกัน ผลลัพธ์จะถูกทิ้ง มาตรวจสอบด้วยว่ารายการบิตทั้งสองตรงกัน หรือมีการสูญเสียใด ๆ เนื่องจากสัญญาณรบกวนหรือปัจจัยอื่น ๆ
# 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 และ Bob แต่ละคนมีรายการบิต และตรงกัน 100% พวกเขาสามารถใช้สิ่งเหล่านี้สร้างตัวเลขใน one-time pad จากนั้นสามารถใช้ในขั้นตอนที่ 4 ของ QKD: การส่งและถอดรหัสความลับ array บิตปัจจุบันสั้นเกินไปที่จะถอดรหัสอะไรได้มาก เราจะกลับมาดูสิ่งนี้หลังจากรวมการดักฟัง
ตรวจสอบความเข้าใจ
อ่านคำถามด้านล่าง คิดคำตอบของคุณ จาก นั้นคลิกสามเหลี่ยมเพื่อดูคำตอบ
สมมติว่าคุณต้องการตัวเลขที่ใหญ่พอที่จะเลื่อนตัวอักษรในตัวอักษรภาษาอังกฤษตามความยาวทั้งหมดของตัวอักษรหรือมากกว่า แม้ว่าจะมีรูปแบบการเข้ารหัสอื่น ๆ อีกแน่นอน
(a) ข้อความยาวกี่ตัวอักษรที่สามารถถอดรหัสได้โดยใช้บิตในกุญแจข้างต้น? (b) คำตอบของคุณต้องตรงกับเพื่อนร่วมชั้นหรือไม่? ทำไมหรือทำไมไม่?
คำตอบ:
(a) คำตอบขึ้นอยู่กับจำนวนฐานที่เลือกแบบสุ่มที่ตรงกันระหว่าง Alice และ Bob เนื่องจากมีโอกาสประมาณ 50-50 ที่ฐานจะตรงกันสำหรับ Qubit ใด ๆ เราคาดว่าบิตประมาณ 10 จาก 20 ตัวจะมีประโยชน์ 9 หรือ 11 เป็นเรื่องปกติมาก แม้แต่ 4 หรือ 15 ก็ไม่ใช่เรื่องที่เป็นไปไม่ได้ ต้องใช้ 5 บิตเพื่อเลื่อนตัวเลขที่มากกว่าหรือเท่ากับความยาวของตัวอักษรภาษาอังกฤษ หมายความว่าคุ ณสามารถใช้การเลื่อนกับตัวอักษรหนึ่งตัวสำหรับทุก ๆ 5 บิตที่คุณมี ถ้าคุณมีบิตอย่างน้อย 5 บิตที่แบ่งปันโดย Alice และ Bob คุณสามารถเข้ารหัสตัวอักษรเดียวได้ ถ้าคุณมีอย่างน้อย 10 คุณสามารถเข้ารหัสได้ 2 ตัวอักษร และอื่น ๆ (b) ไม่จำเป็นต้องตรงกัน ด้วยเหตุผลที่อธิบายไว้ใน (a)
การทดลองที่ 2: QKD กับผู้ดักฟัง
เราจะใช้โปรโตคอลเดียวกับก่อนหน้าทุกประการ คราวนี้เราจะแทรกชุดการวัดอีกชุดหนึ่งโดย Eve ระหว่าง Alice และ 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()
ขั้นตอนที่ 4 ของ Qiskit patterns (การประมวลผลหลังการทดลอง) ง่ายในกรณีนี้ ไม่จำเป็นต้องแสดงการกระจายของการวัด เนื่องจากเราวัดเพียงครั้งเดียว Eve มีบิตต่อไปนี้:
keys = counts.keys()
key = list(keys)[0]
emeas = list(key)
emeas_ints = []
for n in range(bit_num):
emeas_ints.append(int(emeas[n]))
ebits = emeas_ints[::-1]
print(ebits)
[0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1]
ตอนนี้ Eve ต้องสร้างสถานะใหม่เพื่อส่งต่อให้ Bob ตามที่อธิบายไว้ในบทนำ เธอไม่มีทางรู้ว่าเธอเดาฐานการเข้ารหัสถูกต้องหรือไม่ ดังนั้นเธอจึงไม่สามารถเตรียมสถานะเดียวกับที่ส่งมาได้พอดี เธออาจสมมติว่าการเลือกฐานทุกครั้งถูกต้องและเข้ารหัสสิ่งที่เธอวัดได้โดยตรง หรืออาจสมมติว่าเธอเลือกฐานผิดและเลือก eigenstate ใดก็ได้ของฐานตรงข้าม ที่นี่เราสมมติว่าอย่างแรกเพื่อความง่าย เราทำสิ่งนี้โดยสร้าง Circuit ควอนตัมใหม่ทั้งหมด ทำซ้ำขั้นตอน Qiskit patterns ดังก่อนหน้า
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]
มาเปรียบเทียบบิตของ Alice และ 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
ก่อนหน้านี้มีการตรงกันสมบูรณ์แบบระหว่างบิตในกุญแจของ Alice และ Bob ตอนนี้ จากการรบกวนของ Eve เราเห็นว่าบิตของ Alice และ Bob แตกต่างกัน 14% ของกรณีที่ควรตรงกันเนื่องจาก Alice และ Bob เลือกฐานเดียวกัน สิ่งนี้น่าจะตรวจจับได้ง่ายสำหรับ Alice และ Bob อย่างไรก็ตาม การพึ่งพาเปอร์เซ็นต์ข้อผิดพลาดแบบนี้หมายความว่ามีขีดจำกัดสำหรับจำนวนสัญญาณรบกวนที่เราสามารถทนได้ในช่องสัญญาณควอนตัม
การทดลองที่ 3: เปรียบเทียบ QKD กับและไม่มีการดักฟังบนคอมพิวเตอร์ควอนตัมจริง
มารันสิ่งนี้บนคอมพิวเตอร์ควอนตัมจริง วิธีนั้นเราสามารถใช้ประโยชน์จากทฤษฎีบท no-cloning ในขณะเดียวกัน คอมพิวเตอร์ควอนตัมจริงมีสัญญาณรบกวน และมีอัตราข้อผิดพลาดที่สูงกว่าคอมพิวเตอร์คลาสสิก ดังนั้นมาเปรียบเทียบการสูญเสียความแม่นยำของบิตกุญแจของเราทั้งกับและไม่มีการดักฟัง เพื่อให้แน่ใจว่าความแตกต่างนั้นตรวจจับได้เมื่อใช้คอมพิวเตอร์ควอนตัมจริง เราจะเริ่มต้นในกรณีที่ไม่มีการดักฟัง:
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
โดยไม่มีการดักฟัง เราได้รับความแม่นยำ 100% สำหรับบิตทดสอบ 127 ชุดนี้ ส่งผลให้ได้ฐานที่ตรงกัน 55 ฐาน และบิตกุญแจที่ใช้งานได้ ตอนนี้มาทำซ้ำการทดลองนี้โดยมี Eve ดักฟัง:
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
ที่นี่เราพบการสูญเสียความแม่นยำเกือบ 23% ของบิตที่แบ่งปันเนื่องจากการดักฟัง! สิ่งนี้ตรวจจับได้ง่ายมาก โปรดทราบว่าการถ่ายโอนข้อมูลควอนตัมในระยะทางไกลอาจยังคงมีสัญญาณรบกวนและข้อผิดพลาดเพิ่มเติม การรับประกันว่าสามารถตรวจจับการดักฟังได้แม้ในสภาวะที่มีสัญญาณรบกวน และแม้แต่เมื่อ Eve ใช้เทคนิคทั้งหมดที่มีอยู่ในมือเธอ เป็นสาขาที่ซับซ้อนเกินขอบเขตของบทนำนี้
คำถาม
อาจารย์สามารถขอรับเวอร์ชัน notebook ที่มีเฉลยและคำแนะนำเกี่ยวกับการวางในหลักสูตรทั่วไปได้โดยกรอกแบบสำรวจสั้น ๆ นี้เกี่ยวกับวิธีใช้ notebook
แนวคิดหลัก
- ข้อมูลควอนตัมไม่สามารถคัดลอกหรือ "โคลน" ได้
- คุณ สามารถ ทำซ้ำกระบวนการเตรียมการเดิมเพื่อสร้างกลุ่มสถานะควอนตัมที่เหมือนกันทั้งหมด หรือเกือบเหมือนกัน
- กุญแจเข้ารหัส/ถอดรหัส (one-time pad) สามารถแบ่งปันระหว่างเพื่อนสองคนโดยใช้สถานะควอนตัม
- เพื่อนสองคนที่เลือกฐานการวัดแบบสุ่มหมายความว่าครึ่งหนึ่งของเวลาพวกเขาจะเลือกต่างกัน และจะต้องทิ้งข้อมูลบน Qubit เหล่านั้น
- การเลือกฐานการวัดแบบสุ่มยังทำให้มั่นใจว่าผู้ดักฟังไม่สามารถรู้สถานะเริ่มต้นที่เตรียมไว้ได้ และจึงไม่สามารถสร้างสถานะที่ส่งมาใหม่ได้ สิ่งนี้ทำให้มั่นใ จว่าการดักฟังจะถูกตรวจจับ
คำถาม จริง/เท็จ
- จ/ผ ในการกระจายกุญแจเชิงควอนตัม คู่สื่อสารทั้งสองวัด Qubit แต่ละตัวในฐานเดียวกัน
- จ/ผ ผู้ดักฟังที่ดักจับข้อมูลควอนตัมใน QKD ถูกป้องกันไม่ให้คัดลอกสถานะควอนตัมที่ดักจับโดยกฎของธรรมชาติ
- จ/ผ One-time pad คือกุญแจสำหรับการเข้ารหัส/ถอดรหัสข้อความที่ปลอดภัยซึ่งรูปแบบการเข้ารหัสเฉพาะถูกใช้เพียงครั้งเดียว สำหรับข้อมูลชิ้นเดียว (เช่น ตัวอักษรหนึ่งตัวในตัวอักษร)
คำถามตัวเลือก
- เลือกตัวเลือกที่ดีที่สุดในการเติมประโยคให้สมบูรณ์ ตามที่อธิบายไว้ในโมดูลนี้ one-time pad คือชุดกุญแจเข้ารหัส/ถอดรหัสที่ใช้...
- a. เพียงครั้งเดียวสำหรับข้อมูลชิ้นเดียว เช่น ตัวอักษรเดียว
- b. เพียงครั้งเดียวสำหรับข้อความเดียว
- c. เพียงครั้งเดียวในช่วงเวลาที่กำหนด เช่น หนึ่งวัน
- d. จนกว่าจะมีหลักฐานการดักฟัง
- สมมติว่า Alice และ Bob เลือกฐานการวัดแบบสุ่ม พวกเขาวัด จากนั้นแบ่งปันฐานการวัด และเก็บเฉพาะบิตของข้อมูลจากกรณีที่พวกเขาใช้ฐานเดียวกัน ขึ้นอยู่กับความผันผวนแบบสุ่มบางส่วน ประมาณเปอร์เซ็นต์เท่าไรของ Qubit ของพวกเขาที่ควรให้บิตข้อมูลที่ใช้งานได้?
- a. 100%
- b. 50%
- c. 25%
- d. 12.5%
- e. 0%
- หลังจาก Alice และ Bob เลือกกรณีที่พวกเขาใช้ฐานการวัดเดียวกัน เปอร์เซ็นต์ของบิตข้อมูลเหล่านั้นที่ควรตรงกัน ถ้าสัญญาณรบกวนและข้อผิดพลาดเชิงควอนตัมไม่ม ีนัยสำคัญ คือเท่าไร?
- a. 100%
- b. 50%
- c. 25%
- d. 12.5%
- e. 0%
- สมมติว่า Alice เลือกฐานการวัดแบบสุ่ม Eve ก็เลือกฐานแบบสุ่ม และเธอดักฟัง (วัด) เธอส่งสถานะต่อให้ Bob ที่สอดคล้องกับการวัดของเธอ Alice และ Bob เปรียบเทียบการเลือกฐานและเก็บเฉพาะ Qubit ที่วัด/เตรียมโดยพวกเขาในฐานเดียวกัน ขึ้นอยู่กับความผันผวนแบบสุ่มบางส่วน ประมาณเปอร์เซ็นต์เท่าไรของ Qubit ที่เก็บไว้นั้นที่การวัดจะตรงกัน ตามที่ Alice และ Bob ระบุ?
- a. 100%
- b. 75%
- c. 50%
- d. 25%
- e. 12.5%
- f. 0%
คำถามอภิปราย
-
สมมติว่าการเลือกฐานทั้งหมดเป็นแบบสุ่มสำหรับผู้เข้าร่วมทุกคน ทั้ง Alice, Bob และ Eve สมมติว่าหลังจาก Eve ดักฟัง เธอส่งสถานะให้ Bob ที่เต รียมในฐานเดียวกับที่เธอวัด และสอดคล้องกับการวัดนั้น โน้มน้าวให้คู่ของคุณเห็นว่า 12.5% ของ Qubit ทั้งหมดที่ Alice เริ่มต้นจะให้ความไม่ตรงกันของการวัดระหว่าง Alice และ Bob บ่งชี้ถึงการดักฟัง (โดยไม่สนใจข้อผิดพลาดและสัญญาณรบกวนเชิงควอนตัม) คำใบ้ที่ 1: เนื่องจากไม่มีฐานที่ดีกว่าฐานอื่น ถ้าคุณพิจารณาแค่การเลือกเริ่มต้นเดียวสำหรับ Alice อัตราส่วนสำหรับการเลือกนั้นควรเหมือนกับอัตราส่วนสำหรับผลรวมของการเลือกทั้งหมด คำใบ้ที่ 2: อาจไม่เพียงพอที่จะนับจำนวนวิธีที่บางอย่างอาจเกิดขึ้น เนื่องจากผลลัพธ์บางอย่างอาจเกิดขึ้นด้วยความน่าจะเป็นที่ต่างกัน
-
สมมติอีกครั้งว่าการเลือกฐานทั้งหมดเป็นแบบสุ่มสำหรับผู้เข้าร่วมทุกคน ทั้ง Alice, Bob และ Eve แต่ตอนนี้ พิจารณาว่า Eve มีอิสระที่จะส่งสถานะใดก็ได้หลังจากการวัดของเธอ เธออาจลองส่งสถานะที่ไม่สอดคล้องกับการวัดของเธอเองด้วยซ้ำ อภิปรายกับคู่/เพื่อนบ้านของคุณว่าคุณคิดว่ามีการเลือกฐานใดก็ตามที่สามารถลดเปอร์เซ็นต์เฉลี่ยของ Qubit ที่บ่งชี้การดักฟังให้กับ Alice และ Bob ได้หรือไม่