{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e5e44fb3",
   "metadata": {},
   "source": [
    "## Ejemplo 10.2: Seguridad del protocolo BB84"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "71cd75b7",
   "metadata": {},
   "source": [
    "$\\newcommand{\\ket}[1]{|{#1}\\rangle}\\newcommand{\\bra}[1]{\\langle{#1}|}$Imaginemos que en el instante $i$, Alice ha generado los bits de clave $a_i=1$ y $b_i=1$, y por tanto, ha codificado el estado $\\rho_A^{(i)} = \\Pi_{-}$.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "e51496e6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "rhoAi =\n",
      " [[ 0.5 -0.5]\n",
      " [-0.5  0.5]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "# Definimos las bases de medida\n",
    "Pi0 = np.array([[1,0],[0,0]])\n",
    "Pi1 = np.array([[0,0],[0,1]])\n",
    "Pip = np.array([[+1,+1],[+1,+1]])/2\n",
    "Pim = np.array([[+1,-1],[-1,+1]])/2\n",
    "\n",
    "# Y el estado inicial para a_i = b_i = 1\n",
    "rhoAi = Pim\n",
    "print('rhoAi =\\n', rhoAi)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7625c52a",
   "metadata": {},
   "source": [
    "Eve conoce el esquema de codificación, pero no conoce el valor de $a_i$ ni de $b_i$, así que escoje una base al azar para realizar una medida con resultado $e_i$:\n",
    "\n",
    "- Si Eve aplica el POVM $\\{\\Pi_{0}, \\Pi_{1}\\}$, entonces $\\Pr\\bigl\\{E_i\\!=\\!0\\bigr\\} = \\Pr\\bigl\\{E_i\\!=\\!1\\bigr\\} = \\frac{1}{2}$ y el estado pasa a ser:\n",
    "\\begin{align*}\n",
    "\\rho_E^{(i)} = \\begin{cases}\n",
    "           \\Pi_{0}, & e_i=0,\\\\\n",
    "           \\Pi_{1}, & e_i=1.\n",
    "       \\end{cases}\n",
    "\\end{align*}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "746f0b09",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Pr_ei_0 = 0.5 \n",
      "Pr_ei_1 = 0.5\n",
      "rhoEi_0 =\n",
      " [[1. 0.]\n",
      " [0. 0.]] \n",
      "rhoEi_1 =\n",
      " [[0. 0.]\n",
      " [0. 1.]]\n"
     ]
    }
   ],
   "source": [
    "Pr_ei_0 = np.trace(Pi0 @ rhoA_i)\n",
    "Pr_ei_1 = np.trace(Pi1 @ rhoA_i)\n",
    "print('Pr_ei_0 =', Pr_ei_0, '\\nPr_ei_1 =', Pr_ei_1)\n",
    "\n",
    "rhoEi_0 = Pi0 @ rhoA_i@ Pi0.conj().T / Pr_ei_0\n",
    "rhoEi_1 = Pi1 @ rhoA_i @ Pi1.conj().T / Pr_ei_1\n",
    "print('rhoEi_0 =\\n', rhoEi_0, '\\nrhoEi_1 =\\n', rhoEi_1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "94c1b5e6",
   "metadata": {},
   "source": [
    "- Si Eve aplica el POVM correcto $\\{\\Pi_{+}, \\Pi_{-}\\}$, entonces $\\Pr\\bigl\\{E_i\\!=\\!1\\bigr\\} = 1$ y la medida siempre resulta en el bit correcto $e_i=1$. Por tanto, el estado colapsado pasa a ser $\\rho_E^{(i)} = \\rho_A^{(i)} = \\Pi_{-}$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "ddadd2f6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Pr_ei_p = 0.0 \n",
      "Pr_ei_m = 1.0\n",
      "rhoEi_m =\n",
      " [[1. 0.]\n",
      " [0. 0.]]\n"
     ]
    }
   ],
   "source": [
    "Pr_ei_p = np.trace(Pip @ rhoA_i)\n",
    "Pr_ei_m = np.trace(Pim @ rhoA_i)\n",
    "print('Pr_ei_p =', Pr_ei_p, '\\nPr_ei_m =', Pr_ei_m)\n",
    "\n",
    "rhoEi_m = Pim @ rhoA_i@ Pim.conj().T / Pr_ei_m\n",
    "print('rhoEi_m =\\n', rhoEi_0)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9e8713e8",
   "metadata": {},
   "source": [
    "En el segundo caso, Eve puede transmitir el estado $\\rho_E^{(i)}$ a Bob y la intrusión permanecería indetectada, ya que $\\rho_E^{(i)} = \\rho_A^{(i)}$.\n",
    "Sin embargo, en el primer caso tenemos que $\\rho_E^{(i)} \\neq \\rho_A^{(i)}$. Si Eve transmite este estado $\\rho_E^{(i)}$ a Bob y éste realiza su medida en la base $\\{\\Pi_{+}, \\Pi_{-}\\}$, entonces obtendrá un resultado $\\Pr\\bigl\\{\\hat{A}_i = 0\\bigr\\} = \\Pr\\bigl\\{\\hat{A}_i = 1\\bigr\\} = \\frac{1}{2}$ independientemente del valor de $e_i$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "e935943a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "ei =  0 \n",
      "Pr_hat_0 = 0.5 \n",
      "Pr_hat_1 = 0.5\n",
      "\n",
      "ei =  1 \n",
      "Pr_hat_0 = 0.5 \n",
      "Pr_hat_1 = 0.5\n"
     ]
    }
   ],
   "source": [
    "# Medida en Bob cuando Eve utiliza la base {Pi0, Pi1} y Bob aplica la base {Pip, Pim}\n",
    "ei = 0\n",
    "Pr_hat_0 = np.trace(Pip @ rhoEi_0)\n",
    "Pr_hat_1 = np.trace(Pim @ rhoEi_0)\n",
    "print('\\nei = ', ei, '\\nPr_hat_0 =', Pr_hat_0, '\\nPr_hat_1 =', Pr_hat_1)\n",
    "\n",
    "ei = 1\n",
    "Pr_hat_0 = np.trace(Pip @ rhoEi_1)\n",
    "Pr_hat_1 = np.trace(Pim @ rhoEi_1)\n",
    "print('\\nei = ', ei, '\\nPr_hat_0 =', Pr_hat_0, '\\nPr_hat_1 =', Pr_hat_1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ca7f37b0",
   "metadata": {},
   "source": [
    "Concluimos que en las posiciones donde Eve se ha equivocado en la base de medida, ya no se tiene por qué cumplir $a_i=\\hat{a}_i$, aunque coincidan las secuencias $b_i=c_i$."
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Raw Cell Format",
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
