    {-# LANGUAGE CPP                #-}
    {-# LANGUAGE MagicHash          #-}
    {-# LANGUAGE UnboxedTuples      #-}
    {-# LANGUAGE DeriveDataTypeable #-}
    module Basement.Types.Word256
        ( Word256(..)
        , (+)
        , (-)
        , (*)
        , quot
        , rem
        , bitwiseAnd
        , bitwiseOr
        , bitwiseXor
        , complement
        , shiftL
        , shiftR
        , rotateL
        , rotateR
        , popCount
        , fromNatural
        ) where

    import           GHC.Prim hiding (word64ToWord#)
    import qualified GHC.Prim
    import           GHC.Word
    import           GHC.Types
    import qualified Prelude (fromInteger, show, Num(..), quot, rem, mod)
    import           Data.Bits hiding (complement, popCount, bit, testBit
                                      , rotateL, rotateR, shiftL, shiftR)
    import qualified Data.Bits as Bits
    import           Data.Function (on)
    import           Foreign.C
    import           Foreign.Ptr
    import           Foreign.Storable

    import           Basement.Compat.Base
    import           Basement.Compat.Natural
    import           Basement.Compat.Primitive (bool#)
    import           Basement.Numerical.Conversion
    import           Basement.Numerical.Number

    #include "MachDeps.h"

    -- | 256 bits Word
    data Word256 = Word256 {-# UNPACK #-} !Word64
                           {-# UNPACK #-} !Word64
                           {-# UNPACK #-} !Word64
                           {-# UNPACK #-} !Word64
        deriving (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, Typeable)

    instance Show Word256 where
        show :: Word256 -> String
    show Word256
    w = Natural -> String
    forall a. Show a => a -> String
    Prelude.show (Word256 -> Natural
    forall a. IsNatural a => a -> Natural
    toNatural Word256
    w)
    instance Enum Word256 where
        toEnum :: Int -> Word256
    toEnum Int
    i = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    0 Word64
    0 Word64
    0 (Word64 -> Word256) -> Word64 -> Word256
    forall a b. (a -> b) -> a -> b
    $ Int64 -> Word64
    int64ToWord64 (Int -> Int64
    intToInt64 Int
    i)
        fromEnum :: Word256 -> Int
    fromEnum (Word256 Word64
    _ Word64
    _ Word64
    _ Word64
    a0) = Word -> Int
    wordToInt (Word64 -> Word
    word64ToWord Word64
    a0)
        succ :: Word256 -> Word256
    succ (Word256 Word64
    a3 Word64
    a2 Word64
    a1 Word64
    a0)
            | Word64
    a0 Word64 -> Word64 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word64
    forall a. Bounded a => a
    maxBound =
                if Word64
    a1 Word64 -> Word64 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word64
    forall a. Bounded a => a
    maxBound
                    then if Word64
    a2 Word64 -> Word64 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word64
    forall a. Bounded a => a
    maxBound
                            then Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 (Word64 -> Word64
    forall a. Enum a => a -> a
    succ Word64
    a3) Word64
    0 Word64
    0 Word64
    0
                            else Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    a3 (Word64 -> Word64
    forall a. Enum a => a -> a
    succ Word64
    a2) Word64
    0 Word64
    0
                    else Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    a3 Word64
    a2 (Word64 -> Word64
    forall a. Enum a => a -> a
    succ Word64
    a1) Word64
    0
            | Bool
    otherwise      = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    a3 Word64
    a2 Word64
    a1        (Word64 -> Word64
    forall a. Enum a => a -> a
    succ Word64
    a0)
        pred :: Word256 -> Word256
    pred (Word256 Word64
    a3 Word64
    a2 Word64
    a1 Word64
    a0)
            | Word64
    a0 Word64 -> Word64 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word64
    forall a. Bounded a => a
    minBound =
                if Word64
    a1 Word64 -> Word64 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word64
    forall a. Bounded a => a
    minBound
                    then if Word64
    a2 Word64 -> Word64 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word64
    forall a. Bounded a => a
    minBound
                            then Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 (Word64 -> Word64
    forall a. Enum a => a -> a
    pred Word64
    a3) Word64
    forall a. Bounded a => a
    maxBound Word64
    forall a. Bounded a => a
    maxBound Word64
    forall a. Bounded a => a
    maxBound
                            else Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    a3 (Word64 -> Word64
    forall a. Enum a => a -> a
    pred Word64
    a2) Word64
    forall a. Bounded a => a
    maxBound Word64
    forall a. Bounded a => a
    maxBound
                    else Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    a3 Word64
    a2 (Word64 -> Word64
    forall a. Enum a => a -> a
    pred Word64
    a1) Word64
    forall a. Bounded a => a
    maxBound
            | Bool
    otherwise      = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    a3 Word64
    a2 Word64
    a1        (Word64 -> Word64
    forall a. Enum a => a -> a
    pred Word64
    a0)
    instance Bounded Word256 where
        minBound :: Word256
    minBound = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    forall a. Bounded a => a
    minBound Word64
    forall a. Bounded a => a
    minBound Word64
    forall a. Bounded a => a
    minBound Word64
    forall a. Bounded a => a
    minBound
        maxBound :: Word256
    maxBound = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    forall a. Bounded a => a
    maxBound Word64
    forall a. Bounded a => a
    maxBound Word64
    forall a. Bounded a => a
    maxBound Word64
    forall a. Bounded a => a
    maxBound
    instance Ord Word256 where
        compare :: Word256 -> Word256 -> Ordering
    compare (Word256 Word64
    a3 Word64
    a2 Word64
    a1 Word64
    a0) (Word256 Word64
    b3 Word64
    b2 Word64
    b1 Word64
    b0) =
            Word64 -> Word64 -> Ordering -> Ordering
    forall {a}. Ord a => a -> a -> Ordering -> Ordering
    compareEq Word64
    a3 Word64
    b3 (Ordering -> Ordering) -> Ordering -> Ordering
    forall a b. (a -> b) -> a -> b
    $ Word64 -> Word64 -> Ordering -> Ordering
    forall {a}. Ord a => a -> a -> Ordering -> Ordering
    compareEq Word64
    a2 Word64
    b2 (Ordering -> Ordering) -> Ordering -> Ordering
    forall a b. (a -> b) -> a -> b
    $ Word64 -> Word64 -> Ordering -> Ordering
    forall {a}. Ord a => a -> a -> Ordering -> Ordering
    compareEq Word64
    a1 Word64
    b1 (Ordering -> Ordering) -> Ordering -> Ordering
    forall a b. (a -> b) -> a -> b
    $ Word64 -> Word64 -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Word64
    a0 Word64
    b0
          where compareEq :: a -> a -> Ordering -> Ordering
    compareEq a
    x a
    y Ordering
    next =
                    case a -> a -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare a
    x a
    y of
                        Ordering
    EQ -> Ordering
    next
                        Ordering
    r  -> Ordering
    r
        < :: Word256 -> Word256 -> Bool
    (<) (Word256 Word64
    a3 Word64
    a2 Word64
    a1 Word64
    a0) (Word256 Word64
    b3 Word64
    b2 Word64
    b1 Word64
    b0) =
            Word64 -> Word64 -> Bool -> Bool
    forall {a}. Ord a => a -> a -> Bool -> Bool
    compareLt Word64
    a3 Word64
    b3 (Bool -> Bool) -> Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ Word64 -> Word64 -> Bool -> Bool
    forall {a}. Ord a => a -> a -> Bool -> Bool
    compareLt Word64
    a2 Word64
    b2 (Bool -> Bool) -> Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ Word64 -> Word64 -> Bool -> Bool
    forall {a}. Ord a => a -> a -> Bool -> Bool
    compareLt Word64
    a1 Word64
    b1 (Word64
    a0 Word64 -> Word64 -> Bool
    forall a. Ord a => a -> a -> Bool
    < Word64
    b0)
          where compareLt :: a -> a -> Bool -> Bool
    compareLt a
    x a
    y Bool
    next =
                    case a -> a -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare a
    x a
    y of
                        Ordering
    EQ -> Bool
    next
                        Ordering
    r  -> Ordering
    r Ordering -> Ordering -> Bool
    forall a. Eq a => a -> a -> Bool
    == Ordering
    LT
    instance Storable Word256 where
        sizeOf :: Word256 -> Int
    sizeOf Word256
    _ = Int
    32
        alignment :: Word256 -> Int
    alignment Word256
    _ = Int
    32
        peek :: Ptr Word256 -> IO Word256
    peek Ptr Word256
    p = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 (Word64 -> Word64 -> Word64 -> Word64 -> Word256)
    -> IO Word64 -> IO (Word64 -> Word64 -> Word64 -> Word256)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Ptr Word64 -> IO Word64
    forall a. Storable a => Ptr a -> IO a
    peek (Ptr Word256 -> Ptr Word64
    forall a b. Ptr a -> Ptr b
    castPtr Ptr Word256
    p            )
                         IO (Word64 -> Word64 -> Word64 -> Word256)
    -> IO Word64 -> IO (Word64 -> Word64 -> Word256)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Ptr Word64 -> IO Word64
    forall a. Storable a => Ptr a -> IO a
    peek (Ptr Word256 -> Ptr (ZonkAny 0)
    forall a b. Ptr a -> Ptr b
    castPtr Ptr Word256
    p Ptr (ZonkAny 0) -> Int -> Ptr Word64
    forall a b. Ptr a -> Int -> Ptr b
    `plusPtr` Int
    8)
                         IO (Word64 -> Word64 -> Word256)
    -> IO Word64 -> IO (Word64 -> Word256)
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Ptr Word64 -> IO Word64
    forall a. Storable a => Ptr a -> IO a
    peek (Ptr Word256 -> Ptr (ZonkAny 1)
    forall a b. Ptr a -> Ptr b
    castPtr Ptr Word256
    p Ptr (ZonkAny 1) -> Int -> Ptr Word64
    forall a b. Ptr a -> Int -> Ptr b
    `plusPtr` Int
    16)
                         IO (Word64 -> Word256) -> IO Word64 -> IO Word256
    forall a b. IO (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Ptr Word64 -> IO Word64
    forall a. Storable a => Ptr a -> IO a
    peek (Ptr Word256 -> Ptr (ZonkAny 2)
    forall a b. Ptr a -> Ptr b
    castPtr Ptr Word256
    p Ptr (ZonkAny 2) -> Int -> Ptr Word64
    forall a b. Ptr a -> Int -> Ptr b
    `plusPtr` Int
    24)
        poke :: Ptr Word256 -> Word256 -> IO ()
    poke Ptr Word256
    p (Word256 Word64
    a3 Word64
    a2 Word64
    a1 Word64
    a0) = do
            Ptr Word64 -> Word64 -> IO ()
    forall a. Storable a => Ptr a -> a -> IO ()
    poke (Ptr Word256 -> Ptr Word64
    forall a b. Ptr a -> Ptr b
    castPtr Ptr Word256
    p             ) Word64
    a3
            Ptr Word64 -> Word64 -> IO ()
    forall a. Storable a => Ptr a -> a -> IO ()
    poke (Ptr Word256 -> Ptr (ZonkAny 3)
    forall a b. Ptr a -> Ptr b
    castPtr Ptr Word256
    p Ptr (ZonkAny 3) -> Int -> Ptr Word64
    forall a b. Ptr a -> Int -> Ptr b
    `plusPtr` Int
    8 ) Word64
    a2
            Ptr Word64 -> Word64 -> IO ()
    forall a. Storable a => Ptr a -> a -> IO ()
    poke (Ptr Word256 -> Ptr (ZonkAny 4)
    forall a b. Ptr a -> Ptr b
    castPtr Ptr Word256
    p Ptr (ZonkAny 4) -> Int -> Ptr Word64
    forall a b. Ptr a -> Int -> Ptr b
    `plusPtr` Int
    16) Word64
    a1
            Ptr Word64 -> Word64 -> IO ()
    forall a. Storable a => Ptr a -> a -> IO ()
    poke (Ptr Word256 -> Ptr (ZonkAny 5)
    forall a b. Ptr a -> Ptr b
    castPtr Ptr Word256
    p Ptr (ZonkAny 5) -> Int -> Ptr Word64
    forall a b. Ptr a -> Int -> Ptr b
    `plusPtr` Int
    24) Word64
    a0

    instance Integral Word256 where
        fromInteger :: Integer -> Word256
    fromInteger = Integer -> Word256
    literal
    instance HasNegation Word256 where
        negate :: Word256 -> Word256
    negate = Word256 -> Word256
    complement

    instance IsIntegral Word256 where
        toInteger :: Word256 -> Integer
    toInteger (Word256 Word64
    a3 Word64
    a2 Word64
    a1 Word64
    a0) =
            (Word64 -> Integer
    forall a. IsIntegral a => a -> Integer
    toInteger Word64
    a3 Integer -> Int -> Integer
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftL` Int
    192) Integer -> Integer -> Integer
    forall a. Bits a => a -> a -> a
    Bits..|.
            (Word64 -> Integer
    forall a. IsIntegral a => a -> Integer
    toInteger Word64
    a2 Integer -> Int -> Integer
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftL` Int
    128) Integer -> Integer -> Integer
    forall a. Bits a => a -> a -> a
    Bits..|.
            (Word64 -> Integer
    forall a. IsIntegral a => a -> Integer
    toInteger Word64
    a1 Integer -> Int -> Integer
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftL` Int
    64) Integer -> Integer -> Integer
    forall a. Bits a => a -> a -> a
    Bits..|.
            Word64 -> Integer
    forall a. IsIntegral a => a -> Integer
    toInteger Word64
    a0
    instance IsNatural Word256 where
        toNatural :: Word256 -> Natural
    toNatural (Word256 Word64
    a3 Word64
    a2 Word64
    a1 Word64
    a0) =
            (Word64 -> Natural
    forall a. IsNatural a => a -> Natural
    toNatural Word64
    a3 Natural -> Int -> Natural
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftL` Int
    192) Natural -> Natural -> Natural
    forall a. Bits a => a -> a -> a
    Bits..|.
            (Word64 -> Natural
    forall a. IsNatural a => a -> Natural
    toNatural Word64
    a2 Natural -> Int -> Natural
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftL` Int
    128) Natural -> Natural -> Natural
    forall a. Bits a => a -> a -> a
    Bits..|.
            (Word64 -> Natural
    forall a. IsNatural a => a -> Natural
    toNatural Word64
    a1 Natural -> Int -> Natural
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftL` Int
    64) Natural -> Natural -> Natural
    forall a. Bits a => a -> a -> a
    Bits..|.
            Word64 -> Natural
    forall a. IsNatural a => a -> Natural
    toNatural Word64
    a0

    instance Prelude.Num Word256 where
        abs :: Word256 -> Word256
    abs Word256
    w = Word256
    w
        signum :: Word256 -> Word256
    signum w :: Word256
    w@(Word256 Word64
    a3 Word64
    a2 Word64
    a1 Word64
    a0)
            | Word64
    a3 Word64 -> Word64 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word64
    0 Bool -> Bool -> Bool
    && Word64
    a2 Word64 -> Word64 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word64
    0 Bool -> Bool -> Bool
    && Word64
    a1 Word64 -> Word64 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word64
    0 Bool -> Bool -> Bool
    && Word64
    a0 Word64 -> Word64 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word64
    0 = Word256
    w
            | Bool
    otherwise                                = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    0 Word64
    0 Word64
    0 Word64
    1
        fromInteger :: Integer -> Word256
    fromInteger = Integer -> Word256
    literal
        + :: Word256 -> Word256 -> Word256
    (+) = Word256 -> Word256 -> Word256
    (+)
        (-) = (-)
        * :: Word256 -> Word256 -> Word256
    (*) = Word256 -> Word256 -> Word256
    (*)

    instance Bits.Bits Word256 where
        .&. :: Word256 -> Word256 -> Word256
    (.&.) = Word256 -> Word256 -> Word256
    bitwiseAnd
        .|. :: Word256 -> Word256 -> Word256
    (.|.) = Word256 -> Word256 -> Word256
    bitwiseOr
        xor :: Word256 -> Word256 -> Word256
    xor   = Word256 -> Word256 -> Word256
    bitwiseXor
        complement :: Word256 -> Word256
    complement = Word256 -> Word256
    complement
        shiftL :: Word256 -> Int -> Word256
    shiftL = Word256 -> Int -> Word256
    shiftL
        shiftR :: Word256 -> Int -> Word256
    shiftR = Word256 -> Int -> Word256
    shiftR
        rotateL :: Word256 -> Int -> Word256
    rotateL = Word256 -> Int -> Word256
    rotateL
        rotateR :: Word256 -> Int -> Word256
    rotateR = Word256 -> Int -> Word256
    rotateR
        bitSize :: Word256 -> Int
    bitSize Word256
    _ = Int
    256
        bitSizeMaybe :: Word256 -> Maybe Int
    bitSizeMaybe Word256
    _ = Int -> Maybe Int
    forall a. a -> Maybe a
    Just Int
    256
        isSigned :: Word256 -> Bool
    isSigned Word256
    _ = Bool
    False
        testBit :: Word256 -> Int -> Bool
    testBit = Word256 -> Int -> Bool
    testBit
        bit :: Int -> Word256
    bit = Int -> Word256
    bit
        popCount :: Word256 -> Int
    popCount = Word256 -> Int
    popCount

    -- | Add 2 Word256
    (+) :: Word256 -> Word256 -> Word256
    #if WORD_SIZE_IN_BITS < 64
    (+) = applyBiWordOnNatural (Prelude.+)
    #else
    + :: Word256 -> Word256 -> Word256
    (+) (Word256 (W64# Word64#
    a3) (W64# Word64#
    a2) (W64# Word64#
    a1) (W64# Word64#
    a0))
        (Word256 (W64# Word64#
    b3) (W64# Word64#
    b2) (W64# Word64#
    b1) (W64# Word64#
    b0)) =
    #if __GLASGOW_HASKELL__ >= 904
        Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 (Word64# -> Word64
    W64# (Word# -> Word64#
    wordToWord64# Word#
    s3)) (Word64# -> Word64
    W64# (Word# -> Word64#
    wordToWord64# Word#
    s2)) (Word64# -> Word64
    W64# (Word# -> Word64#
    wordToWord64# Word#
    s1)) (Word64# -> Word64
    W64# (Word# -> Word64#
    wordToWord64# Word#
    s0))
      where
        !(# Word#
    c0, Word#
    s0 #) = Word# -> Word# -> (# Word#, Word# #)
    plusWord2# (Word64# -> Word#
    GHC.Prim.word64ToWord# Word64#
    a0) (Word64# -> Word#
    GHC.Prim.word64ToWord#  Word64#
    b0)
        !(# Word#
    c1, Word#
    s1 #) = Word# -> Word# -> Word# -> (# Word#, Word# #)
    plusWord3# (Word64# -> Word#
    GHC.Prim.word64ToWord# Word64#
    a1) (Word64# -> Word#
    GHC.Prim.word64ToWord# Word64#
    b1) (Word#
    c0)
        !(# Word#
    c2, Word#
    s2 #) = Word# -> Word# -> Word# -> (# Word#, Word# #)
    plusWord3# (Word64# -> Word#
    GHC.Prim.word64ToWord# Word64#
    a2) (Word64# -> Word#
    GHC.Prim.word64ToWord# Word64#
    b2) Word#
    c1
        !s3 :: Word#
    s3           = Word# -> Word# -> Word# -> Word#
    plusWord3NoCarry# (Word64# -> Word#
    GHC.Prim.word64ToWord# Word64#
    a3) (Word64# -> Word#
    GHC.Prim.word64ToWord# Word64#
    b3) Word#
    c2

        plusWord3NoCarry# :: Word# -> Word# -> Word# -> Word#
    plusWord3NoCarry# Word#
    a Word#
    b Word#
    c = Word# -> Word# -> Word#
    plusWord# (Word# -> Word# -> Word#
    plusWord# Word#
    a Word#
    b) Word#
    c
        plusWord3# :: Word# -> Word# -> Word# -> (# Word#, Word# #)
    plusWord3# Word#
    a Word#
    b Word#
    c
            | Int# -> Bool
    bool# (Word# -> Word# -> Int#
    eqWord# Word#
    carry Word#
    0##) = Word# -> Word# -> (# Word#, Word# #)
    plusWord2# Word#
    x Word#
    c
            | Bool
    otherwise                 =
                case Word# -> Word# -> (# Word#, Word# #)
    plusWord2# Word#
    x Word#
    c of
                    (# Word#
    carry2, Word#
    x' #)
                        | Int# -> Bool
    bool# (Word# -> Word# -> Int#
    eqWord# Word#
    carry2 Word#
    0##) -> (# Word#
    carry, Word#
    x' #)
                        | Bool
    otherwise                  -> (# Word# -> Word# -> Word#
    plusWord# Word#
    carry Word#
    carry2, Word#
    x' #)
          where
            (# Word#
    carry, Word#
    x #) = Word# -> Word# -> (# Word#, Word# #)
    plusWord2# Word#
    a Word#
    b
    #else
        Word256 (W64# s3) (W64# s2) (W64# s1) (W64# s0)
      where
        !(# c0, s0 #) = plusWord2# a0 b0
        !(# c1, s1 #) = plusWord3# a1 b1 c0
        !(# c2, s2 #) = plusWord3# a2 b2 c1
        !s3           = plusWord3NoCarry# a3 b3 c2

        plusWord3NoCarry# a b c = plusWord# (plusWord# a b) c
        plusWord3# a b c
            | bool# (eqWord# carry 0##) = plusWord2# x c
            | otherwise                 =
                case plusWord2# x c of
                    (# carry2, x' #)
                        | bool# (eqWord# carry2 0##) -> (# carry, x' #)
                        | otherwise                  -> (# plusWord# carry carry2, x' #)
          where
            (# carry, x #) = plusWord2# a b
    #endif
    #endif

    -- temporary available until native operation available
    applyBiWordOnNatural :: (Natural -> Natural -> Natural)
                         -> Word256
                         -> Word256
                         -> Word256
    applyBiWordOnNatural :: (Natural -> Natural -> Natural) -> Word256 -> Word256 -> Word256
    applyBiWordOnNatural Natural -> Natural -> Natural
    f = (Natural -> Word256
    fromNatural (Natural -> Word256) -> (Word256 -> Natural) -> Word256 -> Word256
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    .) ((Word256 -> Natural) -> Word256 -> Word256)
    -> (Word256 -> Word256 -> Natural) -> Word256 -> Word256 -> Word256
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (Natural -> Natural -> Natural
    f (Natural -> Natural -> Natural)
    -> (Word256 -> Natural) -> Word256 -> Word256 -> Natural
    forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
    `on` Word256 -> Natural
    forall a. IsNatural a => a -> Natural
    toNatural)

    -- | Subtract 2 Word256
    (-) :: Word256 -> Word256 -> Word256
    (-) Word256
    a Word256
    b
        | Word256
    a Word256 -> Word256 -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Word256
    b    = (Natural -> Natural -> Natural) -> Word256 -> Word256 -> Word256
    applyBiWordOnNatural Natural -> Natural -> Natural
    forall a. Num a => a -> a -> a
    (Prelude.-) Word256
    a Word256
    b
        | Bool
    otherwise = Word256 -> Word256
    complement ((Natural -> Natural -> Natural) -> Word256 -> Word256 -> Word256
    applyBiWordOnNatural Natural -> Natural -> Natural
    forall a. Num a => a -> a -> a
    (Prelude.-) Word256
    b Word256
    a) Word256 -> Word256 -> Word256
    + Word256
    1

    -- | Multiplication
    (*) :: Word256 -> Word256 -> Word256
    * :: Word256 -> Word256 -> Word256
    (*) = (Natural -> Natural -> Natural) -> Word256 -> Word256 -> Word256
    applyBiWordOnNatural Natural -> Natural -> Natural
    forall a. Num a => a -> a -> a
    (Prelude.*)

    -- | Division
    quot :: Word256 -> Word256 -> Word256
    quot :: Word256 -> Word256 -> Word256
    quot = (Natural -> Natural -> Natural) -> Word256 -> Word256 -> Word256
    applyBiWordOnNatural Natural -> Natural -> Natural
    forall a. Integral a => a -> a -> a
    Prelude.quot

    -- | Modulo
    rem :: Word256 -> Word256 -> Word256
    rem :: Word256 -> Word256 -> Word256
    rem = (Natural -> Natural -> Natural) -> Word256 -> Word256 -> Word256
    applyBiWordOnNatural Natural -> Natural -> Natural
    forall a. Integral a => a -> a -> a
    Prelude.rem

    -- | Bitwise and
    bitwiseAnd :: Word256 -> Word256 -> Word256
    bitwiseAnd :: Word256 -> Word256 -> Word256
    bitwiseAnd (Word256 Word64
    a3 Word64
    a2 Word64
    a1 Word64
    a0) (Word256 Word64
    b3 Word64
    b2 Word64
    b1 Word64
    b0) =
        Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 (Word64
    a3 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    Bits..&. Word64
    b3) (Word64
    a2 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    Bits..&. Word64
    b2)  (Word64
    a1 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    Bits..&. Word64
    b1) (Word64
    a0 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    Bits..&. Word64
    b0)

    -- | Bitwise or
    bitwiseOr :: Word256 -> Word256 -> Word256
    bitwiseOr :: Word256 -> Word256 -> Word256
    bitwiseOr (Word256 Word64
    a3 Word64
    a2 Word64
    a1 Word64
    a0) (Word256 Word64
    b3 Word64
    b2 Word64
    b1 Word64
    b0) =
        Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 (Word64
    a3 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    Bits..|. Word64
    b3) (Word64
    a2 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    Bits..|. Word64
    b2)  (Word64
    a1 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    Bits..|. Word64
    b1) (Word64
    a0 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    Bits..|. Word64
    b0)

    -- | Bitwise xor
    bitwiseXor :: Word256 -> Word256 -> Word256
    bitwiseXor :: Word256 -> Word256 -> Word256
    bitwiseXor (Word256 Word64
    a3 Word64
    a2 Word64
    a1 Word64
    a0) (Word256 Word64
    b3 Word64
    b2 Word64
    b1 Word64
    b0) =
        Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 (Word64
    a3 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    `Bits.xor` Word64
    b3) (Word64
    a2 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    `Bits.xor` Word64
    b2)  (Word64
    a1 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    `Bits.xor` Word64
    b1) (Word64
    a0 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    `Bits.xor` Word64
    b0)

    -- | Bitwise complement
    complement :: Word256 -> Word256
    complement :: Word256 -> Word256
    complement (Word256 Word64
    a3 Word64
    a2 Word64
    a1 Word64
    a0) =
        Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 (Word64 -> Word64
    forall a. Bits a => a -> a
    Bits.complement Word64
    a3) (Word64 -> Word64
    forall a. Bits a => a -> a
    Bits.complement Word64
    a2) (Word64 -> Word64
    forall a. Bits a => a -> a
    Bits.complement Word64
    a1) (Word64 -> Word64
    forall a. Bits a => a -> a
    Bits.complement Word64
    a0)

    -- | Population count
    popCount :: Word256 -> Int
    popCount :: Word256 -> Int
    popCount (Word256 Word64
    a3 Word64
    a2 Word64
    a1 Word64
    a0) =
        Word64 -> Int
    forall a. Bits a => a -> Int
    Bits.popCount Word64
    a3 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.+
        Word64 -> Int
    forall a. Bits a => a -> Int
    Bits.popCount Word64
    a2 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.+
        Word64 -> Int
    forall a. Bits a => a -> Int
    Bits.popCount Word64
    a1 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.+
        Word64 -> Int
    forall a. Bits a => a -> Int
    Bits.popCount Word64
    a0

    -- | Bitwise Shift Left
    shiftL :: Word256 -> Int -> Word256
    shiftL :: Word256 -> Int -> Word256
    shiftL w :: Word256
    w@(Word256 Word64
    a3 Word64
    a2 Word64
    a1 Word64
    a0) Int
    n
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    0 Bool -> Bool -> Bool
    || Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    255 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    0 Word64
    0 Word64
    0 Word64
    0
        | Int
    n Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    0           = Word256
    w
        | Int
    n Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    64          = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    a2 Word64
    a1 Word64
    a0 Word64
    0
        | Int
    n Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    128         = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    a1 Word64
    a0 Word64
    0 Word64
    0
        | Int
    n Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    192         = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    a0 Word64
    0 Word64
    0 Word64
    0
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    64           = Word64 -> Word64 -> Word64 -> Word64 -> Int -> Word256
    mkWordShift Word64
    a3 Word64
    a2 Word64
    a1 Word64
    a0 Int
    n
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    128          = Word64 -> Word64 -> Word64 -> Word64 -> Int -> Word256
    mkWordShift Word64
    a2 Word64
    a1 Word64
    a0 Word64
    0  (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- Int
    64)
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    192          = Word64 -> Word64 -> Word64 -> Word64 -> Int -> Word256
    mkWordShift Word64
    a1 Word64
    a0 Word64
    0  Word64
    0  (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- Int
    128)
        | Bool
    otherwise        = Word64 -> Word64 -> Word64 -> Word64 -> Int -> Word256
    mkWordShift Word64
    a0 Word64
    0  Word64
    0  Word64
    0  (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- Int
    192)
      where
        mkWordShift :: Word64 -> Word64 -> Word64 -> Word64 -> Int -> Word256
        mkWordShift :: Word64 -> Word64 -> Word64 -> Word64 -> Int -> Word256
    mkWordShift Word64
    w Word64
    x Word64
    y Word64
    z Int
    s =
            Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    w Int
    s Word64
    x Int
    s') (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    x Int
    s Word64
    y Int
    s') (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    y Int
    s Word64
    z Int
    s') (Word64
    z Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftL` Int
    s)
          where s' :: Int
    s' = Int -> Int
    inv64 Int
    s

    -- | Bitwise Shift Right
    shiftR :: Word256 -> Int -> Word256
    shiftR :: Word256 -> Int -> Word256
    shiftR w :: Word256
    w@(Word256 Word64
    a3 Word64
    a2 Word64
    a1 Word64
    a0) Int
    n
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    0 Bool -> Bool -> Bool
    || Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    255 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    0 Word64
    0 Word64
    0 Word64
    0
        | Int
    n Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    0           = Word256
    w
        | Int
    n Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    64          = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    0 Word64
    a3 Word64
    a2 Word64
    a1
        | Int
    n Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    128         = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    0 Word64
    0 Word64
    a3 Word64
    a2
        | Int
    n Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    192         = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    0 Word64
    0 Word64
    0 Word64
    a3
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <  Int
    64          = Word64 -> Word64 -> Word64 -> Word64 -> Int -> Word256
    mkWordShift Word64
    a3 Word64
    a2 Word64
    a1 Word64
    a0 Int
    n
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    128          = Word64 -> Word64 -> Word64 -> Word64 -> Int -> Word256
    mkWordShift  Word64
    0 Word64
    a3 Word64
    a2 Word64
    a1 (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- Int
    64)
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    192          = Word64 -> Word64 -> Word64 -> Word64 -> Int -> Word256
    mkWordShift  Word64
    0  Word64
    0 Word64
    a3 Word64
    a2 (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- Int
    128)
        | Bool
    otherwise        = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    0 Word64
    0 Word64
    0 (Word64
    a3 Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftR` (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- Int
    192))
      where
        mkWordShift :: Word64 -> Word64 -> Word64 -> Word64 -> Int -> Word256
        mkWordShift :: Word64 -> Word64 -> Word64 -> Word64 -> Int -> Word256
    mkWordShift Word64
    w Word64
    x Word64
    y Word64
    z Int
    s =
            Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 (Word64
    w Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftR` Int
    s) (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    w Int
    s' Word64
    x Int
    s) (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    x Int
    s' Word64
    y Int
    s) (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    y Int
    s' Word64
    z Int
    s)
          where s' :: Int
    s' = Int -> Int
    inv64 Int
    s

    -- | Bitwise rotate Left
    rotateL :: Word256 -> Int -> Word256
    rotateL :: Word256 -> Int -> Word256
    rotateL (Word256 Word64
    a3 Word64
    a2 Word64
    a1 Word64
    a0) Int
    n'
        | Int
    n Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    0    = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    a3 Word64
    a2 Word64
    a1 Word64
    a0
        | Int
    n Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    192  = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    a0 Word64
    a3 Word64
    a2 Word64
    a1
        | Int
    n Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    128  = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    a1 Word64
    a0 Word64
    a3 Word64
    a2
        | Int
    n Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    64   = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    a2 Word64
    a1 Word64
    a0 Word64
    a3
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    64    = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    a3 Int
    n Word64
    a2 (Int -> Int
    inv64 Int
    n)) (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    a2 Int
    n Word64
    a1 (Int -> Int
    inv64 Int
    n))
                              (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    a1 Int
    n Word64
    a0 (Int -> Int
    inv64 Int
    n)) (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    a0 Int
    n Word64
    a3 (Int -> Int
    inv64 Int
    n))
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    128   = let n :: Int
    n = Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- Int
    64 in Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256
                              (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    a2 Int
    n Word64
    a1 (Int -> Int
    inv64 Int
    n)) (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    a1 Int
    n Word64
    a0 (Int -> Int
    inv64 Int
    n))
                              (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    a0 Int
    n Word64
    a3 (Int -> Int
    inv64 Int
    n)) (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    a3 Int
    n Word64
    a2 (Int -> Int
    inv64 Int
    n))
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    192   = let n :: Int
    n = Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- Int
    128 in Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256
                              (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    a1 Int
    n Word64
    a0 (Int -> Int
    inv64 Int
    n)) (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    a0 Int
    n Word64
    a3 (Int -> Int
    inv64 Int
    n))
                              (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    a3 Int
    n Word64
    a2 (Int -> Int
    inv64 Int
    n)) (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    a2 Int
    n Word64
    a1 (Int -> Int
    inv64 Int
    n))
        | Bool
    otherwise = let n :: Int
    n = Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- Int
    192 in Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256
                              (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    a0 Int
    n Word64
    a3 (Int -> Int
    inv64 Int
    n)) (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    a3 Int
    n Word64
    a2 (Int -> Int
    inv64 Int
    n))
                              (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    a2 Int
    n Word64
    a1 (Int -> Int
    inv64 Int
    n)) (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    a1 Int
    n Word64
    a0 (Int -> Int
    inv64 Int
    n))
      where
        n :: Int
        n :: Int
    n | Int
    n' Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    0   = Int
    n' Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `Prelude.mod` Int
    256
          | Bool
    otherwise = Int
    256 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- (Int
    n' Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `Prelude.mod` Int
    256)

    -- | Bitwise rotate Left
    rotateR :: Word256 -> Int -> Word256
    rotateR :: Word256 -> Int -> Word256
    rotateR Word256
    w Int
    n = Word256 -> Int -> Word256
    rotateL Word256
    w (Int
    256 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- Int
    n)

    inv64 :: Int -> Int
    inv64 :: Int -> Int
    inv64 Int
    i = Int
    64 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- Int
    i

    comb64 :: Word64 -> Int -> Word64 -> Int -> Word64
    comb64 :: Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    x Int
    i Word64
    y Int
    j =
        (Word64
    x Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftL` Int
    i) Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. (Word64
    y Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftR` Int
    j)

    -- | Test bit
    testBit :: Word256 -> Int -> Bool
    testBit :: Word256 -> Int -> Bool
    testBit (Word256 Word64
    a3 Word64
    a2 Word64
    a1 Word64
    a0) Int
    n
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    0 Bool -> Bool -> Bool
    || Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    255 = Bool
    False
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    191          = Word64 -> Int -> Bool
    forall a. Bits a => a -> Int -> Bool
    Bits.testBit Word64
    a3 (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- Int
    192)
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    127          = Word64 -> Int -> Bool
    forall a. Bits a => a -> Int -> Bool
    Bits.testBit Word64
    a2 (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- Int
    128)
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    63           = Word64 -> Int -> Bool
    forall a. Bits a => a -> Int -> Bool
    Bits.testBit Word64
    a1 (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- Int
    64)
        | Bool
    otherwise        = Word64 -> Int -> Bool
    forall a. Bits a => a -> Int -> Bool
    Bits.testBit Word64
    a0 Int
    n

    -- | bit
    bit :: Int -> Word256
    bit :: Int -> Word256
    bit Int
    n
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    0 Bool -> Bool -> Bool
    || Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    255 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    0 Word64
    0 Word64
    0 Word64
    0
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    191          = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 (Int -> Word64
    forall a. Bits a => Int -> a
    Bits.bit (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- Int
    192)) Word64
    0 Word64
    0 Word64
    0
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    127          = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    0 (Int -> Word64
    forall a. Bits a => Int -> a
    Bits.bit (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- Int
    128)) Word64
    0 Word64
    0
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    63           = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    0 Word64
    0 (Int -> Word64
    forall a. Bits a => Int -> a
    Bits.bit (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- Int
    64)) Word64
    0
        | Bool
    otherwise        = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256 Word64
    0 Word64
    0 Word64
    0 (Int -> Word64
    forall a. Bits a => Int -> a
    Bits.bit Int
    n)

    literal :: Integer -> Word256
    literal :: Integer -> Word256
    literal Integer
    i = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256
        (Integer -> Word64
    forall a. Num a => Integer -> a
    Prelude.fromInteger (Integer
    i Integer -> Int -> Integer
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftR` Int
    192))
        (Integer -> Word64
    forall a. Num a => Integer -> a
    Prelude.fromInteger (Integer
    i Integer -> Int -> Integer
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftR` Int
    128))
        (Integer -> Word64
    forall a. Num a => Integer -> a
    Prelude.fromInteger (Integer
    i Integer -> Int -> Integer
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftR` Int
    64))
        (Integer -> Word64
    forall a. Num a => Integer -> a
    Prelude.fromInteger Integer
    i)

    fromNatural :: Natural -> Word256
    fromNatural :: Natural -> Word256
    fromNatural Natural
    n = Word64 -> Word64 -> Word64 -> Word64 -> Word256
    Word256
        (Integer -> Word64
    forall a. Num a => Integer -> a
    Prelude.fromInteger (Natural -> Integer
    naturalToInteger Natural
    n Integer -> Int -> Integer
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftR` Int
    192))
        (Integer -> Word64
    forall a. Num a => Integer -> a
    Prelude.fromInteger (Natural -> Integer
    naturalToInteger Natural
    n Integer -> Int -> Integer
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftR` Int
    128))
        (Integer -> Word64
    forall a. Num a => Integer -> a
    Prelude.fromInteger (Natural -> Integer
    naturalToInteger Natural
    n Integer -> Int -> Integer
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftR` Int
    64))
        (Integer -> Word64
    forall a. Num a => Integer -> a
    Prelude.fromInteger (Integer -> Word64) -> Integer -> Word64
    forall a b. (a -> b) -> a -> b
    $ Natural -> Integer
    naturalToInteger Natural
    n)