module Crypto.ChunkedAlgorithms where import Data.ByteString (ByteString) import qualified Data.ByteString as BS import qualified Data.ByteArray as BA import Crypto.Chunked import Crypto.Error import qualified Crypto.Cipher.ChaChaPoly1305 as ChaP {- | Constructs a ChunkedCrypto based on the ChaChaPoly1305 primitive. No authenticated data is used, and chunk authentication is concatenated to the begining of the chunk. -} chunkedChaChaPoly1305 :: -- | Plain text block size Int -> -- | Encryption key ByteString -> ChunkedCrypto chunkedChaChaPoly1305 s k = ChunkedCrypto enc dec (fromIntegral s) (fromIntegral s + auth_size) where auth_size = 16 enc = \nonce dt -> do n <- ChaP.nonce12 nonce st0 <- ChaP.initialize k n let st1 = ChaP.finalizeAAD st0 let (out, st2) = ChaP.encrypt dt st1 let auth = BA.convert $ ChaP.finalize st2 return $ BS.append auth out dec = \nonce dt' -> do let (auth, dt) = BS.splitAt 16 dt' n <- ChaP.nonce12 nonce st0 <- ChaP.initialize k n let st1 = ChaP.finalizeAAD st0 let (out, st2) = ChaP.decrypt dt st1 let auth' = BA.convert $ ChaP.finalize st2 if auth == auth' then return out else CryptoFailed CryptoError_MacKeyInvalid