El reto consiste en implementar el cifrado RSA con el lenguaje que más gustéis.
Como ya sabréis RSA es un cifrado basado en asimetrías de problemas surgidos en la aritmética modular de números primos, el proceso para cifrado/descifrado es el siguiente:
General:
· Buscamos 2 nº primos medianamente grandes p y q (ponedle un rango entre 1,1000 y será suficiente, no para la práctica ya que la factorización de n, que veremos ahora, será mucho más simple y se podrán encontrar p y q fácilmente.
· Generar n:n=p*q y z:z=(p-1)*(q-1)
Cifrar:
· Generar un e:divisores(e) ∩ divisores(z) = {1}, para los no formales, buscar un e que no tenga ningún divisor en común con z (excepto el 1).
· Ej: Si z=8, coger e = 5. Un truco para esto es coger el inmediatamente inferior a z (o superior), en este caso e = 7 o e = 9
· Ciframos el mensaje: c = (m^e) % n
{c = cifrado,m = mensaje}
Descifrar:
· Buscamos d: e*d % z = 1
· c: c=(c^d) % n
{c = descifrado}
Ejemplo: (hacedlo en decimal, luego si queréis lo usáis para strings y esas cosas que quedan tan bien, además facilitaremos el reto

)
{p->3,q->7,n->21,z->12,m->14}
Divisores z = {1,2,3,4,6,12}
Buscamos e : divisores(e) ∩ divisores(z) = {1}, e.g e=5 -> {1,5} ∩ {1,2,3,4,6,12} = {1}, se cumple.
Generar d: 5*d % 12 = 1, sacamos d = 17
Cifrar: c: c=(14^5) % 21 = 14 -- Casualidad que sale el mismo xD
Descifrar c: c=(14^17)%21 = 14 -- Este es el texto inicial.
Os adjunto una posible solución en haskell:
retN
:: Prime
-> Prime
-> Int retN p q = p * q
retZ
:: Prime
-> Prime
-> Int retZ p q = (p-1)*(q-1)
retE z = (z-1)
retD d e z
cipherCharRsa :: PlainText -> Prime -> Prime -> Cipher
cipherCharRsa c p q
= ((ord c
)^(retE
(retZ p q
))) `
mod`
(retN p q
)
uncipherCharRsa :: Cipher -> Prime -> Prime -> PlainText
uncipherCharRsa c p q
= chr
((c
^(retD
0 (retE
(retZ p q
)) (retZ p q
))) `
mod`
(retN p q
) + 97)
main [] p q = ""
main
(x:xs
) p q
= " " ++ (show (cipherCharRsa x p q
))++(main xs p q
)