{-# LANGUAGE DataKinds                        #-}
{-# LANGUAGE GeneralizedNewtypeDeriving       #-}
{-# LANGUAGE FlexibleInstances                #-}
{-# LANGUAGE MultiParamTypeClasses            #-}
{-# LANGUAGE TypeFamilies                     #-}

{- HLINT ignore "Unused LANGUAGE pragma" -}


-- |
--
-- Module      : Raaz.Primitive.ChaCha20.Internal
-- Description : Internal module for ChaCha20 cipher.
-- Copyright   : (c) Piyush P Kurur, 2019
-- License     : Apache-2.0 OR BSD-3-Clause
-- Maintainer  : Piyush P Kurur <ppk@iitpkd.ac.in>
-- Stability   : experimental
--

module Raaz.Primitive.ChaCha20.Internal
       ( -- * ChaCha20 cipher
         -- $chacha20$
         ChaCha20(..), XChaCha20(..)
       , Key(..), Nounce(..)
       , ChaCha20Mem(..)
       , keyCellPtr, ivCellPtr, counterCellPtr
       ) where

import Foreign.Storable
import Raaz.Core

-- $chacha20$
--
-- This module defines the ChaCha20 ciphers and the memory element
-- used by a typical implementation. The variant of Chacha20 that we
-- support is the IETF version described in RFC 7538 with 32-bit
-- (4-byte) counter and 96-bit (12-byte) IV.

-- | The type associated with the ChaCha20 cipher.
data ChaCha20 = ChaCha20

-- | The type associated with the XChaCha20 variant.
data XChaCha20 = XChaCha20

type WORD     = LE Word32
type KEY      = Tuple 8 WORD

instance Primitive ChaCha20 where
  type WordType      ChaCha20 = WORD
  type WordsPerBlock ChaCha20 = 16

instance Primitive XChaCha20 where
  type WordType      XChaCha20  = WORD
  type WordsPerBlock XChaCha20  = 16


newtype instance Key     ChaCha20 = Key KEY
  deriving (Ptr (Key ChaCha20) -> IO (Key ChaCha20)
Ptr (Key ChaCha20) -> Int -> IO (Key ChaCha20)
Ptr (Key ChaCha20) -> Int -> Key ChaCha20 -> IO ()
Ptr (Key ChaCha20) -> Key ChaCha20 -> IO ()
Key ChaCha20 -> Int
(Key ChaCha20 -> Int)
-> (Key ChaCha20 -> Int)
-> (Ptr (Key ChaCha20) -> Int -> IO (Key ChaCha20))
-> (Ptr (Key ChaCha20) -> Int -> Key ChaCha20 -> IO ())
-> (forall b. Ptr b -> Int -> IO (Key ChaCha20))
-> (forall b. Ptr b -> Int -> Key ChaCha20 -> IO ())
-> (Ptr (Key ChaCha20) -> IO (Key ChaCha20))
-> (Ptr (Key ChaCha20) -> Key ChaCha20 -> IO ())
-> Storable (Key ChaCha20)
forall b. Ptr b -> Int -> IO (Key ChaCha20)
forall b. Ptr b -> Int -> Key ChaCha20 -> IO ()
forall a.
(a -> Int)
-> (a -> Int)
-> (Ptr a -> Int -> IO a)
-> (Ptr a -> Int -> a -> IO ())
-> (forall b. Ptr b -> Int -> IO a)
-> (forall b. Ptr b -> Int -> a -> IO ())
-> (Ptr a -> IO a)
-> (Ptr a -> a -> IO ())
-> Storable a
$csizeOf :: Key ChaCha20 -> Int
sizeOf :: Key ChaCha20 -> Int
$calignment :: Key ChaCha20 -> Int
alignment :: Key ChaCha20 -> Int
$cpeekElemOff :: Ptr (Key ChaCha20) -> Int -> IO (Key ChaCha20)
peekElemOff :: Ptr (Key ChaCha20) -> Int -> IO (Key ChaCha20)
$cpokeElemOff :: Ptr (Key ChaCha20) -> Int -> Key ChaCha20 -> IO ()
pokeElemOff :: Ptr (Key ChaCha20) -> Int -> Key ChaCha20 -> IO ()
$cpeekByteOff :: forall b. Ptr b -> Int -> IO (Key ChaCha20)
peekByteOff :: forall b. Ptr b -> Int -> IO (Key ChaCha20)
$cpokeByteOff :: forall b. Ptr b -> Int -> Key ChaCha20 -> IO ()
pokeByteOff :: forall b. Ptr b -> Int -> Key ChaCha20 -> IO ()
$cpeek :: Ptr (Key ChaCha20) -> IO (Key ChaCha20)
peek :: Ptr (Key ChaCha20) -> IO (Key ChaCha20)
$cpoke :: Ptr (Key ChaCha20) -> Key ChaCha20 -> IO ()
poke :: Ptr (Key ChaCha20) -> Key ChaCha20 -> IO ()
Storable, Storable (Key ChaCha20)
Ptr (Key ChaCha20) -> IO (Key ChaCha20)
Ptr (Key ChaCha20) -> Int -> IO ()
Ptr (Key ChaCha20) -> Key ChaCha20 -> IO ()
Storable (Key ChaCha20) =>
(Ptr (Key ChaCha20) -> Key ChaCha20 -> IO ())
-> (Ptr (Key ChaCha20) -> IO (Key ChaCha20))
-> (Ptr (Key ChaCha20) -> Int -> IO ())
-> EndianStore (Key ChaCha20)
forall w.
Storable w =>
(Ptr w -> w -> IO ())
-> (Ptr w -> IO w) -> (Ptr w -> Int -> IO ()) -> EndianStore w
$cstore :: Ptr (Key ChaCha20) -> Key ChaCha20 -> IO ()
store :: Ptr (Key ChaCha20) -> Key ChaCha20 -> IO ()
$cload :: Ptr (Key ChaCha20) -> IO (Key ChaCha20)
load :: Ptr (Key ChaCha20) -> IO (Key ChaCha20)
$cadjustEndian :: Ptr (Key ChaCha20) -> Int -> IO ()
adjustEndian :: Ptr (Key ChaCha20) -> Int -> IO ()
EndianStore, Key ChaCha20 -> Key ChaCha20 -> Result
(Key ChaCha20 -> Key ChaCha20 -> Result) -> Equality (Key ChaCha20)
forall a. (a -> a -> Result) -> Equality a
$ceq :: Key ChaCha20 -> Key ChaCha20 -> Result
eq :: Key ChaCha20 -> Key ChaCha20 -> Result
Equality, Key ChaCha20 -> Key ChaCha20 -> Bool
(Key ChaCha20 -> Key ChaCha20 -> Bool)
-> (Key ChaCha20 -> Key ChaCha20 -> Bool) -> Eq (Key ChaCha20)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Key ChaCha20 -> Key ChaCha20 -> Bool
== :: Key ChaCha20 -> Key ChaCha20 -> Bool
$c/= :: Key ChaCha20 -> Key ChaCha20 -> Bool
/= :: Key ChaCha20 -> Key ChaCha20 -> Bool
Eq)

newtype instance Nounce  ChaCha20 = Nounce  (Tuple 3 WORD)
  deriving (Ptr (Nounce ChaCha20) -> IO (Nounce ChaCha20)
Ptr (Nounce ChaCha20) -> Int -> IO (Nounce ChaCha20)
Ptr (Nounce ChaCha20) -> Int -> Nounce ChaCha20 -> IO ()
Ptr (Nounce ChaCha20) -> Nounce ChaCha20 -> IO ()
Nounce ChaCha20 -> Int
(Nounce ChaCha20 -> Int)
-> (Nounce ChaCha20 -> Int)
-> (Ptr (Nounce ChaCha20) -> Int -> IO (Nounce ChaCha20))
-> (Ptr (Nounce ChaCha20) -> Int -> Nounce ChaCha20 -> IO ())
-> (forall b. Ptr b -> Int -> IO (Nounce ChaCha20))
-> (forall b. Ptr b -> Int -> Nounce ChaCha20 -> IO ())
-> (Ptr (Nounce ChaCha20) -> IO (Nounce ChaCha20))
-> (Ptr (Nounce ChaCha20) -> Nounce ChaCha20 -> IO ())
-> Storable (Nounce ChaCha20)
forall b. Ptr b -> Int -> IO (Nounce ChaCha20)
forall b. Ptr b -> Int -> Nounce ChaCha20 -> IO ()
forall a.
(a -> Int)
-> (a -> Int)
-> (Ptr a -> Int -> IO a)
-> (Ptr a -> Int -> a -> IO ())
-> (forall b. Ptr b -> Int -> IO a)
-> (forall b. Ptr b -> Int -> a -> IO ())
-> (Ptr a -> IO a)
-> (Ptr a -> a -> IO ())
-> Storable a
$csizeOf :: Nounce ChaCha20 -> Int
sizeOf :: Nounce ChaCha20 -> Int
$calignment :: Nounce ChaCha20 -> Int
alignment :: Nounce ChaCha20 -> Int
$cpeekElemOff :: Ptr (Nounce ChaCha20) -> Int -> IO (Nounce ChaCha20)
peekElemOff :: Ptr (Nounce ChaCha20) -> Int -> IO (Nounce ChaCha20)
$cpokeElemOff :: Ptr (Nounce ChaCha20) -> Int -> Nounce ChaCha20 -> IO ()
pokeElemOff :: Ptr (Nounce ChaCha20) -> Int -> Nounce ChaCha20 -> IO ()
$cpeekByteOff :: forall b. Ptr b -> Int -> IO (Nounce ChaCha20)
peekByteOff :: forall b. Ptr b -> Int -> IO (Nounce ChaCha20)
$cpokeByteOff :: forall b. Ptr b -> Int -> Nounce ChaCha20 -> IO ()
pokeByteOff :: forall b. Ptr b -> Int -> Nounce ChaCha20 -> IO ()
$cpeek :: Ptr (Nounce ChaCha20) -> IO (Nounce ChaCha20)
peek :: Ptr (Nounce ChaCha20) -> IO (Nounce ChaCha20)
$cpoke :: Ptr (Nounce ChaCha20) -> Nounce ChaCha20 -> IO ()
poke :: Ptr (Nounce ChaCha20) -> Nounce ChaCha20 -> IO ()
Storable, Storable (Nounce ChaCha20)
Ptr (Nounce ChaCha20) -> IO (Nounce ChaCha20)
Ptr (Nounce ChaCha20) -> Int -> IO ()
Ptr (Nounce ChaCha20) -> Nounce ChaCha20 -> IO ()
Storable (Nounce ChaCha20) =>
(Ptr (Nounce ChaCha20) -> Nounce ChaCha20 -> IO ())
-> (Ptr (Nounce ChaCha20) -> IO (Nounce ChaCha20))
-> (Ptr (Nounce ChaCha20) -> Int -> IO ())
-> EndianStore (Nounce ChaCha20)
forall w.
Storable w =>
(Ptr w -> w -> IO ())
-> (Ptr w -> IO w) -> (Ptr w -> Int -> IO ()) -> EndianStore w
$cstore :: Ptr (Nounce ChaCha20) -> Nounce ChaCha20 -> IO ()
store :: Ptr (Nounce ChaCha20) -> Nounce ChaCha20 -> IO ()
$cload :: Ptr (Nounce ChaCha20) -> IO (Nounce ChaCha20)
load :: Ptr (Nounce ChaCha20) -> IO (Nounce ChaCha20)
$cadjustEndian :: Ptr (Nounce ChaCha20) -> Int -> IO ()
adjustEndian :: Ptr (Nounce ChaCha20) -> Int -> IO ()
EndianStore, Nounce ChaCha20 -> Nounce ChaCha20 -> Result
(Nounce ChaCha20 -> Nounce ChaCha20 -> Result)
-> Equality (Nounce ChaCha20)
forall a. (a -> a -> Result) -> Equality a
$ceq :: Nounce ChaCha20 -> Nounce ChaCha20 -> Result
eq :: Nounce ChaCha20 -> Nounce ChaCha20 -> Result
Equality, Nounce ChaCha20 -> Nounce ChaCha20 -> Bool
(Nounce ChaCha20 -> Nounce ChaCha20 -> Bool)
-> (Nounce ChaCha20 -> Nounce ChaCha20 -> Bool)
-> Eq (Nounce ChaCha20)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Nounce ChaCha20 -> Nounce ChaCha20 -> Bool
== :: Nounce ChaCha20 -> Nounce ChaCha20 -> Bool
$c/= :: Nounce ChaCha20 -> Nounce ChaCha20 -> Bool
/= :: Nounce ChaCha20 -> Nounce ChaCha20 -> Bool
Eq)

instance Encodable (Key     ChaCha20)
instance Encodable (Nounce  ChaCha20)

instance Show (Key ChaCha20) where
  show :: Key ChaCha20 -> String
show = Key ChaCha20 -> String
forall a. Encodable a => a -> String
showBase16

instance Show (Nounce ChaCha20) where
  show :: Nounce ChaCha20 -> String
show = Nounce ChaCha20 -> String
forall a. Encodable a => a -> String
showBase16


instance IsString (Key ChaCha20) where
  fromString :: String -> Key ChaCha20
fromString = String -> Key ChaCha20
forall a. Encodable a => String -> a
fromBase16


instance IsString (Nounce ChaCha20) where
  fromString :: String -> Nounce ChaCha20
fromString = String -> Nounce ChaCha20
forall a. Encodable a => String -> a
fromBase16


newtype instance Key     XChaCha20 = XKey KEY
  deriving (Ptr (Key XChaCha20) -> IO (Key XChaCha20)
Ptr (Key XChaCha20) -> Int -> IO (Key XChaCha20)
Ptr (Key XChaCha20) -> Int -> Key XChaCha20 -> IO ()
Ptr (Key XChaCha20) -> Key XChaCha20 -> IO ()
Key XChaCha20 -> Int
(Key XChaCha20 -> Int)
-> (Key XChaCha20 -> Int)
-> (Ptr (Key XChaCha20) -> Int -> IO (Key XChaCha20))
-> (Ptr (Key XChaCha20) -> Int -> Key XChaCha20 -> IO ())
-> (forall b. Ptr b -> Int -> IO (Key XChaCha20))
-> (forall b. Ptr b -> Int -> Key XChaCha20 -> IO ())
-> (Ptr (Key XChaCha20) -> IO (Key XChaCha20))
-> (Ptr (Key XChaCha20) -> Key XChaCha20 -> IO ())
-> Storable (Key XChaCha20)
forall b. Ptr b -> Int -> IO (Key XChaCha20)
forall b. Ptr b -> Int -> Key XChaCha20 -> IO ()
forall a.
(a -> Int)
-> (a -> Int)
-> (Ptr a -> Int -> IO a)
-> (Ptr a -> Int -> a -> IO ())
-> (forall b. Ptr b -> Int -> IO a)
-> (forall b. Ptr b -> Int -> a -> IO ())
-> (Ptr a -> IO a)
-> (Ptr a -> a -> IO ())
-> Storable a
$csizeOf :: Key XChaCha20 -> Int
sizeOf :: Key XChaCha20 -> Int
$calignment :: Key XChaCha20 -> Int
alignment :: Key XChaCha20 -> Int
$cpeekElemOff :: Ptr (Key XChaCha20) -> Int -> IO (Key XChaCha20)
peekElemOff :: Ptr (Key XChaCha20) -> Int -> IO (Key XChaCha20)
$cpokeElemOff :: Ptr (Key XChaCha20) -> Int -> Key XChaCha20 -> IO ()
pokeElemOff :: Ptr (Key XChaCha20) -> Int -> Key XChaCha20 -> IO ()
$cpeekByteOff :: forall b. Ptr b -> Int -> IO (Key XChaCha20)
peekByteOff :: forall b. Ptr b -> Int -> IO (Key XChaCha20)
$cpokeByteOff :: forall b. Ptr b -> Int -> Key XChaCha20 -> IO ()
pokeByteOff :: forall b. Ptr b -> Int -> Key XChaCha20 -> IO ()
$cpeek :: Ptr (Key XChaCha20) -> IO (Key XChaCha20)
peek :: Ptr (Key XChaCha20) -> IO (Key XChaCha20)
$cpoke :: Ptr (Key XChaCha20) -> Key XChaCha20 -> IO ()
poke :: Ptr (Key XChaCha20) -> Key XChaCha20 -> IO ()
Storable, Storable (Key XChaCha20)
Ptr (Key XChaCha20) -> IO (Key XChaCha20)
Ptr (Key XChaCha20) -> Int -> IO ()
Ptr (Key XChaCha20) -> Key XChaCha20 -> IO ()
Storable (Key XChaCha20) =>
(Ptr (Key XChaCha20) -> Key XChaCha20 -> IO ())
-> (Ptr (Key XChaCha20) -> IO (Key XChaCha20))
-> (Ptr (Key XChaCha20) -> Int -> IO ())
-> EndianStore (Key XChaCha20)
forall w.
Storable w =>
(Ptr w -> w -> IO ())
-> (Ptr w -> IO w) -> (Ptr w -> Int -> IO ()) -> EndianStore w
$cstore :: Ptr (Key XChaCha20) -> Key XChaCha20 -> IO ()
store :: Ptr (Key XChaCha20) -> Key XChaCha20 -> IO ()
$cload :: Ptr (Key XChaCha20) -> IO (Key XChaCha20)
load :: Ptr (Key XChaCha20) -> IO (Key XChaCha20)
$cadjustEndian :: Ptr (Key XChaCha20) -> Int -> IO ()
adjustEndian :: Ptr (Key XChaCha20) -> Int -> IO ()
EndianStore)
newtype instance Nounce  XChaCha20 = XNounce  (Tuple 6 WORD)
  deriving (Ptr (Nounce XChaCha20) -> IO (Nounce XChaCha20)
Ptr (Nounce XChaCha20) -> Int -> IO (Nounce XChaCha20)
Ptr (Nounce XChaCha20) -> Int -> Nounce XChaCha20 -> IO ()
Ptr (Nounce XChaCha20) -> Nounce XChaCha20 -> IO ()
Nounce XChaCha20 -> Int
(Nounce XChaCha20 -> Int)
-> (Nounce XChaCha20 -> Int)
-> (Ptr (Nounce XChaCha20) -> Int -> IO (Nounce XChaCha20))
-> (Ptr (Nounce XChaCha20) -> Int -> Nounce XChaCha20 -> IO ())
-> (forall b. Ptr b -> Int -> IO (Nounce XChaCha20))
-> (forall b. Ptr b -> Int -> Nounce XChaCha20 -> IO ())
-> (Ptr (Nounce XChaCha20) -> IO (Nounce XChaCha20))
-> (Ptr (Nounce XChaCha20) -> Nounce XChaCha20 -> IO ())
-> Storable (Nounce XChaCha20)
forall b. Ptr b -> Int -> IO (Nounce XChaCha20)
forall b. Ptr b -> Int -> Nounce XChaCha20 -> IO ()
forall a.
(a -> Int)
-> (a -> Int)
-> (Ptr a -> Int -> IO a)
-> (Ptr a -> Int -> a -> IO ())
-> (forall b. Ptr b -> Int -> IO a)
-> (forall b. Ptr b -> Int -> a -> IO ())
-> (Ptr a -> IO a)
-> (Ptr a -> a -> IO ())
-> Storable a
$csizeOf :: Nounce XChaCha20 -> Int
sizeOf :: Nounce XChaCha20 -> Int
$calignment :: Nounce XChaCha20 -> Int
alignment :: Nounce XChaCha20 -> Int
$cpeekElemOff :: Ptr (Nounce XChaCha20) -> Int -> IO (Nounce XChaCha20)
peekElemOff :: Ptr (Nounce XChaCha20) -> Int -> IO (Nounce XChaCha20)
$cpokeElemOff :: Ptr (Nounce XChaCha20) -> Int -> Nounce XChaCha20 -> IO ()
pokeElemOff :: Ptr (Nounce XChaCha20) -> Int -> Nounce XChaCha20 -> IO ()
$cpeekByteOff :: forall b. Ptr b -> Int -> IO (Nounce XChaCha20)
peekByteOff :: forall b. Ptr b -> Int -> IO (Nounce XChaCha20)
$cpokeByteOff :: forall b. Ptr b -> Int -> Nounce XChaCha20 -> IO ()
pokeByteOff :: forall b. Ptr b -> Int -> Nounce XChaCha20 -> IO ()
$cpeek :: Ptr (Nounce XChaCha20) -> IO (Nounce XChaCha20)
peek :: Ptr (Nounce XChaCha20) -> IO (Nounce XChaCha20)
$cpoke :: Ptr (Nounce XChaCha20) -> Nounce XChaCha20 -> IO ()
poke :: Ptr (Nounce XChaCha20) -> Nounce XChaCha20 -> IO ()
Storable, Storable (Nounce XChaCha20)
Ptr (Nounce XChaCha20) -> IO (Nounce XChaCha20)
Ptr (Nounce XChaCha20) -> Int -> IO ()
Ptr (Nounce XChaCha20) -> Nounce XChaCha20 -> IO ()
Storable (Nounce XChaCha20) =>
(Ptr (Nounce XChaCha20) -> Nounce XChaCha20 -> IO ())
-> (Ptr (Nounce XChaCha20) -> IO (Nounce XChaCha20))
-> (Ptr (Nounce XChaCha20) -> Int -> IO ())
-> EndianStore (Nounce XChaCha20)
forall w.
Storable w =>
(Ptr w -> w -> IO ())
-> (Ptr w -> IO w) -> (Ptr w -> Int -> IO ()) -> EndianStore w
$cstore :: Ptr (Nounce XChaCha20) -> Nounce XChaCha20 -> IO ()
store :: Ptr (Nounce XChaCha20) -> Nounce XChaCha20 -> IO ()
$cload :: Ptr (Nounce XChaCha20) -> IO (Nounce XChaCha20)
load :: Ptr (Nounce XChaCha20) -> IO (Nounce XChaCha20)
$cadjustEndian :: Ptr (Nounce XChaCha20) -> Int -> IO ()
adjustEndian :: Ptr (Nounce XChaCha20) -> Int -> IO ()
EndianStore)

instance Encodable (Key     XChaCha20)
instance Encodable (Nounce  XChaCha20)

instance Show (Key XChaCha20) where
  show :: Key XChaCha20 -> String
show = Key XChaCha20 -> String
forall a. Encodable a => a -> String
showBase16

instance Show (Nounce XChaCha20) where
  show :: Nounce XChaCha20 -> String
show = Nounce XChaCha20 -> String
forall a. Encodable a => a -> String
showBase16


instance IsString (Key XChaCha20) where
  fromString :: String -> Key XChaCha20
fromString = String -> Key XChaCha20
forall a. Encodable a => String -> a
fromBase16


instance IsString (Nounce XChaCha20) where
  fromString :: String -> Nounce XChaCha20
fromString = String -> Nounce XChaCha20
forall a. Encodable a => String -> a
fromBase16

---------- Memory for ChaCha20 implementations  ------------------
-- | The memory element used by chacha20. This memory is an instance
-- of `WriteAccessible` where the key portion of the memory can be
-- written into.
data ChaCha20Mem = ChaCha20Mem { ChaCha20Mem -> MemoryCell (Key ChaCha20)
keyCell      :: MemoryCell (Key     ChaCha20)
                               , ChaCha20Mem -> MemoryCell (Nounce ChaCha20)
ivCell       :: MemoryCell (Nounce  ChaCha20)
                               , ChaCha20Mem -> MemoryCell WORD
counterCell  :: MemoryCell WORD
                               }

-- | The pointer into the chacha memory where the key is stored.
keyCellPtr :: ChaCha20Mem -> Ptr (Key ChaCha20)
keyCellPtr :: ChaCha20Mem -> Ptr (Key ChaCha20)
keyCellPtr = MemoryCell (Key ChaCha20) -> Ptr (Key ChaCha20)
forall a. Storable a => MemoryCell a -> Ptr a
unsafeGetCellPointer (MemoryCell (Key ChaCha20) -> Ptr (Key ChaCha20))
-> (ChaCha20Mem -> MemoryCell (Key ChaCha20))
-> ChaCha20Mem
-> Ptr (Key ChaCha20)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChaCha20Mem -> MemoryCell (Key ChaCha20)
keyCell

-- | The pointer into the chacha memory where the iv is stored.
ivCellPtr :: ChaCha20Mem -> Ptr (Nounce ChaCha20)
ivCellPtr :: ChaCha20Mem -> Ptr (Nounce ChaCha20)
ivCellPtr = MemoryCell (Nounce ChaCha20) -> Ptr (Nounce ChaCha20)
forall a. Storable a => MemoryCell a -> Ptr a
unsafeGetCellPointer (MemoryCell (Nounce ChaCha20) -> Ptr (Nounce ChaCha20))
-> (ChaCha20Mem -> MemoryCell (Nounce ChaCha20))
-> ChaCha20Mem
-> Ptr (Nounce ChaCha20)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChaCha20Mem -> MemoryCell (Nounce ChaCha20)
ivCell

-- | The pointer in the chacha memory where the counter is stored.
counterCellPtr :: ChaCha20Mem -> Ptr WORD
counterCellPtr :: ChaCha20Mem -> Ptr WORD
counterCellPtr = MemoryCell WORD -> Ptr WORD
forall a. Storable a => MemoryCell a -> Ptr a
unsafeGetCellPointer (MemoryCell WORD -> Ptr WORD)
-> (ChaCha20Mem -> MemoryCell WORD) -> ChaCha20Mem -> Ptr WORD
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChaCha20Mem -> MemoryCell WORD
counterCell

instance Initialisable  (MemoryCell (Key ChaCha20)) (Key XChaCha20) where
  initialise :: Key XChaCha20 -> MemoryCell (Key ChaCha20) -> IO ()
initialise = Key ChaCha20 -> MemoryCell (Key ChaCha20) -> IO ()
forall m v. Initialisable m v => v -> m -> IO ()
initialise (Key ChaCha20 -> MemoryCell (Key ChaCha20) -> IO ())
-> (Key XChaCha20 -> Key ChaCha20)
-> Key XChaCha20
-> MemoryCell (Key ChaCha20)
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key XChaCha20 -> Key ChaCha20
coerce
    where coerce :: Key XChaCha20 -> Key ChaCha20
coerce (XKey KEY
k) = KEY -> Key ChaCha20
Key KEY
k

instance Memory ChaCha20Mem where
  memoryAlloc :: Alloc ChaCha20Mem
memoryAlloc     = MemoryCell (Key ChaCha20)
-> MemoryCell (Nounce ChaCha20) -> MemoryCell WORD -> ChaCha20Mem
ChaCha20Mem (MemoryCell (Key ChaCha20)
 -> MemoryCell (Nounce ChaCha20) -> MemoryCell WORD -> ChaCha20Mem)
-> TwistRF AllocField (BYTES Int) (MemoryCell (Key ChaCha20))
-> TwistRF
     AllocField
     (BYTES Int)
     (MemoryCell (Nounce ChaCha20) -> MemoryCell WORD -> ChaCha20Mem)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TwistRF AllocField (BYTES Int) (MemoryCell (Key ChaCha20))
forall m. Memory m => Alloc m
memoryAlloc TwistRF
  AllocField
  (BYTES Int)
  (MemoryCell (Nounce ChaCha20) -> MemoryCell WORD -> ChaCha20Mem)
-> TwistRF AllocField (BYTES Int) (MemoryCell (Nounce ChaCha20))
-> TwistRF AllocField (BYTES Int) (MemoryCell WORD -> ChaCha20Mem)
forall a b.
TwistRF AllocField (BYTES Int) (a -> b)
-> TwistRF AllocField (BYTES Int) a
-> TwistRF AllocField (BYTES Int) b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> TwistRF AllocField (BYTES Int) (MemoryCell (Nounce ChaCha20))
forall m. Memory m => Alloc m
memoryAlloc TwistRF AllocField (BYTES Int) (MemoryCell WORD -> ChaCha20Mem)
-> TwistRF AllocField (BYTES Int) (MemoryCell WORD)
-> Alloc ChaCha20Mem
forall a b.
TwistRF AllocField (BYTES Int) (a -> b)
-> TwistRF AllocField (BYTES Int) a
-> TwistRF AllocField (BYTES Int) b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> TwistRF AllocField (BYTES Int) (MemoryCell WORD)
forall m. Memory m => Alloc m
memoryAlloc
  unsafeToPointer :: ChaCha20Mem -> Ptr Word8
unsafeToPointer = MemoryCell (Key ChaCha20) -> Ptr Word8
forall m. Memory m => m -> Ptr Word8
unsafeToPointer (MemoryCell (Key ChaCha20) -> Ptr Word8)
-> (ChaCha20Mem -> MemoryCell (Key ChaCha20))
-> ChaCha20Mem
-> Ptr Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChaCha20Mem -> MemoryCell (Key ChaCha20)
keyCell

instance Initialisable ChaCha20Mem (Key ChaCha20) where
  initialise :: Key ChaCha20 -> ChaCha20Mem -> IO ()
initialise Key ChaCha20
key = Key ChaCha20 -> MemoryCell (Key ChaCha20) -> IO ()
forall m v. Initialisable m v => v -> m -> IO ()
initialise Key ChaCha20
key (MemoryCell (Key ChaCha20) -> IO ())
-> (ChaCha20Mem -> MemoryCell (Key ChaCha20))
-> ChaCha20Mem
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChaCha20Mem -> MemoryCell (Key ChaCha20)
keyCell

instance Initialisable ChaCha20Mem (Nounce ChaCha20)  where
  initialise :: Nounce ChaCha20 -> ChaCha20Mem -> IO ()
initialise Nounce ChaCha20
nounce = Nounce ChaCha20 -> MemoryCell (Nounce ChaCha20) -> IO ()
forall m v. Initialisable m v => v -> m -> IO ()
initialise Nounce ChaCha20
nounce (MemoryCell (Nounce ChaCha20) -> IO ())
-> (ChaCha20Mem -> MemoryCell (Nounce ChaCha20))
-> ChaCha20Mem
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChaCha20Mem -> MemoryCell (Nounce ChaCha20)
ivCell

instance Initialisable ChaCha20Mem (BlockCount ChaCha20) where
  initialise :: BlockCount ChaCha20 -> ChaCha20Mem -> IO ()
initialise BlockCount ChaCha20
bcount = WORD -> MemoryCell WORD -> IO ()
forall m v. Initialisable m v => v -> m -> IO ()
initialise (BlockCount ChaCha20 -> WORD
conv BlockCount ChaCha20
bcount) (MemoryCell WORD -> IO ())
-> (ChaCha20Mem -> MemoryCell WORD) -> ChaCha20Mem -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChaCha20Mem -> MemoryCell WORD
counterCell
    where conv :: BlockCount ChaCha20 -> WORD
          conv :: BlockCount ChaCha20 -> WORD
conv = Int -> WORD
forall a. Enum a => Int -> a
toEnum (Int -> WORD)
-> (BlockCount ChaCha20 -> Int) -> BlockCount ChaCha20 -> WORD
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BlockCount ChaCha20 -> Int
forall a. Enum a => a -> Int
fromEnum

instance Extractable ChaCha20Mem (BlockCount ChaCha20) where
  extract :: ChaCha20Mem -> IO (BlockCount ChaCha20)
extract = (WORD -> BlockCount ChaCha20)
-> IO WORD -> IO (BlockCount ChaCha20)
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap WORD -> BlockCount ChaCha20
conv (IO WORD -> IO (BlockCount ChaCha20))
-> (ChaCha20Mem -> IO WORD)
-> ChaCha20Mem
-> IO (BlockCount ChaCha20)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MemoryCell WORD -> IO WORD
forall m v. Extractable m v => m -> IO v
extract  (MemoryCell WORD -> IO WORD)
-> (ChaCha20Mem -> MemoryCell WORD) -> ChaCha20Mem -> IO WORD
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChaCha20Mem -> MemoryCell WORD
counterCell
    where conv :: WORD -> BlockCount ChaCha20
          conv :: WORD -> BlockCount ChaCha20
conv = Int -> BlockCount ChaCha20
forall a. Enum a => Int -> a
toEnum (Int -> BlockCount ChaCha20)
-> (WORD -> Int) -> WORD -> BlockCount ChaCha20
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WORD -> Int
forall a. Enum a => a -> Int
fromEnum

-- | Writes into the key portion.
instance WriteAccessible ChaCha20Mem where
  writeAccess :: ChaCha20Mem -> [Access]
writeAccess = MemoryCell (Key ChaCha20) -> [Access]
forall mem. WriteAccessible mem => mem -> [Access]
writeAccess (MemoryCell (Key ChaCha20) -> [Access])
-> (ChaCha20Mem -> MemoryCell (Key ChaCha20))
-> ChaCha20Mem
-> [Access]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChaCha20Mem -> MemoryCell (Key ChaCha20)
keyCell
  afterWriteAdjustment :: ChaCha20Mem -> IO ()
afterWriteAdjustment = MemoryCell (Key ChaCha20) -> IO ()
forall mem. WriteAccessible mem => mem -> IO ()
afterWriteAdjustment (MemoryCell (Key ChaCha20) -> IO ())
-> (ChaCha20Mem -> MemoryCell (Key ChaCha20))
-> ChaCha20Mem
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChaCha20Mem -> MemoryCell (Key ChaCha20)
keyCell