{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
-- | Efficient representation for small bytearrays with 128 or 256 bits.
module Data.LargeHashable.LargeWord
    ( Word128(..), Word256(..)
    , bsToW128, w128ToBs
    , bsToW256, w256ToBs
    , xorW128, xorW256
    )
where

-- keep imports in alphabetic order (in Emacs, use "M-x sort-lines")
import Data.Bits
import Data.Data (Data)
import Data.Typeable
import Data.Word
import GHC.Generics (Generic)
import qualified Data.ByteString as BS

data Word128
    = Word128
    { Word128 -> Word64
w128_first :: !Word64
    , Word128 -> Word64
w128_second :: !Word64
    }
    deriving (Int -> Word128 -> ShowS
[Word128] -> ShowS
Word128 -> String
(Int -> Word128 -> ShowS)
-> (Word128 -> String) -> ([Word128] -> ShowS) -> Show Word128
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Word128 -> ShowS
showsPrec :: Int -> Word128 -> ShowS
$cshow :: Word128 -> String
show :: Word128 -> String
$cshowList :: [Word128] -> ShowS
showList :: [Word128] -> ShowS
Show, ReadPrec [Word128]
ReadPrec Word128
Int -> ReadS Word128
ReadS [Word128]
(Int -> ReadS Word128)
-> ReadS [Word128]
-> ReadPrec Word128
-> ReadPrec [Word128]
-> Read Word128
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Word128
readsPrec :: Int -> ReadS Word128
$creadList :: ReadS [Word128]
readList :: ReadS [Word128]
$creadPrec :: ReadPrec Word128
readPrec :: ReadPrec Word128
$creadListPrec :: ReadPrec [Word128]
readListPrec :: ReadPrec [Word128]
Read, Word128 -> Word128 -> Bool
(Word128 -> Word128 -> Bool)
-> (Word128 -> Word128 -> Bool) -> Eq Word128
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Word128 -> Word128 -> Bool
== :: Word128 -> Word128 -> Bool
$c/= :: Word128 -> Word128 -> Bool
/= :: Word128 -> Word128 -> Bool
Eq, Eq Word128
Eq Word128 =>
(Word128 -> Word128 -> Ordering)
-> (Word128 -> Word128 -> Bool)
-> (Word128 -> Word128 -> Bool)
-> (Word128 -> Word128 -> Bool)
-> (Word128 -> Word128 -> Bool)
-> (Word128 -> Word128 -> Word128)
-> (Word128 -> Word128 -> Word128)
-> Ord Word128
Word128 -> Word128 -> Bool
Word128 -> Word128 -> Ordering
Word128 -> Word128 -> Word128
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Word128 -> Word128 -> Ordering
compare :: Word128 -> Word128 -> Ordering
$c< :: Word128 -> Word128 -> Bool
< :: Word128 -> Word128 -> Bool
$c<= :: Word128 -> Word128 -> Bool
<= :: Word128 -> Word128 -> Bool
$c> :: Word128 -> Word128 -> Bool
> :: Word128 -> Word128 -> Bool
$c>= :: Word128 -> Word128 -> Bool
>= :: Word128 -> Word128 -> Bool
$cmax :: Word128 -> Word128 -> Word128
max :: Word128 -> Word128 -> Word128
$cmin :: Word128 -> Word128 -> Word128
min :: Word128 -> Word128 -> Word128
Ord, Typeable, (forall x. Word128 -> Rep Word128 x)
-> (forall x. Rep Word128 x -> Word128) -> Generic Word128
forall x. Rep Word128 x -> Word128
forall x. Word128 -> Rep Word128 x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Word128 -> Rep Word128 x
from :: forall x. Word128 -> Rep Word128 x
$cto :: forall x. Rep Word128 x -> Word128
to :: forall x. Rep Word128 x -> Word128
Generic, Typeable Word128
Typeable Word128 =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> Word128 -> c Word128)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Word128)
-> (Word128 -> Constr)
-> (Word128 -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Word128))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Word128))
-> ((forall b. Data b => b -> b) -> Word128 -> Word128)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Word128 -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Word128 -> r)
-> (forall u. (forall d. Data d => d -> u) -> Word128 -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Word128 -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Word128 -> m Word128)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Word128 -> m Word128)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Word128 -> m Word128)
-> Data Word128
Word128 -> Constr
Word128 -> DataType
(forall b. Data b => b -> b) -> Word128 -> Word128
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Word128 -> u
forall u. (forall d. Data d => d -> u) -> Word128 -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Word128 -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Word128 -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Word128 -> m Word128
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Word128 -> m Word128
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Word128
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Word128 -> c Word128
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Word128)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Word128)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Word128 -> c Word128
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Word128 -> c Word128
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Word128
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Word128
$ctoConstr :: Word128 -> Constr
toConstr :: Word128 -> Constr
$cdataTypeOf :: Word128 -> DataType
dataTypeOf :: Word128 -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Word128)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Word128)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Word128)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Word128)
$cgmapT :: (forall b. Data b => b -> b) -> Word128 -> Word128
gmapT :: (forall b. Data b => b -> b) -> Word128 -> Word128
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Word128 -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Word128 -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Word128 -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Word128 -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Word128 -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> Word128 -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Word128 -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Word128 -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Word128 -> m Word128
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Word128 -> m Word128
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Word128 -> m Word128
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Word128 -> m Word128
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Word128 -> m Word128
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Word128 -> m Word128
Data)

data Word256
    = Word256
    { Word256 -> Word128
w256_first :: !Word128
    , Word256 -> Word128
w256_second :: !Word128
    }
    deriving (Int -> Word256 -> ShowS
[Word256] -> ShowS
Word256 -> String
(Int -> Word256 -> ShowS)
-> (Word256 -> String) -> ([Word256] -> ShowS) -> Show Word256
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Word256 -> ShowS
showsPrec :: Int -> Word256 -> ShowS
$cshow :: Word256 -> String
show :: Word256 -> String
$cshowList :: [Word256] -> ShowS
showList :: [Word256] -> ShowS
Show, ReadPrec [Word256]
ReadPrec Word256
Int -> ReadS Word256
ReadS [Word256]
(Int -> ReadS Word256)
-> ReadS [Word256]
-> ReadPrec Word256
-> ReadPrec [Word256]
-> Read Word256
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Word256
readsPrec :: Int -> ReadS Word256
$creadList :: ReadS [Word256]
readList :: ReadS [Word256]
$creadPrec :: ReadPrec Word256
readPrec :: ReadPrec Word256
$creadListPrec :: ReadPrec [Word256]
readListPrec :: ReadPrec [Word256]
Read, Word256 -> Word256 -> Bool
(Word256 -> Word256 -> Bool)
-> (Word256 -> Word256 -> Bool) -> Eq Word256
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Word256 -> Word256 -> Bool
== :: Word256 -> Word256 -> Bool
$c/= :: Word256 -> Word256 -> Bool
/= :: Word256 -> Word256 -> Bool
Eq, Eq Word256
Eq Word256 =>
(Word256 -> Word256 -> Ordering)
-> (Word256 -> Word256 -> Bool)
-> (Word256 -> Word256 -> Bool)
-> (Word256 -> Word256 -> Bool)
-> (Word256 -> Word256 -> Bool)
-> (Word256 -> Word256 -> Word256)
-> (Word256 -> Word256 -> Word256)
-> Ord Word256
Word256 -> Word256 -> Bool
Word256 -> Word256 -> Ordering
Word256 -> Word256 -> Word256
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Word256 -> Word256 -> Ordering
compare :: Word256 -> Word256 -> Ordering
$c< :: Word256 -> Word256 -> Bool
< :: Word256 -> Word256 -> Bool
$c<= :: Word256 -> Word256 -> Bool
<= :: Word256 -> Word256 -> Bool
$c> :: Word256 -> Word256 -> Bool
> :: Word256 -> Word256 -> Bool
$c>= :: Word256 -> Word256 -> Bool
>= :: Word256 -> Word256 -> Bool
$cmax :: Word256 -> Word256 -> Word256
max :: Word256 -> Word256 -> Word256
$cmin :: Word256 -> Word256 -> Word256
min :: Word256 -> Word256 -> Word256
Ord, Typeable, (forall x. Word256 -> Rep Word256 x)
-> (forall x. Rep Word256 x -> Word256) -> Generic Word256
forall x. Rep Word256 x -> Word256
forall x. Word256 -> Rep Word256 x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Word256 -> Rep Word256 x
from :: forall x. Word256 -> Rep Word256 x
$cto :: forall x. Rep Word256 x -> Word256
to :: forall x. Rep Word256 x -> Word256
Generic, Typeable Word256
Typeable Word256 =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> Word256 -> c Word256)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Word256)
-> (Word256 -> Constr)
-> (Word256 -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Word256))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Word256))
-> ((forall b. Data b => b -> b) -> Word256 -> Word256)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Word256 -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Word256 -> r)
-> (forall u. (forall d. Data d => d -> u) -> Word256 -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Word256 -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Word256 -> m Word256)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Word256 -> m Word256)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Word256 -> m Word256)
-> Data Word256
Word256 -> Constr
Word256 -> DataType
(forall b. Data b => b -> b) -> Word256 -> Word256
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Word256 -> u
forall u. (forall d. Data d => d -> u) -> Word256 -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Word256 -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Word256 -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Word256 -> m Word256
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Word256 -> m Word256
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Word256
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Word256 -> c Word256
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Word256)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Word256)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Word256 -> c Word256
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Word256 -> c Word256
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Word256
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Word256
$ctoConstr :: Word256 -> Constr
toConstr :: Word256 -> Constr
$cdataTypeOf :: Word256 -> DataType
dataTypeOf :: Word256 -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Word256)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Word256)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Word256)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Word256)
$cgmapT :: (forall b. Data b => b -> b) -> Word256 -> Word256
gmapT :: (forall b. Data b => b -> b) -> Word256 -> Word256
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Word256 -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Word256 -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Word256 -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Word256 -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Word256 -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> Word256 -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Word256 -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Word256 -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Word256 -> m Word256
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Word256 -> m Word256
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Word256 -> m Word256
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Word256 -> m Word256
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Word256 -> m Word256
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Word256 -> m Word256
Data)

-- | Converts a 'ByteString' into a 'Word256'. Only the first 32 bytes
-- are taken into account, the rest is ignored.
bsToW256 :: BS.ByteString -> Word256
bsToW256 :: ByteString -> Word256
bsToW256 ByteString
bs = Word128 -> Word128 -> Word256
Word256 Word128
first128 Word128
next128
    where
      first128 :: Word128
first128 = ByteString -> Word128
bsToW128 ByteString
bs
      next128 :: Word128
next128 = ByteString -> Word128
bsToW128 (Int -> ByteString -> ByteString
BS.drop Int
16 ByteString
bs)

w256ToBs :: Word256 -> BS.ByteString
w256ToBs :: Word256 -> ByteString
w256ToBs (Word256 Word128
first128 Word128
next128) =
    Word128 -> ByteString
w128ToBs Word128
first128 ByteString -> ByteString -> ByteString
`BS.append` Word128 -> ByteString
w128ToBs Word128
next128

-- | Converts a 'ByteString' into a 'Word128'. Only the first 16 bytes
-- are taken into account, the rest is ignored.
bsToW128 :: BS.ByteString -> Word128
bsToW128 :: ByteString -> Word128
bsToW128 ByteString
bs = Word64 -> Word64 -> Word128
Word128 Word64
first64 Word64
next64
    where
      first64 :: Word64
first64 = ByteString -> Word64
bsToW64 ByteString
bs
      next64 :: Word64
next64 = ByteString -> Word64
bsToW64 (Int -> ByteString -> ByteString
BS.drop Int
8 ByteString
bs)

w128ToBs :: Word128 -> BS.ByteString
w128ToBs :: Word128 -> ByteString
w128ToBs (Word128 Word64
first64 Word64
next64) =
    Word64 -> ByteString
w64ToBs Word64
first64 ByteString -> ByteString -> ByteString
`BS.append` Word64 -> ByteString
w64ToBs Word64
next64

w64ToBs :: Word64 -> BS.ByteString
w64ToBs :: Word64 -> ByteString
w64ToBs Word64
w64 =
    [Word8] -> ByteString
BS.pack
    [ Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
w64 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
56 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
255)
    , Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
w64 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
48 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
255)
    , Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
w64 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
40 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
255)
    , Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
w64 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
32 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
255)
    , Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
w64 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
24 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
255)
    , Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
w64 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
16 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
255)
    , Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
w64 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
8 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
255)
    , Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
w64 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
255)
    ]

bsToW64 :: BS.ByteString -> Word64
bsToW64 :: ByteString -> Word64
bsToW64 = (Word64 -> Word8 -> Word64) -> Word64 -> ByteString -> Word64
forall a. (a -> Word8 -> a) -> a -> ByteString -> a
BS.foldl' (\Word64
x Word8
w8 -> (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
8) Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word8 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
w8) Word64
0 (ByteString -> Word64)
-> (ByteString -> ByteString) -> ByteString -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ByteString -> ByteString
BS.take Int
8

xorW128 :: Word128 -> Word128 -> Word128
xorW128 :: Word128 -> Word128 -> Word128
xorW128 (Word128 Word64
w11 Word64
w12) (Word128 Word64
w21 Word64
w22) = Word64 -> Word64 -> Word128
Word128 (Word64
w11 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` Word64
w21) (Word64
w12 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` Word64
w22)

xorW256 :: Word256 -> Word256 -> Word256
xorW256 :: Word256 -> Word256 -> Word256
xorW256 (Word256 Word128
w11 Word128
w12) (Word256 Word128
w21 Word128
w22) = Word128 -> Word128 -> Word256
Word256 (Word128
w11 Word128 -> Word128 -> Word128
`xorW128` Word128
w21) (Word128
w12 Word128 -> Word128 -> Word128
`xorW128` Word128
w22)