packages feed

skein 0.1.0.2 → 0.1.0.3

raw patch · 2 files changed

+177/−2 lines, 2 filesdep ~hspecPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: hspec

API changes (from Hackage documentation)

Files

skein.cabal view
@@ -1,6 +1,6 @@ Cabal-version:       >= 1.8 Name:                skein-Version:             0.1.0.2+Version:             0.1.0.3 Synopsis:            Skein, a family of cryptographic hash functions.  Includes Skein-MAC as well. License:             BSD3 License-file:        LICENSE@@ -41,6 +41,7 @@     c_impl/reference/skein_debug.c     c_impl/reference/skein_debug.h     c_impl/reference/skein_port.h+    tests/runtests.hs  Data-files:     tests/skein_golden_kat.txt@@ -112,7 +113,7 @@          filepath     == 1.*,         transformers,-        hspec        == 0.6.*,+        hspec        == 0.9.*,          -- finally, our own package         skein
+ tests/runtests.hs view
@@ -0,0 +1,174 @@+-- from base+import Control.Applicative ((<$>))+import Control.Monad (forM_, unless)+import Data.Char (isNumber)+import Data.Maybe (catMaybes)+import Text.Printf++-- from bytestring+import qualified Data.ByteString as B+--import qualified Data.ByteString.Lazy as L++-- from cereal+import Data.Serialize (encode)++-- from tagged+import Data.Tagged (Tagged(..))++-- from crypto-api+import Crypto.Classes+++-- from filepath+import System.FilePath ((</>))++-- from transformers+import Control.Monad.Trans.Writer.Lazy (Writer)++-- from hspec+import Test.Hspec.Monadic+--import Test.Hspec.QuickCheck+import Test.Hspec.HUnit ()+++-- from this package+import Paths_skein (getDataFileName)+import Crypto.Skein+++++main :: IO ()+main = do+  skein_golden_kat_txt <- getDataFileName ("tests" </> "skein_golden_kat.txt")+  kats <- parseKats <$> readFile skein_golden_kat_txt+  putStrLn $ "Parsed " ++ show (length kats) ++ " known answer tests"+  hspecX $ do+         describe "Skein golden known answer tests" $ do+           skeinKats kats (undefined :: Skein_512_512)+           skeinKats kats (undefined :: Skein_1024_1024)+           skeinKats kats (undefined :: Skein_256_256)+           skeinKats kats (undefined :: Skein_256_128)+           skeinKats kats (undefined :: Skein_256_160)+           skeinKats kats (undefined :: Skein_256_224)+           skeinKats kats (undefined :: Skein_512_128)+           skeinKats kats (undefined :: Skein_512_160)+           skeinKats kats (undefined :: Skein_512_224)+           skeinKats kats (undefined :: Skein_512_256)+           skeinKats kats (undefined :: Skein_512_384)+           skeinKats kats (undefined :: Skein_1024_384)+           skeinKats kats (undefined :: Skein_1024_512)++readMsg :: Read a => String -> String -> a+readMsg msg str = case readsPrec 0 str of+                    [(r, "")] -> r+                    _ -> error msg++----------------------------------------------------------------------++data Kat = Kat { skeinType :: SkeinType+               , message   :: B.ByteString+               , macKey    :: Maybe B.ByteString+               , result    :: B.ByteString+               }++data SkeinType = Skein !Int !Int deriving (Eq)++instance Show SkeinType where+    show (Skein s o) = printf "Skein-%d-%d" s o++parseKats :: String -> [Kat]+parseKats = catMaybes . map parseKat . groupKats . lines . filter (/= '\r')++groupKats :: [String] -> [[String]]+groupKats = go []+    where+      sep = "--------------------------------"+      go acc (x:xs) | x == sep  = reverse acc : go [] xs+                    | otherwise = go (x:acc) xs+      go []    []               = []+      go (_:_) []               = error "groupKats: didn't find last separator"++parseKat :: [String] -> Maybe Kat+parseKat ("":xs) = parseKat xs+parseKat (header:"":rest) =+    case (isTree header, parseMsgLen header, parseBlocks rest) of+      (_, msgLen, _) | msgLen `mod` 8 /= 0 -> Nothing+      (False, _, [Message msg,             Result ret]) -> kat msg Nothing    ret+      (False, _, [Message msg, MACKey mac, Result ret]) -> kat msg (Just mac) ret+      _ -> Nothing+    where kat msg mac ret = Just $ Kat (parseSkeinType header) msg mac ret+parseKat _ = Nothing++isTree :: String -> Bool+isTree ('T':'r':'e':'e':':':_) = True+isTree (_:xs) = isTree xs+isTree []     = False++parseMsgLen :: String -> Int+parseMsgLen ('m':'s':'g':'L':'e':'n':' ':'=':xs) = readMsg "parseMsgLen" $ take 6 xs+parseMsgLen (_:xs) = parseMsgLen xs+parseMsgLen []     = error "parseMsgLen: didn't find msgLen"++parseSkeinType :: String -> SkeinType+parseSkeinType xs0 =+    let (":Skein", '-':xs1) = break (== '-') xs0+        (stateS,   xs2)     = span isNumber xs1+        (':':_,    xs3)     = break isNumber xs2+        (outputS,  _)       = span isNumber xs3+    in Skein (readMsg "stateS" stateS) (readMsg "outputS" outputS)++data Block = Message B.ByteString | MACKey B.ByteString | Result B.ByteString++block :: String -> B.ByteString -> Block+block "Message data:" = Message+block "Result:"       = Result+block ('M':'A':'C':_) = MACKey+block x               = error $ "block: unknown block type " ++ x++parseBlocks :: [String] -> [Block]+parseBlocks [] = []+parseBlocks (header:rest)+    | last header /= ':' = error "parseBlocks: something went wrong"+    | otherwise          = let (data_, rest') = span ((== ' ') . head) rest+                           in block header (parseData data_) : parseBlocks rest'++parseData :: [String] -> B.ByteString+parseData [' ':' ':' ':' ':'(':'n':'o':'n':'e':')':_] = B.empty+parseData xs = B.pack $ map (readMsg "parseData" . ("0x"++)) $ concatMap words xs++----------------------------------------------------------------------++skeinKats :: (SkeinMAC skeinCtx, Hash skeinCtx digest) =>+             [Kat] -> digest -> Writer [Spec] ()+skeinKats kats digest =+  let get t@(Tagged x) = x+          where+            f :: Tagged d a -> d+            f = undefined++            p = f t `asTypeOf` digest+      skeinType = Skein (get blockLength) (get outputLength)+      myHashKats  = [(msg,         ret) | Kat t msg Nothing       ret <- kats, t == skeinType]+      myMacKats   = [(msg, macKey, ret) | Kat t msg (Just macKey) ret <- kats, t == skeinType]+      lenHashKats = length myHashKats+      lenMacKats  = length myMacKats+      testName =+          if lenHashKats + lenMacKats == 0+          then printf "has no tests for %s =(" (show skeinType)+          else printf "works for %s (%d hash tests, %d MAC tests)"+                      (show skeinType) lenHashKats lenMacKats+  in it testName $ do+       putStrLn "Testing hashes..."+       forM_ myHashKats $ \(msg, ret) -> do+         let myHash = hash' msg `asTypeOf` digest+         unless (encode myHash == ret) $ fail $ concat ["Message: ", show msg,+                                                        "\nExpected: ", show ret,+                                                        "\nCalculated: ", show (encode myHash)]+       putStrLn "Testing MACs..."+       forM_ myMacKats $ \(msg, macKey, ret) -> do+         let myMAC = skeinMAC' macKey msg `asTypeOf` digest+         unless (encode myMAC == ret) $ fail $ concat ["Message: ", show msg,+                                                       "MAC Key: ", show macKey,+                                                       "\nExpected: ", show ret,+                                                       "\nCalculated: ", show (encode myMAC)]