ChunkedAlgorithms.hs 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. module Crypto.ChunkedAlgorithms where
  2. import Data.ByteString (ByteString)
  3. import qualified Data.ByteString as BS
  4. import qualified Data.ByteArray as BA
  5. import Crypto.Chunked
  6. import Crypto.Error
  7. import qualified Crypto.Cipher.ChaChaPoly1305 as ChaP
  8. {- |
  9. Constructs a ChunkedCrypto based on the ChaChaPoly1305 primitive.
  10. No authenticated data is used, and chunk authentication is concatenated
  11. to the begining of the chunk.
  12. -}
  13. chunkedChaChaPoly1305 ::
  14. -- | Plain text block size
  15. Int ->
  16. -- | Encryption key
  17. ByteString ->
  18. ChunkedCrypto
  19. chunkedChaChaPoly1305 s k = ChunkedCrypto enc dec (fromIntegral s) (fromIntegral s + auth_size)
  20. where
  21. auth_size = 16
  22. enc = \nonce dt -> do
  23. n <- ChaP.nonce12 nonce
  24. st0 <- ChaP.initialize k n
  25. let st1 = ChaP.finalizeAAD st0
  26. let (out, st2) = ChaP.encrypt dt st1
  27. let auth = BA.convert $ ChaP.finalize st2
  28. return $ BS.append auth out
  29. dec = \nonce dt' -> do
  30. let (auth, dt) = BS.splitAt 16 dt'
  31. n <- ChaP.nonce12 nonce
  32. st0 <- ChaP.initialize k n
  33. let st1 = ChaP.finalizeAAD st0
  34. let (out, st2) = ChaP.decrypt dt st1
  35. let auth' = BA.convert $ ChaP.finalize st2
  36. if auth == auth'
  37. then return out
  38. else CryptoFailed CryptoError_MacKeyInvalid