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

    import Control.Applicative
    import Prelude

    import Raaz.Core
    import Raaz.Hash.Internal
    import Raaz.Hash.Sha224.Internal

    import           Raaz.Hash.Sha256.Internal ( SHA256(..) )
    import qualified Raaz.Hash.Sha256.Implementation.CPortable as SHA256I

    newtype SHA224Memory  = SHA224Memory { SHA224Memory -> HashMemory SHA256
    unSHA224Mem :: HashMemory SHA256 }

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

    instance Initialisable SHA224Memory () where
      initialise :: () -> MT SHA224Memory ()
    initialise _ = (SHA224Memory -> HashMemory SHA256)
    -> MT (HashMemory SHA256) () -> MT SHA224Memory ()
    forall (mT :: * -> * -> *) mem submem a.
    MemoryThread mT =>
    (mem -> submem) -> mT submem a -> mT mem a
    onSubMemory SHA224Memory -> HashMemory SHA256
    unSHA224Mem (MT (HashMemory SHA256) () -> MT SHA224Memory ())
    -> MT (HashMemory SHA256) () -> MT SHA224Memory ()
    forall a b. (a -> b) -> a -> b
    $
                     SHA256 -> MT (HashMemory SHA256) ()
    forall m v. Initialisable m v => v -> MT m ()
    initialise (SHA256 -> MT (HashMemory SHA256) ())
    -> SHA256 -> MT (HashMemory SHA256) ()
    forall a b. (a -> b) -> a -> b
    $ Tuple 8 (BE Word32) -> SHA256
    SHA256 (Tuple 8 (BE Word32) -> SHA256) -> Tuple 8 (BE Word32) -> SHA256
    forall a b. (a -> b) -> a -> b
    $ [BE Word32] -> Tuple 8 (BE Word32)
    forall a (dim :: Nat).
    (Unbox a, Dimension dim) =>
    [a] -> Tuple dim a
    unsafeFromList [ 0xc1059ed8
                                                          , 0x367cd507
                                                          , 0x3070dd17
                                                          , 0xf70e5939
                                                          , 0xffc00b31
                                                          , 0x68581511
                                                          , 0x64f98fa7
                                                          , 0xbefa4fa4
                                                          ]

    instance Extractable SHA224Memory SHA224 where
      extract :: MT SHA224Memory SHA224
    extract = SHA256 -> SHA224
    trunc (SHA256 -> SHA224)
    -> MT SHA224Memory SHA256 -> MT SHA224Memory SHA224
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (SHA224Memory -> HashMemory SHA256)
    -> MT (HashMemory SHA256) SHA256 -> MT SHA224Memory SHA256
    forall (mT :: * -> * -> *) mem submem a.
    MemoryThread mT =>
    (mem -> submem) -> mT submem a -> mT mem a
    onSubMemory SHA224Memory -> HashMemory SHA256
    unSHA224Mem MT (HashMemory SHA256) SHA256
    forall m v. Extractable m v => MT m v
    extract
        where trunc :: SHA256 -> SHA224
    trunc (SHA256 tup :: Tuple 8 (BE Word32)
    tup) = Tuple 7 (BE Word32) -> SHA224
    SHA224 (Tuple 7 (BE Word32) -> SHA224) -> Tuple 7 (BE Word32) -> SHA224
    forall a b. (a -> b) -> a -> b
    $ Tuple 8 (BE Word32) -> Tuple 7 (BE Word32)
    forall a (dim0 :: Nat) (dim1 :: Nat).
    (Unbox a, Dimension dim0) =>
    Tuple dim1 a -> Tuple dim0 a
    initial Tuple 8 (BE Word32)
    tup

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

    cPortable :: HashI SHA224 SHA224Memory
    cPortable :: HashI SHA224 SHA224Memory
    cPortable = (BLOCKS SHA224 -> BLOCKS SHA256)
    -> (SHA224Memory -> HashMemory SHA256)
    -> HashI SHA256 (HashMemory SHA256)
    -> HashI SHA224 SHA224Memory
    forall htrunc h mtrunc m.
    (BLOCKS htrunc -> BLOCKS h)
    -> (mtrunc -> m) -> HashI h m -> HashI htrunc mtrunc
    truncatedI (Int -> BLOCKS SHA256
    forall a. Enum a => Int -> a
    toEnum (Int -> BLOCKS SHA256)
    -> (BLOCKS SHA224 -> Int) -> BLOCKS SHA224 -> BLOCKS SHA256
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . BLOCKS SHA224 -> Int
    forall a. Enum a => a -> Int
    fromEnum) SHA224Memory -> HashMemory SHA256
    unSHA224Mem HashI SHA256 (HashMemory SHA256)
    SHA256I.cPortable