-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Reversable and secure encoding of object ids as a bytestring
--
-- Reversable and secure encoding of object ids as a bytestring
@package cryptoids
@version 0.4.0.0
-- | Given a strict ByteString we compute a cryptographic hash of
-- the associated namespace (carried as a phantom type of kind
-- Symbol). The payload is then encrypted using the symmetric
-- cipher in CBC mode using the hashed namespace as an initialization
-- vector (IV).
--
-- The probability of detecting a namespace mismatch is thus the density
-- of valid payloads within all ByteStrings of the correct length.
module Data.CryptoID.ByteString
newtype CryptoID (namespace :: Symbol) a :: Symbol -> * -> *
CryptoID :: a -> CryptoID a
[ciphertext] :: CryptoID a -> a
-- | This newtype ensures only keys of the correct length can be created
--
-- Use genKey to securely generate keys.
--
-- Use the Binary instance to save and restore values of
-- CryptoIDKey across executions.
data CryptoIDKey
-- | Securely generate a new key using system entropy
--
-- When CryptoCipher accepts keys of varying lengths this function
-- generates a key of the largest accepted size.
genKey :: MonadIO m => m CryptoIDKey
-- | Try to read a CryptoIDKey from a file. If the file does not
-- exist, securely generate a key (using genKey) and save it to
-- the file.
readKeyFile :: MonadIO m => FilePath -> m CryptoIDKey
-- | Encrypt a serialized value
encrypt :: forall m namespace. (KnownSymbol namespace, MonadThrow m) => CryptoIDKey -> ByteString -> m (CryptoID namespace ByteString)
-- | Decrypt a serialized value
decrypt :: forall m namespace. (KnownSymbol namespace, MonadThrow m) => CryptoIDKey -> CryptoID namespace ByteString -> m ByteString
-- | Error cases that can be encountered during encrypt and
-- decrypt
--
-- Care has been taken to ensure that presenting values of
-- CryptoIDError to an attacker leaks no plaintext (it does leak
-- information about the length of the plaintext).
data CryptoIDError
-- | One of the underlying cryptographic algorithms (CryptoHash or
-- CryptoCipher) failed.
AlgorithmError :: CryptoError -> CryptoIDError
-- | The length of the plaintext is not a multiple of the block size of
-- CryptoCipher
--
-- The length of the offending plaintext is included.
PlaintextIsWrongLength :: Int -> CryptoIDError
-- | The length of the digest produced by CryptoHash does not match
-- the block size of CryptoCipher.
--
-- The offending digest is included.
--
-- This error should not occur and is included primarily for sake of
-- totality.
NamespaceHashIsWrongLength :: ByteString -> CryptoIDError
-- | The produced ByteString is the wrong length for deserialization
-- into a ciphertext.
--
-- The offending ByteString is included.
CiphertextConversionFailed :: ByteString -> CryptoIDError
-- | The plaintext obtained by decrypting a ciphertext with the given
-- CryptoIDKey in the context of the namespace could not
-- be deserialized into a value of the expected payload-type.
--
-- This is expected behaviour if the namespace or
-- payload-type does not match the ones used during
-- encryption or if the ciphertext was tempered with.
DeserializationError :: CryptoIDError
-- | We have determined that, allthough deserializion succeded, the
-- ciphertext was likely modified during transit or created using a
-- different namespace.
InvalidNamespaceDetected :: CryptoIDError
-- | The symmetric cipher BlockCipher this module uses
type CryptoCipher = Blowfish
-- | The cryptographic HashAlgorithm this module uses
--
-- We expect the block size of CryptoCipher to be exactly the size
-- of the Digest generated by CryptoHash (since a
-- Digest is used as an IV).
--
-- Violation of this expectation causes runtime errors.
type CryptoHash = SHAKE128 64
cipherBlockSize :: Int
instance GHC.Classes.Eq Data.CryptoID.ByteString.CryptoIDError
instance GHC.Show.Show Data.CryptoID.ByteString.CryptoIDError
instance Data.ByteArray.Types.ByteArrayAccess Data.CryptoID.ByteString.CryptoIDKey
instance GHC.Show.Show Data.CryptoID.ByteString.CryptoIDKey
instance Data.Binary.Class.Binary Data.CryptoID.ByteString.CryptoIDKey
instance GHC.Exception.Exception Data.CryptoID.ByteString.CryptoIDError
-- | Given a value of an arbitrary serializable type (like Int) we
-- perform serialization and compute a cryptographic hash of the
-- associated namespace (carried as a phantom type of kind
-- Symbol). The serializedpayload is then encrypted using the
-- symmetric cipher in CBC mode using the hashed namespace as an
-- initialization vector (IV).
--
-- Since the serialized payload is padded such that its length is an
-- integer multiple of the block size we can detect namespace mismatches
-- by checking that all bytes expected to have been inserted during
-- padding are nil.
--
-- The probability of detecting a namespace mismatch is thus (1 - 2^{l
-- text{mod} 64}) where <math> is the length of the serialized
-- payload in bits.
module Data.CryptoID.Poly
newtype CryptoID (namespace :: Symbol) a :: Symbol -> * -> *
CryptoID :: a -> CryptoID a
[ciphertext] :: CryptoID a -> a
-- | This newtype ensures only keys of the correct length can be created
--
-- Use genKey to securely generate keys.
--
-- Use the Binary instance to save and restore values of
-- CryptoIDKey across executions.
data CryptoIDKey
-- | Securely generate a new key using system entropy
--
-- When CryptoCipher accepts keys of varying lengths this function
-- generates a key of the largest accepted size.
genKey :: MonadIO m => m CryptoIDKey
-- | Try to read a CryptoIDKey from a file. If the file does not
-- exist, securely generate a key (using genKey) and save it to
-- the file.
readKeyFile :: MonadIO m => FilePath -> m CryptoIDKey
-- | Encrypt a serialized value
encrypt :: forall a m c namespace. (KnownSymbol namespace, MonadThrow m, Binary a) => (ByteString -> m (Maybe Int)) -> (ByteString -> m c) -> CryptoIDKey -> a -> m (CryptoID namespace c)
-- | Decrypt a serialized value
decrypt :: forall a m c namespace. (KnownSymbol namespace, MonadThrow m, Binary a) => (c -> m ByteString) -> CryptoIDKey -> CryptoID namespace c -> m a
-- | Error cases that can be encountered during encrypt and
-- decrypt
--
-- Care has been taken to ensure that presenting values of
-- CryptoIDError to an attacker leaks no plaintext (it does leak
-- information about the length of the plaintext).
data CryptoIDError
-- | One of the underlying cryptographic algorithms (CryptoHash or
-- CryptoCipher) failed.
AlgorithmError :: CryptoError -> CryptoIDError
-- | The length of the plaintext is not a multiple of the block size of
-- CryptoCipher
--
-- The length of the offending plaintext is included.
PlaintextIsWrongLength :: Int -> CryptoIDError
-- | The length of the digest produced by CryptoHash does not match
-- the block size of CryptoCipher.
--
-- The offending digest is included.
--
-- This error should not occur and is included primarily for sake of
-- totality.
NamespaceHashIsWrongLength :: ByteString -> CryptoIDError
-- | The produced ByteString is the wrong length for deserialization
-- into a ciphertext.
--
-- The offending ByteString is included.
CiphertextConversionFailed :: ByteString -> CryptoIDError
-- | The plaintext obtained by decrypting a ciphertext with the given
-- CryptoIDKey in the context of the namespace could not
-- be deserialized into a value of the expected payload-type.
--
-- This is expected behaviour if the namespace or
-- payload-type does not match the ones used during
-- encryption or if the ciphertext was tempered with.
DeserializationError :: CryptoIDError
-- | We have determined that, allthough deserializion succeded, the
-- ciphertext was likely modified during transit or created using a
-- different namespace.
InvalidNamespaceDetected :: CryptoIDError
-- | The symmetric cipher BlockCipher this module uses
type CryptoCipher = Blowfish
-- | The cryptographic HashAlgorithm this module uses
--
-- We expect the block size of CryptoCipher to be exactly the size
-- of the Digest generated by CryptoHash (since a
-- Digest is used as an IV).
--
-- Violation of this expectation causes runtime errors.
type CryptoHash = SHAKE128 64