{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
module Raaz.Cipher.ChaCha20.Internal
( ChaCha20(..), WORD, Counter(..), IV(..), KEY(..), ChaCha20Mem(..)
) where
import Control.Applicative
import Data.Word
import Data.String
import Foreign.Storable
import Prelude
import Raaz.Core
import Raaz.Cipher.Internal
type WORD = LE Word32
newtype IV = IV (Tuple 3 (LE Word32)) deriving (Storable, EndianStore)
instance Encodable IV
instance Show IV where
show = showBase16
instance IsString IV where
fromString = fromBase16
newtype Counter = Counter (LE Word32) deriving (Num, Storable, EndianStore, Show, Eq, Ord)
newtype KEY = ChaCha20Key (Tuple 8 WORD) deriving (Storable, EndianStore)
instance Encodable KEY
instance Show KEY where
show = showBase16
instance IsString KEY where
fromString = fromBase16
data ChaCha20 = ChaCha20
instance Primitive ChaCha20 where
blockSize _ = BYTES 64
type Implementation ChaCha20 = SomeCipherI ChaCha20
type instance Key ChaCha20 = (KEY, IV, Counter)
instance Describable ChaCha20 where
name _ = "chacha20"
description _ = "The ChaCha20 cipher"
instance Cipher ChaCha20
instance StreamCipher ChaCha20
data ChaCha20Mem = ChaCha20Mem { keyCell :: MemoryCell KEY
, ivCell :: MemoryCell IV
, counterCell :: MemoryCell Counter
}
instance Memory ChaCha20Mem where
memoryAlloc = ChaCha20Mem <$> memoryAlloc <*> memoryAlloc <*> memoryAlloc
unsafeToPointer = unsafeToPointer . keyCell
instance Initialisable ChaCha20Mem (KEY, IV, Counter) where
initialise (k,iv,ctr) = do onSubMemory keyCell $ initialise k
onSubMemory ivCell $ initialise iv
onSubMemory counterCell $ initialise ctr
instance Initialisable ChaCha20Mem (KEY, IV) where
initialise (k, iv) = initialise (k, iv, 0 :: Counter)