メインコンテンツへスキップ

量子鍵配送

このQiskit in Classroomsモジュールを実行するには、以下のパッケージがインストールされたPython環境が必要です。

  • qiskit v2.1.0 以上
  • qiskit-ibm-runtime v0.40.1 以上
  • qiskit-aer v0.17.0 以上
  • qiskit.visualization
  • numpy
  • pylatexenc

上記パッケージのセットアップとインストール方法については、Qiskitのインストールガイドをご参照ください。 実際の量子コンピューターでジョブを実行するには、IBM Cloudアカウントのセットアップガイドの手順に従って、IBM Quantum®のアカウントを作成する必要があります。

このモジュールはテスト済みで、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の対応関係があります。ポップカルチャーにおける例としては、クリプトクォートやクリプトグラムパズルがあります。これらは引用文やフレーズが単純置換で暗号化されており、プレイヤーはそれを解読することが求められます。十分な長さがあれば比較的容易に解読できます。次の例を考えてみましょう。

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」のような1文字の単語は「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など)は「シーザー暗号」と呼ばれます。

これらの暗号は、メッセージが短い場合には非常に解読困難です。実際、非常に短い場合は解が定まりません。次の例を考えてみましょう。

URYYP

異なる鍵を使うと多くの復号結果が考えられます:HELLO、PETTY、HAPPY、JIGGY、STOOLなど。他に思いつきますか?

しかし、このような暗号文を多数送れば、最終的に暗号は解読されてしまいます。したがって、同じ「鍵」を頻繁に使用すべきではありません。実際には、特定の置換は1回しか使わないのが最善です。1つのメッセージだけでなく、1文字に対して1回だけ使用するのです。つまり、メッセージ内で使用される各文字に対して、順番に暗号化スキームまたは鍵を持つということです。この方法で友人にメッセージを送りたい場合、あなたと友人は(昔ながらの方法では)この常に変化する鍵が書かれた紙のパッドを共有する必要があります。これは1度しか使用しません。これを「ワンタイムパッド」と呼びます。

ワンタイムパッド

例を使ってこの仕組みを見てみましょう。すべて文字だけで行うこともできますが、文字を数字に変換するのが一般的です。たとえばA=0、B=1、C=2…と割り当てます。 私たちが秘密の活動に関わる仲間で、パッドを共有しているとします。理想的にはパッドを多数共有すべきですが、今日のパッドは次のとおりです。

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

上記のコードをそのまま送ることは避けたいです。それは単純置換であり、まったく安全ではありません。これを鍵と何らかの方法で組み合わせる必要があります。一般的な方法は、26を法とした加算(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

鍵を持っていない人がこれを傍受しても、解読はまったく不可能です!「quantum」の2つの「u」でさえ、同じ数字でエンコードされていません!最初の「u」は3、2番目は16です…同じ単語の中なのに!

これをあなたに送ると、あなたは私と同じ鍵を持っています。私が行ったmod 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"

これがワンタイムパッドです。

鍵がメッセージより短い場合、エンコードを繰り返し始めます。それでも解読は難しい問題ですが、十分に繰り返されると不可能ではありません。したがって、長い鍵(または「パッド」)が必要です。

備考

多くの場合、学生はすでにこの暗号に慣れ親しんでおり、このアクティビティをスキップできます。ただし、比較的短時間で完了できる簡単な復習です。

ステップ1:パートナーと組み、鍵として使用する4文字のシーケンスを共有してください。クラスに適切な4文字のシーケンスであれば何でも構いません。
ステップ2:パートナーに送りたい4文字の秘密の単語を選んでください(両方のパートナーがこれを行い、互いに異なる秘密の単語を送ります)。
ステップ3:A = 1、B = 2 などを使用して、4文字の鍵/パッドと各4文字の秘密の単語を数字に変換してください。
ステップ4:modulo 26の加算を使用して、4文字の単語をワンタイムパッドと組み合わせてください。
ステップ5:秘密の単語をエンコードした数字のシーケンスをパートナーに渡し、パートナーもあなたに渡してください。
ステップ6:modulo 26の減算を使用して互いの単語を解読してください。
ステップ7:確認してください。うまくいきましたか?

フォローアップ

ワンタイムパッドを持っていない別のグループと暗号化された単語を交換してください。解読できますか?なぜできる(またはできない)のかを説明してください。

上のアクティビティを通じて、ワンタイムパッドがいくつかの前提条件のもとで解読不可能な暗号化形式であることが明確になったと思います。前提条件とは以下のとおりです。

  • 鍵は送信されるメッセージと同じ長さ以上である
  • 鍵が真にランダムである
  • 鍵は1度だけ使用され、その後破棄される

これは素晴らしいことです。解読不可能な暗号化ができました…誰かが鍵を入手しない限り。鍵を入手されると、すべてが解読されてしまいます。解読不可能な暗号化と秘密がすべて暴露される状態の間のこの差が、安全な鍵の共有を非常に重要なものにしています。量子鍵配送の目標は、自然が量子情報に課した制約を活用して、共有された鍵/ワンタイムパッドを保護することです。

量子状態を鍵として使用する

量子ビット(2つの固有状態を持つことを強調するためにQubitsと呼びます)を使って作業していると仮定しましょう。より多くの量子状態を持つ量子システムを使用することもできますが、IBM®の最先端の量子コンピューターはQubitsを使用しています。A、B、C…を0と1のシーケンスにエンコードすることは問題ありません。したがって、0と1の鍵を共有し、文字を格納する各ビットにmodulo 2の加算を行えば十分です。

理解度の確認

以下の問いを読み、答えを考えてから、三角形をクリックして解答を表示してください。

英語のアルファベットだけに関心がある場合、何ビット必要ですか?

答え:

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

アリスとボブという友人は、他の誰にも傍受されない方法で量子鍵を共有したいと考えています(少なくとも、気づかれずに傍受されることのないように)。そのためには、互いに量子状態を送受信する手段が必要です。これを高い忠実度でノイズや誤りなく行うことは簡単ではありません。しかし、現時点で理解できる2つのアプローチがあります:

  1. 光ファイバーケーブルは光を送ることができます…それは非常に量子力学的です。単一光子は、数キロメートルの光ファイバーケーブルを通じて高い忠実度で検出できます。これは完全で誤りのない量子チャネルではありませんが、非常に優れたものになり得ます。
  2. 前のモジュールで説明したように、量子テレポーテーションを使用することができます。つまり、アリスとボブはエンタングルしたQubitsを共有し、テレポーテーションプロトコルを使用してアリスからボブに状態を送ることができます。

このモジュールでは、光子を共有するための高忠実度の光学セットアップを必要としないため、2番目の方法を使用します。ただし、これが長距離での量子鍵共有に最も現実的な方法であるとは限りません。

ここでは、Charles BennettとGilles Brassardが1984年に発表したプロトコルを探ります。このプロトコルは、アリスからボブに異なる基底で測定された状態を共有するものです。巧みな測定方式を使って、後の暗号化に使用する鍵を構築していきます。つまり、通信を希望する2者間で量子鍵を配送することから、「量子鍵配送」(QKD)と呼ばれます。

QKDステップ1:アリスのランダムビットとランダム基底

アリスはまず、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のランダムなセットと基底選択をランダムに生成することは確かに可能です。今は、以下のようなランダムなセットが生成されたと仮定しましょう。

アリスのビット010011010...
アリスの基底XXZZZXZZX...
アリスの状態+\vert +\rangle\vert -\rangle0\vert 0\rangle0\vert 0\rangle1\vert 1\rangle\vert -\rangle0\vert 0\rangle1\vert 1\rangle+\vert +\rangle...

このランダムなビット、基底、および結果として得られる状態のセットは、十分な長さの鍵を提供するために長いシーケンスとして続きます。

QKDステップ2:ボブのランダム基底

ボブもランダムに基底を選択します。ただし、アリスが基底の選択を使って状態を準備したのとは異なり、ボブはこれらの基底で実際に測定を行います。ボブがアリスの状態準備と同じ基底で測定を行った場合、ボブの測定結果を予測することができます。ボブがアリスの準備時と異なる基底を選んだ場合、ボブの測定結果を知ることはできません。

アリスのビット010011010...
アリスの基底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 という1つの結果しかあり得ません。しかし2列目では、異なる基底を選択しています。アリスが送った状態は =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:基底の公開議論

アリスとボブは、各ケースでどの基底を選んだかを互いに共有できます。同じ基底を選択した列すべてについて、それぞれが相手の状態を確実に知ることができます。ボブは両者が共有する規則に従って、状態と基底を0または1に変換できます。アリスとボブの基底が一致したケースのみを示すように上の表を書き直すと次のようになります。

アリスのビット00100...
アリスの基底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:検証と秘密の送信

アリスとボブが次に進む前に、古典ビットのサブセットを選んで比較すべきです。同じ基底で準備・測定されたQubitsの測定値のみを保持しているため、すべての測定値は一致するはずです。一致しないものが非常に少ない割合であれば、量子ノイズや誤りによるものと考えられます。しかし多くが一致しない場合、何か問題が生じています!

ここでは、鍵のどの割合を検証に使うべきかは取り上げません。今は、この確認がうまくいくと仮定します。盗聴に関する以下のセクションでこの点を再検討します。

友人たちは古典チャネルを介して暗号化されたメッセージを互いに送ります。その後、ワンタイムパッドの数字を使って秘密のメッセージを暗号化・復号します。ワンタイムパッド自体は一方の場所から他方へ送信されることはありません。盗聴に関する次のセクションでは、鍵の共有はすべて、古典チャネルを介して暗号化された秘密が明かされる前に行われることを念頭においてください。

アリスとボブは選択した基底を古典チャネルで伝達しました。それは傍受されないのでしょうか?されるかもしれません!しかし、測定に使用した基底を知っても、送受信されたビットを知ることはできません。それが可能なのは、アリスの最初のビットも知っている場合だけです。しかしそれはアリスのコンピューターにアクセスしていることを意味し、秘密の秘密通信は意味をなさなくなります。したがって、古典的な通信の傍受では暗号を破ることはできません。では、量子チャネルの情報を傍受した場合はどうでしょうか?

QKDの盗聴への耐性

アリスとボブには、盗聴で悪名高い友人のイブがいます。イブはアリスとボブの量子鍵を傍受して、2人の間で送られるメッセージを解読しようとしています。これは必然的に、アリスの状態準備とボブの状態測定の間に行われる必要があります。測定が量子状態を崩壊させるからです。特に、この盗聴は基底の共有や比較が行われるに行われなければなりません。

イブは各ビットのエンコードに使用された基底を推測しなければなりません。アリスのコンピューターにアクセスできない場合、この推測の根拠がなく、ランダムなものになります。アリスの初期状態が以前と同じで、ボブの測定基底のランダムな選択も以前と同じであると仮定しましょう。イブが量子チャネルを測定した場合に何を得るかを記入してみましょう。前と同様に、イブがアリスと同じ基底を選んだ場合、何を得るかはわかります。そうでなければ、それぞれ50%の確率で2つの結果のいずれかを得る可能性があります。

アリスのビット010011010...
アリスの基底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 を測定した場合、確実にわかることはアリスがそのQubitsに 1|1\rangle を準備しなかったということだけです。しかしアリスは 0|0\rangle+|+\rangle、または |-\rangle を準備していた可能性があります。いずれもイブの測定と矛盾しません。そのためイブは選択をしなければなりません。測定した状態をそのまま送信するか、測定がアリスの送った固有状態ではなかったケースを推測しようとするかです。表には両者の混合を含めます:

アリスのビット010011010...
アリスの基底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...

この時点で「なぜイブはアリスの量子状態のコピーを作り、1つを測定用に保持し、もう1つをボブに送らないのか」と疑問に思うかもしれません。答えは「複製不可能」定理です。非公式に言うと、最初のコピーを保持しながら任意の量子状態の2番目のコピーを作ることができるユニタリー(量子力学的)演算は存在しないというものです。証明は比較的単純で、ガイド付き演習として残します。しかし今は、イブが量子状態のコピーを作ることが自然の基本法則によって禁じられており、これがQKDの原理的な強みであることを理解してください。 前と同様に、アリスとボブはお互いに電話をかけて基底を比較します。2人の友人が同じ基底を選択したケースのみを示すように表を縮約します:

アリスのビット00100...
アリスの基底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...

アリスとボブは再びビット列を伝達しましたが…文字列が一致しません。左端のビットと中央のビットが反転しています。前の表を見ると、この不一致がイブの干渉によるものであることが追跡できます。重要なのは、暗号化された秘密が古典チャネルで明かされるずっと前の、鍵の設定段階で、ビット列の一致に関する統計を取ることができるという点です。アリスとボブはワンタイムパッドのビットを好きなだけ自由に使ってチャネルのセキュリティを確認できます。1ビットまたはごく少数の割合が一致しない場合は、ノイズや誤りによるものかもしれません。しかし実質的な割合のビットが一致しない場合は盗聴が示唆されます。「実質的」の意味は使用されているセットアップのノイズ量に依存します。IBM®量子コンピューターでの意味については、このプロトコルを実装する際に以下で説明します。過剰なエラーが検出された場合、アリスとボブは秘密を共有せず、盗聴者の追跡を始めることができます。

注意事項

セキュリティの証明は非常に困難です。実際、ここで概要を説明したプロトコルは1984年に提案されましたが、安全性が証明されたのは16年後のShor & Preskill、2000年でした。この入門の範囲を超える多くの微妙な点があります。しかし、このトピックがここで示されているよりも複雑であることを示すために、いくつかの点を簡単にリストアップします。

  • 安全なチャネル: アリスが何らかの量子セットアップ(チャネル)を通じてQubitsを送り、特に古典的な応答を誰かから受け取る際、私たちはその誰かがボブであると仮定しています。もしイブがこのセットアップに侵入して、アリスのすべての通信が実際にはイブとの間で行われ、ボブのすべての通信も実際にはイブとの間で行われているとしたら、イブは実質的に鍵を入手したことになり、秘密を知ることができます。まず「安全なチャネル」を確保する必要がありますが、これはここでは取り上げていない別のプロトコルセットが必要です。
  • イブに関する前提: セキュリティを真に証明するためには、イブの行動に関する前提を置くことはできません。彼女は常に私たちの期待を覆す可能性があります。ここでは具体的な例を示すために前提を置いています。たとえば、イブがボブに送る状態は常に測定で得られたものと全く同じであると仮定するかもしれません。あるいは、測定と実験的に整合する状態をランダムに選択すると仮定するかもしれません。より根本的には、ここでの言語はイブが実際に測定を行うことを前提としており、状態を別の量子システムに保存してランダムなQubitsをボブに送ることは前提としていません。これらの前提はプロトコルを理解するには問題ありませんが、完全な一般性で何かを証明しているわけではありません。
  • プライバシー増幅: アリスとボブは量子鍵を送信されたままそのまま使う必要はありません。たとえば、共有鍵にハッシュ関数を適用することができます。これにより、盗聴者が鍵について不完全な知識しか持っていないという事実を利用して、より短くても安全な共有鍵を生成することができます。

実験1:盗聴者なしのQKD

盗聴者がいない状況でのプロトコルを実装してみましょう。まずシミュレーターを使ってワークフローを理解します。

最初に、量子シミュレーターについての注意事項があります。約30Qubit以上の量子問題のほとんどは、ほとんどのコンピューターではシミュレーションできません。いかなる古典コンピューター、スーパーコンピューター、GPUでも、127Qubitの量子コンピューターの全ての振る舞いをシミュレーションすることはできません。通常、実際の量子コンピューターを使用する動機は、多数のエンタングルしたQubitsをシミュレーションできないことにあります。この場合、テレポーテーションスキームを使用して情報を移動させない限り、Qubitsのエンタングルメントはありません。この場合、実際の量子コンピューターを使用する動機は異なります:それは複製不可能定理です。Qubitsをシミュレートする古典コンピューターは、量子状態に関する情報をアリスからボブに送ることができますが、この古典情報が傍受された場合、容易に複製でき、イブは完全なコピーを保持しつつ別のコピーをボブに送ることができます。これは実際の量子状態では不可能です。

IBM Quantumでは、「Qiskitパターン」と呼ばれるフレームワークを使って量子コンピューティングの問題に取り組むことを推奨しています。それは以下のステップから構成されます。

  • ステップ1:問題を量子Circuit(回路)にマッピングする
  • ステップ2:実際の量子ハードウェアで実行するためにCircuitを最適化する
  • ステップ3:Runtimeプリミティブを使用して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")
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パターン ステップ2:量子実行に向けた問題の最適化

このステップでは、実行したい演算を特定の量子コンピューターの機能に対応した形式で表現します。また、問題を量子コンピューターのレイアウト上にマッピングします。

まず、IBM量子コンピューターと通信するために必要ないくつかのパッケージを読み込みます。また、実行するBackendを選択する必要があります。最も空いているBackendを選択することも、特性が既知の特定のBackendを選択することも可能です。一時的にシミュレーターを使用しますが、シミュレーションにおいて適切なノイズモデルを使用することが重要であり、後で実際の量子コンピューターに使用するワークフローにできるだけ近い状態を保つことが望ましいです。

初回使用時に認証情報を保存するためのコードが以下に示されています。認証情報を環境に保存した後は、ノートブックからその情報を必ず削除してください。ノートブックを共有する際に認証情報が誤って共有されないようにするためです。詳細については、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

以下ではシミュレーターとノイズモデルを選択します。

# 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:実行

Circuit を引数としてサンプラーを使用してジョブを実行します。

# 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:後処理

ここでは結果を解釈し、有用な情報を抽出します。サンプラーの出力を可視化しようとするかもしれませんが、今回は通常とは異なる方法でサンプラーを使用しています。Circuit の測定を多数行って状態の統計を取得するのではなく、1回だけ(ボブの)測定を行っています。同じ基底で準備・測定された Qubit は決定論的な結果を持つため、1回の測定で十分です。異なる基底で状態が準備・測定された Qubit(確率的な結果を持ち、解釈するために多くの測定が必要)は、ワンタイムパッド/鍵の構築には使用されません。 このビット列から測定結果のリストを抽出しましょう。アリスのビット配列(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]

アリスとボブがランダムに選択した測定基底を比較してみましょう。これはQKDプロトコルのステップ3(基底の公開照合)にあたります。ある Qubit に対して同じ基底が選ばれた場合は常に、その Qubit に関連するビットをワンタイムパッドの数値生成用ビットリストに追加します。基底が一致しない場合、その結果は破棄されます。また、2つのビットリストが一致しているか、ノイズやその他の要因による損失がないかも確認しましょう。

# 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

アリスとボブはそれぞれビットのリストを持っており、それらは100%の忠実度で一致しています。これらを使ってワンタイムパッドの数値を生成することができます。その後、QKDステップ4「秘密情報の送信と復号」に利用できます。現在のビット配列はあまりにも短く、ほとんど何も復号できません。盗聴の実装を含めた後、再度これについて触れます。

理解度の確認

以下の問いを読み、答えを考えてから、三角形をクリックして解答を確認してください。

アルファベット全長分以上のシフトを可能にするのに十分な桁数が必要だと仮定します(他のエンコード方式も存在しますが)。 (a) 上記の鍵のビットを使って復号できるメッセージは最大何文字ですか? (b) あなたの答えはクラスメートと同じである必要がありますか?その理由も答えてください。

解答:

(a) 答えは、アリスとボブの間でランダムに選ばれた基底が何回一致したかによって異なります。ある Qubit に対して基底が一致する確率はおよそ50対50であるため、20ビットのうち約10ビットが有用になると期待されます。9や11もよくある結果です。4や15であっても、まったく起こりえないわけではありません。英語のアルファベットの長さ以上のシフトを行うためには5ビットが必要です。つまり、5ビットごとに1文字をエンコードできます。アリスとボブが共有するビットが5ビット以上あれば1文字をエンコードでき、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()

この場合、Qiskitパターンのステップ4(後処理)は単純です。1回しか測定を行っていないため、測定の分布を可視化する必要はありません。イブが持つビットは以下の通りです:

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]

次に、イブはボブへ送る状態を再構築しなければなりません。はじめにも述べたように、イブはエンコードに使われた基底を正しく推測できたかどうかを知る術がないため、元々送られたのとまったく同じ状態を準備することはできません。イブは、すべての基底選択が正しかったと仮定して測定した通りにエンコードすることも、基底を誤ったと仮定して逆の基底の固有状態のどちらかを選ぶこともできます。ここでは単純化のため、前者を仮定します。これは全く新しい量子回路を構築し、先ほどと同じようにQiskitパターンのステップを繰り返すことで実現します。

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]

それでは、アリスとボブのビットを比較してみましょう:

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

以前は、アリスとボブの鍵のビットが完全に一致していました。今回は、イブの介入によって、アリスとボブが同じ基底を選択したはずのケースで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))
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試行ビットのこのセットで55個の基底一致と有効な鍵ビットが得られ、100%の忠実度を達成しました。 次に、イブが盗聴する場合でこの実験を繰り返してみましょう:

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%も損なわれました。これは十分に検出可能です。量子情報を長距離で転送する場合、追加のノイズやエラーが生じる可能性があることに注意が必要です。ノイズが存在する場合でも、またイブがあらゆる手段を駆使した場合でも、盗聴を検出できることを保証するのは、この入門の範囲を超えた複雑な分野です。

問題

インストラクターは、このノートブックの使用方法に関する簡単なアンケートに回答することで、解答キーとカリキュラムへの組み込み指針を含むノートブックのバージョンをリクエストすることができます。

重要な概念

  • 量子情報はコピーや「クローン」をすることができません。
  • 同じ準備プロセスを繰り返して、すべて同一、またはほぼ同一の量子状態のアンサンブルを作成することは可能です。
  • 量子状態を使って、2人の友人の間で暗号化/復号化鍵(ワンタイムパッド)を共有することができます。
  • 2人の友人が測定基底をランダムに選ぶと、半分の確率で異なる基底を選ぶことになり、それらの Qubit の情報は破棄しなければなりません。
  • 測定基底をランダムに選ぶことで、盗聴者は送信前の初期状態を知ることができず、送信された状態を再現することもできません。これにより、盗聴が必ず検出されます。

正誤問題

  1. 正誤:量子鍵配送では、通信する2者はそれぞれの Qubit を同じ基底で測定する。
  2. 正誤:QKD において量子情報を傍受した盗聴者は、自然の法則によって、傍受した量子状態のコピーが禁じられている。
  3. 正誤:ワンタイムパッドとは、特定の符号化方式をアルファベットの1文字のような単一の情報に対して一度だけ使用する、メッセージの暗号化/復号化のための鍵である。

選択問題

  1. 文を最もよく補完する選択肢を選んでください。このモジュールで説明したように、ワンタイムパッドとは、次のように使用される暗号化/復号化鍵の集合です…
  • a. 1文字のような単一の情報に対して、一度だけ使用する。
  • b. 1つのメッセージに対して、一度だけ使用する。
  • c. 1日のような一定の期間、一度だけ使用する。
  • d. 盗聴の証拠が見つかるまで使用する。
  1. アリスとボブが測定基底をランダムに選んだとします。2人は測定を行い、その後それぞれの測定基底を共有し、同じ基底を使用した場合の情報ビットのみを保持します。ランダムな揺らぎを除くと、Qubit のうち約何パーセントが有効な情報ビットをもたらすはずですか?
  • a. 100%
  • b. 50%
  • c. 25%
  • d. 12.5%
  • e. 0%
  1. アリスとボブが同じ測定基底を使用した場合のビットを選別した後、量子ノイズや誤りが無視できるとすると、それらの情報ビットのうち何パーセントが一致するはずですか?
  • a. 100%
  • b. 50%
  • c. 25%
  • d. 12.5%
  • e. 0%
  1. アリスが測定基底をランダムに選んだとします。イブもランダムに基底を選んで盗聴(測定)し、自分の測定結果と整合する状態をボブに送信します。アリスとボブは基底の選択を比較し、同じ基底で測定/準備した Qubit のみを保持します。ランダムな揺らぎを除くと、アリスとボブが保持した Qubit 測定結果のうち、約何パーセントが一致するでしょうか?
  • a. 100%
  • b. 75%
  • c. 50%
  • d. 25%
  • e. 12.5%
  • f. 0%

討論問題

  1. アリス、ボブ、イブ全員の基底選択がランダムであると仮定します。イブが盗聴した後、自分が測定した基底と同じ基底で準備し、その測定結果と整合する状態をボブに送信するとします。アリスが初期化した全 Qubit のうち12.5%が、アリスとボブの間で測定結果の不一致を引き起こし、盗聴を示すことを(量子誤りとノイズを無視して)パートナーに納得させてください。 ヒント1:優先される基底が存在しないため、アリスの初期選択を1つだけ考えた場合の割合は、すべての選択の合計に対する割合と同じになるはずです。 ヒント2:何かが起こり得る方法の数を数えるだけでは不十分な場合があります。一部の結果は異なる確率で起こり得るためです。

  2. 再び、アリス、ボブ、イブ全員の基底選択がランダムであると仮定します。ただし今回は、イブが測定後に任意の状態を送信できるとします。自分の測定結果と整合しない状態を送ることさえ可能です。アリスとボブに盗聴を示す Qubit の平均割合を減らすことができる基底の選択が存在するかどうか、パートナーや隣の人と議論してください。