    {-# LANGUAGE MultiParamTypeClasses       #-}
    -- | The portable C-implementation of SHA384
    module Raaz.Hash.Sha384.Implementation.CPortable
           ( implementation
           ) where

    import Control.Applicative
    import Prelude

    import Raaz.Core
    import Raaz.Hash.Internal
    import Raaz.Hash.Sha384.Internal
    import Raaz.Hash.Sha512.Internal

    import qualified Raaz.Hash.Sha512.Implementation.CPortable as SHA512I

    newtype SHA384Memory = SHA384Memory { unSHA384Mem :: HashMemory SHA512 }

    instance Memory SHA384Memory where
      memoryAlloc     = SHA384Memory <$> memoryAlloc
      unsafeToPointer = unsafeToPointer . unSHA384Mem

    instance Initialisable SHA384Memory () where
      initialise _ = onSubMemory unSHA384Mem
                     $ initialise
                     $ SHA512
                     $ unsafeFromList [ 0xcbbb9d5dc1059ed8
                                      , 0x629a292a367cd507
                                      , 0x9159015a3070dd17
                                      , 0x152fecd8f70e5939
                                      , 0x67332667ffc00b31
                                      , 0x8eb44a8768581511
                                      , 0xdb0c2e0d64f98fa7
                                      , 0x47b5481dbefa4fa4
                                      ]

    instance Extractable SHA384Memory SHA384 where
      extract = trunc <$> onSubMemory unSHA384Mem extract
        where trunc (SHA512 v) = SHA384 $ initial v

    -- | The portable C implementation of SHA384.
    implementation :: Implementation SHA384
    implementation =  SomeHashI cPortable

    cPortable :: HashI SHA384 SHA384Memory
    cPortable = truncatedI (toEnum . fromEnum) unSHA384Mem SHA512I.cPortable