Saltearse al contenido

Algoritmo de Shor

El algoritmo de Shor es un algoritmo cuántico desarrollado por Peter Shor en 1994, diseñado para factorizar números enteros de manera eficiente.

Su importancia radica en que puede resolver este problema en tiempo polinomial, en contraste con los mejores algoritmos clásicos conocidos, que requieren tiempo subexponencial o exponencial.

La aplicación más destacada está en la criptografía, ya que amenaza la seguridad de los sistemas basados en la factorización de números grandes, como RSA.

El objetivo del algoritmo de Shor es encontrar los factores de un número entero compuesto NN.

La clave del algoritmo radica en identificar el período de la función f(r)=xr mod Nf(r) = x^r\ mod\ N, donde NN es el número que se quiere factorizar, xx es un número elegido al azar tal que 1<x<N1<x<N y xx es coprimo de NN (es decir, xx y NN no comparten factores primos), y rr es el período buscado.

Para lograrlo, utiliza un enfoque híbrido que combina cálculos clásicos con una subrutina cuántica basada en la estimación de fases.

Factorizar un número NN implica encontrar dos números pp y qq tal que N=pqN=pq.

Otra forma de expresar este problema es a partir de la búsqueda del período u orden de un número xrx^r, tal que xr mod N=1x^r\ mod\ N=1, y rr debe ser lo más chico posible y mayor a 00. Por ejemplo:

x=4, N=5x0 mod N=40 mod 5=1x1 mod N=41 mod 5=4x2 mod N=42 mod 5=1x3 mod N=43 mod 5=4x4 mod N=44 mod 5=1x=4,\ N=5\\ x^0\ mod\ N=4^0\ mod\ 5=1\\ x^1\ mod\ N=4^1\ mod\ 5=4\\ x^2\ mod\ N=4^2\ mod\ 5=1\\ x^3\ mod\ N=4^3\ mod\ 5=4\\ x^4\ mod\ N=4^4\ mod\ 5=1\\ \vdots

En este caso r=2r=2, por lo que cada 2 valores se repite la secuencia.

Una vez identificado rr, se obtienen los factores de NN de la siguiente manera (gcdgcd significa Greatest Common Divisor, que en español se traduce como mcdmcd, Máximo Común Divisor):

p=gcd(xr/21,N)=gcd(42/21,N)=1q=gcd(xr/2+1,N)=gcd(42/2+1,N)=5p=gcd(x^{r/2}-1,N)=gcd(4^{2/2}-1,N)=1\\ q=gcd(x^{r/2}+1,N)=gcd(4^{2/2}+1,N)=5\\

El algoritmo de Shor resuelve el problema de factorización utilizando una solución mixta, con componentes clásicos y con un componente cuántico que resuelve el problema de búsqueda del orden.

Este algoritmo tiene tres etapas clave:

  1. Clásico: Inicialización y selección de candidato

  2. Cuántico: Estimación de fases aplicado al candidato

  3. Clásico: Obtención del orden y los factores de NN

Estos pasos se pueden descomponer en componentes funcionales más chicos y menos misteriosos:

Diagrama del algoritmo de Shor, identificando sus componentes funcionales clásicas y cuánticas

Figura (1): Diagrama del algoritmo de Shor, identificando sus componentes funcionales clásicas y cuánticas.

Los componentes funcionales de este algoritmo se pueden a reducir a los siguientes pasos:

  1. Clásico: Si NN es par, p=2p=2 y q=N/2q=N/2. Terminar.

  2. Clásico: Si NN es una potencia de números primos, existe un algoritmo clásico eficiente para obtener rr y por lo tanto los factores pp y qq. Terminar.

  3. Clásico: Si NN no es par ni una potencia de números primos, obtener un número entre 1<x<N1 < x < N, tal que v=gcd(x,N)v=gcd(x,N). Si v1v\neq 1, entonces p=vp=v y q=N/vq=N/v. Terminar.

  4. Cuántico: Si v=1v=1 (son coprimos), obtener s/r~\widetilde{s/r} usando la subrutina cuántica de estimación de fases.

  5. Clásico: Obtener rr de s/r~\widetilde{s/r} utilizando el algoritmo de fracciones continuas.

  6. Clásico: Si rr es impar volver al paso 3. Verificar que xr mod N=1x^r\ mod\ N=1, y que b=xr/2 mod Nb=x^{r/2}\ mod\ N tal que bN1b\neq N-1 y b1b \neq 1, en caso contrario volver al paso 3.

  7. Clásico: Obtener los factores:

    p=gcd(xr/21,N),q=gcd(xr/2+1,N)p=gcd(x^{r/2}-1,N), q=gcd(x^{r/2}+1,N)

Resolviendo estos pasos se soluciona el problema de factorización. En las próximas secciones se profundiza matemáticamente y se implementan estos pasos.

A continuación se divide la explicación de la solución en las tres etapas definidas previamente, a modo de simplificar la lectura del artículo.

Antes de siquiera elegir el candidato, se verifica que NN no sea par. En caso contrario los factores son obvios, p=2p=2 y q=N/2q=N/2.

Verificar que el número sea primo antes de empezar es ideal para evitar la búsqueda de factores no existentes (además de 11 y de sí mismo).

Por otra parte, si NN es una potencia de números primos, es decir N=ckN=c^k siendo cc un número primo, se puede obtener su exponente kk con un algoritmo clásico eficiente. Así, p=cp=c y q=ck1q=c^{k-1}.

Generar un valor aleatorio de xx tal que 1<x<N1 < x < N. Verificar v=gcd(x,N)v=gcd(x,N), si vv es diferente a 11, significa que no son coprimos, por lo que vv es un factor, obteniendo p=vp=v y q=N/vq=N/v.

Si v=1v=1, se procede a la estimación de fases aplicada a xx.

La estimación de fases permite obtener el autovalor de un autovector para una operación U. Este requiere tres parámetros como entrada:

  • El primero, qsalidaq_{salida}, es un registro inicializado en 00 donde se obtendrá φ~\widetilde{\varphi}, la fracción binaria del ángulo del autovalor e2πiφ~e^{2\pi i \widetilde{\varphi}}. Su tamaño condiciona la precisión de la fracción. A mayor tamaño, mayor precisión.
  • Por otra parte, el segundo parámetro es la puerta controlada de U.
  • Finalmente, el tercer parámetro es qentradaq_{entrada}, un registro que representa el autovector de U, del cual se quiere obtener su autovalor.

El primer parámetro es fácil de preparar: un registro de cubits inicializado en 0\ket{0}. El segundo depende de U, la cual se define a continuación.

Se define U en una forma general de la siguiente manera:

Uy=xy mod NU\ket{y}=\ket{xy\ mod\ N}

Aplicar U reiteradas veces sobre 1\ket{1} retorna una potencia de xx:

U01=x0 mod N=1 mod NU11=x1 mod NU21=x2 mod NUr1=xr mod N=x0 mod N\begin{align} U^0\ket{1}&=\ket{x^{0}\ mod\ N}=\ket{1\ mod\ N}\\ U^1\ket{1}&=\ket{x^{1}\ mod\ N}\\ U^2\ket{1}&=\ket{x^{2}\ mod\ N}\\ \vdots&\\ U^r\ket{1}&=\ket{x^{r}\ mod\ N}=\ket{x^0\ mod\ N}\\ \end{align}

A continuación se presenta usu_s, un estado cuántico del cual se quiere probar que es autovector de U con autovalor e2πis/re^{2\pi i s/r}:

us=1r(e2πis(0)/rx0mod N+e2πis(1)/rx1mod N++e2πis(r1)/rxr1mod N)=1rk=0r1e2πisk/rxkmod N\begin{align} \ket{u_s}&=\frac{1}{\sqrt{r}}(e^{-2\pi i s(0)/r} \ket{x^0 mod\ N}+e^{-2\pi i s(1)/r} \ket{x^1 mod\ N}+\\ &\ldots+ e^{-2\pi i s(r-1)/r} \ket{x^{r-1} mod\ N})\\ &=\frac{1}{\sqrt{r}}\sum^{r-1}_{k=0} e^{-2\pi i sk/r}\ket{x^k mod\ N}\\ \end{align}

Ahora se aplica U sobre us\ket{u_s} para verificar su autovalor.

Uus=1rk=0r1e2πisk/rUxkmod N=e2πis/rus\begin{align} U\ket{u_s}&=\frac{1}{\sqrt{r}}\sum^{r-1}_{k=0} e^{-2\pi i sk/r}U\ket{x^k mod\ N}\\ &=e^{2\pi i s/r}\ket{u_s} \end{align}

Por otra parte, al saber que us\ket{u_s} es autovector de U, ocurre el fenómeno de retroceso de fase cuando se aplica la puerta controlada de U:

CU1us=e2πis/r1usCU\ket{1}\ket{u_s}=e^{2\pi i s/r}\ket{1}\ket{u_s}

Para conseguir el tercer parámetro, se debe obtener el estado us\ket{u_s}, el cual se sabe que es autovector de U. Se construye una superposición de us\ket{u_s} que suple esta necesidad:

1rs=0r1us=1\begin{align} \frac{1}{\sqrt{r}}\sum_{s=0}^{r-1}\ket{u_s}&=\ket{1} \end{align}

Así, se tienen los tres parámetros necesarios para la implementación de estimación de fase, por lo que se obtiene el siguiente circuito:

Estructura de la primitiva EF aplicada al algoritmo de Shor, con cuatro señalizadores indicando las distintas secciones del algoritmo. Las puertas siguen un patrón escalonado del cubit de control, empezando por el último (de arriba hacia abajo) y finalizando con el primero (el de arriba) como cubit de control.

Figura (2): Estructura de la primitiva EF aplicada al algoritmo de Shor.

Se aplica el algoritmo de estimación de fases sobre 01\ket{0}\ket{1}. Como el autovalor de 1\ket{1} es e2πis/re^{2\pi i s/r}, el resultado es:

EF01=s/r~1\begin{align} EF\ket{0}\ket{1}&=\ket{\widetilde{s/r}}\ket{1} \end{align}

Se obtiene finalmente el valor de s/r~\widetilde{s/r} luego de aplicar una lectura en qsalidaq_{salida}. Este valor es estimado a un nivel de precisión dependiente de la cantidad de cubits provistos.

Luego de obtener s/r~\widetilde{s/r}, que es una fracción binaria con formato 0.j0j1jn0.j_0j_1\ldots j_n, se convierte la fracción binaria a una fracción decimal de la siguiente manera:

j=0.jn1jn2j0,ji{0,1},0inl=0.lm1lm2l0,lh{0,1,2,3,4,5,6,7,8,9},0hms/r~=j=0.jn1jn2j0=0+jn121+jn222++2n1j0=0.lm1lm2l0=l\begin{align} j=0.j_{n-1}j_{n-2}\ldots j_0&, j_i \in \{0,1\}, 0\leq i \leq n\\ l=0.l_{m-1}l_{m-2}\ldots l_0&, l_h \in \{0,1,2,3,4,5,6,7,8,9\}, 0\leq h \leq m\\ \widetilde{s/r}&=j\\ &=0.j_{n-1}j_{n-2}\ldots j_0\\ &=0+j_{n-1}2^{-1}+j_{n-2}2^{-2}+\ldots +2^{n-1}j_0\\ &=0.l_{m-1}l_{m-2}\ldots l_0\\ &=l \end{align}

Una vez obtenido el valor de la fracción decimal, se utiliza un algoritmo para convertir de la fracción decimal a una fracción continua que tiene el siguiente formato:

x=b0+1b1+1b2+1x=b_0+\frac{1}{b_1+\frac{1}{b_2+\frac{1}{\ddots}}}

El resultado de este algoritmo será un arreglo de valores enteros cfc_f que representa la fracción continua, cf=[b0,b1,b2,]c_f=[b_0,b_1,b_2,\ldots]. Por ejemplo, con el valor 0.15620.1562:

0.1562=156210000=0+1100001562=0+16+6281562=0+16+12+12+119+18\begin{align} 0.1562&=\frac{1562}{10000}\\ &=0+\frac{1}{\frac{10000}{1562}}\\ &=0+\frac{1}{6+\frac{628}{1562}}\\ &\quad\vdots\\ &=0+\frac{1}{6+\frac{1}{2+\frac{1}{2+\frac{1}{19+\frac{1}{8}}}}} \end{align}

Se obtiene la fracción continua como un arreglo de los valores enteros: [0,6,2,2,19,8][0,6,2,2,19,8]

A partir de este arreglo cfc_f es posible conseguir el numerador y denominador de la fracción:

s0=1,r0=0bkcf,0k,g<cfsk=rk1+sk1bkrk=sk1s=sg,r=rg,rg=max(rk)rk<N\begin{align} s_0 = 1,& \quad r_0 = 0\\ b_k \in c_f,& \quad 0\leq k,g < |c_f|\\ s_k &= r_{k-1} + s_{k-1} \cdot b_k\\ r_k &= s_{k-1}\\ s=s_{g}, & \quad r=r_{g},\quad r_g=max(r_k)|r_k<N \end{align}

Por lo que se extrae rr a partir de la fracción continua, siendo este el valor con mayor precisión posible de rkr_k menor a NN.

El último paso a realizar es comprobar que rr es un valor correcto y extraer los factores. En todos los casos en los que rr no sea correcto, se debe elegir un nuevo candidato y reiterar el algoritmo cuántico para obtener otro valor de rr posible.

El valor de rr es correcto cuando es par, es decir que r mod 2=0r\ mod\ 2=0. A su vez, tiene que cumplir que xr mod N=1x^r\ mod\ N=1, siendo esta la premisa del problema del orden.

Por otra parte se computa y=xr/2 mod Ny=x^{r/2}\ mod\ N y se verifica que y1y\neq 1, yN1y\neq N-1 para no obtener los factores “obvios” de NN, es decir 11 y NN.

Finalmente se obtienen los valores de pp y qq de la siguiente manera:

p=gcd(xr/21,N)q=gcd(xr/2+1,N)p=gcd(x^{r/2}-1,N)\\ q=gcd(x^{r/2}+1,N)

Dentro de esta sección se implementará el algoritmo de Shor. Se presentará un ejemplo simple y otro ejemplo más general, expresando limitaciones y desafíos a la hora de implementar este algoritmo.

Como primer ejemplo se factoriza el número 1515 con el candidato 77, cuyos factores pp y qq son 33 y 55.

Los ejemplos con Quirk comprenden la parte cuántica del algoritmo, por lo que luego se debe realizar el algoritmo de fracciones continuas para obtener los factores pp y qq.

Por otra parte en el ejemplo de Qiskit, se resuelve el problema completo, con partes de computación clásica y cuántica.

Se interpreta s/rs/r como una fracción binaria.

Por ejemplo si se obtiene el valor 110000002=21+22=0.751011000000_2=2^{-1}+2^{-2}=0.75_{10}

Luego, con fracciones continuas se tiene que 0.75=[0,1,3]0.75=[0,1,3]. Finalmente, r=4r=4.

Como resultado, p=gcd(721,15)=3p=gcd(7^2-1,15)=3, q=gcd(72+1,15)=5q=gcd(7^2+1,15)=5.

A la hora de factorizar números más grandes se presentan dos problemas.

El primero es el físico. Al no existir máquinas cuánticas con cubits lógicos suficientes, se emula su funcionamiento en computadoras clásicas. Este procedimiento es muy costoso, ya que el crecimiento en cantidad de operaciones es exponencial.

El segundo problema tiene que ver con la implementación de la exponencialización modular. En el ejemplo previo se utilizó una puerta que calculaba el módulo con N=15N=15 y se repitió de forma exponencial la utilización de esta puerta según el cubit, es decir, una vez en el primer cubit, 2 veces en el segundo cubit, 4 veces en el tercero, etc.

La aplicación exponencial de las puertas controladas de módulo deshacen la ventaja exponencial provista por el algoritmo. Existen circuitos eficientes[1][2]^{[1][2]} que resuelven este problema. Debido al costo de emularlos, se decidió evitar la implementación de un algoritmo general de Shor en Qiskit.

Bibliografía:
Recomendada
Alternativa
Opcional