raaz-0.3.0: core/Raaz/Primitive/ChaCha20/Internal.hs
{-# 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 (Storable, EndianStore, Equality, Eq)
newtype instance Nounce ChaCha20 = Nounce (Tuple 3 WORD)
deriving (Storable, EndianStore, Equality, Eq)
instance Encodable (Key ChaCha20)
instance Encodable (Nounce ChaCha20)
instance Show (Key ChaCha20) where
show = showBase16
instance Show (Nounce ChaCha20) where
show = showBase16
instance IsString (Key ChaCha20) where
fromString = fromBase16
instance IsString (Nounce ChaCha20) where
fromString = fromBase16
newtype instance Key XChaCha20 = XKey KEY
deriving (Storable, EndianStore)
newtype instance Nounce XChaCha20 = XNounce (Tuple 6 WORD)
deriving (Storable, EndianStore)
instance Encodable (Key XChaCha20)
instance Encodable (Nounce XChaCha20)
instance Show (Key XChaCha20) where
show = showBase16
instance Show (Nounce XChaCha20) where
show = showBase16
instance IsString (Key XChaCha20) where
fromString = fromBase16
instance IsString (Nounce XChaCha20) where
fromString = 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 { keyCell :: MemoryCell (Key ChaCha20)
, ivCell :: MemoryCell (Nounce ChaCha20)
, counterCell :: MemoryCell WORD
}
-- | The pointer into the chacha memory where the key is stored.
keyCellPtr :: ChaCha20Mem -> Ptr (Key ChaCha20)
keyCellPtr = unsafeGetCellPointer . keyCell
-- | The pointer into the chacha memory where the iv is stored.
ivCellPtr :: ChaCha20Mem -> Ptr (Nounce ChaCha20)
ivCellPtr = unsafeGetCellPointer . ivCell
-- | The pointer in the chacha memory where the counter is stored.
counterCellPtr :: ChaCha20Mem -> Ptr WORD
counterCellPtr = unsafeGetCellPointer . counterCell
instance Initialisable (MemoryCell (Key ChaCha20)) (Key XChaCha20) where
initialise = initialise . coerce
where coerce (XKey k) = Key k
instance Memory ChaCha20Mem where
memoryAlloc = ChaCha20Mem <$> memoryAlloc <*> memoryAlloc <*> memoryAlloc
unsafeToPointer = unsafeToPointer . keyCell
instance Initialisable ChaCha20Mem (Key ChaCha20) where
initialise key = initialise key . keyCell
instance Initialisable ChaCha20Mem (Nounce ChaCha20) where
initialise nounce = initialise nounce . ivCell
instance Initialisable ChaCha20Mem (BlockCount ChaCha20) where
initialise bcount = initialise (conv bcount) . counterCell
where conv :: BlockCount ChaCha20 -> WORD
conv = toEnum . fromEnum
instance Extractable ChaCha20Mem (BlockCount ChaCha20) where
extract = fmap conv . extract . counterCell
where conv :: WORD -> BlockCount ChaCha20
conv = toEnum . fromEnum
-- | Writes into the key portion.
instance WriteAccessible ChaCha20Mem where
writeAccess = writeAccess . keyCell
afterWriteAdjustment = afterWriteAdjustment . keyCell