{
 "nbformat": 4,
 "nbformat_minor": 5,
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.10.0"
  },
  "colab": {
   "provenance": [],
   "toc_visible": true
  }
 },
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "# BBM92 Quantum Key Distribution (Entanglement-Based QKD)\n### Uygulamalı Google Colab Notebook\n\n**Protokol:** BBM92 (Bennett–Brassard–Mermin 1992)  \n**Temel:** Entanglement (Bell durumu) + iki bazda ölçüm  \n**Hedef:** Alice ve Bob arasında paylaşılan gizli anahtar üretmek  \n**Ortam:** Qiskit Aer simülatörü (Colab’da çalışır)\n\n---\n\n## Bu notebook ne öğretir?\n\n1. BBM92 protokolünün teorik temeli\n2. Entangled Bell çifti üretimi\n3. Rastgele baz seçimi ve ölçüm\n4. Sifting (baz eşleştirme)\n5. QBER (Quantum Bit Error Rate) tahmini\n6. Basitleştirilmiş anahtar damıtma\n7. Eve saldırısı simülasyonu (opsiyonel)\n8. Görselleştirme ve metrikler\n\n> Hücreleri **sırayla** çalıştırın."
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "## 📋 İçindekiler\n\n| Aşama | İçerik |\n|-------|--------|\n| 0 | Kütüphane kurulumu |\n| 1 | BBM92 Teorik Özet |\n| 2 | Yardımcı fonksiyonlar |\n| 3 | Entangled pair + ölçüm devresi |\n| 4 | Tek tur simülasyonu |\n| 5 | Çoklu tur + Sifting |\n| 6 | QBER hesaplama |\n| 7 | Anahtar üretimi (sifted key) |\n| 8 | Eve saldırısı örneği |\n| 9 | Görselleştirme ve özet |"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "## AŞAMA 0: Kütüphane Kurulumu"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": "print(\"Qiskit ve yardımcı kütüphaneler yükleniyor...\")\n!pip install -q qiskit qiskit-aer matplotlib numpy pandas\n\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom qiskit import QuantumCircuit, transpile\nfrom qiskit_aer import AerSimulator\nfrom qiskit.visualization import plot_histogram, plot_bloch_multivector\nfrom IPython.display import display, Markdown\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nprint(\"✅ Kurulum tamamlandı.\")\nprint(\"✅ AŞAMA 0 tamamlandı.\")",
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "## AŞAMA 1: BBM92 Teorik Özet\n\n### BBM92 Nedir?\n\nBBM92, **entanglement tabanlı** bir Quantum Key Distribution protokolüdür (1992).  \nBB84’ten farkı: Tek foton polarizasyonu yerine **paylaşılan Bell durumu** (entangled pair) kullanılır.\n\n### Temel Adımlar\n\n1. **Kaynak** (Source) entangled Bell çifti üretir:  \n   $$|\\Phi^+\\rangle = \\frac{1}{\\sqrt{2}}(|00\\rangle + |11\\rangle)$$\n\n2. Bir qubit Alice’e, diğeri Bob’a gönderilir.\n\n3. Alice ve Bob **bağımsız** olarak rastgele baz seçer (Z veya X) ve ölçer.\n\n4. **Sifting:** Bazlarını açık kanalda karşılaştırırlar. Aynı bazda ölçtükleri bitleri tutarlar.\n\n5. **QBER tahmini:** Bir alt küme üzerinde hata oranını hesaplarlar.  \n   Düşük QBER → güvenlik devam eder.\n\n6. **Key distillation:** Error correction + Privacy amplification ile final gizli anahtar üretilir.\n\n### Güvenlik Temeli\n- Entanglement monogamy\n- Bell eşitsizliği ihlali (veya basit QBER eşiği)\n- Eve ölçüm yaparsa korelasyonu bozar → QBER yükselir"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "## AŞAMA 2: Yardımcı Fonksiyonlar"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": "def create_bell_pair():\n    \"\"\"|Φ+⟩ = (|00⟩ + |11⟩)/√2  Bell durumu üretir.\"\"\"\n    qc = QuantumCircuit(2, 2)\n    qc.h(0)\n    qc.cx(0, 1)\n    return qc\n\ndef measure_in_basis(qc, qubit, basis, cbit):\n    \"\"\"\n    basis = 'Z' → standart ölçüm\n    basis = 'X' → H kapısı + ölçüm\n    \"\"\"\n    if basis == 'X':\n        qc.h(qubit)\n    qc.measure(qubit, cbit)\n    return qc\n\ndef run_circuit(qc, shots=1):\n    \"\"\"AerSimulator ile çalıştır.\"\"\"\n    sim = AerSimulator()\n    tqc = transpile(qc, sim)\n    result = sim.run(tqc, shots=shots).result()\n    counts = result.get_counts()\n    return counts\n\nprint(\"✅ Yardımcı fonksiyonlar tanımlandı.\")\nprint(\"✅ AŞAMA 2 tamamlandı.\")",
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "## AŞAMA 3: Entangled Pair + Ölçüm Devresi Örneği\n\nTek bir Bell çifti oluşturup hem Z hem X bazında ölçüm örneği gösterelim."
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": "# Örnek 1: Her ikisi de Z bazında ölçsün\nqc_z = create_bell_pair()\nmeasure_in_basis(qc_z, 0, 'Z', 0)  # Alice\nmeasure_in_basis(qc_z, 1, 'Z', 1)  # Bob\n\nprint(\"Z-Z ölçüm devresi:\")\nprint(qc_z.draw(output='text'))\n\ncounts_z = run_circuit(qc_z, shots=1024)\nprint(\"\\nZ-Z sonuçları (ideal durumda sadece 00 ve 11 çıkmalı):\")\nprint(counts_z)\n\n# Örnek 2: Her ikisi de X bazında ölçsün\nqc_x = create_bell_pair()\nmeasure_in_basis(qc_x, 0, 'X', 0)\nmeasure_in_basis(qc_x, 1, 'X', 1)\n\nprint(\"\\nX-X ölçüm devresi:\")\nprint(qc_x.draw(output='text'))\n\ncounts_x = run_circuit(qc_x, shots=1024)\nprint(\"\\nX-X sonuçları (ideal durumda yine sadece 00 ve 11):\")\nprint(counts_x)\n\nprint(\"\\n✅ AŞAMA 3 tamamlandı.\")",
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "## AŞAMA 4: Tek Tur Simülasyonu (Alice & Bob)"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": "def single_round(alice_basis=None, bob_basis=None, verbose=True):\n    \"\"\"\n    Tek bir BBM92 turu çalıştırır.\n    Alice ve Bob rastgele (veya verilen) baz seçer, ölçer.\n    Dönen: alice_bit, bob_bit, alice_basis, bob_basis\n    \"\"\"\n    if alice_basis is None:\n        alice_basis = np.random.choice(['Z', 'X'])\n    if bob_basis is None:\n        bob_basis = np.random.choice(['Z', 'X'])\n\n    qc = create_bell_pair()\n    measure_in_basis(qc, 0, alice_basis, 0)  # Alice qubit 0\n    measure_in_basis(qc, 1, bob_basis, 1)    # Bob qubit 1\n\n    counts = run_circuit(qc, shots=1)\n    outcome = list(counts.keys())[0]  # örn. '00', '01', '10', '11'\n\n    # Qiskit little-endian: en sağdaki bit qubit 0\n    alice_bit = int(outcome[1])\n    bob_bit   = int(outcome[0])\n\n    if verbose:\n        print(f\"Alice baz: {alice_basis} → bit {alice_bit}   |   Bob baz: {bob_basis} → bit {bob_bit}\")\n\n    return alice_bit, bob_bit, alice_basis, bob_basis\n\nprint(\"Tek tur örnekleri:\")\nfor i in range(5):\n    single_round()\nprint(\"\\n✅ AŞAMA 4 tamamlandı.\")",
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "## AŞAMA 5: Çoklu Tur + Sifting\n\nBirçok tur çalıştırıp aynı bazda ölçülen bitleri (sifted key) çıkaralım."
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": "def run_bbm92(n_rounds=200, seed=42):\n    \"\"\"\n    n_rounds kadar BBM92 turu çalıştırır.\n    Dönen DataFrame: alice_bit, bob_bit, alice_basis, bob_basis, match\n    \"\"\"\n    np.random.seed(seed)\n    records = []\n\n    for _ in range(n_rounds):\n        a_bit, b_bit, a_basis, b_basis = single_round(verbose=False)\n        match = (a_basis == b_basis)\n        records.append({\n            'alice_bit': a_bit,\n            'bob_bit': b_bit,\n            'alice_basis': a_basis,\n            'bob_basis': b_basis,\n            'basis_match': match\n        })\n\n    df = pd.DataFrame(records)\n    return df\n\ndf = run_bbm92(n_rounds=300)\nprint(f\"Toplam tur: {len(df)}\")\nprint(f\"Baz eşleşmesi (sifting adayı): {df['basis_match'].sum()}  (%{100*df['basis_match'].mean():.1f})\")\nprint(\"\\nİlk 10 satır:\")\ndisplay(df.head(10))\nprint(\"\\n✅ AŞAMA 5 tamamlandı.\")",
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "## AŞAMA 6: QBER Hesaplama\n\nSifted bitler üzerinde Quantum Bit Error Rate hesaplanır.  \nİdeal (gürültüsüz) simülasyonda QBER ≈ 0 olmalıdır."
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": "def compute_qber(df):\n    \"\"\"Sifted (baz eşleşen) bitler üzerinde QBER.\"\"\"\n    sifted = df[df['basis_match']].copy()\n    if len(sifted) == 0:\n        return None, 0\n\n    errors = (sifted['alice_bit'] != sifted['bob_bit']).sum()\n    qber = errors / len(sifted)\n    return qber, len(sifted)\n\nqber, n_sifted = compute_qber(df)\nprint(f\"Sifted bit sayısı : {n_sifted}\")\nprint(f\"QBER              : {qber:.4f}  ({qber*100:.2f}%)\")\nprint(\"(İdeal gürültüsüz simülasyonda QBER ≈ 0 olmalı)\")\nprint(\"\\n✅ AŞAMA 6 tamamlandı.\")",
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "## AŞAMA 7: Anahtar Üretimi (Sifted Key)\n\nBazları eşleşen ve (isteğe bağlı) QBER kontrolünden geçen bitler ortak anahtarın ham halini oluşturur."
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": "def extract_sifted_key(df, max_bits=64):\n    \"\"\"Sifted bitlerden Alice ve Bob anahtarını çıkar.\"\"\"\n    sifted = df[df['basis_match']].copy()\n    # İdeal durumda alice_bit == bob_bit olmalı\n    alice_key = sifted['alice_bit'].values[:max_bits]\n    bob_key   = sifted['bob_bit'].values[:max_bits]\n    return alice_key, bob_key\n\nalice_key, bob_key = extract_sifted_key(df, max_bits=40)\n\nprint(\"Alice sifted key (ilk 40 bit):\")\nprint(''.join(map(str, alice_key)))\nprint(\"\\nBob   sifted key (ilk 40 bit):\")\nprint(''.join(map(str, bob_key)))\nprint(f\"\\nEşleşme oranı: {np.mean(alice_key == bob_key)*100:.1f}%\")\nprint(\"\\n✅ AŞAMA 7 tamamlandı.\")",
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "## AŞAMA 8: Eve Saldırısı Simülasyonu (Basit Intercept-Resend)\n\nEve, Bob’a giden qubit’i ölçüp yeniden gönderirse korelasyon bozulur ve QBER yükselir."
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": "def single_round_with_eve(eve_basis='Z', verbose=False):\n    \"\"\"\n    Eve, Bob’un qubit’ini ölçer ve yeniden hazırlar (intercept-resend).\n    Bu, entanglement’ı bozar.\n    \"\"\"\n    alice_basis = np.random.choice(['Z', 'X'])\n    bob_basis   = np.random.choice(['Z', 'X'])\n\n    # 1. Bell pair\n    qc = create_bell_pair()\n\n    # 2. Eve Bob’un qubit’ini (qubit 1) ölçer\n    if eve_basis == 'X':\n        qc.h(1)\n    qc.measure(1, 1)\n    # Eve’nin ölçüm sonucuna göre qubit’i yeniden hazırlamak için\n    # basit bir yaklaşım: ölçüm sonrası reset + hazırlama (simülasyon için)\n    # Gerçekçi intercept-resend için ekstra klasik kontrol gerekir.\n    # Burada QBER artışını göstermek için Eve’nin ölçümünü koruyoruz.\n\n    # Alice kendi qubit’ini ölçer\n    if alice_basis == 'X':\n        qc.h(0)\n    qc.measure(0, 0)\n\n    # Bob da ölçer (ama Eve zaten bozmuş olabilir)\n    # Basitleştirilmiş model: Eve’nin ölçümü Bob’un sonucunu etkiler\n    counts = run_circuit(qc, shots=1)\n    outcome = list(counts.keys())[0]\n    alice_bit = int(outcome[1])\n    bob_bit   = int(outcome[0])   # Eve etkisiyle bozulmuş olabilir\n\n    return alice_bit, bob_bit, alice_basis, bob_basis\n\ndef run_bbm92_with_eve(n_rounds=200, seed=123):\n    np.random.seed(seed)\n    records = []\n    for _ in range(n_rounds):\n        a_bit, b_bit, a_basis, b_basis = single_round_with_eve()\n        match = (a_basis == b_basis)\n        records.append({\n            'alice_bit': a_bit,\n            'bob_bit': b_bit,\n            'alice_basis': a_basis,\n            'bob_basis': b_basis,\n            'basis_match': match\n        })\n    return pd.DataFrame(records)\n\ndf_eve = run_bbm92_with_eve(n_rounds=300)\nqber_eve, n_sifted_eve = compute_qber(df_eve)\n\nprint(\"Eve saldırısı sonrası:\")\nprint(f\"  Sifted bit sayısı : {n_sifted_eve}\")\nprint(f\"  QBER              : {qber_eve:.4f}  ({qber_eve*100:.2f}%)\")\nprint(\"\\nKarşılaştırma (Eve yokken QBER ≈ 0 idi).\")\nprint(\"Eve ölçüm yapınca QBER belirgin şekilde yükselir → saldırı tespit edilir.\")\nprint(\"\\n✅ AŞAMA 8 tamamlandı.\")",
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "## AŞAMA 9: Görselleştirme ve Özet"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": "fig, axes = plt.subplots(1, 2, figsize=(12, 4))\n\n# Baz eşleşme oranı\nmatch_counts = df['basis_match'].value_counts()\naxes[0].bar(['Baz Eşleşmedi', 'Baz Eşleşti'], [match_counts.get(False, 0), match_counts.get(True, 0)], color=['#e74c3c', '#27ae60'])\naxes[0].set_title('Sifting – Baz Eşleşme Dağılımı')\naxes[0].set_ylabel('Tur sayısı')\n\n# Alice vs Bob bit (sifted)\nsifted = df[df['basis_match']]\nagree = (sifted['alice_bit'] == sifted['bob_bit']).sum()\ndisagree = (sifted['alice_bit'] != sifted['bob_bit']).sum()\naxes[1].bar(['Aynı bit', 'Farklı bit'], [agree, disagree], color=['#3498db', '#e67e22'])\naxes[1].set_title('Sifted Bitlerde Anlaşma (QBER göstergesi)')\naxes[1].set_ylabel('Sayı')\n\nplt.tight_layout()\nplt.show()\n\nprint(\"\\n\" + \"=\"*60)\nprint(\"BBM92 SİMÜLASYON ÖZETİ\")\nprint(\"=\"*60)\nprint(f\"Toplam tur              : {len(df)}\")\nprint(f\"Sifted bit (baz eşleşen): {n_sifted}\")\nprint(f\"QBER (Eve yok)          : {qber*100:.2f}%\")\nprint(f\"QBER (Eve var)          : {qber_eve*100:.2f}%\")\nprint(f\"Alice-Bob anahtar eşleşmesi: {np.mean(alice_key == bob_key)*100:.1f}%\")\nprint(\"=\"*60)\nprint(\"\\n✅ AŞAMA 9 tamamlandı.\")\nprint(\"\\nNotebook başarıyla sona erdi.\")\nprint(\"BBM92’nin temel adımları (entanglement → ölçüm → sifting → QBER → key) simüle edildi.\")",
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "## Ek Notlar ve İleri Adımlar\n\n- **Gerçek donanım:** Bu notebook Aer simülatörü kullanır. Gerçek photonic QKD sistemlerinde (ID Quantique, Toshiba, vb.) fiber veya free-space kanallar ve polarizasyon / time-bin encoding kullanılır.\n- **Error Correction & Privacy Amplification:** Production QKD’de Cascade / LDPC + universal hashing adımları eklenir.\n- **Bell test:** BBM92’nin güvenlik kanıtı sıklıkla CHSH eşitsizliği ihlali ile güçlendirilir.\n- **Gürültü modeli:** Depolarizing noise, amplitude damping ekleyerek daha gerçekçi QBER eğrileri çizilebilir.\n\nBu notebook BBM92’nin temel mantığını ve uygulamalı simülasyonunu sunar."
  }
 ]
}