packages feed

siphash (empty) → 1.0.0

raw patch · 6 files changed

+217/−0 lines, 6 filesdep +QuickCheckdep +basedep +bytestringsetup-changed

Dependencies added: QuickCheck, base, bytestring, cereal, siphash, test-framework, test-framework-quickcheck2

Files

+ Crypto/MAC/SipHash.hs view
@@ -0,0 +1,86 @@+-- |+-- Module      : Crypto.MAC.SipHash+-- License     : BSD-style+-- Maintainer  : Vincent Hanquez <vincent@snarc.org>+-- Stability   : experimental+-- Portability : good+--+-- provide the SipHash algorithm.+-- reference: http://131002.net/siphash/siphash.pdf+--+module Crypto.MAC.SipHash+    ( SipKey(..)+    , SipHash(..)+    , hashWith+    , hash+    ) where++import Data.Word+import Data.Bits+import Data.List (foldl')+import Data.Serialize.Get+import Data.ByteString (ByteString)+import qualified Data.ByteString as B+import Control.Monad (foldM,replicateM)++-- | SigHash Key+data SipKey = SipKey {-# UNPACK #-} !Word64 {-# UNPACK #-} !Word64++-- | Siphash tag value+newtype SipHash = SipHash Word64+    deriving (Show,Eq)++data InternalState = InternalState {-# UNPACK #-} !Word64 {-# UNPACK #-} !Word64 {-# UNPACK #-} !Word64 {-# UNPACK #-} !Word64++-- | same as @hash, except also specifies the number of sipround iterations for compression and digest.+hashWith :: Int -> Int -> SipKey -> ByteString -> SipHash+hashWith c d key b = either error (finish d) $ runGet runHash b+    where len = B.length b+          (nb,last) = len `divMod` 8++          runHash = foldM (const . getBlock) (initSip key)[0..(nb-1)] >>= lastBlock+          getBlock st = process c st `fmap` getWord64le+          lastBlock st = do+              let lengthBlock = fromIntegral (len `mod` 256) `shiftL` 56+              z <- (fst . foldl shiftAndAdd (0,0)) `fmap` replicateM last getWord8+              return $ process c st (lengthBlock .|. z)++          shiftAndAdd :: (Word64,Int) -> Word8 -> (Word64,Int)+          shiftAndAdd (acc,pos) v = (acc .|. ((fromIntegral v) `shiftL` pos), pos+8)++-- | produce a siphash with a key and a bytestring.+hash :: SipKey -> ByteString -> SipHash+hash = hashWith 2 4++initSip (SipKey k0 k1) = InternalState (k0 `xor` 0x736f6d6570736575)+                                       (k1 `xor` 0x646f72616e646f6d)+                                       (k0 `xor` 0x6c7967656e657261)+                                       (k1 `xor` 0x7465646279746573)++doRound (InternalState v0 v1 v2 v3) = do+    let v0'    = v0 + v1+        v2'    = v2 + v3+        v1'    = v1 `rotateL` 13+        v3'    = v3 `rotateL` 16+        v1''   = v1' `xor` v0'+        v3''   = v3' `xor` v2'+        v0''   = v0' `rotateL` 32+        v2''   = v2' + v1''+        v0'''  = v0'' + v3''+        v1'''  = v1'' `rotateL` 17+        v3'''  = v3'' `rotateL` 21+        v1'''' = v1''' `xor` v2''+        v3'''' = v3''' `xor` v0'''+        v2'''  = v2'' `rotateL` 32+     in InternalState v0''' v1'''' v2''' v3''''++runRounds n st = foldl' (const . doRound) st [0..(n-1)]++process c istate m = newState+    where newState = postInject $ runRounds c $ preInject $ istate+          preInject  (InternalState v0 v1 v2 v3) = InternalState v0 v1 v2 (v3 `xor` m)+          postInject (InternalState v0 v1 v2 v3) = InternalState (v0 `xor` m) v1 v2 v3++finish d istate = getDigest $ runRounds d $ preInject istate+    where getDigest (InternalState v0 v1 v2 v3) = SipHash (v0 `xor` v1 `xor` v2 `xor` v3)+          preInject (InternalState v0 v1 v2 v3) = InternalState v0 v1 (v2 `xor` 0xff) v3
+ LICENSE view
@@ -0,0 +1,27 @@+Copyright (c) 2012 Vincent Hanquez <vincent@snarc.org>++All rights reserved.++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.+3. Neither the name of the author nor the names of his contributors+   may be used to endorse or promote products derived from this software+   without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 AUTHORS OR CONTRIBUTORS 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.
+ README.md view
@@ -0,0 +1,31 @@+Haskell Siphash+===============++Simple module to compute the [SipHash](http://131002.net/siphash/siphash.pdf)+algorithm.++Install+-------++    cabal install sighash++Usage+-----++sighash-2-4:++    import Crypto.MAC.SigHash (hash)+    import qualified Data.ByteString.Char8 as B+    +    k0 = 0xaaaaaaaaaaaaaaaa+    k1 = 0xbbbbbbbbbbbbbbbb+    tag = hash (SigKey k0 k1) (B.pack "my text to hash")++sighash-c-d:++    import Crypto.MAC.SigHash (hash)+    import qualified Data.ByteString.Char8 as B+    +    k0 = 0xaaaaaaaaaaaaaaaa+    k1 = 0xbbbbbbbbbbbbbbbb+    tag = hashWith nbCompressionRounds nbDigestRounds (SigKey k0 k1) (B.pack "my text to hash")
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ Tests/Tests.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE OverloadedStrings #-}+module Main where++import Control.Applicative+import Control.Monad++import Test.Framework (Test, defaultMain, testGroup)+import Test.Framework.Providers.QuickCheck2 (testProperty)++import Test.QuickCheck+import Test.QuickCheck.Test+import Test.Framework.Providers.QuickCheck2 (testProperty)++import qualified Data.ByteString as B+import qualified Data.ByteString.Char8 as B+import Crypto.MAC.SipHash++assertEq expected got+	| expected == got = True+	| otherwise       = error ("expected: " ++ show expected ++ " got: " ++ show got)++vectors =+    [ ( SipKey 0x0706050403020100 0x0f0e0d0c0b0a0908+      , "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e"+      , SipHash 0xa129ca6149be45e5+      )+    ]++katTests v = map (testProperty "kat" . makeTest) v+    where makeTest (key,msg,tag) = assertEq tag $ hash key msg++tests =+    [ testGroup "KAT" $ katTests vectors+    ]++main = defaultMain tests
+ siphash.cabal view
@@ -0,0 +1,34 @@+Name:                siphash+Version:             1.0.0+Description:+    Haskell implementation of siphash. [http://131002.net/siphash/siphash.pdf]+License:             BSD3+License-file:        LICENSE+Copyright:           Vincent Hanquez <vincent@snarc.org>+Author:              Vincent Hanquez <vincent@snarc.org>+Maintainer:          Vincent Hanquez <vincent@snarc.org>+Synopsis:            siphash: a fast short input PRF+Category:            Data, Cryptography+Build-Type:          Simple+Cabal-Version:       >=1.8+Homepage:            http://github.com/vincenthz/hs-siphash+data-files:          README.md++Library+  Build-Depends:     base >= 4 && < 6, bytestring, cereal+  Exposed-modules:   Crypto.MAC.SipHash++Test-Suite test-siphash+  type:              exitcode-stdio-1.0+  hs-source-dirs:    Tests+  Main-Is:           Tests.hs+  Build-depends:     base >= 4 && < 5+                   , siphash+                   , bytestring+                   , QuickCheck >= 2+                   , test-framework >= 0.3.3 && < 0.7+                   , test-framework-quickcheck2 >= 0.2.9 && < 0.3++source-repository head+  type:     git+  location: git://github.com/vincenthz/hs-siphash