diff --git a/Data/Digest/Murmur3.hs b/Data/Digest/Murmur3.hs
new file mode 100644
--- /dev/null
+++ b/Data/Digest/Murmur3.hs
@@ -0,0 +1,120 @@
+module Data.Digest.Murmur3
+  (Hash,
+   asByteString,
+   hash)
+  where
+
+import Control.Monad
+import Data.Bits
+import Data.ByteString (ByteString)
+import qualified Data.ByteString as BS
+import Data.Word
+
+
+data Hash = Hash Word64 Word64
+          deriving (Eq, Ord)
+
+
+newtype Identity a = MakeIdentity { identityAction :: a }
+instance Monad Identity where
+  return a = MakeIdentity a
+  (>>=) x f = f $ identityAction x
+
+
+asByteString :: Hash -> ByteString
+asByteString (Hash h1 h2) =
+  BS.pack [fromIntegral $ shiftR h1 0 .&. 0xFF,
+           fromIntegral $ shiftR h1 8 .&. 0xFF,
+           fromIntegral $ shiftR h1 16 .&. 0xFF,
+           fromIntegral $ shiftR h1 24 .&. 0xFF,
+           fromIntegral $ shiftR h1 32 .&. 0xFF,
+           fromIntegral $ shiftR h1 40 .&. 0xFF,
+           fromIntegral $ shiftR h1 48 .&. 0xFF,
+           fromIntegral $ shiftR h1 56 .&. 0xFF,
+           fromIntegral $ shiftR h2 0 .&. 0xFF,
+           fromIntegral $ shiftR h2 8 .&. 0xFF,
+           fromIntegral $ shiftR h2 16 .&. 0xFF,
+           fromIntegral $ shiftR h2 24 .&. 0xFF,
+           fromIntegral $ shiftR h2 32 .&. 0xFF,
+           fromIntegral $ shiftR h2 40 .&. 0xFF,
+           fromIntegral $ shiftR h2 48 .&. 0xFF,
+           fromIntegral $ shiftR h2 56 .&. 0xFF]
+
+
+hash :: ByteString -> Hash
+hash input = identityAction $ do
+  let c1 = 0x87c37b91114253d5
+  let c2 = 0x4cf5ad432745937f
+      seed = 0
+      totalLength = fromIntegral $ BS.length input
+  let step :: Word64 -> Word64
+           -> Word64 -> Word64
+           -> Identity (Word64, Word64)
+      step h1 h2 k1 k2 = do
+        -- First line
+        k1 <- return $ k1 * c1
+        k1 <- return $ rotateL k1 31
+        k1 <- return $ k1 * c2
+        h1 <- return $ xor h1 k1
+        -- Second line
+        h1 <- return $ rotateL h1 27
+        h1 <- return $ h1 + h2
+        h1 <- return $ h1 * 5 + 0x52dce729
+        -- Third line
+        k2 <- return $ k2 * c2
+        k2 <- return $ rotateL k2 33
+        k2 <- return $ k2 * c1
+        h2 <- return $ xor h2 k2
+        -- Fourth line
+        h2 <- return $ rotateL h2 31
+        h2 <- return $ h2 + h1
+        h2 <- return $ h2 * 5 + 0x38495ab5
+        return (h1, h2)
+      finish :: Word64 -> Word64
+             -> Word64 -> Word64
+             -> Identity Hash
+      finish h1 h2 k1 k2 = do
+        -- First line
+        k1 <- return $ k1 * c1
+        k1 <- return $ rotateL k1 31
+        k1 <- return $ k1 * c2
+        h1 <- return $ xor h1 k1
+        -- Third line
+        k2 <- return $ k2 * c2
+        k2 <- return $ rotateL k2 33
+        k2 <- return $ k2 * c1
+        h2 <- return $ xor h2 k2
+        -- Finalization
+        h1 <- return $ xor h1 totalLength
+        h2 <- return $ xor h2 totalLength
+        h1 <- mix h1
+        h2 <- mix h2
+        h1 <- return $ h1 + h2
+        h2 <- return $ h2 + h1
+        return $ Hash h1 h2
+      mix :: Word64 -> Identity Word64
+      mix k = do
+        k <- return $ xor k (shiftR k 33)
+        k <- return $ k * 0xff51afd7ed558ccd
+        k <- return $ xor k (shiftR k 33)
+        k <- return $ k * 0xc4ceb9fe1a85ec53
+        k <- return $ xor k (shiftR k 33)
+        return k
+      loop :: Word64 -> Word64 -> ByteString -> Identity Hash
+      loop h1 h2 input = do
+        (k1, input) <- takeWord64 input
+        (k2, input) <- takeWord64 input
+        if BS.null input
+          then finish h1 h2 k1 k2
+          else do
+            (h1, h2) <- step h1 h2 k1 k2
+            loop h1 h2 input
+      takeWord64 :: ByteString -> Identity (Word64, ByteString)
+      takeWord64 input = do
+        let (front, rest) = BS.splitAt 8 input
+        word <- foldM (\sum (byte, offset) -> do
+                         return $ sum + (shiftL (fromIntegral byte) offset))
+                      0
+                      (zip (BS.unpack front) [0, 8 .. 56])
+        return (word, rest)
+  loop seed seed input
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2012 Irene Knapp
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/direct-murmur-hash.cabal b/direct-murmur-hash.cabal
new file mode 100644
--- /dev/null
+++ b/direct-murmur-hash.cabal
@@ -0,0 +1,33 @@
+name: direct-murmur-hash
+version: 1.0
+cabal-version: >= 1.12
+build-type: Simple
+license: BSD3
+license-file: LICENSE
+copyright: Copyright (c) 2013 Irene Knapp
+author: Irene Knapp <irene.knapp@icloud.com>
+maintainer: irene.knapp@icloud.com
+homepage: http://ireneknapp.com/software/
+bug-reports: https://github.com/IreneKnapp/direct-murmur-hash/issues
+category: Data
+synopsis: An implementation of the MurmurHash3 algorithm
+description:
+
+Source-Repository head
+  type: git
+  location: https://github.com/IreneKnapp/direct-murmur-hash.git
+
+Library
+  exposed-modules: Data.Digest.Murmur3
+  build-depends: base >= 4.1 && < 5,
+                 bytestring >= 0.9.1.5 && < 1
+  default-language: Haskell2010
+
+-- Executable test
+--   main-is: Main.hs
+--   other-modules: Data.Digest.Murmur3
+--   build-depends: base >= 4.1 && < 5,
+--                  bytestring >= 0.9.1.5 && < 1,
+--                  utf8-string >= 0.3.7 && < 1
+--   default-language: Haskell2010
+
