mirror of
https://github.com/kazu-yamamoto/crypton.git
synced 2024-10-04 07:50:45 +03:00
merge cryptohash
This commit is contained in:
parent
ec1a44881d
commit
09feb59f62
24
Crypto/Hash/Internal.hs
Normal file
24
Crypto/Hash/Internal.hs
Normal 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
136
Crypto/Hash/MD2.hs
Normal 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
136
Crypto/Hash/MD4.hs
Normal 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
136
Crypto/Hash/MD5.hs
Normal 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
136
Crypto/Hash/RIPEMD160.hs
Normal 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
136
Crypto/Hash/SHA1.hs
Normal 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
136
Crypto/Hash/SHA224.hs
Normal 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
136
Crypto/Hash/SHA256.hs
Normal 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
144
Crypto/Hash/SHA3.hs
Normal 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
136
Crypto/Hash/SHA384.hs
Normal 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
145
Crypto/Hash/SHA512.hs
Normal 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
52
Crypto/Hash/SHA512t.hs
Normal 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
144
Crypto/Hash/Skein256.hs
Normal 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
144
Crypto/Hash/Skein512.hs
Normal 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
136
Crypto/Hash/Tiger.hs
Normal 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
76
Crypto/Hash/Types.hs
Normal 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
77
Crypto/Hash/Utils.hs
Normal 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
136
Crypto/Hash/Whirlpool.hs
Normal 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
135
cbits/cryptonite_md2.c
Normal 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
44
cbits/cryptonite_md2.h
Normal 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
161
cbits/cryptonite_md4.c
Normal 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
43
cbits/cryptonite_md4.h
Normal 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
178
cbits/cryptonite_md5.c
Normal 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
43
cbits/cryptonite_md5.h
Normal 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
299
cbits/cryptonite_ripemd.c
Normal 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
43
cbits/cryptonite_ripemd.h
Normal 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
209
cbits/cryptonite_sha1.c
Normal 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
43
cbits/cryptonite_sha1.h
Normal 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
175
cbits/cryptonite_sha256.c
Normal 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
53
cbits/cryptonite_sha256.h
Normal 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
159
cbits/cryptonite_sha3.c
Normal 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
45
cbits/cryptonite_sha3.h
Normal 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
245
cbits/cryptonite_sha512.c
Normal 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
54
cbits/cryptonite_sha512.h
Normal 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
46
cbits/cryptonite_skein.h
Normal 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
196
cbits/cryptonite_skein256.c
Normal 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];
|
||||
}
|
||||
}
|
45
cbits/cryptonite_skein256.h
Normal file
45
cbits/cryptonite_skein256.h
Normal 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
214
cbits/cryptonite_skein512.c
Normal 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];
|
||||
}
|
||||
}
|
45
cbits/cryptonite_skein512.h
Normal file
45
cbits/cryptonite_skein512.h
Normal 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
415
cbits/cryptonite_tiger.c
Normal 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
43
cbits/cryptonite_tiger.h
Normal 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
1027
cbits/cryptonite_whirlpool.c
Normal file
File diff suppressed because it is too large
Load Diff
31
cbits/cryptonite_whirlpool.h
Normal file
31
cbits/cryptonite_whirlpool.h
Normal 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
|
@ -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
221
tests/KATHash.hs
Normal 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
|
||||
]
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user