74 lines
2.1 KiB
Haskell
74 lines
2.1 KiB
Haskell
import Codec.Crypto.RSA.Pure
|
|
import Control.Monad(forM_)
|
|
import Data.ByteString.Lazy(ByteString)
|
|
import qualified Data.ByteString.Lazy as BS
|
|
import Data.Map.Strict(Map)
|
|
import qualified Data.Map.Strict as Map
|
|
import Numeric
|
|
|
|
groupBy :: Int -> [a] -> [[a]]
|
|
groupBy _ [] = []
|
|
groupBy x xs =
|
|
let (first, rest) = splitAt x xs
|
|
in first : groupBy x rest
|
|
|
|
dictionary :: [String] -> Map String String
|
|
dictionary [] = Map.empty
|
|
dictionary (x:xs) =
|
|
let rest = dictionary xs
|
|
key = take 1 x
|
|
val = drop 3 x
|
|
in Map.insert key val rest
|
|
|
|
number :: String -> Integer
|
|
number x =
|
|
case readHex x of
|
|
[(v, _)] -> v
|
|
_ -> error "number"
|
|
|
|
hash :: String -> (ByteString -> ByteString)
|
|
hash x =
|
|
case x of
|
|
"160" -> hashFunction hashSHA1
|
|
"224" -> hashFunction hashSHA224
|
|
"256" -> hashFunction hashSHA256
|
|
"384" -> hashFunction hashSHA384
|
|
"512" -> hashFunction hashSHA512
|
|
|
|
decrypter :: String ->
|
|
(ByteString -> PrivateKey -> ByteString -> Either RSAError ByteString)
|
|
decrypter x = decryptOAEP hashfun (generateMGF1 hashfun)
|
|
where hashfun = hash x
|
|
|
|
bytestring :: String -> ByteString
|
|
bytestring "" = BS.empty
|
|
bytestring xs =
|
|
let (byte1, rest) = splitAt 2 xs
|
|
in BS.cons (fromIntegral (number byte1)) (bytestring rest)
|
|
|
|
forceLookup :: String -> Map String String -> String
|
|
forceLookup x m =
|
|
case Map.lookup x m of
|
|
Just v -> v
|
|
Nothing -> error ("forceLookup: " ++ x)
|
|
|
|
runCase :: Map String String -> IO ()
|
|
runCase dict =
|
|
do let d = number (forceLookup "d" dict)
|
|
n = number (forceLookup "n" dict)
|
|
m = bytestring (forceLookup "m" dict)
|
|
s = bytestring (forceLookup "s" dict)
|
|
c = bytestring (forceLookup "c" dict)
|
|
public = PublicKey (512 `div` 8) n 65537
|
|
private = PrivateKey public d 0 0 0 0 0
|
|
decrypt = decrypter (forceLookup "h" dict)
|
|
case decrypt BS.empty private m of
|
|
Left err -> fail ("Error: " ++ show err)
|
|
Right _ -> putStrLn "OK"
|
|
|
|
main :: IO ()
|
|
main =
|
|
do strs <- lines `fmap` readFile "rsa512.test"
|
|
let groups = groupBy 7 strs
|
|
forM_ groups (runCase . dictionary)
|