Use Nat for the Blake2's digest sizes
This commit is contained in:
parent
cd552ae5f6
commit
c0c33c5254
@ -45,6 +45,8 @@ module Crypto.Hash.Algorithms
|
||||
#if MIN_VERSION_base(4,7,0)
|
||||
, SHAKE128(..)
|
||||
, SHAKE256(..)
|
||||
, Blake2b(..), Blake2bp(..)
|
||||
, Blake2s(..), Blake2sp(..)
|
||||
#endif
|
||||
, Skein256_224(..)
|
||||
, Skein256_256(..)
|
||||
@ -78,4 +80,5 @@ import Crypto.Hash.Skein512
|
||||
import Crypto.Hash.Whirlpool
|
||||
#if MIN_VERSION_base(4,7,0)
|
||||
import Crypto.Hash.SHAKE
|
||||
import Crypto.Hash.Blake2
|
||||
#endif
|
||||
|
||||
151
Crypto/Hash/Blake2.hs
Normal file
151
Crypto/Hash/Blake2.hs
Normal file
@ -0,0 +1,151 @@
|
||||
-- |
|
||||
-- Module : Crypto.Hash.Blake2
|
||||
-- License : BSD-style
|
||||
-- Maintainer : Nicolas Di Prima <nicolas@primetype.co.uk>
|
||||
-- Stability : experimental
|
||||
-- Portability : unknown
|
||||
--
|
||||
-- module containing the binding functions to work with the
|
||||
-- Blake2
|
||||
--
|
||||
-- Implementation based from [RFC7693](https://tools.ietf.org/html/rfc7693)
|
||||
--
|
||||
-- Please consider the following when chosing a hash:
|
||||
--
|
||||
-- Algorithm | Target | Collision | Digest Size |
|
||||
-- Identifier | Arch | Security | in bytes |
|
||||
-- ---------------+--------+-----------+-------------+
|
||||
-- id-blake2b160 | 64-bit | 2**80 | 20 |
|
||||
-- id-blake2b256 | 64-bit | 2**128 | 32 |
|
||||
-- id-blake2b384 | 64-bit | 2**192 | 48 |
|
||||
-- id-blake2b512 | 64-bit | 2**256 | 64 |
|
||||
-- ---------------+--------+-----------+-------------+
|
||||
-- id-blake2s128 | 32-bit | 2**64 | 16 |
|
||||
-- id-blake2s160 | 32-bit | 2**80 | 20 |
|
||||
-- id-blake2s224 | 32-bit | 2**112 | 28 |
|
||||
-- id-blake2s256 | 32-bit | 2**128 | 32 |
|
||||
-- ---------------+--------+-----------+-------------+
|
||||
--
|
||||
{-# LANGUAGE ForeignFunctionInterface #-}
|
||||
{-# LANGUAGE DeriveDataTypeable #-}
|
||||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
{-# LANGUAGE KindSignatures #-}
|
||||
{-# LANGUAGE DataKinds #-}
|
||||
{-# LANGUAGE TypeFamilies #-}
|
||||
module Crypto.Hash.Blake2
|
||||
( Blake2s(..)
|
||||
, Blake2sp(..)
|
||||
, Blake2b(..)
|
||||
, Blake2bp(..)
|
||||
) where
|
||||
|
||||
import Crypto.Hash.Types
|
||||
import Foreign.Ptr (Ptr)
|
||||
import Data.Data
|
||||
import Data.Typeable
|
||||
import Data.Word (Word8, Word32)
|
||||
import GHC.TypeLits (Nat, KnownNat, natVal)
|
||||
import Crypto.Internal.Nat
|
||||
|
||||
-- | Fast and secure alternative to SHA1 and HMAC-SHA1
|
||||
--
|
||||
-- It is espacially known to target 32bits architectures.
|
||||
--
|
||||
-- known supported digest sizes:
|
||||
--
|
||||
-- * Blake2s 160
|
||||
-- * Blake2s 224
|
||||
-- * Blake2s 256
|
||||
--
|
||||
data Blake2s (bitlen :: Nat) = Blake2s
|
||||
deriving (Show, Typeable)
|
||||
|
||||
instance (IsDivisibleBy8 bitlen, KnownNat bitlen)
|
||||
=> HashAlgorithm (Blake2s bitlen)
|
||||
where
|
||||
hashBlockSize _ = 64
|
||||
hashDigestSize _ = byteLen (Proxy :: Proxy bitlen)
|
||||
hashInternalContextSize _ = 185
|
||||
hashInternalInit p = c_blake2s_init p (integralNatVal (Proxy :: Proxy bitlen))
|
||||
hashInternalUpdate = c_blake2s_update
|
||||
hashInternalFinalize p = c_blake2s_finalize p (integralNatVal (Proxy :: Proxy bitlen))
|
||||
|
||||
foreign import ccall unsafe "cryptonite_blake2s_init"
|
||||
c_blake2s_init :: Ptr (Context a) -> Word32 -> IO ()
|
||||
foreign import ccall "cryptonite_blake2s_update"
|
||||
c_blake2s_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO ()
|
||||
foreign import ccall unsafe "cryptonite_blake2s_finalize"
|
||||
c_blake2s_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO ()
|
||||
|
||||
-- | Fast cryptographic hash.
|
||||
--
|
||||
-- It is especially known to target 64bits architectures.
|
||||
--
|
||||
-- Known supported digest sizes:
|
||||
--
|
||||
-- * Blake2b 160
|
||||
-- * Blake2b 224
|
||||
-- * Blake2b 256
|
||||
-- * Blake2b 384
|
||||
-- * Blake2b 512
|
||||
--
|
||||
data Blake2b (bitlen :: Nat) = Blake2b
|
||||
deriving (Show, Typeable)
|
||||
|
||||
instance (IsDivisibleBy8 bitlen, KnownNat bitlen)
|
||||
=> HashAlgorithm (Blake2b bitlen)
|
||||
where
|
||||
hashBlockSize _ = 128
|
||||
hashDigestSize _ = byteLen (Proxy :: Proxy bitlen)
|
||||
hashInternalContextSize _ = 361
|
||||
hashInternalInit p = c_blake2b_init p (integralNatVal (Proxy :: Proxy bitlen))
|
||||
hashInternalUpdate = c_blake2b_update
|
||||
hashInternalFinalize p = c_blake2b_finalize p (integralNatVal (Proxy :: Proxy bitlen))
|
||||
|
||||
foreign import ccall unsafe "cryptonite_blake2b_init"
|
||||
c_blake2b_init :: Ptr (Context a) -> Word32 -> IO ()
|
||||
foreign import ccall "cryptonite_blake2b_update"
|
||||
c_blake2b_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO ()
|
||||
foreign import ccall unsafe "cryptonite_blake2b_finalize"
|
||||
c_blake2b_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO ()
|
||||
|
||||
data Blake2sp (bitlen :: Nat) = Blake2sp
|
||||
deriving (Show, Typeable)
|
||||
|
||||
instance (IsDivisibleBy8 bitlen, KnownNat bitlen)
|
||||
=> HashAlgorithm (Blake2sp bitlen)
|
||||
where
|
||||
hashBlockSize _ = 64
|
||||
hashDigestSize _ = byteLen (Proxy :: Proxy bitlen)
|
||||
hashInternalContextSize _ = 2185
|
||||
hashInternalInit p = c_blake2sp_init p (integralNatVal (Proxy :: Proxy bitlen))
|
||||
hashInternalUpdate = c_blake2sp_update
|
||||
hashInternalFinalize p = c_blake2sp_finalize p (integralNatVal (Proxy :: Proxy bitlen))
|
||||
|
||||
foreign import ccall unsafe "cryptonite_blake2sp_init"
|
||||
c_blake2sp_init :: Ptr (Context a) -> Word32 -> IO ()
|
||||
foreign import ccall "cryptonite_blake2sp_update"
|
||||
c_blake2sp_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO ()
|
||||
foreign import ccall unsafe "cryptonite_blake2sp_finalize"
|
||||
c_blake2sp_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO ()
|
||||
|
||||
data Blake2bp (bitlen :: Nat) = Blake2bp
|
||||
deriving (Show, Typeable)
|
||||
|
||||
instance (IsDivisibleBy8 bitlen, KnownNat bitlen)
|
||||
=> HashAlgorithm (Blake2bp bitlen)
|
||||
where
|
||||
hashBlockSize _ = 128
|
||||
hashDigestSize _ = byteLen (Proxy :: Proxy bitlen)
|
||||
hashInternalContextSize _ = 2325
|
||||
hashInternalInit p = c_blake2bp_init p (integralNatVal (Proxy :: Proxy bitlen))
|
||||
hashInternalUpdate = c_blake2bp_update
|
||||
hashInternalFinalize p = c_blake2bp_finalize p (integralNatVal (Proxy :: Proxy bitlen))
|
||||
|
||||
|
||||
foreign import ccall unsafe "cryptonite_blake2bp_init"
|
||||
c_blake2bp_init :: Ptr (Context a) -> Word32 -> IO ()
|
||||
foreign import ccall "cryptonite_blake2bp_update"
|
||||
c_blake2bp_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO ()
|
||||
foreign import ccall unsafe "cryptonite_blake2bp_finalize"
|
||||
c_blake2bp_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO ()
|
||||
@ -213,6 +213,7 @@ Library
|
||||
Crypto.Internal.WordArray
|
||||
if impl(ghc >= 7.8)
|
||||
Other-modules: Crypto.Hash.SHAKE
|
||||
Crypto.Hash.Blake2
|
||||
Crypto.Internal.Nat
|
||||
Build-depends: base >= 4.3 && < 5
|
||||
, bytestring
|
||||
|
||||
Loading…
Reference in New Issue
Block a user