merge cryptohash

This commit is contained in:
Vincent Hanquez 2014-07-07 14:55:55 +01:00
parent ec1a44881d
commit 09feb59f62
46 changed files with 6408 additions and 0 deletions

24
Crypto/Hash/Internal.hs Normal file
View File

@ -0,0 +1,24 @@
{-# LANGUAGE CPP #-}
-- |
-- Module : Crypto.Hash.Internal
-- License : BSD-style
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
-- Stability : experimental
-- Portability : unknown
module Crypto.Hash.Internal where
import System.IO.Unsafe
-- | perform io for hashes that do allocation and ffi.
-- unsafeDupablePerformIO is used when possible as the
-- computation is pure and the output is directly linked
-- to the input. we also do not modify anything after it has
-- been returned to the user.
unsafeDoIO :: IO a -> a
#if __GLASGOW_HASKELL__ > 704
unsafeDoIO = unsafeDupablePerformIO
#else
unsafeDoIO = unsafePerformIO
#endif

136
Crypto/Hash/MD2.hs Normal file
View File

@ -0,0 +1,136 @@
{-# LANGUAGE ForeignFunctionInterface #-}
-- |
-- Module : Crypto.Hash.MD2
-- License : BSD-style
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
-- Stability : experimental
-- Portability : unknown
--
-- module containing the basic functions to work with the
-- MD2 cryptographic hash.
--
module Crypto.Hash.MD2
( Ctx(..)
-- * Incremental hashing Functions
, init -- :: Ctx
, update -- :: Ctx -> ByteString -> Ctx
, updates -- :: Ctx -> [ByteString] -> Ctx
, finalize -- :: Ctx -> ByteString
-- * Single Pass hashing
, hash -- :: ByteString -> ByteString
, hashlazy -- :: ByteString -> ByteString
) where
import Prelude hiding (init)
import Foreign.Ptr
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Storable
import Foreign.Marshal.Alloc
import qualified Data.ByteString.Lazy as L
import Data.ByteString (ByteString)
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
import Data.ByteString.Internal (create, toForeignPtr)
import Data.Word
import Crypto.Hash.Internal (unsafeDoIO)
-- | MD2 Context.
newtype Ctx = Ctx ByteString
{-# INLINE digestSize #-}
digestSize :: Int
digestSize = 16
{-# INLINE sizeCtx #-}
sizeCtx :: Int
sizeCtx = 96
{-# RULES "hash" forall b. finalize (update init b) = hash b #-}
{-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-}
{-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-}
{-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-}
{-# INLINE withByteStringPtr #-}
withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
withByteStringPtr b f =
withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
where (fptr, off, _) = toForeignPtr b
{-# INLINE memcopy64 #-}
memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
memcopy64 dst src = mapM_ peekAndPoke [0..(12-1)]
where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
where createCtx = create sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
withCtxThrow (Ctx ctxB) f =
allocaBytes sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
foreign import ccall unsafe "cryptonite_md2.h cryptonite_md2_init"
c_md2_init :: Ptr Ctx -> IO ()
foreign import ccall "cryptonite_md2.h cryptonite_md2_update"
c_md2_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
foreign import ccall unsafe "cryptonite_md2.h cryptonite_md2_finalize"
c_md2_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
updateInternalIO ptr d =
unsafeUseAsCStringLen d (\(cs, len) -> c_md2_update ptr (castPtr cs) (fromIntegral len))
finalizeInternalIO :: Ptr Ctx -> IO ByteString
finalizeInternalIO ptr = create digestSize (c_md2_finalize ptr)
{-# NOINLINE init #-}
-- | init a context
init :: Ctx
init = unsafeDoIO $ withCtxNew $ c_md2_init
{-# NOINLINE update #-}
-- | update a context with a bytestring returning the new updated context
update :: Ctx -- ^ the context to update
-> ByteString -- ^ the data to update with
-> Ctx -- ^ the updated context
update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
{-# NOINLINE updates #-}
-- | updates a context with multiples bytestring returning the new updated context
updates :: Ctx -- ^ the context to update
-> [ByteString] -- ^ a list of data bytestring to update with
-> Ctx -- ^ the updated context
updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
{-# NOINLINE finalize #-}
-- | finalize the context into a digest bytestring
finalize :: Ctx -> ByteString
finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
{-# NOINLINE hash #-}
-- | hash a strict bytestring into a digest bytestring
hash :: ByteString -> ByteString
hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_md2_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr
{-# NOINLINE hashlazy #-}
-- | hash a lazy bytestring into a digest bytestring
hashlazy :: L.ByteString -> ByteString
hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_md2_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr

136
Crypto/Hash/MD4.hs Normal file
View File

@ -0,0 +1,136 @@
{-# LANGUAGE ForeignFunctionInterface #-}
-- |
-- Module : Crypto.Hash.MD4
-- License : BSD-style
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
-- Stability : experimental
-- Portability : unknown
--
-- module containing the basic functions to work with the
-- MD4 cryptographic hash.
--
module Crypto.Hash.MD4
( Ctx(..)
-- * Incremental hashing Functions
, init -- :: Ctx
, update -- :: Ctx -> ByteString -> Ctx
, updates -- :: Ctx -> [ByteString] -> Ctx
, finalize -- :: Ctx -> ByteString
-- * Single Pass hashing
, hash -- :: ByteString -> ByteString
, hashlazy -- :: ByteString -> ByteString
) where
import Prelude hiding (init)
import Foreign.Ptr
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Storable
import Foreign.Marshal.Alloc
import qualified Data.ByteString.Lazy as L
import Data.ByteString (ByteString)
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
import Data.ByteString.Internal (create, toForeignPtr)
import Data.Word
import Crypto.Hash.Internal (unsafeDoIO)
-- | MD4 Context.
newtype Ctx = Ctx ByteString
{-# INLINE digestSize #-}
digestSize :: Int
digestSize = 16
{-# INLINE sizeCtx #-}
sizeCtx :: Int
sizeCtx = 96
{-# RULES "hash" forall b. finalize (update init b) = hash b #-}
{-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-}
{-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-}
{-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-}
{-# INLINE withByteStringPtr #-}
withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
withByteStringPtr b f =
withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
where (fptr, off, _) = toForeignPtr b
{-# INLINE memcopy64 #-}
memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
memcopy64 dst src = mapM_ peekAndPoke [0..(12-1)]
where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
where createCtx = create sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
withCtxThrow (Ctx ctxB) f =
allocaBytes sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
foreign import ccall unsafe "cryptonite_md4.h cryptonite_md4_init"
c_md4_init :: Ptr Ctx -> IO ()
foreign import ccall "cryptonite_md4.h cryptonite_md4_update"
c_md4_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
foreign import ccall unsafe "cryptonite_md4.h cryptonite_md4_finalize"
c_md4_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
updateInternalIO ptr d =
unsafeUseAsCStringLen d (\(cs, len) -> c_md4_update ptr (castPtr cs) (fromIntegral len))
finalizeInternalIO :: Ptr Ctx -> IO ByteString
finalizeInternalIO ptr = create digestSize (c_md4_finalize ptr)
{-# NOINLINE init #-}
-- | init a context
init :: Ctx
init = unsafeDoIO $ withCtxNew $ c_md4_init
{-# NOINLINE update #-}
-- | update a context with a bytestring returning the new updated context
update :: Ctx -- ^ the context to update
-> ByteString -- ^ the data to update with
-> Ctx -- ^ the updated context
update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
{-# NOINLINE updates #-}
-- | updates a context with multiples bytestring returning the new updated context
updates :: Ctx -- ^ the context to update
-> [ByteString] -- ^ a list of data bytestring to update with
-> Ctx -- ^ the updated context
updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
{-# NOINLINE finalize #-}
-- | finalize the context into a digest bytestring
finalize :: Ctx -> ByteString
finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
{-# NOINLINE hash #-}
-- | hash a strict bytestring into a digest bytestring
hash :: ByteString -> ByteString
hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_md4_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr
{-# NOINLINE hashlazy #-}
-- | hash a lazy bytestring into a digest bytestring
hashlazy :: L.ByteString -> ByteString
hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_md4_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr

136
Crypto/Hash/MD5.hs Normal file
View File

@ -0,0 +1,136 @@
{-# LANGUAGE ForeignFunctionInterface #-}
-- |
-- Module : Crypto.Hash.MD5
-- License : BSD-style
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
-- Stability : experimental
-- Portability : unknown
--
-- module containing the basic functions to work with the
-- MD5 cryptographic hash.
--
module Crypto.Hash.MD5
( Ctx(..)
-- * Incremental hashing Functions
, init -- :: Ctx
, update -- :: Ctx -> ByteString -> Ctx
, updates -- :: Ctx -> [ByteString] -> Ctx
, finalize -- :: Ctx -> ByteString
-- * Single Pass hashing
, hash -- :: ByteString -> ByteString
, hashlazy -- :: ByteString -> ByteString
) where
import Prelude hiding (init)
import Foreign.Ptr
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Storable
import Foreign.Marshal.Alloc
import qualified Data.ByteString.Lazy as L
import Data.ByteString (ByteString)
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
import Data.ByteString.Internal (create, toForeignPtr)
import Data.Word
import Crypto.Hash.Internal (unsafeDoIO)
-- | MD5 Context.
newtype Ctx = Ctx ByteString
{-# INLINE digestSize #-}
digestSize :: Int
digestSize = 16
{-# INLINE sizeCtx #-}
sizeCtx :: Int
sizeCtx = 96
{-# RULES "hash" forall b. finalize (update init b) = hash b #-}
{-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-}
{-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-}
{-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-}
{-# INLINE withByteStringPtr #-}
withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
withByteStringPtr b f =
withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
where (fptr, off, _) = toForeignPtr b
{-# INLINE memcopy64 #-}
memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
memcopy64 dst src = mapM_ peekAndPoke [0..(12-1)]
where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
where createCtx = create sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
withCtxThrow (Ctx ctxB) f =
allocaBytes sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
foreign import ccall unsafe "cryptonite_md5.h cryptonite_md5_init"
c_md5_init :: Ptr Ctx -> IO ()
foreign import ccall "cryptonite_md5.h cryptonite_md5_update"
c_md5_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
foreign import ccall unsafe "cryptonite_md5.h cryptonite_md5_finalize"
c_md5_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
updateInternalIO ptr d =
unsafeUseAsCStringLen d (\(cs, len) -> c_md5_update ptr (castPtr cs) (fromIntegral len))
finalizeInternalIO :: Ptr Ctx -> IO ByteString
finalizeInternalIO ptr = create digestSize (c_md5_finalize ptr)
{-# NOINLINE init #-}
-- | init a context
init :: Ctx
init = unsafeDoIO $ withCtxNew $ c_md5_init
{-# NOINLINE update #-}
-- | update a context with a bytestring returning the new updated context
update :: Ctx -- ^ the context to update
-> ByteString -- ^ the data to update with
-> Ctx -- ^ the updated context
update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
{-# NOINLINE updates #-}
-- | updates a context with multiples bytestring returning the new updated context
updates :: Ctx -- ^ the context to update
-> [ByteString] -- ^ a list of data bytestring to update with
-> Ctx -- ^ the updated context
updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
{-# NOINLINE finalize #-}
-- | finalize the context into a digest bytestring
finalize :: Ctx -> ByteString
finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
{-# NOINLINE hash #-}
-- | hash a strict bytestring into a digest bytestring
hash :: ByteString -> ByteString
hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_md5_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr
{-# NOINLINE hashlazy #-}
-- | hash a lazy bytestring into a digest bytestring
hashlazy :: L.ByteString -> ByteString
hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_md5_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr

136
Crypto/Hash/RIPEMD160.hs Normal file
View File

@ -0,0 +1,136 @@
{-# LANGUAGE ForeignFunctionInterface #-}
-- |
-- Module : Crypto.Hash.RIPEMD160
-- License : BSD-style
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
-- Stability : experimental
-- Portability : unknown
--
-- module containing the basic functions to work with the
-- RIPEMD160 cryptographic hash.
--
module Crypto.Hash.RIPEMD160
( Ctx(..)
-- * Incremental hashing Functions
, init -- :: Ctx
, update -- :: Ctx -> ByteString -> Ctx
, updates -- :: Ctx -> [ByteString] -> Ctx
, finalize -- :: Ctx -> ByteString
-- * Single Pass hashing
, hash -- :: ByteString -> ByteString
, hashlazy -- :: ByteString -> ByteString
) where
import Prelude hiding (init)
import Foreign.Ptr
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Storable
import Foreign.Marshal.Alloc
import qualified Data.ByteString.Lazy as L
import Data.ByteString (ByteString)
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
import Data.ByteString.Internal (create, toForeignPtr)
import Data.Word
import Crypto.Hash.Internal (unsafeDoIO)
-- | RIPEMD160 Context.
newtype Ctx = Ctx ByteString
{-# INLINE digestSize #-}
digestSize :: Int
digestSize = 20
{-# INLINE sizeCtx #-}
sizeCtx :: Int
sizeCtx = 128
{-# RULES "hash" forall b. finalize (update init b) = hash b #-}
{-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-}
{-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-}
{-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-}
{-# INLINE withByteStringPtr #-}
withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
withByteStringPtr b f =
withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
where (fptr, off, _) = toForeignPtr b
{-# INLINE memcopy64 #-}
memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
memcopy64 dst src = mapM_ peekAndPoke [0..(16-1)]
where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
where createCtx = create sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
withCtxThrow (Ctx ctxB) f =
allocaBytes sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
foreign import ccall unsafe "cryptonite_ripemd.h cryptonite_ripemd160_init"
c_ripemd160_init :: Ptr Ctx -> IO ()
foreign import ccall "cryptonite_ripemd.h cryptonite_ripemd160_update"
c_ripemd160_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
foreign import ccall unsafe "cryptonite_ripemd.h cryptonite_ripemd160_finalize"
c_ripemd160_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
updateInternalIO ptr d =
unsafeUseAsCStringLen d (\(cs, len) -> c_ripemd160_update ptr (castPtr cs) (fromIntegral len))
finalizeInternalIO :: Ptr Ctx -> IO ByteString
finalizeInternalIO ptr = create digestSize (c_ripemd160_finalize ptr)
{-# NOINLINE init #-}
-- | init a context
init :: Ctx
init = unsafeDoIO $ withCtxNew $ c_ripemd160_init
{-# NOINLINE update #-}
-- | update a context with a bytestring returning the new updated context
update :: Ctx -- ^ the context to update
-> ByteString -- ^ the data to update with
-> Ctx -- ^ the updated context
update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
{-# NOINLINE updates #-}
-- | updates a context with multiples bytestring returning the new updated context
updates :: Ctx -- ^ the context to update
-> [ByteString] -- ^ a list of data bytestring to update with
-> Ctx -- ^ the updated context
updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
{-# NOINLINE finalize #-}
-- | finalize the context into a digest bytestring
finalize :: Ctx -> ByteString
finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
{-# NOINLINE hash #-}
-- | hash a strict bytestring into a digest bytestring
hash :: ByteString -> ByteString
hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_ripemd160_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr
{-# NOINLINE hashlazy #-}
-- | hash a lazy bytestring into a digest bytestring
hashlazy :: L.ByteString -> ByteString
hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_ripemd160_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr

136
Crypto/Hash/SHA1.hs Normal file
View File

@ -0,0 +1,136 @@
{-# LANGUAGE ForeignFunctionInterface #-}
-- |
-- Module : Crypto.Hash.SHA1
-- License : BSD-style
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
-- Stability : experimental
-- Portability : unknown
--
-- module containing the basic functions to work with the
-- SHA1 cryptographic hash.
--
module Crypto.Hash.SHA1
( Ctx(..)
-- * Incremental hashing Functions
, init -- :: Ctx
, update -- :: Ctx -> ByteString -> Ctx
, updates -- :: Ctx -> [ByteString] -> Ctx
, finalize -- :: Ctx -> ByteString
-- * Single Pass hashing
, hash -- :: ByteString -> ByteString
, hashlazy -- :: ByteString -> ByteString
) where
import Prelude hiding (init)
import Foreign.Ptr
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Storable
import Foreign.Marshal.Alloc
import qualified Data.ByteString.Lazy as L
import Data.ByteString (ByteString)
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
import Data.ByteString.Internal (create, toForeignPtr)
import Data.Word
import Crypto.Hash.Internal (unsafeDoIO)
-- | SHA1 Context.
newtype Ctx = Ctx ByteString
{-# INLINE digestSize #-}
digestSize :: Int
digestSize = 20
{-# INLINE sizeCtx #-}
sizeCtx :: Int
sizeCtx = 96
{-# RULES "hash" forall b. finalize (update init b) = hash b #-}
{-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-}
{-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-}
{-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-}
{-# INLINE withByteStringPtr #-}
withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
withByteStringPtr b f =
withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
where (fptr, off, _) = toForeignPtr b
{-# INLINE memcopy64 #-}
memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
memcopy64 dst src = mapM_ peekAndPoke [0..(12-1)]
where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
where createCtx = create sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
withCtxThrow (Ctx ctxB) f =
allocaBytes sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
foreign import ccall unsafe "cryptonite_sha1.h cryptonite_sha1_init"
c_sha1_init :: Ptr Ctx -> IO ()
foreign import ccall "cryptonite_sha1.h cryptonite_sha1_update"
c_sha1_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
foreign import ccall unsafe "cryptonite_sha1.h cryptonite_sha1_finalize"
c_sha1_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
updateInternalIO ptr d =
unsafeUseAsCStringLen d (\(cs, len) -> c_sha1_update ptr (castPtr cs) (fromIntegral len))
finalizeInternalIO :: Ptr Ctx -> IO ByteString
finalizeInternalIO ptr = create digestSize (c_sha1_finalize ptr)
{-# NOINLINE init #-}
-- | init a context
init :: Ctx
init = unsafeDoIO $ withCtxNew $ c_sha1_init
{-# NOINLINE update #-}
-- | update a context with a bytestring returning the new updated context
update :: Ctx -- ^ the context to update
-> ByteString -- ^ the data to update with
-> Ctx -- ^ the updated context
update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
{-# NOINLINE updates #-}
-- | updates a context with multiples bytestring returning the new updated context
updates :: Ctx -- ^ the context to update
-> [ByteString] -- ^ a list of data bytestring to update with
-> Ctx -- ^ the updated context
updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
{-# NOINLINE finalize #-}
-- | finalize the context into a digest bytestring
finalize :: Ctx -> ByteString
finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
{-# NOINLINE hash #-}
-- | hash a strict bytestring into a digest bytestring
hash :: ByteString -> ByteString
hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_sha1_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr
{-# NOINLINE hashlazy #-}
-- | hash a lazy bytestring into a digest bytestring
hashlazy :: L.ByteString -> ByteString
hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_sha1_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr

136
Crypto/Hash/SHA224.hs Normal file
View File

@ -0,0 +1,136 @@
{-# LANGUAGE ForeignFunctionInterface #-}
-- |
-- Module : Crypto.Hash.SHA224
-- License : BSD-style
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
-- Stability : experimental
-- Portability : unknown
--
-- module containing the basic functions to work with the
-- SHA224 cryptographic hash.
--
module Crypto.Hash.SHA224
( Ctx(..)
-- * Incremental hashing Functions
, init -- :: Ctx
, update -- :: Ctx -> ByteString -> Ctx
, updates -- :: Ctx -> [ByteString] -> Ctx
, finalize -- :: Ctx -> ByteString
-- * Single Pass hashing
, hash -- :: ByteString -> ByteString
, hashlazy -- :: ByteString -> ByteString
) where
import Prelude hiding (init)
import Foreign.Ptr
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Storable
import Foreign.Marshal.Alloc
import qualified Data.ByteString.Lazy as L
import Data.ByteString (ByteString)
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
import Data.ByteString.Internal (create, toForeignPtr)
import Data.Word
import Crypto.Hash.Internal (unsafeDoIO)
-- | SHA224 Context.
newtype Ctx = Ctx ByteString
{-# INLINE digestSize #-}
digestSize :: Int
digestSize = 28
{-# INLINE sizeCtx #-}
sizeCtx :: Int
sizeCtx = 192
{-# RULES "hash" forall b. finalize (update init b) = hash b #-}
{-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-}
{-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-}
{-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-}
{-# INLINE withByteStringPtr #-}
withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
withByteStringPtr b f =
withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
where (fptr, off, _) = toForeignPtr b
{-# INLINE memcopy64 #-}
memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
memcopy64 dst src = mapM_ peekAndPoke [0..(24-1)]
where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
where createCtx = create sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
withCtxThrow (Ctx ctxB) f =
allocaBytes sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
foreign import ccall unsafe "cryptonite_sha256.h cryptonite_sha224_init"
c_sha224_init :: Ptr Ctx -> IO ()
foreign import ccall "cryptonite_sha256.h cryptonite_sha224_update"
c_sha224_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
foreign import ccall unsafe "cryptonite_sha256.h cryptonite_sha224_finalize"
c_sha224_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
updateInternalIO ptr d =
unsafeUseAsCStringLen d (\(cs, len) -> c_sha224_update ptr (castPtr cs) (fromIntegral len))
finalizeInternalIO :: Ptr Ctx -> IO ByteString
finalizeInternalIO ptr = create digestSize (c_sha224_finalize ptr)
{-# NOINLINE init #-}
-- | init a context
init :: Ctx
init = unsafeDoIO $ withCtxNew $ c_sha224_init
{-# NOINLINE update #-}
-- | update a context with a bytestring returning the new updated context
update :: Ctx -- ^ the context to update
-> ByteString -- ^ the data to update with
-> Ctx -- ^ the updated context
update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
{-# NOINLINE updates #-}
-- | updates a context with multiples bytestring returning the new updated context
updates :: Ctx -- ^ the context to update
-> [ByteString] -- ^ a list of data bytestring to update with
-> Ctx -- ^ the updated context
updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
{-# NOINLINE finalize #-}
-- | finalize the context into a digest bytestring
finalize :: Ctx -> ByteString
finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
{-# NOINLINE hash #-}
-- | hash a strict bytestring into a digest bytestring
hash :: ByteString -> ByteString
hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_sha224_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr
{-# NOINLINE hashlazy #-}
-- | hash a lazy bytestring into a digest bytestring
hashlazy :: L.ByteString -> ByteString
hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_sha224_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr

136
Crypto/Hash/SHA256.hs Normal file
View File

@ -0,0 +1,136 @@
{-# LANGUAGE ForeignFunctionInterface #-}
-- |
-- Module : Crypto.Hash.SHA256
-- License : BSD-style
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
-- Stability : experimental
-- Portability : unknown
--
-- module containing the basic functions to work with the
-- SHA256 cryptographic hash.
--
module Crypto.Hash.SHA256
( Ctx(..)
-- * Incremental hashing Functions
, init -- :: Ctx
, update -- :: Ctx -> ByteString -> Ctx
, updates -- :: Ctx -> [ByteString] -> Ctx
, finalize -- :: Ctx -> ByteString
-- * Single Pass hashing
, hash -- :: ByteString -> ByteString
, hashlazy -- :: ByteString -> ByteString
) where
import Prelude hiding (init)
import Foreign.Ptr
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Storable
import Foreign.Marshal.Alloc
import qualified Data.ByteString.Lazy as L
import Data.ByteString (ByteString)
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
import Data.ByteString.Internal (create, toForeignPtr)
import Data.Word
import Crypto.Hash.Internal (unsafeDoIO)
-- | SHA256 Context.
newtype Ctx = Ctx ByteString
{-# INLINE digestSize #-}
digestSize :: Int
digestSize = 32
{-# INLINE sizeCtx #-}
sizeCtx :: Int
sizeCtx = 192
{-# RULES "hash" forall b. finalize (update init b) = hash b #-}
{-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-}
{-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-}
{-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-}
{-# INLINE withByteStringPtr #-}
withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
withByteStringPtr b f =
withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
where (fptr, off, _) = toForeignPtr b
{-# INLINE memcopy64 #-}
memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
memcopy64 dst src = mapM_ peekAndPoke [0..(24-1)]
where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
where createCtx = create sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
withCtxThrow (Ctx ctxB) f =
allocaBytes sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
foreign import ccall unsafe "cryptonite_sha256.h cryptonite_sha256_init"
c_sha256_init :: Ptr Ctx -> IO ()
foreign import ccall "cryptonite_sha256.h cryptonite_sha256_update"
c_sha256_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
foreign import ccall unsafe "cryptonite_sha256.h cryptonite_sha256_finalize"
c_sha256_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
updateInternalIO ptr d =
unsafeUseAsCStringLen d (\(cs, len) -> c_sha256_update ptr (castPtr cs) (fromIntegral len))
finalizeInternalIO :: Ptr Ctx -> IO ByteString
finalizeInternalIO ptr = create digestSize (c_sha256_finalize ptr)
{-# NOINLINE init #-}
-- | init a context
init :: Ctx
init = unsafeDoIO $ withCtxNew $ c_sha256_init
{-# NOINLINE update #-}
-- | update a context with a bytestring returning the new updated context
update :: Ctx -- ^ the context to update
-> ByteString -- ^ the data to update with
-> Ctx -- ^ the updated context
update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
{-# NOINLINE updates #-}
-- | updates a context with multiples bytestring returning the new updated context
updates :: Ctx -- ^ the context to update
-> [ByteString] -- ^ a list of data bytestring to update with
-> Ctx -- ^ the updated context
updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
{-# NOINLINE finalize #-}
-- | finalize the context into a digest bytestring
finalize :: Ctx -> ByteString
finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
{-# NOINLINE hash #-}
-- | hash a strict bytestring into a digest bytestring
hash :: ByteString -> ByteString
hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_sha256_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr
{-# NOINLINE hashlazy #-}
-- | hash a lazy bytestring into a digest bytestring
hashlazy :: L.ByteString -> ByteString
hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_sha256_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr

144
Crypto/Hash/SHA3.hs Normal file
View File

@ -0,0 +1,144 @@
{-# LANGUAGE ForeignFunctionInterface #-}
-- |
-- Module : Crypto.Hash.SHA3
-- License : BSD-style
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
-- Stability : experimental
-- Portability : unknown
--
-- module containing the basic functions to work with the
-- SHA3 cryptographic hash.
--
module Crypto.Hash.SHA3
( Ctx(..)
-- * Incremental hashing Functions
, init -- :: Int -> Ctx
, update -- :: Ctx -> ByteString -> Ctx
, updates -- :: Ctx -> [ByteString] -> Ctx
, finalize -- :: Ctx -> ByteString
-- * Single Pass hashing
, hash -- :: Int -> ByteString -> ByteString
, hashlazy -- :: Int -> ByteString -> ByteString
) where
import Prelude hiding (init)
import Foreign.Ptr
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Storable
import Foreign.Marshal.Alloc
import qualified Data.ByteString.Lazy as L
import Data.ByteString (ByteString)
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
import Data.ByteString.Internal (create, toForeignPtr)
import Data.Word
import Crypto.Hash.Internal (unsafeDoIO)
-- | SHA3 Context.
newtype Ctx = Ctx ByteString
{-# INLINE sizeCtx #-}
sizeCtx :: Int
sizeCtx = 360
{- return the number of bytes of output for the digest -}
peekHashlen :: Ptr Ctx -> IO Int
peekHashlen ptr = peek iptr >>= \v -> return $! fromIntegral v
where iptr :: Ptr Word32
iptr = castPtr ptr
{-# RULES "hash" forall b i. finalize (update (init i) b) = hash i b #-}
{-# RULES "hash.list1" forall b i. finalize (updates (init i) [b]) = hash i b #-}
{-# RULES "hashmany" forall b i. finalize (foldl update (init i) b) = hashlazy i (L.fromChunks b) #-}
{-# RULES "hashlazy" forall b i. finalize (foldl update (init i) $ L.toChunks b) = hashlazy i b #-}
{-# INLINE withByteStringPtr #-}
withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
withByteStringPtr b f =
withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
where (fptr, off, _) = toForeignPtr b
{-# INLINE memcopy64 #-}
memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
memcopy64 dst src = mapM_ peekAndPoke [0..(45-1)]
where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
where createCtx = create sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
withCtxThrow (Ctx ctxB) f =
allocaBytes sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
foreign import ccall unsafe "cryptonite_sha3.h cryptonite_sha3_init"
c_sha3_init :: Ptr Ctx -> Word32 -> IO ()
foreign import ccall "cryptonite_sha3.h cryptonite_sha3_update"
c_sha3_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
foreign import ccall unsafe "cryptonite_sha3.h cryptonite_sha3_finalize"
c_sha3_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
updateInternalIO ptr d =
unsafeUseAsCStringLen d (\(cs, len) -> c_sha3_update ptr (castPtr cs) (fromIntegral len))
finalizeInternalIO :: Ptr Ctx -> IO ByteString
finalizeInternalIO ptr =
peekHashlen ptr >>= \digestSize -> create digestSize (c_sha3_finalize ptr)
{-# NOINLINE init #-}
-- | init a context where
init :: Int -- ^ algorithm hash size in bits
-> Ctx
init hashlen = unsafeDoIO $ withCtxNew $ \ptr -> c_sha3_init ptr (fromIntegral hashlen)
{-# NOINLINE update #-}
-- | update a context with a bytestring returning the new updated context
update :: Ctx -- ^ the context to update
-> ByteString -- ^ the data to update with
-> Ctx -- ^ the updated context
update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
{-# NOINLINE updates #-}
-- | updates a context with multiples bytestring returning the new updated context
updates :: Ctx -- ^ the context to update
-> [ByteString] -- ^ a list of data bytestring to update with
-> Ctx -- ^ the updated context
updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
{-# NOINLINE finalize #-}
-- | finalize the context into a digest bytestring
finalize :: Ctx -> ByteString
finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
{-# NOINLINE hash #-}
-- | hash a strict bytestring into a digest bytestring
hash :: Int -- ^ algorithm hash size in bits
-> ByteString -- ^ the data to hash
-> ByteString -- ^ the digest output
hash hashlen d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_sha3_init ptr (fromIntegral hashlen) >> updateInternalIO ptr d >> finalizeInternalIO ptr
{-# NOINLINE hashlazy #-}
-- | hash a lazy bytestring into a digest bytestring
hashlazy :: Int -- ^ algorithm hash size in bits
-> L.ByteString -- ^ the data to hash as a lazy bytestring
-> ByteString -- ^ the digest output
hashlazy hashlen l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_sha3_init ptr (fromIntegral hashlen) >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr

136
Crypto/Hash/SHA384.hs Normal file
View File

@ -0,0 +1,136 @@
{-# LANGUAGE ForeignFunctionInterface #-}
-- |
-- Module : Crypto.Hash.SHA384
-- License : BSD-style
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
-- Stability : experimental
-- Portability : unknown
--
-- module containing the basic functions to work with the
-- SHA384 cryptographic hash.
--
module Crypto.Hash.SHA384
( Ctx(..)
-- * Incremental hashing Functions
, init -- :: Ctx
, update -- :: Ctx -> ByteString -> Ctx
, updates -- :: Ctx -> [ByteString] -> Ctx
, finalize -- :: Ctx -> ByteString
-- * Single Pass hashing
, hash -- :: ByteString -> ByteString
, hashlazy -- :: ByteString -> ByteString
) where
import Prelude hiding (init)
import Foreign.Ptr
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Storable
import Foreign.Marshal.Alloc
import qualified Data.ByteString.Lazy as L
import Data.ByteString (ByteString)
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
import Data.ByteString.Internal (create, toForeignPtr)
import Data.Word
import Crypto.Hash.Internal (unsafeDoIO)
-- | SHA384 Context.
newtype Ctx = Ctx ByteString
{-# INLINE digestSize #-}
digestSize :: Int
digestSize = 48
{-# INLINE sizeCtx #-}
sizeCtx :: Int
sizeCtx = 256
{-# RULES "hash" forall b. finalize (update init b) = hash b #-}
{-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-}
{-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-}
{-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-}
{-# INLINE withByteStringPtr #-}
withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
withByteStringPtr b f =
withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
where (fptr, off, _) = toForeignPtr b
{-# INLINE memcopy64 #-}
memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
memcopy64 dst src = mapM_ peekAndPoke [0..(32-1)]
where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
where createCtx = create sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
withCtxThrow (Ctx ctxB) f =
allocaBytes sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
foreign import ccall unsafe "cryptonite_sha512.h cryptonite_sha384_init"
c_sha384_init :: Ptr Ctx -> IO ()
foreign import ccall "cryptonite_sha512.h cryptonite_sha384_update"
c_sha384_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
foreign import ccall unsafe "cryptonite_sha512.h cryptonite_sha384_finalize"
c_sha384_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
updateInternalIO ptr d =
unsafeUseAsCStringLen d (\(cs, len) -> c_sha384_update ptr (castPtr cs) (fromIntegral len))
finalizeInternalIO :: Ptr Ctx -> IO ByteString
finalizeInternalIO ptr = create digestSize (c_sha384_finalize ptr)
{-# NOINLINE init #-}
-- | init a context
init :: Ctx
init = unsafeDoIO $ withCtxNew $ c_sha384_init
{-# NOINLINE update #-}
-- | update a context with a bytestring returning the new updated context
update :: Ctx -- ^ the context to update
-> ByteString -- ^ the data to update with
-> Ctx -- ^ the updated context
update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
{-# NOINLINE updates #-}
-- | updates a context with multiples bytestring returning the new updated context
updates :: Ctx -- ^ the context to update
-> [ByteString] -- ^ a list of data bytestring to update with
-> Ctx -- ^ the updated context
updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
{-# NOINLINE finalize #-}
-- | finalize the context into a digest bytestring
finalize :: Ctx -> ByteString
finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
{-# NOINLINE hash #-}
-- | hash a strict bytestring into a digest bytestring
hash :: ByteString -> ByteString
hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_sha384_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr
{-# NOINLINE hashlazy #-}
-- | hash a lazy bytestring into a digest bytestring
hashlazy :: L.ByteString -> ByteString
hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_sha384_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr

145
Crypto/Hash/SHA512.hs Normal file
View File

@ -0,0 +1,145 @@
{-# LANGUAGE ForeignFunctionInterface #-}
-- |
-- Module : Crypto.Hash.SHA512
-- License : BSD-style
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
-- Stability : experimental
-- Portability : unknown
--
-- module containing the basic functions to work with the
-- SHA512 cryptographic hash.
--
module Crypto.Hash.SHA512
( Ctx(..)
-- * Incremental hashing Functions
, init -- :: Ctx
, init_t -- :: Int -> Ctx
, update -- :: Ctx -> ByteString -> Ctx
, updates -- :: Ctx -> [ByteString] -> Ctx
, finalize -- :: Ctx -> ByteString
-- * Single Pass hashing
, hash -- :: ByteString -> ByteString
, hashlazy -- :: ByteString -> ByteString
) where
import Prelude hiding (init)
import Foreign.Ptr
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Storable
import Foreign.Marshal.Alloc
import qualified Data.ByteString.Lazy as L
import Data.ByteString (ByteString)
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
import Data.ByteString.Internal (create, toForeignPtr)
import Data.Word
import Crypto.Hash.Internal (unsafeDoIO)
-- | SHA512 Context.
newtype Ctx = Ctx ByteString
{-# INLINE digestSize #-}
digestSize :: Int
digestSize = 64
{-# INLINE sizeCtx #-}
sizeCtx :: Int
sizeCtx = 256
{-# RULES "hash" forall b. finalize (update init b) = hash b #-}
{-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-}
{-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-}
{-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-}
{-# INLINE withByteStringPtr #-}
withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
withByteStringPtr b f =
withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
where (fptr, off, _) = toForeignPtr b
{-# INLINE memcopy64 #-}
memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
memcopy64 dst src = mapM_ peekAndPoke [0..(32-1)]
where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
where createCtx = create sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
withCtxThrow (Ctx ctxB) f =
allocaBytes sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
foreign import ccall unsafe "cryptonite_sha512.h cryptonite_sha512_init"
c_sha512_init :: Ptr Ctx -> IO ()
foreign import ccall "cryptonite_sha512.h cryptonite_sha512_update"
c_sha512_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
foreign import ccall unsafe "cryptonite_sha512.h cryptonite_sha512_finalize"
c_sha512_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
foreign import ccall unsafe "cryptonite_sha512.h cryptonite_sha512_init_t"
c_sha512_init_t :: Ptr Ctx -> Int -> IO ()
{-# NOINLINE init_t #-}
-- | init a context using FIPS 180-4 for truncated SHA512
init_t :: Int -> Ctx
init_t t = unsafeDoIO $ withCtxNew $ \ptr -> c_sha512_init_t ptr t
updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
updateInternalIO ptr d =
unsafeUseAsCStringLen d (\(cs, len) -> c_sha512_update ptr (castPtr cs) (fromIntegral len))
finalizeInternalIO :: Ptr Ctx -> IO ByteString
finalizeInternalIO ptr = create digestSize (c_sha512_finalize ptr)
{-# NOINLINE init #-}
-- | init a context
init :: Ctx
init = unsafeDoIO $ withCtxNew $ c_sha512_init
{-# NOINLINE update #-}
-- | update a context with a bytestring returning the new updated context
update :: Ctx -- ^ the context to update
-> ByteString -- ^ the data to update with
-> Ctx -- ^ the updated context
update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
{-# NOINLINE updates #-}
-- | updates a context with multiples bytestring returning the new updated context
updates :: Ctx -- ^ the context to update
-> [ByteString] -- ^ a list of data bytestring to update with
-> Ctx -- ^ the updated context
updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
{-# NOINLINE finalize #-}
-- | finalize the context into a digest bytestring
finalize :: Ctx -> ByteString
finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
{-# NOINLINE hash #-}
-- | hash a strict bytestring into a digest bytestring
hash :: ByteString -> ByteString
hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_sha512_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr
{-# NOINLINE hashlazy #-}
-- | hash a lazy bytestring into a digest bytestring
hashlazy :: L.ByteString -> ByteString
hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_sha512_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr

52
Crypto/Hash/SHA512t.hs Normal file
View File

@ -0,0 +1,52 @@
-- |
-- Module : Crypto.Hash.SHA512t
-- License : BSD-style
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
-- Stability : experimental
-- Portability : unknown
--
-- A module containing SHA512/t
--
module Crypto.Hash.SHA512t
( Ctx(..)
-- * Incremental hashing Functions
, init -- :: Ctx
, update -- :: Ctx -> ByteString -> Ctx
, finalize -- :: Ctx -> ByteString
-- * Single Pass hashing
, hash -- :: ByteString -> ByteString
, hashlazy -- :: ByteString -> ByteString
) where
import Prelude hiding (init)
import Data.List (foldl')
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as L
import qualified Crypto.Hash.SHA512 as SHA512
-- | SHA512 Context with variable size output
data Ctx = Ctx !Int !SHA512.Ctx
-- | init a context
init :: Int -> Ctx
init t = Ctx t (SHA512.init_t t)
-- | update a context with a bytestring
update :: Ctx -> ByteString -> Ctx
update (Ctx t ctx) d = Ctx t (SHA512.update ctx d)
-- | finalize the context into a digest bytestring
finalize :: Ctx -> ByteString
finalize (Ctx sz ctx) = B.take (sz `div` 8) (SHA512.finalize ctx)
-- | hash a strict bytestring into a digest bytestring
hash :: Int -> ByteString -> ByteString
hash t = finalize . update (init t)
-- | hash a lazy bytestring into a digest bytestring
hashlazy :: Int -> L.ByteString -> ByteString
hashlazy t = finalize . foldl' update (init t) . L.toChunks

144
Crypto/Hash/Skein256.hs Normal file
View File

@ -0,0 +1,144 @@
{-# LANGUAGE ForeignFunctionInterface #-}
-- |
-- Module : Crypto.Hash.Skein256
-- License : BSD-style
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
-- Stability : experimental
-- Portability : unknown
--
-- module containing the basic functions to work with the
-- Skein256 cryptographic hash.
--
module Crypto.Hash.Skein256
( Ctx(..)
-- * Incremental hashing Functions
, init -- :: Int -> Ctx
, update -- :: Ctx -> ByteString -> Ctx
, updates -- :: Ctx -> [ByteString] -> Ctx
, finalize -- :: Ctx -> ByteString
-- * Single Pass hashing
, hash -- :: Int -> ByteString -> ByteString
, hashlazy -- :: Int -> ByteString -> ByteString
) where
import Prelude hiding (init)
import Foreign.Ptr
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Storable
import Foreign.Marshal.Alloc
import qualified Data.ByteString.Lazy as L
import Data.ByteString (ByteString)
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
import Data.ByteString.Internal (create, toForeignPtr)
import Data.Word
import Crypto.Hash.Internal (unsafeDoIO)
-- | Skein256 Context.
newtype Ctx = Ctx ByteString
{-# INLINE sizeCtx #-}
sizeCtx :: Int
sizeCtx = 96
{- return the number of bytes of output for the digest -}
peekHashlen :: Ptr Ctx -> IO Int
peekHashlen ptr = peek iptr >>= \v -> return $! fromIntegral v
where iptr :: Ptr Word32
iptr = castPtr ptr
{-# RULES "hash" forall b i. finalize (update (init i) b) = hash i b #-}
{-# RULES "hash.list1" forall b i. finalize (updates (init i) [b]) = hash i b #-}
{-# RULES "hashmany" forall b i. finalize (foldl update (init i) b) = hashlazy i (L.fromChunks b) #-}
{-# RULES "hashlazy" forall b i. finalize (foldl update (init i) $ L.toChunks b) = hashlazy i b #-}
{-# INLINE withByteStringPtr #-}
withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
withByteStringPtr b f =
withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
where (fptr, off, _) = toForeignPtr b
{-# INLINE memcopy64 #-}
memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
memcopy64 dst src = mapM_ peekAndPoke [0..(12-1)]
where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
where createCtx = create sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
withCtxThrow (Ctx ctxB) f =
allocaBytes sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
foreign import ccall unsafe "cryptonite_skein256.h cryptonite_skein256_init"
c_skein256_init :: Ptr Ctx -> Word32 -> IO ()
foreign import ccall "cryptonite_skein256.h cryptonite_skein256_update"
c_skein256_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
foreign import ccall unsafe "cryptonite_skein256.h cryptonite_skein256_finalize"
c_skein256_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
updateInternalIO ptr d =
unsafeUseAsCStringLen d (\(cs, len) -> c_skein256_update ptr (castPtr cs) (fromIntegral len))
finalizeInternalIO :: Ptr Ctx -> IO ByteString
finalizeInternalIO ptr =
peekHashlen ptr >>= \digestSize -> create digestSize (c_skein256_finalize ptr)
{-# NOINLINE init #-}
-- | init a context where
init :: Int -- ^ algorithm hash size in bits
-> Ctx
init hashlen = unsafeDoIO $ withCtxNew $ \ptr -> c_skein256_init ptr (fromIntegral hashlen)
{-# NOINLINE update #-}
-- | update a context with a bytestring returning the new updated context
update :: Ctx -- ^ the context to update
-> ByteString -- ^ the data to update with
-> Ctx -- ^ the updated context
update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
{-# NOINLINE updates #-}
-- | updates a context with multiples bytestring returning the new updated context
updates :: Ctx -- ^ the context to update
-> [ByteString] -- ^ a list of data bytestring to update with
-> Ctx -- ^ the updated context
updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
{-# NOINLINE finalize #-}
-- | finalize the context into a digest bytestring
finalize :: Ctx -> ByteString
finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
{-# NOINLINE hash #-}
-- | hash a strict bytestring into a digest bytestring
hash :: Int -- ^ algorithm hash size in bits
-> ByteString -- ^ the data to hash
-> ByteString -- ^ the digest output
hash hashlen d = unsafeDoIO $ withCtxNewThrow $ \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 -- ^ algorithm hash size in bits
-> L.ByteString -- ^ the data to hash as a lazy bytestring
-> ByteString -- ^ the digest output
hashlazy hashlen l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_skein256_init ptr (fromIntegral hashlen) >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr

144
Crypto/Hash/Skein512.hs Normal file
View File

@ -0,0 +1,144 @@
{-# LANGUAGE ForeignFunctionInterface #-}
-- |
-- Module : Crypto.Hash.Skein512
-- License : BSD-style
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
-- Stability : experimental
-- Portability : unknown
--
-- module containing the basic functions to work with the
-- Skein512 cryptographic hash.
--
module Crypto.Hash.Skein512
( Ctx(..)
-- * Incremental hashing Functions
, init -- :: Int -> Ctx
, update -- :: Ctx -> ByteString -> Ctx
, updates -- :: Ctx -> [ByteString] -> Ctx
, finalize -- :: Ctx -> ByteString
-- * Single Pass hashing
, hash -- :: Int -> ByteString -> ByteString
, hashlazy -- :: Int -> ByteString -> ByteString
) where
import Prelude hiding (init)
import Foreign.Ptr
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Storable
import Foreign.Marshal.Alloc
import qualified Data.ByteString.Lazy as L
import Data.ByteString (ByteString)
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
import Data.ByteString.Internal (create, toForeignPtr)
import Data.Word
import Crypto.Hash.Internal (unsafeDoIO)
-- | Skein512 Context.
newtype Ctx = Ctx ByteString
{-# INLINE sizeCtx #-}
sizeCtx :: Int
sizeCtx = 160
{- return the number of bytes of output for the digest -}
peekHashlen :: Ptr Ctx -> IO Int
peekHashlen ptr = peek iptr >>= \v -> return $! fromIntegral v
where iptr :: Ptr Word32
iptr = castPtr ptr
{-# RULES "hash" forall b i. finalize (update (init i) b) = hash i b #-}
{-# RULES "hash.list1" forall b i. finalize (updates (init i) [b]) = hash i b #-}
{-# RULES "hashmany" forall b i. finalize (foldl update (init i) b) = hashlazy i (L.fromChunks b) #-}
{-# RULES "hashlazy" forall b i. finalize (foldl update (init i) $ L.toChunks b) = hashlazy i b #-}
{-# INLINE withByteStringPtr #-}
withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
withByteStringPtr b f =
withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
where (fptr, off, _) = toForeignPtr b
{-# INLINE memcopy64 #-}
memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
memcopy64 dst src = mapM_ peekAndPoke [0..(20-1)]
where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
where createCtx = create sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
withCtxThrow (Ctx ctxB) f =
allocaBytes sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
foreign import ccall unsafe "cryptonite_skein512.h cryptonite_skein512_init"
c_skein512_init :: Ptr Ctx -> Word32 -> IO ()
foreign import ccall "cryptonite_skein512.h cryptonite_skein512_update"
c_skein512_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
foreign import ccall unsafe "cryptonite_skein512.h cryptonite_skein512_finalize"
c_skein512_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
updateInternalIO ptr d =
unsafeUseAsCStringLen d (\(cs, len) -> c_skein512_update ptr (castPtr cs) (fromIntegral len))
finalizeInternalIO :: Ptr Ctx -> IO ByteString
finalizeInternalIO ptr =
peekHashlen ptr >>= \digestSize -> create digestSize (c_skein512_finalize ptr)
{-# NOINLINE init #-}
-- | init a context where
init :: Int -- ^ algorithm hash size in bits
-> Ctx
init hashlen = unsafeDoIO $ withCtxNew $ \ptr -> c_skein512_init ptr (fromIntegral hashlen)
{-# NOINLINE update #-}
-- | update a context with a bytestring returning the new updated context
update :: Ctx -- ^ the context to update
-> ByteString -- ^ the data to update with
-> Ctx -- ^ the updated context
update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
{-# NOINLINE updates #-}
-- | updates a context with multiples bytestring returning the new updated context
updates :: Ctx -- ^ the context to update
-> [ByteString] -- ^ a list of data bytestring to update with
-> Ctx -- ^ the updated context
updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
{-# NOINLINE finalize #-}
-- | finalize the context into a digest bytestring
finalize :: Ctx -> ByteString
finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
{-# NOINLINE hash #-}
-- | hash a strict bytestring into a digest bytestring
hash :: Int -- ^ algorithm hash size in bits
-> ByteString -- ^ the data to hash
-> ByteString -- ^ the digest output
hash hashlen d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_skein512_init ptr (fromIntegral hashlen) >> updateInternalIO ptr d >> finalizeInternalIO ptr
{-# NOINLINE hashlazy #-}
-- | hash a lazy bytestring into a digest bytestring
hashlazy :: Int -- ^ algorithm hash size in bits
-> L.ByteString -- ^ the data to hash as a lazy bytestring
-> ByteString -- ^ the digest output
hashlazy hashlen l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_skein512_init ptr (fromIntegral hashlen) >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr

136
Crypto/Hash/Tiger.hs Normal file
View File

@ -0,0 +1,136 @@
{-# LANGUAGE ForeignFunctionInterface #-}
-- |
-- Module : Crypto.Hash.Tiger
-- License : BSD-style
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
-- Stability : experimental
-- Portability : unknown
--
-- module containing the basic functions to work with the
-- Tiger cryptographic hash.
--
module Crypto.Hash.Tiger
( Ctx(..)
-- * Incremental hashing Functions
, init -- :: Ctx
, update -- :: Ctx -> ByteString -> Ctx
, updates -- :: Ctx -> [ByteString] -> Ctx
, finalize -- :: Ctx -> ByteString
-- * Single Pass hashing
, hash -- :: ByteString -> ByteString
, hashlazy -- :: ByteString -> ByteString
) where
import Prelude hiding (init)
import Foreign.Ptr
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Storable
import Foreign.Marshal.Alloc
import qualified Data.ByteString.Lazy as L
import Data.ByteString (ByteString)
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
import Data.ByteString.Internal (create, toForeignPtr)
import Data.Word
import Crypto.Hash.Internal (unsafeDoIO)
-- | Tiger Context.
newtype Ctx = Ctx ByteString
{-# INLINE digestSize #-}
digestSize :: Int
digestSize = 24
{-# INLINE sizeCtx #-}
sizeCtx :: Int
sizeCtx = 96
{-# RULES "hash" forall b. finalize (update init b) = hash b #-}
{-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-}
{-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-}
{-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-}
{-# INLINE withByteStringPtr #-}
withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
withByteStringPtr b f =
withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
where (fptr, off, _) = toForeignPtr b
{-# INLINE memcopy64 #-}
memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
memcopy64 dst src = mapM_ peekAndPoke [0..(12-1)]
where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
where createCtx = create sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
withCtxThrow (Ctx ctxB) f =
allocaBytes sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
foreign import ccall unsafe "cryptonite_tiger.h cryptonite_tiger_init"
c_tiger_init :: Ptr Ctx -> IO ()
foreign import ccall "cryptonite_tiger.h cryptonite_tiger_update"
c_tiger_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
foreign import ccall unsafe "cryptonite_tiger.h cryptonite_tiger_finalize"
c_tiger_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
updateInternalIO ptr d =
unsafeUseAsCStringLen d (\(cs, len) -> c_tiger_update ptr (castPtr cs) (fromIntegral len))
finalizeInternalIO :: Ptr Ctx -> IO ByteString
finalizeInternalIO ptr = create digestSize (c_tiger_finalize ptr)
{-# NOINLINE init #-}
-- | init a context
init :: Ctx
init = unsafeDoIO $ withCtxNew $ c_tiger_init
{-# NOINLINE update #-}
-- | update a context with a bytestring returning the new updated context
update :: Ctx -- ^ the context to update
-> ByteString -- ^ the data to update with
-> Ctx -- ^ the updated context
update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
{-# NOINLINE updates #-}
-- | updates a context with multiples bytestring returning the new updated context
updates :: Ctx -- ^ the context to update
-> [ByteString] -- ^ a list of data bytestring to update with
-> Ctx -- ^ the updated context
updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
{-# NOINLINE finalize #-}
-- | finalize the context into a digest bytestring
finalize :: Ctx -> ByteString
finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
{-# NOINLINE hash #-}
-- | hash a strict bytestring into a digest bytestring
hash :: ByteString -> ByteString
hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_tiger_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr
{-# NOINLINE hashlazy #-}
-- | hash a lazy bytestring into a digest bytestring
hashlazy :: L.ByteString -> ByteString
hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_tiger_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr

76
Crypto/Hash/Types.hs Normal file
View File

@ -0,0 +1,76 @@
-- |
-- Module : Crypto.Hash.Types
-- License : BSD-style
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
-- Stability : experimental
-- Portability : unknown
--
-- Crypto hash types definitions
--
module Crypto.Hash.Types
( HashAlgorithm(..)
, Context(..)
, Digest(..)
-- * deprecated
, contextToByteString
, digestToByteString
)
where
import Data.ByteString (ByteString)
import Data.Byteable
import qualified Data.ByteString.Char8 as BC
import Crypto.Hash.Utils (toHex)
-- | Class representing hashing algorithms.
--
-- The hash algorithm is built over 3 primitives:
--
-- * init : create a new hashing context
--
-- * updates : update the hashing context with some strict bytestrings
-- and return the new context
--
-- * finalize : finalize the context into a digest
--
class HashAlgorithm a where
-- | Block size in bytes the hash algorithm operates on
hashBlockSize :: Context a -> Int
-- | Initialize a new context for this hash algorithm
hashInit :: Context a
-- | Update the context with a list of strict bytestring,
-- and return a new context with the updates.
hashUpdates :: Context a -> [ByteString] -> Context a
-- | Finalize a context and return a digest.
hashFinalize :: Context a -> Digest a
-- | Try to convert a binary digest bytestring to a digest.
digestFromByteString :: ByteString -> Maybe (Digest a)
-- | Represent a context for a given hash algorithm.
newtype Context a = Context ByteString
instance Byteable (Context a) where
toBytes (Context bs) = bs
-- | return the binary bytestring. deprecated use toBytes.
contextToByteString :: Context a -> ByteString
contextToByteString = toBytes
-- | Represent a digest for a given hash algorithm.
newtype Digest a = Digest ByteString
deriving (Eq,Ord)
instance Byteable (Digest a) where
toBytes (Digest bs) = bs
-- | return the binary bytestring. deprecated use toBytes.
{-# DEPRECATED digestToByteString "use toBytes from byteable:Data.Byteable" #-}
digestToByteString :: Digest a -> ByteString
digestToByteString = toBytes
instance Show (Digest a) where
show (Digest bs) = BC.unpack $ toHex bs

77
Crypto/Hash/Utils.hs Normal file
View File

@ -0,0 +1,77 @@
{-# LANGUAGE MagicHash, BangPatterns #-}
-- |
-- Module : Crypto.Hash.Utils
-- License : BSD-style
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
-- Stability : experimental
-- Portability : unknown
--
-- Crypto hash utility for hexadecimal
--
module Crypto.Hash.Utils
( toHex
) where
import Data.ByteString (ByteString)
import qualified Data.ByteString.Internal as B
import GHC.Prim
import GHC.Types
import GHC.Word
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Ptr (plusPtr, castPtr)
import Foreign.Storable (poke, peek)
import Crypto.Hash.Utils.Cpu
import Data.Bits (testBit)
-- | Convert a bytestring to the hexadecimal equivalent
-- using 0123456789abcdef as digit
toHex :: ByteString -> ByteString
toHex (B.PS fp off len) = B.unsafeCreate (len*2) $ \d ->
withForeignPtr fp $ \s -> start d (s `plusPtr` off)
where start db sb
| use32Hex && (len `testBit` 0) == False = loop32 db sb
| otherwise = loop8 db sb
where end = sb `plusPtr` len
-- write the hex output using 32 bits write.
loop32 d s
| s == end = return ()
| otherwise = do b1 <- fromIntegral `fmap` (peek s :: IO Word8)
b2 <- fromIntegral `fmap` (peek (s `plusPtr` 1) :: IO Word8)
poke (castPtr d) (to32 b1 b2)
loop32 (d `plusPtr` 4) (s `plusPtr` 2)
-- write the hex output 8 bits, 2 at a time
loop8 d s
| s == end = return ()
| otherwise = do b <- fromIntegral `fmap` (peek s :: IO Word8)
poke d (r tableHi b)
poke (d `plusPtr` 1) (r tableLo b)
loop8 (d `plusPtr` 2) (s `plusPtr` 1)
-- little endian version
to32 (I# i1) (I# i2) = W32# (or# (or# (or# hi2 lo2) hi1) lo1)
where hi2 = uncheckedShiftL# (indexWord8OffAddr# tableLo i2) 24#
lo2 = uncheckedShiftL# (indexWord8OffAddr# tableHi i2) 16#
hi1 = uncheckedShiftL# (indexWord8OffAddr# tableLo i1) 8#
lo1 = indexWord8OffAddr# tableHi i1
r :: Addr# -> Int -> Word8
r table (I# index) = W8# (indexWord8OffAddr# table index)
!tableLo =
"0123456789abcdef0123456789abcdef\
\0123456789abcdef0123456789abcdef\
\0123456789abcdef0123456789abcdef\
\0123456789abcdef0123456789abcdef\
\0123456789abcdef0123456789abcdef\
\0123456789abcdef0123456789abcdef\
\0123456789abcdef0123456789abcdef\
\0123456789abcdef0123456789abcdef"#
!tableHi =
"00000000000000001111111111111111\
\22222222222222223333333333333333\
\44444444444444445555555555555555\
\66666666666666667777777777777777\
\88888888888888889999999999999999\
\aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb\
\ccccccccccccccccdddddddddddddddd\
\eeeeeeeeeeeeeeeeffffffffffffffff"#

136
Crypto/Hash/Whirlpool.hs Normal file
View File

@ -0,0 +1,136 @@
{-# LANGUAGE ForeignFunctionInterface #-}
-- |
-- Module : Crypto.Hash.Whirlpool
-- License : BSD-style
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
-- Stability : experimental
-- Portability : unknown
--
-- module containing the basic functions to work with the
-- Whirlpool cryptographic hash.
--
module Crypto.Hash.Whirlpool
( Ctx(..)
-- * Incremental hashing Functions
, init -- :: Ctx
, update -- :: Ctx -> ByteString -> Ctx
, updates -- :: Ctx -> [ByteString] -> Ctx
, finalize -- :: Ctx -> ByteString
-- * Single Pass hashing
, hash -- :: ByteString -> ByteString
, hashlazy -- :: ByteString -> ByteString
) where
import Prelude hiding (init)
import Foreign.Ptr
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Storable
import Foreign.Marshal.Alloc
import qualified Data.ByteString.Lazy as L
import Data.ByteString (ByteString)
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
import Data.ByteString.Internal (create, toForeignPtr)
import Data.Word
import Crypto.Hash.Internal (unsafeDoIO)
-- | Whirlpool Context.
newtype Ctx = Ctx ByteString
{-# INLINE digestSize #-}
digestSize :: Int
digestSize = 64
{-# INLINE sizeCtx #-}
sizeCtx :: Int
sizeCtx = 168
{-# RULES "hash" forall b. finalize (update init b) = hash b #-}
{-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-}
{-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-}
{-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-}
{-# INLINE withByteStringPtr #-}
withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
withByteStringPtr b f =
withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
where (fptr, off, _) = toForeignPtr b
{-# INLINE memcopy64 #-}
memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
memcopy64 dst src = mapM_ peekAndPoke [0..(21-1)]
where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
where createCtx = create sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
withCtxThrow (Ctx ctxB) f =
allocaBytes sizeCtx $ \dstPtr ->
withByteStringPtr ctxB $ \srcPtr -> do
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
f (castPtr dstPtr)
withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
foreign import ccall unsafe "cryptonite_whirlpool.h cryptonite_whirlpool_init"
c_whirlpool_init :: Ptr Ctx -> IO ()
foreign import ccall "cryptonite_whirlpool.h cryptonite_whirlpool_update"
c_whirlpool_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
foreign import ccall unsafe "cryptonite_whirlpool.h cryptonite_whirlpool_finalize"
c_whirlpool_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
updateInternalIO ptr d =
unsafeUseAsCStringLen d (\(cs, len) -> c_whirlpool_update ptr (castPtr cs) (fromIntegral len))
finalizeInternalIO :: Ptr Ctx -> IO ByteString
finalizeInternalIO ptr = create digestSize (c_whirlpool_finalize ptr)
{-# NOINLINE init #-}
-- | init a context
init :: Ctx
init = unsafeDoIO $ withCtxNew $ c_whirlpool_init
{-# NOINLINE update #-}
-- | update a context with a bytestring returning the new updated context
update :: Ctx -- ^ the context to update
-> ByteString -- ^ the data to update with
-> Ctx -- ^ the updated context
update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d
{-# NOINLINE updates #-}
-- | updates a context with multiples bytestring returning the new updated context
updates :: Ctx -- ^ the context to update
-> [ByteString] -- ^ a list of data bytestring to update with
-> Ctx -- ^ the updated context
updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d
{-# NOINLINE finalize #-}
-- | finalize the context into a digest bytestring
finalize :: Ctx -> ByteString
finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
{-# NOINLINE hash #-}
-- | hash a strict bytestring into a digest bytestring
hash :: ByteString -> ByteString
hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_whirlpool_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr
{-# NOINLINE hashlazy #-}
-- | hash a lazy bytestring into a digest bytestring
hashlazy :: L.ByteString -> ByteString
hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
c_whirlpool_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr

135
cbits/cryptonite_md2.c Normal file
View File

@ -0,0 +1,135 @@
/*
* 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 <stdio.h>
#include "cryptonite_bitfn.h"
#include "cryptonite_md2.h"
void cryptonite_md2_init(struct md2_ctx *ctx)
{
memset(ctx, 0, sizeof(*ctx));
ctx->sz = 0ULL;
}
static uint8_t S_table[] = {
0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13,
0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA,
0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12,
0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A,
0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03,
0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6,
0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1,
0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02,
0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26,
0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52,
0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A,
0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39,
0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14
};
static uint8_t *padding_table[] = {
"",
"\x1",
"\x2\x2",
"\x3\x3\x3",
"\x4\x4\x4\x4",
"\x5\x5\x5\x5\x5",
"\x6\x6\x6\x6\x6\x6",
"\x7\x7\x7\x7\x7\x7\x7",
"\x8\x8\x8\x8\x8\x8\x8\x8",
"\x9\x9\x9\x9\x9\x9\x9\x9\x9",
"\xa\xa\xa\xa\xa\xa\xa\xa\xa\xa",
"\xb\xb\xb\xb\xb\xb\xb\xb\xb\xb\xb",
"\xc\xc\xc\xc\xc\xc\xc\xc\xc\xc\xc\xc",
"\xd\xd\xd\xd\xd\xd\xd\xd\xd\xd\xd\xd\xd",
"\xe\xe\xe\xe\xe\xe\xe\xe\xe\xe\xe\xe\xe\xe",
"\xf\xf\xf\xf\xf\xf\xf\xf\xf\xf\xf\xf\xf\xf\xf",
"\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10"
};
static void md2_do_chunk(struct md2_ctx *ctx, uint8_t *buf)
{
uint8_t i, j, t;
uint8_t x[48];
memcpy(x, ctx->h, 16);
memcpy(x+16, buf, 16);
for (i = 0; i < 16; i++)
x[i+32] = ctx->h[i] ^ buf[i];
for (t = i = 0; i < 18; i++) {
for (j = 0; j < 48; j++)
t = x[j] ^= S_table[t];
t = (t + i) & 0xff;
}
memcpy(ctx->h, x, 16);
t = ctx->cksum[15];
for (i = 0; i < 16; i++)
t = ctx->cksum[i] ^= S_table[buf[i] ^ t];
}
void cryptonite_md2_update(struct md2_ctx *ctx, uint8_t *data, uint32_t len)
{
uint32_t index, to_fill;
index = (uint32_t) (ctx->sz & 0xf);
to_fill = 16 - index;
ctx->sz += len;
if (index && len >= to_fill) {
memcpy(ctx->buf + index, data, to_fill);
md2_do_chunk(ctx, ctx->buf);
len -= to_fill;
data += to_fill;
index = 0;
}
/* process as much 16-block as possible */
for (; len >= 16; len -= 16, data += 16)
md2_do_chunk(ctx, data);
/* append data into buf */
if (len)
memcpy(ctx->buf + index, data, len);
}
void cryptonite_md2_finalize(struct md2_ctx *ctx, uint8_t *out)
{
uint32_t index, padlen;
index = ctx->sz & 0xf;
padlen = 16 - index;
cryptonite_md2_update(ctx, padding_table[padlen], padlen);
cryptonite_md2_update(ctx, ctx->cksum, 16);
memcpy(out, ctx->h, 16);
}

44
cbits/cryptonite_md2.h Normal file
View File

@ -0,0 +1,44 @@
/*
* Copyright (C) 2006-2009 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_MD2_H
#define CRYPTOHASH_MD2_H
#include <stdint.h>
struct md2_ctx
{
uint64_t sz;
uint8_t buf[16];
uint8_t h[16];
uint8_t cksum[16];
};
#define MD2_DIGEST_SIZE 16
#define MD2_CTX_SIZE sizeof(struct md2_ctx)
void cryptonite_md2_init(struct md2_ctx *ctx);
void cryptonite_md2_update(struct md2_ctx *ctx, uint8_t *data, uint32_t len);
void cryptonite_md2_finalize(struct md2_ctx *ctx, uint8_t *out);
#endif

161
cbits/cryptonite_md4.c Normal file
View File

@ -0,0 +1,161 @@
/*
* Copyright (C) 2006-2009 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 <stdio.h>
#include "cryptonite_bitfn.h"
#include "cryptonite_md4.h"
void cryptonite_md4_init(struct md4_ctx *ctx)
{
memset(ctx, 0, sizeof(*ctx));
ctx->sz = 0ULL;
ctx->h[0] = 0x67452301;
ctx->h[1] = 0xefcdab89;
ctx->h[2] = 0x98badcfe;
ctx->h[3] = 0x10325476;
}
#define f1(x, y, z) ((x & y) | ((~x) & z))
#define f2(x, y, z) ((x & y) | (x & z) | (y & z))
#define f3(x, y, z) (x ^ y ^ z)
#define K1 0x00000000
#define K2 0x5A827999
#define K3 0x6ED9EBA1
#define R(a,b,c,d,f,k,s,i) (a = rol32(a + f(b,c,d) + w[i] + k, s))
static void md4_do_chunk(struct md4_ctx *ctx, uint32_t *buf)
{
uint32_t a, b, c, d;
#ifdef ARCH_IS_BIG_ENDIAN
uint32_t w[16];
cpu_to_le32_array(w, (uint32_t *) buf, 16);
#else
uint32_t *w = buf;
#endif
a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3];
R(a, b, c, d, f1, K1, 3, 0);
R(d, a, b, c, f1, K1, 7, 1);
R(c, d, a, b, f1, K1, 11, 2);
R(b, c, d, a, f1, K1, 19, 3);
R(a, b, c, d, f1, K1, 3, 4);
R(d, a, b, c, f1, K1, 7, 5);
R(c, d, a, b, f1, K1, 11, 6);
R(b, c, d, a, f1, K1, 19, 7);
R(a, b, c, d, f1, K1, 3, 8);
R(d, a, b, c, f1, K1, 7, 9);
R(c, d, a, b, f1, K1, 11, 10);
R(b, c, d, a, f1, K1, 19, 11);
R(a, b, c, d, f1, K1, 3, 12);
R(d, a, b, c, f1, K1, 7, 13);
R(c, d, a, b, f1, K1, 11, 14);
R(b, c, d, a, f1, K1, 19, 15);
R(a, b, c, d, f2, K2, 3, 0);
R(d, a, b, c, f2, K2, 5, 4);
R(c, d, a, b, f2, K2, 9, 8);
R(b, c, d, a, f2, K2, 13, 12);
R(a, b, c, d, f2, K2, 3, 1);
R(d, a, b, c, f2, K2, 5, 5);
R(c, d, a, b, f2, K2, 9, 9);
R(b, c, d, a, f2, K2, 13, 13);
R(a, b, c, d, f2, K2, 3, 2);
R(d, a, b, c, f2, K2, 5, 6);
R(c, d, a, b, f2, K2, 9, 10);
R(b, c, d, a, f2, K2, 13, 14);
R(a, b, c, d, f2, K2, 3, 3);
R(d, a, b, c, f2, K2, 5, 7);
R(c, d, a, b, f2, K2, 9, 11);
R(b, c, d, a, f2, K2, 13, 15);
R(a, b, c, d, f3, K3, 3, 0);
R(d, a, b, c, f3, K3, 9, 8);
R(c, d, a, b, f3, K3, 11, 4);
R(b, c, d, a, f3, K3, 15, 12);
R(a, b, c, d, f3, K3, 3, 2);
R(d, a, b, c, f3, K3, 9, 10);
R(c, d, a, b, f3, K3, 11, 6);
R(b, c, d, a, f3, K3, 15, 14);
R(a, b, c, d, f3, K3, 3, 1);
R(d, a, b, c, f3, K3, 9, 9);
R(c, d, a, b, f3, K3, 11, 5);
R(b, c, d, a, f3, K3, 15, 13);
R(a, b, c, d, f3, K3, 3, 3);
R(d, a, b, c, f3, K3, 9, 11);
R(c, d, a, b, f3, K3, 11, 7);
R(b, c, d, a, f3, K3, 15, 15);
ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d;
}
void cryptonite_md4_update(struct md4_ctx *ctx, uint8_t *data, uint32_t len)
{
uint32_t index, to_fill;
index = (uint32_t) (ctx->sz & 0x3f);
to_fill = 64 - index;
ctx->sz += len;
if (index && len >= to_fill) {
memcpy(ctx->buf + index, data, to_fill);
md4_do_chunk(ctx, (uint32_t *) ctx->buf);
len -= to_fill;
data += to_fill;
index = 0;
}
/* process as much 64-block as possible */
for (; len >= 64; len -= 64, data += 64)
md4_do_chunk(ctx, (uint32_t *) data);
/* append data into buf */
if (len)
memcpy(ctx->buf + index, data, len);
}
void cryptonite_md4_finalize(struct md4_ctx *ctx, uint8_t *out)
{
static uint8_t padding[64] = { 0x80, };
uint64_t bits;
uint32_t index, padlen;
/* add padding and update data with it */
bits = cpu_to_le64(ctx->sz << 3);
/* pad out to 56 */
index = (uint32_t) (ctx->sz & 0x3f);
padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
cryptonite_md4_update(ctx, padding, padlen);
/* append length */
cryptonite_md4_update(ctx, (uint8_t *) &bits, sizeof(bits));
/* output hash */
le32_to_cpu_array((uint32_t *) out, ctx->h, 4);
}

43
cbits/cryptonite_md4.h Normal file
View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2006-2009 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_MD4_H
#define CRYPTOHASH_MD4_H
#include <stdint.h>
struct md4_ctx
{
uint64_t sz;
uint8_t buf[64];
uint32_t h[4];
};
#define MD4_DIGEST_SIZE 16
#define MD4_CTX_SIZE sizeof(struct md4_ctx)
void cryptonite_md4_init(struct md4_ctx *ctx);
void cryptonite_md4_update(struct md4_ctx *ctx, uint8_t *data, uint32_t len);
void cryptonite_md4_finalize(struct md4_ctx *ctx, uint8_t *out);
#endif

178
cbits/cryptonite_md5.c Normal file
View File

@ -0,0 +1,178 @@
/*
* Copyright (C) 2006-2009 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 <stdio.h>
#include "cryptonite_bitfn.h"
#include "cryptonite_md5.h"
void cryptonite_md5_init(struct md5_ctx *ctx)
{
memset(ctx, 0, sizeof(*ctx));
ctx->sz = 0ULL;
ctx->h[0] = 0x67452301;
ctx->h[1] = 0xefcdab89;
ctx->h[2] = 0x98badcfe;
ctx->h[3] = 0x10325476;
}
#define f1(x, y, z) (z ^ (x & (y ^ z)))
#define f2(x, y, z) f1(z, x, y)
#define f3(x, y, z) (x ^ y ^ z)
#define f4(x, y, z) (y ^ (x | ~z))
#define R(f, a, b, c, d, i, k, s) a += f(b, c, d) + w[i] + k; a = rol32(a, s); a += b
static void md5_do_chunk(struct md5_ctx *ctx, uint32_t *buf)
{
uint32_t a, b, c, d;
#ifdef ARCH_IS_BIG_ENDIAN
uint32_t w[16];
cpu_to_le32_array(w, buf, 16);
#else
uint32_t *w = buf;
#endif
a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3];
R(f1, a, b, c, d, 0, 0xd76aa478, 7);
R(f1, d, a, b, c, 1, 0xe8c7b756, 12);
R(f1, c, d, a, b, 2, 0x242070db, 17);
R(f1, b, c, d, a, 3, 0xc1bdceee, 22);
R(f1, a, b, c, d, 4, 0xf57c0faf, 7);
R(f1, d, a, b, c, 5, 0x4787c62a, 12);
R(f1, c, d, a, b, 6, 0xa8304613, 17);
R(f1, b, c, d, a, 7, 0xfd469501, 22);
R(f1, a, b, c, d, 8, 0x698098d8, 7);
R(f1, d, a, b, c, 9, 0x8b44f7af, 12);
R(f1, c, d, a, b, 10, 0xffff5bb1, 17);
R(f1, b, c, d, a, 11, 0x895cd7be, 22);
R(f1, a, b, c, d, 12, 0x6b901122, 7);
R(f1, d, a, b, c, 13, 0xfd987193, 12);
R(f1, c, d, a, b, 14, 0xa679438e, 17);
R(f1, b, c, d, a, 15, 0x49b40821, 22);
R(f2, a, b, c, d, 1, 0xf61e2562, 5);
R(f2, d, a, b, c, 6, 0xc040b340, 9);
R(f2, c, d, a, b, 11, 0x265e5a51, 14);
R(f2, b, c, d, a, 0, 0xe9b6c7aa, 20);
R(f2, a, b, c, d, 5, 0xd62f105d, 5);
R(f2, d, a, b, c, 10, 0x02441453, 9);
R(f2, c, d, a, b, 15, 0xd8a1e681, 14);
R(f2, b, c, d, a, 4, 0xe7d3fbc8, 20);
R(f2, a, b, c, d, 9, 0x21e1cde6, 5);
R(f2, d, a, b, c, 14, 0xc33707d6, 9);
R(f2, c, d, a, b, 3, 0xf4d50d87, 14);
R(f2, b, c, d, a, 8, 0x455a14ed, 20);
R(f2, a, b, c, d, 13, 0xa9e3e905, 5);
R(f2, d, a, b, c, 2, 0xfcefa3f8, 9);
R(f2, c, d, a, b, 7, 0x676f02d9, 14);
R(f2, b, c, d, a, 12, 0x8d2a4c8a, 20);
R(f3, a, b, c, d, 5, 0xfffa3942, 4);
R(f3, d, a, b, c, 8, 0x8771f681, 11);
R(f3, c, d, a, b, 11, 0x6d9d6122, 16);
R(f3, b, c, d, a, 14, 0xfde5380c, 23);
R(f3, a, b, c, d, 1, 0xa4beea44, 4);
R(f3, d, a, b, c, 4, 0x4bdecfa9, 11);
R(f3, c, d, a, b, 7, 0xf6bb4b60, 16);
R(f3, b, c, d, a, 10, 0xbebfbc70, 23);
R(f3, a, b, c, d, 13, 0x289b7ec6, 4);
R(f3, d, a, b, c, 0, 0xeaa127fa, 11);
R(f3, c, d, a, b, 3, 0xd4ef3085, 16);
R(f3, b, c, d, a, 6, 0x04881d05, 23);
R(f3, a, b, c, d, 9, 0xd9d4d039, 4);
R(f3, d, a, b, c, 12, 0xe6db99e5, 11);
R(f3, c, d, a, b, 15, 0x1fa27cf8, 16);
R(f3, b, c, d, a, 2, 0xc4ac5665, 23);
R(f4, a, b, c, d, 0, 0xf4292244, 6);
R(f4, d, a, b, c, 7, 0x432aff97, 10);
R(f4, c, d, a, b, 14, 0xab9423a7, 15);
R(f4, b, c, d, a, 5, 0xfc93a039, 21);
R(f4, a, b, c, d, 12, 0x655b59c3, 6);
R(f4, d, a, b, c, 3, 0x8f0ccc92, 10);
R(f4, c, d, a, b, 10, 0xffeff47d, 15);
R(f4, b, c, d, a, 1, 0x85845dd1, 21);
R(f4, a, b, c, d, 8, 0x6fa87e4f, 6);
R(f4, d, a, b, c, 15, 0xfe2ce6e0, 10);
R(f4, c, d, a, b, 6, 0xa3014314, 15);
R(f4, b, c, d, a, 13, 0x4e0811a1, 21);
R(f4, a, b, c, d, 4, 0xf7537e82, 6);
R(f4, d, a, b, c, 11, 0xbd3af235, 10);
R(f4, c, d, a, b, 2, 0x2ad7d2bb, 15);
R(f4, b, c, d, a, 9, 0xeb86d391, 21);
ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d;
}
void cryptonite_md5_update(struct md5_ctx *ctx, uint8_t *data, uint32_t len)
{
uint32_t index, to_fill;
index = (uint32_t) (ctx->sz & 0x3f);
to_fill = 64 - index;
ctx->sz += len;
if (index && len >= to_fill) {
memcpy(ctx->buf + index, data, to_fill);
md5_do_chunk(ctx, (uint32_t *) ctx->buf);
len -= to_fill;
data += to_fill;
index = 0;
}
/* process as much 64-block as possible */
for (; len >= 64; len -= 64, data += 64)
md5_do_chunk(ctx, (uint32_t *) data);
/* append data into buf */
if (len)
memcpy(ctx->buf + index, data, len);
}
void cryptonite_md5_finalize(struct md5_ctx *ctx, uint8_t *out)
{
static uint8_t padding[64] = { 0x80, };
uint64_t bits;
uint32_t index, padlen;
uint32_t *p = (uint32_t *) out;
/* add padding and update data with it */
bits = cpu_to_le64(ctx->sz << 3);
/* pad out to 56 */
index = (uint32_t) (ctx->sz & 0x3f);
padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
cryptonite_md5_update(ctx, padding, padlen);
/* append length */
cryptonite_md5_update(ctx, (uint8_t *) &bits, sizeof(bits));
/* output hash */
p[0] = cpu_to_le32(ctx->h[0]);
p[1] = cpu_to_le32(ctx->h[1]);
p[2] = cpu_to_le32(ctx->h[2]);
p[3] = cpu_to_le32(ctx->h[3]);
}

43
cbits/cryptonite_md5.h Normal file
View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2006-2009 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_MD5_H
#define CRYPTOHASH_MD5_H
#include <stdint.h>
struct md5_ctx
{
uint64_t sz;
uint8_t buf[64];
uint32_t h[4];
};
#define MD5_DIGEST_SIZE 16
#define MD5_CTX_SIZE sizeof(struct md5_ctx)
void cryptonite_md5_init(struct md5_ctx *ctx);
void cryptonite_md5_update(struct md5_ctx *ctx, uint8_t *data, uint32_t len);
void cryptonite_md5_finalize(struct md5_ctx *ctx, uint8_t *out);
#endif

299
cbits/cryptonite_ripemd.c Normal file
View File

@ -0,0 +1,299 @@
/*
* Copyright (C) 2006-2009 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 "cryptonite_ripemd.h"
#include "cryptonite_bitfn.h"
#include <string.h>
void cryptonite_ripemd160_init(struct ripemd160_ctx *ctx)
{
memset(ctx, 0, sizeof(*ctx));
ctx->h[0] = 0x67452301;
ctx->h[1] = 0xefcdab89;
ctx->h[2] = 0x98badcfe;
ctx->h[3] = 0x10325476;
ctx->h[4] = 0xc3d2e1f0;
}
#define K1 0x00000000
#define K2 0x5a827999
#define K3 0x6ed9eba1
#define K4 0x8f1bbcdc
#define K5 0xa953fd4e
#define K6 0x50a28be6
#define K7 0x5c4dd124
#define K8 0x6d703ef3
#define K9 0x7a6d76e9
#define f1(x, y, z) (x ^ y ^ z)
#define f2(x, y, z) (z ^ (x & (y ^ z)))
#define f3(x, y, z) ((x | ~y) ^ z)
#define f4(x, y, z) (y ^ (z & (x ^ y)))
#define f5(x, y, z) (x ^ (y | ~z))
#define R(a, b, c, d, e, f, k, i, s) \
a += f(b, c, d) + w[i] + k; a = rol32(a, s) + e; c = rol32(c, 10)
static void ripemd160_do_chunk(struct ripemd160_ctx *ctx, uint32_t *buf)
{
uint32_t a1, b1, c1, d1, e1, a2, b2, c2, d2, e2;
#ifdef ARCH_IS_BIG_ENDIAN
uint32_t w[16];
cpu_to_le32_array(w, buf, 16);
#else
uint32_t *w = buf;
#endif
a1 = ctx->h[0]; b1 = ctx->h[1]; c1 = ctx->h[2]; d1 = ctx->h[3]; e1 = ctx->h[4];
a2 = ctx->h[0]; b2 = ctx->h[1]; c2 = ctx->h[2]; d2 = ctx->h[3]; e2 = ctx->h[4];
/* 5 passes on first state copy */
R(a1, b1, c1, d1, e1, f1, K1, 0, 11);
R(e1, a1, b1, c1, d1, f1, K1, 1, 14);
R(d1, e1, a1, b1, c1, f1, K1, 2, 15);
R(c1, d1, e1, a1, b1, f1, K1, 3, 12);
R(b1, c1, d1, e1, a1, f1, K1, 4, 5);
R(a1, b1, c1, d1, e1, f1, K1, 5, 8);
R(e1, a1, b1, c1, d1, f1, K1, 6, 7);
R(d1, e1, a1, b1, c1, f1, K1, 7, 9);
R(c1, d1, e1, a1, b1, f1, K1, 8, 11);
R(b1, c1, d1, e1, a1, f1, K1, 9, 13);
R(a1, b1, c1, d1, e1, f1, K1, 10, 14);
R(e1, a1, b1, c1, d1, f1, K1, 11, 15);
R(d1, e1, a1, b1, c1, f1, K1, 12, 6);
R(c1, d1, e1, a1, b1, f1, K1, 13, 7);
R(b1, c1, d1, e1, a1, f1, K1, 14, 9);
R(a1, b1, c1, d1, e1, f1, K1, 15, 8);
R(e1, a1, b1, c1, d1, f2, K2, 7, 7);
R(d1, e1, a1, b1, c1, f2, K2, 4, 6);
R(c1, d1, e1, a1, b1, f2, K2, 13, 8);
R(b1, c1, d1, e1, a1, f2, K2, 1, 13);
R(a1, b1, c1, d1, e1, f2, K2, 10, 11);
R(e1, a1, b1, c1, d1, f2, K2, 6, 9);
R(d1, e1, a1, b1, c1, f2, K2, 15, 7);
R(c1, d1, e1, a1, b1, f2, K2, 3, 15);
R(b1, c1, d1, e1, a1, f2, K2, 12, 7);
R(a1, b1, c1, d1, e1, f2, K2, 0, 12);
R(e1, a1, b1, c1, d1, f2, K2, 9, 15);
R(d1, e1, a1, b1, c1, f2, K2, 5, 9);
R(c1, d1, e1, a1, b1, f2, K2, 2, 11);
R(b1, c1, d1, e1, a1, f2, K2, 14, 7);
R(a1, b1, c1, d1, e1, f2, K2, 11, 13);
R(e1, a1, b1, c1, d1, f2, K2, 8, 12);
R(d1, e1, a1, b1, c1, f3, K3, 3, 11);
R(c1, d1, e1, a1, b1, f3, K3, 10, 13);
R(b1, c1, d1, e1, a1, f3, K3, 14, 6);
R(a1, b1, c1, d1, e1, f3, K3, 4, 7);
R(e1, a1, b1, c1, d1, f3, K3, 9, 14);
R(d1, e1, a1, b1, c1, f3, K3, 15, 9);
R(c1, d1, e1, a1, b1, f3, K3, 8, 13);
R(b1, c1, d1, e1, a1, f3, K3, 1, 15);
R(a1, b1, c1, d1, e1, f3, K3, 2, 14);
R(e1, a1, b1, c1, d1, f3, K3, 7, 8);
R(d1, e1, a1, b1, c1, f3, K3, 0, 13);
R(c1, d1, e1, a1, b1, f3, K3, 6, 6);
R(b1, c1, d1, e1, a1, f3, K3, 13, 5);
R(a1, b1, c1, d1, e1, f3, K3, 11, 12);
R(e1, a1, b1, c1, d1, f3, K3, 5, 7);
R(d1, e1, a1, b1, c1, f3, K3, 12, 5);
R(c1, d1, e1, a1, b1, f4, K4, 1, 11);
R(b1, c1, d1, e1, a1, f4, K4, 9, 12);
R(a1, b1, c1, d1, e1, f4, K4, 11, 14);
R(e1, a1, b1, c1, d1, f4, K4, 10, 15);
R(d1, e1, a1, b1, c1, f4, K4, 0, 14);
R(c1, d1, e1, a1, b1, f4, K4, 8, 15);
R(b1, c1, d1, e1, a1, f4, K4, 12, 9);
R(a1, b1, c1, d1, e1, f4, K4, 4, 8);
R(e1, a1, b1, c1, d1, f4, K4, 13, 9);
R(d1, e1, a1, b1, c1, f4, K4, 3, 14);
R(c1, d1, e1, a1, b1, f4, K4, 7, 5);
R(b1, c1, d1, e1, a1, f4, K4, 15, 6);
R(a1, b1, c1, d1, e1, f4, K4, 14, 8);
R(e1, a1, b1, c1, d1, f4, K4, 5, 6);
R(d1, e1, a1, b1, c1, f4, K4, 6, 5);
R(c1, d1, e1, a1, b1, f4, K4, 2, 12);
R(b1, c1, d1, e1, a1, f5, K5, 4, 9);
R(a1, b1, c1, d1, e1, f5, K5, 0, 15);
R(e1, a1, b1, c1, d1, f5, K5, 5, 5);
R(d1, e1, a1, b1, c1, f5, K5, 9, 11);
R(c1, d1, e1, a1, b1, f5, K5, 7, 6);
R(b1, c1, d1, e1, a1, f5, K5, 12, 8);
R(a1, b1, c1, d1, e1, f5, K5, 2, 13);
R(e1, a1, b1, c1, d1, f5, K5, 10, 12);
R(d1, e1, a1, b1, c1, f5, K5, 14, 5);
R(c1, d1, e1, a1, b1, f5, K5, 1, 12);
R(b1, c1, d1, e1, a1, f5, K5, 3, 13);
R(a1, b1, c1, d1, e1, f5, K5, 8, 14);
R(e1, a1, b1, c1, d1, f5, K5, 11, 11);
R(d1, e1, a1, b1, c1, f5, K5, 6, 8);
R(c1, d1, e1, a1, b1, f5, K5, 15, 5);
R(b1, c1, d1, e1, a1, f5, K5, 13, 6);
/* 5 passes on second state copy */
R(a2, b2, c2, d2, e2, f5, K6, 5, 8);
R(e2, a2, b2, c2, d2, f5, K6, 14, 9);
R(d2, e2, a2, b2, c2, f5, K6, 7, 9);
R(c2, d2, e2, a2, b2, f5, K6, 0, 11);
R(b2, c2, d2, e2, a2, f5, K6, 9, 13);
R(a2, b2, c2, d2, e2, f5, K6, 2, 15);
R(e2, a2, b2, c2, d2, f5, K6, 11, 15);
R(d2, e2, a2, b2, c2, f5, K6, 4, 5);
R(c2, d2, e2, a2, b2, f5, K6, 13, 7);
R(b2, c2, d2, e2, a2, f5, K6, 6, 7);
R(a2, b2, c2, d2, e2, f5, K6, 15, 8);
R(e2, a2, b2, c2, d2, f5, K6, 8, 11);
R(d2, e2, a2, b2, c2, f5, K6, 1, 14);
R(c2, d2, e2, a2, b2, f5, K6, 10, 14);
R(b2, c2, d2, e2, a2, f5, K6, 3, 12);
R(a2, b2, c2, d2, e2, f5, K6, 12, 6);
R(e2, a2, b2, c2, d2, f4, K7, 6, 9);
R(d2, e2, a2, b2, c2, f4, K7, 11, 13);
R(c2, d2, e2, a2, b2, f4, K7, 3, 15);
R(b2, c2, d2, e2, a2, f4, K7, 7, 7);
R(a2, b2, c2, d2, e2, f4, K7, 0, 12);
R(e2, a2, b2, c2, d2, f4, K7, 13, 8);
R(d2, e2, a2, b2, c2, f4, K7, 5, 9);
R(c2, d2, e2, a2, b2, f4, K7, 10, 11);
R(b2, c2, d2, e2, a2, f4, K7, 14, 7);
R(a2, b2, c2, d2, e2, f4, K7, 15, 7);
R(e2, a2, b2, c2, d2, f4, K7, 8, 12);
R(d2, e2, a2, b2, c2, f4, K7, 12, 7);
R(c2, d2, e2, a2, b2, f4, K7, 4, 6);
R(b2, c2, d2, e2, a2, f4, K7, 9, 15);
R(a2, b2, c2, d2, e2, f4, K7, 1, 13);
R(e2, a2, b2, c2, d2, f4, K7, 2, 11);
R(d2, e2, a2, b2, c2, f3, K8, 15, 9);
R(c2, d2, e2, a2, b2, f3, K8, 5, 7);
R(b2, c2, d2, e2, a2, f3, K8, 1, 15);
R(a2, b2, c2, d2, e2, f3, K8, 3, 11);
R(e2, a2, b2, c2, d2, f3, K8, 7, 8);
R(d2, e2, a2, b2, c2, f3, K8, 14, 6);
R(c2, d2, e2, a2, b2, f3, K8, 6, 6);
R(b2, c2, d2, e2, a2, f3, K8, 9, 14);
R(a2, b2, c2, d2, e2, f3, K8, 11, 12);
R(e2, a2, b2, c2, d2, f3, K8, 8, 13);
R(d2, e2, a2, b2, c2, f3, K8, 12, 5);
R(c2, d2, e2, a2, b2, f3, K8, 2, 14);
R(b2, c2, d2, e2, a2, f3, K8, 10, 13);
R(a2, b2, c2, d2, e2, f3, K8, 0, 13);
R(e2, a2, b2, c2, d2, f3, K8, 4, 7);
R(d2, e2, a2, b2, c2, f3, K8, 13, 5);
R(c2, d2, e2, a2, b2, f2, K9, 8, 15);
R(b2, c2, d2, e2, a2, f2, K9, 6, 5);
R(a2, b2, c2, d2, e2, f2, K9, 4, 8);
R(e2, a2, b2, c2, d2, f2, K9, 1, 11);
R(d2, e2, a2, b2, c2, f2, K9, 3, 14);
R(c2, d2, e2, a2, b2, f2, K9, 11, 14);
R(b2, c2, d2, e2, a2, f2, K9, 15, 6);
R(a2, b2, c2, d2, e2, f2, K9, 0, 14);
R(e2, a2, b2, c2, d2, f2, K9, 5, 6);
R(d2, e2, a2, b2, c2, f2, K9, 12, 9);
R(c2, d2, e2, a2, b2, f2, K9, 2, 12);
R(b2, c2, d2, e2, a2, f2, K9, 13, 9);
R(a2, b2, c2, d2, e2, f2, K9, 9, 12);
R(e2, a2, b2, c2, d2, f2, K9, 7, 5);
R(d2, e2, a2, b2, c2, f2, K9, 10, 15);
R(c2, d2, e2, a2, b2, f2, K9, 14, 8);
R(b2, c2, d2, e2, a2, f1, K1, 12, 8);
R(a2, b2, c2, d2, e2, f1, K1, 15, 5);
R(e2, a2, b2, c2, d2, f1, K1, 10, 12);
R(d2, e2, a2, b2, c2, f1, K1, 4, 9);
R(c2, d2, e2, a2, b2, f1, K1, 1, 12);
R(b2, c2, d2, e2, a2, f1, K1, 5, 5);
R(a2, b2, c2, d2, e2, f1, K1, 8, 14);
R(e2, a2, b2, c2, d2, f1, K1, 7, 6);
R(d2, e2, a2, b2, c2, f1, K1, 6, 8);
R(c2, d2, e2, a2, b2, f1, K1, 2, 13);
R(b2, c2, d2, e2, a2, f1, K1, 13, 6);
R(a2, b2, c2, d2, e2, f1, K1, 14, 5);
R(e2, a2, b2, c2, d2, f1, K1, 0, 15);
R(d2, e2, a2, b2, c2, f1, K1, 3, 13);
R(c2, d2, e2, a2, b2, f1, K1, 9, 11);
R(b2, c2, d2, e2, a2, f1, K1, 11, 11);
d2 += c1 + ctx->h[1];
ctx->h[1] = ctx->h[2] + d1 + e2;
ctx->h[2] = ctx->h[3] + e1 + a2;
ctx->h[3] = ctx->h[4] + a1 + b2;
ctx->h[4] = ctx->h[0] + b1 + c2;
ctx->h[0] = d2;
}
void cryptonite_ripemd160_update(struct ripemd160_ctx *ctx, uint8_t *data, uint32_t len)
{
uint32_t index, to_fill;
index = (uint32_t) (ctx->sz & 0x3f);
to_fill = 64 - index;
ctx->sz += len;
if (index && len >= to_fill) {
memcpy(ctx->buf + index, data, to_fill);
ripemd160_do_chunk(ctx, (uint32_t *) ctx->buf);
len -= to_fill;
data += to_fill;
index = 0;
}
for (; len >= 64; len -= 64, data += 64)
ripemd160_do_chunk(ctx, (uint32_t *) data);
if (len)
memcpy(ctx->buf + index, data, len);
}
void cryptonite_ripemd160_finalize(struct ripemd160_ctx *ctx, uint8_t *out)
{
static uint8_t padding[64] = { 0x80, };
uint64_t bits;
uint32_t index, padlen;
uint32_t *p = (uint32_t *) out;
/* add padding and update data with it */
bits = cpu_to_le64(ctx->sz << 3);
/* pad out to 56 */
index = (uint32_t) (ctx->sz & 0x3f);
padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
cryptonite_ripemd160_update(ctx, padding, padlen);
/* append length */
cryptonite_ripemd160_update(ctx, (uint8_t *) &bits, sizeof(bits));
/* output digest */
p[0] = cpu_to_le32(ctx->h[0]);
p[1] = cpu_to_le32(ctx->h[1]);
p[2] = cpu_to_le32(ctx->h[2]);
p[3] = cpu_to_le32(ctx->h[3]);
p[4] = cpu_to_le32(ctx->h[4]);
}

43
cbits/cryptonite_ripemd.h Normal file
View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2006-2009 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_RIPEMD_H
#define CRYPTOHASH_RIPEMD_H
#include <stdint.h>
struct ripemd160_ctx
{
uint64_t sz;
uint8_t buf[64];
uint32_t h[5];
};
#define RIPEMD160_DIGEST_SIZE 20
#define RIPEMD160_CTX_SIZE sizeof(struct ripemd160_ctx)
void cryptonite_ripemd160_init(struct ripemd160_ctx *ctx);
void cryptonite_ripemd160_update(struct ripemd160_ctx *ctx, uint8_t *data, uint32_t len);
void cryptonite_ripemd160_finalize(struct ripemd160_ctx *ctx, uint8_t *out);
#endif

209
cbits/cryptonite_sha1.c Normal file
View File

@ -0,0 +1,209 @@
/*
* Copyright (C) 2006-2009 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 "cryptonite_sha1.h"
#include "cryptonite_bitfn.h"
void cryptonite_sha1_init(struct sha1_ctx *ctx)
{
memset(ctx, 0, sizeof(*ctx));
ctx->h[0] = 0x67452301;
ctx->h[1] = 0xefcdab89;
ctx->h[2] = 0x98badcfe;
ctx->h[3] = 0x10325476;
ctx->h[4] = 0xc3d2e1f0;
}
#define f1(x, y, z) (z ^ (x & (y ^ z)))
#define f2(x, y, z) (x ^ y ^ z)
#define f3(x, y, z) ((x & y) + (z & (x ^ y)))
#define f4(x, y, z) f2(x, y, z)
#define K1 0x5a827999
#define K2 0x6ed9eba1
#define K3 0x8f1bbcdc
#define K4 0xca62c1d6
#define R(a, b, c, d, e, f, k, w) \
e += rol32(a, 5) + f(b, c, d) + k + w; b = rol32(b, 30)
#define M(i) (w[i & 0x0f] = rol32(w[i & 0x0f] ^ w[(i - 14) & 0x0f] \
^ w[(i - 8) & 0x0f] ^ w[(i - 3) & 0x0f], 1))
static inline void sha1_do_chunk(struct sha1_ctx *ctx, uint32_t *buf)
{
uint32_t a, b, c, d, e;
uint32_t w[16];
#define CPY(i) w[i] = be32_to_cpu(buf[i])
CPY(0); CPY(1); CPY(2); CPY(3); CPY(4); CPY(5); CPY(6); CPY(7);
CPY(8); CPY(9); CPY(10); CPY(11); CPY(12); CPY(13); CPY(14); CPY(15);
#undef CPY
a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; e = ctx->h[4];
R(a, b, c, d, e, f1, K1, w[0]);
R(e, a, b, c, d, f1, K1, w[1]);
R(d, e, a, b, c, f1, K1, w[2]);
R(c, d, e, a, b, f1, K1, w[3]);
R(b, c, d, e, a, f1, K1, w[4]);
R(a, b, c, d, e, f1, K1, w[5]);
R(e, a, b, c, d, f1, K1, w[6]);
R(d, e, a, b, c, f1, K1, w[7]);
R(c, d, e, a, b, f1, K1, w[8]);
R(b, c, d, e, a, f1, K1, w[9]);
R(a, b, c, d, e, f1, K1, w[10]);
R(e, a, b, c, d, f1, K1, w[11]);
R(d, e, a, b, c, f1, K1, w[12]);
R(c, d, e, a, b, f1, K1, w[13]);
R(b, c, d, e, a, f1, K1, w[14]);
R(a, b, c, d, e, f1, K1, w[15]);
R(e, a, b, c, d, f1, K1, M(16));
R(d, e, a, b, c, f1, K1, M(17));
R(c, d, e, a, b, f1, K1, M(18));
R(b, c, d, e, a, f1, K1, M(19));
R(a, b, c, d, e, f2, K2, M(20));
R(e, a, b, c, d, f2, K2, M(21));
R(d, e, a, b, c, f2, K2, M(22));
R(c, d, e, a, b, f2, K2, M(23));
R(b, c, d, e, a, f2, K2, M(24));
R(a, b, c, d, e, f2, K2, M(25));
R(e, a, b, c, d, f2, K2, M(26));
R(d, e, a, b, c, f2, K2, M(27));
R(c, d, e, a, b, f2, K2, M(28));
R(b, c, d, e, a, f2, K2, M(29));
R(a, b, c, d, e, f2, K2, M(30));
R(e, a, b, c, d, f2, K2, M(31));
R(d, e, a, b, c, f2, K2, M(32));
R(c, d, e, a, b, f2, K2, M(33));
R(b, c, d, e, a, f2, K2, M(34));
R(a, b, c, d, e, f2, K2, M(35));
R(e, a, b, c, d, f2, K2, M(36));
R(d, e, a, b, c, f2, K2, M(37));
R(c, d, e, a, b, f2, K2, M(38));
R(b, c, d, e, a, f2, K2, M(39));
R(a, b, c, d, e, f3, K3, M(40));
R(e, a, b, c, d, f3, K3, M(41));
R(d, e, a, b, c, f3, K3, M(42));
R(c, d, e, a, b, f3, K3, M(43));
R(b, c, d, e, a, f3, K3, M(44));
R(a, b, c, d, e, f3, K3, M(45));
R(e, a, b, c, d, f3, K3, M(46));
R(d, e, a, b, c, f3, K3, M(47));
R(c, d, e, a, b, f3, K3, M(48));
R(b, c, d, e, a, f3, K3, M(49));
R(a, b, c, d, e, f3, K3, M(50));
R(e, a, b, c, d, f3, K3, M(51));
R(d, e, a, b, c, f3, K3, M(52));
R(c, d, e, a, b, f3, K3, M(53));
R(b, c, d, e, a, f3, K3, M(54));
R(a, b, c, d, e, f3, K3, M(55));
R(e, a, b, c, d, f3, K3, M(56));
R(d, e, a, b, c, f3, K3, M(57));
R(c, d, e, a, b, f3, K3, M(58));
R(b, c, d, e, a, f3, K3, M(59));
R(a, b, c, d, e, f4, K4, M(60));
R(e, a, b, c, d, f4, K4, M(61));
R(d, e, a, b, c, f4, K4, M(62));
R(c, d, e, a, b, f4, K4, M(63));
R(b, c, d, e, a, f4, K4, M(64));
R(a, b, c, d, e, f4, K4, M(65));
R(e, a, b, c, d, f4, K4, M(66));
R(d, e, a, b, c, f4, K4, M(67));
R(c, d, e, a, b, f4, K4, M(68));
R(b, c, d, e, a, f4, K4, M(69));
R(a, b, c, d, e, f4, K4, M(70));
R(e, a, b, c, d, f4, K4, M(71));
R(d, e, a, b, c, f4, K4, M(72));
R(c, d, e, a, b, f4, K4, M(73));
R(b, c, d, e, a, f4, K4, M(74));
R(a, b, c, d, e, f4, K4, M(75));
R(e, a, b, c, d, f4, K4, M(76));
R(d, e, a, b, c, f4, K4, M(77));
R(c, d, e, a, b, f4, K4, M(78));
R(b, c, d, e, a, f4, K4, M(79));
ctx->h[0] += a;
ctx->h[1] += b;
ctx->h[2] += c;
ctx->h[3] += d;
ctx->h[4] += e;
}
void cryptonite_sha1_update(struct sha1_ctx *ctx, uint8_t *data, uint32_t len)
{
uint32_t index, to_fill;
index = (uint32_t) (ctx->sz & 0x3f);
to_fill = 64 - index;
ctx->sz += len;
/* process partial buffer if there's enough data to make a block */
if (index && len >= to_fill) {
memcpy(ctx->buf + index, data, to_fill);
sha1_do_chunk(ctx, (uint32_t *) ctx->buf);
len -= to_fill;
data += to_fill;
index = 0;
}
/* process as much 64-block as possible */
for (; len >= 64; len -= 64, data += 64)
sha1_do_chunk(ctx, (uint32_t *) data);
/* append data into buf */
if (len)
memcpy(ctx->buf + index, data, len);
}
void cryptonite_sha1_finalize(struct sha1_ctx *ctx, uint8_t *out)
{
static uint8_t padding[64] = { 0x80, };
uint64_t bits;
uint32_t index, padlen;
uint32_t *p = (uint32_t *) out;
/* add padding and update data with it */
bits = cpu_to_be64(ctx->sz << 3);
/* pad out to 56 */
index = (uint32_t) (ctx->sz & 0x3f);
padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
cryptonite_sha1_update(ctx, padding, padlen);
/* append length */
cryptonite_sha1_update(ctx, (uint8_t *) &bits, sizeof(bits));
/* output hash */
p[0] = cpu_to_be32(ctx->h[0]);
p[1] = cpu_to_be32(ctx->h[1]);
p[2] = cpu_to_be32(ctx->h[2]);
p[3] = cpu_to_be32(ctx->h[3]);
p[4] = cpu_to_be32(ctx->h[4]);
}

43
cbits/cryptonite_sha1.h Normal file
View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2006-2009 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_SHA1_H
#define CRYPTOHASH_SHA1_H
#include <stdint.h>
struct sha1_ctx
{
uint64_t sz;
uint8_t buf[64];
uint32_t h[5];
};
#define SHA1_DIGEST_SIZE 20
#define SHA1_CTX_SIZE (sizeof(struct sha1_ctx))
void cryptonite_sha1_init(struct sha1_ctx *ctx);
void cryptonite_sha1_update(struct sha1_ctx *ctx, uint8_t *data, uint32_t len);
void cryptonite_sha1_finalize(struct sha1_ctx *ctx, uint8_t *out);
#endif

175
cbits/cryptonite_sha256.c Normal file
View File

@ -0,0 +1,175 @@
/*
* Copyright (C) 2006-2009 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 "cryptonite_sha256.h"
#include "cryptonite_bitfn.h"
void cryptonite_sha224_init(struct sha224_ctx *ctx)
{
memset(ctx, 0, sizeof(*ctx));
ctx->h[0] = 0xc1059ed8;
ctx->h[1] = 0x367cd507;
ctx->h[2] = 0x3070dd17;
ctx->h[3] = 0xf70e5939;
ctx->h[4] = 0xffc00b31;
ctx->h[5] = 0x68581511;
ctx->h[6] = 0x64f98fa7;
ctx->h[7] = 0xbefa4fa4;
}
void cryptonite_sha256_init(struct sha256_ctx *ctx)
{
memset(ctx, 0, sizeof(*ctx));
ctx->h[0] = 0x6a09e667;
ctx->h[1] = 0xbb67ae85;
ctx->h[2] = 0x3c6ef372;
ctx->h[3] = 0xa54ff53a;
ctx->h[4] = 0x510e527f;
ctx->h[5] = 0x9b05688c;
ctx->h[6] = 0x1f83d9ab;
ctx->h[7] = 0x5be0cd19;
}
/* 232 times the cube root of the first 64 primes 2..311 */
static const uint32_t k[] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
#define e0(x) (ror32(x, 2) ^ ror32(x,13) ^ ror32(x,22))
#define e1(x) (ror32(x, 6) ^ ror32(x,11) ^ ror32(x,25))
#define s0(x) (ror32(x, 7) ^ ror32(x,18) ^ (x >> 3))
#define s1(x) (ror32(x,17) ^ ror32(x,19) ^ (x >> 10))
static void sha256_do_chunk(struct sha256_ctx *ctx, uint32_t buf[])
{
uint32_t a, b, c, d, e, f, g, h, t1, t2;
int i;
uint32_t w[64];
cpu_to_be32_array(w, buf, 16);
for (i = 16; i < 64; i++)
w[i] = s1(w[i - 2]) + w[i - 7] + s0(w[i - 15]) + w[i - 16];
a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3];
e = ctx->h[4]; f = ctx->h[5]; g = ctx->h[6]; h = ctx->h[7];
#define R(a, b, c, d, e, f, g, h, k, w) \
t1 = h + e1(e) + (g ^ (e & (f ^ g))) + k + w; \
t2 = e0(a) + ((a & b) | (c & (a | b))); \
d += t1; \
h = t1 + t2;
for (i = 0; i < 64; i += 8) {
R(a, b, c, d, e, f, g, h, k[i + 0], w[i + 0]);
R(h, a, b, c, d, e, f, g, k[i + 1], w[i + 1]);
R(g, h, a, b, c, d, e, f, k[i + 2], w[i + 2]);
R(f, g, h, a, b, c, d, e, k[i + 3], w[i + 3]);
R(e, f, g, h, a, b, c, d, k[i + 4], w[i + 4]);
R(d, e, f, g, h, a, b, c, k[i + 5], w[i + 5]);
R(c, d, e, f, g, h, a, b, k[i + 6], w[i + 6]);
R(b, c, d, e, f, g, h, a, k[i + 7], w[i + 7]);
}
#undef R
ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d;
ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h;
}
void cryptonite_sha224_update(struct sha224_ctx *ctx, uint8_t *data, uint32_t len)
{
return cryptonite_sha256_update(ctx, data, len);
}
void cryptonite_sha256_update(struct sha256_ctx *ctx, uint8_t *data, uint32_t len)
{
uint32_t index, to_fill;
/* check for partial buffer */
index = (uint32_t) (ctx->sz & 0x3f);
to_fill = 64 - index;
ctx->sz += len;
/* process partial buffer if there's enough data to make a block */
if (index && len >= to_fill) {
memcpy(ctx->buf + index, data, to_fill);
sha256_do_chunk(ctx, (uint32_t *) ctx->buf);
len -= to_fill;
data += to_fill;
index = 0;
}
/* process as much 64-block as possible */
for (; len >= 64; len -= 64, data += 64)
sha256_do_chunk(ctx, (uint32_t *) data);
/* append data into buf */
if (len)
memcpy(ctx->buf + index, data, len);
}
void cryptonite_sha224_finalize(struct sha224_ctx *ctx, uint8_t *out)
{
uint8_t intermediate[SHA256_DIGEST_SIZE];
cryptonite_sha256_finalize(ctx, intermediate);
memcpy(out, intermediate, SHA224_DIGEST_SIZE);
}
void cryptonite_sha256_finalize(struct sha256_ctx *ctx, uint8_t *out)
{
static uint8_t padding[64] = { 0x80, };
uint64_t bits;
uint32_t i, index, padlen;
uint32_t *p = (uint32_t *) out;
/* cpu -> big endian */
bits = cpu_to_be64(ctx->sz << 3);
/* pad out to 56 */
index = (uint32_t) (ctx->sz & 0x3f);
padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
cryptonite_sha256_update(ctx, padding, padlen);
/* append length */
cryptonite_sha256_update(ctx, (uint8_t *) &bits, sizeof(bits));
/* store to digest */
for (i = 0; i < 8; i++)
p[i] = cpu_to_be32(ctx->h[i]);
}

53
cbits/cryptonite_sha256.h Normal file
View File

@ -0,0 +1,53 @@
/*
* Copyright (C) 2006-2009 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_SHA256_H
#define CRYPTOHASH_SHA256_H
#include <stdint.h>
struct sha256_ctx
{
uint64_t sz;
uint8_t buf[128];
uint32_t h[8];
};
#define sha224_ctx sha256_ctx
#define SHA224_DIGEST_SIZE 28
#define SHA224_CTX_SIZE sizeof(struct sha224_ctx)
#define SHA256_DIGEST_SIZE 32
#define SHA256_CTX_SIZE sizeof(struct sha256_ctx)
void cryptonite_sha224_init(struct sha224_ctx *ctx);
void cryptonite_sha224_update(struct sha224_ctx *ctx, uint8_t *data, uint32_t len);
void cryptonite_sha224_finalize(struct sha224_ctx *ctx, uint8_t *out);
void cryptonite_sha256_init(struct sha256_ctx *ctx);
void cryptonite_sha256_update(struct sha256_ctx *ctx, uint8_t *data, uint32_t len);
void cryptonite_sha256_finalize(struct sha256_ctx *ctx, uint8_t *out);
#endif

159
cbits/cryptonite_sha3.c Normal file
View File

@ -0,0 +1,159 @@
/*
* Copyright (C) 2012 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 <stdint.h>
#include <string.h>
#include "cryptonite_bitfn.h"
#include "cryptonite_sha3.h"
#define KECCAK_NB_ROUNDS 24
/* rounds constants */
static const uint64_t keccak_rndc[24] =
{
0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL,
0x8000000080008000ULL, 0x000000000000808bULL, 0x0000000080000001ULL,
0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008aULL,
0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL,
0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL,
0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL,
0x000000000000800aULL, 0x800000008000000aULL, 0x8000000080008081ULL,
0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL,
};
/* triangular numbers constants */
static const int keccak_rotc[24] =
{ 1,3,6,10,15,21,28,36,45,55,2,14,27,41,56,8,25,43,62,18,39,61,20,44 };
static const int keccak_piln[24] =
{ 10,7,11,17,18,3,5,16,8,21,24,4,15,23,19,13,12,2,20,14,22,9,6,1 };
static inline void sha3_do_chunk(uint64_t state[25], uint64_t buf[], int bufsz)
{
int i, j, r;
uint64_t tmp, bc[5];
/* merge buf with state */
for (i = 0; i < bufsz; i++)
state[i] ^= le64_to_cpu(buf[i]);
/* run keccak rounds */
for (r = 0; r < KECCAK_NB_ROUNDS; r++) {
/* compute the parity of each columns */
for (i = 0; i < 5; i++)
bc[i] = state[i] ^ state[i+5] ^ state[i+10] ^ state[i+15] ^ state[i+20];
for (i = 0; i < 5; i++) {
tmp = bc[(i + 4) % 5] ^ rol64(bc[(i + 1) % 5], 1);
for (j = 0; j < 25; j += 5)
state[j + i] ^= tmp;
}
/* rho pi */
tmp = state[1];
for (i = 0; i < 24; i++) {
j = keccak_piln[i];
bc[0] = state[j];
state[j] = rol64(tmp, keccak_rotc[i]);
tmp = bc[0];
}
/* bitwise combine along rows using a = a xor (not b and c) */
for (j = 0; j < 25; j += 5) {
for (i = 0; i < 5; i++)
bc[i] = state[j + i];
#define andn(b,c) (~(b) & (c))
state[j + 0] ^= andn(bc[1], bc[2]);
state[j + 1] ^= andn(bc[2], bc[3]);
state[j + 2] ^= andn(bc[3], bc[4]);
state[j + 3] ^= andn(bc[4], bc[0]);
state[j + 4] ^= andn(bc[0], bc[1]);
#undef andn
}
/* xor the round constant */
state[0] ^= keccak_rndc[r];
}
}
void cryptonite_sha3_init(struct sha3_ctx *ctx, uint32_t hashlen)
{
memset(ctx, 0, sizeof(*ctx));
ctx->hashlen = hashlen / 8;
ctx->bufsz = 200 - 2 * ctx->hashlen;
}
void cryptonite_sha3_update(struct sha3_ctx *ctx, uint8_t *data, uint32_t len)
{
uint32_t to_fill;
to_fill = ctx->bufsz - ctx->bufindex;
if (ctx->bufindex == ctx->bufsz) {
sha3_do_chunk(ctx->state, (uint64_t *) ctx->buf, ctx->bufsz / 8);
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);
sha3_do_chunk(ctx->state, (uint64_t *) ctx->buf, ctx->bufsz / 8);
len -= to_fill;
data += to_fill;
ctx->bufindex = 0;
}
/* process as much ctx->bufsz-block */
for (; len >= ctx->bufsz; len -= ctx->bufsz, data += ctx->bufsz)
sha3_do_chunk(ctx->state, (uint64_t *) data, ctx->bufsz / 8);
/* append data into buf */
if (len) {
memcpy(ctx->buf + ctx->bufindex, data, len);
ctx->bufindex += len;
}
}
void cryptonite_sha3_finalize(struct sha3_ctx *ctx, uint8_t *out)
{
uint64_t w[25];
/* process full buffer if needed */
if (ctx->bufindex == ctx->bufsz) {
sha3_do_chunk(ctx->state, (uint64_t *) ctx->buf, ctx->bufsz / 8);
ctx->bufindex = 0;
}
/* add the 10*1 padding */
ctx->buf[ctx->bufindex++] = 1;
memset(ctx->buf + ctx->bufindex, 0, ctx->bufsz - ctx->bufindex);
ctx->buf[ctx->bufsz - 1] |= 0x80;
/* process */
sha3_do_chunk(ctx->state, (uint64_t *) ctx->buf, ctx->bufsz / 8);
/* output */
cpu_to_le64_array(w, ctx->state, 25);
memcpy(out, w, ctx->hashlen);
}

45
cbits/cryptonite_sha3.h Normal file
View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 2012 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_SHA3_H
#define CRYPTOHASH_SHA3_H
#include <stdint.h>
struct sha3_ctx
{
uint32_t hashlen; /* in bytes */
uint32_t bufindex;
uint64_t state[25];
uint32_t bufsz;
uint32_t _padding;
uint8_t buf[144]; /* minimum SHA3-224, otherwise buffer need increases */
};
#define SHA3_CTX_SIZE sizeof(struct sha3_ctx)
void cryptonite_sha3_init(struct sha3_ctx *ctx, uint32_t hashlen);
void cryptonite_sha3_update(struct sha3_ctx *ctx, uint8_t *data, uint32_t len);
void cryptonite_sha3_finalize(struct sha3_ctx *ctx, uint8_t *out);
#endif

245
cbits/cryptonite_sha512.c Normal file
View File

@ -0,0 +1,245 @@
/*
* Copyright (C) 2006-2009 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 "cryptonite_bitfn.h"
#include "cryptonite_sha512.h"
void cryptonite_sha384_init(struct sha512_ctx *ctx)
{
memset(ctx, 0, sizeof(*ctx));
ctx->h[0] = 0xcbbb9d5dc1059ed8ULL;
ctx->h[1] = 0x629a292a367cd507ULL;
ctx->h[2] = 0x9159015a3070dd17ULL;
ctx->h[3] = 0x152fecd8f70e5939ULL;
ctx->h[4] = 0x67332667ffc00b31ULL;
ctx->h[5] = 0x8eb44a8768581511ULL;
ctx->h[6] = 0xdb0c2e0d64f98fa7ULL;
ctx->h[7] = 0x47b5481dbefa4fa4ULL;
}
void cryptonite_sha512_init(struct sha512_ctx *ctx)
{
memset(ctx, 0, sizeof(*ctx));
ctx->h[0] = 0x6a09e667f3bcc908ULL;
ctx->h[1] = 0xbb67ae8584caa73bULL;
ctx->h[2] = 0x3c6ef372fe94f82bULL;
ctx->h[3] = 0xa54ff53a5f1d36f1ULL;
ctx->h[4] = 0x510e527fade682d1ULL;
ctx->h[5] = 0x9b05688c2b3e6c1fULL;
ctx->h[6] = 0x1f83d9abfb41bd6bULL;
ctx->h[7] = 0x5be0cd19137e2179ULL;
}
/* 232 times the cube root of the first 64 primes 2..311 */
static const uint64_t k[] = {
0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL,
};
#define e0(x) (ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39))
#define e1(x) (ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41))
#define s0(x) (ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7))
#define s1(x) (ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6))
static void sha512_do_chunk(struct sha512_ctx *ctx, uint64_t *buf)
{
uint64_t a, b, c, d, e, f, g, h, t1, t2;
int i;
uint64_t w[80];
cpu_to_be64_array(w, buf, 16);
for (i = 16; i < 80; i++)
w[i] = s1(w[i - 2]) + w[i - 7] + s0(w[i - 15]) + w[i - 16];
a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3];
e = ctx->h[4]; f = ctx->h[5]; g = ctx->h[6]; h = ctx->h[7];
#define R(a, b, c, d, e, f, g, h, k, w) \
t1 = h + e1(e) + (g ^ (e & (f ^ g))) + k + w; \
t2 = e0(a) + ((a & b) | (c & (a | b))); \
d += t1; \
h = t1 + t2
for (i = 0; i < 80; i += 8) {
R(a, b, c, d, e, f, g, h, k[i + 0], w[i + 0]);
R(h, a, b, c, d, e, f, g, k[i + 1], w[i + 1]);
R(g, h, a, b, c, d, e, f, k[i + 2], w[i + 2]);
R(f, g, h, a, b, c, d, e, k[i + 3], w[i + 3]);
R(e, f, g, h, a, b, c, d, k[i + 4], w[i + 4]);
R(d, e, f, g, h, a, b, c, k[i + 5], w[i + 5]);
R(c, d, e, f, g, h, a, b, k[i + 6], w[i + 6]);
R(b, c, d, e, f, g, h, a, k[i + 7], w[i + 7]);
}
#undef R
ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d;
ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h;
}
void cryptonite_sha384_update(struct sha384_ctx *ctx, uint8_t *data, uint32_t len)
{
return cryptonite_sha512_update(ctx, data, len);
}
void cryptonite_sha512_update(struct sha512_ctx *ctx, uint8_t *data, uint32_t len)
{
unsigned int index, to_fill;
/* check for partial buffer */
index = (unsigned int) (ctx->sz[0] & 0x7f);
to_fill = 128 - index;
ctx->sz[0] += len;
if (ctx->sz[0] < len)
ctx->sz[1]++;
/* process partial buffer if there's enough data to make a block */
if (index && len >= to_fill) {
memcpy(ctx->buf + index, data, to_fill);
sha512_do_chunk(ctx, (uint64_t *) ctx->buf);
len -= to_fill;
data += to_fill;
index = 0;
}
/* process as much 128-block as possible */
for (; len >= 128; len -= 128, data += 128)
sha512_do_chunk(ctx, (uint64_t *) data);
/* append data into buf */
if (len)
memcpy(ctx->buf + index, data, len);
}
void cryptonite_sha384_finalize(struct sha384_ctx *ctx, uint8_t *out)
{
uint8_t intermediate[SHA512_DIGEST_SIZE];
cryptonite_sha512_finalize(ctx, intermediate);
memcpy(out, intermediate, SHA384_DIGEST_SIZE);
}
void cryptonite_sha512_finalize(struct sha512_ctx *ctx, uint8_t *out)
{
static uint8_t padding[128] = { 0x80, };
uint32_t i, index, padlen;
uint64_t bits[2];
uint64_t *p = (uint64_t *) out;
/* cpu -> big endian */
bits[0] = cpu_to_be64((ctx->sz[1] << 3 | ctx->sz[0] >> 61));
bits[1] = cpu_to_be64((ctx->sz[0] << 3));
/* pad out to 56 */
index = (unsigned int) (ctx->sz[0] & 0x7f);
padlen = (index < 112) ? (112 - index) : ((128 + 112) - index);
cryptonite_sha512_update(ctx, padding, padlen);
/* append length */
cryptonite_sha512_update(ctx, (uint8_t *) bits, sizeof(bits));
/* store to digest */
for (i = 0; i < 8; i++)
p[i] = cpu_to_be64(ctx->h[i]);
}
#include <stdio.h>
void cryptonite_sha512_init_t(struct sha512_ctx *ctx, int t)
{
memset(ctx, 0, sizeof(*ctx));
if (t >= 512)
return;
switch (t) {
case 224:
ctx->h[0] = 0x8c3d37c819544da2ULL;
ctx->h[1] = 0x73e1996689dcd4d6ULL;
ctx->h[2] = 0x1dfab7ae32ff9c82ULL;
ctx->h[3] = 0x679dd514582f9fcfULL;
ctx->h[4] = 0x0f6d2b697bd44da8ULL;
ctx->h[5] = 0x77e36f7304c48942ULL;
ctx->h[6] = 0x3f9d85a86a1d36c8ULL;
ctx->h[7] = 0x1112e6ad91d692a1ULL;
break;
case 256:
ctx->h[0] = 0x22312194fc2bf72cULL;
ctx->h[1] = 0x9f555fa3c84c64c2ULL;
ctx->h[2] = 0x2393b86b6f53b151ULL;
ctx->h[3] = 0x963877195940eabdULL;
ctx->h[4] = 0x96283ee2a88effe3ULL;
ctx->h[5] = 0xbe5e1e2553863992ULL;
ctx->h[6] = 0x2b0199fc2c85b8aaULL;
ctx->h[7] = 0x0eb72ddc81c52ca2ULL;
break;
default: {
char buf[8+4];
uint8_t out[64];
int i;
cryptonite_sha512_init(ctx);
for (i = 0; i < 8; i++)
ctx->h[i] ^= 0xa5a5a5a5a5a5a5a5ULL;
i = sprintf(buf, "SHA-512/%d", t);
cryptonite_sha512_update(ctx, buf, i);
cryptonite_sha512_finalize(ctx, out);
/* re-init the context, otherwise len is changed */
memset(ctx, 0, sizeof(*ctx));
for (i = 0; i < 8; i++)
ctx->h[i] = cpu_to_be64(((uint64_t *) out)[i]);
}
}
}

54
cbits/cryptonite_sha512.h Normal file
View File

@ -0,0 +1,54 @@
/*
* Copyright (C) 2006-2009 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_SHA512_H
#define CRYPTOHASH_SHA512_H
#include <stdint.h>
struct sha512_ctx
{
uint64_t sz[2];
uint8_t buf[128];
uint64_t h[8];
};
#define sha384_ctx sha512_ctx
#define SHA384_DIGEST_SIZE 64
#define SHA384_CTX_SIZE sizeof(struct sha384_ctx)
#define SHA512_DIGEST_SIZE 64
#define SHA512_CTX_SIZE sizeof(struct sha512_ctx)
void cryptonite_sha384_init(struct sha384_ctx *ctx);
void cryptonite_sha384_update(struct sha384_ctx *ctx, uint8_t *data, uint32_t len);
void cryptonite_sha384_finalize(struct sha384_ctx *ctx, uint8_t *out);
void cryptonite_sha512_init(struct sha512_ctx *ctx);
void cryptonite_sha512_update(struct sha512_ctx *ctx, uint8_t *data, uint32_t len);
void cryptonite_sha512_finalize(struct sha512_ctx *ctx, uint8_t *out);
void cryptonite_sha512_init_t(struct sha512_ctx *ctx, int t);
#endif

46
cbits/cryptonite_skein.h Normal file
View File

@ -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

196
cbits/cryptonite_skein256.c Normal file
View File

@ -0,0 +1,196 @@
/*
* 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 "cryptonite_skein.h"
#include "cryptonite_skein256.h"
#include "cryptonite_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] = 0x1bd11bdaa9fc1a22ULL;
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 cryptonite_skein256_init(struct skein256_ctx *ctx, uint32_t hashlen)
{
uint64_t buf[4];
memset(ctx, 0, sizeof(*ctx));
ctx->hashlen = (hashlen + 7) >> 3;
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 cryptonite_skein256_update(struct skein256_ctx *ctx, uint8_t *data, uint32_t len)
{
uint32_t to_fill;
if (!len)
return;
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
* and there's without doubt further blocks */
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 cryptonite_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;
/* 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 w[4];
*((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;
cpu_to_le64_array(w, ctx->h, 4);
memcpy(out + i*32, w, n);
/* restore h[0--4] */
for (j = 0; j < 4; j++)
ctx->h[j] = x[j];
}
}

View File

@ -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 cryponite_skein256_init(struct skein256_ctx *ctx, uint32_t hashlen);
void cryponite_skein256_update(struct skein256_ctx *ctx, uint8_t *data, uint32_t len);
void cryponite_skein256_finalize(struct skein256_ctx *ctx, uint8_t *out);
#endif

214
cbits/cryptonite_skein512.c Normal file
View File

@ -0,0 +1,214 @@
/*
* 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 "cryptonite_skein.h"
#include "cryptonite_skein512.h"
#include "cryptonite_bitfn.h"
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, };
static const uint8_t K512_3[4] = { 44, 9, 54, 56, };
static const uint8_t K512_4[4] = { 39, 30, 34, 24, };
static const uint8_t K512_5[4] = { 13, 50, 10, 17, };
static const uint8_t K512_6[4] = { 25, 29, 39, 43, };
static const uint8_t K512_7[4] = { 8, 35, 56, 22, };
static inline void skein512_do_chunk(struct skein512_ctx *ctx, uint64_t *buf, uint32_t len)
{
uint64_t x[8];
uint64_t ts[3];
uint64_t ks[8+1];
ks[8] = 0x1bd11bdaa9fc1a22ULL;
ks[0] = ctx->h[0]; ks[8] ^= ctx->h[0];
ks[1] = ctx->h[1]; ks[8] ^= ctx->h[1];
ks[2] = ctx->h[2]; ks[8] ^= ctx->h[2];
ks[3] = ctx->h[3]; ks[8] ^= ctx->h[3];
ks[4] = ctx->h[4]; ks[8] ^= ctx->h[4];
ks[5] = ctx->h[5]; ks[8] ^= ctx->h[5];
ks[6] = ctx->h[6]; ks[8] ^= ctx->h[6];
ks[7] = ctx->h[7]; ks[8] ^= ctx->h[7];
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) % (8+1)]; \
x[1] += ks[((r)+1) % (8+1)]; \
x[2] += ks[((r)+2) % (8+1)]; \
x[3] += ks[((r)+3) % (8+1)]; \
x[4] += ks[((r)+4) % (8+1)]; \
x[5] += ks[((r)+5) % (8+1)] + ts[((r)+0) % 3]; \
x[6] += ks[((r)+6) % (8+1)] + ts[((r)+1) % 3]; \
x[7] += ks[((r)+7) % (8+1)] + (r)
#define ROUND(a,b,c,d,e,f,g,h,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]; \
x[e] += x[f]; x[f] = rol64(x[f],k[2]); x[f] ^= x[e]; \
x[g] += x[h]; x[h] = rol64(x[h],k[3]); x[h] ^= x[g];
#define PASS(i) \
ROUND(0,1,2,3,4,5,6,7,K512_0); \
ROUND(2,1,4,7,6,5,0,3,K512_1); \
ROUND(4,1,6,3,0,5,2,7,K512_2); \
ROUND(6,1,0,7,2,5,4,3,K512_3); \
INJECTKEY((i*2) + 1); \
ROUND(0,1,2,3,4,5,6,7,K512_4); \
ROUND(2,1,4,7,6,5,0,3,K512_5); \
ROUND(4,1,6,3,0,5,2,7,K512_6); \
ROUND(6,1,0,7,2,5,4,3,K512_7); \
INJECTKEY((i*2) + 2)
x[0] = le64_to_cpu(buf[0]) + ks[0];
x[1] = le64_to_cpu(buf[1]) + ks[1];
x[2] = le64_to_cpu(buf[2]) + ks[2];
x[3] = le64_to_cpu(buf[3]) + ks[3];
x[4] = le64_to_cpu(buf[4]) + ks[4];
x[5] = le64_to_cpu(buf[5]) + ks[5] + ts[0];
x[6] = le64_to_cpu(buf[6]) + ks[6] + ts[1];
x[7] = le64_to_cpu(buf[7]) + ks[7];
/* 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]);
ctx->h[4] = x[4] ^ cpu_to_le64(buf[4]);
ctx->h[5] = x[5] ^ cpu_to_le64(buf[5]);
ctx->h[6] = x[6] ^ cpu_to_le64(buf[6]);
ctx->h[7] = x[7] ^ cpu_to_le64(buf[7]);
}
void cryptonite_skein512_init(struct skein512_ctx *ctx, uint32_t hashlen)
{
uint64_t buf[8];
memset(ctx, 0, sizeof(*ctx));
ctx->hashlen = (hashlen + 7) >> 3;
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 */
skein512_do_chunk(ctx, buf, 4*8);
SET_TYPE(ctx, FLAG_FIRST | FLAG_TYPE(TYPE_MSG));
}
void cryptonite_skein512_update(struct skein512_ctx *ctx, uint8_t *data, uint32_t len)
{
uint32_t to_fill;
if (!len)
return;
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
* and there's without doubt further blocks */
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;
data += to_fill;
ctx->bufindex = 0;
}
/* process as much 64-block as possible except the last one in case we finalize */
for (; len > 64; len -= 64, data += 64)
skein512_do_chunk(ctx, (uint64_t *) data, 64);
/* append data into buf */
if (len) {
memcpy(ctx->buf + ctx->bufindex, data, len);
ctx->bufindex += len;
}
}
void cryptonite_skein512_finalize(struct skein512_ctx *ctx, uint8_t *out)
{
uint32_t outsize;
uint64_t *p = (uint64_t *) out;
uint64_t x[8];
int i, j, n;
ctx->t1 |= FLAG_FINAL;
/* if buf is not complete pad with 0 bytes */
if (ctx->bufindex < 64)
memset(ctx->buf + ctx->bufindex, '\0', 64 - ctx->bufindex);
skein512_do_chunk(ctx, (uint64_t *) ctx->buf, ctx->bufindex);
memset(ctx->buf, '\0', 64);
/* make sure we have a 8 bit rounded value */
outsize = ctx->hashlen;
/* backup h[0--7] */
for (j = 0; j < 8; j++)
x[j] = ctx->h[j];
/* threefish in counter mode, 0 for 1st 64 bytes, 1 for 2nd 64 bytes, .. */
for (i = 0; i*64 < outsize; i++) {
uint64_t w[8];
*((uint64_t *) ctx->buf) = cpu_to_le64(i);
SET_TYPE(ctx, FLAG_FIRST | FLAG_FINAL | FLAG_TYPE(TYPE_OUT));
skein512_do_chunk(ctx, (uint64_t *) ctx->buf, sizeof(uint64_t));
n = outsize - i * 64;
if (n >= 64) n = 64;
cpu_to_le64_array(w, ctx->h, 8);
memcpy(out + i*64, w, n);
/* restore h[0--7] */
for (j = 0; j < 8; j++)
ctx->h[j] = x[j];
}
}

View File

@ -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_SKEIN512_H
#define CRYPTOHASH_SKEIN512_H
#include <stdint.h>
struct skein512_ctx
{
uint32_t hashlen; /* in bytes, typically 384/8, 512/8 */
uint32_t bufindex;
uint8_t buf[64];
uint64_t h[8];
uint64_t t0;
uint64_t t1;
};
#define SKEIN512_CTX_SIZE sizeof(struct skein512_ctx)
void cryponite_skein512_init(struct skein512_ctx *ctx, uint32_t hashlen);
void cryponite_skein512_update(struct skein512_ctx *ctx, uint8_t *data, uint32_t len);
void cryponite_skein512_finalize(struct skein512_ctx *ctx, uint8_t *out);
#endif

415
cbits/cryptonite_tiger.c Normal file
View File

@ -0,0 +1,415 @@
/*
* Copyright (C) 2006-2009 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 "cryptonite_tiger.h"
#include "cryptonite_bitfn.h"
static const uint64_t t1[256] = {
0x02aab17cf7e90c5eULL,0xac424b03e243a8ecULL,0x72cd5be30dd5fcd3ULL,0x6d019b93f6f97f3aULL,
0xcd9978ffd21f9193ULL,0x7573a1c9708029e2ULL,0xb164326b922a83c3ULL,0x46883eee04915870ULL,
0xeaace3057103ece6ULL,0xc54169b808a3535cULL,0x4ce754918ddec47cULL,0x0aa2f4dfdc0df40cULL,
0x10b76f18a74dbefaULL,0xc6ccb6235ad1ab6aULL,0x13726121572fe2ffULL,0x1a488c6f199d921eULL,
0x4bc9f9f4da0007caULL,0x26f5e6f6e85241c7ULL,0x859079dbea5947b6ULL,0x4f1885c5c99e8c92ULL,
0xd78e761ea96f864bULL,0x8e36428c52b5c17dULL,0x69cf6827373063c1ULL,0xb607c93d9bb4c56eULL,
0x7d820e760e76b5eaULL,0x645c9cc6f07fdc42ULL,0xbf38a078243342e0ULL,0x5f6b343c9d2e7d04ULL,
0xf2c28aeb600b0ec6ULL,0x6c0ed85f7254bcacULL,0x71592281a4db4fe5ULL,0x1967fa69ce0fed9fULL,
0xfd5293f8b96545dbULL,0xc879e9d7f2a7600bULL,0x860248920193194eULL,0xa4f9533b2d9cc0b3ULL,
0x9053836c15957613ULL,0xdb6dcf8afc357bf1ULL,0x18beea7a7a370f57ULL,0x037117ca50b99066ULL,
0x6ab30a9774424a35ULL,0xf4e92f02e325249bULL,0x7739db07061ccae1ULL,0xd8f3b49ceca42a05ULL,
0xbd56be3f51382f73ULL,0x45faed5843b0bb28ULL,0x1c813d5c11bf1f83ULL,0x8af0e4b6d75fa169ULL,
0x33ee18a487ad9999ULL,0x3c26e8eab1c94410ULL,0xb510102bc0a822f9ULL,0x141eef310ce6123bULL,
0xfc65b90059ddb154ULL,0xe0158640c5e0e607ULL,0x884e079826c3a3cfULL,0x930d0d9523c535fdULL,
0x35638d754e9a2b00ULL,0x4085fccf40469dd5ULL,0xc4b17ad28be23a4cULL,0xcab2f0fc6a3e6a2eULL,
0x2860971a6b943fcdULL,0x3dde6ee212e30446ULL,0x6222f32ae01765aeULL,0x5d550bb5478308feULL,
0xa9efa98da0eda22aULL,0xc351a71686c40da7ULL,0x1105586d9c867c84ULL,0xdcffee85fda22853ULL,
0xccfbd0262c5eef76ULL,0xbaf294cb8990d201ULL,0xe69464f52afad975ULL,0x94b013afdf133e14ULL,
0x06a7d1a32823c958ULL,0x6f95fe5130f61119ULL,0xd92ab34e462c06c0ULL,0xed7bde33887c71d2ULL,
0x79746d6e6518393eULL,0x5ba419385d713329ULL,0x7c1ba6b948a97564ULL,0x31987c197bfdac67ULL,
0xde6c23c44b053d02ULL,0x581c49fed002d64dULL,0xdd474d6338261571ULL,0xaa4546c3e473d062ULL,
0x928fce349455f860ULL,0x48161bbacaab94d9ULL,0x63912430770e6f68ULL,0x6ec8a5e602c6641cULL,
0x87282515337ddd2bULL,0x2cda6b42034b701bULL,0xb03d37c181cb096dULL,0xe108438266c71c6fULL,
0x2b3180c7eb51b255ULL,0xdf92b82f96c08bbcULL,0x5c68c8c0a632f3baULL,0x5504cc861c3d0556ULL,
0xabbfa4e55fb26b8fULL,0x41848b0ab3baceb4ULL,0xb334a273aa445d32ULL,0xbca696f0a85ad881ULL,
0x24f6ec65b528d56cULL,0x0ce1512e90f4524aULL,0x4e9dd79d5506d35aULL,0x258905fac6ce9779ULL,
0x2019295b3e109b33ULL,0xf8a9478b73a054ccULL,0x2924f2f934417eb0ULL,0x3993357d536d1bc4ULL,
0x38a81ac21db6ff8bULL,0x47c4fbf17d6016bfULL,0x1e0faadd7667e3f5ULL,0x7abcff62938beb96ULL,
0xa78dad948fc179c9ULL,0x8f1f98b72911e50dULL,0x61e48eae27121a91ULL,0x4d62f7ad31859808ULL,
0xeceba345ef5ceaebULL,0xf5ceb25ebc9684ceULL,0xf633e20cb7f76221ULL,0xa32cdf06ab8293e4ULL,
0x985a202ca5ee2ca4ULL,0xcf0b8447cc8a8fb1ULL,0x9f765244979859a3ULL,0xa8d516b1a1240017ULL,
0x0bd7ba3ebb5dc726ULL,0xe54bca55b86adb39ULL,0x1d7a3afd6c478063ULL,0x519ec608e7669eddULL,
0x0e5715a2d149aa23ULL,0x177d4571848ff194ULL,0xeeb55f3241014c22ULL,0x0f5e5ca13a6e2ec2ULL,
0x8029927b75f5c361ULL,0xad139fabc3d6e436ULL,0x0d5df1a94ccf402fULL,0x3e8bd948bea5dfc8ULL,
0xa5a0d357bd3ff77eULL,0xa2d12e251f74f645ULL,0x66fd9e525e81a082ULL,0x2e0c90ce7f687a49ULL,
0xc2e8bcbeba973bc5ULL,0x000001bce509745fULL,0x423777bbe6dab3d6ULL,0xd1661c7eaef06eb5ULL,
0xa1781f354daacfd8ULL,0x2d11284a2b16affcULL,0xf1fc4f67fa891d1fULL,0x73ecc25dcb920adaULL,
0xae610c22c2a12651ULL,0x96e0a810d356b78aULL,0x5a9a381f2fe7870fULL,0xd5ad62ede94e5530ULL,
0xd225e5e8368d1427ULL,0x65977b70c7af4631ULL,0x99f889b2de39d74fULL,0x233f30bf54e1d143ULL,
0x9a9675d3d9a63c97ULL,0x5470554ff334f9a8ULL,0x166acb744a4f5688ULL,0x70c74caab2e4aeadULL,
0xf0d091646f294d12ULL,0x57b82a89684031d1ULL,0xefd95a5a61be0b6bULL,0x2fbd12e969f2f29aULL,
0x9bd37013feff9fe8ULL,0x3f9b0404d6085a06ULL,0x4940c1f3166cfe15ULL,0x09542c4dcdf3defbULL,
0xb4c5218385cd5ce3ULL,0xc935b7dc4462a641ULL,0x3417f8a68ed3b63fULL,0xb80959295b215b40ULL,
0xf99cdaef3b8c8572ULL,0x018c0614f8fcb95dULL,0x1b14accd1a3acdf3ULL,0x84d471f200bb732dULL,
0xc1a3110e95e8da16ULL,0x430a7220bf1a82b8ULL,0xb77e090d39df210eULL,0x5ef4bd9f3cd05e9dULL,
0x9d4ff6da7e57a444ULL,0xda1d60e183d4a5f8ULL,0xb287c38417998e47ULL,0xfe3edc121bb31886ULL,
0xc7fe3ccc980ccbefULL,0xe46fb590189bfd03ULL,0x3732fd469a4c57dcULL,0x7ef700a07cf1ad65ULL,
0x59c64468a31d8859ULL,0x762fb0b4d45b61f6ULL,0x155baed099047718ULL,0x68755e4c3d50baa6ULL,
0xe9214e7f22d8b4dfULL,0x2addbf532eac95f4ULL,0x32ae3909b4bd0109ULL,0x834df537b08e3450ULL,
0xfa209da84220728dULL,0x9e691d9b9efe23f7ULL,0x0446d288c4ae8d7fULL,0x7b4cc524e169785bULL,
0x21d87f0135ca1385ULL,0xcebb400f137b8aa5ULL,0x272e2b66580796beULL,0x3612264125c2b0deULL,
0x057702bdad1efbb2ULL,0xd4babb8eacf84be9ULL,0x91583139641bc67bULL,0x8bdc2de08036e024ULL,
0x603c8156f49f68edULL,0xf7d236f7dbef5111ULL,0x9727c4598ad21e80ULL,0xa08a0896670a5fd7ULL,
0xcb4a8f4309eba9cbULL,0x81af564b0f7036a1ULL,0xc0b99aa778199abdULL,0x959f1ec83fc8e952ULL,
0x8c505077794a81b9ULL,0x3acaaf8f056338f0ULL,0x07b43f50627a6778ULL,0x4a44ab49f5eccc77ULL,
0x3bc3d6e4b679ee98ULL,0x9cc0d4d1cf14108cULL,0x4406c00b206bc8a0ULL,0x82a18854c8d72d89ULL,
0x67e366b35c3c432cULL,0xb923dd61102b37f2ULL,0x56ab2779d884271dULL,0xbe83e1b0ff1525afULL,
0xfb7c65d4217e49a9ULL,0x6bdbe0e76d48e7d4ULL,0x08df828745d9179eULL,0x22ea6a9add53bd34ULL,
0xe36e141c5622200aULL,0x7f805d1b8cb750eeULL,0xafe5c7a59f58e837ULL,0xe27f996a4fb1c23cULL,
0xd3867dfb0775f0d0ULL,0xd0e673de6e88891aULL,0x123aeb9eafb86c25ULL,0x30f1d5d5c145b895ULL,
0xbb434a2dee7269e7ULL,0x78cb67ecf931fa38ULL,0xf33b0372323bbf9cULL,0x52d66336fb279c74ULL,
0x505f33ac0afb4eaaULL,0xe8a5cd99a2cce187ULL,0x534974801e2d30bbULL,0x8d2d5711d5876d90ULL,
0x1f1a412891bc038eULL,0xd6e2e71d82e56648ULL,0x74036c3a497732b7ULL,0x89b67ed96361f5abULL,
0xffed95d8f1ea02a2ULL,0xe72b3bd61464d43dULL,0xa6300f170bdc4820ULL,0xebc18760ed78a77aULL,
};
static const uint64_t t2[256] =
{
0xe6a6be5a05a12138ULL,0xb5a122a5b4f87c98ULL,0x563c6089140b6990ULL,0x4c46cb2e391f5dd5ULL,
0xd932addbc9b79434ULL,0x08ea70e42015aff5ULL,0xd765a6673e478cf1ULL,0xc4fb757eab278d99ULL,
0xdf11c6862d6e0692ULL,0xddeb84f10d7f3b16ULL,0x6f2ef604a665ea04ULL,0x4a8e0f0ff0e0dfb3ULL,
0xa5edeef83dbcba51ULL,0xfc4f0a2a0ea4371eULL,0xe83e1da85cb38429ULL,0xdc8ff882ba1b1ce2ULL,
0xcd45505e8353e80dULL,0x18d19a00d4db0717ULL,0x34a0cfeda5f38101ULL,0x0be77e518887caf2ULL,
0x1e341438b3c45136ULL,0xe05797f49089ccf9ULL,0xffd23f9df2591d14ULL,0x543dda228595c5cdULL,
0x661f81fd99052a33ULL,0x8736e641db0f7b76ULL,0x15227725418e5307ULL,0xe25f7f46162eb2faULL,
0x48a8b2126c13d9feULL,0xafdc541792e76eeaULL,0x03d912bfc6d1898fULL,0x31b1aafa1b83f51bULL,
0xf1ac2796e42ab7d9ULL,0x40a3a7d7fcd2ebacULL,0x1056136d0afbbcc5ULL,0x7889e1dd9a6d0c85ULL,
0xd33525782a7974aaULL,0xa7e25d09078ac09bULL,0xbd4138b3eac6edd0ULL,0x920abfbe71eb9e70ULL,
0xa2a5d0f54fc2625cULL,0xc054e36b0b1290a3ULL,0xf6dd59ff62fe932bULL,0x3537354511a8ac7dULL,
0xca845e9172fadcd4ULL,0x84f82b60329d20dcULL,0x79c62ce1cd672f18ULL,0x8b09a2add124642cULL,
0xd0c1e96a19d9e726ULL,0x5a786a9b4ba9500cULL,0x0e020336634c43f3ULL,0xc17b474aeb66d822ULL,
0x6a731ae3ec9baac2ULL,0x8226667ae0840258ULL,0x67d4567691caeca5ULL,0x1d94155c4875adb5ULL,
0x6d00fd985b813fdfULL,0x51286efcb774cd06ULL,0x5e8834471fa744afULL,0xf72ca0aee761ae2eULL,
0xbe40e4cdaee8e09aULL,0xe9970bbb5118f665ULL,0x726e4beb33df1964ULL,0x703b000729199762ULL,
0x4631d816f5ef30a7ULL,0xb880b5b51504a6beULL,0x641793c37ed84b6cULL,0x7b21ed77f6e97d96ULL,
0x776306312ef96b73ULL,0xae528948e86ff3f4ULL,0x53dbd7f286a3f8f8ULL,0x16cadce74cfc1063ULL,
0x005c19bdfa52c6ddULL,0x68868f5d64d46ad3ULL,0x3a9d512ccf1e186aULL,0x367e62c2385660aeULL,
0xe359e7ea77dcb1d7ULL,0x526c0773749abe6eULL,0x735ae5f9d09f734bULL,0x493fc7cc8a558ba8ULL,
0xb0b9c1533041ab45ULL,0x321958ba470a59bdULL,0x852db00b5f46c393ULL,0x91209b2bd336b0e5ULL,
0x6e604f7d659ef19fULL,0xb99a8ae2782ccb24ULL,0xccf52ab6c814c4c7ULL,0x4727d9afbe11727bULL,
0x7e950d0c0121b34dULL,0x756f435670ad471fULL,0xf5add442615a6849ULL,0x4e87e09980b9957aULL,
0x2acfa1df50aee355ULL,0xd898263afd2fd556ULL,0xc8f4924dd80c8fd6ULL,0xcf99ca3d754a173aULL,
0xfe477bacaf91bf3cULL,0xed5371f6d690c12dULL,0x831a5c285e687094ULL,0xc5d3c90a3708a0a4ULL,
0x0f7f903717d06580ULL,0x19f9bb13b8fdf27fULL,0xb1bd6f1b4d502843ULL,0x1c761ba38fff4012ULL,
0x0d1530c4e2e21f3bULL,0x8943ce69a7372c8aULL,0xe5184e11feb5ce66ULL,0x618bdb80bd736621ULL,
0x7d29bad68b574d0bULL,0x81bb613e25e6fe5bULL,0x071c9c10bc07913fULL,0xc7beeb7909ac2d97ULL,
0xc3e58d353bc5d757ULL,0xeb017892f38f61e8ULL,0xd4effb9c9b1cc21aULL,0x99727d26f494f7abULL,
0xa3e063a2956b3e03ULL,0x9d4a8b9a4aa09c30ULL,0x3f6ab7d500090fb4ULL,0x9cc0f2a057268ac0ULL,
0x3dee9d2dedbf42d1ULL,0x330f49c87960a972ULL,0xc6b2720287421b41ULL,0x0ac59ec07c00369cULL,
0xef4eac49cb353425ULL,0xf450244eef0129d8ULL,0x8acc46e5caf4deb6ULL,0x2ffeab63989263f7ULL,
0x8f7cb9fe5d7a4578ULL,0x5bd8f7644e634635ULL,0x427a7315bf2dc900ULL,0x17d0c4aa2125261cULL,
0x3992486c93518e50ULL,0xb4cbfee0a2d7d4c3ULL,0x7c75d6202c5ddd8dULL,0xdbc295d8e35b6c61ULL,
0x60b369d302032b19ULL,0xce42685fdce44132ULL,0x06f3ddb9ddf65610ULL,0x8ea4d21db5e148f0ULL,
0x20b0fce62fcd496fULL,0x2c1b912358b0ee31ULL,0xb28317b818f5a308ULL,0xa89c1e189ca6d2cfULL,
0x0c6b18576aaadbc8ULL,0xb65deaa91299fae3ULL,0xfb2b794b7f1027e7ULL,0x04e4317f443b5bebULL,
0x4b852d325939d0a6ULL,0xd5ae6beefb207ffcULL,0x309682b281c7d374ULL,0xbae309a194c3b475ULL,
0x8cc3f97b13b49f05ULL,0x98a9422ff8293967ULL,0x244b16b01076ff7cULL,0xf8bf571c663d67eeULL,
0x1f0d6758eee30da1ULL,0xc9b611d97adeb9b7ULL,0xb7afd5887b6c57a2ULL,0x6290ae846b984fe1ULL,
0x94df4cdeacc1a5fdULL,0x058a5bd1c5483affULL,0x63166cc142ba3c37ULL,0x8db8526eb2f76f40ULL,
0xe10880036f0d6d4eULL,0x9e0523c9971d311dULL,0x45ec2824cc7cd691ULL,0x575b8359e62382c9ULL,
0xfa9e400dc4889995ULL,0xd1823ecb45721568ULL,0xdafd983b8206082fULL,0xaa7d29082386a8cbULL,
0x269fcd4403b87588ULL,0x1b91f5f728bdd1e0ULL,0xe4669f39040201f6ULL,0x7a1d7c218cf04adeULL,
0x65623c29d79ce5ceULL,0x2368449096c00bb1ULL,0xab9bf1879da503baULL,0xbc23ecb1a458058eULL,
0x9a58df01bb401eccULL,0xa070e868a85f143dULL,0x4ff188307df2239eULL,0x14d565b41a641183ULL,
0xee13337452701602ULL,0x950e3dcf3f285e09ULL,0x59930254b9c80953ULL,0x3bf299408930da6dULL,
0xa955943f53691387ULL,0xa15edecaa9cb8784ULL,0x29142127352be9a0ULL,0x76f0371fff4e7afbULL,
0x0239f450274f2228ULL,0xbb073af01d5e868bULL,0xbfc80571c10e96c1ULL,0xd267088568222e23ULL,
0x9671a3d48e80b5b0ULL,0x55b5d38ae193bb81ULL,0x693ae2d0a18b04b8ULL,0x5c48b4ecadd5335fULL,
0xfd743b194916a1caULL,0x2577018134be98c4ULL,0xe77987e83c54a4adULL,0x28e11014da33e1b9ULL,
0x270cc59e226aa213ULL,0x71495f756d1a5f60ULL,0x9be853fb60afef77ULL,0xadc786a7f7443dbfULL,
0x0904456173b29a82ULL,0x58bc7a66c232bd5eULL,0xf306558c673ac8b2ULL,0x41f639c6b6c9772aULL,
0x216defe99fda35daULL,0x11640cc71c7be615ULL,0x93c43694565c5527ULL,0xea038e6246777839ULL,
0xf9abf3ce5a3e2469ULL,0x741e768d0fd312d2ULL,0x0144b883ced652c6ULL,0xc20b5a5ba33f8552ULL,
0x1ae69633c3435a9dULL,0x97a28ca4088cfdecULL,0x8824a43c1e96f420ULL,0x37612fa66eeea746ULL,
0x6b4cb165f9cf0e5aULL,0x43aa1c06a0abfb4aULL,0x7f4dc26ff162796bULL,0x6cbacc8e54ed9b0fULL,
0xa6b7ffefd2bb253eULL,0x2e25bc95b0a29d4fULL,0x86d6a58bdef1388cULL,0xded74ac576b6f054ULL,
0x8030bdbc2b45805dULL,0x3c81af70e94d9289ULL,0x3eff6dda9e3100dbULL,0xb38dc39fdfcc8847ULL,
0x123885528d17b87eULL,0xf2da0ed240b1b642ULL,0x44cefadcd54bf9a9ULL,0x1312200e433c7ee6ULL,
0x9ffcc84f3a78c748ULL,0xf0cd1f72248576bbULL,0xec6974053638cfe4ULL,0x2ba7b67c0cec4e4cULL,
0xac2f4df3e5ce32edULL,0xcb33d14326ea4c11ULL,0xa4e9044cc77e58bcULL,0x5f513293d934fcefULL,
0x5dc9645506e55444ULL,0x50de418f317de40aULL,0x388cb31a69dde259ULL,0x2db4a83455820a86ULL,
0x9010a91e84711ae9ULL,0x4df7f0b7b1498371ULL,0xd62a2eabc0977179ULL,0x22fac097aa8d5c0eULL,
};
static const uint64_t t3[256]= {
0xf49fcc2ff1daf39bULL,0x487fd5c66ff29281ULL,0xe8a30667fcdca83fULL,0x2c9b4be3d2fcce63ULL,
0xda3ff74b93fbbbc2ULL,0x2fa165d2fe70ba66ULL,0xa103e279970e93d4ULL,0xbecdec77b0e45e71ULL,
0xcfb41e723985e497ULL,0xb70aaa025ef75017ULL,0xd42309f03840b8e0ULL,0x8efc1ad035898579ULL,
0x96c6920be2b2abc5ULL,0x66af4163375a9172ULL,0x2174abdcca7127fbULL,0xb33ccea64a72ff41ULL,
0xf04a4933083066a5ULL,0x8d970acdd7289af5ULL,0x8f96e8e031c8c25eULL,0xf3fec02276875d47ULL,
0xec7bf310056190ddULL,0xf5adb0aebb0f1491ULL,0x9b50f8850fd58892ULL,0x4975488358b74de8ULL,
0xa3354ff691531c61ULL,0x0702bbe481d2c6eeULL,0x89fb24057deded98ULL,0xac3075138596e902ULL,
0x1d2d3580172772edULL,0xeb738fc28e6bc30dULL,0x5854ef8f63044326ULL,0x9e5c52325add3bbeULL,
0x90aa53cf325c4623ULL,0xc1d24d51349dd067ULL,0x2051cfeea69ea624ULL,0x13220f0a862e7e4fULL,
0xce39399404e04864ULL,0xd9c42ca47086fcb7ULL,0x685ad2238a03e7ccULL,0x066484b2ab2ff1dbULL,
0xfe9d5d70efbf79ecULL,0x5b13b9dd9c481854ULL,0x15f0d475ed1509adULL,0x0bebcd060ec79851ULL,
0xd58c6791183ab7f8ULL,0xd1187c5052f3eee4ULL,0xc95d1192e54e82ffULL,0x86eea14cb9ac6ca2ULL,
0x3485beb153677d5dULL,0xdd191d781f8c492aULL,0xf60866baa784ebf9ULL,0x518f643ba2d08c74ULL,
0x8852e956e1087c22ULL,0xa768cb8dc410ae8dULL,0x38047726bfec8e1aULL,0xa67738b4cd3b45aaULL,
0xad16691cec0dde19ULL,0xc6d4319380462e07ULL,0xc5a5876d0ba61938ULL,0x16b9fa1fa58fd840ULL,
0x188ab1173ca74f18ULL,0xabda2f98c99c021fULL,0x3e0580ab134ae816ULL,0x5f3b05b773645abbULL,
0x2501a2be5575f2f6ULL,0x1b2f74004e7e8ba9ULL,0x1cd7580371e8d953ULL,0x7f6ed89562764e30ULL,
0xb15926ff596f003dULL,0x9f65293da8c5d6b9ULL,0x6ecef04dd690f84cULL,0x4782275fff33af88ULL,
0xe41433083f820801ULL,0xfd0dfe409a1af9b5ULL,0x4325a3342cdb396bULL,0x8ae77e62b301b252ULL,
0xc36f9e9f6655615aULL,0x85455a2d92d32c09ULL,0xf2c7dea949477485ULL,0x63cfb4c133a39ebaULL,
0x83b040cc6ebc5462ULL,0x3b9454c8fdb326b0ULL,0x56f56a9e87ffd78cULL,0x2dc2940d99f42bc6ULL,
0x98f7df096b096e2dULL,0x19a6e01e3ad852bfULL,0x42a99ccbdbd4b40bULL,0xa59998af45e9c559ULL,
0x366295e807d93186ULL,0x6b48181bfaa1f773ULL,0x1fec57e2157a0a1dULL,0x4667446af6201ad5ULL,
0xe615ebcacfb0f075ULL,0xb8f31f4f68290778ULL,0x22713ed6ce22d11eULL,0x3057c1a72ec3c93bULL,
0xcb46acc37c3f1f2fULL,0xdbb893fd02aaf50eULL,0x331fd92e600b9fcfULL,0xa498f96148ea3ad6ULL,
0xa8d8426e8b6a83eaULL,0xa089b274b7735cdcULL,0x87f6b3731e524a11ULL,0x118808e5cbc96749ULL,
0x9906e4c7b19bd394ULL,0xafed7f7e9b24a20cULL,0x6509eadeeb3644a7ULL,0x6c1ef1d3e8ef0edeULL,
0xb9c97d43e9798fb4ULL,0xa2f2d784740c28a3ULL,0x7b8496476197566fULL,0x7a5be3e6b65f069dULL,
0xf96330ed78be6f10ULL,0xeee60de77a076a15ULL,0x2b4bee4aa08b9bd0ULL,0x6a56a63ec7b8894eULL,
0x02121359ba34fef4ULL,0x4cbf99f8283703fcULL,0x398071350caf30c8ULL,0xd0a77a89f017687aULL,
0xf1c1a9eb9e423569ULL,0x8c7976282dee8199ULL,0x5d1737a5dd1f7abdULL,0x4f53433c09a9fa80ULL,
0xfa8b0c53df7ca1d9ULL,0x3fd9dcbc886ccb77ULL,0xc040917ca91b4720ULL,0x7dd00142f9d1dcdfULL,
0x8476fc1d4f387b58ULL,0x23f8e7c5f3316503ULL,0x032a2244e7e37339ULL,0x5c87a5d750f5a74bULL,
0x082b4cc43698992eULL,0xdf917becb858f63cULL,0x3270b8fc5bf86ddaULL,0x10ae72bb29b5dd76ULL,
0x576ac94e7700362bULL,0x1ad112dac61efb8fULL,0x691bc30ec5faa427ULL,0xff246311cc327143ULL,
0x3142368e30e53206ULL,0x71380e31e02ca396ULL,0x958d5c960aad76f1ULL,0xf8d6f430c16da536ULL,
0xc8ffd13f1be7e1d2ULL,0x7578ae66004ddbe1ULL,0x05833f01067be646ULL,0xbb34b5ad3bfe586dULL,
0x095f34c9a12b97f0ULL,0x247ab64525d60ca8ULL,0xdcdbc6f3017477d1ULL,0x4a2e14d4decad24dULL,
0xbdb5e6d9be0a1eebULL,0x2a7e70f7794301abULL,0xdef42d8a270540fdULL,0x01078ec0a34c22c1ULL,
0xe5de511af4c16387ULL,0x7ebb3a52bd9a330aULL,0x77697857aa7d6435ULL,0x004e831603ae4c32ULL,
0xe7a21020ad78e312ULL,0x9d41a70c6ab420f2ULL,0x28e06c18ea1141e6ULL,0xd2b28cbd984f6b28ULL,
0x26b75f6c446e9d83ULL,0xba47568c4d418d7fULL,0xd80badbfe6183d8eULL,0x0e206d7f5f166044ULL,
0xe258a43911cbca3eULL,0x723a1746b21dc0bcULL,0xc7caa854f5d7cdd3ULL,0x7cac32883d261d9cULL,
0x7690c26423ba942cULL,0x17e55524478042b8ULL,0xe0be477656a2389fULL,0x4d289b5e67ab2da0ULL,
0x44862b9c8fbbfd31ULL,0xb47cc8049d141365ULL,0x822c1b362b91c793ULL,0x4eb14655fb13dfd8ULL,
0x1ecbba0714e2a97bULL,0x6143459d5cde5f14ULL,0x53a8fbf1d5f0ac89ULL,0x97ea04d81c5e5b00ULL,
0x622181a8d4fdb3f3ULL,0xe9bcd341572a1208ULL,0x1411258643cce58aULL,0x9144c5fea4c6e0a4ULL,
0x0d33d06565cf620fULL,0x54a48d489f219ca1ULL,0xc43e5eac6d63c821ULL,0xa9728b3a72770dafULL,
0xd7934e7b20df87efULL,0xe35503b61a3e86e5ULL,0xcae321fbc819d504ULL,0x129a50b3ac60bfa6ULL,
0xcd5e68ea7e9fb6c3ULL,0xb01c90199483b1c7ULL,0x3de93cd5c295376cULL,0xaed52edf2ab9ad13ULL,
0x2e60f512c0a07884ULL,0xbc3d86a3e36210c9ULL,0x35269d9b163951ceULL,0x0c7d6e2ad0cdb5faULL,
0x59e86297d87f5733ULL,0x298ef221898db0e7ULL,0x55000029d1a5aa7eULL,0x8bc08ae1b5061b45ULL,
0xc2c31c2b6c92703aULL,0x94cc596baf25ef42ULL,0x0a1d73db22540456ULL,0x04b6a0f9d9c4179aULL,
0xeffdafa2ae3d3c60ULL,0xf7c8075bb49496c4ULL,0x9cc5c7141d1cd4e3ULL,0x78bd1638218e5534ULL,
0xb2f11568f850246aULL,0xedfabcfa9502bc29ULL,0x796ce5f2da23051bULL,0xaae128b0dc93537cULL,
0x3a493da0ee4b29aeULL,0xb5df6b2c416895d7ULL,0xfcabbd25122d7f37ULL,0x70810b58105dc4b1ULL,
0xe10fdd37f7882a90ULL,0x524dcab5518a3f5cULL,0x3c9e85878451255bULL,0x4029828119bd34e2ULL,
0x74a05b6f5d3ceccbULL,0xb610021542e13ecaULL,0x0ff979d12f59e2acULL,0x6037da27e4f9cc50ULL,
0x5e92975a0df1847dULL,0xd66de190d3e623feULL,0x5032d6b87b568048ULL,0x9a36b7ce8235216eULL,
0x80272a7a24f64b4aULL,0x93efed8b8c6916f7ULL,0x37ddbff44cce1555ULL,0x4b95db5d4b99bd25ULL,
0x92d3fda169812fc0ULL,0xfb1a4a9a90660bb6ULL,0x730c196946a4b9b2ULL,0x81e289aa7f49da68ULL,
0x64669a0f83b1a05fULL,0x27b3ff7d9644f48bULL,0xcc6b615c8db675b3ULL,0x674f20b9bcebbe95ULL,
0x6f31238275655982ULL,0x5ae488713e45cf05ULL,0xbf619f9954c21157ULL,0xeabac46040a8eae9ULL,
0x454c6fe9f2c0c1cdULL,0x419cf6496412691cULL,0xd3dc3bef265b0f70ULL,0x6d0e60f5c3578a9eULL,
};
static const uint64_t t4[256]=
{
0x5b0e608526323c55ULL,0x1a46c1a9fa1b59f5ULL, 0xa9e245a17c4c8ffaULL,0x65ca5159db2955d7ULL,
0x05db0a76ce35afc2ULL,0x81eac77ea9113d45ULL, 0x528ef88ab6ac0a0dULL,0xa09ea253597be3ffULL,
0x430ddfb3ac48cd56ULL,0xc4b3a67af45ce46fULL, 0x4ececfd8fbe2d05eULL,0x3ef56f10b39935f0ULL,
0x0b22d6829cd619c6ULL,0x17fd460a74df2069ULL, 0x6cf8cc8e8510ed40ULL,0xd6c824bf3a6ecaa7ULL,
0x61243d581a817049ULL,0x048bacb6bbc163a2ULL, 0xd9a38ac27d44cc32ULL,0x7fddff5baaf410abULL,
0xad6d495aa804824bULL,0xe1a6a74f2d8c9f94ULL, 0xd4f7851235dee8e3ULL,0xfd4b7f886540d893ULL,
0x247c20042aa4bfdaULL,0x096ea1c517d1327cULL, 0xd56966b4361a6685ULL,0x277da5c31221057dULL,
0x94d59893a43acff7ULL,0x64f0c51ccdc02281ULL, 0x3d33bcc4ff6189dbULL,0xe005cb184ce66af1ULL,
0xff5ccd1d1db99beaULL,0xb0b854a7fe42980fULL, 0x7bd46a6a718d4b9fULL,0xd10fa8cc22a5fd8cULL,
0xd31484952be4bd31ULL,0xc7fa975fcb243847ULL, 0x4886ed1e5846c407ULL,0x28cddb791eb70b04ULL,
0xc2b00be2f573417fULL,0x5c9590452180f877ULL, 0x7a6bddfff370eb00ULL,0xce509e38d6d9d6a4ULL,
0xebeb0f00647fa702ULL,0x1dcc06cf76606f06ULL, 0xe4d9f28ba286ff0aULL,0xd85a305dc918c262ULL,
0x475b1d8732225f54ULL,0x2d4fb51668ccb5feULL, 0xa679b9d9d72bba20ULL,0x53841c0d912d43a5ULL,
0x3b7eaa48bf12a4e8ULL,0x781e0e47f22f1ddfULL, 0xeff20ce60ab50973ULL,0x20d261d19dffb742ULL,
0x16a12b03062a2e39ULL,0x1960eb2239650495ULL, 0x251c16fed50eb8b8ULL,0x9ac0c330f826016eULL,
0xed152665953e7671ULL,0x02d63194a6369570ULL, 0x5074f08394b1c987ULL,0x70ba598c90b25ce1ULL,
0x794a15810b9742f6ULL,0x0d5925e9fcaf8c6cULL, 0x3067716cd868744eULL,0x910ab077e8d7731bULL,
0x6a61bbdb5ac42f61ULL,0x93513efbf0851567ULL, 0xf494724b9e83e9d5ULL,0xe887e1985c09648dULL,
0x34b1d3c675370cfdULL,0xdc35e433bc0d255dULL, 0xd0aab84234131be0ULL,0x08042a50b48b7eafULL,
0x9997c4ee44a3ab35ULL,0x829a7b49201799d0ULL, 0x263b8307b7c54441ULL,0x752f95f4fd6a6ca6ULL,
0x927217402c08c6e5ULL,0x2a8ab754a795d9eeULL, 0xa442f7552f72943dULL,0x2c31334e19781208ULL,
0x4fa98d7ceaee6291ULL,0x55c3862f665db309ULL, 0xbd0610175d53b1f3ULL,0x46fe6cb840413f27ULL,
0x3fe03792df0cfa59ULL,0xcfe700372eb85e8fULL, 0xa7be29e7adbce118ULL,0xe544ee5cde8431ddULL,
0x8a781b1b41f1873eULL,0xa5c94c78a0d2f0e7ULL, 0x39412e2877b60728ULL,0xa1265ef3afc9a62cULL,
0xbcc2770c6a2506c5ULL,0x3ab66dd5dce1ce12ULL, 0xe65499d04a675b37ULL,0x7d8f523481bfd216ULL,
0x0f6f64fcec15f389ULL,0x74efbe618b5b13c8ULL, 0xacdc82b714273e1dULL,0xdd40bfe003199d17ULL,
0x37e99257e7e061f8ULL,0xfa52626904775aaaULL, 0x8bbbf63a463d56f9ULL,0xf0013f1543a26e64ULL,
0xa8307e9f879ec898ULL,0xcc4c27a4150177ccULL, 0x1b432f2cca1d3348ULL,0xde1d1f8f9f6fa013ULL,
0x606602a047a7ddd6ULL,0xd237ab64cc1cb2c7ULL, 0x9b938e7225fcd1d3ULL,0xec4e03708e0ff476ULL,
0xfeb2fbda3d03c12dULL,0xae0bced2ee43889aULL, 0x22cb8923ebfb4f43ULL,0x69360d013cf7396dULL,
0x855e3602d2d4e022ULL,0x073805bad01f784cULL, 0x33e17a133852f546ULL,0xdf4874058ac7b638ULL,
0xba92b29c678aa14aULL,0x0ce89fc76cfaadcdULL, 0x5f9d4e0908339e34ULL,0xf1afe9291f5923b9ULL,
0x6e3480f60f4a265fULL,0xeebf3a2ab29b841cULL, 0xe21938a88f91b4adULL,0x57dfeff845c6d3c3ULL,
0x2f006b0bf62caaf2ULL,0x62f479ef6f75ee78ULL, 0x11a55ad41c8916a9ULL,0xf229d29084fed453ULL,
0x42f1c27b16b000e6ULL,0x2b1f76749823c074ULL, 0x4b76eca3c2745360ULL,0x8c98f463b91691bdULL,
0x14bcc93cf1ade66aULL,0x8885213e6d458397ULL, 0x8e177df0274d4711ULL,0xb49b73b5503f2951ULL,
0x10168168c3f96b6bULL,0x0e3d963b63cab0aeULL, 0x8dfc4b5655a1db14ULL,0xf789f1356e14de5cULL,
0x683e68af4e51dac1ULL,0xc9a84f9d8d4b0fd9ULL, 0x3691e03f52a0f9d1ULL,0x5ed86e46e1878e80ULL,
0x3c711a0e99d07150ULL,0x5a0865b20c4e9310ULL, 0x56fbfc1fe4f0682eULL,0xea8d5de3105edf9bULL,
0x71abfdb12379187aULL,0x2eb99de1bee77b9cULL, 0x21ecc0ea33cf4523ULL,0x59a4d7521805c7a1ULL,
0x3896f5eb56ae7c72ULL,0xaa638f3db18f75dcULL, 0x9f39358dabe9808eULL,0xb7defa91c00b72acULL,
0x6b5541fd62492d92ULL,0x6dc6dee8f92e4d5bULL, 0x353f57abc4beea7eULL,0x735769d6da5690ceULL,
0x0a234aa642391484ULL,0xf6f9508028f80d9dULL, 0xb8e319a27ab3f215ULL,0x31ad9c1151341a4dULL,
0x773c22a57bef5805ULL,0x45c7561a07968633ULL, 0xf913da9e249dbe36ULL,0xda652d9b78a64c68ULL,
0x4c27a97f3bc334efULL,0x76621220e66b17f4ULL, 0x967743899acd7d0bULL,0xf3ee5bcae0ed6782ULL,
0x409f753600c879fcULL,0x06d09a39b5926db6ULL, 0x6f83aeb0317ac588ULL,0x01e6ca4a86381f21ULL,
0x66ff3462d19f3025ULL,0x72207c24ddfd3bfbULL, 0x4af6b6d3e2ece2ebULL,0x9c994dbec7ea08deULL,
0x49ace597b09a8bc4ULL,0xb38c4766cf0797baULL, 0x131b9373c57c2a75ULL,0xb1822cce61931e58ULL,
0x9d7555b909ba1c0cULL,0x127fafdd937d11d2ULL, 0x29da3badc66d92e4ULL,0xa2c1d57154c2ecbcULL,
0x58c5134d82f6fe24ULL,0x1c3ae3515b62274fULL, 0xe907c82e01cb8126ULL,0xf8ed091913e37fcbULL,
0x3249d8f9c80046c9ULL,0x80cf9bede388fb63ULL, 0x1881539a116cf19eULL,0x5103f3f76bd52457ULL,
0x15b7e6f5ae47f7a8ULL,0xdbd7c6ded47e9ccfULL, 0x44e55c410228bb1aULL,0xb647d4255edb4e99ULL,
0x5d11882bb8aafc30ULL,0xf5098bbb29d3212aULL, 0x8fb5ea14e90296b3ULL,0x677b942157dd025aULL,
0xfb58e7c0a390acb5ULL,0x89d3674c83bd4a01ULL, 0x9e2da4df4bf3b93bULL,0xfcc41e328cab4829ULL,
0x03f38c96ba582c52ULL,0xcad1bdbd7fd85db2ULL, 0xbbb442c16082ae83ULL,0xb95fe86ba5da9ab0ULL,
0xb22e04673771a93fULL,0x845358c9493152d8ULL, 0xbe2a488697b4541eULL,0x95a2dc2dd38e6966ULL,
0xc02c11ac923c852bULL,0x2388b1990df2a87bULL, 0x7c8008fa1b4f37beULL,0x1f70d0c84d54e503ULL,
0x5490adec7ece57d4ULL,0x002b3c27d9063a3aULL, 0x7eaea3848030a2bfULL,0xc602326ded2003c0ULL,
0x83a7287d69a94086ULL,0xc57a5fcb30f57a8aULL, 0xb56844e479ebe779ULL,0xa373b40f05dcbce9ULL,
0xd71a786e88570ee2ULL,0x879cbacdbde8f6a0ULL, 0x976ad1bcc164a32fULL,0xab21e25e9666d78bULL,
0x901063aae5e5c33cULL,0x9818b34448698d90ULL, 0xe36487ae3e1e8abbULL,0xafbdf931893bdcb4ULL,
0x6345a0dc5fbbd519ULL,0x8628fe269b9465caULL, 0x1e5d01603f9c51ecULL,0x4de44006a15049b7ULL,
0xbf6c70e5f776cbb1ULL,0x411218f2ef552bedULL, 0xcb0c0708705a36a3ULL,0xe74d14754f986044ULL,
0xcd56d9430ea8280eULL,0xc12591d7535f5065ULL, 0xc83223f1720aef96ULL,0xc3a0396f7363a51fULL,
};
void cryptonite_tiger_init(struct tiger_ctx *ctx)
{
memset(ctx, 0, sizeof(*ctx));
ctx->h[0] = 0x0123456789abcdefULL;
ctx->h[1] = 0xfedcba9876543210ULL;
ctx->h[2] = 0xf096a5b4c3b2e187ULL;
}
static inline void tiger_do_chunk(struct tiger_ctx *ctx, uint64_t *buf)
{
uint64_t x0, x1, x2, x3, x4, x5, x6, x7;
uint64_t a,b,c;
a = ctx->h[0];
b = ctx->h[1];
c = ctx->h[2];
x0 = cpu_to_le64(buf[0]); x1 = cpu_to_le64(buf[1]); x2 = cpu_to_le64(buf[2]); x3 = cpu_to_le64(buf[3]);
x4 = cpu_to_le64(buf[4]); x5 = cpu_to_le64(buf[5]); x6 = cpu_to_le64(buf[6]); x7 = cpu_to_le64(buf[7]);
#define BYTEOF(c, n) ((uint8_t) (c >> ((n * 8))))
#define ROUND(a,b,c,x,mul) \
c ^= x; \
a -= t1[BYTEOF(c,0)] ^ t2[BYTEOF(c,2)] ^ t3[BYTEOF(c,4)] ^ t4[BYTEOF(c,6)]; \
b += t4[BYTEOF(c,1)] ^ t3[BYTEOF(c,3)] ^ t2[BYTEOF(c,5)] ^ t1[BYTEOF(c,7)]; \
b *= mul;
#define PASS(a,b,c,mul) \
ROUND(a,b,c,x0,mul); \
ROUND(b,c,a,x1,mul); \
ROUND(c,a,b,x2,mul); \
ROUND(a,b,c,x3,mul); \
ROUND(b,c,a,x4,mul); \
ROUND(c,a,b,x5,mul); \
ROUND(a,b,c,x6,mul); \
ROUND(b,c,a,x7,mul)
#define SCHEDULE() \
x0 -= x7 ^ 0xa5a5a5a5a5a5a5a5ULL; \
x1 ^= x0; \
x2 += x1; \
x3 -= x2 ^ ((~x1)<<19); \
x4 ^= x3; \
x5 += x4; \
x6 -= x5 ^ ((~x4)>>23); \
x7 ^= x6; \
x0 += x7; \
x1 -= x0 ^ ((~x7)<<19); \
x2 ^= x1; \
x3 += x2; \
x4 -= x3 ^ ((~x2)>>23); \
x5 ^= x4; \
x6 += x5; \
x7 -= x6 ^ 0x0123456789abcdefULL
PASS(a,b,c,5);
SCHEDULE();
PASS(c,a,b,7);
SCHEDULE();
PASS(b,c,a,9);
ctx->h[0] ^= a;
ctx->h[1] = b - ctx->h[1];
ctx->h[2] += c;
}
void cryptonite_tiger_update(struct tiger_ctx *ctx, uint8_t *data, uint32_t len)
{
uint32_t index, to_fill;
index = (uint32_t) (ctx->sz & 0x3f);
to_fill = 64 - index;
ctx->sz += len;
/* process partial buffer if there's enough data to make a block */
if (index && len >= to_fill) {
memcpy(ctx->buf + index, data, to_fill);
tiger_do_chunk(ctx, (uint64_t *) ctx->buf);
len -= to_fill;
data += to_fill;
index = 0;
}
/* process as much 64-block as possible */
for (; len >= 64; len -= 64, data += 64)
tiger_do_chunk(ctx, (uint64_t *) data);
/* append data into buf */
if (len)
memcpy(ctx->buf + index, data, len);
}
void cryptonite_tiger_finalize(struct tiger_ctx *ctx, uint8_t *out)
{
static uint8_t padding[64] = { 0x01, };
uint64_t bits;
uint32_t index, padlen;
uint64_t *p = (uint64_t *) out;
/* add padding and update data with it */
bits = cpu_to_le64(ctx->sz << 3);
/* pad out to 56 */
index = (uint32_t) (ctx->sz & 0x3f);
padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
cryptonite_tiger_update(ctx, padding, padlen);
/* append length */
cryptonite_tiger_update(ctx, (uint8_t *) &bits, sizeof(bits));
/* output hash */
p[0] = cpu_to_le64(ctx->h[0]);
p[1] = cpu_to_le64(ctx->h[1]);
p[2] = cpu_to_le64(ctx->h[2]);
}

43
cbits/cryptonite_tiger.h Normal file
View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2006-2009 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_TIGER_H
#define CRYPTOHASH_TIGER_H
#include <stdint.h>
struct tiger_ctx
{
uint64_t sz;
uint8_t buf[64];
uint64_t h[3];
};
#define TIGER_DIGEST_SIZE 24
#define TIGER_CTX_SIZE (sizeof(struct tiger_ctx))
void cryptonite_tiger_init(struct tiger_ctx *ctx);
void cryptonite_tiger_update(struct tiger_ctx *ctx, uint8_t *data, uint32_t len);
void cryptonite_tiger_finalize(struct tiger_ctx *ctx, uint8_t *out);
#endif

1027
cbits/cryptonite_whirlpool.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,31 @@
#ifndef CRYPTOHASH_WHIRLPOOL_H
#define CRYPTOHASH_WHIRLPOOL_H
#include <stdint.h>
/*
* Whirlpool-specific definitions.
*/
#define DIGESTBYTES 64
#define DIGESTBITS (8*DIGESTBYTES) /* 512 */
#define WBLOCKBYTES 64
#define WBLOCKBITS (8*WBLOCKBYTES) /* 512 */
#define LENGTHBYTES 32
#define LENGTHBITS (8*LENGTHBYTES) /* 256 */
typedef struct whirlpool_ctx {
uint8_t bitLength[LENGTHBYTES]; /* global number of hashed bits (256-bit counter) */
uint8_t buffer[WBLOCKBYTES]; /* buffer of data to hash */
uint32_t bufferBits; /* current number of bits on the buffer */
uint32_t bufferPos; /* current (possibly incomplete) byte slot on the buffer */
uint64_t hash[DIGESTBYTES/8]; /* the hashing state */
} whirlpool_ctx;
void cryptonite_whirlpool_init(struct whirlpool_ctx * const ctx);
void cryptonite_whirlpool_update(struct whirlpool_ctx * const ctx, const uint8_t * const source, uint32_t len);
void cryptonite_whirlpool_finalize(struct whirlpool_ctx * const ctx, uint8_t * const result);
#endif

View File

@ -23,6 +23,22 @@ Library
Exposed-modules: Crypto.Cipher.ChaCha
Crypto.Cipher.Salsa
Crypto.MAC.Poly1305
Crypto.Hash.SHA1
Crypto.Hash.SHA224
Crypto.Hash.SHA256
Crypto.Hash.SHA384
Crypto.Hash.SHA512
Crypto.Hash.SHA512t
Crypto.Hash.SHA3
Crypto.Hash.MD2
Crypto.Hash.MD4
Crypto.Hash.MD5
Crypto.Hash.RIPEMD160
Crypto.Hash.Skein256
Crypto.Hash.Skein512
Crypto.Hash.Tiger
Crypto.Hash.Whirlpool
Other-modules: Crypto.Hash.Internal
Build-depends: base >= 4 && < 5
, bytestring
, securemem
@ -32,6 +48,18 @@ Library
C-sources: cbits/cryptonite_chacha.c
, cbits/cryptonite_salsa.c
, cbits/cryptonite_poly1305.c
, cbits/cryptonite_sha1.c
, cbits/cryptonite_sha256.c
, cbits/cryptonite_sha512.c
, cbits/cryptonite_sha3.c
, cbits/cryptonite_md2.c
, cbits/cryptonite_md4.c
, cbits/cryptonite_md5.c
, cbits/cryptonite_ripemd.c
, cbits/cryptonite_skein256.c
, cbits/cryptonite_skein512.c
, cbits/cryptonite_tiger.c
, cbits/cryptonite_whirlpool.c
if (arch(i386) || arch(x86_64))
CPP-options: -DARCH_IS_LITTLE_ENDIAN

221
tests/KATHash.hs Normal file
View File

@ -0,0 +1,221 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ViewPatterns #-}
module KATHash
( tests
) where
import Data.Char
import Data.Bits
import Data.Word
import Data.ByteString (ByteString)
import Data.Byteable
import Data.Foldable (foldl')
import Data.Monoid (mconcat)
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as BC
import qualified Crypto.Hash.MD2 as MD2
import qualified Crypto.Hash.MD4 as MD4
import qualified Crypto.Hash.MD5 as MD5
import qualified Crypto.Hash.SHA1 as SHA1
import qualified Crypto.Hash.SHA224 as SHA224
import qualified Crypto.Hash.SHA256 as SHA256
import qualified Crypto.Hash.SHA384 as SHA384
import qualified Crypto.Hash.SHA512 as SHA512
import qualified Crypto.Hash.SHA512t as SHA512t
import qualified Crypto.Hash.SHA3 as SHA3
import qualified Crypto.Hash.RIPEMD160 as RIPEMD160
import qualified Crypto.Hash.Tiger as Tiger
import qualified Crypto.Hash.Skein256 as Skein256
import qualified Crypto.Hash.Skein512 as Skein512
import qualified Crypto.Hash.Whirlpool as Whirlpool
import Test.Tasty
import Test.Tasty.QuickCheck
import Test.Tasty.HUnit
v0,v1,v2 :: ByteString
v0 = ""
v1 = "The quick brown fox jumps over the lazy dog"
v2 = "The quick brown fox jumps over the lazy cog"
vectors = [ v0, v1, v2 ]
instance Arbitrary ByteString where
arbitrary = B.pack `fmap` arbitrary
data HashFct = HashFct
{ fctHash :: (B.ByteString -> B.ByteString)
, fctInc :: ([B.ByteString] -> B.ByteString) }
hashinc i u f = f . foldl u i
md2Hash = HashFct { fctHash = MD2.hash, fctInc = hashinc MD2.init MD2.update MD2.finalize }
md4Hash = HashFct { fctHash = MD4.hash, fctInc = hashinc MD4.init MD4.update MD4.finalize }
md5Hash = HashFct { fctHash = MD5.hash, fctInc = hashinc MD5.init MD5.update MD5.finalize }
sha1Hash = HashFct { fctHash = SHA1.hash, fctInc = hashinc SHA1.init SHA1.update SHA1.finalize }
sha224Hash = HashFct { fctHash = SHA224.hash, fctInc = hashinc SHA224.init SHA224.update SHA224.finalize }
sha256Hash = HashFct { fctHash = SHA256.hash, fctInc = hashinc SHA256.init SHA256.update SHA256.finalize }
sha384Hash = HashFct { fctHash = SHA384.hash, fctInc = hashinc SHA384.init SHA384.update SHA384.finalize }
sha512Hash = HashFct { fctHash = SHA512.hash, fctInc = hashinc SHA512.init SHA512.update SHA512.finalize }
sha512_224Hash = HashFct { fctHash = SHA512t.hash 224, fctInc = hashinc (SHA512t.init 224) SHA512t.update SHA512t.finalize }
sha512_256Hash = HashFct { fctHash = SHA512t.hash 256, fctInc = hashinc (SHA512t.init 256) SHA512t.update SHA512t.finalize }
sha3Hash i = HashFct { fctHash = SHA3.hash i, fctInc = hashinc (SHA3.init i) SHA3.update SHA3.finalize }
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 }
whirlpoolHash = HashFct { fctHash = Whirlpool.hash, fctInc = hashinc Whirlpool.init Whirlpool.update Whirlpool.finalize }
results :: [ (String, HashFct, [String]) ]
results = [
("MD2", md2Hash, [
"8350e5a3e24c153df2275c9f80692773",
"03d85a0d629d2c442e987525319fc471",
"6b890c9292668cdbbfda00a4ebf31f05" ]),
("MD4", md4Hash, [
"31d6cfe0d16ae931b73c59d7e0c089c0",
"1bee69a46ba811185c194762abaeae90",
"b86e130ce7028da59e672d56ad0113df" ]),
("MD5", md5Hash, [
"d41d8cd98f00b204e9800998ecf8427e",
"9e107d9d372bb6826bd81d3542a419d6",
"1055d3e698d289f2af8663725127bd4b" ]),
("SHA1", sha1Hash, [
"da39a3ee5e6b4b0d3255bfef95601890afd80709",
"2fd4e1c67a2d28fced849ee1bb76e7391b93eb12",
"de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3" ]),
("SHA224", sha224Hash, [
"d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f",
"730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525",
"fee755f44a55f20fb3362cdc3c493615b3cb574ed95ce610ee5b1e9b" ]),
("SHA256", sha256Hash, [
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592",
"e4c4d8f3bf76b692de791a173e05321150f7a345b46484fe427f6acc7ecc81be" ]),
("SHA384", sha384Hash, [
"38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b",
"ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c494011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1",
"098cea620b0978caa5f0befba6ddcf22764bea977e1c70b3483edfdf1de25f4b40d6cea3cadf00f809d422feb1f0161b" ]),
("SHA512", sha512Hash, [
"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e",
"07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6",
"3eeee1d0e11733ef152a6c29503b3ae20c4f1f3cda4cb26f1bc1a41f91c7fe4ab3bd86494049e201c4bd5155f31ecb7a3c8606843c4cc8dfcab7da11c8ae5045" ]),
("SHA512/224", sha512_224Hash, [
"6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4",
"944cd2847fb54558d4775db0485a50003111c8e5daa63fe722c6aa37",
"2b9d6565a7e40f780ba8ab7c8dcf41e3ed3b77997f4c55aa987eede5" ]),
("SHA512/256", sha512_256Hash, [
"c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a",
"dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d",
"cc8d255a7f2f38fd50388fd1f65ea7910835c5c1e73da46fba01ea50d5dd76fb" ]),
("RIPEMD160", ripemd160Hash, [
"9c1185a5c5e9fc54612808977ee8f548b2258d31",
"37f332f68db77bd9d7edd4969571ad671cf9dd3b",
"132072df690933835eb8b6ad0b77e7b6f14acad7" ]),
("Tiger", tigerHash, [
"3293ac630c13f0245f92bbb1766e16167a4e58492dde73f3",
"6d12a41e72e644f017b6f0e2f7b44c6285f06dd5d2c5b075",
"a8f04b0f7201a0d728101c9d26525b31764a3493fcd8458f" ])
, ("Skein256-160", skein256Hash 160, [
"ff800bed6d2044ee9d604a674e3fda50d9b24a72",
"3265703c166aa3e0d7da070b9cf1b1a5953f0a77",
"17b29aa1424b3ec022505bd215ff73fd2e6d1e5a" ])
, ("Skein256-256", skein256Hash 256, [
"c8877087da56e072870daa843f176e9453115929094c3a40c463a196c29bf7ba",
"c0fbd7d779b20f0a4614a66697f9e41859eaf382f14bf857e8cdb210adb9b3fe",
"fb2f2f2deed0e1dd7ee2b91cee34e2d1c22072e1f5eaee288c35a0723eb653cd" ])
, ("Skein512-160", skein512Hash 160, [
"49daf1ccebb3544bc93cb5019ba91b0eea8876ee",
"826325ee55a6dd18c3b2dbbc9c10420f5475975e",
"7544ec7a35712ec953f02b0d0c86641cae4eb6e5" ])
, ("Skein512-384", skein512Hash 384, [
"dd5aaf4589dc227bd1eb7bc68771f5baeaa3586ef6c7680167a023ec8ce26980f06c4082c488b4ac9ef313f8cbe70808",
"f814c107f3465e7c54048a5503547deddc377264f05c706b0d19db4847b354855ee52ab6a785c238c9e710d848542041",
"e06520eeadc1d0a44fee1d2492547499c1e58526387c8b9c53905e5edb79f9840575cbf844e21b1ad1ea126dd8a8ca6f" ])
, ("Skein512-512", skein512Hash 512, [
"bc5b4c50925519c290cc634277ae3d6257212395cba733bbad37a4af0fa06af41fca7903d06564fea7a2d3730dbdb80c1f85562dfcc070334ea4d1d9e72cba7a",
"94c2ae036dba8783d0b3f7d6cc111ff810702f5c77707999be7e1c9486ff238a7044de734293147359b4ac7e1d09cd247c351d69826b78dcddd951f0ef912713",
"7f81113575e4b4d3441940e87aca331e6d63d103fe5107f29cd877af0d0f5e0ea34164258c60da5190189d0872e63a96596d2ef25e709099842da71d64111e0f" ])
, ("Skein512-896", skein512Hash 896, [
"b95175236c83a459ce7ec6c12b761a838b22d750e765b3fdaa892201b2aa714bc3d1d887dd64028bbf177c1dd11baa09c6c4ddb598fd07d6a8c131a09fc5b958e2999a8006754b25abe3bf8492b7eabec70e52e04e5ac867df2393c573f16eee3244554f1d2b724f2c0437c62007f770",
"3265708553e7d146e5c7bcbc97b3e9e9f5b53a5e4af53612bdd6454da4fa7b13d413184fe34ed57b6574be10e389d0ec4b1d2b1dd2c80e0257d5a76b2cd86a19a27b1bcb3cc24d911b5dc5ee74d19ad558fd85b5f024e99f56d1d3199f1f9f88ed85fab9f945f11cf9fc00e94e3ca4c7",
"3d23d3db9be719bbd2119f8402a28f38d8225faa79d5b68b80738c64a82004aafc7a840cd6dd9bced6644fa894a3d8d7d2ee89525fd1956a2db052c4c2f8d2111c91ef46b0997540d42bcf384826af1a5ef6510077f52d0574cf2b46f1b6a5dad07ed40f3d21a13ca2d079fa602ff02d" ])
, ("Whirlpool", whirlpoolHash, [
"19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3",
"b97de512e91e3828b40d2b0fdce9ceb3c4a71f9bea8d88e75c4fa854df36725fd2b52eb6544edcacd6f8beddfea403cb55ae31f03ad62a5ef54e42ee82c3fb35",
"dce81fc695cfea3d7e1446509238daf89f24cc61896f2d265927daa70f2108f8902f0dfd68be085d5abb9fcd2e482c1dc24f2fabf81f40b73495cad44d7360d3"])
, ("SHA3-224", sha3Hash 224, [
"f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd",
"310aee6b30c47350576ac2873fa89fd190cdc488442f3ef654cf23fe",
"0b27ff3b732133287f6831e2af47cf342b7ef1f3fcdee248811090cd" ])
, ("SHA3-256", sha3Hash 256, [
"c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
"4d741b6f1eb29cb2a9b9911c82f56fa8d73b04959d3d9d222895df6c0b28aa15",
"ed6c07f044d7573cc53bf1276f8cba3dac497919597a45b4599c8f73e22aa334" ])
, ("SHA3-384", sha3Hash 384, [
"2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff",
"283990fa9d5fb731d786c5bbee94ea4db4910f18c62c03d173fc0a5e494422e8a0b3da7574dae7fa0baf005e504063b3",
"1cc515e1812491058d8b8b226fd85045e746b4937a58b0111b6b7a39dd431b6295bd6b6d05e01e225586b4dab3cbb87a" ])
, ("SHA3-512", sha3Hash 512, [
"0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e",
"d135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609",
"10f8caabb5b179861da5e447d34b84d604e3eb81830880e1c2135ffc94580a47cb21f6243ec0053d58b1124d13af2090033659075ee718e0f111bb3f69fb24cf" ])
]
hexalise s = concatMap (\c -> [ hex $ c `div` 16, hex $ c `mod` 16 ]) s
where hex i
| i >= 0 && i <= 9 = fromIntegral (ord '0') + i
| i >= 10 && i <= 15 = fromIntegral (ord 'a') + i - 10
| otherwise = 0
hexaliseB :: B.ByteString -> B.ByteString
hexaliseB = B.pack . hexalise . B.unpack
splitB :: Int -> ByteString -> [ByteString]
splitB l b =
if B.length b > l
then
let (b1, b2) = B.splitAt l b in
b1 : splitB l b2
else
[ b ]
showHash :: B.ByteString -> String
showHash = map (toEnum.fromEnum) . hexalise . B.unpack
runhash hash v = showHash $ (fctHash hash) $ v
runhashinc hash v = showHash $ (fctInc hash) $ v
makeTestAlg (name, hash, results) = testGroup name $ concatMap maketest (zip3 [0..] vectors results)
where
runtest :: ByteString -> String
runtest v = runhash hash v
runtestinc :: Int -> ByteString -> String
runtestinc i v = runhashinc hash $ splitB i v
maketest (i, v, r) =
[ testCase (show i ++ " one-pass") (r @=? runtest v)
, testCase (show i ++ " inc 1") (r @=? runtestinc 1 v)
, testCase (show i ++ " inc 2") (r @=? runtestinc 2 v)
, testCase (show i ++ " inc 3") (r @=? runtestinc 3 v)
, testCase (show i ++ " inc 4") (r @=? runtestinc 4 v)
, testCase (show i ++ " inc 5") (r @=? runtestinc 5 v)
, testCase (show i ++ " inc 9") (r @=? runtestinc 9 v)
, testCase (show i ++ " inc 16") (r @=? runtestinc 16 v)
]
katTests :: [TestTree]
katTests = map makeTestAlg results
tests = testGroup "hash"
[ testGroup "KATs" katTests
]

View File

@ -14,6 +14,7 @@ import qualified Crypto.Cipher.Salsa as Salsa
import qualified Crypto.MAC.Poly1305 as Poly1305
import qualified KATSalsa
import qualified KATHash
b8_128_k0_i0 = "\xe2\x8a\x5f\xa4\xa6\x7f\x8c\x5d\xef\xed\x3e\x6f\xb7\x30\x34\x86\xaa\x84\x27\xd3\x14\x19\xa7\x29\x57\x2d\x77\x79\x53\x49\x11\x20\xb6\x4a\xb8\xe7\x2b\x8d\xeb\x85\xcd\x6a\xea\x7c\xb6\x08\x9a\x10\x18\x24\xbe\xeb\x08\x81\x4a\x42\x8a\xab\x1f\xa2\xc8\x16\x08\x1b\x8a\x26\xaf\x44\x8a\x1b\xa9\x06\x36\x8f\xd8\xc8\x38\x31\xc1\x8c\xec\x8c\xed\x81\x1a\x02\x8e\x67\x5b\x8d\x2b\xe8\xfc\xe0\x81\x16\x5c\xea\xe9\xf1\xd1\xb7\xa9\x75\x49\x77\x49\x48\x05\x69\xce\xb8\x3d\xe6\xa0\xa5\x87\xd4\x98\x4f\x19\x92\x5f\x5d\x33\x8e\x43\x0d"
@ -65,6 +66,7 @@ tests = testGroup "cryptonite"
msg = B.pack $ take totalLen $ concat (replicate 10 [1..255])
in Poly1305.auth key msg == Poly1305.finalize (foldr (flip Poly1305.update) (Poly1305.initialize key) (chunks chunkLen msg))
]
, KATHash.tests
]
where chachaRunSimple expected rounds klen nonceLen =
let chacha = ChaCha.initialize rounds (B.replicate klen 0) (B.replicate nonceLen 0)