Download IMD-IS 2011–2012. Sesión de laboratorio 5. Números primos

Document related concepts

Pequeño teorema de Fermat wikipedia , lookup

Test de primalidad wikipedia , lookup

Test de primalidad de Fermat wikipedia , lookup

Test de primalidad AKS wikipedia , lookup

Test de Pocklington wikipedia , lookup

Transcript
IMD-IS 2011–2012. Sesión de laboratorio 5.
Números primos
La hoja de SAGE que corresponde a la práctica puede obtenerse de:
http: // personal. us. es/ ebriand/ practica5. sws
En esta práctica, se propone un reto: hallar al mayor número
primo posible, por varios métodos.
¿ Cómo se hace, en práctica, para crear un gran número primo ? Por ejemplo, en el sistema RSA, se necesita producir números
primos de longitud 1024 bits (son números con más de 300 cifras
decimales). Pues, se producen números de este tamaño aleatoriamente, hasta obtener uno que sea primo. Para esto, es necesario
poder determinar si un número es primo o no. Hay varios “tests de
primalidad”, más o menos eficientes, que realizan este trabajo.
El test ingenuo
El test ingenuo consiste en comprobar que ningún entero entre
2 y p − 1 divide p. Admite una ligera mejora: basta comprobar que
√
ningún entero entre 2 y p divide p. En efecto tenemos el resultado
elemental siguiente:
√
Teorema 1. Si p no es primo, entonces admite un divisor entre 2 y p.
def testingenuo(p):
i=2
while i^2 <= p:
if p%i == 0:
return False
i=i+1
return True
Ejercicio 1. Obtener un número primo tan grande como posible
con el test ingenuo. ¿ Parece realista obtener de esta manera números primos de 1024 bits ?
El test de Fermat.
El test de Fermat se basa, por una parte, en el teorema siguiente:
Teorema 2 (Pequeño teorema de Fermat). Sean a y p dos enteros
positivos, con 1 ≤ a ≤ p − 1. Si a p−1 6≡ 1 mod p, entonces p no es
primo.
Se basa también en el resultado complementario siguiente (no es
un teorema, porque su contenido es algo impreciso):
Si a > 1 y a p−1 ≡ 1 mod p, entonces muy probablemente p es
primo.
2
Sea a > 1. El test de Fermat en base a para un entero p > a
consiste en calcular a p−1 modulo p.
Si a p−1 6≡ 1 mod p, entonces p no es primo, por el pequeño
teorema de Fermat. Decimos que p no pasa el test de Fermat en base
a. Decimos también que a es un testigo de que p no es primo.
Sino, decimos que p pasa el test de Fermat en base a. Hay dos posibilidades:
• La más probable: p es primo.
• La menos probable: p no es primo, a pesar de pasar el test de
Fermat en base a. En este caso decimos que p es una pseudoprimo en base a. Decimos también que a es un falso testigo de
primalidad de p.
Es lo que se llama en estadística un
“falso positivo”.
Si un número p pasa el test de Fermat en base a, probablemente
es primo. Como es solamente “probablemente primo”, este test no
basta para demostrar que un número es primo. Sin embargo, es de
interés para las aplicaciones (por ejemplo, en criptografía) donde una
pequeña incerteza puede ser tolerada.
Si un número p pasa el test de Fermat en base a, podemos hacerle pasar el test de Fermat en otras bases, para tener una probabilidad aún más fuerte que sea primo.
Ejemplo 1. Consideramos p = 341. Pasa el test de Fermat en base 2
(2340 ≡ 1 mod 341). Sin embargo, no pasa el test de Fermat en base
3: 3340 ≡ 56 6≡ 1 mod 341.
♦
Desgraciadamente hay números p (una infinidad) que no son
primos y que pasan el test de Fermat en todas las bases a primas
con p. Estos números se llaman números de Carmichael. Afortunadamente, la proporción de números de Carmichael es bastante
pequeña.
Ejercicio 2.
Escribir una función Fermat1 que toma como argumentos los
enteros a y p y determina si p pasa el test de Fermat en base a.
Comprobar que funciona, sobre pequeños ejemplos (p con poco
más de 10 cifras). La función tienen que calcular a p−1 mod p ¿
Es necesario, para esto, calcular a p−1 (un entero muy largo) ?
Hallar un número no primo (otro que 341) que pasa el test de
Fermat en base 2, pero no lo pasa en base 3.
¿ Se nota alguna mejora significativa con respecto al test ingenuo ? (A continuación mejoraremos el test de Fermat).
¿ Parece realista obtener de esta manera números primos de 1024
bits ?
Utilizando Fermat1, hallar números “probablemente primos” tan
grande como posibles (la elección más simple de a es a = 2).
Cálculos con grandes enteros pueden
bloquear la máquina. Pinchar entonces,
si se puede, en “interrupt”, o “restart”
en el menu “Action” (segundo menu
arriba a la derecha en la hoja de
SAGE).
3
El test de Fermat con exponenciación rápida
En la función Fermat1 se calcula a p−1 con p − 2 multiplicaciones.
Es posible de hacer el mismo cálculo con mucho menos multiplicaciones. Por ejemplo, para calcular a168 no son necesarias 167
multiplicaciones: bastan 9.
Para esto, organizamos los cálculos de la manera siguiente:
Calculamos a2 con una sola multiplicación, como a × a.
Calculamos a4 con una sola multiplicación, como a2 × a2 .
Calculamos a8 con una sola multiplicación, como a4 × a4 .
Calculamos a16 (una multiplicación).
Calculamos a32 (una multiplicación).
Calculamos a64 (una multiplicación).
Calculamos a128 (una multiplicación).
No calculamos a256 , no sirve, es demasiado grande, es mayor
que a168 .
Observamos que a168 = a128 × a32 × a8 , ya que 168 =
128 + 32 + 8 (corresponde al hecho que la escritura binaria de 168 es 10101000). Por lo tanto calculamos a168 con
solamente dos multiplicaciones más.
Esta manera eficiente de calcular una potencia repitiendo elevaciones al cuadrado se llama exponenciación rápida. Hace que el test
de Fermat sea muy eficiente.
Ejercicio 3.
Comprobar (con algunos ejemplos) que la función bits de SAGE
proporciona la escritura binaria de un entero. ¿ Dónde está el bit
menos significativo ?
Escribir una función Fermat2 que realiza el test de Fermat, utilizando la exponenciación rápida.
Utilizar Fermat2 para obtener nuevos records de grandes números primos ¿ Se observa alguna mejora significativa con respeto a
los tests anteriores ?
Ejercicio adicional
Ejercicio 4. Facultativo; para los que acabaron todos los ejercicios
anteriores
Encontrar todos los primeros números pseudoprimos en base 2 (por
ejemplo hasta 2000).
Encontrar todos los primeros números de Carmichael (por ejemplo
hasta 2000).
Se utiliza así: 167.bits() para obtener
los bits de 167.
4
Observaciones adicionales
Existen tests de primalidad más sofisticados que el test de Fermat (como por ejemplo el test de Miller–Rabin) que garantizan que
un número es primo con una probabilidad arbitraria. Por ejemplo,
se puede garantizar que un número p es primo con un probabilidad
99, 99999999999999999 % (o cualquiera probabilidad estrictamente
inferior a 1) a condición de hacer funcionar el test el tiempo necesario. Son estos tests que se utilizan en las aplicaciones industriales
(criptografía).