Test de primalidad probabiĺıstico Taller de Álgebra I Segundo cuatrimestre de 2013
Pequeño Teorema de Fermat Teorema (Pierre de Fermat, 1640) Sea p N primo, y a Z, tal que p a. Entonces a p 1 1 (mod p). Teorema (Converso del teorema anterior) Sea p N, a Z, tal que p a, y a p 1 1 (mod p). Entonces p no es primo.
Teorema inverso Idea Entonces, si tengo un p N, y quiero ver si es primo, puedo elegir un a Z, 0 < a < p. Si a p 1 1 (mod p), entonces p no es primo. Si vale la congruencia... vale que p es primo? No Por ejemplo, si tengo p = 9, y a = 8, vemos que a p 1 = 8 8 ( 1) 8 1 (mod 9). Sin embargo, p no es primo.
Definiciones Definición (Testigo) Dado p N, a Z, 0 < a < p, se dice que a es un testigo de Fermat de p cuando a p 1 1 (mod p). Definición (Pseudoprimo de Fermat) Dado p N, a Z, 0 < a < p, se dice que p es un pseudoprimo de Fermat en base a cuando p no es primo, pero a p 1 1 (mod p).
Idea del test de primalidad Idea De todas maneras, puedo usar al inverso del teorema como un test probabiĺıstico: Si a p 1 1 (mod p), a es un testigo de Fermat para p, entonces definitivamente p no es primo. Si a p 1 1 (mod p), puede que p sea primo o no (p podría ser un pseudoprimo de Fermat en base a). Puedo repetir el test con otro a, tantas veces como quiera, para estar más y más seguro de que p es primo.
Test de primalidad de Fermat Test de primalidad de Fermat Entrada: p N, p 2. Salida: Bool, indicando si p es probablemente primo. 1. Elijo un a Z, 0 < a < p. 1.1. Si a p 1 1 (mod p), entonces p no es primo. Devuelvo False. 1.2. Si a p 1 1 (mod p), puede ser que p sea primo. 1.2.1. Si quiero estar más seguro de que p es primo, ir al paso 1. 1.2.2. Si no, devuelvo True.
En la compu... A nuestro algoritmo le vamos a pasar un p :: Integer, y una lista as :: [Integer], 0 < a < p a as. Si para todo a en as, a p 1 1 (mod p), vamos a decir que p es probablemente primo. Si de lo contrario, para algún a en as, a p 1 1 (mod p), vamos a decir que p es definivamente no primo. Test de Primalidad de Fermat (casi) fermat :: Integer - > [ Integer ] - > Bool fermat p [] = True fermat p ( a: as) = a ^( p -1) `mod ` p == 1 && fermat p as
Exponenciación Pequeño problema... si usamos esto para p muy grande, se va a romper, porque está computando a p 1. Por ejemplo, si nos dan p = 13679257, y a = 5, el resultado tendría casi un millón de dígitos. Computar esto es... poco feliz. Idea Vamos a usar el truco que vimos hace algunas clases. Recordemos: 1 si n = 0 ( ) a n = a n 2 2 si n es par ( ) a n 2 2 a si n es impar Podemos hacer todas estas operaciones (mod p), y de esa forma mantener los números que manejamos pequeños!
En la compu... Semántica expmod a b c = x exactamente cuando x a b (mod c), y 0 x < c. Exponenciación modular expmod :: Integer - > Integer - > Integer - > Integer expmod a 0 c = 1 expmod a b c b `mod ` 2 == 0 = x ^2 `mod ` c otherwise = x ^2 * a `mod ` c where x = expmod a ( b `div ` 2) c
En la compu... Ahora estamos listos para ver la implementación final del test. Primero, su semántica: Semántica fermat p as == True exactamente cuando ningún a en as es un testigo de Fermat para p. Test de Primalidad de Fermat fermat :: Integer - > [ Integer ] - > Bool fermat p [] = True fermat p ( a: as) = expmod a ( p -1) p == 1 && fermat p as
Ejercicios 1. Verificar con el algoritmo que vimos, que 29341 es un pseudoprimo de Fermat en las bases 2, 3, 5, 7, y 11, pero no en base 13. 2. Hacer una función que, dado un número natural compuesto n, n 2, devuelva los testigos de Fermat de n. 3. Hacer una función que, dado un número natural compuesto n, n 2, cuente cuantos testigos de Fermat de n existen. 4. Los números de Carmichael son números naturales n, tal que n es un pseudoprimo de Fermat en base a, para todo a Z, 0 < a < n, coprimo con n. Por ejemplo, 561 es un número de Carmichael. Hacer una función que, dado un número natural n, n 2, devuelva True si n es un número de Carmichael, y False de lo contrario. 5. Dados a, c, x 0 N, 0 < a, c, x 0 < p, la sucesión x n+1 = a x n + c (mod p) produce números pseudo-aleatorios 1. Hacer una función que, dado un p N, n 2 y un k N, elija unos a, c, x 0 que ustedes quieran, y devuelva la lista [x 0, x 1,..., x k 1 ]. 6. Usando la función de ejercicio anterior (llamémosla testigos), hacer una función que dado un número n N, n 2, y un k N, corra el test de primalidad de Fermat sobre n, usando a testigos n k como posibles testigos de Fermat para n. 1 Dependiendo de la elección de a, c, y x 0 se parecerán más o menos a números uniformes en [0... p 1]