packages feed

hashable 1.2.0.2 → 1.2.0.3

raw patch · 5 files changed

+100/−25 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

Data/Hashable.hs view
@@ -27,6 +27,9 @@  module Data.Hashable     (+      -- * Hashing and security+      -- $security+       -- * Computing hash values       hash     , Hashable(..)@@ -219,3 +222,45 @@ -- >         s `hashWithSalt` -- >         yr `hashWithSalt` -- >         mo `hashWithSalt` dy++-- $security+-- #security#+--+-- Applications that use hash-based data structures to store input+-- from untrusted users can be susceptible to \"hash DoS\", a class of+-- denial-of-service attack that uses deliberately chosen colliding+-- inputs to force an application into unexpectedly behaving with+-- quadratic time complexity.+--+-- This library uses the SipHash algorithm to hash strings. SipHash+-- was designed to be more robust against collision attacks than+-- traditional hash algorithms, while retaining good performance.+--+-- To further mitigate the risk from collision attacks, this library+-- provides an environment variable named @HASHABLE_SALT@ that allows+-- the default salt used by the 'hash' function to be chosen at+-- application startup time.+--+-- * In the normal case, the environment variable is not set, and a+--   fixed salt is used that does not vary between runs. (This choice+--   can be made permanent by building this package with the+--   @-ffixed-salt@ flag.)+--+-- * If the value is the string @random@, the system's cryptographic+--   pseudo-random number generator will be used to supply a salt.+--   While this may offer added security, it can also violate the+--   assumption of some Haskell libraries that expect the results of+--   'hash' to be stable across application runs. Choose this+--   behaviour with care (and testing)!+--+-- * When the value is an integer (prefixed with @0x@ for hexadecimal),+--   it will be used as the salt.+--+-- If @HASHABLE_SALT@ cannot be parsed, then the first time that a+-- call to 'hash' is made, the application will halt with an+-- informative error message.+--+-- (Implementation note: while SipHash is used for strings, a+-- faster—and almost certainly less secure—algorithm is+-- used for numeric types, on the assumption that strings are much+-- more likely as a hash DoS attack vector.)
Data/Hashable/Class.hs view
@@ -107,8 +107,12 @@ #endif  #ifndef FIXED_SALT+import Control.Exception (tryJust)+import Control.Monad (guard) import Data.Hashable.RandomSource (getRandomBytes_) import Foreign.Marshal.Alloc (alloca)+import System.Environment (getEnv)+import System.IO.Error (isDoesNotExistError) #endif  #include "MachDeps.h"@@ -121,20 +125,32 @@ -- | A default salt used in the implementation of 'hash'. -- -- To reduce the probability of hash collisions, the value of the--- default salt will vary from one program invocation to the next+-- default salt may vary from one program invocation to the next -- unless this package is compiled with the @fixed-salt@ flag set.-defaultSalt :: Int+defaultSalt, fixedSalt :: Int +fixedSalt = 0xdc36d1615b7400a4+{-# INLINE fixedSalt #-}+ #ifdef FIXED_SALT -defaultSalt = 0xdc36d1615b7400a4+defaultSalt = fixedSalt {-# INLINE defaultSalt #-}  #else -defaultSalt = unsafePerformIO . alloca $ \p -> do-                getRandomBytes_ "defaultSalt" p (sizeOf (undefined :: Int))-                peek p+defaultSalt = unsafePerformIO $ do+  let varName = "HASHABLE_SALT"+  msalt <- tryJust (guard . isDoesNotExistError) $ getEnv varName+  case msalt of+    Right "random" -> alloca $ \p -> do+      getRandomBytes_ "defaultSalt" p (sizeOf (undefined :: Int))+      peek p+    Right s -> case reads s of+                 [(salt, "")] -> return salt+                 _            -> fail $ "Fatal: cannot parse contents of " +++                                        varName ++ " environment variable"+    Left _ -> return fixedSalt {-# NOINLINE defaultSalt #-}  #endif@@ -182,16 +198,9 @@ -- | Return a hash value for the argument. Defined in terms of -- 'hashWithSalt' and a default salt. ----- At application startup time, the default salt is initialized with a--- new value from the system's cryptographic pseudo-random number--- generator. This means that the result of 'hash' will vary from one--- application run to the next.------ If you need hashes that do not vary from run to run, use--- 'hashWithSalt' instead, and supply a salt of your choosing. (Be--- aware that if you hash untrusted, uncontrolled input data using a--- fixed salt, you may expose your application to hash collision--- attacks.)+-- (See the \"Hashing and security\" section of the+-- "Data.Hashable#security" documentation for an important note on+-- working safely with untrusted user input.) hash :: Hashable a => a -> Int hash = hashWithSalt defaultSalt 
benchmarks/Benchmarks.hs view
@@ -78,10 +78,12 @@         fnvHash (PS fp off len) =             inlinePerformIO . withForeignPtr fp $ \ptr ->             return $! fnv_hash (ptr `plusPtr` off) (fromIntegral len) 2166136261-#ifdef HAVE_SSE+#ifdef HAVE_SSE2         sse2SipHash (PS fp off len) =             inlinePerformIO . withForeignPtr fp $ \ptr ->             return $! sse2_siphash k0 k1 (ptr `plusPtr` off) (fromIntegral len)+#endif+#ifdef HAVE_SSE41         sse41SipHash (PS fp off len) =             inlinePerformIO . withForeignPtr fp $ \ptr ->             return $! sse41_siphash k0 k1 (ptr `plusPtr` off) (fromIntegral len)@@ -201,7 +203,7 @@           , bench "512" $ whnf cSipHash24 bs512           , bench "2^20" $ whnf cSipHash24 bs1Mb           ]-#ifdef HAVE_SSE+#ifdef HAVE_SSE2         , bgroup "sse2SipHash"           [ bench "5" $ whnf sse2SipHash bs5           , bench "8" $ whnf sse2SipHash bs8@@ -211,6 +213,8 @@           , bench "512" $ whnf sse2SipHash bs512           , bench "2^20" $ whnf sse2SipHash bs1Mb           ]+#endif+#ifdef HAVE_SSE41         , bgroup "sse41SipHash"           [ bench "5" $ whnf sse41SipHash bs5           , bench "8" $ whnf sse41SipHash bs8@@ -261,9 +265,11 @@     :: CInt -> CInt -> Word64 -> Word64 -> Ptr Word8 -> CSize -> Word64 foreign import ccall unsafe "hashable_siphash24" c_siphash24     :: Word64 -> Word64 -> Ptr Word8 -> CSize -> Word64-#ifdef HAVE_SSE+#ifdef HAVE_SSE2 foreign import ccall unsafe "hashable_siphash24_sse2" sse2_siphash     :: Word64 -> Word64 -> Ptr Word8 -> CSize -> Word64+#endif+#ifdef HAVE_SSE41 foreign import ccall unsafe "hashable_siphash24_sse41" sse41_siphash     :: Word64 -> Word64 -> Ptr Word8 -> CSize -> Word64 #endif
cbits/siphash.c view
@@ -109,8 +109,10 @@      if (edx & (1 << 26)) 	_siphash24 = hashable_siphash24_sse2;+#if defined(HAVE_SSE41)     else if (ecx & (1 << 19)) 	_siphash24 = hashable_siphash24_sse41;+#endif     else 	_siphash24 = plain_siphash24; }
hashable.cabal view
@@ -1,5 +1,5 @@ Name:                hashable-Version:             1.2.0.2+Version:             1.2.0.3 Synopsis:            A class for types that can be converted to a hash value Description:         This package defines a class, 'Hashable', for types that                      can be converted to a hash value.  This class@@ -31,6 +31,10 @@   Description: Do we use a single fixed salt every time the program runs?   Default: False +Flag sse41+  Description: Do we want to assume that a target supports SSE 4.1?+  Default: False+ Library   Exposed-modules:   Data.Hashable   Other-modules:     Data.Hashable.Class@@ -53,9 +57,13 @@                      cbits/siphash.c   if arch(i386)     C-sources:       cbits/siphash-sse2.c-                     cbits/siphash-sse41.c-    CC-options:      -msse2 -msse4.1+    CC-options:      -msse2 +    if flag(sse41)+      CPP-Options:   -DHAVE_SSE41+      CC-options:    -msse41+      C-sources:     cbits/siphash-sse41.c+   Ghc-options:       -Wall   if impl(ghc >= 6.8)     Ghc-options: -fwarn-tabs@@ -117,11 +125,16 @@     benchmarks/cbits/inthash.c    if arch(i386) || arch(x86_64)-    cpp-options: -DHAVE_SSE-    cc-options: -msse2 -msse4.1+    cpp-options: -DHAVE_SSE2+    cc-options: -msse2     c-sources:       cbits/siphash-sse2.c-      cbits/siphash-sse41.c++    if flag(sse41)+      cpp-options: -DHAVE_SSE41+      cc-options: -msse4.1+      c-sources:+        cbits/siphash-sse41.c    Ghc-options:       -Wall -O2   if impl(ghc >= 6.8)