My RSA algorithm works fine for three letter words, such as "cat", but as soon as the word gets longer, I get an error message: Exception: decipher2.hs: (37,1) - (62,19): Non- exhaustive templates in the numToLet function
My programs work according to the following steps
For encryption
- Converting a string of letters to a string of numbers, where each letter is assigned to a specific number.
- Combine a string of numbers to form one larger number.
- Using the corresponding values of p and q, we calculate n, and also choose the appropriate number e, which is joint with n (since this is an internal process, keeping the secrecy of p and q unimportant, but can be done)
- Run the RSA algorithm to create an "encryption number"
For decryption
- Calculate the collection of φ (n) using p and q (where φ (n) = (p-1) * (q-1))
- Write the Euclidean algorithm in the code to find the greatest common divisor of two numbers.
- Write the backward substitution part in the code so that it commutatively forms the extended Euclidean algorithm.
- calculate the private key.
- Turn on the option of storing the secret key so that this function is not performed every time (to increase the speed).
- The RSA encryption algorithm must be implemented.
- The result should be divided into a string of numbers (in the opposite process, as it was combined in step 2 of the encryption process).
- A string of numbers must be converted to a string of letters (using the same values that were used in the encryption process).
, ( ). p q, , , ( ) / ?
:
import Data.List
letToNum c'' = (let (Just n) = elemIndex c'' ['a'..'z'] in n) + 10
combine = foldl addDigit 0
where addDigit num i' = (10 ^ (floor $ log (fromIntegral i') / log 10 + 1))*num + i'
firstTwo xs = toInteger (combine (map letToNum xs))
p' = 2^2048 - 1942289
q' = 2^2048 - 2^1056 + 2^736 - 2^320 + 2^128 + 1
n' = p' * q'
e' = 7
newtype ModN = ModN (Integer, Integer) deriving (Eq, Show)
instance Num ModN where
ModN (x, m) + ModN (y, m') | m == m' = ModN ((x + y) `mod` m, m)
| otherwise = undefined
ModN (x, m) * ModN (y, m') | m == m' = ModN ((x * y) `mod` m, m)
| otherwise = undefined
negate (ModN (x, m)) = ModN ((- x) `mod` m, m)
abs _ = undefined
signum _ = undefined
fromInteger _ = undefined
modPow :: Integer -> Integer -> Integer -> Integer
modPow _ 0 m = 1 `mod` m
modPow a b m = c
where a' = ModN (a, m)
ModN (c, _) = a' ^ b
encipherA z' = modPow z' e' n'
encipher xs = encipherA (firstTwo xs)
:
p' = 2^2048 - 1942289
q' = 2^2048 - 2^1056 + 2^736 - 2^320 + 2^128 + 1
n' = p' * q'
d'=149198411630450358098821815816660626082852035578197682912033354754850558281651065264118115990713936905841443816348466119712510491169399086751890869693052182563708139506244285477194512876340531187775438573122278032339474119913958963667476383477798088213829701243686243438754864105731229873495425397653296705562025639940130672903361904637280085880562426594784029436599468688448179303703337724326069153629191476697420768451884440453280134491448395404958914592441919126201747433884753502442027069825305163272842897505994155682996130741544296475635538035696205346055652365820232813677363525296188331517668300986037331017823989462119054758685224752255850280255541024098528388784743634162996954090230161430468033874779937253936100340449079832503240200984659315256173082971785802328581652375418902448324739292188909509903808503871246982928186837296358844444348158079557757543904495890483033995844854839625810784987612815774450940850973031117459144355531047129541648317845165848539683500066541165782574432790936862217277817101197569391139502130923768985262346549685855947859864917650782062626099395684514986479824104485607000960030713840667632064934158997031779846656288570984548383771118345091911988849410656041321592285731293207858515766711
newtype ModN = ModN (Integer, Integer) deriving (Eq, Show)
instance Num ModN where
ModN (x, m) + ModN (y, m') | m == m' = ModN ((x + y) `mod` m, m)
| otherwise = undefined
ModN (x, m) * ModN (y, m') | m == m' = ModN ((x * y) `mod` m, m)
| otherwise = undefined
negate (ModN (x, m)) = ModN ((- x) `mod` m, m)
abs _ = undefined
signum _ = undefined
fromInteger _ = undefined
modPow :: Integer -> Integer -> Integer -> Integer
modPow _ 0 m = 1 `mod` m
modPow a b m = c
where a' = ModN (a, m)
ModN (c, _) = a' ^ b
decipherA c' = modPow c' d' n'
numToLet "10" = "a"
numToLet "11" = "b"
numToLet "12" = "c"
numToLet "13" = "d"
numToLet "14" = "e"
numToLet "15" = "f"
numToLet "16" = "g"
numToLet "17" = "h"
numToLet "18" = "i"
numToLet "19" = "j"
numToLet "20" = "k"
numToLet "21" = "l"
numToLet "22" = "m"
numToLet "23" = "n"
numToLet "24" = "o"
numToLet "25" = "p"
numToLet "26" = "q"
numToLet "27" = "r"
numToLet "28" = "s"
numToLet "29" = "t"
numToLet "30" = "u"
numToLet "31" = "v"
numToLet "32" = "w"
numToLet "33" = "x"
numToLet "34" = "y"
numToLet "35" = "z"
output xs = putStrLn $ concat (map numToLet xs)
partition :: Int -> [a] -> [[a]]
partition _ [] = []
partition n xs = (take n xs) : (partition n (drop n xs))
decipher j' = map numToLet (partition 2 (show (decipherA j')))
, .