cryptohash 0.5 → 0.5.1
raw patch · 18 files changed
+467/−145 lines, 18 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Data.CryptoHash.Skein256: Ctx :: !ByteString -> Ctx
+ Data.CryptoHash.Skein256: data Ctx
+ Data.CryptoHash.Skein256: finalize :: Ctx -> ByteString
+ Data.CryptoHash.Skein256: hash :: Int -> ByteString -> ByteString
+ Data.CryptoHash.Skein256: hashlazy :: Int -> ByteString -> ByteString
+ Data.CryptoHash.Skein256: init :: Int -> Ctx
+ Data.CryptoHash.Skein256: instance Storable Ctx
+ Data.CryptoHash.Skein256: update :: Ctx -> ByteString -> Ctx
- Data.CryptoHash.MD2: Ctx :: ByteString -> Ctx
+ Data.CryptoHash.MD2: Ctx :: !ByteString -> Ctx
- Data.CryptoHash.MD4: Ctx :: ByteString -> Ctx
+ Data.CryptoHash.MD4: Ctx :: !ByteString -> Ctx
- Data.CryptoHash.MD5: Ctx :: ByteString -> Ctx
+ Data.CryptoHash.MD5: Ctx :: !ByteString -> Ctx
- Data.CryptoHash.RIPEMD160: Ctx :: ByteString -> Ctx
+ Data.CryptoHash.RIPEMD160: Ctx :: !ByteString -> Ctx
- Data.CryptoHash.SHA1: Ctx :: ByteString -> Ctx
+ Data.CryptoHash.SHA1: Ctx :: !ByteString -> Ctx
- Data.CryptoHash.SHA224: Ctx :: ByteString -> Ctx
+ Data.CryptoHash.SHA224: Ctx :: !ByteString -> Ctx
- Data.CryptoHash.SHA256: Ctx :: ByteString -> Ctx
+ Data.CryptoHash.SHA256: Ctx :: !ByteString -> Ctx
- Data.CryptoHash.SHA384: Ctx :: ByteString -> Ctx
+ Data.CryptoHash.SHA384: Ctx :: !ByteString -> Ctx
- Data.CryptoHash.SHA512: Ctx :: ByteString -> Ctx
+ Data.CryptoHash.SHA512: Ctx :: !ByteString -> Ctx
- Data.CryptoHash.Tiger: Ctx :: ByteString -> Ctx
+ Data.CryptoHash.Tiger: Ctx :: !ByteString -> Ctx
Files
- Data/CryptoHash/MD2.hs +5/−10
- Data/CryptoHash/MD4.hs +5/−10
- Data/CryptoHash/MD5.hs +5/−10
- Data/CryptoHash/RIPEMD160.hs +5/−10
- Data/CryptoHash/SHA1.hs +5/−10
- Data/CryptoHash/SHA224.hs +5/−10
- Data/CryptoHash/SHA256.hs +5/−10
- Data/CryptoHash/SHA384.hs +5/−10
- Data/CryptoHash/SHA512.hs +5/−10
- Data/CryptoHash/Skein256.hs +102/−0
- Data/CryptoHash/Skein512.hs +7/−20
- Data/CryptoHash/Tiger.hs +5/−10
- Tests.hs +10/−0
- cbits/skein.h +46/−0
- cbits/skein256.c +191/−0
- cbits/skein256.h +45/−0
- cbits/skein512.c +9/−22
- cryptohash.cabal +7/−3
Data/CryptoHash/MD2.hs view
@@ -28,10 +28,10 @@ import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString)-import Data.ByteString.Unsafe (unsafeUseAsCStringLen, unsafeIndex)-import Data.ByteString.Internal (create)+import Data.ByteString.Unsafe (unsafeUseAsCString, unsafeUseAsCStringLen)+import Data.ByteString.Internal (create, memcpy) -data Ctx = Ctx ByteString+data Ctx = Ctx !ByteString digestSize :: Int sizeCtx :: Int@@ -42,14 +42,9 @@ instance Storable Ctx where sizeOf _ = sizeCtx alignment _ = 16- poke ptr (Ctx b) = mapM_ (\i -> poke (ptr `plusPtr` i) (unsafeIndex b i)) [0..(sizeCtx-1)]+ poke ptr (Ctx b) = unsafeUseAsCString b (\cs -> memcpy (castPtr ptr) (castPtr cs) (fromIntegral sizeCtx)) - peek ptr = do- b <- create sizeCtx (\bptr -> mapM_ (\i -> do- f <- peek (ptr `plusPtr` i) :: IO Word8- poke (bptr `plusPtr` i) f- ) [0..(sizeCtx-1)])- return $ Ctx $! b+ peek ptr = create sizeCtx (\bptr -> memcpy bptr (castPtr ptr) (fromIntegral sizeCtx)) >>= return . Ctx foreign import ccall unsafe "md2.h md2_init" c_md2_init :: Ptr Ctx -> IO ()
Data/CryptoHash/MD4.hs view
@@ -28,10 +28,10 @@ import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString)-import Data.ByteString.Unsafe (unsafeUseAsCStringLen, unsafeIndex)-import Data.ByteString.Internal (create)+import Data.ByteString.Unsafe (unsafeUseAsCString, unsafeUseAsCStringLen)+import Data.ByteString.Internal (create, memcpy) -data Ctx = Ctx ByteString+data Ctx = Ctx !ByteString digestSize :: Int sizeCtx :: Int@@ -42,14 +42,9 @@ instance Storable Ctx where sizeOf _ = sizeCtx alignment _ = 16- poke ptr (Ctx b) = mapM_ (\i -> poke (ptr `plusPtr` i) (unsafeIndex b i)) [0..(sizeCtx-1)]+ poke ptr (Ctx b) = unsafeUseAsCString b (\cs -> memcpy (castPtr ptr) (castPtr cs) (fromIntegral sizeCtx)) - peek ptr = do- b <- create sizeCtx (\bptr -> mapM_ (\i -> do- f <- peek (ptr `plusPtr` i) :: IO Word8- poke (bptr `plusPtr` i) f- ) [0..(sizeCtx-1)])- return $ Ctx $! b+ peek ptr = create sizeCtx (\bptr -> memcpy bptr (castPtr ptr) (fromIntegral sizeCtx)) >>= return . Ctx foreign import ccall unsafe "md4.h md4_init" c_md4_init :: Ptr Ctx -> IO ()
Data/CryptoHash/MD5.hs view
@@ -28,10 +28,10 @@ import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString)-import Data.ByteString.Unsafe (unsafeUseAsCStringLen, unsafeIndex)-import Data.ByteString.Internal (create)+import Data.ByteString.Unsafe (unsafeUseAsCString, unsafeUseAsCStringLen)+import Data.ByteString.Internal (create, memcpy) -data Ctx = Ctx ByteString+data Ctx = Ctx !ByteString digestSize :: Int sizeCtx :: Int@@ -42,14 +42,9 @@ instance Storable Ctx where sizeOf _ = sizeCtx alignment _ = 16- poke ptr (Ctx b) = mapM_ (\i -> poke (ptr `plusPtr` i) (unsafeIndex b i)) [0..(sizeCtx-1)]+ poke ptr (Ctx b) = unsafeUseAsCString b (\cs -> memcpy (castPtr ptr) (castPtr cs) (fromIntegral sizeCtx)) - peek ptr = do- b <- create sizeCtx (\bptr -> mapM_ (\i -> do- f <- peek (ptr `plusPtr` i) :: IO Word8- poke (bptr `plusPtr` i) f- ) [0..(sizeCtx-1)])- return $ Ctx $! b+ peek ptr = create sizeCtx (\bptr -> memcpy bptr (castPtr ptr) (fromIntegral sizeCtx)) >>= return . Ctx foreign import ccall unsafe "md5.h md5_init" c_md5_init :: Ptr Ctx -> IO ()
Data/CryptoHash/RIPEMD160.hs view
@@ -28,10 +28,10 @@ import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString)-import Data.ByteString.Unsafe (unsafeUseAsCStringLen, unsafeIndex)-import Data.ByteString.Internal (create)+import Data.ByteString.Unsafe (unsafeUseAsCString, unsafeUseAsCStringLen)+import Data.ByteString.Internal (create, memcpy) -data Ctx = Ctx ByteString+data Ctx = Ctx !ByteString digestSize :: Int sizeCtx :: Int@@ -42,14 +42,9 @@ instance Storable Ctx where sizeOf _ = sizeCtx alignment _ = 16- poke ptr (Ctx b) = mapM_ (\i -> poke (ptr `plusPtr` i) (unsafeIndex b i)) [0..(sizeCtx-1)]+ poke ptr (Ctx b) = unsafeUseAsCString b (\cs -> memcpy (castPtr ptr) (castPtr cs) (fromIntegral sizeCtx)) - peek ptr = do- b <- create sizeCtx (\bptr -> mapM_ (\i -> do- f <- peek (ptr `plusPtr` i) :: IO Word8- poke (bptr `plusPtr` i) f- ) [0..(sizeCtx-1)])- return $ Ctx $! b+ peek ptr = create sizeCtx (\bptr -> memcpy bptr (castPtr ptr) (fromIntegral sizeCtx)) >>= return . Ctx foreign import ccall unsafe "ripemd.h ripemd160_init" c_ripemd160_init :: Ptr Ctx -> IO ()
Data/CryptoHash/SHA1.hs view
@@ -28,10 +28,10 @@ import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString)-import Data.ByteString.Unsafe (unsafeUseAsCStringLen, unsafeIndex)-import Data.ByteString.Internal (create)+import Data.ByteString.Unsafe (unsafeUseAsCString, unsafeUseAsCStringLen)+import Data.ByteString.Internal (create, memcpy) -data Ctx = Ctx ByteString+data Ctx = Ctx !ByteString digestSize :: Int sizeCtx :: Int@@ -42,14 +42,9 @@ instance Storable Ctx where sizeOf _ = sizeCtx alignment _ = 16- poke ptr (Ctx b) = mapM_ (\i -> poke (ptr `plusPtr` i) (unsafeIndex b i)) [0..(sizeCtx-1)]+ poke ptr (Ctx b) = unsafeUseAsCString b (\cs -> memcpy (castPtr ptr) (castPtr cs) (fromIntegral sizeCtx)) - peek ptr = do- b <- create sizeCtx (\bptr -> mapM_ (\i -> do- f <- peek (ptr `plusPtr` i) :: IO Word8- poke (bptr `plusPtr` i) f- ) [0..(sizeCtx-1)])- return $ Ctx $! b+ peek ptr = create sizeCtx (\bptr -> memcpy bptr (castPtr ptr) (fromIntegral sizeCtx)) >>= return . Ctx foreign import ccall unsafe "sha1.h sha1_init" c_sha1_init :: Ptr Ctx -> IO ()
Data/CryptoHash/SHA224.hs view
@@ -28,10 +28,10 @@ import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString)-import Data.ByteString.Unsafe (unsafeUseAsCStringLen, unsafeIndex)-import Data.ByteString.Internal (create)+import Data.ByteString.Unsafe (unsafeUseAsCString, unsafeUseAsCStringLen)+import Data.ByteString.Internal (create, memcpy) -data Ctx = Ctx ByteString+data Ctx = Ctx !ByteString digestSize :: Int sizeCtx :: Int@@ -42,14 +42,9 @@ instance Storable Ctx where sizeOf _ = sizeCtx alignment _ = 16- poke ptr (Ctx b) = mapM_ (\i -> poke (ptr `plusPtr` i) (unsafeIndex b i)) [0..(sizeCtx-1)]+ poke ptr (Ctx b) = unsafeUseAsCString b (\cs -> memcpy (castPtr ptr) (castPtr cs) (fromIntegral sizeCtx)) - peek ptr = do- b <- create sizeCtx (\bptr -> mapM_ (\i -> do- f <- peek (ptr `plusPtr` i) :: IO Word8- poke (bptr `plusPtr` i) f- ) [0..(sizeCtx-1)])- return $ Ctx $! b+ peek ptr = create sizeCtx (\bptr -> memcpy bptr (castPtr ptr) (fromIntegral sizeCtx)) >>= return . Ctx foreign import ccall unsafe "sha256.h sha224_init" c_sha224_init :: Ptr Ctx -> IO ()
Data/CryptoHash/SHA256.hs view
@@ -28,10 +28,10 @@ import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString)-import Data.ByteString.Unsafe (unsafeUseAsCStringLen, unsafeIndex)-import Data.ByteString.Internal (create)+import Data.ByteString.Unsafe (unsafeUseAsCString, unsafeUseAsCStringLen)+import Data.ByteString.Internal (create, memcpy) -data Ctx = Ctx ByteString+data Ctx = Ctx !ByteString digestSize :: Int sizeCtx :: Int@@ -42,14 +42,9 @@ instance Storable Ctx where sizeOf _ = sizeCtx alignment _ = 16- poke ptr (Ctx b) = mapM_ (\i -> poke (ptr `plusPtr` i) (unsafeIndex b i)) [0..(sizeCtx-1)]+ poke ptr (Ctx b) = unsafeUseAsCString b (\cs -> memcpy (castPtr ptr) (castPtr cs) (fromIntegral sizeCtx)) - peek ptr = do- b <- create sizeCtx (\bptr -> mapM_ (\i -> do- f <- peek (ptr `plusPtr` i) :: IO Word8- poke (bptr `plusPtr` i) f- ) [0..(sizeCtx-1)])- return $ Ctx $! b+ peek ptr = create sizeCtx (\bptr -> memcpy bptr (castPtr ptr) (fromIntegral sizeCtx)) >>= return . Ctx foreign import ccall unsafe "sha256.h sha256_init" c_sha256_init :: Ptr Ctx -> IO ()
Data/CryptoHash/SHA384.hs view
@@ -28,10 +28,10 @@ import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString)-import Data.ByteString.Unsafe (unsafeUseAsCStringLen, unsafeIndex)-import Data.ByteString.Internal (create)+import Data.ByteString.Unsafe (unsafeUseAsCString, unsafeUseAsCStringLen)+import Data.ByteString.Internal (create, memcpy) -data Ctx = Ctx ByteString+data Ctx = Ctx !ByteString digestSize :: Int sizeCtx :: Int@@ -42,14 +42,9 @@ instance Storable Ctx where sizeOf _ = sizeCtx alignment _ = 16- poke ptr (Ctx b) = mapM_ (\i -> poke (ptr `plusPtr` i) (unsafeIndex b i)) [0..(sizeCtx-1)]+ poke ptr (Ctx b) = unsafeUseAsCString b (\cs -> memcpy (castPtr ptr) (castPtr cs) (fromIntegral sizeCtx)) - peek ptr = do- b <- create sizeCtx (\bptr -> mapM_ (\i -> do- f <- peek (ptr `plusPtr` i) :: IO Word8- poke (bptr `plusPtr` i) f- ) [0..(sizeCtx-1)])- return $ Ctx $! b+ peek ptr = create sizeCtx (\bptr -> memcpy bptr (castPtr ptr) (fromIntegral sizeCtx)) >>= return . Ctx foreign import ccall unsafe "sha512.h sha384_init" c_sha384_init :: Ptr Ctx -> IO ()
Data/CryptoHash/SHA512.hs view
@@ -28,10 +28,10 @@ import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString)-import Data.ByteString.Unsafe (unsafeUseAsCStringLen, unsafeIndex)-import Data.ByteString.Internal (create)+import Data.ByteString.Unsafe (unsafeUseAsCString, unsafeUseAsCStringLen)+import Data.ByteString.Internal (create, memcpy) -data Ctx = Ctx ByteString+data Ctx = Ctx !ByteString digestSize :: Int sizeCtx :: Int@@ -42,14 +42,9 @@ instance Storable Ctx where sizeOf _ = sizeCtx alignment _ = 16- poke ptr (Ctx b) = mapM_ (\i -> poke (ptr `plusPtr` i) (unsafeIndex b i)) [0..(sizeCtx-1)]+ poke ptr (Ctx b) = unsafeUseAsCString b (\cs -> memcpy (castPtr ptr) (castPtr cs) (fromIntegral sizeCtx)) - peek ptr = do- b <- create sizeCtx (\bptr -> mapM_ (\i -> do- f <- peek (ptr `plusPtr` i) :: IO Word8- poke (bptr `plusPtr` i) f- ) [0..(sizeCtx-1)])- return $ Ctx $! b+ peek ptr = create sizeCtx (\bptr -> memcpy bptr (castPtr ptr) (fromIntegral sizeCtx)) >>= return . Ctx foreign import ccall unsafe "sha512.h sha512_init" c_sha512_init :: Ptr Ctx -> IO ()
+ Data/CryptoHash/Skein256.hs view
@@ -0,0 +1,102 @@+{-# LANGUAGE ForeignFunctionInterface #-}++-- |+-- Module : Data.CryptoHash.Skein256+-- License : BSD-style+-- Maintainer : Vincent Hanquez <vincent@snarc.org>+-- Stability : experimental+-- Portability : unknown+--+-- A module containing Skein256 bindings+--+module Data.CryptoHash.Skein256 (+ Ctx(..),++ -- * Incremental hashing Functions+ init, -- :: Int -> Ctx+ update, -- :: Ctx -> ByteString -> Ctx+ finalize, -- :: Ctx -> ByteString++ -- * Single Pass hashing+ hash, -- :: Int -> ByteString -> ByteString+ hashlazy -- :: Int -> ByteString -> ByteString+ ) where++import Prelude hiding (init)+import Foreign+import Foreign.C.String+import Foreign.C.Types+import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as L+import Data.ByteString (ByteString)+import Data.ByteString.Unsafe (unsafeUseAsCString, unsafeUseAsCStringLen)+import Data.ByteString.Internal (create, memcpy)++data Ctx = Ctx !ByteString++sizeCtx :: Int+sizeCtx = 100++instance Storable Ctx where+ sizeOf _ = sizeCtx+ alignment _ = 16+ poke ptr (Ctx b) = unsafeUseAsCString b (\cs -> memcpy (castPtr ptr) (castPtr cs) (fromIntegral sizeCtx))++ peek ptr = create sizeCtx (\bptr -> memcpy bptr (castPtr ptr) (fromIntegral sizeCtx)) >>= return . Ctx++poke_hashlen :: Ptr Ctx -> IO Int+poke_hashlen ptr = do+ let iptr = castPtr ptr :: Ptr CUInt+ a <- peek iptr+ return $ fromIntegral a++foreign import ccall unsafe "skein256.h skein256_init"+ c_skein256_init :: Ptr Ctx -> CUInt -> IO ()++foreign import ccall "skein256.h skein256_update"+ c_skein256_update :: Ptr Ctx -> CString -> Word32 -> IO ()++foreign import ccall unsafe "skein256.h skein256_finalize"+ c_skein256_finalize :: Ptr Ctx -> CString -> IO ()++allocInternal :: (Ptr Ctx -> IO a) -> IO a+allocInternal = alloca++allocInternalFrom :: Ctx -> (Ptr Ctx -> IO a) -> IO a+allocInternalFrom ctx f = allocInternal $ \ptr -> (poke ptr ctx >> f ptr)++updateInternalIO :: Ptr Ctx -> ByteString -> IO ()+updateInternalIO ptr d =+ unsafeUseAsCStringLen d (\(cs, len) -> c_skein256_update ptr cs (fromIntegral len))++finalizeInternalIO :: Ptr Ctx -> IO ByteString+finalizeInternalIO ptr = do+ digestSize <- fmap (\x -> (x + 7) `shiftR` 3) $ poke_hashlen ptr+ allocaBytes digestSize (\cs -> c_skein256_finalize ptr cs >> B.packCStringLen (cs, digestSize))++{-# NOINLINE init #-}+-- | init a context+init :: Int -> Ctx+init hashlen = unsafePerformIO $ allocInternal $ \ptr -> do (c_skein256_init ptr (fromIntegral hashlen) >> peek ptr)++{-# NOINLINE update #-}+-- | update a context with a bytestring+update :: Ctx -> ByteString -> Ctx+update ctx d = unsafePerformIO $ allocInternalFrom ctx $ \ptr -> do updateInternalIO ptr d >> peek ptr++{-# NOINLINE finalize #-}+-- | finalize the context into a digest bytestring+finalize :: Ctx -> ByteString+finalize ctx = unsafePerformIO $ allocInternalFrom ctx $ \ptr -> do finalizeInternalIO ptr++{-# NOINLINE hash #-}+-- | hash a strict bytestring into a digest bytestring+hash :: Int -> ByteString -> ByteString+hash hashlen d = unsafePerformIO $ allocInternal $ \ptr -> do+ c_skein256_init ptr (fromIntegral hashlen) >> updateInternalIO ptr d >> finalizeInternalIO ptr++{-# NOINLINE hashlazy #-}+-- | hash a lazy bytestring into a digest bytestring+hashlazy :: Int -> L.ByteString -> ByteString+hashlazy hashlen l = unsafePerformIO $ allocInternal $ \ptr -> do+ c_skein256_init ptr (fromIntegral hashlen) >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr
Data/CryptoHash/Skein512.hs view
@@ -29,8 +29,8 @@ import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString)-import Data.ByteString.Unsafe (unsafeUseAsCStringLen, unsafeIndex)-import Data.ByteString.Internal (create)+import Data.ByteString.Unsafe (unsafeUseAsCString, unsafeUseAsCStringLen)+import Data.ByteString.Internal (create, memcpy) data Ctx = Ctx !ByteString @@ -40,28 +40,15 @@ instance Storable Ctx where sizeOf _ = sizeCtx alignment _ = 16- poke ptr (Ctx b) = do- mapM_ (\i -> poke (ptr `plusPtr` i) (unsafeIndex b i)) [0..(sizeCtx-1)]+ poke ptr (Ctx b) = unsafeUseAsCString b (\cs -> memcpy (castPtr ptr) (castPtr cs) (fromIntegral sizeCtx)) - peek ptr = do- b <- create sizeCtx (\bptr -> do- mapM_ (\i -> do- f <- peek (ptr `plusPtr` i) :: IO Word8- poke (bptr `plusPtr` i) f- ) [0..(sizeCtx-1)]- )- return $ Ctx b+ peek ptr = create sizeCtx (\bptr -> memcpy bptr (castPtr ptr) (fromIntegral sizeCtx)) >>= return . Ctx poke_hashlen :: Ptr Ctx -> IO Int poke_hashlen ptr = do- a <- peek (ptr `plusPtr` 3)- b <- peek (ptr `plusPtr` 2)- c <- peek (ptr `plusPtr` 1)- d <- peek (ptr `plusPtr` 0)- return (sl a 24 .|. sl b 16 .|. sl c 8 .|. sl d 0)- where- sl :: Word8 -> Int -> Int- sl a r = (fromIntegral a) `shiftL` r+ let iptr = castPtr ptr :: Ptr CUInt+ a <- peek iptr+ return $ fromIntegral a foreign import ccall unsafe "skein512.h skein512_init" c_skein512_init :: Ptr Ctx -> CUInt -> IO ()
Data/CryptoHash/Tiger.hs view
@@ -28,10 +28,10 @@ import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString)-import Data.ByteString.Unsafe (unsafeUseAsCStringLen, unsafeIndex)-import Data.ByteString.Internal (create)+import Data.ByteString.Unsafe (unsafeUseAsCString, unsafeUseAsCStringLen)+import Data.ByteString.Internal (create, memcpy) -data Ctx = Ctx ByteString+data Ctx = Ctx !ByteString digestSize :: Int sizeCtx :: Int@@ -42,14 +42,9 @@ instance Storable Ctx where sizeOf _ = sizeCtx alignment _ = 16- poke ptr (Ctx b) = mapM_ (\i -> poke (ptr `plusPtr` i) (unsafeIndex b i)) [0..(sizeCtx-1)]+ poke ptr (Ctx b) = unsafeUseAsCString b (\cs -> memcpy (castPtr ptr) (castPtr cs) (fromIntegral sizeCtx)) - peek ptr = do- b <- create sizeCtx (\bptr -> mapM_ (\i -> do- f <- peek (ptr `plusPtr` i) :: IO Word8- poke (bptr `plusPtr` i) f- ) [0..(sizeCtx-1)])- return $ Ctx $! b+ peek ptr = create sizeCtx (\bptr -> memcpy bptr (castPtr ptr) (fromIntegral sizeCtx)) >>= return . Ctx foreign import ccall unsafe "tiger.h tiger_init" c_tiger_init :: Ptr Ctx -> IO ()
Tests.hs view
@@ -13,6 +13,7 @@ import qualified Data.CryptoHash.SHA512 as SHA512 import qualified Data.CryptoHash.RIPEMD160 as RIPEMD160 import qualified Data.CryptoHash.Tiger as Tiger+import qualified Data.CryptoHash.Skein256 as Skein256 import qualified Data.CryptoHash.Skein512 as Skein512 v0 = ""@@ -37,6 +38,7 @@ ripemd160Hash = HashFct { fctHash = RIPEMD160.hash, fctInc = hashinc RIPEMD160.init RIPEMD160.update RIPEMD160.finalize } tigerHash = HashFct { fctHash = Tiger.hash, fctInc = hashinc Tiger.init Tiger.update Tiger.finalize } +skein256Hash x = HashFct { fctHash = Skein256.hash x, fctInc = hashinc (Skein256.init x) Skein256.update Skein256.finalize } skein512Hash x = HashFct { fctHash = Skein512.hash x, fctInc = hashinc (Skein512.init x) Skein512.update Skein512.finalize } results :: [ (String, HashFct, [String]) ]@@ -81,6 +83,14 @@ "3293ac630c13f0245f92bbb1766e16167a4e58492dde73f3", "6d12a41e72e644f017b6f0e2f7b44c6285f06dd5d2c5b075", "a8f04b0f7201a0d728101c9d26525b31764a3493fcd8458f" ])+ , ("Skein256-160", skein256Hash 160, [+ "2ab89f14cfb3a5cb4655379386c42df7a45ccaf7",+ "c86ef8411dc1deb008a3c175091691b74643631e",+ "2775e79484bc087b58eb78d977c143a3029471be" ])+ , ("Skein256-256", skein256Hash 256, [+ "0b04103b828cddaebcf592ac845ecafd5887f61230a755406d38d85376e1ae08",+ "a7e63c4dc73d0cb77184e319ebb6f69b73bfc8b945c1b371fafd01223a2ade1c",+ "2174ca46353601a53826b430b52e76fca51bb0419f7a20ac7ffd53c4c448fa51" ]) , ("Skein512-160", skein512Hash 160, [ "b034bcc065b01b0c486159b3dba3e03aa52fdd70", "9709e7d913bc3eee240e1f302840a0da9d9acc48",
+ cbits/skein.h view
@@ -0,0 +1,46 @@+/*+ * Copyright (C) 2006-2010 Vincent Hanquez <vincent@snarc.org>+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ * notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ * notice, this list of conditions and the following disclaimer in the+ * documentation and/or other materials provided with the distribution.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ */+#ifndef CRYPTOHASH_SKEIN_H+#define CRYPTOHASH_SKEIN_H++#define SKEIN_VERSION 1ULL+#define SKEIN_IDSTRING 0x33414853ULL++/*+t0 0-63 || t1 64-127+0-95 96-111 112-118 119 120-125 126 127+Position reserved TreeLevel BitPad Type First Final+*/+#define FLAG_FIRST (1ULL << 62)+#define FLAG_FINAL (1ULL << 63)+#define FLAG_TYPE(x) (((uint64_t) ((x) & 0x3f)) << 56)++#define TYPE_KEY 0x00+#define TYPE_CFG 0x04+#define TYPE_MSG 0x30+#define TYPE_OUT 0x3f++#define SET_TYPE(ctx, ty) ctx->t0 = 0; ctx->t1 = (ty)++#endif
+ cbits/skein256.c view
@@ -0,0 +1,191 @@+/*+ * Copyright (C) 2006-2010 Vincent Hanquez <vincent@snarc.org>+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ * notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ * notice, this list of conditions and the following disclaimer in the+ * documentation and/or other materials provided with the distribution.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ */++#include <string.h>+#include "skein.h"+#include "skein256.h"+#include "bitfn.h"++static const uint8_t K256_0[2] = { 14, 16, };+static const uint8_t K256_1[2] = { 52, 57, };+static const uint8_t K256_2[2] = { 23, 40, };+static const uint8_t K256_3[2] = { 5, 37, };+static const uint8_t K256_4[2] = { 25, 33, };+static const uint8_t K256_5[2] = { 46, 12, };+static const uint8_t K256_6[2] = { 58, 22, };+static const uint8_t K256_7[2] = { 32, 32, };++static inline void skein256_do_chunk(struct skein256_ctx *ctx, uint64_t *buf, uint32_t len)+{+ uint64_t x[4];+ uint64_t ts[3];+ uint64_t ks[4+1];++ ks[4] = 0x5555555555555555;+ ks[0] = ctx->h[0]; ks[4] ^= ctx->h[0];+ ks[1] = ctx->h[1]; ks[4] ^= ctx->h[1];+ ks[2] = ctx->h[2]; ks[4] ^= ctx->h[2];+ ks[3] = ctx->h[3]; ks[4] ^= ctx->h[3];++ ts[0] = ctx->t0;+ ts[1] = ctx->t1;++ ts[0] += len;++ ts[2] = ts[0] ^ ts[1];++#define INJECTKEY(r) \+ x[0] += ks[((r)+0) % (4+1)]; \+ x[1] += ks[((r)+1) % (4+1)] + ts[((r)+0) % 3]; \+ x[2] += ks[((r)+2) % (4+1)] + ts[((r)+1) % 3]; \+ x[3] += ks[((r)+3) % (4+1)] + (r)++#define ROUND(a,b,c,d,k) \+ x[a] += x[b]; x[b] = rol64(x[b],k[0]); x[b] ^= x[a]; \+ x[c] += x[d]; x[d] = rol64(x[d],k[1]); x[d] ^= x[c];++#define PASS(i) \+ ROUND(0,1,2,3,K256_0); \+ ROUND(0,3,2,1,K256_1); \+ ROUND(0,1,2,3,K256_2); \+ ROUND(0,3,2,1,K256_3); \+ INJECTKEY((i*2) + 1); \+ ROUND(0,1,2,3,K256_4); \+ ROUND(0,3,2,1,K256_5); \+ ROUND(0,1,2,3,K256_6); \+ ROUND(0,3,2,1,K256_7); \+ INJECTKEY((i*2) + 2)++ x[0] = le64_to_cpu(buf[0]) + ks[0];+ x[1] = le64_to_cpu(buf[1]) + ks[1] + ts[0];+ x[2] = le64_to_cpu(buf[2]) + ks[2] + ts[1];+ x[3] = le64_to_cpu(buf[3]) + ks[3];++ /* 9 pass of 8 rounds = 72 rounds */+ PASS(0);+ PASS(1);+ PASS(2);+ PASS(3);+ PASS(4);+ PASS(5);+ PASS(6);+ PASS(7);+ PASS(8);++ ts[1] &= ~FLAG_FIRST;+ ctx->t0 = ts[0];+ ctx->t1 = ts[1];++ ctx->h[0] = x[0] ^ cpu_to_le64(buf[0]);+ ctx->h[1] = x[1] ^ cpu_to_le64(buf[1]);+ ctx->h[2] = x[2] ^ cpu_to_le64(buf[2]);+ ctx->h[3] = x[3] ^ cpu_to_le64(buf[3]);+}++void skein256_init(struct skein256_ctx *ctx, uint32_t hashlen)+{+ uint64_t buf[4];+ memset(ctx, 0, sizeof(*ctx));++ ctx->hashlen = hashlen;+ SET_TYPE(ctx, FLAG_FIRST | FLAG_FINAL | FLAG_TYPE(TYPE_CFG));+ + memset(buf, '\0', sizeof(buf));+ buf[0] = cpu_to_le64((SKEIN_VERSION << 32) | SKEIN_IDSTRING);+ buf[1] = cpu_to_le64(hashlen);+ buf[2] = 0; /* tree info, not implemented */+ skein256_do_chunk(ctx, buf, 4*8);++ SET_TYPE(ctx, FLAG_FIRST | FLAG_TYPE(TYPE_MSG));+}++void skein256_update(struct skein256_ctx *ctx, uint8_t *data, uint32_t len)+{+ uint32_t to_fill;++ to_fill = 32 - ctx->bufindex;++ if (ctx->bufindex == 32) {+ skein256_do_chunk(ctx, (uint64_t *) ctx->buf, 32);+ ctx->bufindex = 0;+ }++ /* process partial buffer if there's enough data to make a block */+ if (ctx->bufindex && len >= to_fill) {+ memcpy(ctx->buf + ctx->bufindex, data, to_fill);+ skein256_do_chunk(ctx, (uint64_t *) ctx->buf, 32);+ len -= to_fill;+ data += to_fill;+ ctx->bufindex = 0;+ }++ /* process as much 32-block as possible except the last one in case we finalize */+ for (; len > 32; len -= 32, data += 32)+ skein256_do_chunk(ctx, (uint64_t *) data, 32);++ /* append data into buf */+ if (len) {+ memcpy(ctx->buf + ctx->bufindex, data, len);+ ctx->bufindex += len;+ }+}++void skein256_finalize(struct skein256_ctx *ctx, uint8_t *out)+{+ uint32_t outsize;+ uint64_t *p = (uint64_t *) out;+ uint64_t x[4];+ int i, j, n;++ ctx->t1 |= FLAG_FINAL;+ /* if buf is not complete pad with 0 bytes */+ if (ctx->bufindex < 32)+ memset(ctx->buf + ctx->bufindex, '\0', 32 - ctx->bufindex);+ skein256_do_chunk(ctx, (uint64_t *) ctx->buf, ctx->bufindex);++ memset(ctx->buf, '\0', 32);++ /* make sure we have a 8 bit rounded value */+ outsize = (ctx->hashlen + 7) >> 3;++ /* backup h[0--4] */+ for (j = 0; j < 4; j++)+ x[j] = ctx->h[j];+ /* threefish in counter mode, 0 for 1st 64 bytes, 1 for 2nd 64 bytes, .. */+ for (i = 0; i*32 < outsize; i++) {+ *((uint64_t *) ctx->buf) = cpu_to_le64(i);+ SET_TYPE(ctx, FLAG_FIRST | FLAG_FINAL | FLAG_TYPE(TYPE_OUT));+ skein256_do_chunk(ctx, (uint64_t *) ctx->buf, sizeof(uint64_t));++ n = outsize - i * 32;+ if (n >= 32) n = 32;++ /* FIXME should be little endian array copy ? */+ memcpy(out + i*32, ctx->h, n);++ /* restore h[0--4] */+ for (j = 0; j < 4; j++)+ ctx->h[j] = x[j];+ }+}
+ cbits/skein256.h view
@@ -0,0 +1,45 @@+/*+ * Copyright (C) 2006-2010 Vincent Hanquez <vincent@snarc.org>+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ * notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ * notice, this list of conditions and the following disclaimer in the+ * documentation and/or other materials provided with the distribution.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ */+#ifndef CRYPTOHASH_SKEIN256_H+#define CRYPTOHASH_SKEIN256_H++#include <stdint.h>++struct skein256_ctx+{+ uint32_t hashlen;+ uint32_t bufindex;+ uint8_t buf[32];+ uint64_t h[4];+ uint64_t t0;+ uint64_t t1;+};++#define SKEIN256_CTX_SIZE sizeof(struct skein256_ctx)++void skein256_init(struct skein256_ctx *ctx, uint32_t hashlen);+void skein256_update(struct skein256_ctx *ctx, uint8_t *data, uint32_t len);+void skein256_finalize(struct skein256_ctx *ctx, uint8_t *out);++#endif
cbits/skein512.c view
@@ -23,28 +23,10 @@ */ #include <string.h>+#include "skein.h" #include "skein512.h" #include "bitfn.h" -#define SKEIN_VERSION 1ULL-#define SKEIN_IDSTRING 0x33414853ULL--/*-t0 0-63 || t1 64-127-0-95 96-111 112-118 119 120-125 126 127-Position reserved TreeLevel BitPad Type First Final-*/-#define FLAG_FIRST (1ULL << 62)-#define FLAG_FINAL (1ULL << 63)-#define FLAG_TYPE(x) (((uint64_t) ((x) & 0x3f)) << 56)--#define TYPE_KEY 0x00-#define TYPE_CFG 0x04-#define TYPE_MSG 0x30-#define TYPE_OUT 0x3f--#define SET_TYPE(ctx, ty) ctx->t0 = 0; ctx->t1 = (ty)- static const uint8_t K512_0[4] = { 46, 36, 19, 37, }; static const uint8_t K512_1[4] = { 33, 27, 14, 42, }; static const uint8_t K512_2[4] = { 17, 49, 36, 39, };@@ -144,7 +126,7 @@ uint64_t buf[8]; memset(ctx, 0, sizeof(*ctx)); - ctx->hashlen = cpu_to_le64(hashlen);+ ctx->hashlen = hashlen; SET_TYPE(ctx, FLAG_FIRST | FLAG_FINAL | FLAG_TYPE(TYPE_CFG)); memset(buf, '\0', sizeof(buf));@@ -162,8 +144,13 @@ to_fill = 64 - ctx->bufindex; + if (ctx->bufindex == 64) {+ skein512_do_chunk(ctx, (uint64_t *) ctx->buf, 64);+ ctx->bufindex = 0;+ }+ /* process partial buffer if there's enough data to make a block */- if ((ctx->bufindex & 0x3f) && len >= to_fill) {+ if (ctx->bufindex && len >= to_fill) { memcpy(ctx->buf + ctx->bufindex, data, to_fill); skein512_do_chunk(ctx, (uint64_t *) ctx->buf, 64); len -= to_fill;@@ -198,7 +185,7 @@ memset(ctx->buf, '\0', 64); /* make sure we have a 8 bit rounded value */- outsize = (le64_to_cpu(ctx->hashlen) + 7) >> 3;+ outsize = (ctx->hashlen + 7) >> 3; /* backup h[0--7] */ for (j = 0; j < 8; j++)
cryptohash.cabal view
@@ -1,5 +1,5 @@ Name: cryptohash-Version: 0.5+Version: 0.5.1 Description: A collection of crypto hashes, with a practical incremental and one-pass, pure APIs, with performance close to the fastest implementations available in others languages.@@ -10,7 +10,7 @@ License-file: LICENSE Author: Vincent Hanquez Maintainer: vincent@snarc.org-Synopsis: collection of crypto hashes, fast, pure and pratical+Synopsis: collection of crypto hashes, fast, pure and practical Category: Data, Cryptography Build-Type: Simple Cabal-Version: >=1.6@@ -19,7 +19,8 @@ extra-source-files: cbits/bitfn.h cbits/md2.h cbits/md4.h cbits/md5.h cbits/ripemd.h cbits/sha1.h cbits/sha256.h cbits/sha512.h- cbits/tiger.h cbits/skein512.h+ cbits/skein.h cbits/skein256.h cbits/skein512.h+ cbits/tiger.h Flag test Description: Build unit test@@ -37,6 +38,7 @@ Data.CryptoHash.MD4 Data.CryptoHash.MD5 Data.CryptoHash.RIPEMD160+ Data.CryptoHash.Skein256 Data.CryptoHash.Skein512 Data.CryptoHash.Tiger ghc-options: -Wall -O2 -optc-O3 -fno-cse@@ -47,6 +49,7 @@ cbits/md4.c cbits/md5.c cbits/ripemd.c+ cbits/skein256.c cbits/skein512.c cbits/tiger.c Include-Dirs: cbits@@ -61,6 +64,7 @@ cbits/md4.c cbits/md5.c cbits/ripemd.c+ cbits/skein256.c cbits/skein512.c cbits/tiger.c if flag(test)