9f42b3cdaf68f2f13517bd744bd01de547ecedd9
[ghc-hetmet.git] / ghc / tests / programs / jl_defaults / jl_defaults.stdin
1 module Main
2 where
3
4 import Rsa
5
6 main = interact (decrypt 2036450659413645137870851576872812267542175329986469156678671505255564383842535488743101632280716717779536712424613501441720195827856504007305662157107
7                          5282760067491066073559694937813662322539426172665930660813609694132726350877)
8 module Main
9 where
10
11 import Rsa
12
13 main = interact (prompt . keys . lines)
14
15 keys (x:y:xs) = makeKeys (read x) (read y)
16 prompt ks = "\nEnter two random numbers on separate lines:\n" ++
17             case ks of
18               (n,e,d) -> "The numbers n, e, and d are:\n" ++
19                          unlines (map show [n,e,d]) ++ "\n"
20
21
22
23  
24 module Main
25 where
26
27 import Rsa
28
29 main = interact (encrypt 2036450659413645137870851576872812267542175329986469156678671505255564383842535488743101632280716717779536712424613501441720195827856504007305662157107
30
31                          387784473137902876992546516170169092918207676456888779623592396031349415024943784869634893342729620092877891356118467738167515879252473323905128540213) 
32 module Rsa (encrypt, decrypt, makeKeys)
33 where
34
35
36 encrypt, decrypt :: Integer -> Integer -> String -> String
37 encrypt n e = unlines . map (show . power e n . code) . collect (size n)
38 decrypt n d = concat . map (decode . power d n . read) . lines
39
40
41 -------- Converting between Strings and Integers -----------
42
43 code :: String -> Integer
44 code = foldl accum 0
45   where accum x y = (128 * x) + fromIntegral (ord y)
46
47 decode :: Integer -> String
48 decode n = reverse (expand n)
49    where expand 0 = []
50          expand x = chr (fromIntegral (x `mod` 128)) : expand (x `div` 128)
51
52 collect :: Int -> [a] -> [[a]]
53 collect 0 xs = []
54 collect n [] = []
55 collect n xs = take n xs : collect n (drop n xs)
56
57 size :: Integer -> Int
58 size n = (length (show n) * 47) `div` 100       -- log_128 10 = 0.4745
59
60
61 ------- Constructing keys -------------------------
62
63 makeKeys :: Integer -> Integer -> (Integer, Integer, Integer)
64 makeKeys p' q' = (n, invert phi d, d)
65    where   p = nextPrime p'
66            q = nextPrime q'
67            n = p*q              
68            phi = (p-1)*(q-1)
69            d = nextPrime (p+q+1)
70
71 nextPrime :: Integer -> Integer
72 nextPrime a = head (filter prime [odd,odd+2..])
73   where  odd | even a = a+1
74              | True   = a
75          prime p = and [power (p-1) p x == 1 | x <- [3,5,7]]
76
77 invert :: Integer -> Integer -> Integer
78 invert n a = if e<0 then e+n else e
79   where  e=iter n 0 a 1
80
81 iter :: Integer -> Integer -> Integer -> Integer -> Integer
82 iter g v 0  w = v
83 iter g v h w = iter h w (g - fact * h) (v - fact * w)
84     where  fact = g `div` h 
85
86
87 ------- Fast exponentiation, mod m -----------------
88
89 power :: Integer -> Integer -> Integer -> Integer
90 power 0 m x          = 1
91 power n m x | even n = sqr (power (n `div` 2) m x) `mod` m
92             | True   = (x * power (n-1) m x) `mod` m
93
94 sqr :: Integer -> Integer
95 sqr x = x * x
96
97