packages feed

keccak-0.1.2: test/Test/Parse/KAT.hs

{-# LANGUAGE OverloadedStrings #-}

module Test.Parse.KAT where

import           Control.Monad          (void)
import qualified Data.ByteString        as BS
import qualified Data.ByteString.Base16 as BS16
import qualified Data.Text              as T
import qualified Data.Text.Encoding     as T
import           Data.Text.IO           as T
import           Text.Parsec
import           Text.Parsec.Text
import           Text.Parsec.Expr

type TestFile = [KAT]

data KAT = KAT { byteLength :: Int
               , message    :: BS.ByteString
               , digest     :: BS.ByteString
               } deriving Show

parseTestFile :: Parser TestFile
parseTestFile = skipMany (commentLine <|> dataLine <|> blankLine) *> many1 parseKat


commentLine :: Parser ()
commentLine = void $ char '#' *> manyTill anyChar endOfLine


dataLine :: Parser ()
dataLine = void $ char '[' *> manyTill anyChar endOfLine


blankLine :: Parser ()
blankLine = void endOfLine


parseKat :: Parser KAT
parseKat = do len <- string "Len = " *> many1 digit <* endOfLine
              msg <- string "Msg = " *> many1 hexDigit <* endOfLine
              digest <- string "MD = " *> many1 hexDigit <* endOfLine
              skipMany (commentLine <|> blankLine)
              let parsedLen = read len
              pure $ KAT parsedLen (BS.take parsedLen $ bytesDecode msg)
                                   (bytesDecode digest)


bytesDecode :: String -> BS.ByteString
bytesDecode = fst . BS16.decode . T.encodeUtf8 . T.pack


parseFromFile :: Parsec T.Text () a -> FilePath -> IO (Either ParseError a)
parseFromFile p fname = do
    input <- T.readFile fname
    return (runParser p () fname input)