{-# LANGUAGE ScopedTypeVariables #-} import System.Random (randomRIO) import Data.Bits (shiftR, (.&.), testBit) import Control.Monad (replicateM) -- Function to generate a random large prime number generatePrime :: Integer -> IO Integer generatePrime bitLength = do let min = 2^(bitLength - 1) let max = 2^bitLength - 1 candidate <- randomRIO (min, max) putStrLn $ "Trying candidate: " ++ show candidate isPrimeCandidate <- isProbablyPrime candidate 5 if isPrimeCandidate then do putStrLn $ "Found prime: " ++ show candidate return candidate else generatePrime bitLength -- Miller-Rabin primality test isProbablyPrime :: Integer -> Int -> IO Bool isProbablyPrime n k | n < 2 = return False | n == 2 || n == 3 = return True | even n = return False | otherwise = do let (r, d) = decompose (n - 1) witnesses <- replicateM k (randomRIO (2, n - 2)) return $ all (millerRabinTest n r d) witnesses -- Decompose (n-1) to find r and d such that (n-1) = 2^r * d decompose :: Integer -> (Integer, Integer) decompose n = go n 0 where go m r | m `mod` 2 == 0 = go (m `div` 2) (r + 1) | otherwise = (r, m) -- Perform the Miller-Rabin test with one witness millerRabinTest :: Integer -> Integer -> Integer -> Integer -> Bool millerRabinTest n r d a = powMod a d n == 1 || any (\i -> powMod a (d * 2^i) n == n - 1) [0..(r - 1)] -- Fast modular exponentiation powMod :: Integer -> Integer -> Integer -> Integer powMod base exp modulus = powMod' base exp modulus 1 where powMod' _ 0 _ result = result powMod' b e m result | e .&. 1 == 1 = powMod' (b * b `mod` m) (shiftR e 1) m (result * b `mod` m) | otherwise = powMod' (b * b `mod` m) (shiftR e 1) m result -- Extended Euclidean Algorithm to find GCD and Bézout coefficients extendedGCD :: Integer -> Integer -> (Integer, Integer, Integer) extendedGCD a 0 = (a, 1, 0) extendedGCD a b = let (g, s, t) = extendedGCD b (a `mod` b) in (g, t, s - (a `div` b) * t) -- Compute the modular multiplicative inverse modInverse :: Integer -> Integer -> Integer modInverse e phi = let (_, inv, _) = extendedGCD e phi in inv `mod` phi -- Encrypt: C = M^e mod n encrypt :: Integer -> Integer -> Integer -> Integer encrypt m e n = powMod m e n -- Decrypt: M = C^d mod n decrypt :: Integer -> Integer -> Integer -> Integer decrypt c d n = powMod c d n main :: IO () main = do -- Generate large primes p and q putStrLn "Generating prime p (1024 bits)..." p <- generatePrime 1024 putStrLn "Generating prime q (1024 bits)..." q <- generatePrime 1024 let n = p * q let phi = (p - 1) * (q - 1) let e = 65537 -- Commonly used public exponent -- Ensure e is coprime with phi putStrLn "Computing modular inverse d..." let d = modInverse e phi putStrLn $ "Prime p: " ++ show p putStrLn $ "Prime q: " ++ show q putStrLn $ "Modulus n: " ++ show n putStrLn $ "Euler's totient phi(n): " ++ show phi putStrLn $ "Public exponent e: " ++ show e putStrLn $ "Private exponent d: " ++ show d -- Encrypt and decrypt a message let message = 1234567890 -- Example message putStrLn $ "Encrypting message: " ++ show message let ciphertext = encrypt message e n putStrLn $ "Encrypted message: " ++ show ciphertext let decryptedMessage = decrypt ciphertext d n putStrLn $ "Decrypted message: " ++ show decryptedMessage putStrLn $ "Original Message: " ++ show message putStrLn $ "Encrypted Message: " ++ show ciphertext putStrLn $ "Decrypted Message: " ++ show decryptedMessage
Write, Run & Share Haskell code online using OneCompiler's Haskell online compiler for free. It's one of the robust, feature-rich online compilers for Haskell language, running the latest Haskell version 8.6. Getting started with the OneCompiler's Haskell editor is easy and fast. The editor shows sample boilerplate code when you choose language as Haskell and start coding.
OneCompiler's Haskell online editor supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample Haskell program which takes name as input and prints hello message with your name.
main = do
name <- getLine
putStrLn ("Hello " ++ name ++ ", Happy learning!")
Haskell is purely a functional programming language which was introduced in 1990's.
Data-type | Description |
---|---|
Numbers | Haskell is intelligent to identify numbers without specifying data type |
Characters | Haskell is intelligent to identify characters and strings without specifying data type |
Tuple | To declare multiple values in a single data type. Tuples are represented in single paranthesis. For example (10, 20, 'apple') |
Boolean | To represent boolean values, true or false |
List | To declare same type of values in a single data type. Lists are represented in square braces.For example [1, 2, 3] or `['a','b','c','d'] |
When ever you want to perform a set of operations based on a condition or set of conditions, then If-Else/ Nested-If-Else are used.
main = do
let age = 21
if age > 18
then putStrLn "Adult"
else putStrLn "child"
Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increases re-usuability and modularity. Functions play an important role in Haskell, since it is a purely functional language.
multiply :: Integer -> Integer -> Integer --declaration of a function
multiply x1 x2 = x1 * x2 --definition of a function
main = do
putStrLn "Multiplication value is:"
print(multiply 10 5) --calling a function