packages feed

hwsl2 (empty) → 0.1.0.0

raw patch · 6 files changed

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

Dependencies added: base, bytestring

Files

+ LICENSE view
@@ -0,0 +1,22 @@+The MIT License (MIT)++Copyright (c) 2015 Sam Rijs++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.+
+ README.md view
@@ -0,0 +1,2 @@+coholos+=======
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ hwsl2.cabal view
@@ -0,0 +1,86 @@+-- Initial hwsl2.cabal generated by cabal init.  For further documentation,+--  see http://haskell.org/cabal/users-guide/++-- The name of the package.+name:                hwsl2++-- The package version.  See the Haskell package versioning policy (PVP) +-- for standards guiding when and how versions should be incremented.+-- http://www.haskell.org/haskellwiki/Package_versioning_policy+-- PVP summary:      +-+------- breaking API changes+--                   | | +----- non-breaking API additions+--                   | | | +--- code changes with no API change+version:             0.1.0.0++-- A short (one-line) description of the package.+synopsis:            Hashing with SL2++-- A longer description of the package.+description:+  An algebraic hash function, inspired by the paper "Hashing with SL2" by Tillich and Zemor.+  .+  The hash function is based on matrix multiplication in the special linear group+  of degree 2, over a Galois field of order 2^127,  with all computations modulo+  the polynomial x^127 + x^63 + 1.+  .+  This construction gives some nice properties, which traditional "bit-scambling"+  hash functions don't possess, including it being composable. It holds:+  .+  > hash (m1 <> m2) == hash m1 <> hash m2+  .+  All operations in this package are implemented in a very efficient manner using SSE instructions.++-- URL for the project homepage or repository.+homepage:            https://github.com/srijs/hwsl2++-- The license under which the package is released.+license:             MIT++-- The file containing the license text.+license-file:        LICENSE++-- The package author(s).+author:              Sam Rijs++-- An email address to which users can send suggestions, bug reports, and +-- patches.+maintainer:          srijs@airpost.net++-- A copyright notice.+-- copyright:           ++category:            Data++build-type:          Simple++-- Extra files to be distributed with the package, such as examples or a +-- README.+extra-source-files:  README.md++-- Constraint on the version of Cabal needed to build this package.+cabal-version:       >=1.10+++library+  -- Modules exported by the library.+  exposed-modules:     Data.Hash.SL2+  +  -- Modules included in this library but not exported.+  -- other-modules:       +  +  -- LANGUAGE extensions used by modules in this package.+  other-extensions:    ForeignFunctionInterface, EmptyDataDecls+  +  -- Other library packages from which modules are imported.+  build-depends:       base >=4.7 && <4.8, bytestring >=0.10 && <0.11+  +  -- Directories containing source files.+  hs-source-dirs:      src++  -- Options for foreign source files.+  c-sources:           src/tillich-zemor.c+  cc-options:          -msse2 -msse4.1 -mpclmul+  +  -- Base language which the package is written in.+  default-language:    Haskell2010+  
+ src/Data/Hash/SL2.hs view
@@ -0,0 +1,110 @@+{-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-}++-- |+-- Module     : Data.Hash.SL2+-- License    : MIT+-- Maintainer : Sam Rijs <srijs@airpost.net>+--+-- An algebraic hash function, inspired by the paper "Hashing with SL2" by+-- Tillich and Zemor.+--+-- The hash function is based on matrix multiplication in the special linear group+-- of degree 2, over a Galois field of order 2^127,  with all computations modulo+-- the polynomial x^127 + x^63 + 1.+--+-- This construction gives some nice properties, which traditional "bit-scambling"+-- hash functions don't possess, including it being composable. It holds:+--+-- prop> hash (m1 <> m2) == hash m1 <> hash m2+--+-- All operations in this package are implemented in a very efficient manner using SSE instructions.+--++module Data.Hash.SL2 (Hash, hash, (<+), (+>), parse) where++import Prelude hiding (concat)++import Foreign+import Foreign.Ptr+import Foreign.C.Types+import Foreign.C.String+import Foreign.Marshal.Array+import Foreign.Marshal.Utils+import Foreign.ForeignPtr+import System.IO.Unsafe++import Data.ByteString (ByteString)+import Data.ByteString.Unsafe++import Data.Monoid+import Data.Functor++foreign import ccall "tillich-zemor.h tz_hash_eq"+  tzHashEq :: Ptr () -> Ptr () -> IO CInt++foreign import ccall "tillich-zemor.h tz_hash_unit"+  tzHashUnit :: Ptr () -> IO ()++foreign import ccall "tillich-zemor.h tz_hash_append"+  tzHashAppend :: Ptr () -> Ptr CChar -> CSize -> IO ()++foreign import ccall "tillich-zemor.h tz_hash_prepend"+  tzHashPrepend :: Ptr () -> Ptr CChar -> CSize -> IO ()++foreign import ccall "tillich-zemor.h tz_hash_concat"+  tzHashConcat :: Ptr () -> Ptr () -> Ptr () -> IO ()++foreign import ccall "tillich-zemor.h tz_hash_serialize"+  tzHashSerialize :: Ptr () -> Ptr CChar -> IO ()++foreign import ccall "tillich-zemor.h tz_hash_unserialize"+  tzHashUnserialize :: Ptr () -> Ptr CChar -> IO ()++-- | Opaque representation of a 512 bit hash.+newtype Hash = H (ForeignPtr ())++tzHashSize = 64+tzHashLen = 86++withHashPtr :: Hash -> (Ptr () -> IO a) -> IO a+withHashPtr (H fp) = withForeignPtr fp++withHashPtr2 :: Hash -> Hash -> (Ptr () -> Ptr () -> IO a) -> IO a+withHashPtr2 a b f = withHashPtr a (withHashPtr b . f)++withHashPtrNew :: (Ptr () -> IO a) -> IO (Hash, a)+withHashPtrNew f = mallocForeignPtrBytes tzHashSize >>= \fp -> (\r -> (H fp, r)) <$> withForeignPtr fp f++withHashPtrCopy :: Hash -> (Ptr () -> IO a) -> IO (Hash, a)+withHashPtrCopy h f = withHashPtr h $ \hp -> withHashPtrNew $ \hp' -> copyBytes hp' hp tzHashSize >> f hp'++instance Show Hash where+  show h = unsafePerformIO $ allocaBytes tzHashLen $ \p -> withHashPtr h (flip tzHashSerialize p) >> peekCStringLen (p, tzHashLen)++instance Eq Hash where+  a == b = toBool $ unsafePerformIO $ withHashPtr2 a b tzHashEq++instance Monoid Hash where+  mempty = fst $ unsafePerformIO $ withHashPtrNew tzHashUnit+  mappend a b = fst $ unsafePerformIO $ withHashPtrNew (withHashPtr2 a b . tzHashConcat)++-- | /O(n)/ Calculate the hash of the 'ByteString'. Alias for @('mempty' '<+')@.+hash :: ByteString -> Hash+hash = (<+) mempty++-- | /O(n)/ Append the hash of the 'ByteString' to the existing 'Hash'.+-- A significantly faster equivalent of @(flip ('<>') . 'hash')@.+(<+) :: Hash -> ByteString -> Hash+(<+) h s = fst $ unsafePerformIO $ unsafeUseAsCStringLen s $ \(s', len) ->+  withHashPtrCopy h $ \hp -> tzHashAppend hp s' $ fromIntegral len++-- | /O(n)/ Prepend the hash of the 'ByteString' to the existing 'Hash'.+-- A significantly faster equivalent of @(('<>') . 'hash')@.+(+>) :: ByteString -> Hash -> Hash+(+>) s h = fst $ unsafePerformIO $ unsafeUseAsCStringLen s $ \(s', len) ->+  withHashPtrCopy h $ \hp -> tzHashPrepend hp s' $ fromIntegral len++-- | /O(1)/ Parse the representation generated by 'show'.+parse :: String -> Maybe Hash+parse s = (\(h, r) -> h <$ r) $ unsafePerformIO $ withHashPtrNew $ \hp -> withCAStringLen s $ \(s', len) ->+  if len == tzHashLen then Just <$> tzHashUnserialize hp s' else return Nothing
+ src/tillich-zemor.c view
@@ -0,0 +1,44 @@+#include "tillich-zemor.h"+#include "sl2-inl.h"++struct tz_hash_struct {+  sl2_t sl2;+};++int tz_hash_eq(tz_hash_t a, tz_hash_t b) {+  return sl2_eq(a->sl2, b->sl2);+}++void tz_hash_copy(tz_hash_t dst, tz_hash_t src) {+  sl2_copy(dst->sl2, src->sl2);+}++void tz_hash_unit(tz_hash_t h) {+  sl2_unit(h->sl2);+}++void tz_hash_append(tz_hash_t h, unsigned char *buf, size_t n) {+  size_t i;+  for (i = 0; i < n; i++) {+    sl2_mul_bits_right(h->sl2, buf[i]);+  }+}++void tz_hash_prepend(tz_hash_t h, unsigned char *buf, size_t n) {+  size_t i;+  for (i = n; i > 0; i--) {+    sl2_mul_bits_left(h->sl2, buf[i - 1]);+  }+}++void tz_hash_concat(tz_hash_t c, tz_hash_t a, tz_hash_t b) {+  sl2_mul(c->sl2, a->sl2, b->sl2);+}++void tz_hash_serialize(tz_hash_t h, unsigned char buf[86]) {+  sl2_serialize(h->sl2, buf);+}++void tz_hash_unserialize(tz_hash_t h, unsigned char buf[86]) {+  sl2_unserialize(h->sl2, buf);+}