skein-0.1: src/Crypto/Skein.hs
-----------------------------------------------------------------------------
-- |
-- Module : Crypto.Skein
-- Copyright : (c) 2011 Felipe A. Lessa
-- License : BSD3 (see LICENSE)
--
-- Maintainer : felipe.lessa@gmail.com
-- Stability : provisional
-- Portability : portable (needs FFI)
--
-- High-level interface for the Skein family of hash functions.
--
-----------------------------------------------------------------------------
module Crypto.Skein
( -- * Using this module
-- $usingMod
-- ** Skein as a cryptographic hash function
-- $skeinAsHash
-- ** Skein as a message authentication code (MAC)
-- $skeinAsMAC
-- * About Skein
-- $about
-- * Main cryptographic hash functions
-- $mainHash
-- ** Skein-512-512
Skein_512_512
, Skein_512_512_Ctx
-- ** Skein-1024-1024
, Skein_1024_1024
, Skein_1024_1024_Ctx
-- ** Skein-256-256
, Skein_256_256
, Skein_256_256_Ctx
-- * Skein-MAC
-- $skeinmac
, Key
, skeinMAC
, skeinMAC'
, SkeinMAC (skeinMACCtx)
-- * Other variants of cryptographic hash functions
-- $variants
-- ** Skein-256-128
, Skein_256_128
, Skein_256_128_Ctx
-- ** Skein-256-160
, Skein_256_160
, Skein_256_160_Ctx
-- ** Skein-256-224
, Skein_256_224
, Skein_256_224_Ctx
-- * Skein-512
-- ** Skein-512-128
, Skein_512_128
, Skein_512_128_Ctx
-- ** Skein-512-160
, Skein_512_160
, Skein_512_160_Ctx
-- ** Skein-512-224
, Skein_512_224
, Skein_512_224_Ctx
-- ** Skein-512-256
, Skein_512_256
, Skein_512_256_Ctx
-- ** Skein-512-384
, Skein_512_384
, Skein_512_384_Ctx
-- * Skein-1024
-- ** Skein-1024-384
, Skein_1024_384
, Skein_1024_384_Ctx
-- ** Skein-1024-512
, Skein_1024_512
, Skein_1024_512_Ctx
) where
-- from base
import Control.Monad (unless)
import Foreign
import Foreign.C
-- from bytestring
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString.Internal as BI
import qualified Data.ByteString.Unsafe as BU
-- from cereal
import Data.Serialize
-- from tagged
import Data.Tagged (Tagged(..))
-- from crypto-api
import Crypto.Classes
-- from this package
import Crypto.Skein.Internal
----------------------------------------------------------------------
-- $usingMod
--
-- Currently this module provides both Skein as a cryptographic
-- hash function and Skein as a MAC. This module currently does
-- not provide some Skein functions, such as tree hashing,
-- pseudo-random number generation, stream ciphing or key
-- derivation.
--
-- Terminology note: we say \"message\" for your variable-sized
-- data that is given to Skein.
-- $skeinAsHash
--
-- There are many variants of Skein as a cryptographic hash
-- function. They are called @Skein_X_Y@, where @X@ is internal
-- state size in bits and @Y@ is the output size in bits. The
-- main ones are 'Skein_512_512', 'Skein_1024_1024' and
-- 'Skein_256_256'. If you are unsure, then use 'Skein_512_512'.
--
-- To use these data types, you have to use 'Hash' and
-- 'Serialize'. Suppose you wanted to hash a lazy 'L.ByteString'
-- @bs@. Then you could use
--
-- @
-- digest :: 'S.ByteString'
-- digest = let h = 'hash' bs :: 'Skein_512_512'
-- in 'encode' h
-- @
--
-- where 'hash' is from "Crypto.Classes" (@crypto-api@ package),
-- 'encode' is from 'Serialize' (@cereal@ package) and @digest@
-- is a strict 'B.ByteString' with the hash. Given that we've
-- used 'Skein_512_512' which has an output size of 512 bits,
-- @digest@ will have @512 / 8 = 64@ bytes of length.
-- $skeinAsMAC
--
-- If you need a message authentication code (MAC), you may use
-- HMAC with Skein (e.g. HMAC-Skein-512-512). Using HMAC with
-- Skein is supported and secure. However, Skein also supports
-- another secure method, called Skein-MAC.
--
-- Skein-MAC is as secure as HMAC with Skein, however with a much
-- lower overhead (especially for short messages). HMAC requires
-- two hash invocations. Skein-MAC, on the other hand, requires
-- just one hash invocation after the setup.
--
-- To use Skein-MAC, you need 'skeinMAC' (or 'skeinMAC'') and
-- 'Serialize'. You also need a 'Key' with at least as many bits
-- as the state size you choose (@256@, @512@ or @1024@ bits).
--
-- Suppose you want to use Skein-MAC with 'Skein_512_512'. To
-- setup the MAC function with a 'Key' @key@ (that has at least
-- @512 / 8 = 64@ bytes), use
--
-- @
-- let calcMAC :: 'L.ByteString' -> 'Skein_512_512'
-- calcMAC = 'skeinMAC' key
-- @
--
-- It is recommended to partially apply 'skeinMAC' (or
-- 'skeinMAC'') to avoid recomputing the key setup. We give an
-- explicit type to 'calcMAC' because we have to choose which
-- Skein we want.
--
-- Now, if you want to calculate the Skein-MAC of a lazy
-- 'L.ByteString' message @msg@, use
--
-- @
-- let msgMAC = 'encode' (calcMAC msg)
-- @
--
-- where 'encode' is from 'Serialize' (@cereal@ package) and
-- @msgMAC@ is a strict 'B.ByteString' with the MAC.
--
-- Now, suppose you are given a @msg'@ with MAC @msgMAC'@ and
-- want to check the integrity and authenticity of @msg'@. You
-- may do so by calculating the MAC of @msg'@ and checking
-- against @msgMAC'@:
--
-- @
-- let msgMAC'' = 'encode' (calcMAC msg')
-- in if msgMAC' == msgMAC''
-- then Right \"Message is okay\"
-- else Left \"Message has been corrupted or tampered with\"
-- @
-- $about
--
-- From <http://www.skein-hash.info/about> at 09/2011:
--
-- Skein is a new family of cryptographic hash functions. Its
-- design combines speed, security, simplicity, and a great deal
-- of flexibility in a modular package that is easy to analyze.
--
-- Skein is fast. Skein-512 -- our primary proposal -- hashes data at
-- 6.1 clock cycles per byte on a 64-bit CPU. This means that on
-- a 3.1 GHz x64 Core 2 Duo CPU, Skein hashes data at 500
-- MBytes/second per core -- almost twice as fast as SHA-512 and
-- three times faster than SHA-256. An optional hash-tree mode
-- speeds up parallelizable implementations even more. Skein is
-- fast for short messages, too; Skein-512 hashes short messages
-- in about 1000 clock cycles.
--
-- Skein is secure. Our current best attack on Skein-512 is on 25
-- of 72 rounds, for a safety factor of 2.9. For comparison, at a
-- similar stage in the standardization process, the AES
-- encryption algorithm had an attack on 6 of 10 rounds, for a
-- safety factor of only 1.7. Additionally, Skein has a number of
-- provably secure properties, increasing confidence in the
-- algorithm.
--
-- Skein is simple. Using only three primitive operations, the
-- Skein compression function can be easily understood and
-- remembered. The rest of the algorithm is a straightforward
-- iteration of this function.
--
-- Skein is flexible. Skein is defined for three different
-- internal state sizes -- 256 bits, 512 bits, and 1024 bits --
-- and any output size. This allows Skein to be a drop-in
-- replacement for the entire SHA family of hash functions. A
-- completely optional and extendable argument system makes Skein
-- an efficient tool to use for a very large number of functions:
-- a PRNG, a stream cipher, a key derivation function,
-- authentication without the overhead of HMAC, and a
-- personalization capability. All these features can be
-- implemented with very low overhead. Together with the
-- Threefish large-block cipher at Skein core, this design
-- provides a full set of symmetric cryptographic primitives
-- suitable for most modern applications.
--
-- Skein is efficient on a variety of platforms, both hardware
-- and software. Skein-512 can be implemented in about 200 bytes
-- of state. Small devices, such as 8-bit smart cards, can
-- implement Skein-256 using about 100 bytes of memory. Larger
-- devices can implement the larger versions of Skein to achieve
-- faster speeds.
--
-- Skein was designed by a team of highly experienced
-- cryptographic experts from academia and industry, with
-- expertise in cryptography, security analysis, software, chip
-- design, and implementation of real-world cryptographic
-- systems. This breadth of knowledge allowed them to create a
-- balanced design that works well in all environments.
-- $mainHash
--
-- These are the main Skein hash functions. Unless you have any
-- special reasons, you should use one of these.
--
-- ['Skein_512_512'] is the primary cryptographic hash function
-- of this package. It can safely be used for all current
-- hashing applications, and should remain secure for the
-- foreseeable future.
--
-- ['Skein_1024_1024'] is the ultra-conservative variant. Even
-- if some future attack managed to break 'Skein_512_512', it
-- is quite likely that 'Skein_1024_1024' would remain secure.
--
-- ['Skein_256_256'] is the low-memory variant. It can be
-- implemented using 100 bytes of RAM, but this is not the case
-- with this implementation. It is faster than 'Skein_512_512'
-- only for small message lengths, so it's preferable to use
-- 'Skein_512_512'. If you can't afford 512 bits of output,
-- you may get the speed advantage of 'Skein_512_512' by using
-- 'Skein_512_256'.
-- $variants
--
-- These hash functions produce less output bits than their state
-- size. For example, 'Skein_512_160' produces 160 output bits
-- while having 512 bits of state size. Their main use is to be
-- a drop-in replacement to legacy hash functions. If you don't
-- have any special reason for using them, use one of the main
-- hash functions above (e.g. 'Skein_512_512').
--
-- You may replace:
--
-- [MD5] with 'Skein_256_128' or 'Skein_512_128'.
--
-- [SHA-1] with 'Skein_256_160' or 'Skein_512_160'.
--
-- [SHA-224] with 'Skein_256_224' or 'Skein_512_224'.
--
-- [SHA-256] with 'Skein_256_256' or 'Skein_512_256'.
--
-- [SHA-384] with 'Skein_512_384' or 'Skein_1024_384'.
--
-- [SHA-512] with 'Skein_512_512' or 'Skein_1024_512'.
----------------------------------------------------------------------
-- $skeinmac
--
-- The standard way to use a hash function for authentication is
-- to use the HMAC construction. While you may securely use
-- Skein with HMAC (e.g. HMAC-Skein-512-512), Skein also supports
-- another mode for MAC. Skein-MAC is as secure as
-- HMAC-Skein, however faster. Skein-MAC is as fast as
-- Skein as a hash function, with zero overhead.
-- | Secret key used to calculate the Skein-MAC.
--
-- The 'Key' may have any length. However, it's recommended to
-- have at least the same number of bits of the state size. For
-- example, when using 'skeinMAC' with 'Skein_512_256', it is
-- recommended to have a key with at least 64 bytes (512 bits),
-- which is the state size of 'Skein_512_256' (the first of the
-- two numbers).
type Key = B.ByteString
-- | Class of Skein contexts that may be used for Skein-MAC (all
-- of them). Included here mostly for documentation purposes,
-- since adding new instances is not safe (functions using
-- 'SkeinMAC' unsurprisingly assume that they are using Skein).
class SkeinMAC skeinCtx where
-- | Construct a context @skeinCtx@ given a 'Key'. This
-- context may be used with the usual 'Hash' interface to
-- obtain a message authentication code (MAC).
--
-- For a simpler interface, see 'skeinMAC' and 'skeinMAC''.
skeinMACCtx :: Key -> skeinCtx
-- | Calculate the Skein-MAC of a lazy 'L.ByteString' given a
-- 'Key'. You probably also want to apply 'encode' to get a
-- 'B.ByteString' out of the @digest@.
--
-- This function may be partially applied for increased
-- performance. Using a partially applied @skeinMAC@ is as fast
-- as using Skein as a cryptographic hash function. So, instead
-- of
--
-- @
-- let mac1 = skeinMAC key message1
-- mac2 = skeinMAC key message2
-- mac3 = skeinMAC key message3
-- ...
-- @
--
-- write the following code:
--
-- @
-- let calcMAC = skeinMAC key
-- mac1 = calcMAC message1
-- mac2 = calcMAC message2
-- mac3 = calcMAC message3
-- ...
-- @
--
-- This way the key will be processed only once (with
-- 'skeinMACCtx').
skeinMAC :: (SkeinMAC skeinCtx, Hash skeinCtx digest) =>
Key -> L.ByteString -> digest
skeinMAC k = go
where
ctx = skeinMACCtx k
go = go' ctx . L.toChunks
go' ctx' [] = finalize ctx' B.empty
go' ctx' [x] = finalize ctx' x
go' ctx' (x:xs) = go' (updateCtx ctx' x) xs
-- See the comment below on skeinMAC'.
-- | Same as 'skeinMAC', however using a strict 'B.ByteString'.
-- Should be faster for small 'B.ByteString'@s@.
skeinMAC' :: (SkeinMAC skeinCtx, Hash skeinCtx digest) =>
Key -> B.ByteString -> digest
skeinMAC' k = go
where
ctx = skeinMACCtx k
go = finalize ctx
-- We can just call 'finalize' because of the way our
-- implementation works. Basically, we accept ByteString
-- of any length on both 'updateCtx' and 'finalize'.
-- Calling just 'finalize' is more efficient.
----------------------------------------------------------------------
-- | Helper function to create 'initialCtx'.
initialCtxSkein :: Storable internalCtx =>
CSize
-> (Ptr internalCtx -> CSize -> IO CInt)
-> (internalCtx -> externalCtx)
-> externalCtx
initialCtxSkein bits init_ mkCtx =
unsafePerformIO $
alloca $ \ctx_ptr -> do
check $ init_ ctx_ptr bits
fmap mkCtx $ peek ctx_ptr
-- | Helper function to create 'updateCtxSkein'.
updateCtxSkein :: Storable internalCtx =>
(Ptr internalCtx -> Ptr Word8 -> CSize -> IO CInt)
-> (externalCtx -> internalCtx)
-> (internalCtx -> externalCtx)
-> (externalCtx -> B.ByteString -> externalCtx)
updateCtxSkein update unCtx mkCtx = \ctx bs ->
unsafePerformIO $
BU.unsafeUseAsCStringLen bs $ \(bs_ptr, bs_len) ->
with (unCtx ctx) $ \ctx_ptr -> do
check $ update ctx_ptr (castPtr bs_ptr) (fromIntegral bs_len)
fmap mkCtx $ peek ctx_ptr
-- | Helper function to create 'finalize'.
finalizeSkein :: Storable internalCtx =>
Int
-> (Ptr internalCtx -> Ptr Word8 -> CSize -> IO CInt)
-> (Ptr internalCtx -> Ptr Word8 -> IO CInt)
-> (externalCtx -> internalCtx)
-> (B.ByteString -> hash)
-> (externalCtx -> B.ByteString -> hash)
finalizeSkein hashLenBytes update final unCtx mkHash = \ctx bs ->
unsafePerformIO $
with (unCtx ctx) $ \ctx_ptr -> do
unless (B.null bs) $
BU.unsafeUseAsCStringLen bs $ \(bs_ptr, bs_len) ->
check $ update ctx_ptr (castPtr bs_ptr) (fromIntegral bs_len)
fmap mkHash $ BI.create hashLenBytes $ check . final ctx_ptr . castPtr
-- | Helper function to create 'skeinMACCtx'.
skeinMACCtxSkein :: Storable internalCtx =>
CSize
-> (Ptr internalCtx -> CSize -> Word64 -> Ptr Word8 -> CSize -> IO CInt)
-> (internalCtx -> externalCtx)
-> (Key -> externalCtx)
skeinMACCtxSkein bits initExt mkCtx = \key ->
unsafePerformIO $
BU.unsafeUseAsCStringLen key $ \(key_ptr, key_len) ->
alloca $ \ctx_ptr -> do
check $ initExt ctx_ptr bits sKEIN_SEQUENTIAL (castPtr key_ptr) (fromIntegral key_len)
fmap mkCtx $ peek ctx_ptr
----------------------------------------------------------------------
-- Skein-256
----------------------------------------------------------------------
-- | Context of the Skein-256-128 hash function.
newtype Skein_256_128_Ctx = S_256_128_Ctx {unS_256_128_Ctx :: Skein256Ctx}
-- | Skein-256-128 hash. You probably want to use 'encode' to
-- obtain a 128-bit (16-byte) 'B.ByteString'. May be used as a
-- drop-in replacement for MD5.
newtype Skein_256_128 = S_256_128 B.ByteString deriving (Eq, Ord)
instance Serialize Skein_256_128 where
put (S_256_128 bs) = putByteString bs
get = fmap S_256_128 $ getByteString 16
instance Hash Skein_256_128_Ctx Skein_256_128 where
outputLength = Tagged 128
blockLength = Tagged 256
initialCtx = initialCtxSkein 128 skein256Init S_256_128_Ctx
updateCtx = updateCtxSkein skein256Update unS_256_128_Ctx S_256_128_Ctx
finalize = finalizeSkein 16 skein256Update skein256Final unS_256_128_Ctx S_256_128
instance SkeinMAC Skein_256_128_Ctx where
skeinMACCtx = skeinMACCtxSkein 128 skein256InitExt S_256_128_Ctx
-- | Context of the Skein-256-160 hash function.
newtype Skein_256_160_Ctx = S_256_160_Ctx {unS_256_160_Ctx :: Skein256Ctx}
-- | Skein-256-160 hash. You probably want to use 'encode' to
-- obtain a 160-bit (20-byte) 'B.ByteString'. May be used as a
-- drop-in replacement for SHA-1.
newtype Skein_256_160 = S_256_160 B.ByteString deriving (Eq, Ord)
instance Serialize Skein_256_160 where
put (S_256_160 bs) = putByteString bs
get = fmap S_256_160 $ getByteString 20
instance Hash Skein_256_160_Ctx Skein_256_160 where
outputLength = Tagged 160
blockLength = Tagged 256
initialCtx = initialCtxSkein 160 skein256Init S_256_160_Ctx
updateCtx = updateCtxSkein skein256Update unS_256_160_Ctx S_256_160_Ctx
finalize = finalizeSkein 20 skein256Update skein256Final unS_256_160_Ctx S_256_160
instance SkeinMAC Skein_256_160_Ctx where
skeinMACCtx = skeinMACCtxSkein 160 skein256InitExt S_256_160_Ctx
-- | Context of the Skein-256-224 hash function.
newtype Skein_256_224_Ctx = S_256_224_Ctx {unS_256_224_Ctx :: Skein256Ctx}
-- | Skein-256-224 hash. You probably want to use 'encode' to
-- obtain a 224-bit (28-byte) 'B.ByteString'. May be used as a
-- drop-in replacement for SHA-224.
newtype Skein_256_224 = S_256_224 B.ByteString deriving (Eq, Ord)
instance Serialize Skein_256_224 where
put (S_256_224 bs) = putByteString bs
get = fmap S_256_224 $ getByteString 28
instance Hash Skein_256_224_Ctx Skein_256_224 where
outputLength = Tagged 224
blockLength = Tagged 256
initialCtx = initialCtxSkein 224 skein256Init S_256_224_Ctx
updateCtx = updateCtxSkein skein256Update unS_256_224_Ctx S_256_224_Ctx
finalize = finalizeSkein 28 skein256Update skein256Final unS_256_224_Ctx S_256_224
instance SkeinMAC Skein_256_224_Ctx where
skeinMACCtx = skeinMACCtxSkein 224 skein256InitExt S_256_224_Ctx
-- | Context of the Skein-256-256 hash function.
newtype Skein_256_256_Ctx = S_256_256_Ctx {unS_256_256_Ctx :: Skein256Ctx}
-- | Skein-256-256 hash. You probably want to use 'encode' to
-- obtain a 256-bit (32-byte) 'B.ByteString'. Usually it's better
-- to use 'Skein_512_256' (256 bits of output) or 'Skein_512_512'
-- (512 bits of output).
newtype Skein_256_256 = S_256_256 B.ByteString deriving (Eq, Ord)
instance Serialize Skein_256_256 where
put (S_256_256 bs) = putByteString bs
get = fmap S_256_256 $ getByteString 32
instance Hash Skein_256_256_Ctx Skein_256_256 where
outputLength = Tagged 256
blockLength = Tagged 256
initialCtx = initialCtxSkein 256 skein256Init S_256_256_Ctx
updateCtx = updateCtxSkein skein256Update unS_256_256_Ctx S_256_256_Ctx
finalize = finalizeSkein 32 skein256Update skein256Final unS_256_256_Ctx S_256_256
instance SkeinMAC Skein_256_256_Ctx where
skeinMACCtx = skeinMACCtxSkein 256 skein256InitExt S_256_256_Ctx
----------------------------------------------------------------------
-- Skein-512
----------------------------------------------------------------------
-- | Context of the Skein-512-128 hash function.
newtype Skein_512_128_Ctx = S_512_128_Ctx {unS_512_128_Ctx :: Skein512Ctx}
-- | Skein-512-128 hash. You probably want to use 'encode' to
-- obtain a 128-bit (16-byte) 'B.ByteString'. May be used as a
-- drop-in replacement for MD5.
newtype Skein_512_128 = S_512_128 B.ByteString deriving (Eq, Ord)
instance Serialize Skein_512_128 where
put (S_512_128 bs) = putByteString bs
get = fmap S_512_128 $ getByteString 16
instance Hash Skein_512_128_Ctx Skein_512_128 where
outputLength = Tagged 128
blockLength = Tagged 512
initialCtx = initialCtxSkein 128 skein512Init S_512_128_Ctx
updateCtx = updateCtxSkein skein512Update unS_512_128_Ctx S_512_128_Ctx
finalize = finalizeSkein 16 skein512Update skein512Final unS_512_128_Ctx S_512_128
instance SkeinMAC Skein_512_128_Ctx where
skeinMACCtx = skeinMACCtxSkein 128 skein512InitExt S_512_128_Ctx
-- | Context of the Skein-512-160 hash function.
newtype Skein_512_160_Ctx = S_512_160_Ctx {unS_512_160_Ctx :: Skein512Ctx}
-- | Skein-512-160 hash. You probably want to use 'encode' to
-- obtain a 160-bit (20-byte) 'B.ByteString'. May be used as a
-- drop-in replacement for SHA-1.
newtype Skein_512_160 = S_512_160 B.ByteString deriving (Eq, Ord)
instance Serialize Skein_512_160 where
put (S_512_160 bs) = putByteString bs
get = fmap S_512_160 $ getByteString 20
instance Hash Skein_512_160_Ctx Skein_512_160 where
outputLength = Tagged 160
blockLength = Tagged 512
initialCtx = initialCtxSkein 160 skein512Init S_512_160_Ctx
updateCtx = updateCtxSkein skein512Update unS_512_160_Ctx S_512_160_Ctx
finalize = finalizeSkein 20 skein512Update skein512Final unS_512_160_Ctx S_512_160
instance SkeinMAC Skein_512_160_Ctx where
skeinMACCtx = skeinMACCtxSkein 160 skein512InitExt S_512_160_Ctx
-- | Context of the Skein-512-224 hash function.
newtype Skein_512_224_Ctx = S_512_224_Ctx {unS_512_224_Ctx :: Skein512Ctx}
-- | Skein-512-224 hash. You probably want to use 'encode' to
-- obtain a 224-bit (28-byte) 'B.ByteString'. May be used as a drop-in replacement for SHA-224.
newtype Skein_512_224 = S_512_224 B.ByteString deriving (Eq, Ord)
instance Serialize Skein_512_224 where
put (S_512_224 bs) = putByteString bs
get = fmap S_512_224 $ getByteString 28
instance Hash Skein_512_224_Ctx Skein_512_224 where
outputLength = Tagged 224
blockLength = Tagged 512
initialCtx = initialCtxSkein 224 skein512Init S_512_224_Ctx
updateCtx = updateCtxSkein skein512Update unS_512_224_Ctx S_512_224_Ctx
finalize = finalizeSkein 28 skein512Update skein512Final unS_512_224_Ctx S_512_224
instance SkeinMAC Skein_512_224_Ctx where
skeinMACCtx = skeinMACCtxSkein 224 skein512InitExt S_512_224_Ctx
-- | Context of the Skein-512-256 hash function.
newtype Skein_512_256_Ctx = S_512_256_Ctx {unS_512_256_Ctx :: Skein512Ctx}
-- | Skein-512-256 hash. You probably want to use 'encode' to
-- obtain a 256-bit (32-byte) 'B.ByteString'.
newtype Skein_512_256 = S_512_256 B.ByteString deriving (Eq, Ord)
instance Serialize Skein_512_256 where
put (S_512_256 bs) = putByteString bs
get = fmap S_512_256 $ getByteString 32
instance Hash Skein_512_256_Ctx Skein_512_256 where
outputLength = Tagged 256
blockLength = Tagged 512
initialCtx = initialCtxSkein 256 skein512Init S_512_256_Ctx
updateCtx = updateCtxSkein skein512Update unS_512_256_Ctx S_512_256_Ctx
finalize = finalizeSkein 32 skein512Update skein512Final unS_512_256_Ctx S_512_256
instance SkeinMAC Skein_512_256_Ctx where
skeinMACCtx = skeinMACCtxSkein 256 skein512InitExt S_512_256_Ctx
-- | Context of the Skein-512-384 hash function.
newtype Skein_512_384_Ctx = S_512_384_Ctx {unS_512_384_Ctx :: Skein512Ctx}
-- | Skein-512-384 hash. You probably want to use 'encode' to
-- obtain a 384-bit (48-byte) 'B.ByteString'. May be used as a
-- drop-in replacement for SHA-384.
newtype Skein_512_384 = S_512_384 B.ByteString deriving (Eq, Ord)
instance Serialize Skein_512_384 where
put (S_512_384 bs) = putByteString bs
get = fmap S_512_384 $ getByteString 48
instance Hash Skein_512_384_Ctx Skein_512_384 where
outputLength = Tagged 384
blockLength = Tagged 512
initialCtx = initialCtxSkein 384 skein512Init S_512_384_Ctx
updateCtx = updateCtxSkein skein512Update unS_512_384_Ctx S_512_384_Ctx
finalize = finalizeSkein 48 skein512Update skein512Final unS_512_384_Ctx S_512_384
instance SkeinMAC Skein_512_384_Ctx where
skeinMACCtx = skeinMACCtxSkein 384 skein512InitExt S_512_384_Ctx
-- | Context of the Skein-512-512 hash function.
newtype Skein_512_512_Ctx = S_512_512_Ctx {unS_512_512_Ctx :: Skein512Ctx}
-- | Skein-512-512 hash. You probably want to use 'encode' to
-- obtain a 512-bit (64-byte) 'B.ByteString'. It's the main Skein
-- hash function. May be used as a drop-in replacement for
-- SHA-512 as well.
newtype Skein_512_512 = S_512_512 B.ByteString deriving (Eq, Ord)
instance Serialize Skein_512_512 where
put (S_512_512 bs) = putByteString bs
get = fmap S_512_512 $ getByteString 64
instance Hash Skein_512_512_Ctx Skein_512_512 where
outputLength = Tagged 512
blockLength = Tagged 512
initialCtx = initialCtxSkein 512 skein512Init S_512_512_Ctx
updateCtx = updateCtxSkein skein512Update unS_512_512_Ctx S_512_512_Ctx
finalize = finalizeSkein 64 skein512Update skein512Final unS_512_512_Ctx S_512_512
instance SkeinMAC Skein_512_512_Ctx where
skeinMACCtx = skeinMACCtxSkein 512 skein512InitExt S_512_512_Ctx
----------------------------------------------------------------------
-- Skein-1024
----------------------------------------------------------------------
-- | Context of the Skein-1024-384 hash function.
newtype Skein_1024_384_Ctx = S_1024_384_Ctx {unS_1024_384_Ctx :: Skein1024Ctx}
-- | Skein-1024-384 hash. You probably want to use 'encode' to
-- obtain a 384-bit (48-byte) 'B.ByteString'. May be used as a
-- drop-in replacement for SHA-384.
newtype Skein_1024_384 = S_1024_384 B.ByteString deriving (Eq, Ord)
instance Serialize Skein_1024_384 where
put (S_1024_384 bs) = putByteString bs
get = fmap S_1024_384 $ getByteString 48
instance Hash Skein_1024_384_Ctx Skein_1024_384 where
outputLength = Tagged 384
blockLength = Tagged 1024
initialCtx = initialCtxSkein 384 skein1024Init S_1024_384_Ctx
updateCtx = updateCtxSkein skein1024Update unS_1024_384_Ctx S_1024_384_Ctx
finalize = finalizeSkein 48 skein1024Update skein1024Final unS_1024_384_Ctx S_1024_384
instance SkeinMAC Skein_1024_384_Ctx where
skeinMACCtx = skeinMACCtxSkein 384 skein1024InitExt S_1024_384_Ctx
-- | Context of the Skein-1024-512 hash function.
newtype Skein_1024_512_Ctx = S_1024_512_Ctx {unS_1024_512_Ctx :: Skein1024Ctx}
-- | Skein-1024-512 hash. You probably want to use 'encode' to
-- obtain a 512-bit (64-byte) 'B.ByteString'. May be used as a
-- drop-in replacement for SHA-512.
newtype Skein_1024_512 = S_1024_512 B.ByteString deriving (Eq, Ord)
instance Serialize Skein_1024_512 where
put (S_1024_512 bs) = putByteString bs
get = fmap S_1024_512 $ getByteString 64
instance Hash Skein_1024_512_Ctx Skein_1024_512 where
outputLength = Tagged 512
blockLength = Tagged 1024
initialCtx = initialCtxSkein 512 skein1024Init S_1024_512_Ctx
updateCtx = updateCtxSkein skein1024Update unS_1024_512_Ctx S_1024_512_Ctx
finalize = finalizeSkein 64 skein1024Update skein1024Final unS_1024_512_Ctx S_1024_512
instance SkeinMAC Skein_1024_512_Ctx where
skeinMACCtx = skeinMACCtxSkein 512 skein1024InitExt S_1024_512_Ctx
-- | Context of the Skein-1024-1024 hash function.
newtype Skein_1024_1024_Ctx = S_1024_1024_Ctx {unS_1024_1024_Ctx :: Skein1024Ctx}
-- | Skein-1024-1024 hash. You probably want to use 'encode' to
-- obtain a 1024-bit (128-byte) 'B.ByteString'. This is the
-- ultra-conservative variant. Even if some future attack
-- managed to break Skein-512, it's quite likely that Skein-1024
-- would remain secure.
newtype Skein_1024_1024 = S_1024_1024 B.ByteString deriving (Eq, Ord)
instance Serialize Skein_1024_1024 where
put (S_1024_1024 bs) = putByteString bs
get = fmap S_1024_1024 $ getByteString 128
instance Hash Skein_1024_1024_Ctx Skein_1024_1024 where
outputLength = Tagged 1024
blockLength = Tagged 1024
initialCtx = initialCtxSkein 1024 skein1024Init S_1024_1024_Ctx
updateCtx = updateCtxSkein skein1024Update unS_1024_1024_Ctx S_1024_1024_Ctx
finalize = finalizeSkein 128 skein1024Update skein1024Final unS_1024_1024_Ctx S_1024_1024
instance SkeinMAC Skein_1024_1024_Ctx where
skeinMACCtx = skeinMACCtxSkein 1024 skein1024InitExt S_1024_1024_Ctx