    {-# LANGUAGE CPP                        #-}
    {-# LANGUAGE DataKinds                  #-}
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    {-# LANGUAGE TypeFamilies               #-}
    {-# LANGUAGE FlexibleInstances          #-}
    {-# LANGUAGE MultiParamTypeClasses      #-}
    {-# CFILES raaz/hash/sha1/portable.c    #-}

    -- | Internals of Sha256.
    module Raaz.Hash.Sha256.Internal
           ( SHA256(..)
           ) where

    import Data.String
    import Data.Word
    import Foreign.Storable    ( Storable )

    import Raaz.Core

    import Raaz.Hash.Internal

    ----------------------------- SHA256 -------------------------------------------

    -- | The Sha256 hash value.
    newtype SHA256 = SHA256 (Tuple 8 (BE Word32))
                  deriving (SHA256 -> SHA256 -> Bool
    (SHA256 -> SHA256 -> Bool)
    -> (SHA256 -> SHA256 -> Bool) -> Eq SHA256
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: SHA256 -> SHA256 -> Bool
    $c/= :: SHA256 -> SHA256 -> Bool
    == :: SHA256 -> SHA256 -> Bool
    $c== :: SHA256 -> SHA256 -> Bool
    Eq, SHA256 -> SHA256 -> Result
    (SHA256 -> SHA256 -> Result) -> Equality SHA256
    forall a. (a -> a -> Result) -> Equality a
    eq :: SHA256 -> SHA256 -> Result
    $ceq :: SHA256 -> SHA256 -> Result
    Equality, Ptr b -> Int -> IO SHA256
    Ptr b -> Int -> SHA256 -> IO ()
    Ptr SHA256 -> IO SHA256
    Ptr SHA256 -> Int -> IO SHA256
    Ptr SHA256 -> Int -> SHA256 -> IO ()
    Ptr SHA256 -> SHA256 -> IO ()
    SHA256 -> Int
    (SHA256 -> Int)
    -> (SHA256 -> Int)
    -> (Ptr SHA256 -> Int -> IO SHA256)
    -> (Ptr SHA256 -> Int -> SHA256 -> IO ())
    -> (forall b. Ptr b -> Int -> IO SHA256)
    -> (forall b. Ptr b -> Int -> SHA256 -> IO ())
    -> (Ptr SHA256 -> IO SHA256)
    -> (Ptr SHA256 -> SHA256 -> IO ())
    -> Storable SHA256
    forall b. Ptr b -> Int -> IO SHA256
    forall b. Ptr b -> Int -> SHA256 -> IO ()
    forall a.
    (a -> Int)
    -> (a -> Int)
    -> (Ptr a -> Int -> IO a)
    -> (Ptr a -> Int -> a -> IO ())
    -> (forall b. Ptr b -> Int -> IO a)
    -> (forall b. Ptr b -> Int -> a -> IO ())
    -> (Ptr a -> IO a)
    -> (Ptr a -> a -> IO ())
    -> Storable a
    poke :: Ptr SHA256 -> SHA256 -> IO ()
    $cpoke :: Ptr SHA256 -> SHA256 -> IO ()
    peek :: Ptr SHA256 -> IO SHA256
    $cpeek :: Ptr SHA256 -> IO SHA256
    pokeByteOff :: Ptr b -> Int -> SHA256 -> IO ()
    $cpokeByteOff :: forall b. Ptr b -> Int -> SHA256 -> IO ()
    peekByteOff :: Ptr b -> Int -> IO SHA256
    $cpeekByteOff :: forall b. Ptr b -> Int -> IO SHA256
    pokeElemOff :: Ptr SHA256 -> Int -> SHA256 -> IO ()
    $cpokeElemOff :: Ptr SHA256 -> Int -> SHA256 -> IO ()
    peekElemOff :: Ptr SHA256 -> Int -> IO SHA256
    $cpeekElemOff :: Ptr SHA256 -> Int -> IO SHA256
    alignment :: SHA256 -> Int
    $calignment :: SHA256 -> Int
    sizeOf :: SHA256 -> Int
    $csizeOf :: SHA256 -> Int
    Storable, Storable SHA256
    Ptr SHA256 -> IO SHA256
    Ptr SHA256 -> Int -> IO ()
    Ptr SHA256 -> SHA256 -> IO ()
    Storable SHA256 =>
    (Ptr SHA256 -> SHA256 -> IO ())
    -> (Ptr SHA256 -> IO SHA256)
    -> (Ptr SHA256 -> Int -> IO ())
    -> EndianStore SHA256
    forall w.
    Storable w =>
    (Ptr w -> w -> IO ())
    -> (Ptr w -> IO w) -> (Ptr w -> Int -> IO ()) -> EndianStore w
    adjustEndian :: Ptr SHA256 -> Int -> IO ()
    $cadjustEndian :: Ptr SHA256 -> Int -> IO ()
    load :: Ptr SHA256 -> IO SHA256
    $cload :: Ptr SHA256 -> IO SHA256
    store :: Ptr SHA256 -> SHA256 -> IO ()
    $cstore :: Ptr SHA256 -> SHA256 -> IO ()
    $cp1EndianStore :: Storable SHA256
    EndianStore)

    instance Encodable SHA256

    instance IsString SHA256 where
      fromString :: String -> SHA256
    fromString = String -> SHA256
    forall a. Encodable a => String -> a
    fromBase16

    instance Show SHA256 where
      show :: SHA256 -> String
    show =  SHA256 -> String
    forall a. Encodable a => a -> String
    showBase16

    instance Initialisable (HashMemory SHA256) () where
      initialise :: () -> MT (HashMemory SHA256) ()
    initialise _ = 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 [ 0x6a09e667
                                                          , 0xbb67ae85
                                                          , 0x3c6ef372
                                                          , 0xa54ff53a
                                                          , 0x510e527f
                                                          , 0x9b05688c
                                                          , 0x1f83d9ab
                                                          , 0x5be0cd19
                                                          ]

    instance Primitive SHA256 where
      blockSize :: SHA256 -> BYTES Int
    blockSize _                = Int -> BYTES Int
    forall a. a -> BYTES a
    BYTES 64
      type Implementation SHA256 = SomeHashI SHA256

    instance Hash SHA256 where
      additionalPadBlocks :: SHA256 -> BLOCKS SHA256
    additionalPadBlocks _ = Int -> BLOCKS SHA256
    forall a. Enum a => Int -> a
    toEnum 1