-- 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.5.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 type CryptoByteString (namespace :: Symbol) = CryptoID namespace ByteString type HasCryptoByteString (namespace :: Symbol) = HasCryptoID namespace ByteString -- | 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.Exception.Exception Data.CryptoID.ByteString.CryptoIDError instance GHC.Show.Show Data.CryptoID.ByteString.CryptoIDKey instance Data.Binary.Class.Binary Data.CryptoID.ByteString.CryptoIDKey instance (Data.CryptoID.Class.MonadCrypto m, Data.CryptoID.Class.MonadCryptoKey m ~ Data.CryptoID.ByteString.CryptoIDKey, GHC.TypeLits.KnownSymbol namespace) => Data.CryptoID.Class.HasCryptoID namespace Data.ByteString.Internal.ByteString Data.ByteString.Internal.ByteString m module Data.CryptoID.ByteString.ImplicitNamespace type CryptoByteString plaintext = CryptoID ByteString plaintext type HasCryptoByteString plaintext = HasCryptoID ByteString plaintext -- | 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 -- | 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 instance (Data.CryptoID.Class.MonadCrypto m, Data.CryptoID.Class.MonadCryptoKey m ~ Data.CryptoID.ByteString.CryptoIDKey, GHC.TypeLits.KnownSymbol namespace, Data.Binary.Class.Binary a) => Data.CryptoID.Class.HasCryptoID namespace Data.ByteString.Internal.ByteString a m module Data.CryptoID.Poly.ImplicitNamespace