Una prueba de primalidad es un algoritmo para determinar si un número de entrada es primo . Entre otros campos de las matemáticas , se utiliza para la criptografía . A diferencia de la factorización de números enteros , las pruebas de primalidad generalmente no dan factores primos , solo indican si el número de entrada es primo o no. Se piensa que la factorización es un problema computacionalmente difícil, mientras que las pruebas de primalidad son comparativamente fáciles (su tiempo de ejecución es polinomial en el tamaño de la entrada). Algunas pruebas de primalidad prueban que un número es primo, mientras que otras como Miller-Rabin prueban que un número es compuesto . Por lo tanto, estas últimas podrían llamarse con mayor precisión pruebas de composición en lugar de pruebas de primalidad.
La prueba de primalidad más simple es la división por tanteo : dado un número de entrada, , verifique si es divisible por cualquier número primo entre 2 y (es decir, si la división no deja resto ). Si es así, entonces es compuesto . De lo contrario, es primo. [1] Para cualquier divisor , debe haber otro divisor , y un divisor primo de , y por lo tanto, buscar divisores primos como máximo es suficiente.
Por ejemplo, consideremos el número 100, cuyos divisores son estos números:
Cuando se prueban todos los divisores posibles hasta , se descubrirán algunos divisores dos veces . Para observar esto, considere la lista de pares de divisores de 100:
Los productos pasados son el reverso de los productos que aparecieron antes. Por ejemplo, y son el reverso uno del otro. Además, el de los dos divisores, y . Esta observación se generaliza a todos los : todos los pares de divisores de contienen un divisor menor o igual a , por lo que el algoritmo solo necesita buscar divisores menores o iguales a para garantizar la detección de todos los pares de divisores. [1]
Además, 2 es un número primo que divide a 100, lo que demuestra inmediatamente que 100 no es primo. Todo entero positivo excepto 1 es divisible por al menos un número primo según el Teorema Fundamental de la Aritmética . Por lo tanto, el algoritmo solo necesita buscar divisores primos menores o iguales a .
Para otro ejemplo, considere cómo este algoritmo determina la primalidad de 17. Uno tiene , y los únicos primos son 2 y 3. Ninguno divide a 17, lo que demuestra que 17 es primo. Para un último ejemplo, considere 221. Uno tiene , y los primos son 2, 3, 5, 7, 11 y 13. Al verificar cada uno, uno descubre que , lo que demuestra que 221 no es primo.
En los casos en los que no es posible calcular la lista de primos , también es posible comprobar de forma sencilla (y lenta) si todos los números entre y tienen divisores. Una optimización bastante sencilla consiste en comprobar la divisibilidad por 2 y solo por los números impares entre 3 y , ya que la divisibilidad por un número par implica la divisibilidad por 2.
Este método se puede mejorar aún más. Observe que todos los primos mayores que 3 tienen la forma para un entero no negativo y . De hecho, cada entero tiene la forma para un entero positivo y . Como 2 divide a , y , y 3 divide a y , los únicos residuos posibles módulo 6 para un primo mayor que 3 son 1 y 5. Por lo tanto, una prueba de primalidad más eficiente para es probar si es divisible por 2 o 3, luego verificar todos los números de la forma y que son . Esto es casi tres veces más rápido que probar todos los números hasta .
Generalizando aún más, todos los primos mayores que ( c primorial ) son de la forma para los enteros positivos, , y coprimos con . Por ejemplo, considere . Todos los enteros son de la forma para los enteros con . Ahora, 2 divide a , 3 divide a , y 5 divide a . Por lo tanto, todos los números primos mayores que 30 son de la forma para . Por supuesto, no todos los números de la forma con coprimos con son primos. Por ejemplo, no es primo, aunque 17 es coprimo con .
A medida que crece, la fracción de restos coprimos a restos disminuye, y por lo tanto el tiempo para realizar la prueba disminuye (aunque todavía es necesario verificar la divisibilidad por todos los primos que son menores que ). Observaciones análogas a las anteriores se pueden aplicar de forma recursiva , dando como resultado la Criba de Eratóstenes .
Una forma de acelerar estos métodos (y todos los demás mencionados a continuación) es calcular previamente y almacenar una lista de todos los primos hasta un cierto límite, como todos los primos hasta 200. (Esta lista se puede calcular con la Criba de Eratóstenes o mediante un algoritmo que prueba cada incremental con todos los primos conocidos ). Luego, antes de probar la primalidad con un método a gran escala, primero se puede verificar la divisibilidad por cualquier primo de la lista. Si es divisible por cualquiera de esos números, entonces es compuesto y se pueden omitir las pruebas posteriores.
Una prueba de primalidad simple pero muy ineficiente utiliza el teorema de Wilson , que establece que es primo si y solo si:
Aunque este método requiere multiplicaciones modulares, lo que lo hace poco práctico, los teoremas sobre primos y residuos modulares forman la base de muchos métodos más prácticos.
Se trata de pruebas que parecen funcionar bien en la práctica, pero que no están probadas y, por lo tanto, técnicamente hablando, no son algoritmos en absoluto. La prueba de Fermat y la prueba de Fibonacci son ejemplos sencillos y son muy eficaces cuando se combinan. John Selfridge ha conjeturado que si p es un número impar y p ≡ ±2 (mod 5), entonces p será primo si se cumplen las dos condiciones siguientes:
donde f k es el k - ésimo número de Fibonacci . La primera condición es la prueba de primalidad de Fermat usando base 2.
En general, si p ≡ a (mod x 2 +4), donde a es un residuo cuadrático no nulo (mod x 2 +4), entonces p debería ser primo si se cumplen las siguientes condiciones:
f ( x ) k es el k -ésimo polinomio de Fibonacci en x .
Selfridge, Carl Pomerance y Samuel Wagstaff juntos ofrecen $620 por un contraejemplo. [2]
Las pruebas probabilísticas son más rigurosas que las heurísticas en el sentido de que proporcionan límites demostrables sobre la probabilidad de ser engañado por un número compuesto. Muchas pruebas de primalidad populares son pruebas probabilísticas. Estas pruebas utilizan, aparte del número probado n , algunos otros números a que se eligen al azar de algún espacio muestral ; las pruebas de primalidad aleatorias habituales nunca informan un número primo como compuesto, pero es posible que un número compuesto se informe como primo. La probabilidad de error se puede reducir repitiendo la prueba con varios valores de a elegidos independientemente ; para dos pruebas de uso común, para cualquier compuesto n al menos la mitad de los a ' detectan la composición de n ' , por lo que k repeticiones reducen la probabilidad de error a como máximo 2 − k , que se puede hacer arbitrariamente pequeña aumentando k .
La estructura básica de las pruebas de primalidad aleatorias es la siguiente:
Después de una o más iteraciones, si no se descubre que n es un número compuesto, entonces se puede declarar probablemente primo .
La prueba de primalidad probabilística más simple es la prueba de primalidad de Fermat (en realidad, una prueba de composición). Funciona de la siguiente manera:
Si a n −1 (módulo n ) es 1 pero n no es primo, entonces n se llama pseudoprimo a base de a . En la práctica, si a n −1 (módulo n ) es 1, entonces n suele ser primo. Pero aquí hay un contraejemplo: si n = 341 y a = 2, entonces
aunque 341 = 11·31 es compuesto. De hecho, 341 es el pseudoprimo más pequeño de base 2 (ver Figura 1 de [3] ).
Sólo hay 21853 pseudoprimos de base 2 que son menores que 2,5 × 1010 (ver página 1005 de [3] ). Esto significa que, para n hasta 2,5 × 1010 , si 2 n −1 (módulo n ) es igual a 1, entonces n es primo, a menos que n sea uno de estos 21853 pseudoprimos.
Algunos números compuestos ( números de Carmichael ) tienen la propiedad de que a n − 1 es 1 (módulo n ) para todo a que sea coprimo con n . El ejemplo más pequeño es n = 561 = 3·11·17, para el cual a 560 es 1 (módulo 561) para todo a coprimo con 561. Sin embargo, la prueba de Fermat se utiliza a menudo si se necesita una selección rápida de números, por ejemplo en la fase de generación de claves del algoritmo criptográfico de clave pública RSA .
La prueba de primalidad de Miller-Rabin y la prueba de primalidad de Solovay-Strassen son variantes más sofisticadas, que detectan todos los compuestos (una vez más, esto significa: para cada número compuesto n , al menos 3/4 (Miller-Rabin) o 1/2 (Solovay-Strassen) de los números a son testigos de la composición de n ). Estas también son pruebas de composición.
La prueba de primalidad de Miller-Rabin funciona de la siguiente manera: dado un entero n , elija un entero positivo a < n . Sea 2 s d = n − 1, donde d es impar. Si
y
entonces n es compuesto y a es un testigo de la composición. De lo contrario, n puede ser primo o no. La prueba de Miller-Rabin es una prueba de primos probables sólida (ver PSW [3] página 1004).
La prueba de primalidad de Solovay-Strassen utiliza otra igualdad: Dado un número impar n , elija algún entero a < n , si
entonces n es compuesto y a es un testigo de la composición. De lo contrario, n puede ser primo o no. La prueba de Solovay-Strassen es una prueba de primos probables de Euler (véase PSW [3] página 1003).
Para cada valor individual de a , la prueba de Solovay–Strassen es más débil que la prueba de Miller–Rabin. Por ejemplo, si n = 1905 y a = 2, entonces la prueba de Miller-Rabin muestra que n es compuesto, pero la prueba de Solovay–Strassen no. Esto se debe a que 1905 es un pseudoprimo de Euler de base 2, pero no un pseudoprimo fuerte de base 2 (esto se ilustra en la Figura 1 de PSW [3] ).
Las pruebas de primalidad de Miller-Rabin y de Solovay-Strassen son sencillas y mucho más rápidas que otras pruebas de primalidad generales. Un método para mejorar aún más la eficiencia en algunos casos es la prueba de pseudoprimalidad de Frobenius ; una ronda de esta prueba lleva aproximadamente tres veces más tiempo que una ronda de Miller-Rabin, pero logra un límite de probabilidad comparable a siete rondas de Miller-Rabin.
La prueba de Frobenius es una generalización de la prueba de primos probables de Lucas .
La prueba de primalidad de Baillie-PSW es una prueba de primalidad probabilística que combina una prueba de Fermat o Miller-Rabin con una prueba de primos probables de Lucas para obtener una prueba de primalidad que no tiene contraejemplos conocidos. Es decir, no hay ningún compuesto n conocido para el cual esta prueba informe que n es probablemente primo. [4] [5] Se ha demostrado que no hay contraejemplos para n .
Leonard Adleman y Ming-Deh Huang presentaron una variante sin errores (pero con un tiempo polinomial esperado) de la prueba de primalidad de curva elíptica . A diferencia de otras pruebas probabilísticas, este algoritmo produce un certificado de primalidad y, por lo tanto, se puede utilizar para demostrar que un número es primo. [6] El algoritmo es prohibitivamente lento en la práctica.
Si existieran ordenadores cuánticos , la primalidad podría comprobarse de forma asintótica más rápida que utilizando ordenadores clásicos. Una combinación del algoritmo de Shor , un método de factorización de números enteros, con la prueba de primalidad de Pocklington podría resolver el problema en . [7]
A principios del siglo XX se demostró que se podía utilizar un corolario del pequeño teorema de Fermat para comprobar la primalidad. [8] Esto dio lugar a la prueba de primalidad de Pocklington . [9] Sin embargo, como esta prueba requiere una factorización parcial de n − 1, el tiempo de ejecución seguía siendo bastante lento en el peor de los casos. La primera prueba de primalidad determinista significativamente más rápida que los métodos ingenuos fue la prueba de ciclotomía ; se puede demostrar que su tiempo de ejecución es O ((log n ) c log log log n ), donde n es el número para comprobar la primalidad y c es una constante independiente de n . Se realizaron muchas mejoras adicionales, pero no se pudo demostrar que ninguna tuviera un tiempo de ejecución polinomial. (El tiempo de ejecución se mide en términos del tamaño de la entrada, que en este caso es ~ log n , que es el número de bits necesarios para representar el número n .) Se puede demostrar que la prueba de primalidad de la curva elíptica se ejecuta en O((log n ) 6 ), si algunas conjeturas sobre la teoría analítica de números son verdaderas. [ ¿cuáles? ] De manera similar, bajo la hipótesis generalizada de Riemann , se puede demostrar que la prueba determinista de Miller , que forma la base de la prueba probabilística de Miller-Rabin, se ejecuta en Õ ((log n ) 4 ). [10] En la práctica, este algoritmo es más lento que los otros dos para tamaños de números con los que se puede trabajar. Debido a que la implementación de estos dos métodos es bastante difícil y crea un riesgo de errores de programación, a menudo se prefieren pruebas más lentas pero más simples.
En 2002, Manindra Agrawal , Neeraj Kayal y Nitin Saxena inventaron la primera prueba polinómica determinista incondicional demostrable para la primalidad . La prueba de primalidad AKS se ejecuta en Õ((log n ) 12 ) (mejorada a Õ((log n ) 7,5 ) [11] en la revisión publicada de su artículo), que puede reducirse aún más a Õ((log n ) 6 ) si la conjetura de Sophie Germain es verdadera. [12] Posteriormente, Lenstra y Pomerance presentaron una versión de la prueba que se ejecuta en un tiempo Õ((log n ) 6 ) incondicionalmente. [13]
Agrawal, Kayal y Saxena sugieren una variante de su algoritmo que funcionaría en Õ((log n ) 3 ) si la conjetura de Agrawal es verdadera; sin embargo, un argumento heurístico de Hendrik Lenstra y Carl Pomerance sugiere que probablemente sea falsa. [11] Una versión modificada de la conjetura de Agrawal, la conjetura de Agrawal-Popovych, [14] todavía puede ser verdadera.
En la teoría de la complejidad computacional , el lenguaje formal correspondiente a los números primos se denota como PRIMES. Es fácil demostrar que PRIMES está en Co-NP : su complemento COMPOSITES está en NP porque uno puede decidir la composición adivinando de manera no determinista un factor.
En 1975, Vaughan Pratt demostró que existía un certificado de primalidad que se podía comprobar en tiempo polinomial y, por lo tanto, que PRIMES estaba en NP y, por lo tanto, en . Véase el certificado de primalidad para más detalles.
El descubrimiento posterior de los algoritmos Solovay–Strassen y Miller–Rabin puso a PRIMES en coRP . En 1992, el algoritmo Adleman–Huang [6] redujo la complejidad a , lo que sustituyó al resultado de Pratt.
La prueba de primalidad de Adleman-Pomerance-Rumely de 1983 puso a PRIMES en QP ( tiempo cuasi-polinomial ), que no se sabe que sea comparable con las clases mencionadas anteriormente.
Debido a su manejabilidad en la práctica, los algoritmos de tiempo polinomial que asumen la hipótesis de Riemann y otras evidencias similares, se sospechó durante mucho tiempo, pero no se demostró, que la primalidad podía resolverse en tiempo polinomial. La existencia de la prueba de primalidad AKS finalmente resolvió esta pregunta de larga data y colocó a PRIMES en P . Sin embargo, no se sabe que PRIMES sea P-completo , y no se sabe si se encuentra en clases que se encuentran dentro de P, como NC o L . Se sabe que PRIMES no está en AC 0 . [15]
Existen ciertos métodos de teoría de números para comprobar si un número es primo, como la prueba de Lucas y la prueba de Proth . Estas pruebas suelen requerir la factorización de n + 1, n − 1 o una cantidad similar, lo que significa que no son útiles para pruebas de primalidad de propósito general, pero suelen ser bastante potentes cuando se sabe que el número n probado tiene una forma especial.
La prueba de Lucas se basa en el hecho de que el orden multiplicativo de un número a módulo n es n − 1 para un número primo n cuando a es una raíz primitiva módulo n . Si podemos demostrar que a es primitivo para n , podemos demostrar que n es primo.