<commit_before>{-|

Some basic types and classes used in the cryptographic protocols.

-}

{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE FlexibleInstances          #-}
module Raaz.Types
       ( CryptoCoerce(..)
       -- * Endian safe types
       -- $endianSafe
       , CryptoAlign
       , CryptoStore(..), toByteString
       , Word32LE, Word32BE
       , Word64LE, Word64BE
       ) where

import Data.Bits
import Data.Word
import Data.ByteString (ByteString)
import Data.ByteString.Internal (create)
import Foreign.Ptr
import Foreign.Storable
import System.Endian

-- Developers notes: I assumes that word alignment is alignment
-- safe. If this is not the case one needs to fix this to avoid
-- performance degradation or worse incorrect load/store.

-- | A type whose only purpose in this universe is to provide
-- alignment safe pointers.
newtype CryptoAlign = CryptoAlign Word deriving Storable

-- | Often we would like to feed the output of one crypto algorithm as
-- the input of the other algorithm, for e.g RSA sign the HMAC of a
-- message.
class CryptoCoerce s t where
  cryptoCoerce :: s -> t


-- | This class is defined mainly to perform endian safe loading and
-- storing. For any type that might have to be encoded as either byte
-- strings or peeked/poked from a memory location it is advisable to
-- define an instance of this class. Using store and load will then
-- prevent endian confusion.
class Storable w => CryptoStore w where
  store :: Ptr CryptoAlign -> w -> IO ()
  load  :: Ptr CryptoAlign -> IO w

-- | Generate a bytestring representation of the object.
toByteString :: CryptoStore w => w -> IO ByteString
toByteString w = create (sizeOf w) putit
      where putit ptr = store (castPtr ptr) w

{-

Developers notes:
-----------------

Make sure that the endian encoded version does not have any
performance penalty. We may have to stare at the core code generated
by ghc.

-}


-- $endianSafe
--
-- One of the most common source of implementation problems in crypto
-- algorithms is the correct dealing of endianness. We define the
-- class `CryptoStore` to solve this problem in a type safe way. Any
-- type that might have to be encoded as either byte strings or
-- peeked/poked from a memory location should be an instance of this
-- class.
--<commit_msg>now uses unsafeCreate to get a pure version<commit_after>{-|

Some basic types and classes used in the cryptographic protocols.

-}

{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE FlexibleInstances          #-}
module Raaz.Types
       ( CryptoCoerce(..)
       -- * Endian safe types
       -- $endianSafe
       , CryptoAlign
       , CryptoStore(..), toByteString
       , Word32LE, Word32BE
       , Word64LE, Word64BE
       ) where

import Data.Bits
import Data.Word
import Data.ByteString (ByteString)
import Data.ByteString.Internal (unsafeCreate)
import Foreign.Ptr
import Foreign.Storable
import System.Endian

-- Developers notes: I assumes that word alignment is alignment
-- safe. If this is not the case one needs to fix this to avoid
-- performance degradation or worse incorrect load/store.

-- | A type whose only purpose in this universe is to provide
-- alignment safe pointers.
newtype CryptoAlign = CryptoAlign Word deriving Storable

-- | Often we would like to feed the output of one crypto algorithm as
-- the input of the other algorithm, for e.g RSA sign the HMAC of a
-- message.
class CryptoCoerce s t where
  cryptoCoerce :: s -> t


-- | This class is defined mainly to perform endian safe loading and
-- storing. For any type that might have to be encoded as either byte
-- strings or peeked/poked from a memory location it is advisable to
-- define an instance of this class. Using store and load will then
-- prevent endian confusion.
class Storable w => CryptoStore w where
  store :: Ptr CryptoAlign -> w -> IO ()
  load  :: Ptr CryptoAlign -> IO w

-- | Generate a bytestring representation of the object.
toByteString :: CryptoStore w => w -> ByteString
toByteString w = unsafeCreate (sizeOf w) putit
      where putit ptr = store (castPtr ptr) w

{-

Developers notes:
-----------------

Make sure that the endian encoded version does not have any
performance penalty. We may have to stare at the core code generated
by ghc.

-}


-- $endianSafe
--
-- One of the most common source of implementation problems in crypto
-- algorithms is the correct dealing of endianness. We define the
-- class `CryptoStore` to solve this problem in a type safe way. Any
-- type that might have to be encoded as either byte strings or
-- peeked/poked from a memory location should be an instance of this
-- class.
--
{'fraction_non_alphanumeric': 0.07927472064094455, 'fraction_numerical': 0.003373392367699768, 'mean_word_length': 3.0512382578992314, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5499462', 'n_tokens_mistral': 1337, 'n_tokens_neox': 1291, 'n_words': 626}