Skip to main content
IBM Quantum Platform

양자 키 배포

이 교실 내 키스킷 모듈을 사용하려면 학생에게 다음 패키지가 설치된 Python 환경이 있어야 합니다:

  • qiskit v2.1.0 이상
  • qiskit-ibm-runtime v0.40.1 이상
  • qiskit-aer v0.17.0 이상
  • qiskit.visualization
  • numpy
  • pylatexenc

위의 패키지를 설정하고 설치하려면 키스킷 설치 가이드를 참조하세요. 실제 양자 컴퓨터에서 작업을 실행하려면 학생들은 IBM Cloud 계정 설정 가이드의 단계에 따라 IBM Quantum®에 계정을 설정해야 합니다.

이 모듈은 5초의 QPU 시간을 테스트하고 사용했습니다. 이는 추정치일 뿐입니다. 실제 사용량은 다를 수 있습니다.

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

아래에서 케이티 박사( McCormick )의 모듈 워크스루를 시청하거나 여기를 클릭하여 YouTube 에서 시청하세요.



서론 및 동기

정보를 암호화하고 해독하는 방법은 무한히 많으며, 말 그대로 수천 가지의 방법이 잘 연구되어 있습니다. 여기서는 이 프로토콜의 양자 부분에 집중하기 위해 '단순 대체'라고 하는 매우 초기의 매우 간단한 암호화 방법으로 제한하겠습니다. 양자 부분은 비교적 적은 변경만으로 다른 많은 프로토콜에 적용할 수 있습니다.

단순 교체

단순 대체 암호화는 한 문자나 숫자를 다른 문자나 숫자로 대체하여 메시지의 문자와 숫자에서 암호화된 시퀀스에 사용되는 문자와 숫자로 1:1 매핑을 만드는 암호화입니다. 대중문화에서 흔히 볼 수 있는 예로는 간단한 대체를 통해 명언이나 문구를 암호화하고 플레이어가 이를 해독하는 크립토퀘스트 또는 암호 퍼즐을 들 수 있습니다. 길이가 충분히 길면 쉽게 해결할 수 있습니다. 예를 들어 보겠습니다:

R wvxrwvw gszg r'w yvggvi nzpv gsrh kivggb OLMT. GSZG DZB, KVL코프 드로우 ZM VJRVI GRNV HLOERMT RG. R SLKV R NZWV RG HRNKOV VMLFTS.

수작업으로 해결하는 사람들은 대부분 원래 메시지의 언어 구조에 익숙한 트릭을 사용합니다. 예를 들어, 영어에서 암호화된 "R"과 같은 한 글자 단어는 "a"와 "I"뿐입니다. 예를 들어 'KIVGGB'로 암호화된 이중 문자는 특정 값만 사용할 수 있습니다. "GSZG" 패턴에 맞는 가장 일반적인 단어는 "그"와 같이 단서를 제공하는 미묘한 것들이 있습니다. 코드를 사용하여 이 문제를 해결하는 사람들은 단순히 영어 단어가 복구될 때까지 가능성을 스캔하고 해당 단어를 보존하면서 업데이트하는 등 더 많은 옵션이 있습니다. 간단하지만 강력한 방법 중 하나는 문자 빈도를 사용하는 것인데, 특히 메시지가 영어의 대표적인 샘플을 구성할 수 있을 정도로 긴 경우에는 더욱 그렇습니다.

체크인 질문

원하신다면 이 내용을 해독해 보세요. 다만, 이 모듈의 나머지 부분을 진행하는 데 꼭 필요한 것은 아닙니다. 아래의 “답변”을 클릭하면 메시지를 볼 수 있습니다.

  • 저는 이 글을 꽤 길게 쓰는 것이 좋겠다고 생각했습니다. 이렇게 하면 사람들이 문제를 더 쉽게 해결할 수 있습니다. 충분히 간단하게 만들었기를 바랍니다.

위의 예는 암호화된 문자에서 해독된 문자로의 매핑인 '키'와 연관되어 있습니다. 이 경우 핵심은 다음과 같습니다:

  • A(사용되지 않음, Z라고 함)
  • B->Y
  • C(사용되지 않음, X라고 함)
  • D->W
  • E->V
  • F->U
  • ...

작업을 계속 수행합니다. 간단히 말해서 이것은 좋은 키가 아닙니다. 암호화 및 복호화된 문자가 단순히 알파벳의 시프트 버전인 키(예: A->B, B->C)를 "시저 시프트" 암호라고 합니다.

길이가 짧으면 매우 어렵다는 점에 유의하세요. 실제로 매우 짧으면 불확실한 것입니다. 다음을 고려하십시오.

URYYP

다양한 키를 사용하여 암호를 해독할 수 있습니다: 안녕하세요, 사소한, 행복한, 지그재그, 스툴. 다른 사람이 생각나시나요?

하지만 이렇게 많은 메시지를 보내면 결국에는 암호화가 해독됩니다. 따라서 같은 '키'를 너무 자주 사용하지 않아야 합니다. 사실, 가장 좋은 방법은 특정 대체물을 한 번만 사용하는 것입니다. 하나의 메시지가 아니라 단 한 명의 캐릭터에게만! 즉, 메시지에 사용된 각 문자에 대한 암호화 체계 또는 키를 순서대로 갖게 된다는 뜻입니다. 이 메시지를 사용하여 친구에게 메시지를 보내려면, 여러분과 친구는 이 변화무쌍한 열쇠가 적힌 종이를 준비해야 합니다(옛날에는). 이 기능은 한 번만 사용할 수 있습니다. 이를 '일회용 패드'라고 합니다.

일회용 패드

예시를 통해 어떻게 작동하는지 살펴보겠습니다. 문자로만 변환할 수도 있지만 A=0, B=1, C=2… 과 같이 문자에서 숫자로 변환하는 것이 일반적입니다. 우리가 비밀스러운 활동을 하는 친구이고 패드를 공유했다고 가정해 보겠습니다. 이상적으로는 여러 개의 패드를 공유하는 것이 좋지만 현재는 그렇지 않습니다:

EDGRPOJNCUWQZVMK.

또는 알파벳 순서에 따라 숫자로 변환할 수도 있습니다:

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

여러분과 공유하고 싶은 메시지가 있다고 가정해 보겠습니다:

"저는 퀀텀을 사랑합니다!"

또는 이와 동등하게:

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

위의 코드는 보안이 전혀 보장되지 않는 단순한 대체 코드입니다. 우리는 이것을 어떤 식으로든 키와 결합하고 싶습니다. 일반적인 방법은 모듈 26을 더하는 것입니다. 메시지의 끝에 도달할 때까지 키의 값인 모드 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

누군가 이를 가로채고 열쇠를 가지고 있지 않다면 암호를 해독하는 것은 완전히 불가능합니다! "양자"의 두 "유"도 같은 숫자로 인코딩되지 않습니다! 첫 번째는 3, 두 번째는 16... 같은 단어입니다!

그래서 제가 이걸 보내면 여러분도 저와 같은 열쇠를 갖게 됩니다. 제가 수행한 추가 모듈 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.

마지막으로, 이를 텍스트로 변환하면 다음과 같습니다

"저는 퀀텀을 사랑합니다".

이것은 일회성 패드입니다.

키가 메시지보다 짧으면 인코딩을 반복하기 시작한다는 점에 유의하세요. 여전히 풀기 어려운 암호 해독 문제이지만 충분히 반복하면 불가능하지는 않습니다. 따라서 긴 키(또는 '패드')가 필요합니다.

Note

많은 상황에서 학생들은 이미 이 암호화에 익숙할 것이므로 이 활동은 건너뛸 수 있습니다. 하지만 비교적 빠르고 간단한 리프레시입니다.

1단계: 파트너를 구하고, 키로 사용할 4글자 시퀀스를 공유합니다. 클래스에 적합한 4글자 시퀀스라면 무엇이든 가능합니다. \ 2단계: 파트너에게 보낼 4글자 비밀 단어를 선택합니다(두 파트너가 서로 다른 비밀 단어를 보낼 수 있도록 이 작업을 수행합니다) \ 3단계: 4글자 키/패드와 각 4글자 비밀 단어를 A = 1, B = 2 등을 사용하여 숫자로 변환합니다. \ 4단계: 모듈로 26 덧셈을 사용하여 4글자 단어를 일회성 패드와 결합합니다. \ 5단계: 파트너에게 비밀 단어를 암호화하는 일련의 숫자를 건네면 파트너가 자신의 비밀 단어를 건네줍니다. \ 6단계: 모듈로 26 뺄셈을 사용하여 서로의 단어를 해독합니다. \ 7단계: 확인. 성공했나요?

후속 작업

암호화된 단어를 일회용 패드에 액세스할 수 없는 다른 그룹과 교환하세요. 해독할 수 있나요? 그 이유 또는 이유를 설명하세요

위의 활동을 통해 다음과 같은 몇 가지 가정 하에 일회용 패드가 깨지지 않는 암호화 형태라는 점을 분명히 알 수 있기를 바랍니다:

  • 키는 전송되는 메시지와 같거나 더 긴 길이입니다
  • 열쇠는 정말 무작위입니다
  • 키는 한 번만 사용된 후 폐기됩니다

그래서 이것은 훌륭합니다. 깨지지 않는 암호화가 있습니다... 누군가 열쇠를 가져가지 않는다면요. 누군가 키를 입수하면 모든 것이 해독됩니다. 깨지지 않는 암호화와 모든 비밀이 노출되는 것의 차이는 보안 키 공유가 매우 중요하다는 것을 의미합니다. 양자 키 분배의 목표는 자연이 양자 정보에 부과한 제약을 활용하여 공유 키/원타임 패드를 확보하는 것입니다.


양자 상태를 열쇠로 사용하여

큐비트로 작업한다고 가정해 보겠습니다(큐비트에는 두 가지 고유 상태가 있다는 점을 강조합니다). 양자 상태의 수가 많은 양자 시스템을 사용할 수도 있지만, IBM® 의 최첨단 양자 컴퓨터는 큐비트를 사용합니다. A, B, C를 0’s 및 1’s 의 시퀀스로 인코딩하는 것은 문제가 되지 않습니다. 따라서 0’s 및 1’s 키를 공유하고 문자를 저장하는 각 비트에 모듈로 2를 더하면 충분합니다.

이해도 점검

정말 영문자만 신경 쓴다면 얼마나 많은 비트가 필요할까요?

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

친구인 앨리스와 밥은 양자 키를 다른 사람이 가로챌 수 없도록(적어도 자신들 모르게는) 공유하고자 합니다. 양자 상태를 서로에게 전송할 수 있는 방법이 필요합니다. 노이즈/오류 없이 높은 충실도로 이 작업을 수행하는 것은 결코 쉬운 일이 아닙니다. 하지만 이 시점에서 우리가 이해할 수 있어야 하는 두 가지 접근 방식이 있습니다:

  1. 광섬유 케이블을 사용하면 매우 양자 기계적인 방식으로 빛을 전송할 수 있습니다. 단일 광자는 수 킬로미터의 광섬유 케이블을 통해 높은 충실도로 감지할 수 있습니다. 이것은 완벽하고 오류가 없는 양자 채널은 아니지만, 매우 좋은 채널일 수 있습니다.
  2. 이전 모듈에서 설명한 것처럼 양자 순간 이동을 사용할 수 있습니다. 즉, 앨리스와 밥이 얽힌 큐비트를 공유하고 텔레포트 프로토콜을 사용하여 앨리스에서 밥으로 상태를 전송할 수 있습니다.

이 모듈에서는 광자 공유를 위한 고충실도 광학 설정이 필요하지 않으므로 양자 상태 공유를 위해 두 번째 방법을 사용하겠습니다. 그러나 이것이 양자 키의 장거리 공유에 가장 현실적이라고 말할 수는 없습니다.

이제 1984년 찰스 베넷과 질 브라사드가 앨리스에서 밥까지 서로 다른 기준에서 측정된 상태를 공유하기 위해 처음 제시한 프로토콜을 살펴보겠습니다. 이후 암호화에 사용할 키를 구축하기 위해 영리한 측정 방식을 사용합니다. 즉, 통신을 원하는 두 당사자 간에 양자 키를 배포하는 것을 '양자 키 배포'(QKD)라고 합니다.

양자 키 분배 1단계: 앨리스의 난수 비트와 난수 기저

Alice는 0과 1의 무작위 시퀀스를 생성하는 것으로 시작합니다. 그런 다음 아래 표(밥도 가지고 있는 표)를 사용하여 각 무작위 비트에 따라 양자 상태를 준비할 기준을 무작위로 선택합니다:

기본
비트 = 0
비트 = 1
Z0\vert 0\rangle1\vert 1\rangle
X+\vert +\rangle\vert -\rangle

예를 들어 앨리스가 무작위로 0을 생성하고 X 베이스를 무작위로 선택했다고 가정해 보겠습니다. 그런 다음 양자 상태 ψ=+x=12(0+1)|\psi\rangle = |+\rangle_x = \frac{1}{\sqrt{2}}(|0\rangle+|1\rangle) 를 준비합니다. 양자 무작위성을 활용하여 0과 1의 무작위 집합과 무작위 기저 선택을 생성할 수 있습니다. 지금은 다음과 같이 무작위 세트가 생성되었다고 가정해 보겠습니다:

앨리스의 비트
0
1
0
0
1
1
0
1
0
...
앨리스의 기지XXZZZXZZX...
앨리스의 상태+\vert +\rangle\vert -\rangle0\vert 0\rangle0\vert 0\rangle1\vert 1\rangle\vert -\rangle0\vert 0\rangle1\vert 1\rangle+\vert +\rangle...

이 임의의 비트, 염기 및 결과 상태의 집합은 충분한 길이의 키를 제공하기 위해 긴 시퀀스로 계속됩니다.

양자 키 분배 2단계: 밥의 무작위 베이스

밥은 또한 무작위로 기지를 선택합니다. 그러나 앨리스가 기본 선택을 사용하여 상태를 준비했다면, 밥은 실제로 이러한 기본에서 측정을 수행합니다. 밥이 앨리스가 상태를 준비한 것과 동일한 기준으로 측정을 수행하면 밥의 측정 결과를 예측할 수 있습니다. 밥이 앨리스가 준비할 때 사용한 기준과 다른 기준을 선택하면 밥의 측정 결과를 알 수 없습니다.

앨리스의 비트
0
1
0
0
1
1
0
1
0
...
앨리스의 기지XXZZZXZZX...
앨리스의 상태+\vert +\rangle\vert -\rangle0\vert 0\rangle0\vert 0\rangle1\vert 1\rangle\vert -\rangle0\vert 0\rangle1\vert 1\rangle+\vert +\rangle...
밥의 베이스XZXZXXZXX...
밥의 상태(선험적)+\vert +\rangle??0\vert 0\rangle?\vert -\rangle0\vert 0\rangle?+\vert +\rangle...
밥의 상태(측정된)+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle+\vert +\rangle\vert -\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle...

아래 표에서 첫 번째 열을 살펴보십시오. 앨리스는 X의 고유상태인 +\vert +\rangle 상태를 준비했습니다. 밥 역시 무작위로 X 기저에서 측정을 선택했기 때문에, 밥이 측정한 상태에 대한 가능한 결과는 단 하나뿐입니다: +\vert +\rangle. 그러나 두 번째 열에서는 두 사람이 서로 다른 기저를 선택했습니다. 앨리스가 보낸 상태는 =12(01)\vert -\rangle = \frac{1}{\sqrt{2}}(\vert 0\rangle-\vert 1 \rangle) 입니다. 이 상태는 밥이 0\vert 0\rangle 상태에서 측정할 확률이 50%이고, 1\vert 1\rangle 상태에서 측정할 확률도 50%입니다. 따라서 밥의 측정 결과에 대해 우리가 선험적으로 알고 있는 내용을 나타내는 행은 2열에 기입할 수 없습니다. 하지만 밥은 측정을 수행하여 (해당 열에서) Z의 고유상태를 구해낼 것이다. 맨 아래 줄에는 이러한 측정 결과로 도출된 수치를 기입합니다.

QKD 단계 3: 기반에 대한 공개 토론

이제 앨리스와 밥은 각 사례에서 어떤 기준을 선택했는지 서로 공유할 수 있습니다. 우연히 같은 기준을 선택한 모든 열에 대해, 그들은 각각 상대방이 어떤 상태인지 확실히 알고 있습니다. Bob은 양 당사자가 공유하는 규칙에 따라 상태와 베이스를 0 또는 1로 변환할 수 있습니다. 위의 표를 다시 작성하여 앨리스와 밥의 기지가 일치하는 경우만 표시할 수 있습니다:

앨리스의 비트
0
0
1
0
0
...
앨리스의 기지XZXZX...
앨리스의 상태+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle+\vert +\rangle...
밥의 베이스XZXZXX...
밥의 상태(선험적)+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle+\vert +\rangle...
밥의 상태(측정된)+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle+\vert +\rangle...
밥의 비트00100...

앨리스는 00100...이라는 비트열을 성공적으로 전송했습니다. 밥에게. 친구들이 사전에 원타임 패드에서 숫자로 5비트 문자열을 사용하기로 합의했다면, 이 첫 5비트는 그들에게 숫자 4=0×24+0×23+1×22+0×21+0×204 = 0\times2^4+0\times2^3+1\times2^2+0\times2^1+0\times2^0 를 제공하게 될 것입니다.

QKD 단계 4: 비밀 검증 및 전송

앨리스와 밥은 더 나아가기 전에 비교할 클래식 비트의 하위 집합을 선택해야 합니다. 동일한 기준으로 준비되고 측정된 큐비트의 측정값만 보관했기 때문에 모든 측정값이 일치해야 합니다. 동의하지 않은 비율이 매우 적다면 이는 양자 노이즈나 오류로 인한 것일 수 있습니다. 하지만 많은 사람이 동의하지 않는다면 뭔가 잘못되었다는 뜻입니다!

여기서는 확인을 위해 키의 어떤 부분을 사용해야 하는지에 대해서는 언급하지 않겠습니다. 지금은 이 점검이 잘 이루어졌다고 가정하고 아래 도청에 대한 섹션에서 다시 살펴보겠습니다.

그런 다음 친구들은 기존 채널을 사용하여 서로에게 암호화된 메시지를 보냅니다. 그런 다음 일회용 패드를 한 위치에서 다른 위치로 전송하지 않고 일회용 패드의 번호를 사용하여 비밀 메시지를 암호화/복호화할 수 있습니다. 도청에 대한 다음 섹션에서는 이 모든 키 공유가 기존 채널을 통해 암호화된 비밀이 공개되기 전에 이루어진다는 점을 유념하시기 바랍니다.

앨리스와 밥은 고전적인 채널을 통해 선택의 근거를 전달했는데, 이를 가로챌 수 없나요? 네 있습니다! 그러나 측정에 사용한 기준을 안다고 해서 어떤 비트를 전송하거나 획득했는지 알 수 있는 것은 아닙니다. 이는 앨리스의 시작 비트도 알고 있어야만 가능합니다. 하지만 그러면 비밀이 저장된 앨리스의 컴퓨터에 들어가게 되고, 비밀의 비밀 통신은 무의미해집니다. 따라서 기존 통신을 가로채도 암호화가 깨지지 않습니다. 그렇다면 양자 채널에서 정보를 가로채는 것은 어떨까요?


양자 키 분배(QKD)의 도청에 대한 저항성

앨리스와 밥에게는 엿듣기로 악명 높은 친구 이브가 있습니다. 이브는 앨리스와 밥의 양자 키를 가로채서 둘 사이에 전송된 메시지를 해독하는 데 사용하고자 합니다. 이는 앨리스의 상태 준비와 밥의 상태 측정 사이에 반드시 발생하는데, 측정이 양자 상태를 붕괴시키기 때문입니다. 특히, 이는 기지의 공유나 비교가 이루어지기 전에 도청이 이루어져야 한다는 것을 의미합니다.

Eve는 각 비트를 인코딩할 때 어떤 베이스가 사용되었는지 추측해야 합니다. 다시 말하지만, 앨리스의 컴퓨터에 액세스할 수 없는 경우 이 추측의 근거가 될 만한 것이 없으며 무작위일 것입니다. 앨리스의 시작이 이전과 동일하다고 가정하고, 밥의 무작위 측정 기준 선택이 이전과 동일하다고 가정해 보겠습니다. 이브가 양자 채널을 측정하면 무엇을 얻을 수 있는지 채워보겠습니다. 이전과 마찬가지로 이브가 앨리스와 같은 기준을 선택하면 무엇을 얻을 수 있는지 알 수 있습니다. 그렇지 않은 경우, 그녀는 각각 50%의 확률로 두 가지 결과 중 하나를 얻을 수 있습니다.

앨리스의 비트
0
1
0
0
1
1
0
1
0
...
앨리스의 기지XXZZZXZZX...
앨리스의 상태+\vert +\rangle\vert -\rangle0\vert 0\rangle0\vert 0\rangle1\vert 1\rangle\vert -\rangle0\vert 0\rangle1\vert 1\rangle+\vert +\rangle...
이브의 추측 기반ZXXZXZZXX...
이브의 상태(선험적)?\vert -\rangle?0\vert 0\rangle??0\vert 0\rangle?+\vert +\rangle...
이브의 상태(측정된)1\vert 1\rangle\vert -\rangle+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle...
밥의 베이스XZXZXXZXX...

이브는 자신이 앨리스의 기저와 일치했는지 여부를 전혀 알지 못하기 때문에, 앨리스의 원래 상태와 일치하도록 밥에게 무엇을 전송해야 할지 알지 못합니다. 예를 들어 이브가 0|0\rangle 을 측정할 때, 그녀가 확실히 알 수 있는 것은 앨리스가 해당 큐비트에 대해 1|1\rangle 상태를 준비하지 않았다는 것뿐입니다. 하지만 앨리스는 0|0\rangle, +|+\rangle, 또는 |-\rangle 를 준비했을 수도 있다. 이 모든 경우 모두 이브의 측정 결과와 일치할 수 있다. 그래서 이브는 선택을 해야만 한다. 그녀는 자신이 측정한 상태를 그대로 전달할 수도 있고, 자신의 측정 결과가 앨리스가 보낸 고유상태가 아니었던 경우를 추측해 볼 수도 있다. 다음과 같은 혼합물을 표에 포함시키겠습니다:

앨리스의 비트
0
1
0
0
1
1
0
1
0
...
앨리스의 기지XXZZZXZZX...
앨리스의 상태+\vert +\rangle\vert -\rangle0\vert 0\rangle0\vert 0\rangle1\vert 1\rangle\vert -\rangle0\vert 0\rangle1\vert 1\rangle+\vert +\rangle...
이브의 추측 기반ZXXZXZZXX...
이브의 상태(선험적)?\vert -\rangle?0\vert 0\rangle??0\vert 0\rangle?+\vert +\rangle...
이브의 상태(측정된)1\vert 1\rangle\vert -\rangle+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle...
이브의 상태(전송됨)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...
밥의 베이스XZXZXXZXX...
밥의 상태(선험적)?0\vert 0\rangle?0\vert 0\rangle\vert -\rangle+\vert +\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle...
밥의 상태(측정된)\vert -\rangle0\vert 0\rangle+\vert +\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle0\vert 0\rangle\vert -\rangle+\vert +\rangle...
밥의 비트100010010...

이 시점에서 "왜 이브는 앨리스의 양자 상태를 복사해서 하나는 측정용으로 보관하고 다른 하나는 밥에게 전송하지 않는가?"라고 질문하는 것이 합리적입니다 정답은 '복제 금지' 정리입니다. 비공식적으로는 첫 번째 복사본을 보존하면서 임의의 양자 상태의 두 번째 복사본을 만들 수 있는 단일 (양자 역학적) 연산은 존재하지 않는다고 말합니다. 증명은 비교적 간단하며, 연습 문제로 남겨져 있습니다. 하지만 현재로서는 이브가 양자 상태를 복사하는 것이 자연의 기본 법칙에 의해 금지되어 있으며, 이것이 QKD의 원칙적인 강점이라는 점을 이해해 주세요.

이전과 마찬가지로 앨리스와 밥은 서로에게 전화를 걸어 기지를 비교했습니다. 이 표는 두 친구가 같은 기지를 선택한 경우로 축소됩니다:

앨리스의 비트
0
0
1
0
0
...
앨리스의 기지XZXZX...
앨리스의 상태+\vert +\rangle0\vert 0\rangle\vert -\rangle0\vert 0\rangle+\vert +\rangle...
이브의 추측 기반ZZZZX...
이브의 상태(선험적)?0\vert 0\rangle?0\vert 0\rangle+\vert +\rangle...
이브의 상태(측정된)1\vert 1\rangle0\vert 0\rangle0\vert 0\rangle0\vert 0\rangle+\vert +\rangle...
이브의 상태(전송됨)1\vert 1\rangle0\vert 0\rangle+\vert +\rangle0\vert 0\rangle0\vert 0\rangle...
밥의 베이스XZXZX...
밥의 상태(선험적)?0\vert 0\rangle+\vert +\rangle0\vert 0\rangle+\vert +\rangle...
밥의 상태(측정된)\vert -\rangle0\vert 0\rangle+\vert +\rangle0\vert 0\rangle+\vert +\rangle...
밥의 비트10000...

앨리스와 밥은 다시 한 번 비트 문자열을 전달했습니다... 를 입력했지만 문자열이 일치하지 않습니다. 맨 왼쪽과 가운데 비트가 뒤집혀 있습니다. 앞의 표를 보면 이 불일치를 Eve의 간섭으로 추적할 수 있습니다. 중요한 점은 암호화된 비밀을 공유하기 훨씬 전에 키를 설정하면서 비트스트링 간의 일치 여부를 통계로 확인할 수 있다는 점입니다. 앨리스와 밥은 채널의 보안을 확인하기 위해 일회용 패드 비트를 원하는 만큼 자유롭게 사용할 수 있습니다. 단일 비트 또는 매우 적은 비율의 비트가 일치하지 않는 경우 노이즈 또는 오류 때문일 수 있습니다. 그러나 불일치의 상당 부분은 도청을 의미합니다. 여기서 "상당한"의 의미는 사용 중인 설정의 노이즈에 따라 약간 달라지며, 이 프로토콜을 구현할 때 IBM® 양자 컴퓨터의 의미는 아래에서 설명합니다. 초과 오류가 감지되면 앨리스와 밥은 비밀을 공유하지 않고 도청자를 추적할 수 있습니다.

경고

보안을 입증하는 것은 매우 어렵습니다. 사실, 여기에 느슨하게 설명된 프로토콜은 1984년에 제안되었고, 16년 후인 Shor & Preskill, 2000 에서야 안전하다는 것이 증명되었습니다. 이 소개에서 다루지 못한 미묘한 부분도 많이 있습니다. 그러나 여기서는 이 주제가 여기에 설명된 것보다 더 복잡하다는 것을 보여주기 위해 몇 가지를 간략하게 나열하겠습니다.

  • 보안 채널: 앨리스가 어떤 양자 설정(채널)을 통해 큐비트를 전송할 때, 특히 누군가로부터 고전적인 응답을 들을 때, 우리는 그 누군가가 실제로 밥이라고 가정했습니다. 앨리스의 모든 통신이 실제로 이브와 이루어지고 밥의 모든 통신이 실제로 이브와 이루어지는 방식으로 이브가 이 설정에 침투했다면, 이브는 효과적으로 키를 획득하고 비밀을 알아낼 수 있게 됩니다. 먼저 '보안 채널'을 확보해야 하는데, 여기서는 다루지 않은 다른 프로토콜을 사용하는 프로세스입니다.
  • 이브에 대한 가정: 진정한 보안을 증명하기 위해서는 이브의 행동에 대해 가정할 수 없습니다. 이브는 언제든 우리의 예상을 뒤엎을 수 있기 때문입니다. 여기서는 구체적인 예를 들기 위해 가정을 가정해 보겠습니다. 예를 들어, 이브가 밥에게 전송하는 상태는 항상 측정 시 얻은 상태와 정확히 일치한다고 가정할 수 있습니다. 또는 측정값과 실험적으로 일치하는 상태를 임의로 선택한다고 가정할 수도 있습니다. 보다 근본적으로, 여기서의 언어는 이브가 다른 양자 시스템에 상태를 저장하고 무작위 큐비트를 밥에게 보내는 것과는 달리 실제로 측정을 한다고 가정합니다. 이러한 가정은 프로토콜을 이해하는 데는 좋지만, 완전한 일반성을 증명하지 못한다는 것을 의미합니다.
  • 개인 정보 증폭: 앨리스와 밥은 전송된 양자 키를 정확히 사용할 필요가 없습니다. 예를 들어 공유 키에 해시 함수를 적용할 수 있습니다. 이렇게 하면 도청자가 키에 대한 불완전한 지식을 가지고 있다는 사실을 악용하여 더 짧지만 안전한 공유 키를 생성할 수 있습니다.

실험 1: 도청자가 없는 양자 키 분배(QKD)

도청기가 없을 때 위의 프로토콜을 구현해 보겠습니다. 먼저 워크플로우를 이해하기 위해 시뮬레이터를 사용하여 이 작업을 수행합니다.

먼저, 양자 시뮬레이터에 대한 참고 사항입니다: 30 큐비트 이상의 양자 문제를 포함하는 대부분의 양자 문제는 대부분의 컴퓨터로 시뮬레이션할 수 없습니다. 기존 컴퓨터, 슈퍼컴퓨터, GPU로는 127큐비트 양자 컴퓨터의 모든 동작을 시뮬레이션할 수 없습니다. 일반적으로 실제 양자 컴퓨터를 사용하는 동기는 얽혀 있는 수많은 큐비트를 시뮬레이션할 수 없기 때문입니다. 이 경우 정보를 이동하기 위해 순간이동 방식을 사용하지 않는 한 큐비트의 얽힘이 발생하지 않습니다. 이 경우 실제 양자 컴퓨터를 사용하는 동기는 다른데, 바로 복제 금지 정리입니다. 큐비트를 시뮬레이션하는 고전적인 컴퓨터는 앨리스에서 밥에게 양자 상태에 대한 정보를 보낼 수 있지만, 이 고전적인 정보를 가로채면 쉽게 복제할 수 있고 이브는 완벽한 사본을 보관하면서 다른 사본을 밥에게 보낼 수 있습니다. 이는 실제 양자 상태에서는 불가능합니다.

IBM 퀀텀은 "키스킷 패턴"이라는 프레임워크를 사용하여 양자 컴퓨팅 문제를 해결할 것을 권장합니다. 다음 단계로 구성됩니다.

  • 1단계: 문제를 양자 회로에 매핑하기
  • 2단계: 실제 양자 하드웨어에서 실행되도록 회로 최적화하기
  • 3단계: 런타임 프리미티브를 사용하여 IBM 퀀텀 컴퓨터에서 작업 실행하기
  • 4단계: 결과 후처리

Qiskit 패턴 1단계: 문제를 양자 회로로 매핑하기

이 경우 문제를 양자 회로에 매핑하는 작업은 단순히 앨리스의 상태를 준비한 다음 밥의 측정값을 포함시키는 것으로 축소됩니다. 무작위 비트 및 무작위 기준 선택부터 시작합니다.

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

비트, 베이스, 회로를 시각화해 보겠습니다. 베이스가 일치하는 경우도 있고 일치하지 않는 경우도 있습니다.

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

Qiskit 패턴 2단계: 양자 실행을 위한 문제 최적화

이 단계에서는 수행하고자 하는 연산을 특정 양자 컴퓨터의 기능으로 표현합니다. 또한 우리의 문제를 양자 컴퓨터의 레이아웃에 매핑합니다.

IBM 양자 컴퓨터와 통신하는 데 필요한 몇 가지 패키지를 로드하는 것부터 시작하겠습니다. 또한 실행할 백엔드도 선택해야 합니다. 가장 사용량이 적은 백엔드를 선택하거나 속성을 알고 있는 특정 백엔드를 선택할 수 있습니다. 잠시 시뮬레이터를 사용하겠지만, 시뮬레이션에서 합리적인 노이즈 모델을 사용하는 것이 중요하며, 나중에 실제 양자 컴퓨터에서 사용할 워크플로우와 최대한 비슷하게 유지하는 것이 좋습니다.

처음 사용할 때 자격 증명을 저장하는 코드는 아래에 있습니다. 노트북을 공유할 때 실수로 자격 증명이 공유되지 않도록 노트북을 환경에 저장한 후 이 정보를 노트북에서 삭제해야 합니다. 자세한 안내는 IBM Cloud 계정 설정하기신뢰할 수 없는 환경에서 서비스 초기화를 참조하세요.

# 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

아래에서 시뮬레이터와 노이즈 모델을 선택합니다.

# 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 패턴 3단계: 실행

샘플러를 사용하여 회로를 인수로 사용하여 작업을 실행합니다.

# 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 패턴 4단계: 후처리

여기에서 결과를 해석하고 유용한 정보를 추출합니다. 샘플러의 출력을 시각화할 수도 있지만, 저희는 샘플러를 색다른 방식으로 사용했습니다. 회로를 여러 번 측정하고 상태에 대한 통계를 개발하는 대신 단 한 번만 측정했습니다(Bob의 경우). 동일한 기준으로 준비되고 측정된 상태를 가진 큐비트는 결정론적 결과를 가져야 하므로 단 한 번의 측정만 필요합니다. 서로 다른 베이스에서 준비되고 측정된 상태(확률적인 결과를 가져오고 해석을 위해 많은 측정이 필요한)를 가진 큐비트는 일회성 패드/키를 구축하는 데 사용되지 않습니다.

이 비트 문자열에서 측정 결과 목록을 추출해 보겠습니다. 회로를 생성할 때 사용한 앨리스의 비트 배열과 비교할 때는 순서를 반대로 하도록 주의하세요.

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

앨리스와 밥이 임의로 선택한 측정 기준을 비교해 보겠습니다. 이것은 QKD 프로토콜의 3단계(거점에 대한 공개 토론)입니다. 큐비트에 대해 동일한 기준을 선택할 때마다 해당 큐비트와 관련된 비트를 일회용 패드에서 숫자를 생성하기 위한 비트 목록에 추가합니다. 기준이 일치하지 않으면 결과가 버려집니다. 또한 두 비트 목록이 일치하는지, 노이즈나 기타 요인으로 인해 손실이 발생했는지 확인합니다.

# 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

앨리스와 밥은 각각 비트 목록을 가지고 있으며, 100% 충실도로 일치합니다. 이를 사용하여 일회용 패드에 숫자를 생성할 수 있습니다. 그런 다음 QKD 4단계: 비밀 전송 및 암호 해독에서 이를 사용할 수 있습니다. 현재의 비트 배열은 너무 짧아서 많은 것을 해독할 수 없습니다. 도청 기능을 포함시킨 후에 다시 설명하겠습니다.

이해도 점검

물론 다른 인코딩 체계도 있지만 영어 알파벳의 문자를 해당 알파벳의 전체 길이 또는 그 이상으로 쉽게 이동할 수 있을 만큼 큰 숫자가 필요하다고 가정합니다. (a) 위의 키의 비트를 사용하여 메시지를 해독하려면 메시지의 길이가 몇 글자가 되어야 할까요? (b) 귀하의 답변이 반 친구들의 답변과 일치해야 합니까? 그 이유는?

  • (a) 답은 앨리스와 밥 사이에서 무작위로 선택된 염기 중 몇 개가 일치했는지에 달려 있다. 주어진 큐비트 하나당 염기 쌍이 일치할 확률이 대략 50%이므로, 약 10비트 정도가 유용하게 사용될 것으로 예상됩니다. 9나 11은 아주 흔한 일이 될 것입니다. 4나 15조차도 불가능한 일은 아니다. 영어 알파벳의 글자 수와 같거나 그보다 큰 수만큼 시프트하려면 5비트가 필요하며, 이는 보유한 5비트마다 한 글자에 대해 시프트를 적용할 수 있음을 의미합니다. 앨리스와 밥이 공유하는 비트가 5비트 이상이라면, 한 글자를 인코딩할 수 있습니다. 10개 이상 있다면 2글자를 인코딩할 수 있으며, 이와 같은 방식으로 계속할 수 있습니다.

    (b) (a)항에 명시된 사유로 인해 반드시 일치할 필요는 없다.


실험 2: 도청자가 존재하는 양자 키 분배(QKD)

이전과 동일한 프로토콜을 구현할 예정입니다. 이번에는 이브가 앨리스와 밥 사이에 또 다른 측정값 세트를 삽입합니다.

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단계(후처리)는 간단합니다. 한 번만 측정했기 때문에 측정값의 분포를 시각화할 필요가 없습니다. 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)

Output:

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

이제 이브는 밥에게 전송할 상태를 재구성해야 합니다. A는 인코딩 기반을 올바르게 추측했는지 알 방법이 없기 때문에 전송된 상태와 정확히 동일한 상태를 준비할 수 없다고 설명했습니다. 모든 기준이 정확하다고 가정하고 측정한 내용을 정확히 인코딩하거나, 기준을 잘못 선택했다고 가정하고 반대 기준의 고유 상태를 선택할 수 있습니다. 여기서는 단순화를 위해 전자를 가정합니다. 이전과 마찬가지로 키스킷 패턴 단계를 반복하여 완전히 새로운 양자 회로를 구성함으로써 이를 달성합니다.

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]

이제 앨리스와 밥의 비트를 비교해 보겠습니다:

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

이전에는 앨리스와 밥의 열쇠에 있는 비트가 완벽하게 일치했습니다. 이제 이브의 간섭으로 인해 앨리스와 밥이 같은 염기를 선택했기 때문에 일치해야 하는 경우의 14%에서 앨리스와 밥의 비트가 다른 것을 볼 수 있습니다. 앨리스와 밥은 이를 쉽게 감지할 수 있을 것입니다. 그러나 이와 같은 오류의 비율에 의존한다는 것은 양자 채널에서 허용할 수 있는 노이즈의 양에 한계가 있다는 것을 의미합니다.


실험 3: 실제 양자 컴퓨터에서 도청 유무에 따른 양자 키 분배(QKD) 비교

실제 양자 컴퓨터에서 실행해 보겠습니다. 이렇게 하면 복제 금지 정리를 활용할 수 있습니다. 동시에 실제 양자 컴퓨터는 노이즈가 있고 기존 컴퓨터보다 오류율이 높습니다. 실제 양자컴퓨터를 사용할 때 그 차이를 감지할 수 있는지 확인하기 위해 도청을 했을 때와 하지 않았을 때 키 비트의 충실도 손실을 비교해 보겠습니다. 도청이 없는 상태에서 시작하겠습니다:

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

도청 없이 127개의 시험 비트 세트에 대해 100% 충실도를 달성하여 55개의 일치하는 베이스와 사용 가능한 키 비트를 얻었습니다. 이제 이브가 듣고 있는 상태에서 이 실험을 반복해 보겠습니다:

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

여기서 도청으로 인해 공유 비트의 충실도가 거의 23% 손실되는 것을 발견했습니다! 이것은 매우 감지할 수 있습니다! 양자 정보를 장거리로 전송할 때는 여전히 추가적인 노이즈와 오류가 발생할 수 있습니다. 이브가 모든 수단을 동원하여 소음이 있는 상황에서도 도청을 탐지할 수 있도록 하는 것은 이 소개에서 다루지 않은 복잡한 분야입니다.


질문

교수자는 노트북이 어떻게 사용되고 있는지에 대한 이 간단한 설문조사를 작성하여 공통 커리큘럼에 배치하는 방법에 대한 안내와 답안지가 포함된 노트북 버전을 요청할 수 있습니다.

핵심 개념

  • 양자 정보는 복사하거나 '복제'할 수 없습니다.
  • 동일한 준비 과정을 반복하여 모두 동일하거나 거의 동일한 양자 상태의 앙상블을 만들 수 있습니다.
  • 양자 상태를 사용하여 두 친구 간에 암호화/복호화 키(일회용 패드)를 공유할 수 있습니다.
  • 두 친구가 무작위로 측정 기준을 선택하면 절반은 서로 다른 기준을 선택하게 되고, 그 큐비트에 대한 정보를 버려야 합니다.
  • 또한 측정 기준을 무작위로 선택하면 도청자가 준비된 초기 상태를 알 수 없으므로 전송된 상태를 재현할 수 없습니다. 이렇게 하면 도청을 감지할 수 있습니다.

참/거짓 문제

  1. T/F 양자 키 분배에서는 두 통신 파트너가 동일한 기준으로 각 큐비트를 측정합니다.
  2. T/F 양자 정보를 가로채는 도청기는 자연의 법칙에 의해 가로챈 양자 상태를 복사할 수 없습니다.
  3. T/F 일회용 패드는 보안 메시지를 암호화/복호화하기 위한 키로, 특정 인코딩 체계가 단일 정보(예: 알파벳 한 글자)에 대해 한 번만 사용됩니다.

MC 질문

  1. 문장을 가장 잘 완성할 수 있는 옵션을 선택합니다. 이 모듈에서 설명한 대로 일회용 패드는 암호화/복호화 키 세트입니다...
  • a. 편지 한 장과 같은 단일 정보에 대해 한 번만 사용할 수 있습니다.
  • b. 단일 메시지에 대해 한 번만 가능합니다.
  • c. 하루와 같이 정해진 기간 동안 한 번만 사용할 수 있습니다.
  • d. 도청의 증거가 있을 때까지.
  1. 앨리스와 밥이 측정 기준을 무작위로 선택한다고 가정합니다. 측정합니다. 그런 다음 측정 기준을 공유하고 동일한 기준을 사용한 사례의 일부 정보만 보관합니다. 어느 정도의 무작위 변동까지, 대략 몇 퍼센트의 큐비트에서 사용 가능한 비트 정보를 얻을 수 있을까요?
  • a. 100%로
  • b. 50%
  • c. 25%
  • d. 12.5%
  • e. 0%
  1. 앨리스와 밥이 동일한 측정 기반을 사용한 사례를 선택한 후, 양자 잡음과 오류가 무시할 수 있는 수준이라면 해당 정보 비트의 몇 퍼센트가 일치해야 할까요?
  • a. 100%로
  • b. 50%
  • c. 25%
  • d. 12.5%
  • e. 0%
  1. 앨리스가 측정 기준을 무작위로 선택했다고 가정합니다. 이브는 또한 무작위로 기지를 선택하고 (측정)을 듣습니다. 그녀는 자신의 측정값과 일치하는 상태를 Bob에게 보냅니다. 앨리스와 밥이 선택한 베이스를 비교하고 측정/준비한 큐비트만 동일한 베이스에 보관합니다. 앨리스와 밥에 따르면, 어느 정도의 무작위 변동이 있을 때까지 보관된 큐비트 측정값 중 대략 몇 퍼센트가 일치할까요?
  • a. 100%로
  • b. 75%
  • c. 50%
  • d. 25%
  • e. 12.5%
  • f. 0%

토론 질문

  1. 모든 참가자인 앨리스, 밥, 이브에게 모든 기본 선택이 무작위라고 가정합니다. 이브가 청취한 후 자신이 측정한 것과 동일한 기준으로 준비되고 해당 측정과 일치하는 상태를 밥에게 보낸다고 가정해 보겠습니다. 파트너에게 앨리스가 초기화한 모든 큐비트 중 12.5 %가 앨리스와 밥 사이에 측정 불일치를 일으켜 도청(양자 오류 및 잡음 무시)을 나타낼 것이라고 설득하세요. 힌트 1: 선호 기준이 없으므로 앨리스에 대한 초기 선택지를 하나만 고려하는 경우, 그 선택지의 비율은 모든 선택지의 합에 대한 비율과 같아야 합니다. 힌트 2: 어떤 결과가 다른 확률로 발생할 수 있으므로 어떤 결과가 발생할 수 있는 방법의 수를 세는 것만으로는 충분하지 않을 수 있습니다.

  2. 모든 참가자인 앨리스, 밥, 이브에게 모든 기본 선택이 무작위라고 다시 가정합니다. 하지만 이제 이브는 측정 후 원하는 상태를 자유롭게 전송할 수 있다고 생각해보세요. 심지어 자신의 측정값과 일치하지 않는 상태를 전송해 볼 수도 있습니다. 앨리스와 밥에게 도청을 나타내는 큐비트의 평균 비율을 줄일 수 있는 기지가 있다고 생각하는지 파트너/이웃과 토론하세요.

이 페이지가 도움이 되었습니까?
GitHub에서 버그, 오타를 보고하거나 컨텐츠를 요청하십시오.