{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# CFILES raaz/hash/sha1/portable.c #-} -- | -- -- Module : Raaz.Primitive.Blake2.Internal -- Description : Internal modules for Blake2 hashes. -- Copyright : (c) Piyush P Kurur, 2019 -- License : Apache-2.0 OR BSD-3-Clause -- Maintainer : Piyush P Kurur -- Stability : experimental -- module Raaz.Primitive.Blake2.Internal ( -- * The blake2 types Blake2b, Blake2s , Blake2bMem, Blake2sMem , blake2Pad ) where import Data.Vector.Unboxed ( Unbox ) import Foreign.Storable ( Storable ) import Raaz.Core import Raaz.Primitive.HashMemory import Raaz.Primitive.Keyed.Internal ----------------------------- The blake2 type --------------------------------- -- | The Blake2 type. newtype Blake2 w = Blake2 (Tuple 8 w) deriving (Eq, Equality, Storable, EndianStore) instance ( Unbox w , EndianStore w ) => Primitive (Blake2 w) where type WordType (Blake2 w) = w type WordsPerBlock (Blake2 w) = 16 instance (Unbox w, EndianStore w) => Encodable (Blake2 w) instance (EndianStore w, Unbox w) => IsString (Blake2 w) where fromString = fromBase16 instance (EndianStore w, Unbox w) => Show (Blake2 w) where show = showBase16 -- | The Blake2b hash type. type Blake2b = Blake2 (LE Word64) -- | The Blake2s hash type. type Blake2s = Blake2 (LE Word32) keyLength :: (Storable prim, Num b) => Proxy prim -> BYTES Int -> b keyLength proxy len | len > tLen = fromIntegral tLen | otherwise = fromIntegral len where tLen = sizeOf proxy instance KeyedHash Blake2b where hashInit len = Blake2 $ unsafeFromList [ 0x6a09e667f3bcc908 `xor` iv0 , 0xbb67ae8584caa73b , 0x3c6ef372fe94f82b , 0xa54ff53a5f1d36f1 , 0x510e527fade682d1 , 0x9b05688c2b3e6c1f , 0x1f83d9abfb41bd6b , 0x5be0cd19137e2179 ] where len8 = keyLength (Proxy :: Proxy Blake2b) len iv0 = 0x01010040 .|. shiftL len8 8 instance KeyedHash Blake2s where hashInit len = Blake2 $ unsafeFromList [ 0x6a09e667 `xor` iv0 , 0xbb67ae85 , 0x3c6ef372 , 0xa54ff53a , 0x510e527f , 0x9b05688c , 0x1f83d9ab , 0x5be0cd19 ] where len8 = keyLength (Proxy :: Proxy Blake2s) len iv0 = 0x01010020 .|. shiftL len8 8 ---------------------------------- Memory element for Blake2b ----------------------- -- | The memory element for blake2b hash. type Blake2bMem = HashMemory128 Blake2b -- | The memory element for blake2s hash. type Blake2sMem = HashMemory64 Blake2s instance Initialisable Blake2bMem () where initialise _ = initialise (hashInit 0 :: Blake2b) instance Initialisable Blake2sMem () where initialise _ = initialise (hashInit 0 :: Blake2s) ----------------------- Padding for Blake code ------------------------------ -- | The generic blake2 padding algorithm. We pad the message with -- just enough zero's to make it a multiple of the block size. The -- exception is the empty message which should generate a single block -- of zeros. -- blake2Pad :: Primitive prim => Proxy prim -- ^ the primitive (Blake2b or Blake2s). -> BYTES Int -- ^ length of the message -> WriteTo blake2Pad primProxy m | m == 0 = writeBytes 0 $ blocksOf 1 primProxy -- empty message | otherwise = padWrite 0 (blocksOf 1 primProxy) $ skip m