Departamento de Matemática Aplicada http://www.dma.fi.upm.es/ Faculta de Informática – Universidad Politécnica de Madrid Aplicaciones de Aritmética Modular Laboratorio de Matemática Discreta Jesús Martínez Mateo [email protected] Algunas de las aplicaciones más interesantes de la aritmética modular son aquellas en las que se utilizan los conocimientos de esta disciplina para el cifrado y descifrado de mensajes. Es lo que conocemos como criptografía, y que comúnmente utilizamos para el intercambio de secretos entre dos interlocutores. Sesión 1. Cifrado de clave privada: Método de Julio César Antes de poder cifrar un mensaje, en primer lugar debemos codificar el mismo substituyendo cada letra del mensaje por un valor numérico. Por ejemplo, podemos utilizar como valor numérico la posición que ocupa cada letra en el alfabeto utilizado. Después de codificar, cifrar y descifrar el mensaje, podremos decodificar el mismo y recuperar el texto original. Esta codificación y decodificación la podemos implementar en Python utilizando las dos siguientes funciones, char2num(c) y num2char(n). Asumimos que ‘a’ será la primera letra del alfabeto y por lo tanto ocupará la posición cero, y ‘z’ –la última letra del alfabeto– corresponderá con la posición 25 (asumiendo que no incluimos la letra ‘ñ’ dentro de nuestro alfabeto). La función char2num(c) devuelve el número asociado a la letra proporcionada. En este ejemplo la función nos proporcionará el valor esperado siempre que proporcionemos una letra en minúsculas correspondiente del alfabeto utilizado. def char2num(c): n = ord(c) - ord('a') return n Por ejemplo: >>> char2num('d') 3 La función num2char(n) realiza el proceso inverso y devuelve la letra correspondiente a la posición proporcionada. Departamento de Matemática Aplicada http://www.dma.fi.upm.es/ Faculta de Informática – Universidad Politécnica de Madrid def num2char(n): c = chr(ord('a') + n) return c Por ejemplo: >>> num2char(13) 'n' Utilizando ambas funciones podemos codificar y decodificar un mensaje. Durante la codificación convertimos una cadena de caracteres (letras) en una lista de números. La codificación de una cadena de texto la podemos implementarla con la siguiente función: def text2list(T): L = [] for c in T: L.append(char2num(c)) return L Una cadena de texto en Python la proporcionamos entrecomillando el texto de la siguiente forma. Ejemplo: >>> text2list('hola') [7, 14, 11, 0] Decodificamos un mensaje mediante la función: def list2text(L): T = '' for n in L: T = T + num2char(n) return T Ejemplo >>> list2text([0, 3, 8, 14, 18]) 'adios' Asumiendo que queremos cifrar un mensaje utilizando una transformación afín de la forma x → a x + b (mod 26), con m.c.d.(a, 26) = 1 (donde 26 es el número de letras del alfabeto utilizado). La función que implementa este cifrado es la siguiente: Departamento de Matemática Aplicada http://www.dma.fi.upm.es/ Faculta de Informática – Universidad Politécnica de Madrid def cifra(M, a, b): L = text2list(M) U = [] n = char2num('z') + 1 for x in L: y = (a * x + b) % n U.append(y) return list2text(U) Ejercicio 1 a) Escribe la función descifra(M, a1, b) que implemente el procedimiento inverso, esto es, el procedimiento de descifrado. La función recibirá como parámetros: el mensaje cifrado (en texto), M, el inverso de a en aritmética Zn, a1, y b. Donde a y b son los mismos parámetros que se utilizaron para cifrar el mensaje. Recuerda que en las funciones proporcionadas n = 26. b) Prueba ambas funciones con el cifrado y descifrado del mensaje “aritmetica”, utilizando los valores a = 5, y b = 7. Calcula manualmente el inverso requerido para llamar a la función descifra(). c) [OPCIONAL] Implementa la función inverso(a, m) que calcule de forma genérica el inverso de a (mod n) e incluye esta función dentro de una función descifra(M, a, b) que reciba como parámetro a en vez de su inverso. Departamento de Matemática Aplicada http://www.dma.fi.upm.es/ Faculta de Informática – Universidad Politécnica de Madrid Sesión 2. Cifrado de clave pública: Método RSA Para realizar el cifrado de clave pública mediante el método RSA necesitamos convertir un texto en una secuencia de números. Cada uno de esos números se construirá a partir de un número determinado de letras. Teniendo en cuenta que nuestro alfabeto requiere al menos dos cifras decimales para identificar el mayor de los índices de una letra, utilizaremos una asignación fija de dos cifras por letra de la siguiente forma: 'a' = 00, 'b' = 01, 'c' = 02, …, 'z' = 25 (teniendo en cuenta una vez más que no incluimos la letra ñ en nuestro alfabeto, el espacio, así como ningún otro carácter especial). La siguiente función en Python convierte una cadena de texto en un número: def text2num(T): L = text2list(T) m = 0 i = (len(L) - 1) * 2 for n in L: m = m + (n + 1) * 10**i i = i - 2 return m Ejemplo 1 >>> text2num('hola') 8151201 La función inversa es la siguiente: def num2text(m): L = [] while m > 0: n = m % 100 m = m / 100 L.insert(0, n - 1) return list2text(L) Ejemplo 2 >>> num2text(8151201) 'hola' Departamento de Matemática Aplicada http://www.dma.fi.upm.es/ Faculta de Informática – Universidad Politécnica de Madrid Se escogen dos números primos p y q que se mantienen en secreto en todo momento. A partir de ambos números primos calculamos n = p * q, y escogemos otro número primo e que será nuestro exponente. Hacemos públicos los números n y e, que se utilizarán para cifrar y descifrar un mensaje de la siguiente forma. Asumiendo que el número correspondiente a nuestro mensaje es M. Calculamos el mensaje cifrado, C, como: C = Me (mod n) Para descifrar el mensaje original calculamos: M = Cd (mod n) donde d es el inverso de e (mod (p-1)(q-1)). Ejercicio 2 a) Implementa las funciones cifraRSA(M, n, e) y descifraRSA(M, n, d) que implementen los procedimientos de cifrado y descifrado de un mensaje descritos anteriormente. Utiliza los siguiente valores: p = 89, q = 97, e = 71, y d = 119. b) Prueba ambas funciones con el cifrado y descifrado de los textos “ca”, “qt”, y “zp”. c) [OPCIONAL] Implementa una función que permita el cifrado de un mensaje independientemente de su longitud (como punto de partida se puede asumir que el mensaje contiene un número para de letras). d) [OPCIONAL] ¿Podría mejorarse la codificación de los mensajes de texto? Implementa dicha mejora.
© Copyright 2024