    {-# LINE 1 "src/Crypto/Skein/Internal.hsc" #-}
    {-# CFILES
          c_impl/reference/skein.c
          c_impl/reference/skein_block.c #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Crypto.Skein.Internal
    -- Copyright   :  (c) 2011 Felipe A. Lessa
    -- License     :  BSD3 (see LICENSE)
    --
    -- Maintainer  :  felipe.lessa@gmail.com
    -- Stability   :  provisional
    -- Portability :  portable (needs FFI)
    --
    -- Basic wrappers around the C library.  You shouldn't need to
    -- use these functions.  Instead, use the high-level
    -- "Crypto.Skein" module.
    --
    -----------------------------------------------------------------------------

    module Crypto.Skein.Internal
        ( -- * Return codes
          sKEIN_SUCCESS
        , sKEIN_FAIL
        , sKEIN_BAD_HASHLEN
        , check

          -- * Skein-256
        , Skein256Ctx(..)
        , skein256Init
        , skein256Update
        , skein256Final
        , skein256InitExt
        , skein256FinalPad
        , skein256Output

          -- * Skein-512
        , Skein512Ctx(..)
        , skein512Init
        , skein512Update
        , skein512Final
        , skein512InitExt
        , skein512FinalPad
        , skein512Output

          -- * Skein-1024
        , Skein1024Ctx(..)
        , skein1024Init
        , skein1024Update
        , skein1024Final
        , skein1024InitExt
        , skein1024FinalPad
        , skein1024Output

          -- * Misc constants
        , sKEIN_SEQUENTIAL
        ) where

    -- from base
    import Foreign
    import Foreign.C

    -- from bytestring
    import qualified Data.ByteString as B
    import qualified Data.ByteString.Internal as BI
    import qualified Data.ByteString.Unsafe as BU

    -- from this package

    sKEIN_SUCCESS, sKEIN_FAIL, sKEIN_BAD_HASHLEN :: CInt
    sKEIN_SUCCESS :: CInt
    sKEIN_SUCCESS     = CInt
    0
    {-# LINE 73 "src/Crypto/Skein/Internal.hsc" #-}
    sKEIN_FAIL        = 1
    {-# LINE 74 "src/Crypto/Skein/Internal.hsc" #-}
    sKEIN_BAD_HASHLEN = 2
    {-# LINE 75 "src/Crypto/Skein/Internal.hsc" #-}

    -- | Throws exception if the function does not return
    -- successfully.
    check :: IO CInt -> IO ()
    check :: IO CInt -> IO ()
    check IO CInt
    act = do
      CInt
    x <- IO CInt
    act
      case () of
        () | CInt
    x CInt -> CInt -> Bool
    forall a. Eq a => a -> a -> Bool
    == CInt
    sKEIN_SUCCESS     -> () -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
           | CInt
    x CInt -> CInt -> Bool
    forall a. Eq a => a -> a -> Bool
    == CInt
    sKEIN_FAIL        -> String -> IO ()
    forall a. String -> IO a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "Skein returned FAIL."
           | CInt
    x CInt -> CInt -> Bool
    forall a. Eq a => a -> a -> Bool
    == CInt
    sKEIN_BAD_HASHLEN -> String -> IO ()
    forall a. String -> IO a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "Skein returned BAD_HASHLEN."
           | Bool
    otherwise              -> String -> IO ()
    forall a. String -> IO a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "Skein returned unknown code."

    newtype Skein256Ctx  = S256Ctx  {Skein256Ctx -> ByteString
    unS256Ctx  :: B.ByteString}
    newtype Skein512Ctx  = S512Ctx  {Skein512Ctx -> ByteString
    unS512Ctx  :: B.ByteString}
    newtype Skein1024Ctx = S1024Ctx {Skein1024Ctx -> ByteString
    unS1024Ctx :: B.ByteString}

    size256Ctx, size512Ctx, size1024Ctx :: Int
    size256Ctx :: Int
    size256Ctx  = (Int
    96)
    {-# LINE 93 "src/Crypto/Skein/Internal.hsc" #-}
    size512Ctx  = (160)
    {-# LINE 94 "src/Crypto/Skein/Internal.hsc" #-}
    size1024Ctx = (288)
    {-# LINE 95 "src/Crypto/Skein/Internal.hsc" #-}

    instance Storable Skein256Ctx where
        sizeOf :: Skein256Ctx -> Int
    sizeOf    Skein256Ctx
    _ = Int
    size256Ctx
        alignment :: Skein256Ctx -> Int
    alignment Skein256Ctx
    _ = Int
    16
        peek :: Ptr Skein256Ctx -> IO Skein256Ctx
    peek Ptr Skein256Ctx
    ptr =
            (ByteString -> Skein256Ctx) -> IO ByteString -> IO Skein256Ctx
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ByteString -> Skein256Ctx
    S256Ctx (IO ByteString -> IO Skein256Ctx)
    -> IO ByteString -> IO Skein256Ctx
    forall a b. (a -> b) -> a -> b
    $ Int -> (Ptr Word8 -> IO ()) -> IO ByteString
    BI.create Int
    size256Ctx ((Ptr Word8 -> IO ()) -> IO ByteString)
    -> (Ptr Word8 -> IO ()) -> IO ByteString
    forall a b. (a -> b) -> a -> b
    $ \Ptr Word8
    bptr ->
                Ptr Word8 -> Ptr Word8 -> Int -> IO ()
    BI.memcpy Ptr Word8
    bptr (Ptr Skein256Ctx -> Ptr Word8
    forall a b. Ptr a -> Ptr b
    castPtr Ptr Skein256Ctx
    ptr) (Int -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    size256Ctx)
        poke :: Ptr Skein256Ctx -> Skein256Ctx -> IO ()
    poke Ptr Skein256Ctx
    ptr (S256Ctx ByteString
    bs) =
            ByteString -> (CString -> IO ()) -> IO ()
    forall a. ByteString -> (CString -> IO a) -> IO a
    BU.unsafeUseAsCString ByteString
    bs ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \CString
    bs_ptr ->
                Ptr Word8 -> Ptr Word8 -> Int -> IO ()
    BI.memcpy (Ptr Skein256Ctx -> Ptr Word8
    forall a b. Ptr a -> Ptr b
    castPtr Ptr Skein256Ctx
    ptr) (CString -> Ptr Word8
    forall a b. Ptr a -> Ptr b
    castPtr CString
    bs_ptr) (Int -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    size256Ctx)

    instance Storable Skein512Ctx where
        sizeOf :: Skein512Ctx -> Int
    sizeOf    Skein512Ctx
    _ = Int
    size512Ctx
        alignment :: Skein512Ctx -> Int
    alignment Skein512Ctx
    _ = Int
    16
        peek :: Ptr Skein512Ctx -> IO Skein512Ctx
    peek Ptr Skein512Ctx
    ptr =
            (ByteString -> Skein512Ctx) -> IO ByteString -> IO Skein512Ctx
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ByteString -> Skein512Ctx
    S512Ctx (IO ByteString -> IO Skein512Ctx)
    -> IO ByteString -> IO Skein512Ctx
    forall a b. (a -> b) -> a -> b
    $ Int -> (Ptr Word8 -> IO ()) -> IO ByteString
    BI.create Int
    size512Ctx ((Ptr Word8 -> IO ()) -> IO ByteString)
    -> (Ptr Word8 -> IO ()) -> IO ByteString
    forall a b. (a -> b) -> a -> b
    $ \Ptr Word8
    bptr ->
                Ptr Word8 -> Ptr Word8 -> Int -> IO ()
    BI.memcpy Ptr Word8
    bptr (Ptr Skein512Ctx -> Ptr Word8
    forall a b. Ptr a -> Ptr b
    castPtr Ptr Skein512Ctx
    ptr) (Int -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    size512Ctx)
        poke :: Ptr Skein512Ctx -> Skein512Ctx -> IO ()
    poke Ptr Skein512Ctx
    ptr (S512Ctx ByteString
    bs) =
            ByteString -> (CString -> IO ()) -> IO ()
    forall a. ByteString -> (CString -> IO a) -> IO a
    BU.unsafeUseAsCString ByteString
    bs ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \CString
    bs_ptr ->
                Ptr Word8 -> Ptr Word8 -> Int -> IO ()
    BI.memcpy (Ptr Skein512Ctx -> Ptr Word8
    forall a b. Ptr a -> Ptr b
    castPtr Ptr Skein512Ctx
    ptr) (CString -> Ptr Word8
    forall a b. Ptr a -> Ptr b
    castPtr CString
    bs_ptr) (Int -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    size512Ctx)

    instance Storable Skein1024Ctx where
        sizeOf :: Skein1024Ctx -> Int
    sizeOf    Skein1024Ctx
    _ = Int
    size1024Ctx
        alignment :: Skein1024Ctx -> Int
    alignment Skein1024Ctx
    _ = Int
    16
        peek :: Ptr Skein1024Ctx -> IO Skein1024Ctx
    peek Ptr Skein1024Ctx
    ptr =
            (ByteString -> Skein1024Ctx) -> IO ByteString -> IO Skein1024Ctx
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ByteString -> Skein1024Ctx
    S1024Ctx (IO ByteString -> IO Skein1024Ctx)
    -> IO ByteString -> IO Skein1024Ctx
    forall a b. (a -> b) -> a -> b
    $ Int -> (Ptr Word8 -> IO ()) -> IO ByteString
    BI.create Int
    size1024Ctx ((Ptr Word8 -> IO ()) -> IO ByteString)
    -> (Ptr Word8 -> IO ()) -> IO ByteString
    forall a b. (a -> b) -> a -> b
    $ \Ptr Word8
    bptr ->
                Ptr Word8 -> Ptr Word8 -> Int -> IO ()
    BI.memcpy Ptr Word8
    bptr (Ptr Skein1024Ctx -> Ptr Word8
    forall a b. Ptr a -> Ptr b
    castPtr Ptr Skein1024Ctx
    ptr) (Int -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    size1024Ctx)
        poke :: Ptr Skein1024Ctx -> Skein1024Ctx -> IO ()
    poke Ptr Skein1024Ctx
    ptr (S1024Ctx ByteString
    bs) =
            ByteString -> (CString -> IO ()) -> IO ()
    forall a. ByteString -> (CString -> IO a) -> IO a
    BU.unsafeUseAsCString ByteString
    bs ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \CString
    bs_ptr ->
                Ptr Word8 -> Ptr Word8 -> Int -> IO ()
    BI.memcpy (Ptr Skein1024Ctx -> Ptr Word8
    forall a b. Ptr a -> Ptr b
    castPtr Ptr Skein1024Ctx
    ptr) (CString -> Ptr Word8
    forall a b. Ptr a -> Ptr b
    castPtr CString
    bs_ptr) (Int -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    size1024Ctx)

    foreign import ccall unsafe "skein.h Skein_256_Init" skein256Init  :: Ptr Skein256Ctx  -> CSize -> IO CInt
    foreign import ccall unsafe "skein.h Skein_512_Init" skein512Init  :: Ptr Skein512Ctx  -> CSize -> IO CInt
    foreign import ccall unsafe "skein.h Skein1024_Init" skein1024Init :: Ptr Skein1024Ctx -> CSize -> IO CInt

    foreign import ccall unsafe "skein.h Skein_256_Update" skein256Update  :: Ptr Skein256Ctx  -> Ptr Word8 -> CSize -> IO CInt
    foreign import ccall unsafe "skein.h Skein_512_Update" skein512Update  :: Ptr Skein512Ctx  -> Ptr Word8 -> CSize -> IO CInt
    foreign import ccall unsafe "skein.h Skein1024_Update" skein1024Update :: Ptr Skein1024Ctx -> Ptr Word8 -> CSize -> IO CInt

    foreign import ccall unsafe "skein.h Skein_256_Final" skein256Final  :: Ptr Skein256Ctx  -> Ptr Word8 -> IO CInt
    foreign import ccall unsafe "skein.h Skein_512_Final" skein512Final  :: Ptr Skein512Ctx  -> Ptr Word8 -> IO CInt
    foreign import ccall unsafe "skein.h Skein1024_Final" skein1024Final :: Ptr Skein1024Ctx -> Ptr Word8 -> IO CInt

    foreign import ccall unsafe "skein.h Skein_256_InitExt" skein256InitExt   :: Ptr Skein256Ctx  -> CSize -> Word64 -> Ptr Word8 -> CSize -> IO CInt
    foreign import ccall unsafe "skein.h Skein_512_InitExt" skein512InitExt   :: Ptr Skein512Ctx  -> CSize -> Word64 -> Ptr Word8 -> CSize -> IO CInt
    foreign import ccall unsafe "skein.h Skein1024_InitExt" skein1024InitExt  :: Ptr Skein1024Ctx -> CSize -> Word64 -> Ptr Word8 -> CSize -> IO CInt

    foreign import ccall unsafe "skein.h Skein_256_Final_Pad" skein256FinalPad  :: Ptr Skein256Ctx  -> Ptr Word8 -> IO CInt
    foreign import ccall unsafe "skein.h Skein_512_Final_Pad" skein512FinalPad  :: Ptr Skein512Ctx  -> Ptr Word8 -> IO CInt
    foreign import ccall unsafe "skein.h Skein1024_Final_Pad" skein1024FinalPad :: Ptr Skein1024Ctx -> Ptr Word8 -> IO CInt

    foreign import ccall unsafe "skein.h Skein_256_Output" skein256Output  :: Ptr Skein256Ctx  -> Ptr Word8 -> IO CInt
    foreign import ccall unsafe "skein.h Skein_512_Output" skein512Output  :: Ptr Skein512Ctx  -> Ptr Word8 -> IO CInt
    foreign import ccall unsafe "skein.h Skein1024_Output" skein1024Output :: Ptr Skein1024Ctx -> Ptr Word8 -> IO CInt

    -- | Pass to @InitExt@ to get sequential processing.
    sKEIN_SEQUENTIAL :: Word64
    sKEIN_SEQUENTIAL :: Word64
    sKEIN_SEQUENTIAL = Word64
    0