    {-# 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 { SHA384Memory -> HashMemory SHA512
    unSHA384Mem :: HashMemory SHA512 }

    instance Memory SHA384Memory where
      memoryAlloc :: Alloc SHA384Memory
    memoryAlloc     = HashMemory SHA512 -> SHA384Memory
    SHA384Memory (HashMemory SHA512 -> SHA384Memory)
    -> TwistRF AllocField (BYTES Int) (HashMemory SHA512)
    -> Alloc SHA384Memory
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> TwistRF AllocField (BYTES Int) (HashMemory SHA512)
    forall m. Memory m => Alloc m
    memoryAlloc
      unsafeToPointer :: SHA384Memory -> Pointer
    unsafeToPointer = HashMemory SHA512 -> Pointer
    forall m. Memory m => m -> Pointer
    unsafeToPointer (HashMemory SHA512 -> Pointer)
    -> (SHA384Memory -> HashMemory SHA512) -> SHA384Memory -> Pointer
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SHA384Memory -> HashMemory SHA512
    unSHA384Mem

    instance Initialisable SHA384Memory () where
      initialise :: () -> MT SHA384Memory ()
    initialise _ = (SHA384Memory -> HashMemory SHA512)
    -> MT (HashMemory SHA512) () -> MT SHA384Memory ()
    forall (mT :: * -> * -> *) mem submem a.
    MemoryThread mT =>
    (mem -> submem) -> mT submem a -> mT mem a
    onSubMemory SHA384Memory -> HashMemory SHA512
    unSHA384Mem
                     (MT (HashMemory SHA512) () -> MT SHA384Memory ())
    -> MT (HashMemory SHA512) () -> MT SHA384Memory ()
    forall a b. (a -> b) -> a -> b
    $ SHA512 -> MT (HashMemory SHA512) ()
    forall m v. Initialisable m v => v -> MT m ()
    initialise
                     (SHA512 -> MT (HashMemory SHA512) ())
    -> SHA512 -> MT (HashMemory SHA512) ()
    forall a b. (a -> b) -> a -> b
    $ Tuple 8 (BE Word64) -> SHA512
    SHA512
                     (Tuple 8 (BE Word64) -> SHA512) -> Tuple 8 (BE Word64) -> SHA512
    forall a b. (a -> b) -> a -> b
    $ [BE Word64] -> Tuple 8 (BE Word64)
    forall a (dim :: Nat).
    (Unbox a, Dimension dim) =>
    [a] -> Tuple dim a
    unsafeFromList [ 0xcbbb9d5dc1059ed8
                                      , 0x629a292a367cd507
                                      , 0x9159015a3070dd17
                                      , 0x152fecd8f70e5939
                                      , 0x67332667ffc00b31
                                      , 0x8eb44a8768581511
                                      , 0xdb0c2e0d64f98fa7
                                      , 0x47b5481dbefa4fa4
                                      ]

    instance Extractable SHA384Memory SHA384 where
      extract :: MT SHA384Memory SHA384
    extract = SHA512 -> SHA384
    trunc (SHA512 -> SHA384)
    -> MT SHA384Memory SHA512 -> MT SHA384Memory SHA384
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (SHA384Memory -> HashMemory SHA512)
    -> MT (HashMemory SHA512) SHA512 -> MT SHA384Memory SHA512
    forall (mT :: * -> * -> *) mem submem a.
    MemoryThread mT =>
    (mem -> submem) -> mT submem a -> mT mem a
    onSubMemory SHA384Memory -> HashMemory SHA512
    unSHA384Mem MT (HashMemory SHA512) SHA512
    forall m v. Extractable m v => MT m v
    extract
        where trunc :: SHA512 -> SHA384
    trunc (SHA512 v :: Tuple 8 (BE Word64)
    v) = Tuple 6 (BE Word64) -> SHA384
    SHA384 (Tuple 6 (BE Word64) -> SHA384) -> Tuple 6 (BE Word64) -> SHA384
    forall a b. (a -> b) -> a -> b
    $ Tuple 8 (BE Word64) -> Tuple 6 (BE Word64)
    forall a (dim0 :: Nat) (dim1 :: Nat).
    (Unbox a, Dimension dim0) =>
    Tuple dim1 a -> Tuple dim0 a
    initial Tuple 8 (BE Word64)
    v

    -- | The portable C implementation of SHA384.
    implementation :: Implementation SHA384
    implementation :: Implementation SHA384
    implementation =  HashI SHA384 SHA384Memory -> SomeHashI SHA384
    forall h m. HashM h m => HashI h m -> SomeHashI h
    SomeHashI HashI SHA384 SHA384Memory
    cPortable

    cPortable :: HashI SHA384 SHA384Memory
    cPortable :: HashI SHA384 SHA384Memory
    cPortable = (BLOCKS SHA384 -> BLOCKS SHA512)
    -> (SHA384Memory -> HashMemory SHA512)
    -> HashI SHA512 (HashMemory SHA512)
    -> HashI SHA384 SHA384Memory
    forall htrunc h mtrunc m.
    (BLOCKS htrunc -> BLOCKS h)
    -> (mtrunc -> m) -> HashI h m -> HashI htrunc mtrunc
    truncatedI (Int -> BLOCKS SHA512
    forall a. Enum a => Int -> a
    toEnum (Int -> BLOCKS SHA512)
    -> (BLOCKS SHA384 -> Int) -> BLOCKS SHA384 -> BLOCKS SHA512
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . BLOCKS SHA384 -> Int
    forall a. Enum a => a -> Int
    fromEnum) SHA384Memory -> HashMemory SHA512
    unSHA384Mem HashI SHA512 (HashMemory SHA512)
    SHA512I.cPortable