{-# 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 [ BE Word32
0xc1059ed8
                                                      , BE Word32
0x367cd507
                                                      , BE Word32
0x3070dd17
                                                      , BE Word32
0xf70e5939
                                                      , BE Word32
0xffc00b31
                                                      , BE Word32
0x68581511
                                                      , BE Word32
0x64f98fa7
                                                      , BE Word32
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 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