-- | -- Module : Raaz.Digest -- Description : Message digest. -- Copyright : (c) Piyush P Kurur, 2016 -- License : Apache-2.0 OR BSD-3-Clause -- Maintainer : Piyush P Kurur <ppk@iitpkd.ac.in> -- Stability : experimental -- module Raaz.Digest ( -- ** Message digest. -- -- $messagedigest$ Digest, digest, digestFile, digestSource -- ** Incremental processing. -- $incremental$ , DigestCxt , startDigest, updateDigest, finaliseDigest -- -- *** Specific message digests. -- $specific-digest$ ) where import GHC.TypeLits import Raaz.Core import qualified Raaz.V1.Digest as Digest -- $messagedigest$ -- -- A message digest is a short (fixed size) summary of a long message -- which is cryptographically secure against tampering. Use a message -- digest if all you care about is integrity: If @d@ is the digest of -- a message @m@, then a computationally bound adversary cannot -- produce another message @m'@ for which the digest is also -- @d@. -- -- Here is a simple application for computing and verifying the digest -- of a file. -- -- -- > -- Program to compute the message digest of a file -- > -- > import Raaz -- > import System.Environment -- > -- > main = getArgs >>= digestFile . head >>= print -- > -- -- > -- Program to verify the integrity of a file -- > -- > import Raaz -- > import System.Environment -- > -- > main = do [d,file] <- getArgs -- > dp <- digestFile file -- > if fromString d == dp -- > then putStrLn "OK" -- > else putStrLn "FAILED" -- > -- -- There are three variants for computing the digest of a -- message. `digest`, `digestFile` and `digestSource`. -- -- === Serialisation -- -- Digests are instances of `Encodable` and hence can be serialised -- directly to byte string. -- -- -- == Warning -- -- Message digests __DO NOT__ provide any authentication; any one -- could have compute the digest of a given message `m` and hence says -- nothing about the peer from whom the digest has been received. If -- you want some guarantee on who the digest came from consider using -- a message authenticator (see "Raaz.Auth"). In addition if you also -- want secrecy consider using encrypted authenticator (see -- "Raaz.AuthEncrypt") -- $incremental$ -- -- Message digest can also be computed incrementally using a digest -- context captured by the `DigestCxt` data type. The three functions -- relevant for this style of operation are `startDigest`, -- `updateDigest`, and `finaliseDigest` which respectively prepares -- the context for a new incremental processing, updates the context -- with an additional chunk of data, and finalises the context to -- recover the digest. The type `DigestCxt` is an instance of the -- class `Memory` and hence any IO action that requires a `DigestCxt` -- as argument can be run using `withMemory`. -- -- If the entire input is with you either as a file or a string, the -- `digest` and `digestFile` is a much more high level interface and -- should be preferred. -- $specific-digest$ -- -- To inter-operate with other libraries and applications, one might -- want to compute the digest using specific cryptographic hash. In -- such a situation, import one of the more specific module instead of -- this one. -- -- * Raaz.Digest.Blake2b -- * Raaz.Digest.Blake2s -- * Raaz.Digest.Sha512 -- * Raaz.Digest.Sha256 -- -- Here is an example that uses sha512 to compute the digest. -- -- > import Raaz.Digest.Sha512 -- > import System.Environment -- > -- > main = getArgs >>= digestFile . head >>= print -- > -- | The digest type. type Digest = Digest.Digest -- | The context type used for incremental processing of -- input. Incremental processing first collects data into the context -- and when the context buffer is full, processes it in one go using -- the digest compression routine. parameter @n@ measures how many -- blocks of data can be held in the context till the compression -- routine is invoked. type DigestCxt n = Digest.DigestCxt n -- | Compute the digest of a pure byte source like `B.ByteString`. digest :: PureByteSource src => src -- ^ Message -> Digest digest :: src -> Digest digest = src -> Digest forall src. PureByteSource src => src -> Digest Digest.digest -- | Compute the digest of file. digestFile :: FilePath -- ^ File to be digested -> IO Digest digestFile :: FilePath -> IO Digest digestFile = FilePath -> IO Digest Digest.digestFile -- | Compute the digest of an arbitrary byte source. digestSource :: ByteSource src => src -> IO Digest digestSource :: src -> IO Digest digestSource = src -> IO Digest forall src. ByteSource src => src -> IO Digest Digest.digestSource -- | Prepare the context to (re)start a session of incremental -- processing. startDigest :: KnownNat n => DigestCxt n -> IO () startDigest :: DigestCxt n -> IO () startDigest = DigestCxt n -> IO () forall (n :: Nat). KnownNat n => Cxt n -> IO () Digest.startDigest -- | Add some more data into the context, in this case the entirety of -- the byte source src. updateDigest :: (KnownNat n, ByteSource src) => src -> DigestCxt n -> IO () updateDigest :: src -> DigestCxt n -> IO () updateDigest = src -> DigestCxt n -> IO () forall (n :: Nat) src. (KnownNat n, ByteSource src) => src -> Cxt n -> IO () Digest.updateDigest -- | Finalise the context to get hold of the digest. finaliseDigest :: KnownNat n => DigestCxt n -> IO Digest finaliseDigest :: DigestCxt n -> IO Digest finaliseDigest = DigestCxt n -> IO Digest forall (n :: Nat). KnownNat n => Cxt n -> IO Digest Digest.finaliseDigest