ChunkedAlgorithms.hs 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  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. st1 <- initChaP nonce
  24. let (out, st2) = ChaP.encrypt dt st1
  25. let auth = BA.convert $ ChaP.finalize st2
  26. return $ BS.append auth out
  27. dec nonce dt' = do
  28. let (auth, dt) = BS.splitAt 16 dt'
  29. st1 <- initChaP nonce
  30. let (out, st2) = ChaP.decrypt dt st1
  31. let auth' = BA.convert $ ChaP.finalize st2
  32. if auth == auth'
  33. then return out
  34. else CryptoFailed CryptoError_MacKeyInvalid
  35. initChaP nonce = do
  36. n <- ChaP.nonce12 nonce
  37. st0 <- ChaP.initialize k n
  38. return $ ChaP.finalizeAAD st0